#include "gtkutil.h"
#endif
-#include "font.h"
-
#ifndef FRAME_X_OUTPUT
#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
#endif
static void pint2hrstr (char *, int, ptrdiff_t);
static struct text_pos run_window_scroll_functions (Lisp_Object,
struct text_pos);
-static void reconsider_clip_changes (struct window *, struct buffer *);
static int text_outside_line_unchanged_p (struct window *,
ptrdiff_t, ptrdiff_t);
static void store_mode_line_noprop_char (char);
static void handle_stop_backwards (struct it *, ptrdiff_t);
static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
static void ensure_echo_area_buffers (void);
-static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
+static void unwind_with_echo_area_buffer (Lisp_Object);
static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
static int with_echo_area_buffer (struct window *, int,
int (*) (ptrdiff_t, Lisp_Object),
ptrdiff_t, Lisp_Object);
static void clear_garbaged_frames (void);
static int current_message_1 (ptrdiff_t, Lisp_Object);
-static void pop_message (void);
static int truncate_message_1 (ptrdiff_t, Lisp_Object);
static void set_message (Lisp_Object);
static int set_message_1 (ptrdiff_t, Lisp_Object);
static int display_echo_area (struct window *);
static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
-static Lisp_Object unwind_redisplay (Lisp_Object);
+static void unwind_redisplay (void);
static int string_char_and_length (const unsigned char *, int *);
static struct text_pos display_prop_end (struct it *, Lisp_Object,
struct text_pos);
return make_number (line_bottom_y (&it));
}
+/* Return the default pixel height of text lines in window W. The
+ value is the canonical height of the W frame's default font, plus
+ any extra space required by the line-spacing variable or frame
+ parameter.
+
+ Implementation note: this ignores any line-spacing text properties
+ put on the newline characters. This is because those properties
+ only affect the _screen_ line ending in the newline (i.e., in a
+ continued line, only the last screen line will be affected), which
+ means only a small number of lines in a buffer can ever use this
+ feature. Since this function is used to compute the default pixel
+ equivalent of text lines in a window, we can safely ignore those
+ few lines. For the same reasons, we ignore the line-height
+ properties. */
+int
+default_line_pixel_height (struct window *w)
+{
+ struct frame *f = WINDOW_XFRAME (w);
+ int height = FRAME_LINE_HEIGHT (f);
+
+ if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
+ {
+ struct buffer *b = XBUFFER (w->contents);
+ Lisp_Object val = BVAR (b, extra_line_spacing);
+
+ if (NILP (val))
+ val = BVAR (&buffer_defaults, extra_line_spacing);
+ if (!NILP (val))
+ {
+ if (RANGED_INTEGERP (0, val, INT_MAX))
+ height += XFASTINT (val);
+ else if (FLOATP (val))
+ {
+ int addon = XFLOAT_DATA (val) * height + 0.5;
+
+ if (addon >= 0)
+ height += addon;
+ }
+ }
+ else
+ height += f->extra_line_spacing;
+ }
+
+ return height;
+}
+
/* Subroutine of pos_visible_p below. Extracts a display string, if
any, from the display spec given as its argument. */
static Lisp_Object
struct it save_it = it;
/* Why 10? because we don't know how many canonical lines
will the height of the next line(s) be. So we guess. */
- int ten_more_lines =
- 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w)));
+ int ten_more_lines = 10 * default_line_pixel_height (w);
move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
MOVE_TO_POS | MOVE_TO_Y);
not force the value into range. */
void
-pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
+pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
int *x, int *y, NativeRectangle *bounds, int noclip)
{
composition (in the case that the composition is from the current
buffer), draw a glyph composed from the composition components. */
if (find_composition (pos, -1, &start, &end, &prop, string)
- && COMPOSITION_VALID_P (start, end, prop)
+ && composition_valid_p (start, end, prop)
&& (STRINGP (it->string) || (PT <= start || PT >= end)))
{
if (start < pos)
static int
compare_overlay_entries (const void *e1, const void *e2)
{
- struct overlay_entry *entry1 = (struct overlay_entry *) e1;
- struct overlay_entry *entry2 = (struct overlay_entry *) e2;
+ struct overlay_entry const *entry1 = e1;
+ struct overlay_entry const *entry2 = e2;
int result;
if (entry1->after_string_p != entry2->after_string_p)
start_pos = IT_CHARPOS (*it);
/* Estimate how many newlines we must move back. */
- nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
+ nlines = max (1, dy / default_line_pixel_height (it->w));
if (it->line_wrap == TRUNCATE)
pos_limit = BEGV;
else
void
message1 (const char *m)
{
- message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil);
+ message3 (m ? build_unibyte_string (m) : Qnil);
}
void
message1_nolog (const char *m)
{
- message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil);
+ message3_nolog (m ? build_unibyte_string (m) : Qnil);
}
/* Display a message M which contains a single %s
ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
char *message_buf = alloca (maxsize + 1);
- len = doprnt (message_buf, maxsize, m, (char *)0, ap);
+ len = doprnt (message_buf, maxsize, m, 0, ap);
message3 (make_string (message_buf, len));
}
/* Restore global state from VECTOR which was created by
with_echo_area_buffer_unwind_data. */
-static Lisp_Object
+static void
unwind_with_echo_area_buffer (Lisp_Object vector)
{
set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
}
Vwith_echo_area_save_vector = vector;
- return Qnil;
}
}
-/* Handler for record_unwind_protect calling pop_message. */
+/* Handler for unwind-protect calling pop_message. */
-Lisp_Object
-pop_message_unwind (Lisp_Object dummy)
-{
- pop_message ();
- return Qnil;
-}
-
-/* Pop the top-most entry off Vmessage_stack. */
-
-static void
-pop_message (void)
+void
+pop_message_unwind (void)
{
+ /* Pop the top-most entry off Vmessage_stack. */
eassert (CONSP (Vmessage_stack));
Vmessage_stack = XCDR (Vmessage_stack);
}
&& UNCHANGED_MODIFIED < MODIFF);
}
-/* Nonzero if W doesn't reflect the actual state of current buffer due
- to its text or overlays change. FIXME: this may be called when
- XBUFFER (w->contents) != current_buffer, which looks suspicious. */
-
-static int
-window_outdated (struct window *w)
-{
- return (w->last_modified < MODIFF
- || w->last_overlay_modified < OVERLAY_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. */
return vector;
}
-static Lisp_Object
+static void
unwind_format_mode_line (Lisp_Object vector)
{
Lisp_Object old_window = AREF (vector, 7);
}
Vmode_line_unwind_vector = vector;
- return Qnil;
}
{
f = XFRAME (frame);
if (!EQ (frame, tooltip_frame)
- && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
+ && (FRAME_ICONIFIED_P (f)
+ || FRAME_VISIBLE_P (f) == 1
+ /* Exclude TTY frames that are obscured because they
+ are not the top frame on their console. This is
+ because x_consider_frame_title actually switches
+ to the frame, which for TTY frames means it is
+ marked as garbaged, and will be completely
+ redrawn on the next redisplay cycle. This causes
+ TTY frames to be completely redrawn, when there
+ are more than one of them, even though nothing
+ should be changed on display. */
+ || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
x_consider_frame_title (frame);
}
}
/* EXPORT:
Set the global variable output_cursor to CURSOR. All cursor
- positions are relative to updated_window. */
+ positions are relative to currently updated window. */
void
set_output_cursor (struct cursor_pos *cursor)
/* EXPORT for RIF:
Set a nominal cursor position.
- HPOS and VPOS are column/row positions in a window glyph matrix. X
- and Y are window text area relative pixel positions.
+ HPOS and VPOS are column/row positions in a window glyph matrix.
+ X and Y are window text area relative pixel positions.
- If this is done during an update, updated_window will contain the
- window that is being updated and the position is the future output
- cursor position for that window. If updated_window is null, use
- selected_window and display the cursor at the given position. */
+ This is always done during window update, so the position is the
+ future output cursor position for currently updated window W.
+ NOTE: W is used only to check whether this function is called
+ in a consistent manner via the redisplay interface. */
void
-x_cursor_to (int vpos, int hpos, int y, int x)
+x_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
{
- struct window *w;
-
- /* If updated_window is not set, work on selected_window. */
- if (updated_window)
- w = updated_window;
- else
- w = XWINDOW (selected_window);
+ eassert (w);
/* Set the output cursor. */
output_cursor.hpos = hpos;
output_cursor.vpos = vpos;
output_cursor.x = x;
output_cursor.y = y;
-
- /* If not called as part of an update, really display the cursor.
- This will also set the cursor position of W. */
- if (updated_window == NULL)
- {
- block_input ();
- display_and_set_cursor (w, 1, hpos, vpos, x, y);
- if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
- FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
- unblock_input ();
- }
}
#endif /* HAVE_WINDOW_SYSTEM */
/* Where the mouse was last time we reported a mouse event. */
-FRAME_PTR last_mouse_frame;
+struct frame *last_mouse_frame;
/* Tool-bar item index of the item on which a mouse button was pressed
or -1. */
do_switch_frame.
FIXME: Maybe do_switch_frame should be trimmed down similarly
when `norecord' is set. */
-static Lisp_Object
+static void
fast_set_selected_frame (Lisp_Object frame)
{
if (!EQ (selected_frame, frame))
selected_frame = frame;
selected_window = XFRAME (frame)->selected_window;
}
- return Qnil;
}
/* Update the tool-bar item list for frame F. This has to be done
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qtool_bar_lines,
- make_number (nlines)),
- Qnil));
+ list1 (Fcons (Qtool_bar_lines,
+ make_number (nlines))));
if (WINDOW_TOTAL_LINES (w) != old_height)
{
clear_glyph_matrix (w->desired_matrix);
{
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qtool_bar_lines,
- make_number (nlines)),
- Qnil));
+ list1 (Fcons (Qtool_bar_lines,
+ make_number (nlines))));
if (WINDOW_TOTAL_LINES (w) != old_height)
{
clear_glyph_matrix (w->desired_matrix);
static void
debug_method_add (struct window *w, char const *fmt, ...)
{
+ void *ptr = w;
char *method = w->desired_matrix->method;
int len = strlen (method);
int size = sizeof w->desired_matrix->method;
if (trace_redisplay_p)
fprintf (stderr, "%p (%s): %s\n",
- w,
+ ptr,
((BUFFERP (w->contents)
&& STRINGP (BVAR (XBUFFER (w->contents), name)))
? SSDATA (BVAR (XBUFFER (w->contents), name))
if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
&& find_composition (prev_pt, -1, &start, &end, &prop, buffer)
- && COMPOSITION_VALID_P (start, end, prop)
+ && composition_valid_p (start, end, prop)
&& start < prev_pt && end > prev_pt)
/* The last point was within the composition. Return 1 iff
point moved out of the composition. */
/* Check a composition at the current point. */
return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
&& find_composition (pt, -1, &start, &end, &prop, buffer)
- && COMPOSITION_VALID_P (start, end, prop)
+ && composition_valid_p (start, end, prop)
&& start < pt && end > pt);
}
-
-/* Reconsider the setting of B->clip_changed which is displayed
- in window W. */
+/* Reconsider the clip changes of buffer which is displayed in W. */
static void
-reconsider_clip_changes (struct window *w, struct buffer *b)
+reconsider_clip_changes (struct window *w)
{
+ struct buffer *b = XBUFFER (w->contents);
+
if (b->clip_changed
&& w->window_end_valid
&& w->current_matrix->buffer == b
we set b->clip_changed to 1 to force updating the screen. If
b->clip_changed has already been set to 1, we can skip this
check. */
- if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid)
+ if (!b->clip_changed && w->window_end_valid)
{
- ptrdiff_t pt;
-
- if (w == XWINDOW (selected_window))
- pt = PT;
- else
- pt = marker_position (w->pointm);
+ ptrdiff_t pt = (w == XWINDOW (selected_window)
+ ? PT : marker_position (w->pointm));
- if ((w->current_matrix->buffer != XBUFFER (w->contents)
- || pt != w->last_point)
+ if ((w->current_matrix->buffer != b || pt != w->last_point)
&& check_point_in_composition (w->current_matrix->buffer,
- w->last_point,
- XBUFFER (w->contents), pt))
+ w->last_point, b, pt))
b->clip_changed = 1;
}
}
-\f
#define STOP_POLLING \
do { if (! polling_stopped_here) stop_polling (); \
struct window *sw;
struct frame *fr;
int pending;
- int must_finish = 0;
+ bool must_finish = 0, match_p;
struct text_pos tlbufpos, tlendpos;
int number_of_visible_frames;
- ptrdiff_t count, count1;
+ ptrdiff_t count;
struct frame *sf;
int polling_stopped_here = 0;
Lisp_Object tail, frame;
/* Record a function that clears redisplaying_p
when we leave this function. */
count = SPECPDL_INDEX ();
- record_unwind_protect (unwind_redisplay, selected_frame);
+ record_unwind_protect_void (unwind_redisplay);
redisplaying_p = 1;
specbind (Qinhibit_free_realized_faces, Qnil);
sw = w;
pending = 0;
- reconsider_clip_changes (w, current_buffer);
last_escape_glyph_frame = NULL;
last_escape_glyph_face_id = (1 << FACE_ID_BITS);
last_glyphless_glyph_frame = NULL;
/* do_pending_window_change could change the selected_window due to
frame resizing which makes the selected window too small. */
if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
- {
- sw = w;
- reconsider_clip_changes (w, current_buffer);
- }
+ sw = w;
/* Clear frames marked as garbaged. */
clear_garbaged_frames ();
if (windows_or_buffers_changed)
update_mode_lines++;
- /* Detect case that we need to write or remove a star in the mode line. */
- if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
+ reconsider_clip_changes (w);
+
+ /* In most cases selected window displays current buffer. */
+ match_p = XBUFFER (w->contents) == current_buffer;
+ if (match_p)
{
- w->update_mode_line = 1;
- if (buffer_shared_and_changed ())
- update_mode_lines++;
- }
+ ptrdiff_t count1;
- /* Avoid invocation of point motion hooks by `current_column' below. */
- count1 = SPECPDL_INDEX ();
- specbind (Qinhibit_point_motion_hooks, Qt);
+ /* 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++;
+ }
- if (mode_line_update_needed (w))
- w->update_mode_line = 1;
+ /* 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);
+ unbind_to (count1, Qnil);
+ }
consider_all_windows_p = (update_mode_lines
|| buffer_shared_and_changed ()
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
/* Make sure recorded data applies to current buffer, etc. */
&& this_line_buffer == current_buffer
- && current_buffer == XBUFFER (w->contents)
+ && match_p
&& !w->force_start
&& !w->optional_new_start
/* Point must be on the line that we have info recorded about. */
}
-/* Function registered with record_unwind_protect in redisplay_internal.
- Clear redisplaying_p. Also select the previously selected frame. */
+/* Function registered with record_unwind_protect in redisplay_internal. */
-static Lisp_Object
-unwind_redisplay (Lisp_Object old_frame)
+static void
+unwind_redisplay (void)
{
redisplaying_p = 0;
- return Qnil;
}
struct window *w = XWINDOW (window);
SET_MARKER_FROM_TEXT_POS (w->start, startp);
- if (current_buffer != XBUFFER (w->contents))
- emacs_abort ();
+ eassert (current_buffer == XBUFFER (w->contents));
if (!NILP (Vwindow_scroll_functions))
{
Lisp_Object aggressive;
/* We will never try scrolling more than this number of lines. */
int scroll_limit = SCROLL_LIMIT;
+ int frame_line_height = default_line_pixel_height (w);
+ int window_total_lines
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
#ifdef GLYPH_DEBUG
debug_method_add (w, "try_scrolling");
/* Compute scroll margin height in pixels. We scroll when point is
within this distance from the top or bottom of the window. */
if (scroll_margin > 0)
- this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
- * FRAME_LINE_HEIGHT (f);
+ this_scroll_margin = min (scroll_margin, window_total_lines / 4)
+ * frame_line_height;
else
this_scroll_margin = 0;
if (arg_scroll_conservatively > scroll_limit)
{
arg_scroll_conservatively = scroll_limit + 1;
- scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
+ scroll_max = scroll_limit * frame_line_height;
}
else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
/* Compute how much we should try to scroll maximally to bring
point into view. */
scroll_max = (max (scroll_step,
max (arg_scroll_conservatively, temp_scroll_step))
- * FRAME_LINE_HEIGHT (f));
+ * frame_line_height);
else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
|| NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
/* We're trying to scroll because of aggressive scrolling but no
scroll_step is set. Choose an arbitrary one. */
- scroll_max = 10 * FRAME_LINE_HEIGHT (f);
+ scroll_max = 10 * frame_line_height;
else
scroll_max = 0;
either that ypos or PT, whichever comes first. */
start_display (&it, w, startp);
scroll_margin_y = it.last_visible_y - this_scroll_margin
- - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
+ - frame_line_height * extra_scroll_margin_lines;
move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
(MOVE_TO_POS | MOVE_TO_Y));
the user limited scrolling by a small number of lines, but
always finds PT if scroll_conservatively is set to a large
number, such as most-positive-fixnum. */
- int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
+ int slack = max (scroll_max, 10 * frame_line_height);
int y_to_move = it.last_visible_y + slack;
/* Compute the distance from the scroll margin to PT or to
move it down by scroll_step. */
if (arg_scroll_conservatively)
amount_to_scroll
- = min (max (dy, FRAME_LINE_HEIGHT (f)),
- FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
+ = min (max (dy, frame_line_height),
+ frame_line_height * arg_scroll_conservatively);
else if (scroll_step || temp_scroll_step)
amount_to_scroll = scroll_max;
else
start_display (&it, w, pos);
y0 = it.current_y;
y_to_move = max (it.last_visible_y,
- max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
+ max (scroll_max, 10 * frame_line_height));
move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
y_to_move, -1,
MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
start_display (&it, w, startp);
if (arg_scroll_conservatively)
- amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
+ amount_to_scroll = max (dy, frame_line_height *
max (scroll_step, temp_scroll_step));
else if (scroll_step || temp_scroll_step)
amount_to_scroll = scroll_max;
{
int this_scroll_margin, top_scroll_margin;
struct glyph_row *row = NULL;
+ int frame_line_height = default_line_pixel_height (w);
+ int window_total_lines
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
#ifdef GLYPH_DEBUG
debug_method_add (w, "cursor movement");
of the window. This is a pixel value. */
if (scroll_margin > 0)
{
- this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
- this_scroll_margin *= FRAME_LINE_HEIGHT (f);
+ this_scroll_margin = min (scroll_margin, window_total_lines / 4);
+ this_scroll_margin *= frame_line_height;
}
else
this_scroll_margin = 0;
int centering_position = -1;
int last_line_misfit = 0;
ptrdiff_t beg_unchanged, end_unchanged;
+ int frame_line_height;
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
eassert (XMARKER (w->pointm)->buffer == buffer);
restart:
- reconsider_clip_changes (w, buffer);
+ reconsider_clip_changes (w);
+ frame_line_height = default_line_pixel_height (w);
/* Has the mode line to be updated? */
update_mode_line = (w->update_mode_line
startp = run_window_scroll_functions (window, startp);
}
- w->last_modified = 0;
- w->last_overlay_modified = 0;
if (CHARPOS (startp) < BEGV)
SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
else if (CHARPOS (startp) > ZV)
/* Some people insist on not letting point enter the scroll
margin, even though this part handles windows that didn't
scroll at all. */
- int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
- int pixel_margin = margin * FRAME_LINE_HEIGHT (f);
+ int window_total_lines
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
+ int margin = min (scroll_margin, window_total_lines / 4);
+ int pixel_margin = margin * frame_line_height;
bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
/* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
the Y coordinate of the _next_ row, see the definition of
MATRIX_ROW_BOTTOM_Y. */
if (w->cursor.vpos < margin + header_line)
- new_vpos
- = pixel_margin + (header_line
- ? CURRENT_HEADER_LINE_HEIGHT (w)
- : 0) + FRAME_LINE_HEIGHT (f);
+ {
+ w->cursor.vpos = -1;
+ clear_glyph_matrix (w->desired_matrix);
+ goto try_to_scroll;
+ }
else
{
int window_height = window_box_height (w);
if (header_line)
window_height += CURRENT_HEADER_LINE_HEIGHT (w);
if (w->cursor.y >= window_height - pixel_margin)
- new_vpos = window_height - pixel_margin;
+ {
+ w->cursor.vpos = -1;
+ clear_glyph_matrix (w->desired_matrix);
+ goto try_to_scroll;
+ }
}
}
try_to_scroll:
- w->last_modified = 0;
- w->last_overlay_modified = 0;
-
/* Redisplay the mode line. Select the buffer properly for that. */
if (!update_mode_line)
{
it.current_y = it.last_visible_y;
if (centering_position < 0)
{
+ int window_total_lines
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
int margin =
scroll_margin > 0
- ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+ ? min (scroll_margin, window_total_lines / 4)
: 0;
ptrdiff_t margin_pos = CHARPOS (startp);
Lisp_Object aggressive;
SAVE_IT (it1, it, it1data);
start_display (&it1, w, startp);
- move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f));
+ move_it_vertically (&it1, margin * frame_line_height);
margin_pos = IT_CHARPOS (it1);
RESTORE_IT (&it, &it, it1data);
}
if (pt_offset)
centering_position -= pt_offset;
centering_position -=
- FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
+ frame_line_height * (1 + margin + (last_line_misfit != 0))
+ WINDOW_HEADER_LINE_HEIGHT (w);
/* Don't let point enter the scroll margin near top of
the window. */
- if (centering_position < margin * FRAME_LINE_HEIGHT (f))
- centering_position = margin * FRAME_LINE_HEIGHT (f);
+ if (centering_position < margin * frame_line_height)
+ centering_position = margin * frame_line_height;
}
else
- centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
+ centering_position = margin * frame_line_height + pt_offset;
}
else
/* Set the window start half the height of the window backward
make that row fully visible and out of the margin. */
if (scroll_conservatively > SCROLL_LIMIT)
{
+ int window_total_lines
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
int margin =
scroll_margin > 0
- ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+ ? min (scroll_margin, window_total_lines / 4)
: 0;
- int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2;
+ int move_down = w->cursor.vpos >= window_total_lines / 2;
move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
clear_glyph_matrix (w->desired_matrix);
struct it it;
struct glyph_row *last_text_row = NULL;
struct frame *f = XFRAME (w->frame);
+ int frame_line_height = default_line_pixel_height (w);
/* Make POS the new window start. */
set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
&& !MINI_WINDOW_P (w))
{
int this_scroll_margin;
+ int window_total_lines
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
if (scroll_margin > 0)
{
- this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
- this_scroll_margin *= FRAME_LINE_HEIGHT (f);
+ this_scroll_margin = min (scroll_margin, window_total_lines / 4);
+ this_scroll_margin *= frame_line_height;
}
else
this_scroll_margin = 0;
/* Don't let the cursor end in the scroll margins. */
{
int this_scroll_margin, cursor_height;
+ int frame_line_height = default_line_pixel_height (w);
+ int window_total_lines
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
this_scroll_margin =
- max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
- this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
+ max (0, min (scroll_margin, window_total_lines / 4));
+ this_scroll_margin *= frame_line_height;
cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
if ((w->cursor.y < this_scroll_margin
(Lisp_Object direction)
{
struct window *w = XWINDOW (selected_window);
- struct buffer *b = NULL;
+ struct buffer *b = XBUFFER (w->contents);
struct glyph_row *row;
int dir;
Lisp_Object paragraph_dir;
else
dir = -1;
- if (BUFFERP (w->contents))
- b = XBUFFER (w->contents);
-
/* If current matrix is up-to-date, we can use the information
recorded in the glyphs, at least as long as the goal is on the
screen. */
&& b
&& !b->clip_changed
&& !b->prevent_redisplay_optimizations_p
- && w->last_modified >= BUF_MODIFF (b)
- && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b)
+ && !window_outdated (w)
&& w->cursor.vpos >= 0
&& w->cursor.vpos < w->current_matrix->nrows
&& (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
if (NILP (face))
face = mode_line_string_face;
else
- face = Fcons (face, Fcons (mode_line_string_face, Qnil));
+ face = list2 (face, mode_line_string_face);
props = Fplist_put (props, Qface, face);
}
Fadd_text_properties (make_number (0), make_number (len),
if (NILP (face))
face = mode_line_string_face;
else
- face = Fcons (face, Fcons (mode_line_string_face, Qnil));
- props = Fcons (Qface, Fcons (face, Qnil));
+ face = list2 (face, mode_line_string_face);
+ props = list2 (Qface, face);
if (copy_string)
lisp_string = Fcopy_sequence (lisp_string);
}
mode_line_string_list = Qnil;
mode_line_string_face = face;
mode_line_string_face_prop
- = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
+ = NILP (face) ? Qnil : list2 (Qface, face);
}
push_kboard (FRAME_KBOARD (it.f));
&& hlinfo->mouse_face_beg_row >= 0
&& hlinfo->mouse_face_end_row >= 0)
{
- struct glyph_row *mouse_beg_row, *mouse_end_row;
-
- mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
- mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
+ ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
- if (row >= mouse_beg_row && row <= mouse_end_row)
+ if (row_vpos >= hlinfo->mouse_face_beg_row
+ && row_vpos <= hlinfo->mouse_face_end_row)
{
check_mouse_face = 1;
- mouse_beg_col = (row == mouse_beg_row)
+ mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
? hlinfo->mouse_face_beg_col : 0;
- mouse_end_col = (row == mouse_end_row)
+ mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
? hlinfo->mouse_face_end_col
: row->used[TEXT_AREA];
}
/* EXPORT for RIF:
Output LEN glyphs starting at START at the nominal cursor position.
Advance the nominal cursor over the text. The global variable
- updated_window contains the window being updated, updated_row is
- the glyph row being updated, and updated_area is the area of that
- row being updated. */
+ updated_row is the glyph row being updated, and updated_area is the
+ area of that row being updated. */
void
-x_write_glyphs (struct glyph *start, int len)
+x_write_glyphs (struct window *w, struct glyph *start, int len)
{
- int x, hpos, chpos = updated_window->phys_cursor.hpos;
+ int x, hpos, chpos = w->phys_cursor.hpos;
- eassert (updated_window && updated_row);
+ eassert (updated_row);
/* When the window is hscrolled, cursor hpos can legitimately be out
of bounds, but we draw the cursor at the corresponding window
margin in that case. */
/* Write glyphs. */
hpos = start - updated_row->glyphs[updated_area];
- x = draw_glyphs (updated_window, output_cursor.x,
+ x = draw_glyphs (w, output_cursor.x,
updated_row, updated_area,
hpos, hpos + len,
DRAW_NORMAL_TEXT, 0);
/* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
if (updated_area == TEXT_AREA
- && updated_window->phys_cursor_on_p
- && updated_window->phys_cursor.vpos == output_cursor.vpos
+ && w->phys_cursor_on_p
+ && w->phys_cursor.vpos == output_cursor.vpos
&& chpos >= hpos
&& chpos < hpos + len)
- updated_window->phys_cursor_on_p = 0;
+ w->phys_cursor_on_p = 0;
unblock_input ();
Insert LEN glyphs from START at the nominal cursor position. */
void
-x_insert_glyphs (struct glyph *start, int len)
+x_insert_glyphs (struct window *w, struct glyph *start, int len)
{
struct frame *f;
- struct window *w;
int line_height, shift_by_width, shifted_region_width;
struct glyph_row *row;
struct glyph *glyph;
int frame_x, frame_y;
ptrdiff_t hpos;
- eassert (updated_window && updated_row);
+ eassert (updated_row);
block_input ();
- w = updated_window;
f = XFRAME (WINDOW_FRAME (w));
/* Get the height of the line we are in. */
(inclusive) to pixel column TO_X (exclusive). The idea is that
everything from TO_X onward is already erased.
- TO_X is a pixel position relative to updated_area of
- updated_window. TO_X == -1 means clear to the end of this area. */
+ TO_X is a pixel position relative to updated_area of currently
+ updated window W. TO_X == -1 means clear to the end of this area. */
void
-x_clear_end_of_line (int to_x)
+x_clear_end_of_line (struct window *w, int to_x)
{
struct frame *f;
- struct window *w = updated_window;
int max_x, min_y, max_y;
int from_x, from_y, to_y;
- eassert (updated_window && updated_row);
+ eassert (updated_row);
f = XFRAME (w->frame);
if (updated_row->full_width_p)
/* Are we in a window whose display is up to date?
And verify the buffer's text has not changed. */
b = XBUFFER (w->contents);
- if (part == ON_TEXT
- && w->window_end_valid
- && w->last_modified == BUF_MODIFF (b)
- && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
+ if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
{
int hpos, vpos, dx, dy, area = LAST_AREA;
ptrdiff_t pos;
/* When we're currently updating the window, display and current
matrix usually don't agree. Arrange for a thorough display
later. */
- if (w == updated_window)
+ if (w->must_be_updated_p)
{
SET_FRAME_GARBAGED (f);
return 0;
DEFSYM (Qarrow, "arrow");
DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
- list_of_error = Fcons (Fcons (intern_c_string ("error"),
- Fcons (intern_c_string ("void-variable"), Qnil)),
- Qnil);
+ list_of_error = list1 (list2 (intern_c_string ("error"),
+ intern_c_string ("void-variable")));
staticpro (&list_of_error);
DEFSYM (Qlast_arrow_position, "last-arrow-position");
The symbols on this list are examined during redisplay to determine
where to display overlay arrows. */);
Voverlay_arrow_variable_list
- = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
+ = list1 (intern_c_string ("overlay-arrow-position"));
DEFVAR_INT ("scroll-step", emacs_scroll_step,
doc: /* The number of lines to try scrolling a window by when point moves out.