/* Display generation from window structure and buffer text.
-Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
-Inc.
+Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* Non-zero means print newline to stdout before next mini-buffer
message. */
-int noninteractive_need_newline;
+bool noninteractive_need_newline;
/* Non-zero means print newline to message log before next message. */
-static int message_log_need_newline;
+static bool message_log_need_newline;
/* Three markers that message_dolog uses.
It could allocate them itself, but that causes trouble
/* Nonzero if an overlay arrow has been displayed in this window. */
-static int overlay_arrow_seen;
+static bool overlay_arrow_seen;
/* Vector containing glyphs for an ellipsis `...'. */
/* Nonzero means multibyte characters were enabled when the echo area
message was specified. */
-static int message_enable_multibyte;
+static bool message_enable_multibyte;
/* Nonzero if we should redraw the mode lines on the next redisplay. */
int windows_or_buffers_changed;
-/* Nonzero means a frame's cursor type has been changed. */
-
-static int cursor_type_changed;
-
/* Nonzero after display_mode_line if %l was used and it displayed a
line number. */
-static int line_number_displayed;
+static bool line_number_displayed;
/* The name of the *Messages* buffer, a string. */
/* Non-zero means display_echo_area should display the last echo area
message again. Set by redisplay_preserve_echo_area. */
-static int display_last_displayed_message_p;
+static bool display_last_displayed_message_p;
/* Nonzero if echo area is being used by print; zero if being used by
message. */
-static int message_buf_print;
+static bool message_buf_print;
/* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
/* Set to 1 in clear_message to make redisplay_internal aware
of an emptied echo area. */
-static int message_cleared_p;
+static bool message_cleared_p;
/* A scratch glyph row with contents used for generating truncation
glyphs. Also used in direct_output_for_insert. */
/* Non-zero if there's a help-echo in the echo area. */
-int help_echo_showing_p;
+bool help_echo_showing_p;
/* The maximum distance to look ahead for text properties. Values
that are too small let us call compute_char_face and similar
Lisp_Object previous_help_echo_string;
-/* Platform-independent portion of hourglass implementation. */
+/* Platform-independent portion of hourglass implementation. */
#ifdef HAVE_WINDOW_SYSTEM
/* Non-zero means an hourglass cursor is currently shown. */
-int hourglass_shown_p;
+bool hourglass_shown_p;
/* If non-null, an asynchronous timer that, when it expires, displays
an hourglass cursor on all frames. */
#endif /* HAVE_WINDOW_SYSTEM */
/* Name of the face used to display glyphless characters. */
-Lisp_Object Qglyphless_char;
+static Lisp_Object Qglyphless_char;
/* Symbol for the purpose of Vglyphless_char_display. */
static Lisp_Object Qglyphless_char_display;
#ifdef HAVE_WINDOW_SYSTEM
static void x_consider_frame_title (Lisp_Object);
-static int tool_bar_lines_needed (struct frame *, int *);
static void update_tool_bar (struct frame *, int);
-static void build_desired_tool_bar_string (struct frame *f);
static int redisplay_tool_bar (struct frame *);
-static void display_tool_bar_line (struct it *, int);
static void notice_overwritten_cursor (struct window *,
enum glyph_row_area,
int, int, int, int);
text, or we can't tell because W's current matrix is not up to
date. */
-static
-struct glyph *
+static struct glyph *
x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
int *dx, int *dy, int *area)
{
#endif /* GLYPH_DEBUG and ENABLE_CHECKING */
-/* Return mark position if current buffer has the region of non-zero length,
- or -1 otherwise. */
-
-static ptrdiff_t
-markpos_of_region (void)
-{
- if (!NILP (Vtransient_mark_mode)
- && !NILP (BVAR (current_buffer, mark_active))
- && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
- {
- ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
-
- if (markpos != PT)
- return markpos;
- }
- return -1;
-}
-
/***********************************************************************
Iterator initialization
***********************************************************************/
ptrdiff_t charpos, ptrdiff_t bytepos,
struct glyph_row *row, enum face_id base_face_id)
{
- ptrdiff_t markpos;
enum face_id remapped_base_face_id = base_face_id;
/* Some precondition checks. */
/* Are multibyte characters enabled in current_buffer? */
it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
- /* If visible region is of non-zero length, set IT->region_beg_charpos
- and IT->region_end_charpos to the start and end of a visible region
- in window IT->w. Set both to -1 to indicate no region. */
- markpos = markpos_of_region ();
- if (markpos >= 0
- /* Maybe highlight only in selected window. */
- && (/* Either show region everywhere. */
- highlight_nonselected_windows
- /* Or show region in the selected window. */
- || w == XWINDOW (selected_window)
- /* Or show the region if we are in the mini-buffer and W is
- the window the mini-buffer refers to. */
- || (MINI_WINDOW_P (XWINDOW (selected_window))
- && WINDOWP (minibuf_selected_window)
- && w == XWINDOW (minibuf_selected_window))))
- {
- it->region_beg_charpos = min (PT, markpos);
- it->region_end_charpos = max (PT, markpos);
- }
- else
- it->region_beg_charpos = it->region_end_charpos = -1;
-
/* Get the position at which the redisplay_end_trigger hook should
be run, if it is to be run at all. */
if (MARKERP (w->redisplay_end_trigger)
if (pos < it->stop_charpos)
it->stop_charpos = pos;
- /* If showing the region, we have to stop at the region
- start or end because the face might change there. */
- if (it->region_beg_charpos > 0)
- {
- if (IT_CHARPOS (*it) < it->region_beg_charpos)
- it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
- else if (IT_CHARPOS (*it) < it->region_end_charpos)
- it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
- }
-
/* Set up variables for computing the stop position from text
property changes. */
XSETBUFFER (object, current_buffer);
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object val;
struct buffer *obuf = current_buffer;
- int begv = BEGV, zv = ZV;
- int old_clip_changed = current_buffer->clip_changed;
+ ptrdiff_t begv = BEGV, zv = ZV;
+ bool old_clip_changed = current_buffer->clip_changed;
val = Vfontification_functions;
specbind (Qfontification_functions, Qnil);
new_face_id
= face_at_buffer_position (it->w,
IT_CHARPOS (*it),
- it->region_beg_charpos,
- it->region_end_charpos,
&next_stop,
(IT_CHARPOS (*it)
+ TEXT_PROP_DISTANCE_LIMIT),
base_face_id
= face_for_overlay_string (it->w,
IT_CHARPOS (*it),
- it->region_beg_charpos,
- it->region_end_charpos,
&next_stop,
(IT_CHARPOS (*it)
+ TEXT_PROP_DISTANCE_LIMIT),
it->string,
IT_STRING_CHARPOS (*it),
bufpos,
- it->region_beg_charpos,
- it->region_end_charpos,
&next_stop,
base_face_id, 0);
it->string,
charpos,
bufpos,
- it->region_beg_charpos,
- it->region_end_charpos,
&next_check_charpos,
base_face_id, 0);
/* Determine face for CHARSET_ASCII, or unibyte. */
face_id = face_at_buffer_position (it->w,
CHARPOS (pos),
- it->region_beg_charpos,
- it->region_end_charpos,
&next_check_charpos,
limit, 0, -1);
ptrdiff_t charpos, ptrdiff_t precision, int field_width,
int multibyte)
{
- /* No region in strings. */
- it->region_beg_charpos = it->region_end_charpos = -1;
-
/* No text property checks performed by default, but see below. */
it->stop_charpos = -1;
if (c >= 0)
{
glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
- if (CONSP (glyphless_method))
- glyphless_method = FRAME_WINDOW_P (it->f)
+ if (CONSP (glyphless_method))
+ glyphless_method = FRAME_WINDOW_P (it->f)
? XCAR (glyphless_method)
: XCDR (glyphless_method);
}
return glyphless_method;
}
-/* Load IT's display element fields with information about the next
- display element from the current position of IT. Value is zero if
- end of buffer (or C string) is reached. */
+/* Merge escape glyph face and cache the result. */
static struct frame *last_escape_glyph_frame = NULL;
static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
static int last_escape_glyph_merged_face_id = 0;
-struct frame *last_glyphless_glyph_frame = NULL;
-int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
-int last_glyphless_glyph_merged_face_id = 0;
+static int
+merge_escape_glyph_face (struct it *it)
+{
+ int face_id;
+
+ if (it->f == last_escape_glyph_frame
+ && it->face_id == last_escape_glyph_face_id)
+ face_id = last_escape_glyph_merged_face_id;
+ else
+ {
+ /* Merge the `escape-glyph' face into the current face. */
+ face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
+ last_escape_glyph_frame = it->f;
+ last_escape_glyph_face_id = it->face_id;
+ last_escape_glyph_merged_face_id = face_id;
+ }
+ return face_id;
+}
+
+/* Likewise for glyphless glyph face. */
+
+static struct frame *last_glyphless_glyph_frame = NULL;
+static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
+static int last_glyphless_glyph_merged_face_id = 0;
+
+int
+merge_glyphless_glyph_face (struct it *it)
+{
+ int face_id;
+
+ if (it->f == last_glyphless_glyph_frame
+ && it->face_id == last_glyphless_glyph_face_id)
+ face_id = last_glyphless_glyph_merged_face_id;
+ else
+ {
+ /* Merge the `glyphless-char' face into the current face. */
+ face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
+ last_glyphless_glyph_frame = it->f;
+ last_glyphless_glyph_face_id = it->face_id;
+ last_glyphless_glyph_merged_face_id = face_id;
+ }
+ return face_id;
+}
+
+/* Load IT's display element fields with information about the next
+ display element from the current position of IT. Value is zero if
+ end of buffer (or C string) is reached. */
static int
get_next_display_element (struct it *it)
Non-printable characters and raw-byte characters are also
translated to octal form. */
- if (((c < ' ' || c == 127) /* ASCII control chars */
+ if (((c < ' ' || c == 127) /* ASCII control chars. */
? (it->area != TEXT_AREA
/* In mode line, treat \n, \t like other crl chars. */
|| (c != '\t'
g = GLYPH_CODE_CHAR (gc);
lface_id = GLYPH_CODE_FACE (gc);
}
- if (lface_id)
- {
- face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
- }
- else if (it->f == last_escape_glyph_frame
- && it->face_id == last_escape_glyph_face_id)
- {
- face_id = last_escape_glyph_merged_face_id;
- }
- else
- {
- /* Merge the escape-glyph face into the current face. */
- face_id = merge_faces (it->f, Qescape_glyph, 0,
- it->face_id);
- last_escape_glyph_frame = it->f;
- last_escape_glyph_face_id = it->face_id;
- last_escape_glyph_merged_face_id = face_id;
- }
+
+ face_id = (lface_id
+ ? merge_faces (it->f, Qt, lface_id, it->face_id)
+ : merge_escape_glyph_face (it));
XSETINT (it->ctl_chars[0], g);
XSETINT (it->ctl_chars[1], c ^ 0100);
escape_glyph = GLYPH_CODE_CHAR (gc);
lface_id = GLYPH_CODE_FACE (gc);
}
- if (lface_id)
- {
- /* The display table specified a face.
- Merge it into face_id and also into escape_glyph. */
- face_id = merge_faces (it->f, Qt, lface_id,
- it->face_id);
- }
- else if (it->f == last_escape_glyph_frame
- && it->face_id == last_escape_glyph_face_id)
- {
- face_id = last_escape_glyph_merged_face_id;
- }
- else
- {
- /* Merge the escape-glyph face into the current face. */
- face_id = merge_faces (it->f, Qescape_glyph, 0,
- it->face_id);
- last_escape_glyph_frame = it->f;
- last_escape_glyph_face_id = it->face_id;
- last_escape_glyph_merged_face_id = face_id;
- }
+
+ face_id = (lface_id
+ ? merge_faces (it->f, Qt, lface_id, it->face_id)
+ : merge_escape_glyph_face (it));
/* Draw non-ASCII hyphen with just highlighting: */
}
}
+#ifdef HAVE_WINDOW_SYSTEM
/* Adjust face id for a multibyte character. There are no multibyte
character in unibyte text. */
if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
}
}
+#endif /* HAVE_WINDOW_SYSTEM */
done:
/* Is this character the last one of a run of characters with
INC_TEXT_POS (pos, it->multibyte_p);
next_face_id = face_at_buffer_position
- (it->w, CHARPOS (pos), it->region_beg_charpos,
- it->region_end_charpos, &ignore,
+ (it->w, CHARPOS (pos), &ignore,
(IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
-1);
it->end_of_box_run_p
/* The commented-out optimization uses vmotion on terminals. This
gives bad results, because elements like it->what, on which
- callers such as pos_visible_p rely, aren't updated. */
+ callers such as pos_visible_p rely, aren't updated. */
/* struct position pos;
if (!FRAME_WINDOW_P (it->f))
{
{
/* DVPOS == 0 means move to the start of the screen line. */
move_it_vertically_backward (it, 0);
- /* Let next call to line_bottom_y calculate real line height */
+ /* Let next call to line_bottom_y calculate real line height. */
last_height = 0;
}
else if (dvpos > 0)
old_deactivate_mark = Vdeactivate_mark;
oldbuf = current_buffer;
- Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
+
+ /* Ensure the Messages buffer exists, and switch to it.
+ If we created it, set the major-mode. */
+ {
+ int newbuffer = 0;
+ if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
+
+ Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
+
+ if (newbuffer &&
+ !NILP (Ffboundp (intern ("messages-buffer-mode"))))
+ call0 (intern ("messages-buffer-mode"));
+ }
+
bset_undo_list (current_buffer, Qt);
+ bset_cache_long_scans (current_buffer, Qnil);
oldpoint = message_dolog_marker1;
set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
shown in some window. So we must manually incrementing
windows_or_buffers_changed here to make up for that. */
if (shown)
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 41;
else
windows_or_buffers_changed = old_windows_or_buffers_changed;
message_log_need_newline = !nlflag;
putc ('\n', stderr);
noninteractive_need_newline = 0;
if (STRINGP (m))
- fwrite (SDATA (m), SBYTES (m), 1, stderr);
+ {
+ Lisp_Object s = ENCODE_SYSTEM (m);
+
+ fwrite (SDATA (s), SBYTES (s), 1, stderr);
+ }
if (cursor_in_echo_area == 0)
fprintf (stderr, "\n");
fflush (stderr);
{
if (m)
{
+ /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
+ String whose data pointer might be passed to us in M. So
+ we use a local copy. */
+ char *fmt = xstrdup (m);
+
if (noninteractive_need_newline)
putc ('\n', stderr);
noninteractive_need_newline = 0;
- fprintf (stderr, m, SDATA (string));
+ fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string)));
if (!cursor_in_echo_area)
fprintf (stderr, "\n");
fflush (stderr);
+ xfree (fmt);
}
}
else if (INTERACTIVE)
(intptr_t) w, resize_exactly);
if (resized_p)
{
- ++windows_or_buffers_changed;
- ++update_mode_lines;
+ windows_or_buffers_changed = 42;
+ update_mode_lines = 30;
redisplay_internal ();
}
}
if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
{
if (f->resized_p)
- {
- redraw_frame (f);
- f->force_flush_display_p = 1;
- }
- clear_current_matrices (f);
+ redraw_frame (f);
+ else
+ clear_current_matrices (f);
changed_count++;
f->garbaged = 0;
f->resized_p = 0;
frame_garbaged = 0;
if (changed_count)
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 43;
}
}
pending input. */
ptrdiff_t count = SPECPDL_INDEX ();
specbind (Qredisplay_dont_pause, Qt);
- windows_or_buffers_changed = 1;
+ windows_or_buffers_changed = 44;
redisplay_internal ();
unbind_to (count, Qnil);
}
Can do with a display update of the echo area,
unless we displayed some mode lines. */
update_single_window (w, 1);
- FRAME_RIF (f)->flush_display (f);
+ flush_frame (f);
}
else
update_frame (f, 1, 1);
redisplay displays the minibuffer, so that the cursor will
be replaced with what the minibuffer wants. */
if (cursor_in_echo_area)
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 45;
}
}
else if (!EQ (mini_window, selected_window))
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 46;
/* Last displayed message is now the current message. */
echo_area_buffer[1] = echo_area_buffer[0];
&& UNCHANGED_MODIFIED < MODIFF);
}
-/* Nonzero if W's buffer was changed but not saved or Transient Mark mode
- is enabled and mark of W's buffer was changed since last W's update. */
+/* Nonzero if W's buffer was changed but not saved. */
static int
window_buffer_changed (struct window *w)
eassert (BUFFER_LIVE_P (b));
- return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
- || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
- != (w->region_showing != 0)));
+ return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
}
/* Nonzero if W has %c in its mode line and mode line should be updated. */
/* Prepare for redisplay by updating menu-bar item lists when
appropriate. This can call eval. */
-void
+static void
prepare_menu_bars (void)
{
int all_windows;
all_windows = (update_mode_lines
|| buffer_shared_and_changed ()
|| windows_or_buffers_changed);
+
+ if (FUNCTIONP (Vpre_redisplay_function))
+ safe_call1 (Vpre_redisplay_function, all_windows ? Qt : Qnil);
+
if (all_windows)
{
Lisp_Object tail, frame;
#ifdef HAVE_WINDOW_SYSTEM
-/* Where the mouse was last time we reported a mouse event. */
-
-struct frame *last_mouse_frame;
-
/* Tool-bar item index of the item on which a mouse button was pressed
or -1. */
}
}
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
/* Set F->desired_tool_bar_string to a Lisp string representing frame
F's desired tool-bar contents. F->tool_bar_items must have
return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
}
+#endif /* !USE_GTK && !HAVE_NS */
+
+#if defined USE_GTK || defined HAVE_NS
+EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
+#endif
DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
0, 1, 0,
If FRAME is nil or omitted, use the selected frame. */)
(Lisp_Object frame)
{
+ int nlines = 0;
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
struct frame *f = decode_any_frame (frame);
struct window *w;
- int nlines = 0;
if (WINDOWP (f->tool_bar_window)
&& (w = XWINDOW (f->tool_bar_window),
nlines = tool_bar_lines_needed (f, NULL);
}
}
-
+#endif
return make_number (nlines);
}
static int
redisplay_tool_bar (struct frame *f)
{
- struct window *w;
- struct it it;
- struct glyph_row *row;
-
#if defined (USE_GTK) || defined (HAVE_NS)
+
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
return 0;
-#endif
+
+#else /* !USE_GTK && !HAVE_NS */
+
+ struct window *w;
+ struct it it;
+ struct glyph_row *row;
/* If frame hasn't a tool-bar window or if it is zero-height, don't
do anything. This means you must start with tool-bar-lines
if (WINDOW_TOTAL_LINES (w) != old_height)
{
clear_glyph_matrix (w->desired_matrix);
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
return 1;
}
}
{
clear_glyph_matrix (w->desired_matrix);
f->n_tool_bar_rows = nrows;
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
return 1;
}
}
f->minimize_tool_bar_window_p = 0;
return 0;
+
+#endif /* USE_GTK || HAVE_NS */
}
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
/* Get information about the tool-bar item which is displayed in GLYPH
on frame F. Return in *PROP_IDX the index where tool-bar item
{
Lisp_Object window = f->tool_bar_window;
struct window *w = XWINDOW (window);
- Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
int hpos, vpos;
struct glyph *glyph;
clear_mouse_face (hlinfo);
/* Mouse is down, but on different tool-bar item? */
- mouse_down_p = (dpyinfo->grabbed
- && f == last_mouse_frame
- && FRAME_LIVE_P (f));
+ mouse_down_p = (x_mouse_grabbed (dpyinfo)
+ && f == dpyinfo->last_mouse_frame);
+
if (mouse_down_p
&& last_tool_bar_item != prop_idx)
return;
help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
}
+#endif /* !USE_GTK && !HAVE_NS */
+
#endif /* HAVE_WINDOW_SYSTEM */
int polling_stopped_here = 0;
Lisp_Object tail, frame;
- /* Non-zero means redisplay has to consider all windows on all
- frames. Zero means, only selected_window is considered. */
- int consider_all_windows_p;
+ /* True means redisplay has to consider all windows on all
+ frames. False, only selected_window is considered. */
+ bool consider_all_windows_p;
- /* Non-zero means redisplay has to redisplay the miniwindow. */
- int update_miniwindow_p = 0;
+ /* True means redisplay has to redisplay the miniwindow. */
+ bool update_miniwindow_p = false;
TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
last_glyphless_glyph_frame = NULL;
last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
- /* If new fonts have been loaded that make a glyph matrix adjustment
- necessary, do it. */
- if (fonts_changed_p)
- {
- adjust_glyphs (NULL);
- ++windows_or_buffers_changed;
- fonts_changed_p = 0;
- }
-
/* If face_change_count is non-zero, init_iterator will free all
realized faces, which includes the faces referenced from current
matrices. So, we can't reuse current matrices in this case. */
if (face_change_count)
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 47;
if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
&& FRAME_TTY (sf)->previous_frame != sf)
/* Since frames on a single ASCII terminal share the same
display area, displaying a different frame means redisplay
the whole thing. */
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 48;
SET_FRAME_GARBAGED (sf);
#ifndef DOS_NT
set_tty_color_mode (FRAME_TTY (sf), sf);
struct frame *f = XFRAME (frame);
if (FRAME_VISIBLE_P (f))
- ++number_of_visible_frames;
+ {
+ ++number_of_visible_frames;
+ /* Adjust matrices for visible frames only. */
+ if (f->fonts_changed)
+ {
+ adjust_frame_glyphs (f);
+ f->fonts_changed = 0;
+ }
+ /* If cursor type has been changed on the frame
+ other than selected, consider all frames. */
+ if (f != sf && f->cursor_type_changed)
+ update_mode_lines = 31;
+ }
clear_desired_matrices (f);
}
if (NILP (Vmemory_full))
prepare_menu_bars ();
- if (windows_or_buffers_changed)
- update_mode_lines++;
+ if (windows_or_buffers_changed && !update_mode_lines)
+ update_mode_lines = 32;
reconsider_clip_changes (w);
match_p = XBUFFER (w->contents) == current_buffer;
if (match_p)
{
- ptrdiff_t count1;
-
/* Detect case that we need to write or remove a star in the mode line. */
if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
{
w->update_mode_line = 1;
if (buffer_shared_and_changed ())
- update_mode_lines++;
+ update_mode_lines = 33;
}
- /* Avoid invocation of point motion hooks by `current_column' below. */
- count1 = SPECPDL_INDEX ();
- specbind (Qinhibit_point_motion_hooks, Qt);
-
if (mode_line_update_needed (w))
w->update_mode_line = 1;
-
- unbind_to (count1, Qnil);
}
consider_all_windows_p = (update_mode_lines
- || buffer_shared_and_changed ()
- || cursor_type_changed);
+ || buffer_shared_and_changed ());
/* If specs for an arrow have changed, do thorough redisplay
to ensure we remove any arrow that should no longer exist. */
if (overlay_arrows_changed_p ())
- consider_all_windows_p = windows_or_buffers_changed = 1;
+ {
+ consider_all_windows_p = true;
+ windows_or_buffers_changed = 49;
+ }
/* Normally the message* functions will have already displayed and
updated the echo area, but the frame may have been trashed, or
int window_height_changed_p = echo_area_display (0);
if (message_cleared_p)
- update_miniwindow_p = 1;
+ update_miniwindow_p = true;
must_finish = 1;
if (!display_last_displayed_message_p)
message_cleared_p = 0;
- if (fonts_changed_p)
- goto retry;
- else if (window_height_changed_p)
+ if (window_height_changed_p)
{
- consider_all_windows_p = 1;
- ++update_mode_lines;
- ++windows_or_buffers_changed;
+ consider_all_windows_p = true;
+ update_mode_lines = 34;
+ windows_or_buffers_changed = 50;
/* If window configuration was changed, frames may have been
marked garbaged. Clear them or we will experience
since only the current frame needs to be considered. This function
needs to be rewritten with two variables, consider_all_windows and
consider_all_frames. */
- consider_all_windows_p = 1;
- ++windows_or_buffers_changed;
- ++update_mode_lines;
+ consider_all_windows_p = true;
+ windows_or_buffers_changed = 51;
+ update_mode_lines = 35;
/* If window configuration was changed, frames may have been
marked garbaged. Clear them or we will experience
clear_garbaged_frames ();
}
- /* If showing the region, and mark has changed, we must redisplay
- the whole window. The assignment to this_line_start_pos prevents
- the optimization directly below this if-statement. */
- if (((!NILP (Vtransient_mark_mode)
- && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
- != (w->region_showing > 0))
- || (w->region_showing
- && w->region_showing
- != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
- CHARPOS (this_line_start_pos) = 0;
+ if (VECTORP (Vredisplay__all_windows_cause)
+ && windows_or_buffers_changed >= 0
+ && windows_or_buffers_changed < ASIZE (Vredisplay__all_windows_cause)
+ && INTEGERP (AREF (Vredisplay__all_windows_cause,
+ windows_or_buffers_changed)))
+ ASET (Vredisplay__all_windows_cause, windows_or_buffers_changed,
+ make_number (1 + XINT (AREF (Vredisplay__all_windows_cause,
+ windows_or_buffers_changed))));
+
+ if (VECTORP (Vredisplay__mode_lines_cause)
+ && update_mode_lines >= 0
+ && update_mode_lines < ASIZE (Vredisplay__mode_lines_cause)
+ && INTEGERP (AREF (Vredisplay__mode_lines_cause,
+ update_mode_lines)))
+ ASET (Vredisplay__mode_lines_cause, update_mode_lines,
+ make_number (1 + XINT (AREF (Vredisplay__mode_lines_cause,
+ update_mode_lines))));
/* Optimize the case that only the line containing the cursor in the
selected window has changed. Variables starting with this_ are
&& !current_buffer->prevent_redisplay_optimizations_p
&& FRAME_VISIBLE_P (XFRAME (w->frame))
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
+ && !XFRAME (w->frame)->cursor_type_changed
/* Make sure recorded data applies to current buffer, etc. */
&& this_line_buffer == current_buffer
&& match_p
}
/* If highlighting the region, or if the cursor is in the echo area,
then we can't just move the cursor. */
- else if (! (!NILP (Vtransient_mark_mode)
- && !NILP (BVAR (current_buffer, mark_active)))
- && (EQ (selected_window,
- BVAR (current_buffer, last_selected_window))
- || highlight_nonselected_windows)
- && !w->region_showing
- && NILP (Vshow_trailing_whitespace)
+ else if (NILP (Vshow_trailing_whitespace)
&& !cursor_in_echo_area)
{
struct it it;
}
CHARPOS (this_line_start_pos) = 0;
- consider_all_windows_p |= buffer_shared_and_changed ();
++clear_face_cache_count;
#ifdef HAVE_WINDOW_SYSTEM
++clear_image_cache_count;
&& !EQ (FRAME_TTY (f)->top_frame, frame))
continue;
+ retry_frame:
+
if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
{
/* Mark all the scroll bars to be removed; we'll redeem
if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
- /* If fonts changed, display again. */
- /* ??? rms: I suspect it is a mistake to jump all the way
- back to retry here. It should just retry this frame. */
- if (fonts_changed_p)
- goto retry;
-
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
{
+ /* If fonts changed on visible frame, display again. */
+ if (f->fonts_changed)
+ {
+ adjust_frame_glyphs (f);
+ f->fonts_changed = 0;
+ goto retry_frame;
+ }
+
/* See if we have to hscroll. */
if (!f->already_hscrolled_p)
{
f->already_hscrolled_p = 1;
if (hscroll_windows (f->root_window))
- goto retry;
+ goto retry_frame;
}
/* Prevent various kinds of signals during display
unrequest_sigio ();
STOP_POLLING;
- /* Update the display. */
- set_window_update_flags (XWINDOW (f->root_window), 1);
+ /* Mark windows on frame F to update. If we decide to
+ update all frames but windows_or_buffers_changed is
+ zero, we assume that only the windows that shows
+ current buffer should be really updated. */
+ set_window_update_flags
+ (XWINDOW (f->root_window),
+ (windows_or_buffers_changed ? NULL : current_buffer), 1);
pending |= update_frame (f, 0, 0);
+ f->cursor_type_changed = 0;
f->updated_p = 1;
}
}
update:
/* If fonts changed, display again. */
- if (fonts_changed_p)
+ if (sf->fonts_changed)
goto retry;
/* Prevent various kinds of signals during display update.
XWINDOW (selected_window)->must_be_updated_p = 1;
pending = update_frame (sf, 0, 0);
+ sf->cursor_type_changed = 0;
}
/* We may have called echo_area_display at the top of this
{
XWINDOW (mini_window)->must_be_updated_p = 1;
pending |= update_frame (mini_frame, 0, 0);
+ mini_frame->cursor_type_changed = 0;
if (!pending && hscroll_windows (mini_window))
goto retry;
}
matrices of some windows are not valid. */
if (!WINDOW_FULL_WIDTH_P (w)
&& !FRAME_WINDOW_P (XFRAME (w->frame)))
- update_mode_lines = 1;
+ update_mode_lines = 36;
}
else
{
update_mode_lines = 0;
windows_or_buffers_changed = 0;
- cursor_type_changed = 0;
}
/* Start SIGIO interrupts coming again. Having them off during the
}
if (new_count != number_of_visible_frames)
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 52;
}
/* Change frame size now if a change is pending. */
else
redisplay_internal ();
- if (FRAME_RIF (SELECTED_FRAME ()) != NULL
- && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
- FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
+ flush_frame (SELECTED_FRAME ());
}
cases. */
&& !update_mode_lines
&& !windows_or_buffers_changed
- && !cursor_type_changed
- /* Can't use this case if highlighting a region. When a
- region exists, cursor movement has to do more than just
- set the cursor. */
- && markpos_of_region () < 0
- && !w->region_showing
+ && !f->cursor_type_changed
&& NILP (Vshow_trailing_whitespace)
/* This code is not used for mini-buffer for the sake of the case
of redisplaying to replace an echo area message; since in
/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
selected_window is redisplayed.
- We can return without actually redisplaying the window if
- fonts_changed_p. In that case, redisplay_internal will
- retry. */
+ We can return without actually redisplaying the window if fonts has been
+ changed on window's frame. In that case, redisplay_internal will retry. */
static void
redisplay_window (Lisp_Object window, int just_this_one_p)
}
else if ((w != XWINDOW (minibuf_window)
|| minibuf_level == 0)
- /* When buffer is nonempty, redisplay window normally. */
+ /* When buffer is nonempty, redisplay window normally. */
&& BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
/* Quail displays non-mini buffers in minibuffer window.
In that case, redisplay the window normally. */
Move it back to a fully-visible line. */
new_vpos = window_box_height (w);
}
- else if (w->cursor.vpos >=0)
+ else if (w->cursor.vpos >= 0)
{
/* Some people insist on not letting point enter the scroll
margin, even though this part handles windows that didn't
/* If we are highlighting the region, then we just changed
the region, so redisplay to show it. */
- if (markpos_of_region () >= 0)
+ /* FIXME: We need to (re)run pre-redisplay-function! */
+ /* if (markpos_of_region () >= 0)
{
clear_glyph_matrix (w->desired_matrix);
if (!try_window (window, startp, 0))
goto need_larger_matrices;
}
+ */
}
#ifdef GLYPH_DEBUG
debug_method_add (w, "try_window_id %d", tem);
#endif
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
if (tem > 0)
goto done;
IF_DEBUG (debug_method_add (w, "1"));
if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
/* -1 means we need to scroll.
- 0 means we need new matrices, but fonts_changed_p
+ 0 means we need new matrices, but fonts_changed
is set in that case, so we will detect it below. */
goto try_to_scroll;
}
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
if (w->cursor.vpos >= 0)
/* Redisplay the window. */
if (!current_matrix_up_to_date_p
|| windows_or_buffers_changed
- || cursor_type_changed
+ || f->cursor_type_changed
/* Don't use try_window_reusing_current_matrix in this case
because it can have changed the buffer. */
|| !NILP (Vwindow_scroll_functions)
/* If new fonts have been loaded (due to fontsets), give up. We
have to start a new redisplay since we need to re-adjust glyph
matrices. */
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
/* If cursor did not appear assume that the middle of the window is
if (WINDOW_WANTS_MODELINE_P (w)
&& CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
{
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
w->mode_line_height = -1;
MATRIX_MODE_LINE_ROW (w->current_matrix)->height
= DESIRED_MODE_LINE_HEIGHT (w);
if (WINDOW_WANTS_HEADER_LINE_P (w)
&& CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
{
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
w->header_line_height = -1;
MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
= DESIRED_HEADER_LINE_HEIGHT (w);
}
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
}
}
#endif /* HAVE_WINDOW_SYSTEM */
- /* We go to this label, with fonts_changed_p set,
- if it is necessary to try again using larger glyph matrices.
+ /* We go to this label, with fonts_changed set, if it is
+ necessary to try again using larger glyph matrices.
We have to redeem the scroll bar even in this case,
because the loop in redisplay_internal expects that. */
need_larger_matrices:
{
if (display_line (&it))
last_text_row = it.glyph_row - 1;
- if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
+ if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
return 0;
}
/* Don't try to reuse the display if windows have been split
or such. */
|| windows_or_buffers_changed
- || cursor_type_changed)
+ || f->cursor_type_changed)
return 0;
- /* Can't do this if region may have changed. */
- if (markpos_of_region () >= 0
- || w->region_showing
- || !NILP (Vshow_trailing_whitespace))
+ /* Can't do this if showing trailing whitespace. */
+ if (!NILP (Vshow_trailing_whitespace))
return 0;
/* If top-line visibility has changed, give up. */
w->cursor.vpos = -1;
last_text_row = last_reused_text_row = NULL;
- while (it.current_y < it.last_visible_y
- && !fonts_changed_p)
+ while (it.current_y < it.last_visible_y && !f->fonts_changed)
{
/* If we have reached into the characters in the START row,
that means the line boundaries have changed. So we
if (pt_row == NULL)
w->cursor.vpos = -1;
last_text_row = NULL;
- while (it.current_y < it.last_visible_y && !fonts_changed_p)
+ while (it.current_y < it.last_visible_y && !f->fonts_changed)
if (display_line (&it))
last_text_row = it.glyph_row - 1;
GIVE_UP (1);
/* This flag is used to prevent redisplay optimizations. */
- if (windows_or_buffers_changed || cursor_type_changed)
+ if (windows_or_buffers_changed || f->cursor_type_changed)
GIVE_UP (2);
/* Verify that narrowing has not changed.
if (!w->window_end_valid)
GIVE_UP (8);
- /* Can't use this if highlighting a region because a cursor movement
- will do more than just set the cursor. */
- if (markpos_of_region () >= 0)
- GIVE_UP (9);
-
/* Likewise if highlighting trailing whitespace. */
if (!NILP (Vshow_trailing_whitespace))
GIVE_UP (11);
- /* Likewise if showing a region. */
- if (w->region_showing)
- GIVE_UP (10);
-
/* Can't use this if overlay arrow position and/or string have
changed. */
if (overlay_arrows_changed_p ())
row = row_containing_pos (w, PT, r0, NULL, 0);
if (row)
set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
- else
- emacs_abort ();
return 1;
}
}
row = row_containing_pos (w, PT, r0, NULL, 0);
if (row)
set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
- else
- emacs_abort ();
return 2;
}
}
last_text_row = NULL;
overlay_arrow_seen = 0;
while (it.current_y < it.last_visible_y
- && !fonts_changed_p
+ && !f->fonts_changed
&& (first_unchanged_at_end_row == NULL
|| IT_CHARPOS (it) < stop_pos))
{
last_text_row = it.glyph_row - 1;
}
- if (fonts_changed_p)
+ if (f->fonts_changed)
return -1;
/* Display the rest of the lines at the window end. */
it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
- while (it.current_y < it.last_visible_y
- && !fonts_changed_p)
+ while (it.current_y < it.last_visible_y && !f->fonts_changed)
{
/* Is it always sure that the display agrees with lines in
the current matrix? I don't think so, so we mark rows
doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
GLYPH 0 means don't dump glyphs.
GLYPH 1 means dump glyphs in short form.
-GLYPH > 1 or omitted means dump glyphs in long form. */)
+GLYPH > 1 or omitted means dump glyphs in long form.
+
+If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
+do nothing. */)
(Lisp_Object row, Lisp_Object glyphs)
{
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
struct frame *sf = SELECTED_FRAME ();
struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
EMACS_INT vpos;
if (vpos >= 0 && vpos < m->nrows)
dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
+#endif
return Qnil;
}
it->len = 1;
/* If the default face was remapped, be sure to use the
- remapped face for the appended newline. */
+ remapped face for the appended newline. */
if (default_face_p)
it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
else if (it->face_before_selective_p)
&& MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
&& face->box == FACE_NO_BOX
&& face->background == FRAME_BACKGROUND_PIXEL (f)
+#ifdef HAVE_WINDOW_SYSTEM
&& !face->stipple
+#endif
&& !it->glyph_row->reversed_p)
return;
>= it->w->desired_matrix->nrows)
{
it->w->nrows_scale_factor++;
- fonts_changed_p = 1;
+ it->f->fonts_changed = 1;
return 0;
}
- /* Is IT->w showing the region? */
- it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
-
/* Clear the result glyph row and enable it. */
prepare_desired_row (row);
compute_line_metrics (&it);
}
+#ifdef HAVE_MENUS
+/* Deep copy of a glyph row, including the glyphs. */
+static void
+deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
+{
+ struct glyph *pointers[1 + LAST_AREA];
+ int to_used = to->used[TEXT_AREA];
+
+ /* Save glyph pointers of TO. */
+ memcpy (pointers, to->glyphs, sizeof to->glyphs);
+
+ /* Do a structure assignment. */
+ *to = *from;
+ /* Restore original glyph pointers of TO. */
+ memcpy (to->glyphs, pointers, sizeof to->glyphs);
+
+ /* Copy the glyphs. */
+ memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
+ min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
+
+ /* If we filled only part of the TO row, fill the rest with
+ space_glyph (which will display as empty space). */
+ if (to_used > from->used[TEXT_AREA])
+ fill_up_frame_row_with_spaces (to, to_used);
+}
+
+/* Display one menu item on a TTY, by overwriting the glyphs in the
+ frame F's desired glyph matrix with glyphs produced from the menu
+ item text. Called from term.c to display TTY drop-down menus one
+ item at a time.
+
+ ITEM_TEXT is the menu item text as a C string.
+
+ FACE_ID is the face ID to be used for this menu item. FACE_ID
+ could specify one of 3 faces: a face for an enabled item, a face
+ for a disabled item, or a face for a selected item.
+
+ X and Y are coordinates of the first glyph in the frame's desired
+ matrix to be overwritten by the menu item. Since this is a TTY, Y
+ is the zero-based number of the glyph row and X is the zero-based
+ glyph number in the row, starting from left, where to start
+ displaying the item.
+
+ SUBMENU non-zero means this menu item drops down a submenu, which
+ should be indicated by displaying a proper visual cue after the
+ item text. */
+
+void
+display_tty_menu_item (const char *item_text, int width, int face_id,
+ int x, int y, int submenu)
+{
+ struct it it;
+ struct frame *f = SELECTED_FRAME ();
+ struct window *w = XWINDOW (f->selected_window);
+ int saved_used, saved_truncated, saved_width, saved_reversed;
+ struct glyph_row *row;
+ size_t item_len = strlen (item_text);
+
+ eassert (FRAME_TERMCAP_P (f));
+
+ /* Don't write beyond the matrix's last row. This can happen for
+ TTY screens that are not high enough to show the entire menu.
+ (This is actually a bit of defensive programming, as
+ tty_menu_display already limits the number of menu items to one
+ less than the number of screen lines.) */
+ if (y >= f->desired_matrix->nrows)
+ return;
+
+ init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
+ it.first_visible_x = 0;
+ it.last_visible_x = FRAME_COLS (f) - 1;
+ row = it.glyph_row;
+ /* Start with the row contents from the current matrix. */
+ deep_copy_glyph_row (row, f->current_matrix->rows + y);
+ saved_width = row->full_width_p;
+ row->full_width_p = 1;
+ saved_reversed = row->reversed_p;
+ row->reversed_p = 0;
+ row->enabled_p = 1;
+
+ /* Arrange for the menu item glyphs to start at (X,Y) and have the
+ desired face. */
+ eassert (x < f->desired_matrix->matrix_w);
+ it.current_x = it.hpos = x;
+ it.current_y = it.vpos = y;
+ saved_used = row->used[TEXT_AREA];
+ saved_truncated = row->truncated_on_right_p;
+ row->used[TEXT_AREA] = x;
+ it.face_id = face_id;
+ it.line_wrap = TRUNCATE;
+
+ /* FIXME: This should be controlled by a user option. See the
+ comments in redisplay_tool_bar and display_mode_line about this.
+ Also, if paragraph_embedding could ever be R2L, changes will be
+ needed to avoid shifting to the right the row characters in
+ term.c:append_glyph. */
+ it.paragraph_embedding = L2R;
+
+ /* Pad with a space on the left. */
+ display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
+ width--;
+ /* Display the menu item, pad with spaces to WIDTH. */
+ if (submenu)
+ {
+ display_string (item_text, Qnil, Qnil, 0, 0, &it,
+ item_len, 0, FRAME_COLS (f) - 1, -1);
+ width -= item_len;
+ /* Indicate with " >" that there's a submenu. */
+ display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
+ FRAME_COLS (f) - 1, -1);
+ }
+ else
+ display_string (item_text, Qnil, Qnil, 0, 0, &it,
+ width, 0, FRAME_COLS (f) - 1, -1);
+
+ row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
+ row->truncated_on_right_p = saved_truncated;
+ row->hash = row_hash (row);
+ row->full_width_p = saved_width;
+ row->reversed_p = saved_reversed;
+}
+#endif /* HAVE_MENUS */
\f
/***********************************************************************
Mode Line
it->face_id
= face_at_string_position (it->w, face_string, face_string_pos,
- 0, it->region_beg_charpos,
- it->region_end_charpos,
- &endptr, it->base_face_id, 0);
+ 0, &endptr, it->base_face_id, 0);
face = FACE_FROM_ID (it->f, it->face_id);
it->face_box_p = face->box != FACE_NO_BOX;
}
#define IT_EXPAND_MATRIX_WIDTH(it, area) \
{ \
- if (!fonts_changed_p \
+ if (!it->f->fonts_changed \
&& (it->glyph_row->glyphs[area] \
< it->glyph_row->glyphs[area + 1])) \
{ \
it->w->ncols_scale_factor++; \
- fonts_changed_p = 1; \
+ it->f->fonts_changed = 1; \
} \
}
base_height = it->ascent + it->descent;
base_width = font->average_width;
- /* Get a face ID for the glyph by utilizing a cache (the same way as
- done for `escape-glyph' in get_next_display_element). */
- if (it->f == last_glyphless_glyph_frame
- && it->face_id == last_glyphless_glyph_face_id)
- {
- face_id = last_glyphless_glyph_merged_face_id;
- }
- else
- {
- /* Merge the `glyphless-char' face into the current face. */
- face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
- last_glyphless_glyph_frame = it->f;
- last_glyphless_glyph_face_id = it->face_id;
- last_glyphless_glyph_merged_face_id = face_id;
- }
+ face_id = merge_glyphless_glyph_face (it);
if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
{
lower_yoff = descent - 2 - metrics_lower.descent;
upper_yoff = (lower_yoff - metrics_lower.ascent - 1
- metrics_upper.descent);
- /* Don't make the height shorter than the base height. */
+ /* Don't make the height shorter than the base height. */
if (height > base_height)
{
it->ascent = ascent;
struct face *face = FACE_FROM_ID (it->f, it->face_id);
struct font *font = face->font;
struct font_metrics *pcm = NULL;
- int boff; /* baseline offset */
+ int boff; /* Baseline offset. */
if (font == NULL)
{
/* When no suitable font is found, display this character by
the method specified in the first extra slot of
Vglyphless_char_display. */
- Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
+ Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
- eassert (it->what == IT_GLYPHLESS);
+ eassert (it->what == IT_GLYPHLESS);
produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
goto done;
}
{
/* A newline has no width, but we need the height of the
line. But if previous part of the line sets a height,
- don't increase that height */
+ don't increase that height. */
Lisp_Object height;
Lisp_Object total_height = Qnil;
it->nglyphs = 0;
height = get_it_property (it, Qline_height);
- /* Split (line-height total-height) list */
+ /* Split (line-height total-height) list. */
if (CONSP (height)
&& CONSP (XCDR (height))
&& NILP (XCDR (XCDR (height))))
FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
/* Make sure the cursor gets redrawn. */
- cursor_type_changed = 1;
+ f->cursor_type_changed = 1;
}
/* Detect a nonselected window or nonselected frame. */
else if (w != XWINDOW (f->selected_window)
- || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
+ || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
{
*active_cursor = 0;
}
-/* EXPORT:
- Erase the image of a cursor of window W from the screen. */
+/* Erase the image of a cursor of window W from the screen. */
+#ifndef HAVE_NTGUI
+static
+#endif
void
erase_phys_cursor (struct window *w)
{
/* Change the mouse cursor. */
if (FRAME_WINDOW_P (f))
{
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
if (draw == DRAW_NORMAL_TEXT
&& !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
- else if (draw == DRAW_MOUSE_FACE)
+ else
+#endif
+ if (draw == DRAW_MOUSE_FACE)
FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
else
FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
hlinfo->mouse_face_window = window;
hlinfo->mouse_face_face_id
- = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
+ = face_at_buffer_position (w, mouse_charpos, &ignore,
mouse_charpos + 1,
!hlinfo->mouse_face_hidden, -1);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
#endif /* not used */
/* Find the positions of the first and the last glyphs in window W's
- current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
+ current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
(assumed to be a string), and return in HLINFO's mouse_face_*
members the pixel and column/row coordinates of those glyphs. */
int found = 0;
/* Find the glyph row with at least one position in the range
- [STARTPOS..ENDPOS], and the first glyph in that row whose
+ [STARTPOS..ENDPOS), and the first glyph in that row whose
position belongs to that range. */
for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
r->enabled_p && r->y < yb;
e = g + r->used[TEXT_AREA];
for (gx = r->x; g < e; gx += g->pixel_width, ++g)
if (EQ (g->object, object)
- && startpos <= g->charpos && g->charpos <= endpos)
+ && startpos <= g->charpos && g->charpos < endpos)
{
hlinfo->mouse_face_beg_row
= MATRIX_ROW_VPOS (r, w->current_matrix);
g = e + r->used[TEXT_AREA];
for ( ; g > e; --g)
if (EQ ((g-1)->object, object)
- && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
+ && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
{
hlinfo->mouse_face_beg_row
= MATRIX_ROW_VPOS (r, w->current_matrix);
found = 0;
for ( ; g < e; ++g)
if (EQ (g->object, object)
- && startpos <= g->charpos && g->charpos <= endpos)
+ && startpos <= g->charpos && g->charpos < endpos)
{
found = 1;
break;
e = g + r->used[TEXT_AREA];
for ( ; e > g; --e)
if (EQ ((e-1)->object, object)
- && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
+ && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
break;
hlinfo->mouse_face_end_col = e - g;
for (gx = r->x ; e < g; ++e)
{
if (EQ (e->object, object)
- && startpos <= e->charpos && e->charpos <= endpos)
+ && startpos <= e->charpos && e->charpos < endpos)
break;
gx += e->pixel_width;
}
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
#ifdef HAVE_X_WINDOWS
else if (EQ (pointer, intern ("vdrag")))
- cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
+ cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
#endif
else if (EQ (pointer, intern ("hourglass")))
cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
/* Change the mouse pointer according to what is under it. */
if (FRAME_WINDOW_P (f))
{
- dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
if (STRINGP (string))
{
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
}
else
/* Default mode-line pointer. */
- cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
+ cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
}
#endif
}
hlinfo->mouse_face_face_id = face_at_string_position (w, string,
charpos,
- 0, 0, 0,
- &ignore,
+ 0, &ignore,
glyph->face_id,
1);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
w = XWINDOW (window);
frame_to_window_pixel_xy (w, &x, &y);
-#ifdef HAVE_WINDOW_SYSTEM
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
/* Handle tool-bar window differently since it doesn't display a
buffer. */
if (EQ (window, f->tool_bar_window))
if (NILP (s))
s = make_number (0);
if (NILP (e))
- e = make_number (SCHARS (object) - 1);
+ e = make_number (SCHARS (object));
mouse_face_from_string_pos (w, hlinfo, object,
XINT (s), XINT (e));
hlinfo->mouse_face_past_end = 0;
hlinfo->mouse_face_window = window;
hlinfo->mouse_face_face_id
- = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
+ = face_at_string_position (w, object, pos, 0, &ignore,
glyph->face_id, 1);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
cursor = No_Cursor;
the first row visible in a window does not
necessarily display the character whose position
is the smallest. */
- Lisp_Object lim1 =
- NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
+ Lisp_Object lim1
+ = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
? Fmarker_position (w->start)
: Qnil;
- Lisp_Object lim2 =
- NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
- ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
+ Lisp_Object lim2
+ = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
+ ? make_number (BUF_Z (XBUFFER (buffer))
+ - w->window_end_pos)
: Qnil;
if (NILP (overlay))
TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
if (WINDOWP (f->tool_bar_window))
mouse_face_overwritten_p
|= expose_window (XWINDOW (f->tool_bar_window), &r);
+#endif
#ifdef HAVE_X_WINDOWS
#ifndef MSDOS
DEFSYM (Qthin_space, "thin-space");
DEFSYM (Qzero_width, "zero-width");
+ DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
+ doc: /* Function run just before redisplay.
+It is called with one argument, which is the set of windows that are to
+be redisplayed. This set can be nil (meaning, only the selected window),
+or t (meaning all windows). */);
+ Vpre_redisplay_function = intern ("ignore");
+
DEFSYM (Qglyphless_char_display, "glyphless-char-display");
Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
The char-table has one extra slot to control the display of a character for
which no font is found. This slot only takes effect on graphical terminals.
Its value should be an ASCII acronym string, `hex-code', `empty-box', or
-`thin-space'. The default is `empty-box'. */);
+`thin-space'. The default is `empty-box'.
+
+If a character has a non-nil entry in an active display table, the
+display table takes effect; in this case, Emacs does not consult
+`glyphless-char-display' at all. */);
Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
Qempty_box);
DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
Vdebug_on_message = Qnil;
+
+ DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
+ doc: /* */);
+ Vredisplay__all_windows_cause
+ = Fmake_vector (make_number (100), make_number (0));
+
+ DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
+ doc: /* */);
+ Vredisplay__mode_lines_cause
+ = Fmake_vector (make_number (100), make_number (0));
}