Lisp_Object Qinhibit_eval_during_redisplay;
Lisp_Object Qbuffer_position, Qposition, Qobject;
+/* Cursor shapes */
+Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
+
Lisp_Object Qrisky_local_variable;
/* Holds the list (error). */
/* Non-zero means we want a hollow cursor in windows that are not
selected. Zero means there's no cursor in such windows. */
-int cursor_in_non_selected_windows;
+Lisp_Object Vcursor_in_non_selected_windows;
Lisp_Object Qcursor_in_non_selected_windows;
+/* Specifies the desired cursor-type to use to show the blinking
+ cursor off state and cursor shown in non-selected windows.
+ t means to use the default. */
+
+Lisp_Object Valternate_cursor_type;
+Lisp_Object Qalternate_cursor_type;
+
+/* How to blink the default frame cursor off. */
+Lisp_Object Vblink_cursor_alist;
+
/* A scratch glyph row with contents used for generating truncation
glyphs. Also used in direct_output_for_insert. */
MOVE_NEWLINE_OR_CR
};
+/* This counter is used to clear the face cache every once in a while
+ in redisplay_internal. It is incremented for each redisplay.
+ Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
+ cleared. */
+
+#define CLEAR_FACE_CACHE_COUNT 500
+static int clear_face_cache_count;
+
+/* Record the previous terminal frame we displayed. */
+
+static struct frame *previous_terminal_frame;
+
+/* Non-zero while redisplay_internal is in progress. */
+
+int redisplaying_p;
+
+/* Non-zero means don't free realized faces. Bound while freeing
+ realized faces is dangerous because glyph matrices might still
+ reference them. */
+
+int inhibit_free_realized_faces;
+Lisp_Object Qinhibit_free_realized_faces;
\f
/* Function prototypes. */
static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
static void store_frame_title_char P_ ((char));
-static int store_frame_title P_ ((unsigned char *, int, int));
+static int store_frame_title P_ ((const unsigned char *, int, int));
static void x_consider_frame_title P_ ((Lisp_Object));
static void handle_stop P_ ((struct it *));
static int tool_bar_lines_needed P_ ((struct frame *));
static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
-static int string_char_and_length P_ ((unsigned char *, int, int *));
+static int string_char_and_length P_ ((const unsigned char *, int, int *));
static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
struct text_pos));
static int compute_window_start_on_continuation_line P_ ((struct window *));
static INLINE int
string_char_and_length (str, maxlen, len)
- unsigned char *str;
+ const unsigned char *str;
int maxlen, *len;
{
int c;
if (STRING_MULTIBYTE (string))
{
int rest = SBYTES (string) - BYTEPOS (pos);
- unsigned char *p = SDATA (string) + BYTEPOS (pos);
+ const unsigned char *p = SDATA (string) + BYTEPOS (pos);
int len;
while (nchars--)
val = Qnil;
else
{
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
struct gcpro gcpro1;
GCPRO1 (sexpr);
val = Qnil;
else
{
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
struct gcpro gcpro1;
GCPRO1 (args[0]);
/* If face attributes have been changed since the last redisplay,
free realized faces now because they depend on face definitions
- that might have changed. */
- if (face_change_count)
+ that might have changed. Don't free faces while there might be
+ desired matrices pending which reference these faces. */
+ if (face_change_count && !inhibit_free_realized_faces)
{
face_change_count = 0;
free_all_realized_faces (Qnil);
for (i = 0; i < it->n_overlay_strings; ++i)
{
- char *s = SDATA (it->overlay_strings[i]);
- char *e = s + SBYTES (it->overlay_strings[i]);
+ const char *s = SDATA (it->overlay_strings[i]);
+ const char *e = s + SBYTES (it->overlay_strings[i]);
while (s < e && *s != '\n')
++s;
prop = Fget_char_property (pos, Qfontified, Qnil),
NILP (prop)))
{
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
Lisp_Object val;
val = Vfontification_functions;
suitable for unibyte text if IT->string is unibyte. */
if (STRING_MULTIBYTE (it->string))
{
- unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
+ const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
int rest = SBYTES (it->string) - BYTEPOS (pos);
int c, len;
struct face *face = FACE_FROM_ID (it->f, face_id);
suitable for unibyte text if current_buffer is unibyte. */
if (it->multibyte_p)
{
- int c = FETCH_MULTIBYTE_CHAR (CHARPOS (pos));
+ int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
struct face *face = FACE_FROM_ID (it->f, face_id);
face_id = FACE_FOR_CHAR (it->f, face, c);
}
if (!NILP (form) && !EQ (form, Qt))
{
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
struct gcpro gcpro1;
/* Bind `object' to the object having the `display' property, a
/* Evaluate IT->font_height with `height' bound to the
current specified height to get the new height. */
Lisp_Object value;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
value = safe_eval (it->font_height);
it->stop_charpos = 0;
xassert (STRINGP (it->string));
it->end_charpos = SCHARS (it->string);
- it->multibyte_p = SMBP (it->string);
+ it->multibyte_p = STRING_MULTIBYTE (it->string);
it->method = next_element_from_string;
}
else
n += STRINGP (it->string) ? 0 : 1)
{
if (!get_next_display_element (it))
- break;
+ return 0;
newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
set_iterator_to_next (it, 0);
}
/* If we didn't find a newline near enough, see if we can use a
short-cut. */
- if (n == MAX_NEWLINE_DISTANCE)
+ if (!newline_found_p)
{
int start = IT_CHARPOS (*it);
int limit = find_next_newline_no_quit (start, 1);
are invisible. */
if (it->selective > 0
&& indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
- (float) it->selective)) /* iftc */
+ (double) it->selective)) /* iftc */
visible_p = 0;
else
{
if (it->selective > 0)
while (IT_CHARPOS (*it) < ZV
&& indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
- (float) it->selective)) /* iftc */
+ (double) it->selective)) /* iftc */
{
xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
newline_found_p = forward_to_next_line_start (it, &skipped_p);
the translation. This could easily be changed but I
don't believe that it is worth doing.
- Non-printable multibyte characters are also translated
- octal form. */
- else if ((it->c < ' '
+ If it->multibyte_p is nonzero, eight-bit characters and
+ non-printable multibyte characters are also translated to
+ octal form.
+
+ If it->multibyte_p is zero, eight-bit characters that
+ don't have corresponding multibyte char code are also
+ translated to octal form. */
+ else if (((it->c < ' ' || it->c == 127)
&& (it->area != TEXT_AREA
|| (it->c != '\n' && it->c != '\t')))
- || (it->c >= 127
- && it->len == 1)
- || !CHAR_PRINTABLE_P (it->c))
+ || (it->multibyte_p
+ ? ((it->c >= 127
+ && it->len == 1)
+ || !CHAR_PRINTABLE_P (it->c))
+ : (it->c >= 128
+ && it->c == unibyte_char_to_multibyte (it->c))))
{
/* IT->c is a control character which must be displayed
either as '\003' or as `^C' where the '\\' and '^'
else if (STRING_MULTIBYTE (it->string))
{
int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
- unsigned char *s = SDATA (it->string) + IT_STRING_BYTEPOS (*it);
+ const unsigned char *s = (SDATA (it->string)
+ + IT_STRING_BYTEPOS (*it));
it->c = string_char_and_length (s, remaining, &it->len);
}
else
else if (STRING_MULTIBYTE (it->string))
{
int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
- unsigned char *s = SDATA (it->string) + IT_STRING_BYTEPOS (*it);
+ const unsigned char *s = (SDATA (it->string)
+ + IT_STRING_BYTEPOS (*it));
it->c = string_char_and_length (s, maxlen, &it->len);
}
else
&& IT_CHARPOS (*it) + 1 < ZV
&& indented_beyond_p (IT_CHARPOS (*it) + 1,
IT_BYTEPOS (*it) + 1,
- (float) it->selective)) /* iftc */
+ (double) it->selective)) /* iftc */
{
success_p = next_element_from_ellipsis (it);
it->dpvec_char_len = -1;
void
message_dolog (m, nbytes, nlflag, multibyte)
- char *m;
+ const char *m;
int nbytes, nlflag, multibyte;
{
+ if (!NILP (Vmemory_full))
+ return;
+
if (!NILP (Vmessage_log_max))
{
struct buffer *oldbuf;
void
message2 (m, nbytes, multibyte)
- char *m;
+ const char *m;
int nbytes;
int multibyte;
{
void
message2_nolog (m, nbytes, multibyte)
- char *m;
+ const char *m;
int nbytes;
{
struct frame *sf = SELECTED_FRAME ();
message = Fformat (2, args);
if (log)
- message3 (message, SBYTES (message), SMBP (message));
+ message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
else
- message3_nolog (message, SBYTES (message), SMBP (message));
+ message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
UNGCPRO;
}
-/* Make sure echo area buffers in echo_buffers[] are life. If they
- aren't, make new ones. */
+/* Make sure echo area buffers in `echo_buffers' are live.
+ If they aren't, make new ones. */
static void
ensure_echo_area_buffers ()
{
Lisp_Object buffer;
int this_one, the_other, clear_buffer_p, rc;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
/* If buffers aren't live, make new ones. */
ensure_echo_area_buffers ();
if (Z > BEG)
{
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
specbind (Qinhibit_read_only, Qt);
+ /* Note that undo recording is always disabled. */
del_range (BEG, Z);
unbind_to (count, Qnil);
}
xassert (CONSP (Vmessage_stack));
msg = XCAR (Vmessage_stack);
if (STRINGP (msg))
- message3_nolog (msg, SBYTES (msg), SMBP (msg));
+ message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
else
message3_nolog (msg, 0, 0);
}
void
set_message (s, string, nbytes, multibyte_p)
- char *s;
+ const char *s;
Lisp_Object string;
int nbytes;
{
Lisp_Object a2;
EMACS_INT nbytes, multibyte_p;
{
- char *s = (char *) a1;
+ const char *s = (const char *) a1;
Lisp_Object string = a2;
xassert (BEG == Z);
{
/* Convert from single-byte to multi-byte. */
int i, c, n;
- unsigned char *msg = (unsigned char *) s;
+ const unsigned char *msg = (const unsigned char *) s;
unsigned char str[MAX_MULTIBYTE_LENGTH];
/* Convert a single-byte string to multibyte. */
/* Must update other windows. Likewise as in other
cases, don't let this update be interrupted by
pending input. */
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
specbind (Qredisplay_dont_pause, Qt);
windows_or_buffers_changed = 1;
redisplay_internal (0);
static int
store_frame_title (str, field_width, precision)
- unsigned char *str;
+ const unsigned char *str;
int field_width, precision;
{
int n = 0;
if (all_windows)
{
Lisp_Object tail, frame;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
!= !NILP (w->region_showing)))
{
struct buffer *prev = current_buffer;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
specbind (Qinhibit_menubar_update, Qt);
!= !NILP (w->region_showing)))
{
struct buffer *prev = current_buffer;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
/* Set current_buffer to the buffer of the selected
window of the frame, so that we get the right local
#endif /* GLYPH_DEBUG */
-/* This counter is used to clear the face cache every once in a while
- in redisplay_internal. It is incremented for each redisplay.
- Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
- cleared. */
-
-#define CLEAR_FACE_CACHE_COUNT 500
-static int clear_face_cache_count;
-
-/* Record the previous terminal frame we displayed. */
-
-static struct frame *previous_terminal_frame;
-
-/* Non-zero while redisplay_internal is in progress. */
-
-int redisplaying_p;
-
-
/* Value is non-zero if all changes in window W, which displays
current_buffer, are in the text between START and END. START is a
buffer position, END is given as a distance from Z. Used in
struct window *w;
struct buffer *b;
{
- if (b->prevent_redisplay_optimizations_p)
- b->clip_changed = 1;
- else if (b->clip_changed
+ if (b->clip_changed
&& !NILP (w->window_end_valid)
&& w->current_matrix->buffer == b
&& w->current_matrix->zv == BUF_ZV (b)
/* Record a function that resets redisplaying_p to its old value
when we leave this function. */
- count = BINDING_STACK_SIZE ();
+ count = SPECPDL_INDEX ();
record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
++redisplaying_p;
+ specbind (Qinhibit_free_realized_faces, Qnil);
retry:
pause = 0;
&& CHARPOS (tlbufpos) > 0
&& NILP (w->update_mode_line)
&& !current_buffer->clip_changed
+ && !current_buffer->prevent_redisplay_optimizations_p
&& FRAME_VISIBLE_P (XFRAME (w->frame))
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
/* Make sure recorded data applies to current buffer, etc. */
redisplay_window_error);
/* Compare desired and current matrices, perform output. */
+
update:
-
/* If fonts changed, display again. */
if (fonts_changed_p)
goto retry;
if (windows_or_buffers_changed && !pause)
goto retry;
- end_of_redisplay:;
-
+ end_of_redisplay:
unbind_to (count, Qnil);
}
/* Function registered with record_unwind_protect in
- redisplay_internal. Clears the flag indicating that a redisplay is
- in progress. */
+ redisplay_internal. Reset redisplaying_p to the value it had
+ before redisplay_internal was called, and clear
+ prevent_freeing_realized_faces_p. */
static Lisp_Object
unwind_redisplay (old_redisplaying_p)
}
-/* Modify the desired matrix of window W and W->vscroll so that the
- line containing the cursor is fully visible.
- A value of 1 means there is nothing to be done or we did it.
- A value of 0 causes redisplay. */
+/* Make sure the line containing the cursor is fully visible.
+ A value of 1 means there is nothing to be done.
+ (Either the line is fully visible, or it cannot be made so,
+ or we cannot tell.)
+ A value of 0 means the caller should do scrolling
+ as if point had gone off the screen. */
static int
make_cursor_line_fully_visible (w)
if (row->height >= window_height)
return 1;
+ return 0;
+
+#if 0
+ /* This code used to try to scroll the window just enough to make
+ the line visible. It returned 0 to say that the caller should
+ allocate larger glyph matrices. */
+
if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
{
int dy = row->height - row->visible_height;
}
return 1;
+#endif /* 0 */
}
{
int y0;
+ too_near_end:
/* Point is in the scroll margin at the bottom of the window, or
below. Compute a new window start that makes point visible. */
|| BEG_UNCHANGED < CHARPOS (startp))
w->base_line_number = Qnil;
- /* If cursor ends up on a partially visible line, shift display
- lines up or down. If that fails because we need larger
- matrices, give up. */
- if (!make_cursor_line_fully_visible (w))
- rc = SCROLLING_NEED_LARGER_MATRICES;
- else
- rc = SCROLLING_SUCCESS;
+ /* If cursor ends up on a partially visible line,
+ treat that as being off the bottom of the screen. */
+ if (! make_cursor_line_fully_visible (w))
+ goto too_near_end;
+ rc = SCROLLING_SUCCESS;
}
return rc;
set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
try_window (window, startp);
if (!make_cursor_line_fully_visible (w))
- rc = CURSOR_MOVEMENT_NEED_LARGER_MATRICES;
+ rc = CURSOR_MOVEMENT_MUST_SCROLL;
else
rc = CURSOR_MOVEMENT_SUCCESS;
}
struct it it;
/* Record it now because it's overwritten. */
int current_matrix_up_to_date_p = 0;
+ /* This is less strict than current_matrix_up_to_date_p.
+ It indictes that the buffer contents and narrowing are unchanged. */
+ int buffer_unchanged_p = 0;
int temp_scroll_step = 0;
- int count = BINDING_STACK_SIZE ();
+ int count = SPECPDL_INDEX ();
int rc;
+ int centering_position;
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
/* Has the mode line to be updated? */
update_mode_line = (!NILP (w->update_mode_line)
|| update_mode_lines
- || buffer->clip_changed);
+ || buffer->clip_changed
+ || buffer->prevent_redisplay_optimizations_p);
if (MINI_WINDOW_P (w))
{
SET_TEXT_POS (opoint, PT, PT_BYTE);
current_matrix_up_to_date_p
+ = (!NILP (w->window_end_valid)
+ && !current_buffer->clip_changed
+ && !current_buffer->prevent_redisplay_optimizations_p
+ && XFASTINT (w->last_modified) >= MODIFF
+ && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
+
+ buffer_unchanged_p
= (!NILP (w->window_end_valid)
&& !current_buffer->clip_changed
&& XFASTINT (w->last_modified) >= MODIFF
w->window_end_valid = Qnil;
/* Forget any recorded base line for line number display. */
- if (!current_matrix_up_to_date_p
- || current_buffer->clip_changed)
+ if (!buffer_unchanged_p)
w->base_line_number = Qnil;
/* Redisplay the mode line. Select the buffer properly for that.
}
if (!make_cursor_line_fully_visible (w))
- goto need_larger_matrices;
+ {
+ /* CVS rev. 1.761 had changed this to ``goto try_to_scroll''.
+
+ The intention of the fix -- AFAIU -- was to ensure that
+ the cursor didn't end up on a partially visible last (or
+ first?) line when scrolling.
+
+
+ But that change causes havoc when scrolling backwards and
+ a partially visible first (or last?) line is present when
+ we reach the top of the buffer. In effect, the text
+ already in the window is repeated (each line is appended
+ to the same or another lines in the window)...
+
+ I changed it back to ``goto need_larger_matrices'' which
+ in effect mean that we don't go through `try_scrolling'
+ when the cursor is already at the first line of the buffer,
+ and there is really only a few pixels [rather than lines]
+ to scroll backwards. I guess move_it_by_lines etc. really
+ isn't the right device for doing that, ref. the code in
+ make_cursor_line_fully_visible which was also disabled by
+ CVS rev. 1.761.
+
+ But how do we know that we are already on the top line of
+ the window showing the first line in the buffer, so that
+ scrolling really wont help here?
+
+ I cannot find a simple fix for this (I tried various
+ approaches), but I prefer to an occasional partial line
+ rather than the visual messup, so I reverted this part of
+ the fix.
+
+ Someone will need to look into this when time allows.
+
+ -- 2002-08-22, Kim F. Storm */
+
+ goto need_larger_matrices;
+ }
#if GLYPH_DEBUG
debug_method_add (w, "forced window start");
#endif
}
/* Handle case where text has not changed, only point, and it has
- not moved off the frame. */
+ not moved off the frame, and we are not retrying after hscroll.
+ (current_matrix_up_to_date_p is nonzero when retrying.) */
if (current_matrix_up_to_date_p
&& (rc = try_cursor_movement (window, startp, &temp_scroll_step),
rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
w->base_line_number = Qnil;
if (!make_cursor_line_fully_visible (w))
- goto need_larger_matrices;
+ /* Drop through and scroll. */
+ ;
goto done;
}
else
/* Finally, just choose place to start which centers point */
recenter:
+ centering_position = window_box_height (w) / 2;
+
+ point_at_top:
+ /* Jump here with centering_position already set to 0. */
#if GLYPH_DEBUG
debug_method_add (w, "recenter");
/* w->vscroll = 0; */
/* Forget any previously recorded base line for line number display. */
- if (!current_matrix_up_to_date_p
- || current_buffer->clip_changed)
+ if (!buffer_unchanged_p)
w->base_line_number = Qnil;
/* Move backward half the height of the window. */
init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
it.current_y = it.last_visible_y;
- move_it_vertically_backward (&it, window_box_height (w) / 2);
+ move_it_vertically_backward (&it, centering_position);
xassert (IT_CHARPOS (it) >= BEGV);
/* The function move_it_vertically_backward may move over more
}
if (!make_cursor_line_fully_visible (w))
- goto need_larger_matrices;
+ {
+ /* If centering point failed to make the whole line visible,
+ put point at the top instead. That has to make the whole line
+ visible, if it can be done. */
+ centering_position = 0;
+ goto point_at_top;
+ }
done:
if (windows_or_buffers_changed || cursor_type_changed)
GIVE_UP (2);
- /* Verify that narrowing has not changed. This flag is also set to prevent
- redisplay optimizations. It would be nice to further
+ /* Verify that narrowing has not changed.
+ Also verify that we were not told to prevent redisplay optimizations.
+ It would be nice to further
reduce the number of cases where this prevents try_window_id. */
- if (current_buffer->clip_changed)
+ if (current_buffer->clip_changed
+ || current_buffer->prevent_redisplay_optimizations_p)
GIVE_UP (3);
/* Window must either use window-based redisplay or be full width. */
DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
- doc: /* Like `format', but print result to stderr. */)
+ doc: /* Like `format', but print result to stderr.
+usage: (trace-to-stderr STRING &rest OBJECTS) */)
(nargs, args)
int nargs;
Lisp_Object *args;
struct frame *f = XFRAME (WINDOW_FRAME (w));
struct buffer *buffer = XBUFFER (w->buffer);
struct buffer *old = current_buffer;
- unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
+ const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
int arrow_len = SCHARS (Voverlay_arrow_string);
- unsigned char *arrow_end = arrow_string + arrow_len;
- unsigned char *p;
+ const unsigned char *arrow_end = arrow_string + arrow_len;
+ const unsigned char *p;
struct it it;
int multibyte_p;
int n_glyphs_before;
{
/* Glyph is completely off the left margin of the
window. This should not happen because of the
- move_it_in_display_line at the start of
- this function. */
- abort ();
+ move_it_in_display_line at the start of this
+ function, unless the text display area of the
+ window is empty. */
+ xassert (it->first_visible_x <= it->last_visible_x);
}
}
{
/* A string: output it and check for %-constructs within it. */
unsigned char c;
- unsigned char *this, *lisp_string;
+ const unsigned char *this, *lisp_string;
if (!NILP (props) || risky)
{
|| !NILP (mode_line_string_list)
|| it->current_x < it->last_visible_x))
{
- unsigned char *last = this;
+ const unsigned char *last = this;
/* Advance to end of string or next format specifier. */
while ((c = *this++) != '\0' && c != '%')
}
else /* c == '%' */
{
- unsigned char *percent_position = this;
+ const unsigned char *percent_position = this;
/* Get the specified minimum width. Zero means
don't pad. */
Lisp_Object format, window, no_props;
{
struct it it;
- struct face *face;
int len;
struct window *w;
struct buffer *old_buffer = NULL;
{
Lisp_Object val;
int multibyte = !NILP (current_buffer->enable_multibyte_characters);
- unsigned char *eol_str;
+ const unsigned char *eol_str;
int eol_str_len;
/* The EOL conversion we are using. */
Lisp_Object eoltype;
else if (INTEGERP (eoltype)
&& CHAR_VALID_P (XINT (eoltype), 0))
{
- eol_str = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
- eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);
+ unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
+ eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
+ eol_str = tmp;
}
else
{
}
\f
+/***********************************************************************
+ Cursor types
+ ***********************************************************************/
+
+/* Value is the internal representation of the specified cursor type
+ ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
+ of the bar cursor. */
+
+enum text_cursor_kinds
+get_specified_cursor_type (arg, width)
+ Lisp_Object arg;
+ int *width;
+{
+ enum text_cursor_kinds type;
+
+ if (NILP (arg))
+ return NO_CURSOR;
+
+ if (EQ (arg, Qbox))
+ return FILLED_BOX_CURSOR;
+
+ if (EQ (arg, Qhollow))
+ return HOLLOW_BOX_CURSOR;
+
+ if (EQ (arg, Qbar))
+ {
+ *width = 2;
+ return BAR_CURSOR;
+ }
+
+ if (CONSP (arg)
+ && EQ (XCAR (arg), Qbar)
+ && INTEGERP (XCDR (arg))
+ && XINT (XCDR (arg)) >= 0)
+ {
+ *width = XINT (XCDR (arg));
+ return BAR_CURSOR;
+ }
+
+ if (EQ (arg, Qhbar))
+ {
+ *width = 2;
+ return HBAR_CURSOR;
+ }
+
+ if (CONSP (arg)
+ && EQ (XCAR (arg), Qhbar)
+ && INTEGERP (XCDR (arg))
+ && XINT (XCDR (arg)) >= 0)
+ {
+ *width = XINT (XCDR (arg));
+ return HBAR_CURSOR;
+ }
+
+ /* Treat anything unknown as "hollow box cursor".
+ It was bad to signal an error; people have trouble fixing
+ .Xdefaults with Emacs, when it has something bad in it. */
+ type = HOLLOW_BOX_CURSOR;
+
+ return type;
+}
+
+/* Set the default cursor types for specified frame. */
+void
+set_frame_cursor_types (f, arg)
+ struct frame *f;
+ Lisp_Object arg;
+{
+ int width;
+ Lisp_Object tem;
+
+ FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
+ FRAME_CURSOR_WIDTH (f) = width;
+
+ /* By default, set up the blink-off state depending on the on-state. */
+
+ tem = Fassoc (arg, Vblink_cursor_alist);
+ if (!NILP (tem))
+ {
+ FRAME_BLINK_OFF_CURSOR (f)
+ = get_specified_cursor_type (XCDR (tem), &width);
+ FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
+ }
+ else
+ FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
+}
+
+
+/* Return the cursor we want to be displayed. In a mini-buffer
+ window, we want the cursor only to appear if we are reading input
+ from this window. For the selected window, we want the cursor type
+ given by the frame parameter or buffer local setting of
+ cursor-type. If explicitly marked off, draw no cursor. In all
+ other cases, we want a hollow box cursor. */
+
+enum text_cursor_kinds
+get_window_cursor_type (w, width)
+ struct window *w;
+ int *width;
+{
+ struct frame *f = XFRAME (w->frame);
+ struct buffer *b = XBUFFER (w->buffer);
+ int cursor_type = DEFAULT_CURSOR;
+ Lisp_Object alt_cursor;
+ int non_selected = 0;
+
+ /* Echo area */
+ if (cursor_in_echo_area
+ && FRAME_HAS_MINIBUF_P (f)
+ && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
+ {
+ if (w == XWINDOW (echo_area_window))
+ {
+ *width = FRAME_CURSOR_WIDTH (f);
+ return FRAME_DESIRED_CURSOR (f);
+ }
+
+ non_selected = 1;
+ }
+
+ /* Nonselected window or nonselected frame. */
+ else if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
+ || w != XWINDOW (f->selected_window))
+ {
+ if (MINI_WINDOW_P (w) && minibuf_level == 0)
+ return NO_CURSOR;
+
+ non_selected = 1;
+ }
+
+ /* Never display a cursor in a window in which cursor-type is nil. */
+ if (NILP (b->cursor_type))
+ return NO_CURSOR;
+
+ /* Use cursor-in-non-selected-windows for non-selected window or frame. */
+ if (non_selected)
+ {
+ alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
+ return get_specified_cursor_type (alt_cursor, width);
+ }
+
+ /* Get the normal cursor type for this window. */
+ if (EQ (b->cursor_type, Qt))
+ {
+ cursor_type = FRAME_DESIRED_CURSOR (f);
+ *width = FRAME_CURSOR_WIDTH (f);
+ }
+ else
+ cursor_type = get_specified_cursor_type (b->cursor_type, width);
+
+ /* Use normal cursor if not blinked off. */
+ if (!w->cursor_off_p)
+ return cursor_type;
+
+ /* Cursor is blinked off, so determine how to "toggle" it. */
+
+ /* First try to use alternate-cursor-type, unless it is t. */
+ alt_cursor = Fbuffer_local_value (Qalternate_cursor_type, w->buffer);
+ if (!EQ (alt_cursor, Qt))
+ return get_specified_cursor_type (alt_cursor, width);
+
+ /* Then unless buffer's cursor-type is t (use default),
+ look for an entry matching normal cursor in blink-cursor-alist. */
+ if (!EQ (b->cursor_type, Qt) &&
+ (alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
+ return get_specified_cursor_type (XCDR (alt_cursor), width);
+
+ /* Then see if frame has specified a specific blink off cursor type. */
+ if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
+ {
+ *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
+ return FRAME_BLINK_OFF_CURSOR (f);
+ }
+
+ /* Finally perform built-in cursor blinking:
+ filled box <-> hollow box
+ wide [h]bar <-> narrow [h]bar
+ narrow [h]bar <-> no cursor
+ other type <-> no cursor */
+
+ if (cursor_type == FILLED_BOX_CURSOR)
+ return HOLLOW_BOX_CURSOR;
+
+ if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
+ {
+ *width = 1;
+ return cursor_type;
+ }
+
+ return NO_CURSOR;
+}
+
+\f
/***********************************************************************
Initialization
***********************************************************************/
staticpro (&Qmessage_truncate_lines);
Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
staticpro (&Qcursor_in_non_selected_windows);
+ Qalternate_cursor_type = intern ("alternate-cursor-type");
+ staticpro (&Qalternate_cursor_type);
Qgrow_only = intern ("grow-only");
staticpro (&Qgrow_only);
Qinhibit_menubar_update = intern ("inhibit-menubar-update");
staticpro (&Qbuffer_position);
Qobject = intern ("object");
staticpro (&Qobject);
+ Qbar = intern ("bar");
+ staticpro (&Qbar);
+ Qhbar = intern ("hbar");
+ staticpro (&Qhbar);
+ Qbox = intern ("box");
+ staticpro (&Qbox);
+ Qhollow = intern ("hollow");
+ staticpro (&Qhollow);
Qrisky_local_variable = intern ("risky-local-variable");
staticpro (&Qrisky_local_variable);
+ Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
+ staticpro (&Qinhibit_free_realized_faces);
list_of_error = Fcons (intern ("error"), Qnil);
staticpro (&list_of_error);
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.
Any other value means to use the appropriate face, `mode-line',
-`header-line', or `menu' respectively.
-
-This variable is deprecated; please change the above faces instead. */);
+`header-line', or `menu' respectively. */);
mode_line_inverse_video = 1;
DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
go back to their normal size. */);
Vresize_mini_windows = Qgrow_only;
- DEFVAR_BOOL ("cursor-in-non-selected-windows",
- &cursor_in_non_selected_windows,
- doc: /* *Non-nil means display a hollow cursor in non-selected windows.
-nil means don't display a cursor there. */);
- cursor_in_non_selected_windows = 1;
+ DEFVAR_LISP ("cursor-in-non-selected-windows",
+ &Vcursor_in_non_selected_windows,
+ doc: /* *Cursor type to display in non-selected windows.
+t means to use hollow box cursor. See `cursor-type' for other values. */);
+ Vcursor_in_non_selected_windows = Qt;
+
+ DEFVAR_LISP ("alternate-cursor-type", &Valternate_cursor_type,
+ doc: /* *Cursor type displayed in the blinking cursor off state.
+t means to use default. See `cursor-type' for other values. */);
+ Valternate_cursor_type = Qt;
+
+ DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
+ doc: /* Alist specifying how to blink the cursor off.
+Each element has the form (ON-STATE . OFF-STATE). Whenever the
+`cursor-type' frame-parameter or variable equals ON-STATE,
+comparing using `equal', Emacs uses OFF-STATE to specify
+how to blink it off. */);
+ Vblink_cursor_alist = Qnil;
DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
doc: /* *Non-nil means scroll the display automatically to make point visible. */);
doc: /* Non-nil means don't eval Lisp during redisplay. */);
inhibit_eval_during_redisplay = 0;
+ DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
+ doc: /* Non-nil means don't free realized faces. Internal use only. */);
+ inhibit_free_realized_faces = 0;
+
#if GLYPH_DEBUG
DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
doc: /* Inhibit try_window_id display optimization. */);