X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/7393bcbb8bf25c97aed35079da765436d4e9fc03..a7727d05be4047b4ab6c8218ad2de5e2ad8624da:/src/xdisp.c diff --git a/src/xdisp.c b/src/xdisp.c index e9bf472696..c0dafc820c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1,6 +1,7 @@ /* Display generation from window structure and buffer text. -Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc. +Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, +Inc. This file is part of GNU Emacs. @@ -273,9 +274,9 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include #include "lisp.h" +#include "atimer.h" #include "keyboard.h" #include "frame.h" #include "window.h" @@ -302,7 +303,7 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_X_WINDOWS #include "xterm.h" #endif -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI #include "w32term.h" #endif #ifdef HAVE_NS @@ -333,10 +334,10 @@ static Lisp_Object Qinhibit_eval_during_redisplay; static Lisp_Object Qbuffer_position, Qposition, Qobject; static Lisp_Object Qright_to_left, Qleft_to_right; -/* Cursor shapes */ +/* Cursor shapes. */ Lisp_Object Qbar, Qhbar, Qbox, Qhollow; -/* Pointer shapes */ +/* Pointer shapes. */ static Lisp_Object Qarrow, Qhand; Lisp_Object Qtext; @@ -347,6 +348,7 @@ static Lisp_Object Qfontification_functions; static Lisp_Object Qwrap_prefix; static Lisp_Object Qline_prefix; +static Lisp_Object Qredisplay_internal; /* Non-nil means don't actually do any redisplay. */ @@ -365,6 +367,28 @@ Lisp_Object Qcenter; static Lisp_Object Qmargin, Qpointer; static Lisp_Object Qline_height; +/* These setters are used only in this file, so they can be private. */ +static void +wset_base_line_number (struct window *w, Lisp_Object val) +{ + w->base_line_number = val; +} +static void +wset_base_line_pos (struct window *w, Lisp_Object val) +{ + w->base_line_pos = val; +} +static void +wset_column_number_displayed (struct window *w, Lisp_Object val) +{ + w->column_number_displayed = val; +} +static void +wset_region_showing (struct window *w, Lisp_Object val) +{ + w->region_showing = val; +} + #ifdef HAVE_WINDOW_SYSTEM /* Test if overflow newline into fringe. Called with iterator IT @@ -746,9 +770,9 @@ static int clear_image_cache_count; static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 }; #endif -/* Non-zero while redisplay_internal is in progress. */ +/* True while redisplay_internal is in progress. */ -int redisplaying_p; +bool redisplaying_p; static Lisp_Object Qinhibit_free_realized_faces; static Lisp_Object Qmode_line_default_help_echo; @@ -838,7 +862,6 @@ static int string_char_and_length (const unsigned char *, int *); static struct text_pos display_prop_end (struct it *, Lisp_Object, struct text_pos); static int compute_window_start_on_continuation_line (struct window *); -static Lisp_Object safe_eval_handler (Lisp_Object); static void insert_left_trunc_glyphs (struct it *); static struct glyph_row *get_overlay_arrow_glyph_row (struct window *, Lisp_Object); @@ -906,6 +929,7 @@ static enum move_it_result move_it_in_display_line_to (struct it *, ptrdiff_t, int, enum move_operation_enum); void move_it_vertically_backward (struct it *, int); +static void get_visually_first_element (struct it *); static void init_to_row_start (struct it *, struct window *, struct glyph_row *); static int init_to_row_end (struct it *, struct window *, @@ -1169,7 +1193,7 @@ window_box (struct window *w, int area, int *box_x, int *box_y, *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the box. */ -static inline void +static void window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y, int *bottom_right_x, int *bottom_right_y) { @@ -1256,7 +1280,7 @@ string_from_display_spec (Lisp_Object spec) /* Limit insanely large values of W->hscroll on frame F to the largest value that will still prevent first_visible_x and last_visible_x of 'struct it' from overflowing an int. */ -static inline int +static int window_hscroll_limited (struct window *w, struct frame *f) { ptrdiff_t window_hscroll = w->hscroll; @@ -1310,7 +1334,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, if (WINDOW_WANTS_HEADER_LINE_P (w)) current_header_line_height = display_mode_line (w, HEADER_LINE_FACE_ID, - BVAR (current_buffer, header_line_format)); + BVAR (current_buffer, header_line_format)); start_display (&it, w, top); move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, @@ -1603,7 +1627,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, returns an invalid character. If we find one, we return a `?', but with the length of the invalid character. */ -static inline int +static int string_char_and_length (const unsigned char *str, int *len) { int c; @@ -1651,7 +1675,7 @@ string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t ncha /* Value is the text position, i.e. character and byte position, for character position CHARPOS in STRING. */ -static inline struct text_pos +static struct text_pos string_pos (ptrdiff_t charpos, Lisp_Object string) { struct text_pos pos; @@ -2397,9 +2421,10 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect) /* Error handler for safe_eval and safe_call. */ static Lisp_Object -safe_eval_handler (Lisp_Object arg) +safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args) { - add_to_log ("Error during redisplay: %S", arg, Qnil); + add_to_log ("Error during redisplay: %S signaled %S", + Flist (nargs, args), arg); return Qnil; } @@ -2420,7 +2445,7 @@ safe_call (ptrdiff_t nargs, Lisp_Object func, ...) ptrdiff_t i; ptrdiff_t count = SPECPDL_INDEX (); struct gcpro gcpro1; - Lisp_Object *args = alloca (nargs * sizeof (Lisp_Object)); + Lisp_Object *args = alloca (nargs * word_size); args[0] = func; va_start (ap, func); @@ -2591,7 +2616,8 @@ init_iterator (struct it *it, struct window *w, /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */ if (! NILP (Vface_remapping_alist)) - remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id); + remapped_base_face_id + = lookup_basic_face (XFRAME (w->frame), base_face_id); /* Use one of the mode line rows of W's desired matrix if appropriate. */ @@ -2659,9 +2685,9 @@ init_iterator (struct it *it, struct window *w, is invisible. >0 means lines indented more than this value are invisible. */ it->selective = (INTEGERP (BVAR (current_buffer, selective_display)) - ? clip_to_bounds (-1, XINT (BVAR (current_buffer, - selective_display)), - PTRDIFF_MAX) + ? (clip_to_bounds + (-1, XINT (BVAR (current_buffer, selective_display)), + PTRDIFF_MAX)) : (!NILP (BVAR (current_buffer, selective_display)) ? -1 : 0)); it->selective_display_ellipsis_p @@ -3089,6 +3115,40 @@ init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos) eassert (STRINGP (it->string)); it->current.string_pos = pos->string_pos; it->method = GET_FROM_STRING; + it->end_charpos = SCHARS (it->string); + /* Set up the bidi iterator for this overlay string. */ + if (it->bidi_p) + { + it->bidi_it.string.lstring = it->string; + it->bidi_it.string.s = NULL; + it->bidi_it.string.schars = SCHARS (it->string); + it->bidi_it.string.bufpos = it->overlay_strings_charpos; + it->bidi_it.string.from_disp_str = it->string_from_display_prop_p; + it->bidi_it.string.unibyte = !it->multibyte_p; + bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it), + FRAME_WINDOW_P (it->f), &it->bidi_it); + + /* Synchronize the state of the bidi iterator with + pos->string_pos. For any string position other than + zero, this will be done automagically when we resume + iteration over the string and get_visually_first_element + is called. But if string_pos is zero, and the string is + to be reordered for display, we need to resync manually, + since it could be that the iteration state recorded in + pos ended at string_pos of 0 moving backwards in string. */ + if (CHARPOS (pos->string_pos) == 0) + { + get_visually_first_element (it); + if (IT_STRING_CHARPOS (*it) != 0) + do { + /* Paranoia. */ + eassert (it->bidi_it.charpos < it->bidi_it.string.schars); + bidi_move_to_visually_next (&it->bidi_it); + } while (it->bidi_it.charpos != 0); + } + eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos + && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos); + } } if (CHARPOS (pos->string_pos) >= 0) @@ -3098,6 +3158,9 @@ init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos) IT should already be filled with that string. */ it->current.string_pos = pos->string_pos; eassert (STRINGP (it->string)); + if (it->bidi_p) + bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it), + FRAME_WINDOW_P (it->f), &it->bidi_it); } /* Restore position in display vector translations, control @@ -3320,7 +3383,7 @@ compute_stop_pos (struct it *it) interval if there isn't such an interval. */ position = make_number (charpos); iv = validate_interval_range (object, &position, &position, 0); - if (!NULL_INTERVAL_P (iv)) + if (iv) { Lisp_Object values_here[LAST_PROP_IDX]; struct props *p; @@ -3332,7 +3395,7 @@ compute_stop_pos (struct it *it) /* Look for an interval following iv that has different properties. */ for (next_iv = next_interval (iv); - (!NULL_INTERVAL_P (next_iv) + (next_iv && (NILP (limit) || XFASTINT (limit) > next_iv->position)); next_iv = next_interval (next_iv)) @@ -3350,7 +3413,7 @@ compute_stop_pos (struct it *it) break; } - if (!NULL_INTERVAL_P (next_iv)) + if (next_iv) { if (INTEGERP (limit) && next_iv->position >= XFASTINT (limit)) @@ -3643,7 +3706,7 @@ handle_fontified_prop (struct it *it) } /* There isn't much we can reasonably do to protect against misbehaving fontification, but here's a fig leaf. */ - else if (!NILP (BVAR (obuf, name))) + else if (BUFFER_LIVE_P (obuf)) set_buffer_internal_1 (obuf); /* The fontification code may have added/removed text. @@ -4046,38 +4109,54 @@ static enum prop_handled handle_invisible_prop (struct it *it) { enum prop_handled handled = HANDLED_NORMALLY; + int invis_p; + Lisp_Object prop; if (STRINGP (it->string)) { - Lisp_Object prop, end_charpos, limit, charpos; + Lisp_Object end_charpos, limit, charpos; /* Get the value of the invisible text property at the current position. Value will be nil if there is no such property. */ charpos = make_number (IT_STRING_CHARPOS (*it)); prop = Fget_text_property (charpos, Qinvisible, it->string); + invis_p = TEXT_PROP_MEANS_INVISIBLE (prop); - if (!NILP (prop) - && IT_STRING_CHARPOS (*it) < it->end_charpos) + if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos) { - ptrdiff_t endpos; + /* Record whether we have to display an ellipsis for the + invisible text. */ + int display_ellipsis_p = (invis_p == 2); + ptrdiff_t len, endpos; handled = HANDLED_RECOMPUTE_PROPS; - /* Get the position at which the next change of the - invisible text property can be found in IT->string. - Value will be nil if the property value is the same for - all the rest of IT->string. */ - XSETINT (limit, SCHARS (it->string)); - end_charpos = Fnext_single_property_change (charpos, Qinvisible, - it->string, limit); - - /* Text at current position is invisible. The next - change in the property is at position end_charpos. - Move IT's current position to that position. */ - if (INTEGERP (end_charpos) - && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit)) + /* Get the position at which the next visible text can be + found in IT->string, if any. */ + endpos = len = SCHARS (it->string); + XSETINT (limit, len); + do { + end_charpos = Fnext_single_property_change (charpos, Qinvisible, + it->string, limit); + if (INTEGERP (end_charpos)) + { + endpos = XFASTINT (end_charpos); + prop = Fget_text_property (end_charpos, Qinvisible, it->string); + invis_p = TEXT_PROP_MEANS_INVISIBLE (prop); + if (invis_p == 2) + display_ellipsis_p = 1; + } + } + while (invis_p && endpos < len); + + if (display_ellipsis_p) + it->ellipsis_p = 1; + + if (endpos < len) + { + /* Text at END_CHARPOS is visible. Move IT there. */ struct text_pos old; ptrdiff_t oldpos; @@ -4113,7 +4192,8 @@ handle_invisible_prop (struct it *it) /* The rest of the string is invisible. If this is an overlay string, proceed with the next overlay string or whatever comes and return a character from there. */ - if (it->current.overlay_string_index >= 0) + if (it->current.overlay_string_index >= 0 + && !display_ellipsis_p) { next_overlay_string (it); /* Don't check for overlay strings when we just @@ -4130,9 +4210,8 @@ handle_invisible_prop (struct it *it) } else { - int invis_p; ptrdiff_t newpos, next_stop, start_charpos, tem; - Lisp_Object pos, prop, overlay; + Lisp_Object pos, overlay; /* First of all, is there invisible text at this position? */ tem = start_charpos = IT_CHARPOS (*it); @@ -5308,6 +5387,7 @@ next_overlay_string (struct it *it) SET_TEXT_POS (it->current.string_pos, 0, 0); it->method = GET_FROM_STRING; it->stop_charpos = 0; + it->end_charpos = SCHARS (it->string); if (it->cmp_it.stop_pos >= 0) it->cmp_it.stop_pos = 0; it->prev_stop = 0; @@ -6009,7 +6089,7 @@ back_to_previous_visible_line_start (struct it *it) { Lisp_Object prop; prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1), - Qinvisible, it->window); + Qinvisible, it->window); if (TEXT_PROP_MEANS_INVISIBLE (prop)) continue; } @@ -6261,6 +6341,8 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p) it->stop_charpos = CHARPOS (pos); it->base_level_stop = CHARPOS (pos); } + /* This make the information stored in it->cmp_it invalidate. */ + it->cmp_it.id = -1; } @@ -7267,7 +7349,7 @@ set_iterator_to_next (struct it *it, int reseat_p) default: /* There are no other methods defined, so this should be a bug. */ - abort (); + emacs_abort (); } eassert (it->method != GET_FROM_STRING @@ -7717,12 +7799,12 @@ compute_stop_pos_backwards (struct it *it) { it->end_charpos = min (charpos + 1, ZV); charpos = max (charpos - SCAN_BACK_LIMIT, BEGV); - SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos)); + SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos)); reseat_1 (it, pos, 0); compute_stop_pos (it); /* We must advance forward, right? */ if (it->stop_charpos <= charpos) - abort (); + emacs_abort (); } while (charpos > BEGV && it->stop_charpos >= it->end_charpos); @@ -7771,7 +7853,7 @@ handle_stop_backwards (struct it *it, ptrdiff_t charpos) compute_stop_pos (it); /* We must advance forward, right? */ if (it->stop_charpos <= it->prev_stop) - abort (); + emacs_abort (); charpos = it->stop_charpos; } while (charpos <= where_we_are); @@ -7980,7 +8062,7 @@ run_redisplay_end_trigger_hook (struct it *it) /* Since we are *trying* to run these functions, don't try to run them again, even if they get an error. */ - it->w->redisplay_end_trigger = Qnil; + wset_redisplay_end_trigger (it->w, Qnil); Frun_hook_with_args (3, args); /* Notice if it changed the face of the character we are on. */ @@ -8859,7 +8941,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos break; default: - abort (); + emacs_abort (); } /* Reset/increment for the next run. */ @@ -9252,12 +9334,6 @@ add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2) struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; USE_SAFE_ALLOCA; - /* Do nothing if called asynchronously. Inserting text into - a buffer may call after-change-functions and alike and - that would means running Lisp asynchronously. */ - if (handling_signal) - return; - fmt = msg = Qnil; GCPRO4 (fmt, msg, arg1, arg2); @@ -9267,7 +9343,7 @@ add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2) msg = Fformat (3, args); len = SBYTES (msg) + 1; - SAFE_ALLOCA (buffer, char *, len); + buffer = SAFE_ALLOCA (len); memcpy (buffer, SDATA (msg), len); message_dolog (buffer, len - 1, 1, 0); @@ -9317,7 +9393,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) old_deactivate_mark = Vdeactivate_mark; oldbuf = current_buffer; Fset_buffer (Fget_buffer_create (Vmessages_buffer_name)); - BVAR (current_buffer, undo_list) = Qt; + bset_undo_list (current_buffer, Qt); oldpoint = message_dolog_marker1; set_marker_restricted (oldpoint, make_number (PT), Qnil); @@ -9594,10 +9670,8 @@ message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte) message_log_maybe_newline (); if (STRINGP (m)) { - char *buffer; USE_SAFE_ALLOCA; - - SAFE_ALLOCA (buffer, char *, nbytes); + char *buffer = SAFE_ALLOCA (nbytes); memcpy (buffer, SDATA (m), nbytes); message_dolog (buffer, nbytes, 1, multibyte); SAFE_FREE (); @@ -9872,7 +9946,7 @@ ensure_echo_area_buffers (void) for (i = 0; i < 2; ++i) if (!BUFFERP (echo_buffer[i]) - || NILP (BVAR (XBUFFER (echo_buffer[i]), name))) + || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i]))) { char name[30]; Lisp_Object old_buffer; @@ -9881,7 +9955,7 @@ ensure_echo_area_buffers (void) old_buffer = echo_buffer[i]; echo_buffer[i] = Fget_buffer_create (make_formatted_string (name, " *Echo Area %d*", i)); - BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil; + bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil); /* to force word wrap in echo area - it was decided to postpone this*/ /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */ @@ -9970,12 +10044,12 @@ with_echo_area_buffer (struct window *w, int which, set_buffer_internal_1 (XBUFFER (buffer)); if (w) { - w->buffer = buffer; + wset_buffer (w, buffer); set_marker_both (w->pointm, buffer, BEG, BEG_BYTE); } - BVAR (current_buffer, undo_list) = Qt; - BVAR (current_buffer, read_only) = Qnil; + bset_undo_list (current_buffer, Qt); + bset_read_only (current_buffer, Qnil); specbind (Qinhibit_read_only, Qt); specbind (Qinhibit_modification_hooks, Qt); @@ -10055,7 +10129,7 @@ unwind_with_echo_area_buffer (Lisp_Object vector) charpos = AREF (vector, 5); bytepos = AREF (vector, 6); - w->buffer = buffer; + wset_buffer (w, buffer); set_marker_both (w->pointm, buffer, XFASTINT (charpos), XFASTINT (bytepos)); } @@ -10088,7 +10162,7 @@ setup_echo_area_for_printing (int multibyte_p) /* Switch to that buffer and clear it. */ set_buffer_internal (XBUFFER (echo_area_buffer[0])); - BVAR (current_buffer, truncate_lines) = Qnil; + bset_truncate_lines (current_buffer, Qnil); if (Z > BEG) { @@ -10131,7 +10205,7 @@ setup_echo_area_for_printing (int multibyte_p) { /* Someone switched buffers between print requests. */ set_buffer_internal (XBUFFER (echo_area_buffer[0])); - BVAR (current_buffer, truncate_lines) = Qnil; + bset_truncate_lines (current_buffer, Qnil); } } } @@ -10443,11 +10517,10 @@ current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4) empty. This is a relatively infrequent operation, so it's not worth optimizing. */ -int +bool push_message (void) { - Lisp_Object msg; - msg = current_message (); + Lisp_Object msg = current_message (); Vmessage_stack = Fcons (msg, Vmessage_stack); return STRINGP (msg); } @@ -10496,7 +10569,7 @@ void check_message_stack (void) { if (!NILP (Vmessage_stack)) - abort (); + emacs_abort (); } @@ -10535,7 +10608,6 @@ truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4 return 0; } - /* Set the current message to a substring of S or STRING. If STRING is a Lisp string, set the message to the first NBYTES @@ -10562,6 +10634,10 @@ set_message (const char *s, Lisp_Object string, (intptr_t) s, string, nbytes, multibyte_p); message_buf_print = 0; help_echo_showing_p = 0; + + if (STRINGP (Vdebug_on_message) + && fast_string_match (Vdebug_on_message, string) >= 0) + call_debugger (list2 (Qerror, string)); } @@ -10583,9 +10659,9 @@ set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multiby != !NILP (BVAR (current_buffer, enable_multibyte_characters))) Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil); - BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil; + bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil); if (!NILP (BVAR (current_buffer, bidi_display_reordering))) - BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right; + bset_bidi_paragraph_direction (current_buffer, Qleft_to_right); /* Insert new message at BEG. */ TEMP_SET_PT_BOTH (BEG, BEG_BYTE); @@ -11053,7 +11129,8 @@ x_consider_frame_title (Lisp_Object frame) (f, current_buffer, selected_window, 0)); Fselect_window (f->selected_window, Qt); - set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer)); + set_buffer_internal_1 + (XBUFFER (XWINDOW (f->selected_window)->buffer)); fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; mode_line_target = MODE_LINE_TITLE; @@ -11171,8 +11248,8 @@ prepare_menu_bars (void) #ifdef HAVE_NS if (windows_or_buffers_changed && FRAME_NS_P (f)) - ns_set_doc_edited (f, Fbuffer_modified_p - (XWINDOW (f->selected_window)->buffer)); + ns_set_doc_edited + (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer)); #endif UNGCPRO; } @@ -11274,7 +11351,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run) } XSETFRAME (Vmenu_updating_frame, f); - FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); + fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); /* Redisplay the menu bar in case we changed it. */ #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ @@ -11368,11 +11445,11 @@ x_cursor_to (int vpos, int hpos, int y, int x) This will also set the cursor position of W. */ if (updated_window == NULL) { - BLOCK_INPUT; + 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; + unblock_input (); } } @@ -11475,8 +11552,9 @@ update_tool_bar (struct frame *f, int save_match_data) selected_frame = frame; /* Build desired tool-bar items from keymaps. */ - new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items), - &new_n_tool_bar); + new_tool_bar + = tool_bar_items (Fcopy_sequence (f->tool_bar_items), + &new_n_tool_bar); /* Redisplay the tool-bar if we changed it. */ if (new_n_tool_bar != f->n_tool_bar_items @@ -11485,11 +11563,11 @@ update_tool_bar (struct frame *f, int save_match_data) /* Redisplay that happens asynchronously due to an expose event may access f->tool_bar_items. Make sure we update both variables within BLOCK_INPUT so no such event interrupts. */ - BLOCK_INPUT; - f->tool_bar_items = new_tool_bar; + block_input (); + fset_tool_bar_items (f, new_tool_bar); f->n_tool_bar_items = new_n_tool_bar; w->update_mode_line = 1; - UNBLOCK_INPUT; + unblock_input (); } UNGCPRO; @@ -11528,8 +11606,8 @@ build_desired_tool_bar_string (struct frame *f) /* Reuse f->desired_tool_bar_string, if possible. */ if (size < size_needed || NILP (f->desired_tool_bar_string)) - f->desired_tool_bar_string = Fmake_string (make_number (size_needed), - make_number (' ')); + fset_desired_tool_bar_string + (f, Fmake_string (make_number (size_needed), make_number (' '))); else { props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil); @@ -11542,7 +11620,8 @@ build_desired_tool_bar_string (struct frame *f) is the index of the item in F's tool-bar item vector. */ for (i = 0; i < f->n_tool_bar_items; ++i) { -#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX)) +#define PROP(IDX) \ + AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX)) int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)); int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)); @@ -12539,7 +12618,7 @@ debug_method_add (struct window *w, char const *fmt, ...) buffer position, END is given as a distance from Z. Used in redisplay_internal for display optimization. */ -static inline int +static int text_outside_line_unchanged_p (struct window *w, ptrdiff_t start, ptrdiff_t end) { @@ -12750,7 +12829,7 @@ overlay_arrow_at_row (struct it *it, struct glyph_row *row) return make_number (fringe_bitmap); } #endif - return make_number (-1); /* Use default arrow bitmap */ + return make_number (-1); /* Use default arrow bitmap. */ } return overlay_arrow_string_or_property (var); } @@ -12800,7 +12879,7 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt, /* Reconsider the setting of B->clip_changed which is displayed in window W. */ -static inline void +static void reconsider_clip_changes (struct window *w, struct buffer *b) { if (b->clip_changed @@ -12851,7 +12930,8 @@ select_frame_for_redisplay (Lisp_Object frame) selected_frame = frame; do { - for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail)) + for (tail = XFRAME (frame)->param_alist; + CONSP (tail); tail = XCDR (tail)) if (CONSP (XCAR (tail)) && (tem = XCAR (XCAR (tail)), SYMBOLP (tem)) @@ -12891,12 +12971,13 @@ redisplay_internal (void) struct frame *sf; int polling_stopped_here = 0; Lisp_Object old_frame = selected_frame; + struct backtrace backtrace; /* Non-zero means redisplay has to consider all windows on all frames. Zero means, only selected_window is considered. */ int consider_all_windows_p; - /* Non-zero means redisplay has to redisplay the miniwindow */ + /* Non-zero means redisplay has to redisplay the miniwindow. */ int update_miniwindow_p = 0; TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p)); @@ -12926,14 +13007,21 @@ redisplay_internal (void) if (redisplaying_p) return; - /* Record a function that resets redisplaying_p to its old value + /* Record a function that clears redisplaying_p when we leave this function. */ count = SPECPDL_INDEX (); - record_unwind_protect (unwind_redisplay, - Fcons (make_number (redisplaying_p), selected_frame)); - ++redisplaying_p; + record_unwind_protect (unwind_redisplay, selected_frame); + redisplaying_p = 1; specbind (Qinhibit_free_realized_faces, Qnil); + /* Record this function, so it appears on the profiler's backtraces. */ + backtrace.next = backtrace_list; + backtrace.function = Qredisplay_internal; + backtrace.args = &Qnil; + backtrace.nargs = 0; + backtrace.debug_on_exit = 0; + backtrace_list = &backtrace; + { Lisp_Object tail, frame; @@ -13263,12 +13351,12 @@ redisplay_internal (void) if ((it.glyph_row - 1)->displays_text_p) { if (XFASTINT (w->window_end_vpos) < this_line_vpos) - XSETINT (w->window_end_vpos, this_line_vpos); + wset_window_end_vpos (w, make_number (this_line_vpos)); } else if (XFASTINT (w->window_end_vpos) == this_line_vpos && this_line_vpos > 0) - XSETINT (w->window_end_vpos, this_line_vpos - 1); - w->window_end_valid = Qnil; + wset_window_end_vpos (w, make_number (this_line_vpos - 1)); + wset_window_end_valid (w, Qnil); /* Update hint: No need to try to scroll in update_window. */ w->desired_matrix->no_scrolling_p = 1; @@ -13450,7 +13538,8 @@ redisplay_internal (void) and selected_window to be temporarily out-of-sync but let's make sure this stays contained. */ select_frame_for_redisplay (old_frame); - eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); + eassert (EQ (XFRAME (selected_frame)->selected_window, + selected_window)); if (!pending) { @@ -13630,6 +13719,7 @@ redisplay_internal (void) #endif /* HAVE_WINDOW_SYSTEM */ end_of_redisplay: + backtrace_list = backtrace.next; unbind_to (count, Qnil); RESUME_POLLING; } @@ -13668,21 +13758,15 @@ redisplay_preserve_echo_area (int from_where) } -/* Function registered with record_unwind_protect in - 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 +/* Function registered with record_unwind_protect in redisplay_internal. + Clear redisplaying_p. Also, select the previously selected frame, unless it has been deleted (by an X connection failure during redisplay, for example). */ static Lisp_Object -unwind_redisplay (Lisp_Object val) +unwind_redisplay (Lisp_Object old_frame) { - Lisp_Object old_redisplaying_p, old_frame; - - old_redisplaying_p = XCAR (val); - redisplaying_p = XFASTINT (old_redisplaying_p); - old_frame = XCDR (val); + redisplaying_p = 0; if (! EQ (old_frame, selected_frame) && FRAME_LIVE_P (XFRAME (old_frame))) select_frame_for_redisplay (old_frame); @@ -13733,7 +13817,7 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p) if (accurate_p) { - w->window_end_valid = w->buffer; + wset_window_end_valid (w, w->buffer); w->update_mode_line = 0; } } @@ -14149,7 +14233,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, GLYPH_BEFORE and GLYPH_AFTER. */ if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end) && BUFFERP (glyph->object) && glyph->charpos == pt_old) - && bpos_covered < pt_old) + && !(bpos_max < pt_old && pt_old <= bpos_covered)) { /* An empty line has a single glyph whose OBJECT is zero and whose CHARPOS is the position of a newline on that line. @@ -14158,7 +14242,12 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, CHARPOS is zero or negative. */ int empty_line_p = (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end) - && INTEGERP (glyph->object) && glyph->charpos > 0; + && INTEGERP (glyph->object) && glyph->charpos > 0 + /* On a TTY, continued and truncated rows also have a glyph at + their end whose OBJECT is zero and whose CHARPOS is + positive (the continuation and truncation glyphs), but such + rows are obviously not "empty". */ + && !(row->continued_p || row->truncated_on_right_p); if (row->ends_in_ellipsis_p && pos_after == last_pos) { @@ -14381,7 +14470,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++) { if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]) - abort (); + emacs_abort (); x += g->pixel_width; } } @@ -14495,14 +14584,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, We assume that the window's buffer is really current. */ -static inline struct text_pos +static struct text_pos run_window_scroll_functions (Lisp_Object window, struct text_pos startp) { struct window *w = XWINDOW (window); SET_MARKER_FROM_TEXT_POS (w->start, startp); if (current_buffer != XBUFFER (w->buffer)) - abort (); + emacs_abort (); if (!NILP (Vwindow_scroll_functions)) { @@ -14510,8 +14599,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp) make_number (CHARPOS (startp))); SET_TEXT_POS_FROM_MARKER (startp, w->start); /* In case the hook functions switch buffers. */ - if (current_buffer != XBUFFER (w->buffer)) - set_buffer_internal_1 (XBUFFER (w->buffer)); + set_buffer_internal (XBUFFER (w->buffer)); } return startp; @@ -14709,13 +14797,18 @@ try_scrolling (Lisp_Object window, int just_this_one_p, if (NUMBERP (aggressive)) { double float_amount = XFLOATINT (aggressive) * height; - amount_to_scroll = float_amount; - if (amount_to_scroll == 0 && float_amount > 0) - amount_to_scroll = 1; + int aggressive_scroll = float_amount; + if (aggressive_scroll == 0 && float_amount > 0) + aggressive_scroll = 1; /* Don't let point enter the scroll margin near top of - the window. */ - if (amount_to_scroll > height - 2*this_scroll_margin + dy) - amount_to_scroll = height - 2*this_scroll_margin + dy; + the window. This could happen if the value of + scroll_up_aggressively is too large and there are + non-zero margins, because scroll_up_aggressively + means put point that fraction of window height + _from_the_bottom_margin_. */ + if (aggressive_scroll + 2*this_scroll_margin > height) + aggressive_scroll = height - 2*this_scroll_margin; + amount_to_scroll = dy + aggressive_scroll; } } @@ -14775,7 +14868,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p, /* Compute the vertical distance from PT to the scroll margin position. Move as far as scroll_max allows, or one screenful, or 10 screen lines, whichever is largest. - Give up if distance is greater than scroll_max. */ + Give up if distance is greater than scroll_max or if we + didn't reach the scroll margin position. */ SET_TEXT_POS (pos, PT, PT_BYTE); start_display (&it, w, pos); y0 = it.current_y; @@ -14785,7 +14879,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p, y_to_move, -1, MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); dy = it.current_y - y0; - if (dy > scroll_max) + if (dy > scroll_max + || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos)) return SCROLLING_FAILED; /* Compute new window start. */ @@ -14803,15 +14898,16 @@ try_scrolling (Lisp_Object window, int just_this_one_p, if (NUMBERP (aggressive)) { double float_amount = XFLOATINT (aggressive) * height; - amount_to_scroll = float_amount; - if (amount_to_scroll == 0 && float_amount > 0) - amount_to_scroll = 1; - amount_to_scroll -= - this_scroll_margin - dy - FRAME_LINE_HEIGHT (f); + int aggressive_scroll = float_amount; + if (aggressive_scroll == 0 && float_amount > 0) + aggressive_scroll = 1; /* Don't let point enter the scroll margin near - bottom of the window. */ - if (amount_to_scroll > height - 2*this_scroll_margin + dy) - amount_to_scroll = height - 2*this_scroll_margin + dy; + bottom of the window, if the value of + scroll_down_aggressively happens to be too + large. */ + if (aggressive_scroll + 2*this_scroll_margin > height) + aggressive_scroll = height - 2*this_scroll_margin; + amount_to_scroll = dy + aggressive_scroll; } } @@ -14841,7 +14937,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p, if (!just_this_one_p || current_buffer->clip_changed || BEG_UNCHANGED < CHARPOS (startp)) - w->base_line_number = Qnil; + wset_base_line_number (w, Qnil); /* If cursor ends up on a partially visible line, treat that as being off the bottom of the screen. */ @@ -15339,7 +15435,7 @@ set_vertical_scroll_bar (struct window *w) selected_window is redisplayed. We can return without actually redisplaying the window if - fonts_changed_p is nonzero. In that case, redisplay_internal will + fonts_changed_p. In that case, redisplay_internal will retry. */ static void @@ -15466,15 +15562,15 @@ redisplay_window (Lisp_Object window, int just_this_one_p) if (XMARKER (w->start)->buffer == current_buffer) compute_window_start_on_continuation_line (w); - w->window_end_valid = Qnil; + wset_window_end_valid (w, Qnil); } /* Some sanity checks. */ CHECK_WINDOW_END (w); if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint)) - abort (); + emacs_abort (); if (BYTEPOS (opoint) < CHARPOS (opoint)) - abort (); + emacs_abort (); /* If %c is in mode line, update it if needed. */ if (!NILP (w->column_number_displayed) @@ -15533,8 +15629,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p) { struct Lisp_Char_Table *disptab = buffer_display_table (); - if (! disptab_matches_widthtab (disptab, - XVECTOR (BVAR (current_buffer, width_table)))) + if (! disptab_matches_widthtab + (disptab, XVECTOR (BVAR (current_buffer, width_table)))) { invalidate_region_cache (current_buffer, current_buffer->width_run_cache, @@ -15577,11 +15673,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p) w->force_start = 0; w->vscroll = 0; - w->window_end_valid = Qnil; + wset_window_end_valid (w, Qnil); /* Forget any recorded base line for line number display. */ if (!buffer_unchanged_p) - w->base_line_number = Qnil; + wset_base_line_number (w, Qnil); /* Redisplay the mode line. Select the buffer properly for that. Also, run the hook window-scroll-functions @@ -15686,7 +15782,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) goto try_to_scroll; default: - abort (); + emacs_abort (); } } /* If current starting point was originally the beginning of a line @@ -15795,7 +15891,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) || current_buffer->clip_changed || BEG_UNCHANGED < CHARPOS (startp)) /* Forget any recorded base line for line number display. */ - w->base_line_number = Qnil; + wset_base_line_number (w, Qnil); if (!cursor_row_fully_visible_p (w, 1, 0)) { @@ -15849,7 +15945,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) break; default: - abort (); + emacs_abort (); } } @@ -15866,7 +15962,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) /* Forget any previously recorded base line for line number display. */ if (!buffer_unchanged_p) - w->base_line_number = Qnil; + wset_base_line_number (w, Qnil); /* Determine the window start relative to point. */ init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); @@ -16124,8 +16220,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p) if (!line_number_displayed && !BUFFERP (w->base_line_pos)) { - w->base_line_pos = Qnil; - w->base_line_number = Qnil; + wset_base_line_pos (w, Qnil); + wset_base_line_number (w, Qnil); } finish_menu_bars: @@ -16175,15 +16271,15 @@ redisplay_window (Lisp_Object window, int just_this_one_p) || w->pseudo_window_p))) { update_begin (f); - BLOCK_INPUT; + block_input (); if (draw_window_fringes (w, 1)) x_draw_vertical_border (w); - UNBLOCK_INPUT; + unblock_input (); update_end (f); } #endif /* HAVE_WINDOW_SYSTEM */ - /* We go to this label, with fonts_changed_p nonzero, + /* We go to this label, with fonts_changed_p set, if it is necessary to try again using larger glyph matrices. We have to redeem the scroll bar even in this case, because the loop in redisplay_internal expects that. */ @@ -16302,22 +16398,23 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row)); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - w->window_end_pos - = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); - w->window_end_vpos - = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)); - eassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos)) - ->displays_text_p); + wset_window_end_pos + (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); + wset_window_end_vpos + (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix))); + eassert + (MATRIX_ROW (w->desired_matrix, + XFASTINT (w->window_end_vpos))->displays_text_p); } else { w->window_end_bytepos = Z_BYTE - ZV_BYTE; - w->window_end_pos = make_number (Z - ZV); - w->window_end_vpos = make_number (0); + wset_window_end_pos (w, make_number (Z - ZV)); + wset_window_end_vpos (w, make_number (0)); } /* But that is not valid info until redisplay finishes. */ - w->window_end_valid = Qnil; + wset_window_end_valid (w, Qnil); return 1; } @@ -16541,29 +16638,31 @@ try_window_reusing_current_matrix (struct window *w) { w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row); - w->window_end_pos - = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row)); - w->window_end_vpos - = make_number (MATRIX_ROW_VPOS (last_reused_text_row, - w->current_matrix)); + wset_window_end_pos + (w, make_number (Z + - MATRIX_ROW_END_CHARPOS (last_reused_text_row))); + wset_window_end_vpos + (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row, + w->current_matrix))); } else if (last_text_row) { w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - w->window_end_pos - = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); - w->window_end_vpos - = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)); + wset_window_end_pos + (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); + wset_window_end_vpos + (w, make_number (MATRIX_ROW_VPOS (last_text_row, + w->desired_matrix))); } else { /* This window must be completely empty. */ w->window_end_bytepos = Z_BYTE - ZV_BYTE; - w->window_end_pos = make_number (Z - ZV); - w->window_end_vpos = make_number (0); + wset_window_end_pos (w, make_number (Z - ZV)); + wset_window_end_vpos (w, make_number (0)); } - w->window_end_valid = Qnil; + wset_window_end_valid (w, Qnil); /* Update hint: don't try scrolling again in update_window. */ w->desired_matrix->no_scrolling_p = 1; @@ -16712,28 +16811,33 @@ try_window_reusing_current_matrix (struct window *w) } if (row < bottom_row) { - struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; - struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; - - /* Can't use this optimization with bidi-reordered glyph - rows, unless cursor is already at point. */ + /* Can't simply scan the row for point with + bidi-reordered glyph rows. Let set_cursor_from_row + figure out where to put the cursor, and if it fails, + give up. */ if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))) { - if (!(w->cursor.hpos >= 0 - && w->cursor.hpos < row->used[TEXT_AREA] - && BUFFERP (glyph->object) - && glyph->charpos == PT)) - return 0; + if (!set_cursor_from_row (w, row, w->current_matrix, + 0, 0, 0, 0)) + { + clear_glyph_matrix (w->desired_matrix); + return 0; + } } else - for (; glyph < end - && (!BUFFERP (glyph->object) - || glyph->charpos < PT); - glyph++) - { - w->cursor.hpos++; - w->cursor.x += glyph->pixel_width; - } + { + struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; + struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; + + for (; glyph < end + && (!BUFFERP (glyph->object) + || glyph->charpos < PT); + glyph++) + { + w->cursor.hpos++; + w->cursor.x += glyph->pixel_width; + } + } } } @@ -16744,18 +16848,19 @@ try_window_reusing_current_matrix (struct window *w) { w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - w->window_end_pos - = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); - w->window_end_vpos - = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)); + wset_window_end_pos + (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); + wset_window_end_vpos + (w, make_number (MATRIX_ROW_VPOS (last_text_row, + w->desired_matrix))); } else { - w->window_end_vpos - = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled); + wset_window_end_vpos + (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled)); } - w->window_end_valid = Qnil; + wset_window_end_valid (w, Qnil); w->desired_matrix->no_scrolling_p = 1; #ifdef GLYPH_DEBUG @@ -17293,7 +17398,7 @@ try_window_id (struct window *w) if (row) set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0); else - abort (); + emacs_abort (); return 1; } } @@ -17327,8 +17432,8 @@ try_window_id (struct window *w) { /* We have to compute the window end anew since text could have been added/removed after it. */ - w->window_end_pos - = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); + wset_window_end_pos + (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); @@ -17337,7 +17442,7 @@ try_window_id (struct window *w) if (row) set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0); else - abort (); + emacs_abort (); return 2; } } @@ -17660,15 +17765,15 @@ try_window_id (struct window *w) { rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos, bottom_vpos, dvpos); - enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos, - bottom_vpos, 0); + clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos, + bottom_vpos); } else if (dvpos > 0) { rotate_matrix (current_matrix, first_unchanged_at_end_vpos, bottom_vpos, dvpos); - enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos, - first_unchanged_at_end_vpos + dvpos, 0); + clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos, + first_unchanged_at_end_vpos + dvpos); } /* For frame-based redisplay, make sure that current frame and window @@ -17762,21 +17867,22 @@ try_window_id (struct window *w) first_unchanged_at_end_row); eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); - w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); + wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); - w->window_end_vpos - = make_number (MATRIX_ROW_VPOS (row, w->current_matrix)); + wset_window_end_vpos + (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix))); eassert (w->window_end_bytepos >= 0); IF_DEBUG (debug_method_add (w, "A")); } else if (last_text_row_at_end) { - w->window_end_pos - = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)); + wset_window_end_pos + (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end))); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end); - w->window_end_vpos - = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix)); + wset_window_end_vpos + (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end, + desired_matrix))); eassert (w->window_end_bytepos >= 0); IF_DEBUG (debug_method_add (w, "B")); } @@ -17785,12 +17891,12 @@ try_window_id (struct window *w) /* We have displayed either to the end of the window or at the end of the window, i.e. the last row with text is to be found in the desired matrix. */ - w->window_end_pos - = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); + wset_window_end_pos + (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - w->window_end_vpos - = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)); + wset_window_end_vpos + (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix))); eassert (w->window_end_bytepos >= 0); } else if (first_unchanged_at_end_row == NULL @@ -17818,20 +17924,20 @@ try_window_id (struct window *w) } eassert (row != NULL); - w->window_end_vpos = make_number (vpos + 1); - w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); + wset_window_end_vpos (w, make_number (vpos + 1)); + wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); eassert (w->window_end_bytepos >= 0); IF_DEBUG (debug_method_add (w, "C")); } else - abort (); + emacs_abort (); IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos); debug_end_vpos = XFASTINT (w->window_end_vpos)); /* Record that display has not been completed. */ - w->window_end_valid = Qnil; + wset_window_end_valid (w, Qnil); w->desired_matrix->no_scrolling_p = 1; return 3; @@ -17872,18 +17978,23 @@ dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs) void dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) { - if (glyph->type == CHAR_GLYPH) + if (glyph->type == CHAR_GLYPH + || glyph->type == GLYPHLESS_GLYPH) { fprintf (stderr, - " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", + " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n", glyph - row->glyphs[TEXT_AREA], - 'C', + (glyph->type == CHAR_GLYPH + ? 'C' + : 'G'), glyph->charpos, (BUFFERP (glyph->object) ? 'B' : (STRINGP (glyph->object) ? 'S' - : '-')), + : (INTEGERP (glyph->object) + ? '0' + : '-'))), glyph->pixel_width, glyph->u.ch, (glyph->u.ch < 0x80 && glyph->u.ch >= ' ' @@ -17896,7 +18007,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) else if (glyph->type == STRETCH_GLYPH) { fprintf (stderr, - " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", + " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n", glyph - row->glyphs[TEXT_AREA], 'S', glyph->charpos, @@ -17904,10 +18015,12 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) ? 'B' : (STRINGP (glyph->object) ? 'S' - : '-')), + : (INTEGERP (glyph->object) + ? '0' + : '-'))), glyph->pixel_width, 0, - '.', + ' ', glyph->face_id, glyph->left_box_line_p, glyph->right_box_line_p); @@ -17915,7 +18028,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) else if (glyph->type == IMAGE_GLYPH) { fprintf (stderr, - " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", + " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n", glyph - row->glyphs[TEXT_AREA], 'I', glyph->charpos, @@ -17923,7 +18036,9 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) ? 'B' : (STRINGP (glyph->object) ? 'S' - : '-')), + : (INTEGERP (glyph->object) + ? '0' + : '-'))), glyph->pixel_width, glyph->u.img_id, '.', @@ -17934,7 +18049,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) else if (glyph->type == COMPOSITE_GLYPH) { fprintf (stderr, - " %5td %4c %6"pI"d %c %3d 0x%05x", + " %5"pD"d %c %9"pI"d %c %3d 0x%06x", glyph - row->glyphs[TEXT_AREA], '+', glyph->charpos, @@ -17942,7 +18057,9 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) ? 'B' : (STRINGP (glyph->object) ? 'S' - : '-')), + : (INTEGERP (glyph->object) + ? '0' + : '-'))), glyph->pixel_width, glyph->u.cmp.id); if (glyph->u.cmp.automatic) @@ -17967,10 +18084,10 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) { if (glyphs != 1) { - fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n"); - fprintf (stderr, "======================================================================\n"); + fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n"); + fprintf (stderr, "==============================================================================\n"); - fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\ + fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\ %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n", vpos, MATRIX_ROW_START_CHARPOS (row), @@ -17995,13 +18112,14 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) row->visible_height, row->ascent, row->phys_ascent); - fprintf (stderr, "%9"pD"d %5"pD"d\t%5d\n", row->start.overlay_string_index, + /* The next 3 lines should align to "Start" in the header. */ + fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index, row->end.overlay_string_index, row->continuation_lines_width); - fprintf (stderr, "%9"pI"d %5"pI"d\n", + fprintf (stderr, " %9"pI"d %9"pI"d\n", CHARPOS (row->start.string_pos), CHARPOS (row->end.string_pos)); - fprintf (stderr, "%9d %5d\n", row->start.dpvec_index, + fprintf (stderr, " %9d %9d\n", row->start.dpvec_index, row->end.dpvec_index); } @@ -18019,7 +18137,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) ++glyph_end; if (glyph < glyph_end) - fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n"); + fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n"); for (; glyph < glyph_end; ++glyph) dump_glyph (row, glyph, area); @@ -18031,15 +18149,24 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) { - char *s = alloca (row->used[area] + 1); + char *s = alloca (row->used[area] + 4); int i; for (i = 0; i < row->used[area]; ++i) { struct glyph *glyph = row->glyphs[area] + i; - if (glyph->type == CHAR_GLYPH - && glyph->u.ch < 0x80 - && glyph->u.ch >= ' ') + if (i == row->used[area] - 1 + && area == TEXT_AREA + && INTEGERP (glyph->object) + && glyph->type == CHAR_GLYPH + && glyph->u.ch == ' ') + { + strcpy (&s[i], "[\\n]"); + i += 4; + } + else if (glyph->type == CHAR_GLYPH + && glyph->u.ch < 0x80 + && glyph->u.ch >= ' ') s[i] = glyph->u.ch; else s[i] = '.'; @@ -19202,7 +19329,7 @@ find_row_edges (struct it *it, struct glyph_row *row, /* A line that is entirely from a string/image/stretch... */ row->maxpos = row->minpos; else - abort (); + emacs_abort (); } else row->maxpos = it->current.pos; @@ -19244,7 +19371,7 @@ display_line (struct it *it) } /* Is IT->w showing the region? */ - it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil; + wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil); /* Clear the result glyph row and enable it. */ prepare_desired_row (row); @@ -20043,7 +20170,7 @@ See also `bidi-paragraph-direction'. */) return Qright_to_left; break; default: - abort (); + emacs_abort (); } } } @@ -20121,10 +20248,6 @@ display_menu_bar (struct window *w) this. */ it.paragraph_embedding = L2R; - if (! mode_line_inverse_video) - /* Force the menu-bar to be displayed in the default face. */ - it.base_face_id = it.face_id = DEFAULT_FACE_ID; - /* Clear all rows of the menu bar. */ for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i) { @@ -20248,7 +20371,7 @@ display_mode_lines (struct window *w) /* These will be set while the mode line specs are processed. */ line_number_displayed = 0; - w->column_number_displayed = Qnil; + wset_column_number_displayed (w, Qnil); if (WINDOW_WANTS_MODELINE_P (w)) { @@ -20294,10 +20417,6 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) it.glyph_row->mode_line_p = 1; - if (! mode_line_inverse_video) - /* Force the mode-line to be displayed in the default face. */ - it.base_face_id = it.face_id = DEFAULT_FACE_ID; - /* FIXME: This should be controlled by a user option. But supporting such an option is not trivial, since the mode line is made up of many separate strings. */ @@ -20998,8 +21117,7 @@ are the selected window and the WINDOW's buffer). */) : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID : DEFAULT_FACE_ID; - if (XBUFFER (buffer) != current_buffer) - old_buffer = current_buffer; + old_buffer = current_buffer; /* Save things including mode_line_proptrans_alist, and set that to nil so that we don't alter the outer value. */ @@ -21010,8 +21128,7 @@ are the selected window and the WINDOW's buffer). */) mode_line_proptrans_alist = Qnil; Fselect_window (window, Qt); - if (old_buffer) - set_buffer_internal_1 (XBUFFER (buffer)); + set_buffer_internal_1 (XBUFFER (buffer)); init_iterator (&it, w, -1, -1, NULL, face_id); @@ -21290,6 +21407,12 @@ decode_mode_spec (struct window *w, register int c, int field_width, Lisp_Object obj; struct frame *f = XFRAME (WINDOW_FRAME (w)); char *decode_mode_spec_buf = f->decode_mode_spec_buffer; + /* We are going to use f->decode_mode_spec_buffer as the buffer to + produce strings from numerical values, so limit preposterously + large values of FIELD_WIDTH to avoid overrunning the buffer's + end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE + bytes plus the terminating null. */ + int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f)); struct buffer *b = current_buffer; obj = Qnil; @@ -21384,8 +21507,8 @@ decode_mode_spec (struct window *w, register int c, int field_width, else { ptrdiff_t col = current_column (); - w->column_number_displayed = make_number (col); - pint2str (decode_mode_spec_buf, field_width, col); + wset_column_number_displayed (w, make_number (col)); + pint2str (decode_mode_spec_buf, width, col); return decode_mode_spec_buf; } @@ -21416,14 +21539,14 @@ decode_mode_spec (struct window *w, register int c, int field_width, case 'i': { ptrdiff_t size = ZV - BEGV; - pint2str (decode_mode_spec_buf, field_width, size); + pint2str (decode_mode_spec_buf, width, size); return decode_mode_spec_buf; } case 'I': { ptrdiff_t size = ZV - BEGV; - pint2hrstr (decode_mode_spec_buf, field_width, size); + pint2hrstr (decode_mode_spec_buf, width, size); return decode_mode_spec_buf; } @@ -21447,14 +21570,14 @@ decode_mode_spec (struct window *w, register int c, int field_width, goto no_value; /* But do forget it, if the window shows a different buffer now. */ else if (BUFFERP (w->base_line_pos)) - w->base_line_pos = Qnil; + wset_base_line_pos (w, Qnil); /* If the buffer is very big, don't waste time. */ if (INTEGERP (Vline_number_display_limit) && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit)) { - w->base_line_pos = Qnil; - w->base_line_number = Qnil; + wset_base_line_pos (w, Qnil); + wset_base_line_number (w, Qnil); goto no_value; } @@ -21486,8 +21609,8 @@ decode_mode_spec (struct window *w, register int c, int field_width, go back past it. */ if (startpos == BUF_BEGV (b)) { - w->base_line_number = make_number (topline); - w->base_line_pos = make_number (BUF_BEGV (b)); + wset_base_line_number (w, make_number (topline)); + wset_base_line_pos (w, make_number (BUF_BEGV (b))); } else if (nlines < height + 25 || nlines > height * 3 + 50 || linepos == BUF_BEGV (b)) @@ -21513,13 +21636,13 @@ decode_mode_spec (struct window *w, register int c, int field_width, give up on line numbers for this window. */ if (position == limit_byte && limit == startpos - distance) { - w->base_line_pos = w->buffer; - w->base_line_number = Qnil; + wset_base_line_pos (w, w->buffer); + wset_base_line_number (w, Qnil); goto no_value; } - w->base_line_number = make_number (topline - nlines); - w->base_line_pos = make_number (BYTE_TO_CHAR (position)); + wset_base_line_number (w, make_number (topline - nlines)); + wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position))); } /* Now count lines from the start pos to point. */ @@ -21530,12 +21653,12 @@ decode_mode_spec (struct window *w, register int c, int field_width, line_number_displayed = 1; /* Make the string to show. */ - pint2str (decode_mode_spec_buf, field_width, topline + nlines); + pint2str (decode_mode_spec_buf, width, topline + nlines); return decode_mode_spec_buf; no_value: { char* p = decode_mode_spec_buf; - int pad = field_width - 2; + int pad = width - 2; while (pad-- > 0) *p++ = ' '; *p++ = '?'; @@ -21671,10 +21794,10 @@ decode_mode_spec (struct window *w, register int c, int field_width, obj = Fget_buffer_process (Fcurrent_buffer ()); if (PROCESSP (obj)) { - p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system, - p, eol_flag); - p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system, - p, eol_flag); + p = decode_mode_spec_coding + (XPROCESS (obj)->decode_coding_system, p, eol_flag); + p = decode_mode_spec_coding + (XPROCESS (obj)->encode_coding_system, p, eol_flag); } #endif /* subprocesses */ #endif /* 0 */ @@ -21693,11 +21816,15 @@ decode_mode_spec (struct window *w, register int c, int field_width, } -/* Count up to COUNT lines starting from START_BYTE. - But don't go beyond LIMIT_BYTE. - Return the number of lines thus found (always nonnegative). +/* Count up to COUNT lines starting from START_BYTE. COUNT negative + means count lines back from START_BYTE. But don't go beyond + LIMIT_BYTE. Return the number of lines thus found (always + nonnegative). - Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */ + Set *BYTE_POS_PTR to the byte position where we stopped. This is + either the position COUNT lines after/before START_BYTE, if we + found COUNT lines, or LIMIT_BYTE if we hit the limit before finding + COUNT lines. */ static ptrdiff_t display_count_lines (ptrdiff_t start_byte, @@ -21956,7 +22083,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st { /* Glyph is off the left margin of the display area. Should not happen. */ - abort (); + emacs_abort (); } row->ascent = max (row->ascent, it->max_ascent); @@ -22449,7 +22576,7 @@ init_glyph_string (struct glyph_string *s, /* Append the list of glyph strings with head H and tail T to the list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */ -static inline void +static void append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail, struct glyph_string *h, struct glyph_string *t) { @@ -22469,7 +22596,7 @@ append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tai list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */ -static inline void +static void prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail, struct glyph_string *h, struct glyph_string *t) { @@ -22488,7 +22615,7 @@ prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **ta /* Append glyph string S to the list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the resulting list. */ -static inline void +static void append_glyph_string (struct glyph_string **head, struct glyph_string **tail, struct glyph_string *s) { @@ -22503,7 +22630,7 @@ append_glyph_string (struct glyph_string **head, struct glyph_string **tail, Value is a pointer to a realized face that is ready for display if DISPLAY_P is non-zero. */ -static inline struct face * +static struct face * get_char_face_and_encoding (struct frame *f, int c, int face_id, XChar2b *char2b, int display_p) { @@ -22536,7 +22663,7 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id, The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is a pointer to a realized face that is ready for display. */ -static inline struct face * +static struct face * get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph, XChar2b *char2b, int *two_byte_p) { @@ -22573,7 +22700,7 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph, /* Get glyph code of character C in FONT in the two-byte form CHAR2B. Return 1 if FONT has a glyph for C, otherwise return 0. */ -static inline int +static int get_char_glyph_code (int c, struct font *font, XChar2b *char2b) { unsigned code; @@ -23001,7 +23128,8 @@ right_overwritten (struct glyph_string *s) { int x = 0, i; struct glyph *glyphs = s->row->glyphs[s->area]; - int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); + int first = (s->first_glyph - glyphs + + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars)); int end = s->row->used[s->area]; for (i = first; i < end && s->right_overhang > x; ++i) @@ -23024,7 +23152,8 @@ right_overwriting (struct glyph_string *s) int i, k, x; int end = s->row->used[s->area]; struct glyph *glyphs = s->row->glyphs[s->area]; - int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); + int first = (s->first_glyph - glyphs + + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars)); k = -1; x = 0; @@ -23045,7 +23174,7 @@ right_overwriting (struct glyph_string *s) first glyph following S. LAST_X is the right-most x-position + 1 in the drawing area. */ -static inline void +static void set_glyph_string_background_width (struct glyph_string *s, int start, int last_x) { /* If the face of this glyph string has to be drawn to the end of @@ -23321,7 +23450,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p) break; \ \ default: \ - abort (); \ + emacs_abort (); \ } \ \ if (s) \ @@ -23414,7 +23543,9 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, /* If mouse highlighting is on, we may need to draw adjacent glyphs using mouse-face highlighting. */ - if (area == TEXT_AREA && row->mouse_face_p) + if (area == TEXT_AREA && row->mouse_face_p + && hlinfo->mouse_face_beg_row >= 0 + && hlinfo->mouse_face_end_row >= 0) { struct glyph_row *mouse_beg_row, *mouse_end_row; @@ -23606,7 +23737,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, /* Store one glyph for IT->char_to_display in IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is non-null. */ -static inline void +static void append_glyph (struct it *it) { struct glyph *glyph; @@ -23662,7 +23793,7 @@ append_glyph (struct it *it) { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } else @@ -23680,7 +23811,7 @@ append_glyph (struct it *it) IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is non-null. */ -static inline void +static void append_composite_glyph (struct it *it) { struct glyph *glyph; @@ -23736,7 +23867,7 @@ append_composite_glyph (struct it *it) { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } ++it->glyph_row->used[area]; @@ -23749,7 +23880,7 @@ append_composite_glyph (struct it *it) /* Change IT->ascent and IT->height according to the setting of IT->voffset. */ -static inline void +static void take_vertical_position_into_account (struct it *it) { if (it->voffset) @@ -23915,7 +24046,7 @@ produce_image_glyph (struct it *it) { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } ++it->glyph_row->used[area]; @@ -23976,7 +24107,7 @@ append_stretch_glyph (struct it *it, Lisp_Object object, { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } else @@ -24030,17 +24161,16 @@ produce_stretch_glyph (struct it *it) Lisp_Object prop, plist; int width = 0, height = 0, align_to = -1; int zero_width_ok_p = 0; - int ascent = 0; double tem; - struct face *face = NULL; struct font *font = NULL; #ifdef HAVE_WINDOW_SYSTEM + int ascent = 0; int zero_height_ok_p = 0; if (FRAME_WINDOW_P (it->f)) { - face = FACE_FROM_ID (it->f, it->face_id); + struct face *face = FACE_FROM_ID (it->f, it->face_id); font = face->font ? face->font : FRAME_FONT (it->f); PREPARE_FACE_FOR_DISPLAY (it->f, face); } @@ -24231,7 +24361,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what) } } else - abort (); + emacs_abort (); #ifdef HAVE_WINDOW_SYSTEM /* On a GUI frame, when the right fringe (left fringe for R2L rows) @@ -24428,7 +24558,7 @@ append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len, { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } ++it->glyph_row->used[area]; @@ -24949,7 +25079,7 @@ x_produce_glyphs (struct it *it) font_descent = FONT_DESCENT (font) - boff; font_height = FONT_HEIGHT (font); - cmp->font = (void *) font; + cmp->font = font; pcm = NULL; if (! font_not_found_p) @@ -25287,7 +25417,7 @@ x_write_glyphs (struct glyph *start, int len) if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA]) chpos = updated_row->used[TEXT_AREA] - 1; - BLOCK_INPUT; + block_input (); /* Write glyphs. */ @@ -25305,7 +25435,7 @@ x_write_glyphs (struct glyph *start, int len) && chpos < hpos + len) updated_window->phys_cursor_on_p = 0; - UNBLOCK_INPUT; + unblock_input (); /* Advance the output cursor. */ output_cursor.hpos += len; @@ -25328,7 +25458,7 @@ x_insert_glyphs (struct glyph *start, int len) ptrdiff_t hpos; eassert (updated_window && updated_row); - BLOCK_INPUT; + block_input (); w = updated_window; f = XFRAME (WINDOW_FRAME (w)); @@ -25362,7 +25492,7 @@ x_insert_glyphs (struct glyph *start, int len) /* Advance the output cursor. */ output_cursor.hpos += len; output_cursor.x += shift_by_width; - UNBLOCK_INPUT; + unblock_input (); } @@ -25431,10 +25561,10 @@ x_clear_end_of_line (int to_x) /* Prevent inadvertently clearing to end of the X window. */ if (to_x > from_x && to_y > from_y) { - BLOCK_INPUT; + block_input (); FRAME_RIF (f)->clear_frame_area (f, from_x, from_y, to_x - from_x, to_y - from_y); - UNBLOCK_INPUT; + unblock_input (); } } @@ -25761,7 +25891,7 @@ x_fix_overlapping_area (struct window *w, struct glyph_row *row, { int i, x; - BLOCK_INPUT; + block_input (); x = 0; for (i = 0; i < row->used[area];) @@ -25789,7 +25919,7 @@ x_fix_overlapping_area (struct window *w, struct glyph_row *row, } } - UNBLOCK_INPUT; + unblock_input (); } @@ -26007,7 +26137,7 @@ display_and_set_cursor (struct window *w, int on, || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])) glyph = glyph_row->glyphs[TEXT_AREA] + hpos; - eassert (interrupt_input_blocked); + eassert (input_blocked_p ()); /* Set new_cursor_type to the cursor we want to be displayed. */ new_cursor_type = get_window_cursor_type (w, glyph, @@ -26077,10 +26207,10 @@ update_window_cursor (struct window *w, int on) if (row->reversed_p && hpos >= row->used[TEXT_AREA]) hpos = row->used[TEXT_AREA] - 1; - BLOCK_INPUT; + block_input (); display_and_set_cursor (w, on, hpos, vpos, w->phys_cursor.x, w->phys_cursor.y); - UNBLOCK_INPUT; + unblock_input (); } } @@ -26258,10 +26388,10 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw) if (row->reversed_p && hpos >= row->used[TEXT_AREA]) hpos = row->used[TEXT_AREA] - 1; - BLOCK_INPUT; + block_input (); display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos, w->phys_cursor.x, w->phys_cursor.y); - UNBLOCK_INPUT; + unblock_input (); } #endif /* HAVE_WINDOW_SYSTEM */ } @@ -28076,11 +28206,11 @@ x_clear_window_mouse_face (struct window *w) Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); Lisp_Object window; - BLOCK_INPUT; + block_input (); XSETWINDOW (window, w); if (EQ (window, hlinfo->mouse_face_window)) clear_mouse_face (hlinfo); - UNBLOCK_INPUT; + unblock_input (); } @@ -28650,6 +28780,7 @@ syms_of_xdisp (void) staticpro (&Vmessage_stack); DEFSYM (Qinhibit_redisplay, "inhibit-redisplay"); + DEFSYM (Qredisplay_internal, "redisplay_internal (C function)"); message_dolog_marker1 = Fmake_marker (); staticpro (&message_dolog_marker1); @@ -28889,12 +29020,6 @@ A value of nil means to respect the value of `truncate-lines'. If `word-wrap' is enabled, you might want to reduce this. */); Vtruncate_partial_width_windows = make_number (50); - DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video, - 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; - DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit, doc: /* Maximum buffer size for which line number should be displayed. If the buffer is bigger than this, the line number does not appear @@ -28947,7 +29072,7 @@ and is used only on frames for which no explicit name has been set 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 (100); + Vmessage_log_max = make_number (1000); DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions, doc: /* Functions called before redisplay, if window sizes have changed. @@ -29261,6 +29386,10 @@ Its value should be an ASCII acronym string, `hex-code', `empty-box', or Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil); Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0), Qempty_box); + + DEFVAR_LISP ("debug-on-message", Vdebug_on_message, + doc: /* If non-nil, debug if a message matching this regexp is displayed. */); + Vdebug_on_message = Qnil; } @@ -29284,12 +29413,13 @@ init_xdisp (void) echo_area_window = minibuf_window; - XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f)); - XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)); - XSETFASTINT (r->total_cols, FRAME_COLS (f)); - XSETFASTINT (m->top_line, FRAME_LINES (f) - 1); - XSETFASTINT (m->total_lines, 1); - XSETFASTINT (m->total_cols, FRAME_COLS (f)); + wset_top_line (r, make_number (FRAME_TOP_MARGIN (f))); + wset_total_lines + (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f))); + wset_total_cols (r, make_number (FRAME_COLS (f))); + wset_top_line (m, make_number (FRAME_LINES (f) - 1)); + wset_total_lines (m, make_number (1)); + wset_total_cols (m, make_number (FRAME_COLS (f))); scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs; scratch_glyph_row.glyphs[TEXT_AREA + 1] @@ -29313,11 +29443,7 @@ init_xdisp (void) help_echo_showing_p = 0; } -/* Since w32 does not support atimers, it defines its own implementation of - the following three functions in w32fns.c. */ -#ifndef WINDOWSNT - -/* Platform-independent portion of hourglass implementation. */ +/* Platform-independent portion of hourglass implementation. */ /* Cancel a currently active hourglass timer, and start a new one. */ void @@ -29339,6 +29465,13 @@ start_hourglass (void) else delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0); +#ifdef HAVE_NTGUI + { + extern void w32_note_current_window (void); + w32_note_current_window (); + } +#endif /* HAVE_NTGUI */ + hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, show_hourglass, NULL); #endif @@ -29361,4 +29494,3 @@ cancel_hourglass (void) hide_hourglass (); #endif } -#endif /* ! WINDOWSNT */