/* Display generation from window structure and buffer text.
Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
EMACS_INT tool_bar_button_relief;
-/* Non-zero means automatically resize tool-bars so that all tool-bar
- items are visible, and no blank lines remain. */
+/* Non-nil means automatically resize tool-bars so that all tool-bar
+ items are visible, and no blank lines remain.
-int auto_resize_tool_bars_p;
+ If value is `grow-only', only make tool-bar bigger. */
+
+Lisp_Object Vauto_resize_tool_bars;
/* Non-zero means draw block and hollow cursor as wide as the glyph
under it. For example, if a block cursor is over a tab, it will be
static Lisp_Object Vmessages_buffer_name;
-/* Index 0 is the buffer that holds the current (desired) echo area message,
- or nil if none is desired right now.
-
- Index 1 is the buffer that holds the previously displayed echo area message,
- or nil to indicate no message. This is normally what's on the screen now.
-
- These two can point to the same buffer. That happens when the last
- message output by the user (or made by echoing) has been displayed. */
+/* Current, index 0, and last displayed echo area message. Either
+ buffers from echo_buffers, or nil to indicate no message. */
Lisp_Object echo_area_buffer[2];
-/* Permanent pointers to the two buffers that are used for echo area
- purposes. Once the two buffers are made, and their pointers are
- placed here, these two slots remain unchanged unless those buffers
- need to be created afresh. */
+/* The buffers referenced from echo_area_buffer. */
static Lisp_Object echo_buffer[2];
static int clear_image_cache_count;
#endif
-/* Record the previous terminal frame we displayed. */
-
-static struct frame *previous_terminal_frame;
-
/* Non-zero while redisplay_internal is in progress. */
int redisplaying_p;
XSETWINDOW (it->window, w);
it->w = w;
it->f = XFRAME (w->frame);
-
+
/* Extra space between lines (on window systems only). */
if (base_face_id == DEFAULT_FACE_ID
&& FRAME_WINDOW_P (it->f))
/* If realized faces have been removed, e.g. because of face
attribute changes of named faces, recompute them. When running
- in batch mode, the face cache of Vterminal_frame is null. If
+ in batch mode, the face cache of the initial frame is null. If
we happen to get called, make a dummy face cache. */
- if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
+ if (FRAME_FACE_CACHE (it->f) == NULL)
init_frame_faces (it->f);
if (FRAME_FACE_CACHE (it->f)->used == 0)
recompute_basic_faces (it->f);
&& EQ (XCAR (spec), Qheight)
&& CONSP (XCDR (spec)))
{
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
it->font_height = XCAR (XCDR (spec));
&& EQ (XCAR (spec), Qspace_width)
&& CONSP (XCDR (spec)))
{
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
value = XCAR (XCDR (spec));
{
Lisp_Object tem;
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
if (tem = XCDR (spec), CONSP (tem))
&& EQ (XCAR (spec), Qraise)
&& CONSP (XCDR (spec)))
{
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
#ifdef HAVE_WINDOW_SYSTEM
int face_id = DEFAULT_FACE_ID;
int fringe_bitmap;
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
/* If we return here, POSITION has been advanced
across the text with this property. */
return 0;
it->left_user_fringe_face_id = face_id;
}
else
- {
+ {
it->right_user_fringe_bitmap = fringe_bitmap;
it->right_user_fringe_face_id = face_id;
}
valid_p = (STRINGP (value)
#ifdef HAVE_WINDOW_SYSTEM
- || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
+ || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
#endif /* not HAVE_WINDOW_SYSTEM */
- || (CONSP (value) && EQ (XCAR (value), Qspace)));
+ || (CONSP (value) && EQ (XCAR (value), Qspace)));
if (valid_p && !display_replaced_before_p)
{
}
-/* Check if SPEC is a display specification value whose text should be
+/* Check if SPEC is a display sub-property value whose text should be
treated as intangible. */
static int
it->c = *p, it->len = 1;
/* Record what we have and where it came from. */
- it->what = IT_CHARACTER;;
+ it->what = IT_CHARACTER;
it->object = it->w->buffer;
it->position = it->current.pos;
break;
case MOVE_LINE_CONTINUED:
- it->continuation_lines_width += it->current_x;
+ /* For continued lines ending in a tab, some of the glyphs
+ associated with the tab are displayed on the current
+ line. Since it->current_x does not include these glyphs,
+ we use it->last_visible_x instead. */
+ it->continuation_lines_width +=
+ (it->c == '\t') ? it->last_visible_x : it->current_x;
break;
default:
do_pending_window_change (0);
echo_area_display (1);
do_pending_window_change (0);
- if (frame_up_to_date_hook != 0 && ! gc_in_progress)
- (*frame_up_to_date_hook) (f);
+ if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+ (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
}
}
do_pending_window_change (0);
echo_area_display (1);
do_pending_window_change (0);
- if (frame_up_to_date_hook != 0 && ! gc_in_progress)
- (*frame_up_to_date_hook) (f);
+ if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+ (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
}
}
WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
suitable buffer from echo_buffer[] and clear it.
+ If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
+ that the current message becomes the last displayed one, make
+ choose a suitable buffer for echo_area_buffer[0], and clear it.
+
Value is what FN returns. */
static int
this_one = 0, the_other = 1;
else if (which > 0)
this_one = 1, the_other = 0;
+ else
+ {
+ this_one = 0, the_other = 1;
+ clear_buffer_p = 1;
+
+ /* We need a fresh one in case the current echo buffer equals
+ the one containing the last displayed echo area message. */
+ 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
have one. */
= ((s && multibyte_p)
|| (STRINGP (string) && STRING_MULTIBYTE (string)));
- with_echo_area_buffer (0, 0, set_message_1,
+ with_echo_area_buffer (0, -1, set_message_1,
(EMACS_INT) s, string, nbytes, multibyte_p);
message_buf_print = 0;
help_echo_showing_p = 0;
/* Insert new message at BEG. */
TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
- Ferase_buffer ();
if (STRINGP (string))
{
{
Lisp_Object tail, frame;
int changed_count = 0;
-
+
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
-
+
if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
{
if (f->resized_p)
f->resized_p = 0;
}
}
-
+
frame_garbaged = 0;
if (changed_count)
++windows_or_buffers_changed;
/* The terminal frame is used as the first Emacs frame on the Mac OS. */
#ifndef MAC_OS8
#ifdef HAVE_WINDOW_SYSTEM
- /* 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. */
- if (EQ (selected_frame, Vterminal_frame)
- && !NILP (Vwindow_system))
+ /* When Emacs starts, selected_frame may be the initial terminal
+ frame. If we let this through, a message would be displayed on
+ the terminal. */
+ if (FRAME_INITIAL_P (XFRAME (selected_frame)))
return 0;
#endif /* HAVE_WINDOW_SYSTEM */
#endif
Can do with a display update of the echo area,
unless we displayed some mode lines. */
update_single_window (w, 1);
- rif->flush_display (f);
+ FRAME_RIF (f)->flush_display (f);
}
else
update_frame (f, 1, 1);
else if (!EQ (mini_window, selected_window))
windows_or_buffers_changed++;
- /* The current message is now also the last one displayed. */
+ /* Last displayed message is now the current message. */
echo_area_buffer[1] = echo_area_buffer[0];
+ /* Inform read_char that we're not echoing. */
+ echo_message_buffer = Qnil;
/* Prevent redisplay optimization in redisplay_internal by resetting
this_line_start_pos. This is done because the mini-buffer now
{
BLOCK_INPUT;
display_and_set_cursor (w, 1, hpos, vpos, x, y);
- if (rif->flush_display_optional)
- rif->flush_display_optional (SELECTED_FRAME ());
+ if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+ FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
UNBLOCK_INPUT;
}
}
struct frame *f;
int save_match_data;
{
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
int do_update = WINDOWP (f->tool_bar_window)
out:;
row->displays_text_p = row->used[TEXT_AREA] != 0;
- /* Use default face for the border below the tool bar. */
- if (!row->displays_text_p)
+
+ /* Use default face for the border below the tool bar.
+
+ FIXME: When auto-resize-tool-bars is grow-only, there is
+ no additional border below the possibly empty tool-bar lines.
+ So to make the extra empty lines look "normal", we have to
+ use the tool-bar face for the border too. */
+ if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
it->face_id = DEFAULT_FACE_ID;
+
extend_face_to_end_of_line (it);
last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
last->right_box_line_p = 1;
if (!row->displays_text_p)
{
row->height = row->phys_height = it->last_visible_y - row->y;
+ row->visible_height = row->height;
row->ascent = row->phys_ascent = 0;
row->extra_line_spacing = 0;
}
struct window *w;
struct it it;
struct glyph_row *row;
- int change_height_p = 0;
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
return 0;
w->desired_matrix->no_scrolling_p = 1;
w->must_be_updated_p = 1;
- if (auto_resize_tool_bars_p)
+ if (!NILP (Vauto_resize_tool_bars))
{
- int nlines, nrows;
int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
+ int change_height_p = 0;
/* If we couldn't display everything, change the tool-bar's
height if there is room for more. */
/* Resize windows as needed by changing the `tool-bar-lines'
frame parameter. */
- if (change_height_p
- && (nlines = tool_bar_lines_needed (f, &nrows),
- nlines != WINDOW_TOTAL_LINES (w)))
+ if (change_height_p)
{
extern Lisp_Object Qtool_bar_lines;
Lisp_Object frame;
int old_height = WINDOW_TOTAL_LINES (w);
+ int nrows;
+ int nlines = tool_bar_lines_needed (f, &nrows);
- XSETFRAME (frame, f);
- Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qtool_bar_lines,
- make_number (nlines)),
- Qnil));
- if (WINDOW_TOTAL_LINES (w) != old_height)
+ change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
+ && !f->minimize_tool_bar_window_p)
+ ? (nlines > old_height)
+ : (nlines != old_height));
+ f->minimize_tool_bar_window_p = 0;
+
+ if (change_height_p)
{
- clear_glyph_matrix (w->desired_matrix);
- f->n_tool_bar_rows = nrows;
- fonts_changed_p = 1;
+ XSETFRAME (frame, f);
+ Fmodify_frame_parameters (frame,
+ Fcons (Fcons (Qtool_bar_lines,
+ make_number (nlines)),
+ Qnil));
+ if (WINDOW_TOTAL_LINES (w) != old_height)
+ {
+ clear_glyph_matrix (w->desired_matrix);
+ f->n_tool_bar_rows = nrows;
+ fonts_changed_p = 1;
+ return 1;
+ }
}
}
}
- return change_height_p;
+ f->minimize_tool_bar_window_p = 0;
+ return 0;
}
Lisp_Object tail, sym, val;
Lisp_Object old = selected_frame;
+ xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
+
selected_frame = frame;
for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
int must_finish = 0;
struct text_pos tlbufpos, tlendpos;
int number_of_visible_frames;
- int count;
+ int count, count1;
struct frame *sf;
int polling_stopped_here = 0;
return;
}
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
if (popup_activated ())
return;
#endif
if (face_change_count)
++windows_or_buffers_changed;
- if (! FRAME_WINDOW_P (sf)
- && previous_terminal_frame != sf)
+ if (FRAME_TERMCAP_P (sf)
+ && FRAME_TTY (sf)->previous_frame != sf)
{
- /* Since frames on an ASCII terminal share the same display
- area, displaying a different frame means redisplay the whole
- thing. */
+ /* Since frames on a single ASCII terminal share the same
+ display area, displaying a different frame means redisplay
+ the whole thing. */
windows_or_buffers_changed++;
SET_FRAME_GARBAGED (sf);
- XSETFRAME (Vterminal_frame, sf);
+ FRAME_TTY (sf)->previous_frame = sf;
}
- 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
}
}
+
/* Notice any pending interrupt request to change frame size. */
do_pending_window_change (1);
update_mode_lines++;
}
+ /* Avoid invocation of point motion hooks by `current_column' below. */
+ count1 = SPECPDL_INDEX ();
+ specbind (Qinhibit_point_motion_hooks, Qt);
+
/* If %c is in the mode line, update it if needed. */
if (!NILP (w->column_number_displayed)
/* This alternative quickly identifies a common case
!= (int) current_column ())) /* iftc */
w->update_mode_line = Qt;
+ unbind_to (count1, Qnil);
+
FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
/* The variable buffer_shared is set in redisplay_window and
{
struct frame *f = XFRAME (frame);
- if (FRAME_WINDOW_P (f) || f == sf)
+ if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
{
if (! EQ (frame, selected_frame))
/* Select the frame, for the sake of frame-local
/* Mark all the scroll bars to be removed; we'll redeem
the ones we want when we redisplay their windows. */
- if (condemn_scroll_bars_hook)
- condemn_scroll_bars_hook (f);
+ if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
+ FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
redisplay_windows (FRAME_ROOT_WINDOW (f));
/* Any scroll bars which redisplay_windows should have
nuked should now go away. */
- if (judge_scroll_bars_hook)
- judge_scroll_bars_hook (f);
+ if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
+ FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
/* If fonts changed, display again. */
/* ??? rms: I suspect it is a mistake to jump all the way
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
- if (f->updated_p)
- {
- mark_window_display_accurate (f->root_window, 1);
- if (frame_up_to_date_hook)
- frame_up_to_date_hook (f);
- }
+ if (f->updated_p)
+ {
+ mark_window_display_accurate (f->root_window, 1);
+ if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
+ FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
+ }
}
}
}
/* Say overlay arrows are up to date. */
update_overlay_arrows (1);
- if (frame_up_to_date_hook != 0)
- frame_up_to_date_hook (sf);
+ if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
+ FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
}
update_mode_lines = 0;
else
redisplay_internal (1);
- if (rif != NULL && rif->flush_display_optional)
- rif->flush_display_optional (NULL);
+ if (FRAME_RIF (SELECTED_FRAME ()) != NULL
+ && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+ FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
}
redisplay_internal. Reset redisplaying_p to the value it had
before redisplay_internal was called, and clear
prevent_freeing_realized_faces_p. It also selects the previously
- selected frame. */
+ selected frame, unless it has been deleted (by an X connection
+ failure during redisplay, for example). */
static Lisp_Object
unwind_redisplay (val)
old_redisplaying_p = XCAR (val);
redisplaying_p = XFASTINT (old_redisplaying_p);
old_frame = XCDR (val);
- if (! EQ (old_frame, selected_frame))
+ if (! EQ (old_frame, selected_frame)
+ && FRAME_LIVE_P (XFRAME (old_frame)))
select_frame_for_redisplay (old_frame);
return Qnil;
}
start = end = whole = 0;
/* Indicate what this scroll bar ought to be displaying now. */
- set_vertical_scroll_bar_hook (w, end - start, whole, start);
+ if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+ (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+ (w, end - start, whole, start);
}
int rc;
int centering_position = -1;
int last_line_misfit = 0;
+ int beg_unchanged, end_unchanged;
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
set_buffer_internal_1 (XBUFFER (w->buffer));
SET_TEXT_POS (opoint, PT, PT_BYTE);
+ beg_unchanged = BEG_UNCHANGED;
+ end_unchanged = END_UNCHANGED;
+
current_matrix_up_to_date_p
= (!NILP (w->window_end_valid)
&& !current_buffer->clip_changed
w->force_start = Qt;
}
+ force_start:
+
/* Handle case where place to start displaying has been specified,
unless the specified location is outside the accessible range. */
if (!NILP (w->force_start)
/* If first window line is a continuation line, and window start
is inside the modified region, but the first change is before
- current window start, we must select a new window start.*/
- if (NILP (w->start_at_line_beg)
- && CHARPOS (startp) > BEGV)
- {
- /* Make sure beg_unchanged and end_unchanged are up to date.
- Do it only if buffer has really changed. This may or may
- not have been done by try_window_id (see which) already. */
- if (MODIFF > SAVE_MODIFF
- /* This seems to happen sometimes after saving a buffer. */
- || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
- {
- if (GPT - BEG < BEG_UNCHANGED)
- BEG_UNCHANGED = GPT - BEG;
- if (Z - GPT < END_UNCHANGED)
- END_UNCHANGED = Z - GPT;
- }
+ current window start, we must select a new window start.
- if (CHARPOS (startp) > BEG + BEG_UNCHANGED
- && CHARPOS (startp) <= Z - END_UNCHANGED)
- {
- /* There doesn't seems to be a simple way to find a new
- window start that is near the old window start, so
- we just recenter. */
- goto recenter;
- }
- }
+ However, if this is the result of a down-mouse event (e.g. by
+ extending the mouse-drag-overlay), we don't want to select a
+ new window start, since that would change the position under
+ the mouse, resulting in an unwanted mouse-movement rather
+ than a simple mouse-click. */
+ if (NILP (w->start_at_line_beg)
+ && NILP (do_mouse_tracking)
+ && CHARPOS (startp) > BEGV
+ && CHARPOS (startp) > BEG + beg_unchanged
+ && CHARPOS (startp) <= Z - end_unchanged)
+ {
+ w->force_start = Qt;
+ if (XMARKER (w->start)->buffer == current_buffer)
+ compute_window_start_on_continuation_line (w);
+ SET_TEXT_POS_FROM_MARKER (startp, w->start);
+ goto force_start;
+ }
#if GLYPH_DEBUG
debug_method_add (w, "same window start");
display_menu_bar (w);
#ifdef HAVE_WINDOW_SYSTEM
-#ifdef USE_GTK
- redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
+ if (FRAME_WINDOW_P (f))
+ {
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
+ redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
#else
- redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
- && (FRAME_TOOL_BAR_LINES (f) > 0
- || auto_resize_tool_bars_p);
-
+ redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
+ && (FRAME_TOOL_BAR_LINES (f) > 0
+ || !NILP (Vauto_resize_tool_bars));
#endif
- if (redisplay_tool_bar_p)
- redisplay_tool_bar (f);
+ if (redisplay_tool_bar_p && redisplay_tool_bar (f))
+ {
+ extern int ignore_mouse_drag_p;
+ ignore_mouse_drag_p = 1;
+ }
+ }
#endif
}
/* Note that we actually used the scroll bar attached to this
window, so it shouldn't be deleted at the end of redisplay. */
- redeem_scroll_bar_hook (w);
+ if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
+ (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
}
/* Restore current_buffer and value of point in it. */
struct window *w = XWINDOW (window);
struct it it;
struct glyph_row *last_text_row = NULL;
+ struct frame *f = XFRAME (w->frame);
/* Make POS the new window start. */
set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
if (run.height > 0 && run.current_y != run.desired_y)
{
update_begin (f);
- rif->update_window_begin_hook (w);
- rif->clear_window_mouse_face (w);
- rif->scroll_run_hook (w, &run);
- rif->update_window_end_hook (w, 0, 0);
+ FRAME_RIF (f)->update_window_begin_hook (w);
+ FRAME_RIF (f)->clear_window_mouse_face (w);
+ FRAME_RIF (f)->scroll_run_hook (w, &run);
+ FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
update_end (f);
}
nrows_scrolled);
/* Disable lines that must be updated. */
- for (i = 0; i < it.vpos; ++i)
+ for (i = 0; i < nrows_scrolled; ++i)
(start_row + i)->enabled_p = 0;
/* Re-compute Y positions. */
if (run.height)
{
update_begin (f);
- rif->update_window_begin_hook (w);
- rif->clear_window_mouse_face (w);
- rif->scroll_run_hook (w, &run);
- rif->update_window_end_hook (w, 0, 0);
+ FRAME_RIF (f)->update_window_begin_hook (w);
+ FRAME_RIF (f)->clear_window_mouse_face (w);
+ FRAME_RIF (f)->scroll_run_hook (w, &run);
+ FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
update_end (f);
}
/* Window must either use window-based redisplay or be full width. */
if (!FRAME_WINDOW_P (f)
- && (!line_ins_del_ok
+ && (!FRAME_LINE_INS_DEL_OK (f)
|| !WINDOW_FULL_WIDTH_P (w)))
GIVE_UP (4);
if (FRAME_WINDOW_P (f))
{
- rif->update_window_begin_hook (w);
- rif->clear_window_mouse_face (w);
- rif->scroll_run_hook (w, &run);
- rif->update_window_end_hook (w, 0, 0);
+ FRAME_RIF (f)->update_window_begin_hook (w);
+ FRAME_RIF (f)->clear_window_mouse_face (w);
+ FRAME_RIF (f)->scroll_run_hook (w, &run);
+ FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
}
else
{
{
/* Scroll last_unchanged_at_beg_row to the end of the
window down dvpos lines. */
- set_terminal_window (end);
+ set_terminal_window (f, end);
/* On dumb terminals delete dvpos lines at the end
before inserting dvpos empty lines. */
- if (!scroll_region_ok)
- ins_del_lines (end - dvpos, -dvpos);
+ if (!FRAME_SCROLL_REGION_OK (f))
+ ins_del_lines (f, end - dvpos, -dvpos);
/* Insert dvpos empty lines in front of
last_unchanged_at_beg_row. */
- ins_del_lines (from, dvpos);
+ ins_del_lines (f, from, dvpos);
}
else if (dvpos < 0)
{
/* Scroll up last_unchanged_at_beg_vpos to the end of
the window to last_unchanged_at_beg_vpos - |dvpos|. */
- set_terminal_window (end);
+ set_terminal_window (f, end);
/* Delete dvpos lines in front of
last_unchanged_at_beg_vpos. ins_del_lines will set
the cursor to the given vpos and emit |dvpos| delete
line sequences. */
- ins_del_lines (from + dvpos, dvpos);
+ ins_del_lines (f, from + dvpos, dvpos);
/* On a dumb terminal insert dvpos empty lines at the
end. */
- if (!scroll_region_ok)
- ins_del_lines (end + dvpos, -dvpos);
+ if (!FRAME_SCROLL_REGION_OK (f))
+ ins_del_lines (f, end + dvpos, -dvpos);
}
- set_terminal_window (0);
+ set_terminal_window (f, 0);
}
update_end (f);
sync_frame_with_window_matrix_rows (w);
/* Adjust buffer positions in reused rows. */
- if (delta)
+ if (delta || delta_bytes)
increment_matrix_positions (current_matrix,
first_unchanged_at_end_vpos + dvpos,
bottom_vpos, delta, delta_bytes);
if (PT == MATRIX_ROW_END_CHARPOS (row))
{
- /* If the row ends with a newline from a string, we don't want
- the cursor there, but we still want it at the start of the
- string if the string starts in this row.
- If the row is continued it doesn't end in a newline. */
+ /* Suppose the row ends on a string.
+ Unless the row is continued, that means it ends on a newline
+ in the string. If it's anything other than a display string
+ (e.g. a before-string from an overlay), we don't want the
+ cursor there. (This heuristic seems to give the optimal
+ behavior for the various types of multi-line strings.) */
if (CHARPOS (row->end.string_pos) >= 0)
- cursor_row_p = (row->continued_p
- || PT >= MATRIX_ROW_START_CHARPOS (row));
+ {
+ if (row->continued_p)
+ cursor_row_p = 1;
+ else
+ {
+ /* Check for `display' property. */
+ struct glyph *beg = row->glyphs[TEXT_AREA];
+ struct glyph *end = beg + row->used[TEXT_AREA] - 1;
+ struct glyph *glyph;
+
+ cursor_row_p = 0;
+ for (glyph = end; glyph >= beg; --glyph)
+ if (STRINGP (glyph->object))
+ {
+ Lisp_Object prop
+ = Fget_char_property (make_number (PT),
+ Qdisplay, Qnil);
+ cursor_row_p =
+ (!NILP (prop)
+ && display_prop_string_p (prop, glyph->object));
+ break;
+ }
+ }
+ }
else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
{
/* If the row ends in middle of a real character,
/* Don't do all this for graphical frames. */
#ifdef HAVE_NTGUI
- if (!NILP (Vwindow_system))
+ if (FRAME_W32_P (f))
return;
#endif
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Temporarily make frame's keyboard the current kboard so that
kboard-local variables in the mode_line_format will get the right
values. */
- push_frame_kboard (it.f);
+ push_kboard (FRAME_KBOARD (it.f));
record_unwind_save_match_data ();
display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
- pop_frame_kboard ();
+ pop_kboard ();
unbind_to (count, Qnil);
Optional second arg FACE specifies the face property to put
on all characters for which no face is specified.
-t means whatever face the window's mode line currently uses
+The value t means whatever face the window's mode line currently uses
\(either `mode-line' or `mode-line-inactive', depending).
-nil means the default is no face property.
+A value of nil means the default is no face property.
If FACE is an integer, the value string has no text properties.
Optional third and fourth args WINDOW and BUFFER specify the window
CHECK_BUFFER (buffer);
if (NILP (format))
- return build_string ("");
+ return empty_unibyte_string;
if (no_props)
face = Qnil;
= (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
}
- push_frame_kboard (it.f);
+ push_kboard (FRAME_KBOARD (it.f));
display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
- pop_frame_kboard ();
+ pop_kboard ();
if (no_props)
{
{
mode_line_string_list = Fnreverse (mode_line_string_list);
str = Fmapconcat (intern ("identity"), mode_line_string_list,
- make_string ("", 0));
+ empty_unibyte_string);
}
unbind_to (count, Qnil);
#endif
break;
+ case '@':
+ {
+ Lisp_Object val;
+ val = call1 (intern ("file-remote-p"), current_buffer->directory);
+ if (NILP (val))
+ return "-";
+ else
+ return "@";
+ }
+
case 't': /* indicate TEXT or BINARY */
#ifdef MODE_LINE_BINARY_TEXT
return MODE_LINE_BINARY_TEXT (b);
{
/* No need to mention EOL here--the terminal never needs
to do EOL conversion. */
- p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
- p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
+ p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
+ p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
}
p = decode_mode_spec_coding (b->buffer_file_coding_system,
p, eol_flag);
if (NILP (prop))
return OK_PIXELS (0);
+ xassert (FRAME_LIVE_P (it->f));
+
if (SYMBOLP (prop))
{
if (SCHARS (SYMBOL_NAME (prop)) == 2)
if (SYMBOLP (car))
{
#ifdef HAVE_WINDOW_SYSTEM
- if (valid_image_p (prop))
+ if (FRAME_WINDOW_P (it->f)
+ && valid_image_p (prop))
{
int id = lookup_image (it->f, prop);
struct image *img = IMAGE_FROM_ID (it->f, id);
= FONT_INFO_FROM_ID (f, face->font_info_id);
if (font_info)
glyph->font_type
- = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
+ = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
}
}
font = face->font;
font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
if (font /* ++KFS: Should this be font_info ? */
- && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
+ && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
{
if (pcm->rbearing > pcm->width)
*right = pcm->rbearing - pcm->width;
struct font_info *font_info
= FONT_INFO_FROM_ID (f, face->font_info_id);
if (font_info)
- rif->encode_char (c, char2b, font_info, 0);
+ FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
}
}
{
while (s)
{
- if (rif->compute_glyph_string_overhangs)
- rif->compute_glyph_string_overhangs (s);
+ if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+ FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
x -= s->width;
s->x = x;
s = s->prev;
{
while (s)
{
- if (rif->compute_glyph_string_overhangs)
- rif->compute_glyph_string_overhangs (s);
+ if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+ FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
s->x = x;
x += s->width;
s = s->next;
struct glyph_string *h, *t;
/* Compute overhangs for all glyph strings. */
- if (rif->compute_glyph_string_overhangs)
+ if (FRAME_RIF (f)->compute_glyph_string_overhangs)
for (s = head; s; s = s->next)
- rif->compute_glyph_string_overhangs (s);
+ FRAME_RIF (f)->compute_glyph_string_overhangs (s);
/* Prepend glyph strings for glyphs in front of the first glyph
string that are overwritten because of the first glyph
/* Draw all strings. */
for (s = head; s; s = s->next)
- rif->draw_glyph_string (s);
+ FRAME_RIF (f)->draw_glyph_string (s);
if (area == TEXT_AREA
&& !row->full_width_p
it->nglyphs = 1;
- pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
-
- if (it->override_ascent >= 0)
- {
- it->ascent = it->override_ascent;
- it->descent = it->override_descent;
- boff = it->override_boff;
- }
- else
- {
- it->ascent = FONT_BASE (font) + boff;
- it->descent = FONT_DESCENT (font) - boff;
- }
+ pcm = FRAME_RIF (it->f)->per_char_metric
+ (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
+
+ if (it->override_ascent >= 0)
+ {
+ it->ascent = it->override_ascent;
+ it->descent = it->override_descent;
+ boff = it->override_boff;
+ }
+ else
+ {
+ it->ascent = FONT_BASE (font) + boff;
+ it->descent = FONT_DESCENT (font) - boff;
+ }
if (pcm)
{
from the charset width; this is what old redisplay code
did. */
- pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_MULTIBYTE (font, it->c));
+ pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+ FONT_TYPE_FOR_MULTIBYTE (font, it->c));
if (font_not_found_p || !pcm)
{
/* Initialize the bounding box. */
if (font_info
- && (pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
+ && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+ FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
{
width = pcm->width;
ascent = pcm->ascent;
}
if (font_info
- && (pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_MULTIBYTE (font, ch))))
+ && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+ FONT_TYPE_FOR_MULTIBYTE (font, ch))))
{
width = pcm->width;
ascent = pcm->ascent;
frame_x = window_box_left (w, updated_area) + output_cursor.x;
frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
- rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
- line_height, shift_by_width);
+ FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
+ line_height, shift_by_width);
/* Write the glyphs. */
hpos = start - row->glyphs[updated_area];
if (to_x > from_x && to_y > from_y)
{
BLOCK_INPUT;
- rif->clear_frame_area (f, from_x, from_y,
- to_x - from_x, to_y - from_y);
+ FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
+ to_x - from_x, to_y - from_y);
UNBLOCK_INPUT;
}
}
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
if (width > 0)
- rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
+ FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
}
/* Erase the cursor by redrawing the character underneath it. */
w->phys_cursor.vpos = vpos;
}
- rif->draw_window_cursor (w, glyph_row, x, y,
- new_cursor_type, new_cursor_width,
- on, active_cursor);
+ FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
+ new_cursor_type, new_cursor_width,
+ on, active_cursor);
}
}
/* Change the mouse cursor. */
- if (draw == DRAW_NORMAL_TEXT)
- rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
+ if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
+ FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
else if (draw == DRAW_MOUSE_FACE)
- rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
+ FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
else
- rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
+ FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
}
/* EXPORT:
return inside;
}
}
- /* If we don't understand the format, pretend we're not in the hot-spot. */
return 0;
}
}
if (cursor != No_Cursor)
- rif->define_frame_cursor (f, cursor);
+ FRAME_RIF (f)->define_frame_cursor (f, cursor);
}
/* Take proper action when mouse has moved to the mode or header line
Lisp_Object mouse_face;
int original_x_pixel = x;
- struct glyph * glyph = NULL;
+ struct glyph * glyph = NULL, * row_start_glyph = NULL;
struct glyph_row *row;
if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
/* Find glyph */
if (row->mode_line_p && row->enabled_p)
{
- glyph = row->glyphs[TEXT_AREA];
+ glyph = row_start_glyph = row->glyphs[TEXT_AREA];
end = glyph + row->used[TEXT_AREA];
for (x0 = original_x_pixel;
is converted to a flatten by emacs lisp interpreter.
The internal string is an element of the structures.
The displayed string is the flatten string. */
- for (tmp_glyph = glyph - 1, gpos = 0;
- tmp_glyph->charpos >= XINT (b);
- tmp_glyph--, gpos++)
+ gpos = 0;
+ if (glyph > row_start_glyph)
{
- if (!EQ (tmp_glyph->object, glyph->object))
- break;
+ tmp_glyph = glyph - 1;
+ while (tmp_glyph >= row_start_glyph
+ && tmp_glyph->charpos >= XINT (b)
+ && EQ (tmp_glyph->object, glyph->object))
+ {
+ tmp_glyph--;
+ gpos++;
+ }
}
/* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
struct buffer *b;
/* When a menu is active, don't highlight because this looks odd. */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
if (popup_activated ())
return;
#endif
I assume the effect is the same -- and this is portable. */
return x_intersect_rectangles (&cr, r, &result);
}
- else
- return 0;
+ /* If we don't understand the format, pretend we're not in the hot-spot. */
+ return 0;
}
x_draw_vertical_border (w)
struct window *w;
{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+
/* We could do better, if we knew what type of scroll-bar the adjacent
windows (on either side) have... But we don't :-(
However, I think this works ok. ++KFS 2003-04-25 */
y1 -= 1;
if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
- x1 -= 1;
+ x1 -= 1;
- rif->draw_vertical_window_border (w, x1, y0, y1);
+ FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
}
else if (!WINDOW_LEFTMOST_P (w)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
y1 -= 1;
if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
- x0 -= 1;
+ x0 -= 1;
- rif->draw_vertical_window_border (w, x0, y0, y1);
+ FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
}
}
truncate_partial_width_windows = 1;
DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
- doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
+ doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
Any other value means to use the appropriate face, `mode-line',
`header-line', or `menu' respectively. */);
mode_line_inverse_video = 1;
= Vframe_title_format
= Fcons (intern ("multiple-frames"),
Fcons (build_string ("%b"),
- Fcons (Fcons (empty_string,
+ Fcons (Fcons (empty_unibyte_string,
Fcons (intern ("invocation-name"),
Fcons (build_string ("@"),
Fcons (intern ("system-name"),
doc: /* Maximum number of lines to keep in the message log buffer.
If nil, disable message logging. If t, log messages but don't truncate
the buffer when it becomes large. */);
- Vmessage_log_max = make_number (50);
+ Vmessage_log_max = make_number (100);
DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
doc: /* Functions called before redisplay, if window sizes have changed.
unselects the minibuffer if it is active. */);
Vmouse_autoselect_window = Qnil;
- DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
+ DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
doc: /* *Non-nil means automatically resize tool-bars.
-This increases a tool-bar's height if not all tool-bar items are visible.
-It decreases a tool-bar's height when it would display blank lines
-otherwise. */);
- auto_resize_tool_bars_p = 1;
+This dynamically changes the tool-bar's height to the minimum height
+that is needed to make all tool-bar items visible.
+If value is `grow-only', the tool-bar's height is only increased
+automatically; to decrease the tool-bar height, use \\[recenter]. */);
+ Vauto_resize_tool_bars = Qt;
DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);