static Lisp_Object Qmargin, Qpointer;
static Lisp_Object Qline_height;
+/* These setters are used only in this file, so they can be private. */
+static inline void
+wset_base_line_number (struct window *w, Lisp_Object val)
+{
+ w->base_line_number = val;
+}
+static inline void
+wset_base_line_pos (struct window *w, Lisp_Object val)
+{
+ w->base_line_pos = val;
+}
+static inline void
+wset_column_number_displayed (struct window *w, Lisp_Object val)
+{
+ w->column_number_displayed = val;
+}
+static inline void
+wset_region_showing (struct window *w, Lisp_Object val)
+{
+ w->region_showing = val;
+}
+
#ifdef HAVE_WINDOW_SYSTEM
/* Test if overflow newline into fringe. Called with iterator IT
static struct text_pos display_prop_end (struct it *, Lisp_Object,
struct text_pos);
static int compute_window_start_on_continuation_line (struct window *);
-static Lisp_Object safe_eval_handler (Lisp_Object);
static void insert_left_trunc_glyphs (struct it *);
static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
Lisp_Object);
#endif /* HAVE_WINDOW_SYSTEM */
+static void produce_special_glyphs (struct it *, enum display_element_type);
static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
static int coords_in_mouse_face_p (struct window *, int, int);
return spec;
}
+
+/* Limit insanely large values of W->hscroll on frame F to the largest
+ value that will still prevent first_visible_x and last_visible_x of
+ 'struct it' from overflowing an int. */
+static inline int
+window_hscroll_limited (struct window *w, struct frame *f)
+{
+ ptrdiff_t window_hscroll = w->hscroll;
+ int window_text_width = window_box_width (w, TEXT_AREA);
+ int colwidth = FRAME_COLUMN_WIDTH (f);
+
+ if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
+ window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
+
+ return window_hscroll;
+}
+
/* Return 1 if position CHARPOS is visible in window W.
CHARPOS < 0 means return info about WINDOW_END position.
If visible, set *X and *Y to pixel coordinates of top left corner.
if (WINDOW_WANTS_HEADER_LINE_P (w))
current_header_line_height
= display_mode_line (w, HEADER_LINE_FACE_ID,
- BVAR (current_buffer, header_line_format));
+ BVAR (current_buffer, header_line_format));
start_display (&it, w, top);
move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
current_header_line_height = current_mode_line_height = -1;
if (visible_p && w->hscroll > 0)
- *x -= w->hscroll * WINDOW_FRAME_COLUMN_WIDTH (w);
+ *x -=
+ window_hscroll_limited (w, WINDOW_XFRAME (w))
+ * WINDOW_FRAME_COLUMN_WIDTH (w);
#if 0
/* Debugging code. */
/* Error handler for safe_eval and safe_call. */
static Lisp_Object
-safe_eval_handler (Lisp_Object arg)
+safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
{
- add_to_log ("Error during redisplay: %S", arg, Qnil);
+ add_to_log ("Error during redisplay: %S signalled %S",
+ Flist (nargs, args), arg);
return Qnil;
}
-
-/* Evaluate SEXPR and return the result, or nil if something went
+/* Call function FUNC with the rest of NARGS - 1 arguments
+ following. Return the result, or nil if something went
wrong. Prevent redisplay during the evaluation. */
-/* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
- Return the result, or nil if something went wrong. Prevent
- redisplay during the evaluation. */
-
Lisp_Object
-safe_call (ptrdiff_t nargs, Lisp_Object *args)
+safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
{
Lisp_Object val;
val = Qnil;
else
{
+ va_list ap;
+ ptrdiff_t i;
ptrdiff_t count = SPECPDL_INDEX ();
struct gcpro gcpro1;
+ Lisp_Object *args = alloca (nargs * word_size);
+
+ args[0] = func;
+ va_start (ap, func);
+ for (i = 1; i < nargs; i++)
+ args[i] = va_arg (ap, Lisp_Object);
+ va_end (ap);
GCPRO1 (args[0]);
gcpro1.nvars = nargs;
Lisp_Object
safe_call1 (Lisp_Object fn, Lisp_Object arg)
{
- Lisp_Object args[2];
- args[0] = fn;
- args[1] = arg;
- return safe_call (2, args);
+ return safe_call (2, fn, arg);
}
static Lisp_Object Qeval;
return safe_call1 (Qeval, sexpr);
}
-/* Call function FN with one argument ARG.
+/* Call function FN with two arguments ARG1 and ARG2.
Return the result, or nil if something went wrong. */
Lisp_Object
safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
{
- Lisp_Object args[3];
- args[0] = fn;
- args[1] = arg1;
- args[2] = arg2;
- return safe_call (3, args);
+ return safe_call (3, fn, arg1, arg2);
}
/* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
if (! NILP (Vface_remapping_alist))
- remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
+ remapped_base_face_id
+ = lookup_basic_face (XFRAME (w->frame), base_face_id);
/* Use one of the mode line rows of W's desired matrix if
appropriate. */
is invisible. >0 means lines indented more than this value are
invisible. */
it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
- ? clip_to_bounds (-1, XINT (BVAR (current_buffer,
- selective_display)),
- PTRDIFF_MAX)
+ ? (clip_to_bounds
+ (-1, XINT (BVAR (current_buffer, selective_display)),
+ PTRDIFF_MAX))
: (!NILP (BVAR (current_buffer, selective_display))
? -1 : 0));
it->selective_display_ellipsis_p
it->line_wrap = TRUNCATE;
/* Get dimensions of truncation and continuation glyphs. These are
- displayed as fringe bitmaps under X, so we don't need them for such
- frames. */
- if (!FRAME_WINDOW_P (it->f))
+ displayed as fringe bitmaps under X, but we need them for such
+ frames when the fringes are turned off. But leave the dimensions
+ zero for tooltip frames, as these glyphs look ugly there and also
+ sabotage calculations of tooltip dimensions in x-show-tip. */
+#ifdef HAVE_WINDOW_SYSTEM
+ if (!(FRAME_WINDOW_P (it->f)
+ && FRAMEP (tip_frame)
+ && it->f == XFRAME (tip_frame)))
+#endif
{
if (it->line_wrap == TRUNCATE)
{
produce_special_glyphs (it, IT_CONTINUATION);
it->continuation_pixel_width = it->pixel_width;
}
-
- /* Reset these values to zero because the produce_special_glyphs
- above has changed them. */
- it->pixel_width = it->ascent = it->descent = 0;
- it->phys_ascent = it->phys_descent = 0;
}
+ /* Reset these values to zero because the produce_special_glyphs
+ above has changed them. */
+ it->pixel_width = it->ascent = it->descent = 0;
+ it->phys_ascent = it->phys_descent = 0;
+
/* Set this after getting the dimensions of truncation and
continuation glyphs, so that we don't produce glyphs when calling
produce_special_glyphs, above. */
}
else
{
- it->first_visible_x
- = it->w->hscroll * FRAME_COLUMN_WIDTH (it->f);
+ it->first_visible_x =
+ window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
it->last_visible_x = (it->first_visible_x
+ window_box_width (w, TEXT_AREA));
- /* If we truncate lines, leave room for the truncator glyph(s) at
+ /* If we truncate lines, leave room for the truncation glyph(s) at
the right margin. Otherwise, leave room for the continuation
- glyph(s). Truncation and continuation glyphs are not inserted
- for window-based redisplay. */
- if (!FRAME_WINDOW_P (it->f))
+ glyph(s). Done only if the window has no fringes. Since we
+ don't know at this point whether there will be any R2L lines in
+ the window, we reserve space for truncation/continuation glyphs
+ even if only one of the fringes is absent. */
+ if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
+ || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
{
if (it->line_wrap == TRUNCATE)
it->last_visible_x -= it->truncation_pixel_width;
/* Or it fits exactly and we're on a window
system frame. */
|| (new_x == it->last_visible_x
- && FRAME_WINDOW_P (it->f))))
+ && FRAME_WINDOW_P (it->f)
+ && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
{
if ((it->current.dpvec_index >= 0
|| it->current.overlay_string_index >= 0)
interval if there isn't such an interval. */
position = make_number (charpos);
iv = validate_interval_range (object, &position, &position, 0);
- if (!NULL_INTERVAL_P (iv))
+ if (iv)
{
Lisp_Object values_here[LAST_PROP_IDX];
struct props *p;
/* Look for an interval following iv that has different
properties. */
for (next_iv = next_interval (iv);
- (!NULL_INTERVAL_P (next_iv)
+ (next_iv
&& (NILP (limit)
|| XFASTINT (limit) > next_iv->position));
next_iv = next_interval (next_iv))
break;
}
- if (!NULL_INTERVAL_P (next_iv))
+ if (next_iv)
{
if (INTEGERP (limit)
&& next_iv->position >= XFASTINT (limit))
ptrdiff_t size = 20;
ptrdiff_t n = 0, i, j;
int invis_p;
- struct overlay_entry *entries
- = (struct overlay_entry *) alloca (size * sizeof *entries);
+ struct overlay_entry *entries = alloca (size * sizeof *entries);
USE_SAFE_ALLOCA;
if (charpos <= 0)
/* Since we are *trying* to run these functions, don't try to run
them again, even if they get an error. */
- it->w->redisplay_end_trigger = Qnil;
+ wset_redisplay_end_trigger (it->w, Qnil);
Frun_hook_with_args (3, args);
/* Notice if it changed the face of the character we are on. */
/* Or it fits exactly and we're on a window
system frame. */
|| (new_x == it->last_visible_x
- && FRAME_WINDOW_P (it->f))))
+ && FRAME_WINDOW_P (it->f)
+ && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
{
if (/* IT->hpos == 0 means the very first glyph
doesn't fit on the line, e.g. a wide image. */
/* On graphical terminals, newlines may
"overflow" into the fringe if
overflow-newline-into-fringe is non-nil.
- On text terminals, newlines may overflow
- into the last glyph on the display
- line.*/
+ On text terminals, and on graphical
+ terminals with no right margin, newlines
+ may overflow into the last glyph on the
+ display line.*/
if (!FRAME_WINDOW_P (it->f)
+ || ((it->bidi_p
+ && it->bidi_it.paragraph_dir == R2L)
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
|| IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
if (!get_next_display_element (it))
&& it->current_x >= it->last_visible_x)
{
if (!FRAME_WINDOW_P (it->f)
+ || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
|| IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
int at_eob_p = 0;
msg = Fformat (3, args);
len = SBYTES (msg) + 1;
- SAFE_ALLOCA (buffer, char *, len);
+ buffer = SAFE_ALLOCA (len);
memcpy (buffer, SDATA (msg), len);
message_dolog (buffer, len - 1, 1, 0);
old_deactivate_mark = Vdeactivate_mark;
oldbuf = current_buffer;
Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
- BVAR (current_buffer, undo_list) = Qt;
+ BSET (current_buffer, undo_list, Qt);
oldpoint = message_dolog_marker1;
set_marker_restricted (oldpoint, make_number (PT), Qnil);
message_log_maybe_newline ();
if (STRINGP (m))
{
- char *buffer;
USE_SAFE_ALLOCA;
-
- SAFE_ALLOCA (buffer, char *, nbytes);
+ char *buffer = SAFE_ALLOCA (nbytes);
memcpy (buffer, SDATA (m), nbytes);
message_dolog (buffer, nbytes, 1, multibyte);
SAFE_FREE ();
int j;
old_buffer = echo_buffer[i];
- sprintf (name, " *Echo Area %d*", i);
- echo_buffer[i] = Fget_buffer_create (build_string (name));
- BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
+ echo_buffer[i] = Fget_buffer_create
+ (make_formatted_string (name, " *Echo Area %d*", i));
+ BSET (XBUFFER (echo_buffer[i]), truncate_lines, Qnil);
/* to force word wrap in echo area -
it was decided to postpone this*/
/* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
set_buffer_internal_1 (XBUFFER (buffer));
if (w)
{
- w->buffer = buffer;
+ wset_buffer (w, buffer);
set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
}
- BVAR (current_buffer, undo_list) = Qt;
- BVAR (current_buffer, read_only) = Qnil;
+ BSET (current_buffer, undo_list, Qt);
+ BSET (current_buffer, read_only, Qnil);
specbind (Qinhibit_read_only, Qt);
specbind (Qinhibit_modification_hooks, Qt);
charpos = AREF (vector, 5);
bytepos = AREF (vector, 6);
- w->buffer = buffer;
+ wset_buffer (w, buffer);
set_marker_both (w->pointm, buffer,
XFASTINT (charpos), XFASTINT (bytepos));
}
/* Switch to that buffer and clear it. */
set_buffer_internal (XBUFFER (echo_area_buffer[0]));
- BVAR (current_buffer, truncate_lines) = Qnil;
+ BSET (current_buffer, truncate_lines, Qnil);
if (Z > BEG)
{
{
/* Someone switched buffers between print requests. */
set_buffer_internal (XBUFFER (echo_area_buffer[0]));
- BVAR (current_buffer, truncate_lines) = Qnil;
+ BSET (current_buffer, truncate_lines, Qnil);
}
}
}
!= !NILP (BVAR (current_buffer, enable_multibyte_characters)))
Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
- BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
+ BSET (current_buffer, truncate_lines, message_truncate_lines ? Qt : Qnil);
if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
- BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
+ BSET (current_buffer, bidi_paragraph_direction, Qleft_to_right);
/* Insert new message at BEG. */
TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
(f, current_buffer, selected_window, 0));
Fselect_window (f->selected_window, Qt);
- set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
+ set_buffer_internal_1
+ (XBUFFER (XWINDOW (f->selected_window)->buffer));
fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
mode_line_target = MODE_LINE_TITLE;
#ifdef HAVE_NS
if (windows_or_buffers_changed
&& FRAME_NS_P (f))
- ns_set_doc_edited (f, Fbuffer_modified_p
- (XWINDOW (f->selected_window)->buffer));
+ ns_set_doc_edited
+ (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer));
#endif
UNGCPRO;
}
}
XSETFRAME (Vmenu_updating_frame, f);
- FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
+ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
/* Redisplay the menu bar in case we changed it. */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
selected_frame = frame;
/* Build desired tool-bar items from keymaps. */
- new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
- &new_n_tool_bar);
+ new_tool_bar
+ = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
+ &new_n_tool_bar);
/* Redisplay the tool-bar if we changed it. */
if (new_n_tool_bar != f->n_tool_bar_items
may access f->tool_bar_items. Make sure we update both
variables within BLOCK_INPUT so no such event interrupts. */
BLOCK_INPUT;
- f->tool_bar_items = new_tool_bar;
+ fset_tool_bar_items (f, new_tool_bar);
f->n_tool_bar_items = new_n_tool_bar;
w->update_mode_line = 1;
UNBLOCK_INPUT;
/* Reuse f->desired_tool_bar_string, if possible. */
if (size < size_needed || NILP (f->desired_tool_bar_string))
- f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
- make_number (' '));
+ fset_desired_tool_bar_string
+ (f, Fmake_string (make_number (size_needed), make_number (' ')));
else
{
props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
is the index of the item in F's tool-bar item vector. */
for (i = 0; i < f->n_tool_bar_items; ++i)
{
-#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
+#define PROP(IDX) \
+ AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
static void
debug_method_add (struct window *w, char const *fmt, ...)
{
- char buffer[512];
char *method = w->desired_matrix->method;
int len = strlen (method);
int size = sizeof w->desired_matrix->method;
int remaining = size - len - 1;
va_list ap;
- va_start (ap, fmt);
- vsprintf (buffer, fmt, ap);
- va_end (ap);
if (len && remaining)
{
method[len] = '|';
--remaining, ++len;
}
- strncpy (method + len, buffer, remaining);
+ va_start (ap, fmt);
+ vsnprintf (method + len, remaining + 1, fmt, ap);
+ va_end (ap);
if (trace_redisplay_p)
fprintf (stderr, "%p (%s): %s\n",
&& STRINGP (BVAR (XBUFFER (w->buffer), name)))
? SSDATA (BVAR (XBUFFER (w->buffer), name))
: "no buffer"),
- buffer);
+ method + len);
}
#endif /* GLYPH_DEBUG */
selected_frame = frame;
do {
- for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
+ for (tail = XFRAME (frame)->param_alist;
+ CONSP (tail); tail = XCDR (tail))
if (CONSP (XCAR (tail))
&& (tem = XCAR (XCAR (tail)),
SYMBOLP (tem))
if ((it.glyph_row - 1)->displays_text_p)
{
if (XFASTINT (w->window_end_vpos) < this_line_vpos)
- XSETINT (w->window_end_vpos, this_line_vpos);
+ wset_window_end_vpos (w, make_number (this_line_vpos));
}
else if (XFASTINT (w->window_end_vpos) == this_line_vpos
&& this_line_vpos > 0)
- XSETINT (w->window_end_vpos, this_line_vpos - 1);
- w->window_end_valid = Qnil;
+ wset_window_end_vpos (w, make_number (this_line_vpos - 1));
+ wset_window_end_valid (w, Qnil);
/* Update hint: No need to try to scroll in update_window. */
w->desired_matrix->no_scrolling_p = 1;
and selected_window to be temporarily out-of-sync but let's make
sure this stays contained. */
select_frame_for_redisplay (old_frame);
- eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
+ eassert (EQ (XFRAME (selected_frame)->selected_window,
+ selected_window));
if (!pending)
{
if (accurate_p)
{
- w->window_end_valid = w->buffer;
+ wset_window_end_valid (w, w->buffer);
w->update_mode_line = 0;
}
}
if (!just_this_one_p
|| current_buffer->clip_changed
|| BEG_UNCHANGED < CHARPOS (startp))
- w->base_line_number = Qnil;
+ wset_base_line_number (w, Qnil);
/* If cursor ends up on a partially visible line,
treat that as being off the bottom of the screen. */
return rc;
#endif
- /* Previously, there was a check for Lisp integer in the
+ /* Previously, there was a check for Lisp integer in the
if-statement below. Now, this field is converted to
ptrdiff_t, thus zero means invalid position in a buffer. */
eassert (w->last_point > 0);
if (XMARKER (w->start)->buffer == current_buffer)
compute_window_start_on_continuation_line (w);
- w->window_end_valid = Qnil;
+ wset_window_end_valid (w, Qnil);
}
/* Some sanity checks. */
{
struct Lisp_Char_Table *disptab = buffer_display_table ();
- if (! disptab_matches_widthtab (disptab,
- XVECTOR (BVAR (current_buffer, width_table))))
+ if (! disptab_matches_widthtab
+ (disptab, XVECTOR (BVAR (current_buffer, width_table))))
{
invalidate_region_cache (current_buffer,
current_buffer->width_run_cache,
w->force_start = 0;
w->vscroll = 0;
- w->window_end_valid = Qnil;
+ wset_window_end_valid (w, Qnil);
/* Forget any recorded base line for line number display. */
if (!buffer_unchanged_p)
- w->base_line_number = Qnil;
+ wset_base_line_number (w, Qnil);
/* Redisplay the mode line. Select the buffer properly for that.
Also, run the hook window-scroll-functions
|| current_buffer->clip_changed
|| BEG_UNCHANGED < CHARPOS (startp))
/* Forget any recorded base line for line number display. */
- w->base_line_number = Qnil;
+ wset_base_line_number (w, Qnil);
if (!cursor_row_fully_visible_p (w, 1, 0))
{
/* Forget any previously recorded base line for line number display. */
if (!buffer_unchanged_p)
- w->base_line_number = Qnil;
+ wset_base_line_number (w, Qnil);
/* Determine the window start relative to point. */
init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
if (!line_number_displayed
&& !BUFFERP (w->base_line_pos))
{
- w->base_line_pos = Qnil;
- w->base_line_number = Qnil;
+ wset_base_line_pos (w, Qnil);
+ wset_base_line_number (w, Qnil);
}
finish_menu_bars:
eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
w->window_end_bytepos
= Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- w->window_end_pos
- = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
- w->window_end_vpos
- = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
- eassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
- ->displays_text_p);
+ wset_window_end_pos
+ (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
+ wset_window_end_vpos
+ (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
+ eassert
+ (MATRIX_ROW (w->desired_matrix,
+ XFASTINT (w->window_end_vpos))->displays_text_p);
}
else
{
w->window_end_bytepos = Z_BYTE - ZV_BYTE;
- w->window_end_pos = make_number (Z - ZV);
- w->window_end_vpos = make_number (0);
+ wset_window_end_pos (w, make_number (Z - ZV));
+ wset_window_end_vpos (w, make_number (0));
}
/* But that is not valid info until redisplay finishes. */
- w->window_end_valid = Qnil;
+ wset_window_end_valid (w, Qnil);
return 1;
}
{
w->window_end_bytepos
= Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
- w->window_end_pos
- = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
- w->window_end_vpos
- = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
- w->current_matrix));
+ wset_window_end_pos
+ (w, make_number (Z
+ - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
+ wset_window_end_vpos
+ (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
+ w->current_matrix)));
}
else if (last_text_row)
{
w->window_end_bytepos
= Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- w->window_end_pos
- = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
- w->window_end_vpos
- = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
+ wset_window_end_pos
+ (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
+ wset_window_end_vpos
+ (w, make_number (MATRIX_ROW_VPOS (last_text_row,
+ w->desired_matrix)));
}
else
{
/* This window must be completely empty. */
w->window_end_bytepos = Z_BYTE - ZV_BYTE;
- w->window_end_pos = make_number (Z - ZV);
- w->window_end_vpos = make_number (0);
+ wset_window_end_pos (w, make_number (Z - ZV));
+ wset_window_end_vpos (w, make_number (0));
}
- w->window_end_valid = Qnil;
+ wset_window_end_valid (w, Qnil);
/* Update hint: don't try scrolling again in update_window. */
w->desired_matrix->no_scrolling_p = 1;
{
w->window_end_bytepos
= Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- w->window_end_pos
- = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
- w->window_end_vpos
- = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
+ wset_window_end_pos
+ (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
+ wset_window_end_vpos
+ (w, make_number (MATRIX_ROW_VPOS (last_text_row,
+ w->desired_matrix)));
}
else
{
- w->window_end_vpos
- = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
+ wset_window_end_vpos
+ (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
}
- w->window_end_valid = Qnil;
+ wset_window_end_valid (w, Qnil);
w->desired_matrix->no_scrolling_p = 1;
#ifdef GLYPH_DEBUG
{
/* We have to compute the window end anew since text
could have been added/removed after it. */
- w->window_end_pos
- = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
+ wset_window_end_pos
+ (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
w->window_end_bytepos
= Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
first_unchanged_at_end_row);
eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
- w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
+ wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
- w->window_end_vpos
- = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
+ wset_window_end_vpos
+ (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
eassert (w->window_end_bytepos >= 0);
IF_DEBUG (debug_method_add (w, "A"));
}
else if (last_text_row_at_end)
{
- w->window_end_pos
- = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
+ wset_window_end_pos
+ (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
w->window_end_bytepos
= Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
- w->window_end_vpos
- = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
+ wset_window_end_vpos
+ (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
+ desired_matrix)));
eassert (w->window_end_bytepos >= 0);
IF_DEBUG (debug_method_add (w, "B"));
}
/* We have displayed either to the end of the window or at the
end of the window, i.e. the last row with text is to be found
in the desired matrix. */
- w->window_end_pos
- = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
+ wset_window_end_pos
+ (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
w->window_end_bytepos
= Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- w->window_end_vpos
- = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
+ wset_window_end_vpos
+ (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
eassert (w->window_end_bytepos >= 0);
}
else if (first_unchanged_at_end_row == NULL
}
eassert (row != NULL);
- w->window_end_vpos = make_number (vpos + 1);
- w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
+ wset_window_end_vpos (w, make_number (vpos + 1));
+ wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
eassert (w->window_end_bytepos >= 0);
IF_DEBUG (debug_method_add (w, "C"));
debug_end_vpos = XFASTINT (w->window_end_vpos));
/* Record that display has not been completed. */
- w->window_end_valid = Qnil;
+ wset_window_end_valid (w, Qnil);
w->desired_matrix->no_scrolling_p = 1;
return 3;
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
- char *s = (char *) alloca (row->used[area] + 1);
+ char *s = alloca (row->used[area] + 1);
int i;
for (i = 0; i < row->used[area]; ++i)
}
-/* Insert truncation glyphs at the start of IT->glyph_row. Truncation
- glyphs are only inserted for terminal frames since we can't really
- win with truncation glyphs when partially visible glyphs are
- involved. Which glyphs to insert is determined by
- produce_special_glyphs. */
+/* Insert truncation glyphs at the start of IT->glyph_row. Which
+ glyphs to insert is determined by produce_special_glyphs. */
static void
insert_left_trunc_glyphs (struct it *it)
struct it truncate_it;
struct glyph *from, *end, *to, *toend;
- eassert (!FRAME_WINDOW_P (it->f));
+ eassert (!FRAME_WINDOW_P (it->f)
+ || (!it->glyph_row->reversed_p
+ && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
+ || (it->glyph_row->reversed_p
+ && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
/* Get the truncation glyphs. */
truncate_it = *it;
/* Overwrite glyphs from IT with truncation glyphs. */
if (!it->glyph_row->reversed_p)
{
+ short tused = truncate_it.glyph_row->used[TEXT_AREA];
+
from = truncate_it.glyph_row->glyphs[TEXT_AREA];
- end = from + truncate_it.glyph_row->used[TEXT_AREA];
+ end = from + tused;
to = it->glyph_row->glyphs[TEXT_AREA];
toend = to + it->glyph_row->used[TEXT_AREA];
+ if (FRAME_WINDOW_P (it->f))
+ {
+ /* On GUI frames, when variable-size fonts are displayed,
+ the truncation glyphs may need more pixels than the row's
+ glyphs they overwrite. We overwrite more glyphs to free
+ enough screen real estate, and enlarge the stretch glyph
+ on the right (see display_line), if there is one, to
+ preserve the screen position of the truncation glyphs on
+ the right. */
+ int w = 0;
+ struct glyph *g = to;
+ short used;
+
+ /* The first glyph could be partially visible, in which case
+ it->glyph_row->x will be negative. But we want the left
+ truncation glyphs to be aligned at the left margin of the
+ window, so we override the x coordinate at which the row
+ will begin. */
+ it->glyph_row->x = 0;
+ while (g < toend && w < it->truncation_pixel_width)
+ {
+ w += g->pixel_width;
+ ++g;
+ }
+ if (g - to - tused > 0)
+ {
+ memmove (to + tused, g, (toend - g) * sizeof(*g));
+ it->glyph_row->used[TEXT_AREA] -= g - to - tused;
+ }
+ used = it->glyph_row->used[TEXT_AREA];
+ if (it->glyph_row->truncated_on_right_p
+ && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
+ && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
+ == STRETCH_GLYPH)
+ {
+ int extra = w - it->truncation_pixel_width;
+
+ it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
+ }
+ }
while (from < end)
*to++ = *from++;
/* There may be padding glyphs left over. Overwrite them too. */
- while (to < toend && CHAR_GLYPH_PADDING_P (*to))
+ if (!FRAME_WINDOW_P (it->f))
{
- from = truncate_it.glyph_row->glyphs[TEXT_AREA];
- while (from < end)
- *to++ = *from++;
+ while (to < toend && CHAR_GLYPH_PADDING_P (*to))
+ {
+ from = truncate_it.glyph_row->glyphs[TEXT_AREA];
+ while (from < end)
+ *to++ = *from++;
+ }
}
if (to > toend)
}
else
{
+ short tused = truncate_it.glyph_row->used[TEXT_AREA];
+
/* In R2L rows, overwrite the last (rightmost) glyphs, and do
that back to front. */
end = truncate_it.glyph_row->glyphs[TEXT_AREA];
from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
toend = it->glyph_row->glyphs[TEXT_AREA];
to = toend + it->glyph_row->used[TEXT_AREA] - 1;
+ if (FRAME_WINDOW_P (it->f))
+ {
+ int w = 0;
+ struct glyph *g = to;
+
+ while (g >= toend && w < it->truncation_pixel_width)
+ {
+ w += g->pixel_width;
+ --g;
+ }
+ if (to - g - tused > 0)
+ to = g + tused;
+ if (it->glyph_row->truncated_on_right_p
+ && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
+ && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
+ {
+ int extra = w - it->truncation_pixel_width;
+
+ it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
+ }
+ }
while (from >= end && to >= toend)
*to-- = *from--;
- while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
+ if (!FRAME_WINDOW_P (it->f))
{
- from =
- truncate_it.glyph_row->glyphs[TEXT_AREA]
- + truncate_it.glyph_row->used[TEXT_AREA] - 1;
- while (from >= end && to >= toend)
- *to-- = *from--;
+ while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
+ {
+ from =
+ truncate_it.glyph_row->glyphs[TEXT_AREA]
+ + truncate_it.glyph_row->used[TEXT_AREA] - 1;
+ while (from >= end && to >= toend)
+ *to-- = *from--;
+ }
}
if (from >= end)
{
}
/* Is IT->w showing the region? */
- it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
+ wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil);
/* Clear the result glyph row and enable it. */
prepare_desired_row (row);
if the first glyph is partially visible or if we hit a line end. */
if (it->current_x < it->first_visible_x)
{
+ enum move_it_result move_result;
+
this_line_min_pos = row->start.pos;
- move_it_in_display_line_to (it, ZV, it->first_visible_x,
- MOVE_TO_POS | MOVE_TO_X);
+ move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
+ MOVE_TO_POS | MOVE_TO_X);
+ /* If we are under a large hscroll, move_it_in_display_line_to
+ could hit the end of the line without reaching
+ it->first_visible_x. Pretend that we did reach it. This is
+ especially important on a TTY, where we will call
+ extend_face_to_end_of_line, which needs to know how many
+ blank glyphs to produce. */
+ if (it->current_x < it->first_visible_x
+ && (move_result == MOVE_NEWLINE_OR_CR
+ || move_result == MOVE_POS_MATCH_OR_ZV))
+ it->current_x = it->first_visible_x;
+
/* Record the smallest positions seen while we moved over
display elements that are not visible. This is needed by
redisplay_internal for optimizing the case where the cursor
new_x > it->last_visible_x
/* Or it fits exactly on a window system frame. */
|| (new_x == it->last_visible_x
- && FRAME_WINDOW_P (it->f))))
+ && FRAME_WINDOW_P (it->f)
+ && (row->reversed_p
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
{
/* End of a continued line. */
if (it->hpos == 0
|| (new_x == it->last_visible_x
- && FRAME_WINDOW_P (it->f)))
+ && FRAME_WINDOW_P (it->f)
+ && (row->reversed_p
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
{
/* Current glyph is the only one on the line or
fits exactly on the line. We must continue
window system frames. We leave the glyph in
this row and let it fill the row, but don't
consume the TAB. */
+ if ((row->reversed_p
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
+ produce_special_glyphs (it, IT_CONTINUATION);
it->continuation_lines_width += it->last_visible_x;
row->ends_in_middle_of_char_p = 1;
row->continued_p = 1;
row->used[TEXT_AREA] = n_glyphs_before + i;
/* Display continuation glyphs. */
- if (!FRAME_WINDOW_P (it->f))
+ it->current_x = x_before;
+ it->continuation_lines_width += x;
+ if (!FRAME_WINDOW_P (it->f)
+ || (row->reversed_p
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
produce_special_glyphs (it, IT_CONTINUATION);
row->continued_p = 1;
- it->current_x = x_before;
- it->continuation_lines_width += x;
extend_face_to_end_of_line (it);
if (nglyphs > 1 && i > 0)
/* If we truncate lines, we are done when the last displayed
glyphs reach past the right margin of the window. */
if (it->line_wrap == TRUNCATE
- && (FRAME_WINDOW_P (it->f)
+ && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
? (it->current_x >= it->last_visible_x)
: (it->current_x > it->last_visible_x)))
{
/* Maybe add truncation glyphs. */
- if (!FRAME_WINDOW_P (it->f))
+ if (!FRAME_WINDOW_P (it->f)
+ || (row->reversed_p
+ ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
{
int i, n;
i = row->used[TEXT_AREA] - (i + 1);
}
- for (n = row->used[TEXT_AREA]; i < n; ++i)
+ it->current_x = x_before;
+ if (!FRAME_WINDOW_P (it->f))
+ {
+ for (n = row->used[TEXT_AREA]; i < n; ++i)
+ {
+ row->used[TEXT_AREA] = i;
+ produce_special_glyphs (it, IT_TRUNCATION);
+ }
+ }
+ else
{
row->used[TEXT_AREA] = i;
produce_special_glyphs (it, IT_TRUNCATION);
row->exact_window_width_line_p = 1;
goto at_end_of_line;
}
+ it->current_x = x_before;
}
row->truncated_on_right_p = 1;
reseat_at_next_visible_line_start (it, 0);
row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
it->hpos = hpos_before;
- it->current_x = x_before;
break;
}
}
if (it->first_visible_x
&& IT_CHARPOS (*it) != CHARPOS (row->start.pos))
{
- if (!FRAME_WINDOW_P (it->f))
+ if (!FRAME_WINDOW_P (it->f)
+ || (row->reversed_p
+ ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
+ : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
insert_left_trunc_glyphs (it);
row->truncated_on_left_p = 1;
}
/* These will be set while the mode line specs are processed. */
line_number_displayed = 0;
- w->column_number_displayed = Qnil;
+ wset_column_number_displayed (w, Qnil);
if (WINDOW_WANTS_MODELINE_P (w))
{
depth++;
- switch (SWITCH_ENUM_CAST (XTYPE (elt)))
+ switch (XTYPE (elt))
{
case Lisp_String:
{
}
else if (CHARACTERP (eoltype))
{
- unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
+ unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
int c = XFASTINT (eoltype);
eol_str_len = CHAR_STRING (c, tmp);
eol_str = tmp;
else
{
ptrdiff_t col = current_column ();
- w->column_number_displayed = make_number (col);
+ wset_column_number_displayed (w, make_number (col));
pint2str (decode_mode_spec_buf, field_width, col);
return decode_mode_spec_buf;
}
goto no_value;
/* But do forget it, if the window shows a different buffer now. */
else if (BUFFERP (w->base_line_pos))
- w->base_line_pos = Qnil;
+ wset_base_line_pos (w, Qnil);
/* If the buffer is very big, don't waste time. */
if (INTEGERP (Vline_number_display_limit)
&& BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
{
- w->base_line_pos = Qnil;
- w->base_line_number = Qnil;
+ wset_base_line_pos (w, Qnil);
+ wset_base_line_number (w, Qnil);
goto no_value;
}
go back past it. */
if (startpos == BUF_BEGV (b))
{
- w->base_line_number = make_number (topline);
- w->base_line_pos = make_number (BUF_BEGV (b));
+ wset_base_line_number (w, make_number (topline));
+ wset_base_line_pos (w, make_number (BUF_BEGV (b)));
}
else if (nlines < height + 25 || nlines > height * 3 + 50
|| linepos == BUF_BEGV (b))
give up on line numbers for this window. */
if (position == limit_byte && limit == startpos - distance)
{
- w->base_line_pos = w->buffer;
- w->base_line_number = Qnil;
+ wset_base_line_pos (w, w->buffer);
+ wset_base_line_number (w, Qnil);
goto no_value;
}
- w->base_line_number = make_number (topline - nlines);
- w->base_line_pos = make_number (BYTE_TO_CHAR (position));
+ wset_base_line_number (w, make_number (topline - nlines));
+ wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position)));
}
/* Now count lines from the start pos to point. */
obj = Fget_buffer_process (Fcurrent_buffer ());
if (PROCESSP (obj))
{
- p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
- p, eol_flag);
- p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
- p, eol_flag);
+ p = decode_mode_spec_coding
+ (XPROCESS (obj)->decode_coding_system, p, eol_flag);
+ p = decode_mode_spec_coding
+ (XPROCESS (obj)->encode_coding_system, p, eol_flag);
}
#endif /* subprocesses */
#endif /* 0 */
if (it->first_visible_x
&& it_charpos > 0)
{
- if (!FRAME_WINDOW_P (it->f))
+ if (!FRAME_WINDOW_P (it->f)
+ || (row->reversed_p
+ ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
+ : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
insert_left_trunc_glyphs (it);
row->truncated_on_left_p = 1;
}
last = s->row->glyphs[s->area] + end;
voffset = glyph->voffset;
s->face = FACE_FROM_ID (s->f, face_id);
- s->font = s->face->font;
+ s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
s->nchars = 1;
s->width = glyph->pixel_width;
glyph++;
#define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
do \
{ \
- s = (struct glyph_string *) alloca (sizeof *s); \
+ s = alloca (sizeof *s); \
INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
START = fill_stretch_glyph_string (s, START, END); \
append_glyph_string (&HEAD, &TAIL, s); \
#define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
do \
{ \
- s = (struct glyph_string *) alloca (sizeof *s); \
+ s = alloca (sizeof *s); \
INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
fill_image_glyph_string (s); \
append_glyph_string (&HEAD, &TAIL, s); \
\
face_id = (row)->glyphs[area][START].face_id; \
\
- s = (struct glyph_string *) alloca (sizeof *s); \
- char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
+ s = alloca (sizeof *s); \
+ char2b = alloca ((END - START) * sizeof *char2b); \
INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
append_glyph_string (&HEAD, &TAIL, s); \
s->x = (X); \
struct glyph_string *first_s = NULL; \
int n; \
\
- char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
+ char2b = alloca (cmp->glyph_len * sizeof *char2b); \
\
/* Make glyph_strings for each glyph sequence that is drawable by \
the same face, and append them to HEAD/TAIL. */ \
for (n = 0; n < cmp->glyph_len;) \
{ \
- s = (struct glyph_string *) alloca (sizeof *s); \
+ s = alloca (sizeof *s); \
INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
append_glyph_string (&(HEAD), &(TAIL), s); \
s->cmp = cmp; \
face_id = (row)->glyphs[area][START].face_id; \
gstring = (composition_gstring_from_id \
((row)->glyphs[area][START].u.cmp.id)); \
- s = (struct glyph_string *) alloca (sizeof *s); \
- char2b = (XChar2b *) alloca ((sizeof *char2b) \
- * LGSTRING_GLYPH_LEN (gstring)); \
+ s = alloca (sizeof *s); \
+ char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
append_glyph_string (&(HEAD), &(TAIL), s); \
s->x = (X); \
\
face_id = (row)->glyphs[area][START].face_id; \
\
- s = (struct glyph_string *) alloca (sizeof *s); \
+ s = alloca (sizeof *s); \
INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
append_glyph_string (&HEAD, &TAIL, s); \
s->x = (X); \
it->nglyphs = width;
}
+/* Get information about special display element WHAT in an
+ environment described by IT. WHAT is one of IT_TRUNCATION or
+ IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
+ non-null glyph_row member. This function ensures that fields like
+ face_id, c, len of IT are left untouched. */
+
+static void
+produce_special_glyphs (struct it *it, enum display_element_type what)
+{
+ struct it temp_it;
+ Lisp_Object gc;
+ GLYPH glyph;
+
+ temp_it = *it;
+ temp_it.object = make_number (0);
+ memset (&temp_it.current, 0, sizeof temp_it.current);
+
+ if (what == IT_CONTINUATION)
+ {
+ /* Continuation glyph. For R2L lines, we mirror it by hand. */
+ if (it->bidi_it.paragraph_dir == R2L)
+ SET_GLYPH_FROM_CHAR (glyph, '/');
+ else
+ SET_GLYPH_FROM_CHAR (glyph, '\\');
+ if (it->dp
+ && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
+ {
+ /* FIXME: Should we mirror GC for R2L lines? */
+ SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
+ spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
+ }
+ }
+ else if (what == IT_TRUNCATION)
+ {
+ /* Truncation glyph. */
+ SET_GLYPH_FROM_CHAR (glyph, '$');
+ if (it->dp
+ && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
+ {
+ /* FIXME: Should we mirror GC for R2L lines? */
+ SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
+ spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
+ }
+ }
+ else
+ abort ();
+
+#ifdef HAVE_WINDOW_SYSTEM
+ /* On a GUI frame, when the right fringe (left fringe for R2L rows)
+ is turned off, we precede the truncation/continuation glyphs by a
+ stretch glyph whose width is computed such that these special
+ glyphs are aligned at the window margin, even when very different
+ fonts are used in different glyph rows. */
+ if (FRAME_WINDOW_P (temp_it.f)
+ /* init_iterator calls this with it->glyph_row == NULL, and it
+ wants only the pixel width of the truncation/continuation
+ glyphs. */
+ && temp_it.glyph_row
+ /* insert_left_trunc_glyphs calls us at the beginning of the
+ row, and it has its own calculation of the stretch glyph
+ width. */
+ && temp_it.glyph_row->used[TEXT_AREA] > 0
+ && (temp_it.glyph_row->reversed_p
+ ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
+ : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
+ {
+ int stretch_width = temp_it.last_visible_x - temp_it.current_x;
+
+ if (stretch_width > 0)
+ {
+ struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
+ struct font *font =
+ face->font ? face->font : FRAME_FONT (temp_it.f);
+ int stretch_ascent =
+ (((temp_it.ascent + temp_it.descent)
+ * FONT_BASE (font)) / FONT_HEIGHT (font));
+
+ append_stretch_glyph (&temp_it, make_number (0), stretch_width,
+ temp_it.ascent + temp_it.descent,
+ stretch_ascent);
+ }
+ }
+#endif
+
+ temp_it.dp = NULL;
+ temp_it.what = IT_CHARACTER;
+ temp_it.len = 1;
+ temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
+ temp_it.face_id = GLYPH_FACE (glyph);
+ temp_it.len = CHAR_BYTES (temp_it.c);
+
+ PRODUCE_GLYPHS (&temp_it);
+ it->pixel_width = temp_it.pixel_width;
+ it->nglyphs = temp_it.pixel_width;
+}
+
#ifdef HAVE_WINDOW_SYSTEM
/* Calculate line-height and line-spacing properties.
font_descent = FONT_DESCENT (font) - boff;
font_height = FONT_HEIGHT (font);
- cmp->font = (void *) font;
+ cmp->font = font;
pcm = NULL;
if (! font_not_found_p)
staticpro (&echo_area_buffer[0]);
staticpro (&echo_area_buffer[1]);
- Vmessages_buffer_name = make_pure_c_string ("*Messages*");
+ Vmessages_buffer_name = build_pure_c_string ("*Messages*");
staticpro (&Vmessages_buffer_name);
mode_line_proptrans_alist = Qnil;
DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
doc: /* String to display as an arrow in non-window frames.
See also `overlay-arrow-position'. */);
- Voverlay_arrow_string = make_pure_c_string ("=>");
+ Voverlay_arrow_string = build_pure_c_string ("=>");
DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
doc: /* List of variables (symbols) which hold markers for overlay arrows.
\(see `modify-frame-parameters'). */);
Vicon_title_format
= Vframe_title_format
- = pure_cons (intern_c_string ("multiple-frames"),
- pure_cons (make_pure_c_string ("%b"),
- pure_cons (pure_cons (empty_unibyte_string,
- pure_cons (intern_c_string ("invocation-name"),
- pure_cons (make_pure_c_string ("@"),
- pure_cons (intern_c_string ("system-name"),
- Qnil)))),
- Qnil)));
+ = listn (CONSTYPE_PURE, 3,
+ intern_c_string ("multiple-frames"),
+ build_pure_c_string ("%b"),
+ listn (CONSTYPE_PURE, 4,
+ empty_unibyte_string,
+ intern_c_string ("invocation-name"),
+ build_pure_c_string ("@"),
+ intern_c_string ("system-name")));
DEFVAR_LISP ("message-log-max", Vmessage_log_max,
doc: /* Maximum number of lines to keep in the message log buffer.
echo_area_window = minibuf_window;
- XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
- XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
- XSETFASTINT (r->total_cols, FRAME_COLS (f));
- XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
- XSETFASTINT (m->total_lines, 1);
- XSETFASTINT (m->total_cols, FRAME_COLS (f));
+ wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
+ wset_total_lines
+ (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)));
+ wset_total_cols (r, make_number (FRAME_COLS (f)));
+ wset_top_line (m, make_number (FRAME_LINES (f) - 1));
+ wset_total_lines (m, make_number (1));
+ wset_total_cols (m, make_number (FRAME_COLS (f)));
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]
/* Allocate the buffer for frame titles.
Also used for `format-mode-line'. */
int size = 100;
- mode_line_noprop_buf = (char *) xmalloc (size);
+ mode_line_noprop_buf = xmalloc (size);
mode_line_noprop_buf_end = mode_line_noprop_buf + size;
mode_line_noprop_ptr = mode_line_noprop_buf;
mode_line_target = MODE_LINE_DISPLAY;
if (INTEGERP (Vhourglass_delay)
&& XINT (Vhourglass_delay) > 0)
- EMACS_SET_SECS_NSECS (delay,
- min (XINT (Vhourglass_delay), TYPE_MAXIMUM (time_t)),
- 0);
+ delay = make_emacs_time (min (XINT (Vhourglass_delay),
+ TYPE_MAXIMUM (time_t)),
+ 0);
else if (FLOATP (Vhourglass_delay)
&& XFLOAT_DATA (Vhourglass_delay) > 0)
delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
else
- EMACS_SET_SECS_NSECS (delay, DEFAULT_HOURGLASS_DELAY, 0);
+ delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
show_hourglass, NULL);