X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/01a054bcfa98363577e3f128d8ca4fd68295d4b9..919fa9cbf0b0aabb55af71e54a2050304f4347bf:/src/xdisp.c diff --git a/src/xdisp.c b/src/xdisp.c index 65340f57d0..cbcad61400 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -42,6 +42,8 @@ extern void set_frame_menubar (); extern int interrupt_input; extern int command_loop_level; +extern Lisp_Object Qface; + /* Nonzero means print newline before next minibuffer message. */ int noninteractive_need_newline; @@ -83,6 +85,10 @@ char *previous_echo_glyphs; /* Nonzero means truncate lines in all windows less wide than the frame */ int truncate_partial_width_windows; +/* Nonzero means we have more than one non-minibuffer-only frame. + Not guaranteed to be accurate except while parsing frame-title-format. */ +int multiple_frames; + Lisp_Object Vglobal_mode_string; /* Marker for where to display an arrow on top of the buffer text. */ @@ -91,9 +97,17 @@ Lisp_Object Voverlay_arrow_position; /* String to display for the arrow. */ Lisp_Object Voverlay_arrow_string; +/* Like mode-line-format, but for the titlebar on a visible frame. */ +Lisp_Object Vframe_title_format; + +/* Like mode-line-format, but for the titlebar on an iconified frame. */ +Lisp_Object Vicon_title_format; + /* Values of those variables at last redisplay. */ static Lisp_Object last_arrow_position, last_arrow_string; +Lisp_Object Qmenu_bar_update_hook; + /* Nonzero if overlay arrow has been displayed once in this window. */ static int overlay_arrow_seen; @@ -142,7 +156,7 @@ static void display_menu_bar (); static int display_count_lines (); /* Prompt to display in front of the minibuffer contents */ -char *minibuf_prompt; +Lisp_Object minibuf_prompt; /* Width in columns of current minibuffer prompt. */ int minibuf_prompt_width; @@ -237,6 +251,8 @@ message2 (m, len) echo_area_display (); update_frame (XFRAME (XWINDOW (minibuf_window)->frame), 1, 1); do_pending_window_change (); + if (frame_up_to_date_hook != 0 && ! gc_in_progress) + (*frame_up_to_date_hook) (XFRAME (XWINDOW (minibuf_window)->frame)); } } @@ -271,6 +287,7 @@ int message_buf_print; void message (m, a1, a2, a3) char *m; + EMACS_INT a1, a2, a3; { if (noninteractive) { @@ -307,7 +324,7 @@ message (m, a1, a2, a3) { int len; #ifdef NO_ARG_ARRAY - int a[3]; + EMACS_INT a[3]; a[0] = a1; a[1] = a2; a[2] = a3; @@ -331,6 +348,12 @@ message (m, a1, a2, a3) } } +void +update_echo_area () +{ + message2 (echo_area_glyphs, echo_area_glyphs_length); +} + static void echo_area_display () { @@ -388,32 +411,57 @@ echo_area_display () } #ifdef HAVE_X_WINDOWS -/* I'm trying this out because I saw Unimpress use it, but it's - possible that this may mess adversely with some window managers. -jla +static char frame_title_buf[512]; +static char *frame_title_ptr; - Wouldn't it be nice to use something like mode-line-format to - describe frame titles? -JimB */ +static int +store_frame_title (str, mincol, maxcol) + char *str; + int mincol, maxcol; +{ + char *limit; + if (maxcol < 0 || maxcol >= sizeof(frame_title_buf)) + maxcol = sizeof (frame_title_buf); + limit = &frame_title_buf[maxcol]; + while (*str != '\0' && frame_title_ptr < limit) + *frame_title_ptr++ = *str++; + while (frame_title_ptr < &frame_title_buf[mincol]) + *frame_title_ptr++ = ' '; + return frame_title_ptr - frame_title_buf; +} -/* Change the title of the frame to the name of the buffer displayed - in the currently selected window. Don't do this for minibuffer frames, - and don't do it when there's only one non-minibuffer frame. */ static void x_consider_frame_title (frame) Lisp_Object frame; { + Lisp_Object fmt; + struct buffer *obuf; + int len; FRAME_PTR f = XFRAME (frame); - if (FRAME_X_P (f) && ! FRAME_MINIBUF_ONLY_P (f)) - { - Lisp_Object title; - - title = Qnil; - if (! EQ (Fnext_frame (frame, Qnil), frame)) - title = XBUFFER (XWINDOW (f->selected_window)->buffer)->name; - - x_implicitly_set_name (f, title, Qnil); - } + if (!FRAME_X_P (f) || FRAME_MINIBUF_ONLY_P (f) || f->explicit_name) + return; + multiple_frames = !EQ (Fnext_frame (frame, Qnil), frame); + obuf = current_buffer; + Fset_buffer (XWINDOW (f->selected_window)->buffer); + fmt = (FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format); + frame_title_ptr = frame_title_buf; + len = display_mode_element (XWINDOW (f->selected_window), 0, 0, 0, + 0, sizeof (frame_title_buf), fmt); + frame_title_ptr = 0; + set_buffer_internal (obuf); + /* Set the name only if it's changed. This avoids consing + in the common case where it hasn't. (If it turns out that we've + already wasted too much time by walking through the list with + display_mode_element, then we might need to optimize at a higher + level than this.) */ + if (! STRINGP (f->name) || XSTRING (f->name)->size != len + || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0) + x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil); } +#else +#define frame_title_ptr ((char *)0) +#define store_frame_title(str, mincol, maxcol) 0 #endif /* Prepare for redisplay by updating menu-bar item lists when appropriate. @@ -448,25 +496,20 @@ prepare_menu_bars () frame_garbaged = 0; } - if (clip_changed || windows_or_buffers_changed) - update_mode_lines++; + all_windows = (update_mode_lines || buffer_shared > 1 + || clip_changed || windows_or_buffers_changed); - /* Detect case that we need to write a star in the mode line. */ - if (XFASTINT (w->last_modified) < MODIFF - && XFASTINT (w->last_modified) <= current_buffer->save_modified) +#ifdef HAVE_X_WINDOWS + if (windows_or_buffers_changed) { - w->update_mode_line = Qt; - if (buffer_shared > 1) - update_mode_lines++; - } - - all_windows = update_mode_lines || buffer_shared > 1; + Lisp_Object tail, frame; - /* If specs for an arrow have changed, do thorough redisplay - to ensure we remove any arrow that should no longer exist. */ - if (! EQ (Voverlay_arrow_position, last_arrow_position) - || ! EQ (Voverlay_arrow_string, last_arrow_string)) - all_windows = 1, clip_changed = 1; + FOR_EACH_FRAME (tail, frame) + if (FRAME_VISIBLE_P (XFRAME (frame)) + || FRAME_ICONIFIED_P (XFRAME (frame))) + x_consider_frame_title (frame); + } +#endif /* Update the menu bar item lists, if appropriate. This has to be done before any actual redisplay @@ -476,15 +519,10 @@ prepare_menu_bars () Lisp_Object tail, frame; FOR_EACH_FRAME (tail, frame) - { - FRAME_PTR f = XFRAME (frame); - - if (FRAME_VISIBLE_P (f)) - update_menu_bars (FRAME_ROOT_WINDOW (f)); - } + update_menu_bar (XFRAME (frame)); } - else if (FRAME_VISIBLE_P (selected_frame)) - update_menu_bar (selected_window); + else + update_menu_bar (selected_frame); } /* Do a frame update, taking possible shortcuts into account. @@ -505,6 +543,12 @@ prepare_menu_bars () See Fcall_process; if you called it from here, it could be entered recursively. */ +static int do_verify_charstarts; + +/* Counter is used to clear the face cache + no more than once ever 1000 redisplays. */ +static int clear_face_cache_count; + void redisplay () { @@ -589,8 +633,8 @@ redisplay () && current_buffer == XBUFFER (w->buffer) && NILP (w->force_start) /* Point must be on the line that we have info recorded about */ - && point >= tlbufpos - && point <= Z - tlendpos + && PT >= tlbufpos + && PT <= Z - tlendpos /* All text outside that line, including its final newline, must be unchanged */ && (XFASTINT (w->last_modified) >= MODIFF @@ -598,7 +642,7 @@ redisplay () && GPT >= tlbufpos /* If selective display, can't optimize if the changes start at the beginning of the line. */ - && ((XTYPE (current_buffer->selective_display) == Lisp_Int + && ((INTEGERP (current_buffer->selective_display) && XINT (current_buffer->selective_display) > 0 ? (beg_unchanged >= tlbufpos && GPT > tlbufpos) @@ -623,23 +667,29 @@ redisplay () if (cursor_vpos >= 0 && this_line_bufpos && this_line_endpos == tlendpos) { - int left = XFASTINT (w->left); - int *charstart_next_line - = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w)))->charstarts[this_line_vpos + 1]; - int i; - int adjust; - - if (Z - tlendpos == ZV) - /* This line ends at end of (accessible part of) buffer. - There is no newline to count. */ - adjust = Z - tlendpos - charstart_next_line[left]; - else - /* This line ends in a newline. - Must take account of the newline and the rest of the - text that follows. */ - adjust = Z - tlendpos + 1 - charstart_next_line[left]; - - adjust_window_charstarts (w, this_line_vpos, adjust); + /* If this is not the window's last line, + we must adjust the charstarts of the lines below. */ + if (this_line_vpos + 1 + < XFASTINT (w->top) + window_internal_height (w)) + { + int left = XFASTINT (w->left); + int *charstart_next_line + = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w)))->charstarts[this_line_vpos + 1]; + int i; + int adjust; + + if (Z - tlendpos == ZV) + /* This line ends at end of (accessible part of) buffer. + There is no newline to count. */ + adjust = Z - tlendpos - charstart_next_line[left]; + else + /* This line ends in a newline. + Must take account of the newline and the rest of the + text that follows. */ + adjust = Z - tlendpos + 1 - charstart_next_line[left]; + + adjust_window_charstarts (w, this_line_vpos, adjust); + } if (XFASTINT (w->width) != FRAME_WIDTH (XFRAME (WINDOW_FRAME (w)))) preserve_other_columns (w); @@ -648,7 +698,7 @@ redisplay () else goto cancel; } - else if (point == XFASTINT (w->last_point)) + else if (PT == XFASTINT (w->last_point)) { if (!must_finish) { @@ -664,10 +714,10 @@ redisplay () { pos = *compute_motion (tlbufpos, 0, XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0, - point, 2, - (1 << (SHORTBITS - 1)), + PT, 2, - (1 << (SHORTBITS - 1)), window_internal_width (w) - 1, XINT (w->hscroll), - pos_tab_offset (w, tlbufpos)); + pos_tab_offset (w, tlbufpos), w); if (pos.vpos < 1) { FRAME_CURSOR_X (selected_frame) @@ -686,14 +736,20 @@ redisplay () this_line_bufpos = 0; all_windows |= buffer_shared > 1; + clear_face_cache_count++; + if (all_windows) { Lisp_Object tail, frame; #ifdef HAVE_X_WINDOWS - /* Since we're doing a thorough redisplay, we might as well - recompute all our display faces. */ - clear_face_vector (); + /* Clear the face cache, only when we do a full redisplay + and not too often either. */ + if (clear_face_cache_count > 1000) + { + clear_face_cache (); + clear_face_cache_count = 0; + } #endif /* Recompute # windows showing selected buffer. @@ -711,11 +767,6 @@ redisplay () if (FRAME_VISIBLE_P (f)) redisplay_windows (FRAME_ROOT_WINDOW (f)); -#ifdef HAVE_X_WINDOWS - else if (FRAME_ICONIFIED_P (f) - && ! MINI_WINDOW_P (XWINDOW (f->selected_window))) - x_consider_frame_title (frame); -#endif /* Any scroll bars which redisplay_windows should have nuked should now go away. */ @@ -749,7 +800,7 @@ update: { FRAME_PTR f; - if (XTYPE (XCONS (tail)->car) != Lisp_Frame) + if (!FRAMEP (XCONS (tail)->car)) continue; f = XFRAME (XCONS (tail)->car); @@ -816,19 +867,21 @@ update: beg_unchanged = BUF_GPT (b) - BUF_BEG (b); end_unchanged = BUF_Z (b) - BUF_GPT (b); - XFASTINT (w->last_point) = BUF_PT (b); - XFASTINT (w->last_point_x) = FRAME_CURSOR_X (selected_frame); - XFASTINT (w->last_point_y) = FRAME_CURSOR_Y (selected_frame); + XSETFASTINT (w->last_point, BUF_PT (b)); + XSETFASTINT (w->last_point_x, FRAME_CURSOR_X (selected_frame)); + XSETFASTINT (w->last_point_y, FRAME_CURSOR_Y (selected_frame)); if (all_windows) mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1); else { w->update_mode_line = Qnil; - XFASTINT (w->last_modified) = BUF_MODIFF (b); - w->window_end_valid = Qt; + XSETFASTINT (w->last_modified, BUF_MODIFF (b)); + w->window_end_valid = w->buffer; last_arrow_position = Voverlay_arrow_position; last_arrow_string = Voverlay_arrow_string; + if (do_verify_charstarts) + verify_charstarts (w); if (frame_up_to_date_hook != 0) (*frame_up_to_date_hook) (selected_frame); } @@ -849,6 +902,11 @@ update: /* Change frame size now if a change is pending. */ do_pending_window_change (); + + /* If we just did a pending size change, redisplay again + for the new size. */ + if (windows_or_buffers_changed && !pause) + redisplay (); } /* Redisplay, but leave alone any recent echo area message @@ -880,15 +938,13 @@ mark_window_display_accurate (window, flag) for (;!NILP (window); window = w->next) { - if (XTYPE (window) != Lisp_Window) abort (); + if (!WINDOWP (window)) abort (); w = XWINDOW (window); if (!NILP (w->buffer)) { - XFASTINT (w->last_modified) - = !flag ? 0 - : XBUFFER (w->buffer) == current_buffer - ? MODIFF : BUF_MODIFF (XBUFFER (w->buffer)); + XSETFASTINT (w->last_modified, + !flag ? 0 : BUF_MODIFF (XBUFFER (w->buffer))); /* Record if we are showing a region, so can make sure to update it fully at next redisplay. */ @@ -898,7 +954,7 @@ mark_window_display_accurate (window, flag) : Qnil); } - w->window_end_valid = Qt; + w->window_end_valid = w->buffer; w->update_mode_line = Qnil; if (!NILP (w->vchild)) @@ -920,55 +976,30 @@ mark_window_display_accurate (window, flag) } } -/* Update the menu bar item lists for WINDOW - and its subwindows and siblings. +/* Update the menu bar item list for frame F. This has to be done before we start to fill in any display lines, because it can call eval. */ static void -update_menu_bars (window) - Lisp_Object window; -{ - for (; !NILP (window); window = XWINDOW (window)->next) - update_menu_bar (window); -} - -/* Update the menu bar item list for window WINDOW and its subwindows. */ - -static void -update_menu_bar (window) - Lisp_Object window; +update_menu_bar (f) + FRAME_PTR f; { - register struct window *w = XWINDOW (window); struct buffer *old = current_buffer; - FRAME_PTR f = XFRAME (WINDOW_FRAME (w)); - - /* If this is a combination window, do its children; that's all. */ - - if (!NILP (w->vchild)) - { - update_menu_bars (w->vchild); - return; - } - if (!NILP (w->hchild)) - { - update_menu_bars (w->hchild); - return; - } - if (NILP (w->buffer)) - abort (); + Lisp_Object window; + register struct window *w; + window = FRAME_SELECTED_WINDOW (f); + w = XWINDOW (window); if (update_mode_lines) w->update_mode_line = Qt; - /* When we reach a frame's selected window, redo the frame's menu bar. */ - if (!NILP (w->update_mode_line) + if ( #ifdef USE_X_TOOLKIT - && FRAME_EXTERNAL_MENU_BAR (f) + FRAME_EXTERNAL_MENU_BAR (f) #else - && FRAME_MENU_BAR_LINES (f) > 0 + FRAME_MENU_BAR_LINES (f) > 0 #endif - && EQ (FRAME_SELECTED_WINDOW (f), window)) + ) { /* If the user has switched buffers or windows, we need to recompute to reflect the new bindings. But we'll @@ -978,12 +1009,13 @@ update_menu_bar (window) the rest of the redisplay algorithm is about the same as windows_or_buffers_changed anyway. */ if (windows_or_buffers_changed - || update_mode_lines + || !NILP (w->update_mode_line) || (XFASTINT (w->last_modified) < MODIFF && (XFASTINT (w->last_modified) <= XBUFFER (w->buffer)->save_modified))) { struct buffer *prev = current_buffer; + call1 (Vrun_hooks, Qmenu_bar_update_hook); current_buffer = XBUFFER (w->buffer); FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); current_buffer = prev; @@ -1016,13 +1048,13 @@ redisplay_window (window, just_this_one) register struct window *w = XWINDOW (window); FRAME_PTR f = XFRAME (WINDOW_FRAME (w)); int height; - register int lpoint = point; + register int lpoint = PT; struct buffer *old = current_buffer; register int width = window_internal_width (w) - 1; register int startp; register int hscroll = XINT (w->hscroll); struct position pos; - int opoint = point; + int opoint = PT; int tem; int window_needs_modeline; @@ -1076,7 +1108,7 @@ redisplay_window (window, just_this_one) /* Otherwise set up data on this window; select its buffer and point value */ current_buffer = XBUFFER (w->buffer); - opoint = point; + opoint = PT; /* Count number of windows showing the selected buffer. */ @@ -1089,17 +1121,38 @@ redisplay_window (window, just_this_one) if (!EQ (window, selected_window)) { - SET_PT (marker_position (w->pointm)); - if (point < BEGV) + int new_pt = marker_position (w->pointm); + if (new_pt < BEGV) { - SET_PT (BEGV); - Fset_marker (w->pointm, make_number (point), Qnil); + new_pt = BEGV; + Fset_marker (w->pointm, make_number (new_pt), Qnil); } - else if (point > (ZV - 1)) + else if (new_pt > (ZV - 1)) { - SET_PT (ZV); - Fset_marker (w->pointm, make_number (point), Qnil); + new_pt = ZV; + Fset_marker (w->pointm, make_number (new_pt), Qnil); } + /* We don't use SET_PT so that the point-motion hooks don't run. */ + BUF_PT (current_buffer) = new_pt; + } + + /* If any of the character widths specified in the display table + have changed, invalidate the width run cache. It's true that this + may be a bit late to catch such changes, but the rest of + redisplay goes (non-fatally) haywire when the display table is + changed, so why should we worry about doing any better? */ + if (current_buffer->width_run_cache) + { + struct Lisp_Vector *disptab = buffer_display_table (); + + if (! disptab_matches_widthtab (disptab, + XVECTOR (current_buffer->width_table))) + { + invalidate_region_cache (current_buffer, + current_buffer->width_run_cache, + BEG, Z); + recompute_width_table (current_buffer, disptab); + } } /* If window-start is screwed up, choose a new one. */ @@ -1116,13 +1169,12 @@ redisplay_window (window, just_this_one) w->base_line_number = Qnil; w->update_mode_line = Qt; w->force_start = Qnil; - XFASTINT (w->last_modified) = 0; + XSETFASTINT (w->last_modified, 0); if (startp < BEGV) startp = BEGV; if (startp > ZV) startp = ZV; try_window (window, startp); if (cursor_vpos < 0) { - /* ??? What should happen here if highlighting a region? */ /* If point does not appear, move point so it does appear */ pos = *compute_motion (startp, 0, ((EQ (window, minibuf_window) && startp == 1) @@ -1131,17 +1183,25 @@ redisplay_window (window, just_this_one) (hscroll ? 1 - hscroll : 0), ZV, height / 2, - (1 << (SHORTBITS - 1)), - width, hscroll, pos_tab_offset (w, startp)); - SET_PT (pos.bufpos); + width, hscroll, pos_tab_offset (w, startp), w); + BUF_PT (current_buffer) = pos.bufpos; if (w != XWINDOW (selected_window)) - Fset_marker (w->pointm, make_number (point), Qnil); + Fset_marker (w->pointm, make_number (PT), Qnil); else { if (current_buffer == old) - lpoint = point; + lpoint = PT; FRAME_CURSOR_X (f) = max (0, pos.hpos) + XFASTINT (w->left); FRAME_CURSOR_Y (f) = pos.vpos + XFASTINT (w->top); } + /* If we are highlighting the region, + then we just changed the region, so redisplay to show it. */ + if (!NILP (Vtransient_mark_mode) + && !NILP (current_buffer->mark_active)) + { + cancel_my_columns (XWINDOW (window)); + try_window (window, startp); + } } goto done; } @@ -1157,16 +1217,19 @@ redisplay_window (window, just_this_one) in redisplay handles the same cases. */ if (XFASTINT (w->last_modified) >= MODIFF - && point >= startp && !clip_changed + && PT >= startp && !clip_changed && (just_this_one || XFASTINT (w->width) == FRAME_WIDTH (f)) /* Can't use this case if highlighting a region. */ && !(!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active)) && NILP (w->region_showing) + /* If end pos is out of date, scroll bar and percentage will be wrong */ + && INTEGERP (w->window_end_vpos) + && XFASTINT (w->window_end_vpos) < XFASTINT (w->height) && !EQ (window, minibuf_window)) { pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), - point, height + 1, 10000, width, hscroll, - pos_tab_offset (w, startp)); + PT, height + 1, 10000, width, hscroll, + pos_tab_offset (w, startp), w); if (pos.vpos < height) { @@ -1192,13 +1255,13 @@ redisplay_window (window, just_this_one) /* If current starting point was originally the beginning of a line but no longer is, find a new starting point. */ else if (!NILP (w->start_at_line_beg) - && !(startp == BEGV + && !(startp <= BEGV || FETCH_CHAR (startp - 1) == '\n')) { goto recenter; } else if (just_this_one && !MINI_WINDOW_P (w) - && point >= startp + && PT >= startp && XFASTINT (w->last_modified) /* or else vmotion on first line won't work. */ && ! NILP (w->start_at_line_beg) @@ -1241,14 +1304,14 @@ redisplay_window (window, just_this_one) cancel_my_columns (w); } - XFASTINT (w->last_modified) = 0; + XSETFASTINT (w->last_modified, 0); w->update_mode_line = Qt; /* Try to scroll by specified few lines */ if (scroll_step && !clip_changed) { - if (point > startp) + if (PT > startp) { pos = *vmotion (Z - XFASTINT (w->window_end_pos), scroll_step, width, hscroll, window); @@ -1256,10 +1319,10 @@ redisplay_window (window, just_this_one) goto scroll_fail; } - pos = *vmotion (startp, point < startp ? - scroll_step : scroll_step, + pos = *vmotion (startp, PT < startp ? - scroll_step : scroll_step, width, hscroll, window); - if (point >= pos.bufpos) + if (PT >= pos.bufpos) { try_window (window, pos.bufpos); if (cursor_vpos >= 0) @@ -1281,12 +1344,12 @@ recenter: /* Forget any previously recorded base line for line number display. */ w->base_line_number = Qnil; - pos = *vmotion (point, - (height / 2), width, hscroll, window); + pos = *vmotion (PT, - (height / 2), width, hscroll, window); try_window (window, pos.bufpos); startp = marker_position (w->start); - w->start_at_line_beg = - (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil; + w->start_at_line_beg + = (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil; done: if ((!NILP (w->update_mode_line) @@ -1348,9 +1411,9 @@ done: (*redeem_scroll_bar_hook) (w); } - SET_PT (opoint); + BUF_PT (current_buffer) = opoint; current_buffer = old; - SET_PT (lpoint); + BUF_PT (current_buffer) = lpoint; } /* Do full redisplay on one window, starting at position `pos'. */ @@ -1404,8 +1467,8 @@ try_window (window, pos) w->update_mode_line = Qt; /* Say where last char on frame will be, once redisplay is finished. */ - XFASTINT (w->window_end_pos) = Z - pos; - XFASTINT (w->window_end_vpos) = last_text_vpos - XFASTINT (w->top); + XSETFASTINT (w->window_end_pos, Z - pos); + XSETFASTINT (w->window_end_vpos, last_text_vpos - XFASTINT (w->top)); /* But that is not valid info until redisplay finishes. */ w->window_end_valid = Qnil; } @@ -1434,10 +1497,9 @@ try_window_id (window) register int i, tem; int last_text_vpos = 0; int stop_vpos; - int selective - = XTYPE (current_buffer->selective_display) == Lisp_Int - ? XINT (current_buffer->selective_display) - : !NILP (current_buffer->selective_display) ? -1 : 0; + int selective = (INTEGERP (current_buffer->selective_display) + ? XINT (current_buffer->selective_display) + : !NILP (current_buffer->selective_display) ? -1 : 0); struct position val, bp, ep, xp, pp; int scroll_amount = 0; @@ -1455,10 +1517,10 @@ try_window_id (window) /* Find position before which nothing is changed. */ bp = *compute_motion (start, 0, lmargin, min (ZV, beg_unchanged + BEG), height + 1, 0, - width, hscroll, pos_tab_offset (w, start)); + width, hscroll, pos_tab_offset (w, start), w); if (bp.vpos >= height) { - if (point < bp.bufpos && !bp.contin) + if (PT < bp.bufpos && !bp.contin) { /* All changes are below the frame, and point is on the frame. We don't need to change the frame at all. @@ -1466,9 +1528,9 @@ try_window_id (window) any change in buffer size. */ bp = *compute_motion (start, 0, lmargin, Z, height, 0, - width, hscroll, pos_tab_offset (w, start)); - XFASTINT (w->window_end_vpos) = height; - XFASTINT (w->window_end_pos) = Z - bp.bufpos; + width, hscroll, pos_tab_offset (w, start), w); + XSETFASTINT (w->window_end_vpos, height); + XSETFASTINT (w->window_end_pos, Z - bp.bufpos); return 1; } return 0; @@ -1514,7 +1576,7 @@ try_window_id (window) /* Compute the cursor position after that newline. */ ep = *compute_motion (pos, vpos, val.hpos, tem, height, - (1 << (SHORTBITS - 1)), - width, hscroll, pos_tab_offset (w, bp.bufpos)); + width, hscroll, pos_tab_offset (w, bp.bufpos), w); /* If changes reach past the text available on the frame, just display rest of frame. */ @@ -1545,7 +1607,7 @@ try_window_id (window) epto = pos_tab_offset (w, ep.bufpos); xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, Z - XFASTINT (w->window_end_pos), - 10000, 0, width, hscroll, epto); + 10000, 0, width, hscroll, epto, w); scroll_amount = xp.vpos - XFASTINT (w->window_end_vpos); /* Is everything on frame below the changes whitespace? @@ -1559,24 +1621,26 @@ try_window_id (window) if (i == xp.bufpos) return -2; - XFASTINT (w->window_end_vpos) += scroll_amount; + XSETFASTINT (w->window_end_vpos, + XFASTINT (w->window_end_vpos) + scroll_amount); /* Before doing any scrolling, verify that point will be on frame. */ - if (point > ep.bufpos && !(point <= xp.bufpos && xp.bufpos < height)) + if (PT > ep.bufpos && !(PT <= xp.bufpos && xp.bufpos < height)) { - if (point <= xp.bufpos) + if (PT <= xp.bufpos) { pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, - point, height, - (1 << (SHORTBITS - 1)), - width, hscroll, epto); + PT, height, - (1 << (SHORTBITS - 1)), + width, hscroll, epto, w); } else { pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, - point, height, - (1 << (SHORTBITS - 1)), - width, hscroll, pos_tab_offset (w, xp.bufpos)); + PT, height, - (1 << (SHORTBITS - 1)), + width, hscroll, + pos_tab_offset (w, xp.bufpos), w); } - if (pp.bufpos < point || pp.vpos == height) + if (pp.bufpos < PT || pp.vpos == height) return 0; cursor_vpos = pp.vpos + top; cursor_hpos = pp.hpos + XFASTINT (w->left); @@ -1597,7 +1661,14 @@ try_window_id (window) blank_end_of_window = 1; } else if (!scroll_amount) - {} + { + /* Even if we don't need to scroll, we must adjust the + charstarts of subsequent lines (that we won't redisplay) + according to the amount of text inserted or deleted. */ + int oldpos = FRAME_CURRENT_GLYPHS (f)->charstarts[ep.vpos + top][0]; + int adjust = ep.bufpos - oldpos; + adjust_window_charstarts (w, ep.vpos + top - 1, adjust); + } else if (bp.bufpos == Z - end_unchanged) { /* If reprinting everything is nearly as fast as scrolling, @@ -1616,7 +1687,24 @@ try_window_id (window) tem = scroll_frame_lines (f, bp.vpos + top - scroll_amount, top + height - max (0, scroll_amount), scroll_amount, bp.bufpos); - if (!tem) stop_vpos = height; + if (!tem) + stop_vpos = height; + else + { + /* scroll_frame_lines did not properly adjust subsequent + lines' charstarts in the case where the text of the + screen line at bp.vpos has changed. + (This can happen in a deletion that ends in mid-line.) + To adjust properly, we need to make things constent at + the position ep. + So do a second adjust to make that happen. + Note that stop_vpos >= ep.vpos, so it is sufficient + to update the charstarts for lines at ep.vpos and below. */ + int oldstart + = FRAME_CURRENT_GLYPHS (f)->charstarts[ep.vpos + top][0]; + adjust_window_charstarts (w, ep.vpos + top - 1, + ep.bufpos - oldstart); + } } else if (scroll_amount) { @@ -1680,8 +1768,8 @@ try_window_id (window) include the split character in the text considered on the frame */ if (val.hpos < lmargin) val.bufpos++; - XFASTINT (w->window_end_vpos) = last_text_vpos; - XFASTINT (w->window_end_pos) = Z - val.bufpos; + XSETFASTINT (w->window_end_vpos, last_text_vpos); + XSETFASTINT (w->window_end_pos, Z - val.bufpos); } /* If scrolling made blank lines at window bottom, @@ -1720,7 +1808,7 @@ try_window_id (window) /* Here is a case where display_text_line sets cursor_vpos wrong. Make it be fixed up, below. */ if (xp.bufpos == ZV - && xp.bufpos == point) + && xp.bufpos == PT) cursor_vpos = -1; } @@ -1739,8 +1827,9 @@ try_window_id (window) { val = *vmotion (Z - XFASTINT (w->window_end_pos), delta, width, hscroll, window); - XFASTINT (w->window_end_pos) = Z - val.bufpos; - XFASTINT (w->window_end_vpos) += val.vpos; + XSETFASTINT (w->window_end_pos, Z - val.bufpos); + XSETFASTINT (w->window_end_vpos, + XFASTINT (w->window_end_vpos) + val.vpos); } } @@ -1749,8 +1838,8 @@ try_window_id (window) /* If point was not in a line that was displayed, find it */ if (cursor_vpos < 0) { - val = *compute_motion (start, 0, lmargin, point, 10000, 10000, - width, hscroll, pos_tab_offset (w, start)); + val = *compute_motion (start, 0, lmargin, PT, 10000, 10000, + width, hscroll, pos_tab_offset (w, start), w); /* Admit failure if point is off frame now */ if (val.vpos >= height) { @@ -1769,7 +1858,7 @@ try_window_id (window) { val = *compute_motion (start, 0, lmargin, ZV, height, - (1 << (SHORTBITS - 1)), - width, hscroll, pos_tab_offset (w, start)); + width, hscroll, pos_tab_offset (w, start), w); if (val.vpos != XFASTINT (w->window_end_vpos)) abort (); if (XFASTINT (w->window_end_pos) @@ -1813,7 +1902,15 @@ redisplay_region (buf, start, end) start = end; end = temp; } - if (buf != current_buffer) + /* If this is a buffer not in the selected window, + we must do other windows. */ + if (buf != XBUFFER (XWINDOW (selected_window)->buffer)) + windows_or_buffers_changed = 1; + /* If it's not current, we can't use beg_unchanged, end_unchanged for it. */ + else if (buf != current_buffer) + windows_or_buffers_changed = 1; + /* If multiple windows show this buffer, we must do other windows. */ + else if (buffer_shared > 1) windows_or_buffers_changed = 1; else { @@ -1866,7 +1963,7 @@ copy_part_of_rope (f, to, s, from, len, face) if (! FRAME_TERMCAP_P (f)) while (n--) { - int glyph = XFASTINT (*fp); + int glyph = (INTEGERP (*fp) ? XFASTINT (*fp) : 0); int facecode; if (FAST_GLYPH_FACE (glyph) == 0) @@ -1891,7 +1988,7 @@ copy_part_of_rope (f, to, s, from, len, face) #endif while (n--) { - if (to >= s) *to = XFASTINT (*fp); + if (to >= s) *to = (INTEGERP (*fp) ? XFASTINT (*fp) : 0); ++to; ++fp; } @@ -1902,29 +1999,36 @@ copy_part_of_rope (f, to, s, from, len, face) with a displayable computed face code. */ static GLYPH -fix_glyph (f, glyph, current_face) +fix_glyph (f, glyph, cface) FRAME_PTR f; GLYPH glyph; - int current_face; + int cface; { #ifdef HAVE_X_WINDOWS - if (! FRAME_TERMCAP_P (f) && FAST_GLYPH_FACE (glyph) != 0) - return FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph), - compute_glyph_face (f, FAST_GLYPH_FACE (glyph), - current_face)); + if (! FRAME_TERMCAP_P (f)) + { + if (FAST_GLYPH_FACE (glyph) != 0) + cface = compute_glyph_face (f, FAST_GLYPH_FACE (glyph), cface); + glyph = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph), cface); + } #endif return glyph; } -/* Display one line of window w, starting at position START in W's buffer. - Display starting at horizontal position HPOS, which is normally zero - or negative. A negative value causes output up to hpos = 0 to be discarded. - This is done for negative hscroll, or when this is a continuation line - and the continuation occurred in the middle of a multi-column character. +/* Display one line of window W, starting at position START in W's buffer. + + Display starting at horizontal position HPOS, expressed relative to + W's left edge. In situations where the text at START shouldn't + start at the left margin (i.e. when the window is hscrolled, or + we're continuing a line which left off in the midst of a + multi-column character), HPOS should be negative; we throw away + characters up 'til hpos = 0. So, HPOS must take hscrolling into + account. TABOFFSET is an offset for ostensible hpos, used in tab stop calculations. - Display on position VPOS on the frame. (origin 0). + Display on position VPOS on the frame. It is origin 0, relative to + the top of the frame, not W. Returns a STRUCT POSITION giving character to start next line with and where to display it, including a zero or negative hpos. @@ -1947,7 +2051,7 @@ display_text_line (w, start, vpos, hpos, taboffset) register int pause; register unsigned char *p; GLYPH *endp; - register GLYPH *startp; + register GLYPH *leftmargin; register GLYPH *p1prev = 0; register GLYPH *p1start; int *charstart; @@ -1959,20 +2063,19 @@ display_text_line (w, start, vpos, hpos, taboffset) int lastpos; int invis; int hscroll = XINT (w->hscroll); - int truncate = hscroll - || (truncate_partial_width_windows - && XFASTINT (w->width) < FRAME_WIDTH (f)) - || !NILP (current_buffer->truncate_lines); + int truncate = (hscroll + || (truncate_partial_width_windows + && XFASTINT (w->width) < FRAME_WIDTH (f)) + || !NILP (current_buffer->truncate_lines)); /* 1 if we should highlight the region. */ int highlight_region = !NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active); int region_beg, region_end; - int selective - = XTYPE (current_buffer->selective_display) == Lisp_Int - ? XINT (current_buffer->selective_display) - : !NILP (current_buffer->selective_display) ? -1 : 0; + int selective = (INTEGERP (current_buffer->selective_display) + ? XINT (current_buffer->selective_display) + : !NILP (current_buffer->selective_display) ? -1 : 0); register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (f); register struct Lisp_Vector *dp = window_display_table (w); @@ -1980,20 +2083,20 @@ display_text_line (w, start, vpos, hpos, taboffset) /* Nonzero means display something where there are invisible lines. The precise value is the number of glyphs to display. */ int selective_rlen - = (selective && dp && XTYPE (DISP_INVIS_VECTOR (dp)) == Lisp_Vector + = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp)) ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : selective && !NILP (current_buffer->selective_display_ellipses) ? 3 : 0); /* This is the sequence of Lisp objects to display when there are invisible lines. */ Lisp_Object *invis_vector_contents - = (dp && XTYPE (DISP_INVIS_VECTOR (dp)) == Lisp_Vector + = (dp && VECTORP (DISP_INVIS_VECTOR (dp)) ? XVECTOR (DISP_INVIS_VECTOR (dp))->contents : default_invis_vector); - GLYPH truncator = (dp == 0 || XTYPE (DISP_TRUNC_GLYPH (dp)) != Lisp_Int + GLYPH truncator = (dp == 0 || !INTEGERP (DISP_TRUNC_GLYPH (dp)) ? '$' : XINT (DISP_TRUNC_GLYPH (dp))); - GLYPH continuer = (dp == 0 || XTYPE (DISP_CONTINUE_GLYPH (dp)) != Lisp_Int + GLYPH continuer = (dp == 0 || !INTEGERP (DISP_CONTINUE_GLYPH (dp)) ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp))); /* The next buffer location at which the face should change, due @@ -2009,7 +2112,7 @@ display_text_line (w, start, vpos, hpos, taboffset) int current_face = 0; int i; - XFASTINT (default_invis_vector[2]) = '.'; + XSETFASTINT (default_invis_vector[2], '.'); default_invis_vector[0] = default_invis_vector[1] = default_invis_vector[2]; hpos += XFASTINT (w->left); @@ -2035,25 +2138,65 @@ display_text_line (w, start, vpos, hpos, taboffset) else region_beg = region_end = -1; - if (MINI_WINDOW_P (w) && start == 1 + if (MINI_WINDOW_P (w) + && start == 1 && vpos == XFASTINT (w->top)) { - if (minibuf_prompt) - hpos = display_string (w, vpos, minibuf_prompt, -1, hpos, + if (! NILP (minibuf_prompt)) + { + minibuf_prompt_width + = (display_string (w, vpos, XSTRING (minibuf_prompt)->data, + XSTRING (minibuf_prompt)->size, hpos, (!truncate ? continuer : truncator), - 1, -1, -1); - minibuf_prompt_width = hpos; + 1, -1, -1) + - hpos); + hpos += minibuf_prompt_width; + } + else + minibuf_prompt_width = 0; + } + + end = ZV; + + /* If we're hscrolled at all, use compute_motion to skip over any + text off the left edge of the window. compute_motion may know + tricks to do this faster than we can. */ + if (hpos < 0) + { + struct position *left_edge + = compute_motion (pos, vpos, hpos, + end, vpos, 0, + width, hscroll, taboffset, w); + + /* Retrieve the buffer position and column provided by + compute_motion. We can't assume that the column will be + zero, because you may have multi-column characters crossing + the left margin. + + compute_motion may have moved us past the screen position we + requested, if we hit a multi-column character, or the end of + the line. If so, back up. */ + if (left_edge->vpos > vpos + || left_edge->hpos > 0) + { + pos = left_edge->bufpos - 1; + hpos = left_edge->prevhpos; + } + else + { + pos = left_edge->bufpos; + hpos = left_edge->hpos; + } } - desired_glyphs->bufp[vpos] = pos; + desired_glyphs->bufp[vpos] = start; p1 = desired_glyphs->glyphs[vpos] + hpos; p1start = p1; charstart = desired_glyphs->charstarts[vpos] + hpos; /* In case we don't ever write anything into it... */ - *charstart = -1; - end = ZV; - startp = desired_glyphs->glyphs[vpos] + XFASTINT (w->left); - endp = startp + width; + desired_glyphs->charstarts[vpos][XFASTINT (w->left)] = -1; + leftmargin = desired_glyphs->glyphs[vpos] + XFASTINT (w->left); + endp = leftmargin + width; /* Arrange the overlays nicely for our purposes. Usually, we call display_text_line on only one line at a time, in which case this @@ -2071,11 +2214,15 @@ display_text_line (w, start, vpos, hpos, taboffset) #ifdef USE_TEXT_PROPERTIES next_invisible = pos; #endif - while (p1 < endp) + while (1) { /* Record which glyph starts a character, and the character position of that character. */ - charstart[p1 - p1start] = pos; + if (p1 >= leftmargin) + charstart[p1 - p1start] = pos; + + if (p1 >= endp) + break; p1prev = p1; if (pos >= pause) @@ -2086,10 +2233,10 @@ display_text_line (w, start, vpos, hpos, taboffset) break; /* Did we reach point? Record the cursor location. */ - if (pos == point && cursor_vpos < 0) + if (pos == PT && cursor_vpos < 0) { cursor_vpos = vpos; - cursor_hpos = p1 - startp; + cursor_hpos = p1 - leftmargin; } #ifdef USE_TEXT_PROPERTIES @@ -2098,14 +2245,14 @@ display_text_line (w, start, vpos, hpos, taboffset) while (pos == next_invisible && pos < end) { Lisp_Object position, limit, endpos, prop, ww; - XFASTINT (position) = pos; - XSET (ww, Lisp_Window, w); + XSETFASTINT (position, pos); + XSETWINDOW (ww, w); prop = Fget_char_property (position, Qinvisible, ww); /* This is just an estimate to give reasonable performance; nothing should go wrong if it is too small. */ limit = Fnext_overlay_change (position); if (XFASTINT (limit) > pos + 50) - XFASTINT (limit) = pos + 50; + XSETFASTINT (limit, pos + 50); endpos = Fnext_single_property_change (position, Qinvisible, Fcurrent_buffer (), limit); if (INTEGERP (endpos)) @@ -2114,10 +2261,10 @@ display_text_line (w, start, vpos, hpos, taboffset) next_invisible = end; if (! NILP (prop)) { - if (pos < point && next_invisible >= point) + if (pos < PT && next_invisible >= PT) { cursor_vpos = vpos; - cursor_hpos = p1 - startp; + cursor_hpos = p1 - leftmargin; } pos = next_invisible; } @@ -2147,8 +2294,8 @@ display_text_line (w, start, vpos, hpos, taboffset) /* Wouldn't you hate to read the next line to someone over the phone? */ - if (pos < point && point < pause) - pause = point; + if (pos < PT && PT < pause) + pause = PT; if (pos < GPT && GPT < pause) pause = GPT; @@ -2156,16 +2303,16 @@ display_text_line (w, start, vpos, hpos, taboffset) } c = *p++; if (c >= 040 && c < 0177 - && (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector)) + && (dp == 0 || !VECTORP (DISP_CHAR_VECTOR (dp, c)))) { - if (p1 >= startp) + if (p1 >= leftmargin) *p1 = MAKE_GLYPH (f, c, current_face); p1++; } else if (c == '\n') { invis = 0; - while (pos < end + while (pos + 1 < end && selective > 0 && indented_beyond_p (pos + 1, selective)) { @@ -2174,10 +2321,10 @@ display_text_line (w, start, vpos, hpos, taboffset) if (FETCH_CHAR (pos - 1) == '\n') pos--; } - if (invis && selective_rlen > 0 && p1 >= startp) + if (invis && selective_rlen > 0 && p1 >= leftmargin) { p1 += selective_rlen; - if (p1 - startp > width) + if (p1 - leftmargin > width) p1 = endp; copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents, (p1 - p1prev), current_face); @@ -2186,8 +2333,12 @@ display_text_line (w, start, vpos, hpos, taboffset) /* Draw the face of the newline character as extending all the way to the end of the frame line. */ if (current_face) - while (p1 < endp) - *p1++ = FAST_MAKE_GLYPH (' ', current_face); + { + if (p1 < leftmargin) + p1 = leftmargin; + while (p1 < endp) + *p1++ = FAST_MAKE_GLYPH (' ', current_face); + } #endif break; } @@ -2195,11 +2346,11 @@ display_text_line (w, start, vpos, hpos, taboffset) { do { - if (p1 >= startp && p1 < endp) + if (p1 >= leftmargin && p1 < endp) *p1 = MAKE_GLYPH (f, ' ', current_face); p1++; } - while ((p1 - startp + taboffset + hscroll - (hscroll > 0)) + while ((p1 - leftmargin + taboffset + hscroll - (hscroll > 0)) % tab_width); } else if (c == Ctl ('M') && selective == -1) @@ -2210,7 +2361,7 @@ display_text_line (w, start, vpos, hpos, taboffset) if (selective_rlen > 0) { p1 += selective_rlen; - if (p1 - startp > width) + if (p1 - leftmargin > width) p1 = endp; copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents, (p1 - p1prev), current_face); @@ -2219,60 +2370,76 @@ display_text_line (w, start, vpos, hpos, taboffset) /* Draw the face of the newline character as extending all the way to the end of the frame line. */ if (current_face) - while (p1 < endp) - *p1++ = FAST_MAKE_GLYPH (' ', current_face); + { + if (p1 < leftmargin) + p1 = leftmargin; + while (p1 < endp) + *p1++ = FAST_MAKE_GLYPH (' ', current_face); + } #endif break; } - else if (dp != 0 && XTYPE (DISP_CHAR_VECTOR (dp, c)) == Lisp_Vector) + else if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) { - p1 = copy_part_of_rope (f, p1, startp, + p1 = copy_part_of_rope (f, p1, leftmargin, XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents, XVECTOR (DISP_CHAR_VECTOR (dp, c))->size, current_face); } else if (c < 0200 && ctl_arrow) { - if (p1 >= startp) - *p1 = fix_glyph (f, (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int + if (p1 >= leftmargin) + *p1 = fix_glyph (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp)) ? XINT (DISP_CTRL_GLYPH (dp)) : '^'), current_face); p1++; - if (p1 >= startp && p1 < endp) + if (p1 >= leftmargin && p1 < endp) *p1 = MAKE_GLYPH (f, c ^ 0100, current_face); p1++; } else { - if (p1 >= startp) - *p1 = fix_glyph (f, (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int + if (p1 >= leftmargin) + *p1 = fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp)) ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'), current_face); p1++; - if (p1 >= startp && p1 < endp) + if (p1 >= leftmargin && p1 < endp) *p1 = MAKE_GLYPH (f, (c >> 6) + '0', current_face); p1++; - if (p1 >= startp && p1 < endp) + if (p1 >= leftmargin && p1 < endp) *p1 = MAKE_GLYPH (f, (7 & (c >> 3)) + '0', current_face); p1++; - if (p1 >= startp && p1 < endp) + if (p1 >= leftmargin && p1 < endp) *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face); p1++; } - /* For all the glyphs occupied by this character, except for the - first, store -1 in charstarts. */ - if (p1 != p1prev) + /* Do nothing here for a char that's entirely off the left edge. */ + if (p1 >= leftmargin) { - int *p2x = &charstart[p1prev - p1start] + 1; - int *p2 = &charstart[p1 - p1start]; - while (p2x != p2) - *p2x++ = -1; + /* For all the glyphs occupied by this character, except for the + first, store -1 in charstarts. */ + if (p1 != p1prev) + { + int *p2x = &charstart[p1prev - p1start]; + int *p2 = &charstart[(p1 < endp ? p1 : endp) - p1start]; + + /* The window's left column should always + contain a character position. + And don't clobber anything to the left of that. */ + if (p1prev < leftmargin) + { + p2x = charstart + (leftmargin - p1start); + *p2x = pos; + } + + /* This loop skips over the char p2x initially points to. */ + while (++p2x < p2) + *p2x = -1; + } } - else - /* If this character took up no space, - erase all mention of it from charstart. */ - charstart[p1 - p1start] = 0; + pos++; } @@ -2287,7 +2454,13 @@ display_text_line (w, start, vpos, hpos, taboffset) /* Store 0 in this charstart line for the positions where there is no character. But do leave what was recorded for the character that ended the line. */ - for (i = p1 - p1start + 1; i < endp - p1start; i++) + /* Add 1 in the endtest to compensate for the fact that ENDP was + made from WIDTH, which is 1 less than the window's actual + internal width. */ + i = p1 - p1start + 1; + if (p1 < leftmargin) + i += leftmargin - p1; + for (; i < endp - p1start + 1; i++) charstart[i] = 0; /* Handle continuation in middle of a character */ @@ -2354,10 +2527,10 @@ display_text_line (w, start, vpos, hpos, taboffset) /* If point is at eol or in invisible text at eol, record its frame location now. */ - if (start <= point && point <= lastpos && cursor_vpos < 0) + if (start <= PT && PT <= lastpos && cursor_vpos < 0) { cursor_vpos = vpos; - cursor_hpos = p1 - startp; + cursor_hpos = p1 - leftmargin; } if (cursor_vpos == vpos) @@ -2393,15 +2566,15 @@ display_text_line (w, start, vpos, hpos, taboffset) /* If hscroll and line not empty, insert truncation-at-left marker */ if (hscroll && lastpos != start) { - *startp = fix_glyph (f, truncator, 0); - if (p1 <= startp) - p1 = startp + 1; + *leftmargin = fix_glyph (f, truncator, 0); + if (p1 <= leftmargin) + p1 = leftmargin + 1; } if (XFASTINT (w->width) + XFASTINT (w->left) != FRAME_WIDTH (f)) { endp++; - if (p1 < startp) p1 = startp; + if (p1 < leftmargin) p1 = leftmargin; while (p1 < endp) *p1++ = SPACEGLYPH; /* Don't draw vertical bars if we're using scroll bars. They're @@ -2409,7 +2582,10 @@ display_text_line (w, start, vpos, hpos, taboffset) them when the scroll bar windows are flickering around to be reconfigured. */ *p1++ = (FRAME_HAS_VERTICAL_SCROLL_BARS (f) - ? ' ' : '|'); + ? ' ' + : (dp && INTEGERP (DISP_BORDER_GLYPH (dp)) + ? DISP_BORDER_GLYPH (dp) + : '|')); } desired_glyphs->used[vpos] = max (desired_glyphs->used[vpos], p1 - desired_glyphs->glyphs[vpos]); @@ -2418,10 +2594,10 @@ display_text_line (w, start, vpos, hpos, taboffset) /* If the start of this line is the overlay arrow-position, then put the arrow string into the display-line. */ - if (XTYPE (Voverlay_arrow_position) == Lisp_Marker + if (MARKERP (Voverlay_arrow_position) && current_buffer == XMARKER (Voverlay_arrow_position)->buffer && start == marker_position (Voverlay_arrow_position) - && XTYPE (Voverlay_arrow_string) == Lisp_String + && STRINGP (Voverlay_arrow_string) && ! overlay_arrow_seen) { unsigned char *p = XSTRING (Voverlay_arrow_string)->data; @@ -2431,11 +2607,31 @@ display_text_line (w, start, vpos, hpos, taboffset) if (len > width) len = width; - for (i = 0; i < len; i++) - startp[i] = p[i]; +#ifdef HAVE_X_WINDOWS + if (!NULL_INTERVAL_P (XSTRING (Voverlay_arrow_string)->intervals)) + { + /* If the arrow string has text props, obey them when displaying. */ + for (i = 0; i < len; i++) + { + int c = p[i]; + Lisp_Object face, ilisp; + int newface; + + XSETFASTINT (ilisp, i); + face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string); + newface = compute_glyph_face_1 (f, face, 0); + leftmargin[i] = FAST_MAKE_GLYPH (c, newface); + } + } + else +#endif /* HAVE_X_WINDOWS */ + { + for (i = 0; i < len; i++) + leftmargin[i] = p[i]; + } /* Bug in SunOS 4.1.1 compiler requires this intermediate variable. */ - arrow_end = (startp - desired_glyphs->glyphs[vpos]) + len; + arrow_end = (leftmargin - desired_glyphs->glyphs[vpos]) + len; if (desired_glyphs->used[vpos] < arrow_end) desired_glyphs->used[vpos] = arrow_end; @@ -2474,7 +2670,7 @@ display_menu_bar (w) if (NILP (string)) break; - XFASTINT (XVECTOR (items)->contents[i + 2]) = hpos; + XSETFASTINT (XVECTOR (items)->contents[i + 2], hpos); if (hpos < maxendcol) hpos = display_string (XWINDOW (FRAME_ROOT_WINDOW (f)), vpos, @@ -2541,11 +2737,6 @@ display_mode_line (w) ptr[i] = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (ptr[i]), 1); } #endif - -#ifdef HAVE_X_WINDOWS - if (w == XWINDOW (f->selected_window)) - x_consider_frame_title (WINDOW_FRAME (w)); -#endif } /* Contribute ELT to the mode line for window W. @@ -2607,8 +2798,11 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) if (this - 1 != last) { register int lim = --this - last + hpos; - hpos = display_string (w, vpos, last, -1, hpos, 0, 1, - hpos, min (lim, maxendcol)); + if (frame_title_ptr) + hpos = store_frame_title (last, hpos, min (lim, maxendcol)); + else + hpos = display_string (w, vpos, last, -1, hpos, 0, 1, + hpos, min (lim, maxendcol)); } else /* c == '%' */ { @@ -2633,11 +2827,15 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) spec_width, maxendcol, Vglobal_mode_string); else if (c != 0) - hpos = display_string (w, vpos, - decode_mode_spec (w, c, - maxendcol - hpos), - -1, - hpos, 0, 1, spec_width, maxendcol); + { + char *spec = decode_mode_spec (w, c, maxendcol - hpos); + if (frame_title_ptr) + hpos = store_frame_title (spec, spec_width, maxendcol); + else + hpos = display_string (w, vpos, spec, -1, + hpos, 0, 1, + spec_width, maxendcol); + } } } } @@ -2656,10 +2854,16 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) tem = Fsymbol_value (elt); /* If value is a string, output that string literally: don't check for % within it. */ - if (XTYPE (tem) == Lisp_String) - hpos = display_string (w, vpos, XSTRING (tem)->data, - XSTRING (tem)->size, - hpos, 0, 1, minendcol, maxendcol); + if (STRINGP (tem)) + { + if (frame_title_ptr) + hpos = store_frame_title (XSTRING (tem)->data, + minendcol, maxendcol); + else + hpos = display_string (w, vpos, XSTRING (tem)->data, + XSTRING (tem)->size, + hpos, 0, 1, minendcol, maxendcol); + } /* Give up right away for nil or t. */ else if (!EQ (tem, elt)) { elt = tem; goto tail_recurse; } @@ -2680,11 +2884,11 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) If first element is a symbol, process the cadr or caddr recursively according to whether the symbol's value is non-nil or nil. */ car = XCONS (elt)->car; - if (XTYPE (car) == Lisp_Symbol) + if (SYMBOLP (car)) { tem = Fboundp (car); elt = XCONS (elt)->cdr; - if (XTYPE (elt) != Lisp_Cons) + if (!CONSP (elt)) goto invalid; /* elt is now the cdr, and we know it is a cons cell. Use its car if CAR has a non-nil value. */ @@ -2700,12 +2904,12 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) elt = XCONS (elt)->cdr; if (NILP (elt)) break; - else if (XTYPE (elt) != Lisp_Cons) + else if (!CONSP (elt)) goto invalid; elt = XCONS (elt)->car; goto tail_recurse; } - else if (XTYPE (car) == Lisp_Int) + else if (INTEGERP (car)) { register int lim = XINT (car); elt = XCONS (elt)->cdr; @@ -2730,11 +2934,11 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) } goto tail_recurse; } - else if (XTYPE (car) == Lisp_String || XTYPE (car) == Lisp_Cons) + else if (STRINGP (car) || CONSP (car)) { register int limit = 50; /* LIMIT is to protect against circular lists. */ - while (XTYPE (elt) == Lisp_Cons && --limit > 0 + while (CONSP (elt) && --limit > 0 && hpos < maxendcol) { hpos = display_mode_element (w, vpos, hpos, depth, @@ -2748,13 +2952,19 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) default: invalid: - return (display_string (w, vpos, "*invalid*", -1, hpos, 0, 1, - minendcol, maxendcol)); + if (frame_title_ptr) + hpos = store_frame_title ("*invalid*", minendcol, maxendcol); + else + hpos = display_string (w, vpos, "*invalid*", -1, hpos, 0, 1, + minendcol, maxendcol); + return hpos; } - end: if (minendcol > hpos) - hpos = display_string (w, vpos, "", 0, hpos, 0, 1, minendcol, maxendcol); + if (frame_title_ptr) + hpos = store_frame_title ("", minendcol, maxendcol); + else + hpos = display_string (w, vpos, "", 0, hpos, 0, 1, minendcol, maxendcol); return hpos; } @@ -2772,6 +2982,7 @@ decode_mode_spec (w, c, maxwidth) Lisp_Object obj; FRAME_PTR f = XFRAME (WINDOW_FRAME (w)); char *decode_mode_spec_buf = (char *) FRAME_TEMP_GLYPHS (f)->total_contents; + struct buffer *b = XBUFFER (w->buffer); obj = Qnil; if (maxwidth > FRAME_WIDTH (f)) @@ -2780,7 +2991,7 @@ decode_mode_spec (w, c, maxwidth) switch (c) { case 'b': - obj = current_buffer->name; + obj = b->name; #if 0 if (maxwidth >= 3 && XSTRING (obj)->size > maxwidth) { @@ -2793,11 +3004,11 @@ decode_mode_spec (w, c, maxwidth) break; case 'f': - obj = current_buffer->filename; + obj = b->filename; #if 0 if (NILP (obj)) return "[none]"; - else if (XTYPE (obj) == Lisp_String && XSTRING (obj)->size > maxwidth) + else if (STRINGP (obj) && XSTRING (obj)->size > maxwidth) { bcopy ("...", decode_mode_spec_buf, 3); bcopy (XSTRING (obj)->data + XSTRING (obj)->size - maxwidth + 3, @@ -2821,7 +3032,7 @@ decode_mode_spec (w, c, maxwidth) return "??"; /* If the buffer is very big, don't waste time. */ - if (ZV - BEGV > line_number_display_limit) + if (BUF_ZV (b) - BUF_BEGV (b) > line_number_display_limit) { w->base_line_pos = Qnil; w->base_line_number = Qnil; @@ -2838,7 +3049,7 @@ decode_mode_spec (w, c, maxwidth) else { line = 1; - linepos = BEGV; + linepos = BUF_BEGV (b); } /* Count lines from base line to window start position. */ @@ -2850,15 +3061,15 @@ decode_mode_spec (w, c, maxwidth) or too far away, or if we did not have one. "Too close" means it's plausible a scroll-down would go back past it. */ - if (startpos == BEGV) + if (startpos == BUF_BEGV (b)) { - XFASTINT (w->base_line_number) = topline; - XFASTINT (w->base_line_pos) = BEGV; + XSETFASTINT (w->base_line_number, topline); + XSETFASTINT (w->base_line_pos, BUF_BEGV (b)); } else if (nlines < height + 25 || nlines > height * 3 + 50 - || linepos == BEGV) + || linepos == BUF_BEGV (b)) { - int limit = BEGV; + int limit = BUF_BEGV (b); int position; int distance = (height * 2 + 30) * 200; @@ -2878,8 +3089,8 @@ decode_mode_spec (w, c, maxwidth) return "??"; } - XFASTINT (w->base_line_number) = topline - nlines; - XFASTINT (w->base_line_pos) = position; + XSETFASTINT (w->base_line_number, topline - nlines); + XSETFASTINT (w->base_line_pos, position); } /* Now count lines from the start pos to point. */ @@ -2895,29 +3106,38 @@ decode_mode_spec (w, c, maxwidth) break; case 'm': - obj = current_buffer->mode_name; + obj = b->mode_name; break; case 'n': - if (BEGV > BEG || ZV < Z) + if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b)) return " Narrow"; break; case '*': - if (!NILP (current_buffer->read_only)) + if (!NILP (b->read_only)) return "%"; - if (MODIFF > current_buffer->save_modified) + if (BUF_MODIFF (b) > b->save_modified) return "*"; return "-"; case '+': - if (MODIFF > current_buffer->save_modified) + /* This differs from %* only for a modified read-only buffer. */ + if (BUF_MODIFF (b) > b->save_modified) + return "*"; + if (!NILP (b->read_only)) + return "%"; + return "-"; + + case '&': + /* This differs from %* in ignoring read-only-ness. */ + if (BUF_MODIFF (b) > b->save_modified) return "*"; return "-"; case 's': /* status of process */ - obj = Fget_buffer_process (Fcurrent_buffer ()); + obj = Fget_buffer_process (w->buffer); if (NILP (obj)) return "no process"; #ifdef subprocesses @@ -2926,32 +3146,29 @@ decode_mode_spec (w, c, maxwidth) break; case 't': /* indicate TEXT or BINARY */ -#ifdef MSDOS - decode_mode_spec_buf[0] - = NILP (current_buffer->buffer_file_type) ? "T" : "B"; - decode_mode_spec_buf[1] = 0; - return decode_mode_spec_buf; -#else /* not MSDOS */ +#ifdef MODE_LINE_BINARY_TEXT + return MODE_LINE_BINARY_TEXT (b); +#else return "T"; -#endif /* not MSDOS */ +#endif case 'p': { int pos = marker_position (w->start); - int total = ZV - BEGV; + int total = BUF_ZV (b) - BUF_BEGV (b); - if (XFASTINT (w->window_end_pos) <= Z - ZV) + if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b)) { - if (pos <= BEGV) + if (pos <= BUF_BEGV (b)) return "All"; else return "Bottom"; } - else if (pos <= BEGV) + else if (pos <= BUF_BEGV (b)) return "Top"; else { - total = ((pos - BEGV) * 100 + total - 1) / total; + total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total; /* We can't normally display a 3-digit number, so get us a 2-digit number that is close. */ if (total == 100) @@ -2965,24 +3182,24 @@ decode_mode_spec (w, c, maxwidth) case 'P': { int toppos = marker_position (w->start); - int botpos = Z - XFASTINT (w->window_end_pos); - int total = ZV - BEGV; + int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos); + int total = BUF_ZV (b) - BUF_BEGV (b); - if (botpos >= ZV) + if (botpos >= BUF_ZV (b)) { - if (toppos <= BEGV) + if (toppos <= BUF_BEGV (b)) return "All"; else return "Bottom"; } else { - total = ((botpos - BEGV) * 100 + total - 1) / total; + total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total; /* We can't normally display a 3-digit number, so get us a 2-digit number that is close. */ if (total == 100) total = 99; - if (toppos <= BEGV) + if (toppos <= BUF_BEGV (b)) sprintf (decode_mode_spec_buf, "Top%2d%%", total); else sprintf (decode_mode_spec_buf, "%2d%%", total); @@ -3020,7 +3237,7 @@ decode_mode_spec (w, c, maxwidth) *p = 0; return decode_mode_spec_buf; } - + case '-': { register char *p; @@ -3037,12 +3254,113 @@ decode_mode_spec (w, c, maxwidth) return decode_mode_spec_buf; } } - - if (XTYPE (obj) == Lisp_String) + + if (STRINGP (obj)) return (char *) XSTRING (obj)->data; else return ""; } + +/* Search for COUNT instances of a line boundary, which means either a + newline or (if selective display enabled) a carriage return. + Start at START. If COUNT is negative, search backwards. + + If we find COUNT instances, set *SHORTAGE to zero, and return the + position after the COUNTth match. Note that for reverse motion + this is not the same as the usual convention for Emacs motion commands. + + If we don't find COUNT instances before reaching the end of the + buffer (or the beginning, if scanning backwards), set *SHORTAGE to + the number of line boundaries left unfound, and return the end of the + buffer we bumped up against. */ + +static int +display_scan_buffer (start, count, shortage) + int *shortage, start; + register int count; +{ + int limit = ((count > 0) ? ZV - 1 : BEGV); + int direction = ((count > 0) ? 1 : -1); + + register unsigned char *cursor; + unsigned char *base; + + register int ceiling; + register unsigned char *ceiling_addr; + + /* If we are not in selective display mode, + check only for newlines. */ + if (! (!NILP (current_buffer->selective_display) + && !INTEGERP (current_buffer->selective_display))) + return scan_buffer ('\n', start, 0, count, shortage, 0); + + /* The code that follows is like scan_buffer + but checks for either newline or carriage return. */ + + if (shortage != 0) + *shortage = 0; + + if (count > 0) + while (start != limit + 1) + { + ceiling = BUFFER_CEILING_OF (start); + ceiling = min (limit, ceiling); + ceiling_addr = &FETCH_CHAR (ceiling) + 1; + base = (cursor = &FETCH_CHAR (start)); + while (1) + { + while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) + ; + if (cursor != ceiling_addr) + { + if (--count == 0) + { + immediate_quit = 0; + return (start + cursor - base + 1); + } + else + if (++cursor == ceiling_addr) + break; + } + else + break; + } + start += cursor - base; + } + else + { + start--; /* first character we scan */ + while (start > limit - 1) + { /* we WILL scan under start */ + ceiling = BUFFER_FLOOR_OF (start); + ceiling = max (limit, ceiling); + ceiling_addr = &FETCH_CHAR (ceiling) - 1; + base = (cursor = &FETCH_CHAR (start)); + cursor++; + while (1) + { + while (--cursor != ceiling_addr + && *cursor != '\n' && *cursor != 015) + ; + if (cursor != ceiling_addr) + { + if (++count == 0) + { + immediate_quit = 0; + return (start + cursor - base + 1); + } + } + else + break; + } + start += cursor - base; + } + } + + if (shortage != 0) + *shortage = count * direction; + return (start + ((direction == 1 ? 0 : 1))); +} /* Count up to N lines starting from FROM. But don't go beyond LIMIT. @@ -3063,7 +3381,7 @@ display_count_lines (from, limit, n, pos_ptr) else ZV = limit; - *pos_ptr = scan_buffer ('\n', from, n, &shortage, 0); + *pos_ptr = display_scan_buffer (from, n, &shortage); ZV = oldzv; BEGV = oldbegv; @@ -3123,7 +3441,7 @@ display_string (w, vpos, string, length, hpos, truncate, register struct Lisp_Vector *dp = 0; int i; - if (XTYPE (Vstandard_display_table) == Lisp_Vector + if (VECTORP (Vstandard_display_table) && XVECTOR (Vstandard_display_table)->size == DISP_TABLE_SIZE) dp = XVECTOR (Vstandard_display_table); @@ -3142,7 +3460,7 @@ display_string (w, vpos, string, length, hpos, truncate, { int i; - for (i = 0; i < VERTICAL_SCROLL_BAR_WIDTH; i++) + for (i = 0; i < FRAME_SCROLL_BAR_COLS (f); i++) *end-- = ' '; } else @@ -3155,7 +3473,7 @@ display_string (w, vpos, string, length, hpos, truncate, end = desired_glyphs->glyphs[vpos] + maxcol; /* Store 0 in charstart for these columns. */ - for (i = hpos; i < end - p1start + hpos; i++) + for (i = (hpos >= 0 ? hpos : 0); i < end - p1start + hpos; i++) desired_glyphs->charstarts[vpos][i] = 0; if (maxcol >= 0 && mincol > maxcol) @@ -3174,7 +3492,7 @@ display_string (w, vpos, string, length, hpos, truncate, break; if (c >= 040 && c < 0177 - && (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector)) + && (dp == 0 || !VECTORP (DISP_CHAR_VECTOR (dp, c)))) { if (p1 >= start) *p1 = c; @@ -3190,7 +3508,7 @@ display_string (w, vpos, string, length, hpos, truncate, } while ((p1 - start + hscroll - (hscroll > 0)) % tab_width); } - else if (dp != 0 && XTYPE (DISP_CHAR_VECTOR (dp, c)) == Lisp_Vector) + else if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) { p1 = copy_part_of_rope (f, p1, start, XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents, @@ -3200,7 +3518,7 @@ display_string (w, vpos, string, length, hpos, truncate, else if (c < 0200 && ! NILP (buffer_defaults.ctl_arrow)) { if (p1 >= start) - *p1 = fix_glyph (f, (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int + *p1 = fix_glyph (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp)) ? XINT (DISP_CTRL_GLYPH (dp)) : '^'), 0); p1++; @@ -3211,7 +3529,7 @@ display_string (w, vpos, string, length, hpos, truncate, else { if (p1 >= start) - *p1 = fix_glyph (f, (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int + *p1 = fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp)) ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'), 0); p1++; @@ -3253,6 +3571,9 @@ display_string (w, vpos, string, length, hpos, truncate, void syms_of_xdisp () { + staticpro (&Qmenu_bar_update_hook); + Qmenu_bar_update_hook = intern ("menu-bar-update-hook"); + staticpro (&last_arrow_position); staticpro (&last_arrow_string); last_arrow_position = Qnil; @@ -3295,6 +3616,33 @@ If this is zero, point is always centered after it moves off frame."); DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows, "*Non-nil means highlight region even in nonselected windows."); highlight_nonselected_windows = 1; + + DEFVAR_BOOL ("multiple-frames", &multiple_frames, + "Non-nil means more than one frame is in use, not counting minibuffer frames.\n\ +Not guaranteed to be accurate except while parsing frame-title-format."); + + DEFVAR_LISP ("frame-title-format", &Vframe_title_format, + "Template for displaying the titlebar of visible frames.\n\ +\(Assuming the window manager supports this feature.)\n\ +This variable has the same structure as `mode-line-format' (which see),\n\ +and is used only on frames for which no explicit name has been set\n\ +\(see `modify-frame-parameters')."); + DEFVAR_LISP ("icon-title-format", &Vicon_title_format, + "Template for displaying the titlebar of an iconified frame.\n\ +\(Assuming the window manager supports this feature.)\n\ +This variable has the same structure as `mode-line-format' (which see),\n\ +and is used only on frames for which no explicit name has been set\n\ +\(see `modify-frame-parameters')."); + Vicon_title_format + = Vframe_title_format + = Fcons (intern ("multiple-frames"), + Fcons (build_string ("%b"), + Fcons (Fcons (build_string (""), + Fcons (intern ("invocation-name"), + Fcons (build_string ("@"), + Fcons (intern ("system-name"), + Qnil)))), + Qnil))); } /* initialize the window system */ @@ -3317,12 +3665,12 @@ init_xdisp () if (!noninteractive) { FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (root_window))); - XFASTINT (XWINDOW (root_window)->top) = 0; + XSETFASTINT (XWINDOW (root_window)->top, 0); set_window_height (root_window, FRAME_HEIGHT (f) - 1, 0); - XFASTINT (mini_w->top) = FRAME_HEIGHT (f) - 1; + XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1); set_window_height (minibuf_window, 1, 0); - XFASTINT (XWINDOW (root_window)->width) = FRAME_WIDTH (f); - XFASTINT (mini_w->width) = FRAME_WIDTH (f); + XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f)); + XSETFASTINT (mini_w->width, FRAME_WIDTH (f)); } }