#include <config.h>
#include <stdio.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
#include "lisp.h"
#include "frame.h"
#include "window.h"
Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
Lisp_Object Qredisplay_end_trigger_functions;
Lisp_Object Qinhibit_point_motion_hooks;
-Lisp_Object QCeval, QCwhen;
+Lisp_Object QCeval, Qwhen, QCfile;
Lisp_Object Qfontified;
/* Functions called to fontify regions of text. */
Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qheight, Qraise;
+Lisp_Object Qmargin;
/* Non-nil means highlight trailing whitespace. */
static void insert_left_trunc_glyphs P_ ((struct it *));
static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
static void extend_face_to_end_of_line P_ ((struct it *));
-static void append_space P_ ((struct it *, int));
+static int append_space P_ ((struct it *, int));
static void make_cursor_line_fully_visible P_ ((struct window *));
static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
static int trailing_whitespace_p P_ ((int));
static void display_mode_line P_ ((struct window *, enum face_id,
Lisp_Object));
static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
-static char *decode_mode_spec P_ ((struct window *, char, int, int));
+static char *decode_mode_spec P_ ((struct window *, int, int, int));
static void display_menu_bar P_ ((struct window *));
static int display_count_lines P_ ((int, int, int, int, int *));
static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
{
Lisp_Object prop, pos;
enum prop_handled handled = HANDLED_NORMALLY;
+ struct gcpro gcpro1;
/* Get the value of the `fontified' property at IT's current buffer
position. (The `fontified' property doesn't have a special
{
Lisp_Object args[2];
+ GCPRO1 (pos);
/* Run the hook functions. */
args[0] = Qfontification_functions;
args[1] = pos;
fontify the text for which reason ever. */
if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
handled = HANDLED_RECOMPUTE_PROPS;
+ UNGCPRO;
}
return handled;
return HANDLED_NORMALLY;
space_or_image_found_p = 0;
- if (CONSP (prop) && CONSP (XCAR (prop)))
+ if (CONSP (prop)
+ && CONSP (XCAR (prop))
+ && !EQ (Qmargin, XCAR (XCAR (prop))))
{
+ /* A list of sub-properties. */
while (CONSP (prop))
{
if (handle_single_display_prop (it, XCAR (prop), object, position))
}
-/* Value is the position of the end of the `display' property stating
+/* Value is the position of the end of the `display' property starting
at START_POS in OBJECT. */
static struct text_pos
{
Lisp_Object end;
struct text_pos end_pos;
-
- /* Characters having this form of property are not displayed, so
- we have to find the end of the property. */
- end = Fnext_single_property_change (make_number (start_pos.charpos),
- Qdisplay, object, Qnil);
- if (NILP (end))
- {
- /* A nil value of `end' means there are no changes of the
- property to the end of the buffer or string. */
- if (it->current.overlay_string_index >= 0)
- end_pos.charpos = XSTRING (it->string)->size;
- else
- end_pos.charpos = it->end_charpos;
- }
- else
- end_pos.charpos = XFASTINT (end);
- if (STRINGP (it->string))
+ end = next_single_char_property_change (make_number (CHARPOS (start_pos)),
+ Qdisplay, object, Qnil);
+ CHARPOS (end_pos) = XFASTINT (end);
+ if (STRINGP (object))
compute_string_pos (&end_pos, start_pos, it->string);
else
- end_pos.bytepos = CHAR_TO_BYTE (end_pos.charpos);
+ BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
return end_pos;
}
Lisp_Object form;
- /* If PROP is a list of the form `(:when FORM . VALUE)', FORM is
+ /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
evaluated. If the result is nil, VALUE is ignored. */
form = Qt;
- if (CONSP (prop) && EQ (XCAR (prop), QCwhen))
+ if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
{
prop = XCDR (prop);
if (!CONSP (prop))
}
else if (!it->string_from_display_prop_p)
{
- /* `(left-margin VALUE)' or `(right-margin VALUE)
- or `(nil VALUE)' or VALUE. */
+ /* `((margin left-margin) VALUE)' or `((margin right-margin)
+ VALUE) or `((margin nil) VALUE)' or VALUE. */
Lisp_Object location, value;
struct text_pos start_pos;
int valid_p;
text properties change there. */
it->stop_charpos = position->charpos;
- if (CONSP (prop)
- && !EQ (XCAR (prop), Qspace)
- && !EQ (XCAR (prop), Qimage))
+ location = Qunbound;
+ if (CONSP (prop) && CONSP (XCAR (prop)))
{
- location = XCAR (prop);
+ Lisp_Object tem;
+
value = XCDR (prop);
+ if (CONSP (value))
+ value = XCAR (value);
+
+ tem = XCAR (prop);
+ if (EQ (XCAR (tem), Qmargin)
+ && (tem = XCDR (tem),
+ tem = CONSP (tem) ? XCAR (tem) : Qnil,
+ (NILP (tem)
+ || EQ (tem, Qleft_margin)
+ || EQ (tem, Qright_margin))))
+ location = tem;
}
- else
+
+ if (EQ (location, Qunbound))
{
location = Qnil;
value = prop;
&& indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
it->selective))
visible_p = 0;
-#ifdef USE_TEXT_PROPERTIES
else
{
Lisp_Object prop;
if (TEXT_PROP_MEANS_INVISIBLE (prop))
visible_p = 0;
}
-#endif /* USE_TEXT_PROPERTIES */
/* Back one more newline if the current one is invisible. */
if (!visible_p)
- when we stopped at a line end, i.e. a newline or a CR and selective
display is on. */
-enum move_it_result
+static enum move_it_result
move_it_in_display_line_to (it, to_charpos, to_x, op)
struct it *it;
int to_charpos, to_x, op;
struct it *it;
int start_charpos, end_charpos;
{
-#ifdef USE_TEXT_PROPERTIES
Lisp_Object prop, limit;
int invisible_found_p;
invisible_found_p = 1;
else
{
- limit = Fnext_single_property_change (make_number (start_charpos),
- Qinvisible,
- Fcurrent_buffer (),
- make_number (end_charpos));
+ limit = next_single_char_property_change (make_number (start_charpos),
+ Qinvisible, Qnil,
+ make_number (end_charpos));
invisible_found_p = XFASTINT (limit) < end_charpos;
}
return invisible_found_p;
-
-#else /* not USE_TEXT_PROPERTIES */
- return 0;
-#endif /* not USE_TEXT_PROPERTIES */
}
***********************************************************************/
+/* Add a message with format string FORMAT and arguments ARG1 and ARG2
+ to *Messages*. */
+
+void
+add_to_log (format, arg1, arg2)
+ char *format;
+ Lisp_Object arg1, arg2;
+{
+ Lisp_Object args[3];
+ Lisp_Object msg, fmt;
+ char *buffer;
+ int len;
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+
+ fmt = msg = Qnil;
+ GCPRO4 (fmt, msg, arg1, arg2);
+
+ args[0] = fmt = build_string (format);
+ args[1] = arg1;
+ args[2] = arg2;
+ msg = Fformat (make_number (3), args);
+
+ len = STRING_BYTES (XSTRING (msg)) + 1;
+ buffer = (char *) alloca (len);
+ strcpy (buffer, XSTRING (msg)->data);
+
+ message_dolog (buffer, len, 1, 0);
+ UNGCPRO;
+}
+
+
/* Output a newline in the *Messages* buffer if "needs" one. */
void
char *m;
int len;
{
+ struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
if (noninteractive)
initialized yet. Error messages get reported properly by
cmd_error, so this must be just an informative message; toss it. */
else if (INTERACTIVE
- && selected_frame->glyphs_initialized_p
- && FRAME_MESSAGE_BUF (selected_frame))
+ && sf->glyphs_initialized_p
+ && FRAME_MESSAGE_BUF (sf))
{
Lisp_Object mini_window;
struct frame *f;
/* Get the frame containing the mini-buffer
that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
FRAME_SAMPLE_VISIBILITY (f);
- if (FRAME_VISIBLE_P (selected_frame)
+ if (FRAME_VISIBLE_P (sf)
&& ! FRAME_VISIBLE_P (f))
Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
Lisp_Object m;
int nbytes, multibyte;
{
+ struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
if (noninteractive)
initialized yet. Error messages get reported properly by
cmd_error, so this must be just an informative message; toss it. */
else if (INTERACTIVE
- && selected_frame->glyphs_initialized_p
- && FRAME_MESSAGE_BUF (selected_frame))
+ && sf->glyphs_initialized_p
+ && FRAME_MESSAGE_BUF (sf))
{
Lisp_Object mini_window;
Lisp_Object frame;
/* Get the frame containing the mini-buffer
that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
frame = XWINDOW (mini_window)->frame;
f = XFRAME (frame);
FRAME_SAMPLE_VISIBILITY (f);
- if (FRAME_VISIBLE_P (selected_frame)
+ if (FRAME_VISIBLE_P (sf)
&& !FRAME_VISIBLE_P (f))
Fmake_frame_visible (frame);
It may be larger than the selected frame, so we need
to use its buffer, not the selected frame's buffer. */
Lisp_Object mini_window;
- FRAME_PTR f;
+ struct frame *f, *sf = SELECTED_FRAME ();
/* Get the frame containing the minibuffer
that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
/* A null message buffer means that the frame hasn't really been
on. It may be larger than the selected frame, so we need to
use its buffer, not the selected frame's buffer. */
Lisp_Object mini_window;
- struct frame *f;
+ struct frame *f, *sf = SELECTED_FRAME ();
/* Get the frame containing the mini-buffer
that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
/* A null message buffer means that the frame hasn't really been
if (!NILP (echo_area_buffer[this_one])
&& EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
echo_area_buffer[this_one] = Qnil;
-
}
/* Choose a suitable buffer from echo_buffer[] is we don't
/* Raise the frame containing the echo area. */
if (minibuffer_auto_raise)
{
+ struct frame *sf = SELECTED_FRAME ();
Lisp_Object mini_window;
- mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
}
struct window *w;
{
Lisp_Object window;
- struct frame *f = XFRAME (w->frame);
struct text_pos start;
int window_height_changed_p = 0;
/* Do this before displaying, so that we have a large enough glyph
matrix for the display. */
- window_height_changed_p = resize_mini_window (w);
+ window_height_changed_p = resize_mini_window (w, 0);
/* Display. */
clear_glyph_matrix (w->desired_matrix);
}
-/* Resize mini-window W to fit the size of its contents. Value is
- non-zero if the window height has been changed. */
+/* Resize the echo area window to exactly the size needed for the
+ currently displayed message, if there is one. */
+
+void
+resize_echo_area_axactly ()
+{
+ if (BUFFERP (echo_area_buffer[0])
+ && WINDOWP (echo_area_window))
+ {
+ struct window *w = XWINDOW (echo_area_window);
+ int resized_p;
+
+ resized_p = with_echo_area_buffer (w, 0,
+ (int (*) ()) resize_mini_window,
+ w, 1);
+ if (resized_p)
+ {
+ ++windows_or_buffers_changed;
+ ++update_mode_lines;
+ redisplay_internal (0);
+ }
+ }
+}
+
+
+/* Resize mini-window W to fit the size of its contents. EXACT:P
+ means size the window exactly to the size needed. Otherwise, it's
+ only enlarged until W's buffer is empty. Value is non-zero if
+ the window height has been changed. */
int
-resize_mini_window (w)
+resize_mini_window (w, exact_p)
struct window *w;
+ int exact_p;
{
struct frame *f = XFRAME (w->frame);
int window_height_changed_p = 0;
xassert (MINI_WINDOW_P (w));
/* Nil means don't try to resize. */
- if (NILP (Vmax_mini_window_height))
+ if (NILP (Vmax_mini_window_height)
+ || (FRAME_X_P (f) && f->output_data.x == NULL))
return 0;
if (!FRAME_MINIBUF_ONLY_P (f))
max_height = min (total_height, max_height);
/* Find out the height of the text in the window. */
+ last_height = 0;
move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
- height = (unit - 1 + it.current_y + last_height) / unit;
- height = max (1, height);
+ if (it.max_ascent == 0 && it.max_descent == 0)
+ height = it.current_y + last_height;
+ else
+ height = it.current_y + it.max_ascent + it.max_descent;
+ height = (height + unit - 1) / unit;
/* Compute a suitable window start. */
if (height > max_height)
/* Let it grow only, until we display an empty message, in which
case the window shrinks again. */
- if (height > XFASTINT (w->height)
- || BEGV == ZV)
+ if (height > XFASTINT (w->height))
{
- Lisp_Object old_selected_window;
-
- freeze_window_starts (f, height > XFASTINT (w->height));
- old_selected_window = selected_window;
- XSETWINDOW (selected_window, w);
- change_window_height (height - XFASTINT (w->height), 0);
- selected_window = old_selected_window;
- window_height_changed_p = 1;
+ int old_height = XFASTINT (w->height);
+ freeze_window_starts (f, 1);
+ grow_mini_window (w, height - XFASTINT (w->height));
+ window_height_changed_p = XFASTINT (w->height) != old_height;
+ }
+ else if (height < XFASTINT (w->height)
+ && (exact_p || BEGV == ZV))
+ {
+ int old_height = XFASTINT (w->height);
+ freeze_window_starts (f, 0);
+ shrink_mini_window (w);
+ window_height_changed_p = XFASTINT (w->height) != old_height;
}
}
cmd_error, so this must be just an informative message; toss it. */
else if (!noninteractive
&& INTERACTIVE
- && FRAME_MESSAGE_BUF (selected_frame)
&& !NILP (echo_area_buffer[0]))
- with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
+ {
+ struct frame *sf = SELECTED_FRAME ();
+ if (FRAME_MESSAGE_BUF (sf))
+ with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
+ }
}
}
-/* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is
- non-zero update selected_frame. Value is non-zero if the
+/* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
+ is non-zero update selected_frame. Value is non-zero if the
mini-windows height has been changed. */
static int
struct window *w;
struct frame *f;
int window_height_changed_p = 0;
+ struct frame *sf = SELECTED_FRAME ();
- mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
w = XWINDOW (mini_window);
f = XFRAME (WINDOW_FRAME (w));
if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
return 0;
+#ifdef HAVE_X_WINDOWS
/* When Emacs starts, selected_frame may be a visible terminal
frame, even if we run under a window system. If we let this
through, a message would be displayed on the terminal. */
-#ifdef HAVE_WINDOW_SYSTEM
- if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame))
+ if (EQ (selected_frame, Vterminal_frame)
+ && !NILP (Vwindow_system))
return 0;
-#endif /* HAVE_WINDOW_SYSTEM */
+#endif /* HAVE_X_WINDOWS */
/* Redraw garbaged frames. */
if (frame_garbaged)
}
else
{
- update_menu_bar (selected_frame, 1);
+ struct frame *sf = SELECTED_FRAME ();
+ update_menu_bar (sf, 1);
#ifdef HAVE_WINDOW_SYSTEM
- update_tool_bar (selected_frame, 1);
+ update_tool_bar (sf, 1);
#endif
}
{
int hscroll_margin, text_area_x, text_area_y;
int text_area_width, text_area_height;
- struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix,
- w->cursor.vpos);
+ struct glyph_row *current_cursor_row
+ = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
+ struct glyph_row *desired_cursor_row
+ = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
+ struct glyph_row *cursor_row
+ = (desired_cursor_row->enabled_p
+ ? desired_cursor_row
+ : current_cursor_row);
window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
&text_area_width, &text_area_height);
if ((XFASTINT (w->hscroll)
&& w->cursor.x < hscroll_margin)
- || (cursor_row->truncated_on_right_p
+ || (cursor_row->enabled_p
+ && cursor_row->truncated_on_right_p
&& (w->cursor.x > text_area_width - hscroll_margin)))
{
struct it it;
struct text_pos tlbufpos, tlendpos;
int number_of_visible_frames;
int count;
+ struct frame *sf = SELECTED_FRAME ();
/* Non-zero means redisplay has to consider all windows on all
frames. Zero means, only selected_window is considered. */
fonts_changed_p = 0;
}
- if (! FRAME_WINDOW_P (selected_frame)
- && previous_terminal_frame != selected_frame)
+ if (! FRAME_WINDOW_P (sf)
+ && previous_terminal_frame != sf)
{
/* Since frames on an ASCII terminal share the same display
area, displaying a different frame means redisplay the whole
thing. */
windows_or_buffers_changed++;
- SET_FRAME_GARBAGED (selected_frame);
- XSETFRAME (Vterminal_frame, selected_frame);
+ SET_FRAME_GARBAGED (sf);
+ XSETFRAME (Vterminal_frame, sf);
}
- previous_terminal_frame = selected_frame;
+ previous_terminal_frame = sf;
/* Set the visible flags for all frames. Do this before checking
for resized or garbaged frames; they want to know if their frames
&& (current_buffer->clip_changed
|| XFASTINT (w->last_modified) < MODIFF
|| XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
- && resize_mini_window (w))
+ && resize_mini_window (w, 0))
{
/* Resized active mini-window to fit the size of what it is
showing if its contents might have changed. */
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
- if (FRAME_WINDOW_P (f) || f == selected_frame)
+ if (FRAME_WINDOW_P (f) || f == sf)
{
/* Mark all the scroll bars to be removed; we'll redeem
the ones we want when we redisplay their windows. */
}
}
}
- else if (FRAME_VISIBLE_P (selected_frame)
- && !FRAME_OBSCURED_P (selected_frame))
+ else if (FRAME_VISIBLE_P (sf)
+ && !FRAME_OBSCURED_P (sf))
redisplay_window (selected_window, 1);
if (consider_all_windows_p)
{
Lisp_Object tail;
+ struct frame *f;
+ int hscrolled_p;
pause = 0;
+ hscrolled_p = 0;
+ /* See if we have to hscroll. */
for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
- {
- struct frame *f;
+ if (FRAMEP (XCAR (tail)))
+ {
+ f = XFRAME (XCAR (tail));
+
+ if ((FRAME_WINDOW_P (f)
+ || f == sf)
+ && FRAME_VISIBLE_P (f)
+ && !FRAME_OBSCURED_P (f)
+ && hscroll_windows (f->root_window))
+ hscrolled_p = 1;
+ }
+ if (hscrolled_p)
+ goto retry;
+
+ for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+ {
if (!FRAMEP (XCAR (tail)))
continue;
f = XFRAME (XCAR (tail));
- if ((FRAME_WINDOW_P (f) || f == selected_frame)
+ if ((FRAME_WINDOW_P (f) || f == sf)
&& FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
{
/* Mark all windows as to be updated. */
pause |= update_frame (f, 0, 0);
if (!pause)
{
- if (hscroll_windows (f->root_window))
- goto retry;
-
mark_window_display_accurate (f->root_window, 1);
if (frame_up_to_date_hook != 0)
(*frame_up_to_date_hook) (f);
}
else
{
- if (FRAME_VISIBLE_P (selected_frame)
- && !FRAME_OBSCURED_P (selected_frame))
+ if (FRAME_VISIBLE_P (sf)
+ && !FRAME_OBSCURED_P (sf))
{
- XWINDOW (selected_window)->must_be_updated_p = 1;
- pause = update_frame (selected_frame, 0, 0);
- if (!pause && hscroll_windows (selected_window))
+ if (hscroll_windows (selected_window))
goto retry;
+
+ XWINDOW (selected_window)->must_be_updated_p = 1;
+ pause = update_frame (sf, 0, 0);
}
else
pause = 0;
Lisp_Object mini_window;
struct frame *mini_frame;
- mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+ mini_window = FRAME_MINIBUF_WINDOW (sf);
mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
- if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
+ if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
{
XWINDOW (mini_window)->must_be_updated_p = 1;
pause |= update_frame (mini_frame, 0, 0);
BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
if (consider_all_windows_p)
- mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
+ mark_window_display_accurate (FRAME_ROOT_WINDOW (sf), 1);
else
{
XSETFASTINT (w->last_point, BUF_PT (b));
last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
last_arrow_string = Voverlay_arrow_string;
if (frame_up_to_date_hook != 0)
- (*frame_up_to_date_hook) (selected_frame);
+ (*frame_up_to_date_hook) (sf);
w->current_matrix->buffer = b;
w->current_matrix->begv = BUF_BEGV (b);
/* Run window scroll functions, if any, for WINDOW with new window
- start STARTP. Sets the window start of WINDOW to that position. */
+ start STARTP. Sets the window start of WINDOW to that position.
+
+ We assume that the window's buffer is really current. */
static INLINE struct text_pos
run_window_scroll_functions (window, startp)
{
struct window *w = XWINDOW (window);
SET_MARKER_FROM_TEXT_POS (w->start, startp);
-
+
+ if (current_buffer != XBUFFER (w->buffer))
+ abort ();
+
if (!NILP (Vwindow_scroll_functions))
{
run_hook_with_args_2 (Qwindow_scroll_functions, window,
make_number (CHARPOS (startp)));
SET_TEXT_POS_FROM_MARKER (startp, w->start);
+ /* In case the hook functions switch buffers. */
+ if (current_buffer != XBUFFER (w->buffer))
+ set_buffer_internal_1 (XBUFFER (w->buffer));
}
return startp;
{
struct it it;
struct glyph_row *row;
+
+ /* Handle the case that the window start is out of range. */
+ if (CHARPOS (start_pos) < BEGV)
+ SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
+ else if (CHARPOS (start_pos) > ZV)
+ SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
/* Find the start of the continued line. This should be fast
because scan_buffer is fast (newline cache). */
make_cursor_line_fully_visible (w);
+ done:
+
SET_TEXT_POS_FROM_MARKER (startp, w->start);
w->start_at_line_beg = ((CHARPOS (startp) == BEGV
|| FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
? Qt : Qnil);
- done:
-
/* Display the mode line, if we must. */
if ((update_mode_line
/* If window not full width, must redo its mode line
while (window_row < window_row_end)
{
int area;
+
for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
frame_row->glyphs[area] = window_row->glyphs[area];
+
+ /* Disable frame rows whose corresponding window rows have
+ been disabled in try_window_id. */
+ if (!window_row->enabled_p)
+ frame_row->enabled_p = 0;
+
++window_row, ++frame_row;
}
}
mentioned, this is not a frequent case. */
if (w->cursor.vpos < 0)
{
- int last_y = min (it.last_visible_y, it.last_visible_y + dy);
-
/* Cursor in unchanged rows at the top? */
if (PT < CHARPOS (start_pos)
&& last_unchanged_at_beg_row)
0, 0, "", "")
()
{
- struct glyph_matrix *m = (XWINDOW (selected_frame->tool_bar_window)
+ struct frame *sf = SELECTED_FRAME ();
+ struct glyph_matrix *m = (XWINDOW (sf->tool_bar_window)
->current_matrix);
dump_glyph_row (m, 0, 1);
return Qnil;
/* Append one space to the glyph row of iterator IT if doing a
window-based redisplay. DEFAULT_FACE_P non-zero means let the
space have the default face, otherwise let it have the same face as
- IT->face_id.
+ IT->face_id. Value is non-zero if a space was added.
This function is called to make sure that there is always one glyph
at the end of a glyph row that the cursor can be set on under
At the same time this space let's a nicely handle clearing to the
end of the line if the row ends in italic text. */
-static void
+static int
append_space (it, default_face_p)
struct it *it;
int default_face_p;
it->what = saved_what;
it->face_id = saved_face_id;
it->charset = saved_charset;
+ return 1;
}
}
+
+ return 0;
}
if (!get_next_display_element (it))
{
/* Maybe add a space at the end of this line that is used to
- display the cursor there under X. */
- append_space (it, 1);
-
- /* The position -1 below indicates a blank line not
- corresponding to any text, as opposed to an empty line
- corresponding to a line end. */
- if (row->used[TEXT_AREA] <= 1)
+ display the cursor there under X. Set the charpos of the
+ first glyph of blank lines not corresponding to any text
+ to -1. */
+ if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
+ || row->used[TEXT_AREA] == 0)
{
row->glyphs[TEXT_AREA]->charpos = -1;
row->displays_text_p = 0;
#ifdef USE_X_TOOLKIT
xassert (!FRAME_WINDOW_P (f));
- init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MODE_LINE_FACE_ID);
+ init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
it.first_visible_x = 0;
it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
#else /* not USE_X_TOOLKIT */
xassert (WINDOWP (f->menu_bar_window));
menu_w = XWINDOW (f->menu_bar_window);
init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
- MODE_LINE_FACE_ID);
+ MENU_FACE_ID);
it.first_visible_x = 0;
it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
}
/* This is a TTY frame, i.e. character hpos/vpos are used as
pixel x/y. */
init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
- MODE_LINE_FACE_ID);
+ MENU_FACE_ID);
it.first_visible_x = 0;
it.last_visible_x = FRAME_WIDTH (f);
}
static char *
decode_mode_spec (w, c, field_width, precision)
struct window *w;
- register char c;
+ register int c;
int field_width, precision;
{
Lisp_Object obj;
start, it, field_width, precision, max_x, multibyte)
unsigned char *string;
Lisp_Object lisp_string;
+ Lisp_Object face_string;
+ int face_string_pos;
int start;
struct it *it;
int field_width, precision, max_x;
staticpro (&Qinhibit_point_motion_hooks);
Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
- staticpro (&Qdisplay);
Qdisplay = intern ("display");
- staticpro (&Qleft_margin);
+ staticpro (&Qdisplay);
Qspace_width = intern ("space-width");
staticpro (&Qspace_width);
Qheight = intern ("height");
staticpro (&Qraise);
Qspace = intern ("space");
staticpro (&Qspace);
+ Qmargin = intern ("margin");
+ staticpro (&Qmargin);
Qleft_margin = intern ("left-margin");
- staticpro (&Qright_margin);
+ staticpro (&Qleft_margin);
Qright_margin = intern ("right-margin");
+ staticpro (&Qright_margin);
Qalign_to = intern ("align-to");
staticpro (&Qalign_to);
QCalign_to = intern (":align-to");
staticpro (&QCrelative_height);
QCeval = intern (":eval");
staticpro (&QCeval);
- QCwhen = intern (":when");
- staticpro (&QCwhen);
+ Qwhen = intern ("when");
+ staticpro (&Qwhen);
+ QCfile = intern (":file");
+ staticpro (&QCfile);
Qfontified = intern ("fontified");
staticpro (&Qfontified);
Qfontification_functions = intern ("fontification-functions");
Qimage = intern ("image");
staticpro (&Qimage);
- staticpro (&last_arrow_position);
- staticpro (&last_arrow_string);
last_arrow_position = Qnil;
last_arrow_string = Qnil;
+ staticpro (&last_arrow_position);
+ staticpro (&last_arrow_string);
echo_buffer[0] = echo_buffer[1] = Qnil;
staticpro (&echo_buffer[0]);