X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fredisplay.c;h=7436b6225464dcd6adaee066b10720df4c65f737;hb=e4092ce710193e23052612e97aa7815e547f6461;hp=7e29d59caa0acfd787926fdbbcf7b48efc3bf2ef;hpb=46f51e794ddb493a8a76ec2f3be00b41e3b0be22;p=chise%2Fxemacs-chise.git diff --git a/src/redisplay.c b/src/redisplay.c index 7e29d59..7436b62 100644 --- a/src/redisplay.c +++ b/src/redisplay.c @@ -40,7 +40,6 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" -#include #include "buffer.h" #include "commands.h" @@ -64,11 +63,10 @@ Boston, MA 02111-1307, USA. */ #include "file-coding.h" #endif +#include "sysfile.h" + #ifdef HAVE_TTY #include "console-tty.h" -#ifdef HAVE_UNISTD_H -#include /* for isatty() */ -#endif #endif /* HAVE_TTY */ /* Note: We have to be careful throughout this code to properly handle @@ -87,16 +85,10 @@ Boston, MA 02111-1307, USA. */ #define LEFT_GLYPHS 2 #define RIGHT_GLYPHS 3 -/* Set the vertical clip to 0 if we are currently updating the line - start cache. Otherwise for buffers of line height 1 it may fail to - be able to work properly because regenerate_window will not layout - a single line. */ #define VERTICAL_CLIP(w, display) \ - (updating_line_start_cache \ - ? 0 \ - : ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \ + ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \ ? INT_MAX \ - : vertical_clip)) + : vertical_clip) /* The following structures are completely private to redisplay.c so we put them here instead of in a header file, for modularity. */ @@ -246,18 +238,13 @@ typedef struct } prop_block_dynarr; -static void generate_formatted_string_db (Lisp_Object format_str, - Lisp_Object result_str, - struct window *w, - struct display_line *dl, - struct display_block *db, - face_index findex, int min_pixpos, - int max_pixpos, int type); static Charcount generate_fstring_runes (struct window *w, pos_data *data, Charcount pos, Charcount min_pos, Charcount max_pos, Lisp_Object elt, int depth, int max_pixsize, - face_index findex, int type); + face_index findex, int type, + Charcount *offset, + Lisp_Object cur_ext); static prop_block_dynarr *add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type, int allow_cursor, @@ -300,10 +287,6 @@ static int max_preempts; isn't any reason we need more than a single set. */ display_line_dynarr *cmotion_display_lines; -/* Used by generate_formatted_string. Global because they get used so - much that the dynamic allocation time adds up. */ -static Emchar_dynarr *formatted_string_emchar_dynarr; -static struct display_line formatted_string_display_line; /* We store the extents that we need to generate in a Dynarr and then frob them all on at the end of generating the string. We do it this way rather than adding them as we generate the string because @@ -337,9 +320,6 @@ int vertical_clip; /* Minimum visible pixel width of clipped glyphs at right margin. */ int horizontal_clip; -/* Set if currently inside update_line_start_cache. */ -static int updating_line_start_cache; - /* Nonzero means reading single-character input with prompt so put cursor on minibuffer after the prompt. */ int cursor_in_echo_area; @@ -373,8 +353,7 @@ int frame_changed; int glyphs_changed; int glyphs_changed_set; -/* non-zero if any displayed subwindow is in need of updating - somewhere. */ +/* non-zero if any subwindow has been deleted. */ int subwindows_changed; int subwindows_changed_set; @@ -428,10 +407,9 @@ int windows_structure_changed; Lisp_Object Vbar_cursor; Lisp_Object Qbar_cursor; - -int visible_bell; /* If true and the terminal will support it - then the frame will flash instead of - beeping when an error occurs */ +Lisp_Object Vvisible_bell; /* If true and the terminal will support it + then the frame will flash instead of + beeping when an error occurs */ /* Nonzero means no need to redraw the entire frame on resuming a suspended Emacs. This is useful on terminals with multiple pages, @@ -461,6 +439,9 @@ Lisp_Object Vwindow_size_change_functions; Lisp_Object Vwindow_scroll_functions; Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions; +Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook; + + #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about this more. */ #ifndef INHIBIT_REDISPLAY_HOOKS @@ -481,8 +462,9 @@ Lisp_Object Vtext_cursor_visible_p; int column_number_start_at_one; -#define WINDOW_SCROLLED(w) \ -(w->hscroll > 0 || w->left_xoffset) +Lisp_Object Qtop_bottom; + +#define WINDOW_SCROLLED(w) ((w)->hscroll > 0 || (w)->left_xoffset) /***************************************************************************/ @@ -492,13 +474,13 @@ int column_number_start_at_one; /***************************************************************************/ static int -redisplay_text_width_emchar_string (struct window *w, int findex, - Emchar *str, Charcount len) +redisplay_text_width_charc_string (struct window *w, int findex, + Charc *str, Charcount len) { - unsigned char charsets[NUM_LEADING_BYTES]; + Charset_ID charsets[NUM_LEADING_BYTES]; Lisp_Object window; - find_charsets_in_emchar_string (charsets, str, len); + find_charsets_in_charc_string (charsets, str, len); XSETWINDOW (window, w); ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window, charsets); @@ -507,24 +489,24 @@ redisplay_text_width_emchar_string (struct window *w, int findex, WINDOW_FACE_CACHEL (w, findex), str, len)); } -static Emchar_dynarr *rtw_emchar_dynarr; +static Charc_dynarr *rtw_charc_dynarr; int redisplay_text_width_string (struct window *w, int findex, Bufbyte *nonreloc, Lisp_Object reloc, Bytecount offset, Bytecount len) { - if (!rtw_emchar_dynarr) - rtw_emchar_dynarr = Dynarr_new (Emchar); - Dynarr_reset (rtw_emchar_dynarr); + if (!rtw_charc_dynarr) + rtw_charc_dynarr = Dynarr_new (Charc); + Dynarr_reset (rtw_charc_dynarr); fixup_internal_substring (nonreloc, reloc, offset, &len); if (STRINGP (reloc)) nonreloc = XSTRING_DATA (reloc); - convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr); - return redisplay_text_width_emchar_string - (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0), - Dynarr_length (rtw_emchar_dynarr)); + convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr); + return redisplay_text_width_charc_string + (w, findex, Dynarr_atp (rtw_charc_dynarr, 0), + Dynarr_length (rtw_charc_dynarr)); } int @@ -532,26 +514,26 @@ redisplay_frame_text_width_string (struct frame *f, Lisp_Object face, Bufbyte *nonreloc, Lisp_Object reloc, Bytecount offset, Bytecount len) { - unsigned char charsets[NUM_LEADING_BYTES]; + Charset_ID charsets[NUM_LEADING_BYTES]; Lisp_Object frame; struct face_cachel cachel; - if (!rtw_emchar_dynarr) - rtw_emchar_dynarr = Dynarr_new (Emchar); - Dynarr_reset (rtw_emchar_dynarr); + if (!rtw_charc_dynarr) + rtw_charc_dynarr = Dynarr_new (Charc); + Dynarr_reset (rtw_charc_dynarr); fixup_internal_substring (nonreloc, reloc, offset, &len); if (STRINGP (reloc)) nonreloc = XSTRING_DATA (reloc); - convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr); + convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr); find_charsets_in_bufbyte_string (charsets, nonreloc, len); reset_face_cachel (&cachel); cachel.face = face; XSETFRAME (frame, f); ensure_face_cachel_complete (&cachel, frame, charsets); return DEVMETH (XDEVICE (FRAME_DEVICE (f)), - text_width, (f, &cachel, Dynarr_atp (rtw_emchar_dynarr, 0), - Dynarr_length (rtw_emchar_dynarr))); + text_width, (f, &cachel, Dynarr_atp (rtw_charc_dynarr, 0), + Dynarr_length (rtw_charc_dynarr))); } /* Return the display block from DL of the given TYPE. A display line @@ -813,7 +795,7 @@ add_hscroll_rune (pos_data *data) gb.glyph = Vhscroll_glyph; { int oldpixpos = data->pixpos; - retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1, + retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, GLYPH_CACHEL (XWINDOW (data->window), HSCROLL_GLYPH_INDEX)); data->hscroll_glyph_width_adjust = @@ -837,6 +819,7 @@ add_emchar_rune (pos_data *data) { struct rune rb, *crb; int width, local; + Charc char_glyph; if (data->start_col) { @@ -853,13 +836,17 @@ add_emchar_rune (pos_data *data) if (data->ch == '\n') { + char_glyph = ASCII_TO_CHARC ('\n'); data->font_is_bogus = 0; /* Cheesy end-of-line pseudo-character. */ width = data->blank_width; } else { - Lisp_Object charset = CHAR_CHARSET (data->ch); + Lisp_Object charset; + + char_glyph = CHAR_TO_CHARC (data->ch); + charset = CHARC_CHARSET (char_glyph); if (!EQ (charset, data->last_charset) || data->findex != data->last_findex) { @@ -869,7 +856,7 @@ add_emchar_rune (pos_data *data) Lisp_Object font_instance = ensure_face_cachel_contains_charset (cachel, data->window, charset); - struct Lisp_Font_Instance *fi; + Lisp_Font_Instance *fi; if (EQ (font_instance, Vthe_null_font_instance)) { @@ -895,9 +882,9 @@ add_emchar_rune (pos_data *data) if (width < 0) { /* bummer. Proportional fonts. */ - width = redisplay_text_width_emchar_string (XWINDOW (data->window), - data->findex, - &data->ch, 1); + width = redisplay_text_width_charc_string (XWINDOW (data->window), + data->findex, + &char_glyph, 1); } } @@ -928,17 +915,18 @@ add_emchar_rune (pos_data *data) data->bi_bufpos); else crb->bufpos = - bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos); + bytecount_to_charcount (XSTRING_DATA (data->string), + data->bi_bufpos); } else if (data->is_modeline) crb->bufpos = data->modeline_charpos; else - /* fuckme if this shouldn't be an abort. */ - /* abort (); fuckme harder, this abort gets tripped quite often, - in propagation and whatnot. #### fixme */ + /* Text but not in buffer */ crb->bufpos = 0; crb->type = RUNE_CHAR; - crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch; + crb->object.cglyph = data->font_is_bogus + ? ASCII_TO_CHARC ('~') + : char_glyph; crb->endpos = 0; if (data->cursor_type == CURSOR_ON) @@ -1330,6 +1318,7 @@ add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry) case '%': dst += set_charptr_emchar (dst, '%'); break; + /* #### unimplemented */ } } } @@ -1351,7 +1340,7 @@ add_disp_table_entry_runes (pos_data *data, Lisp_Object entry) prop_block_dynarr *prop = NULL; if (VECTORP (entry)) { - struct Lisp_Vector *de = XVECTOR (entry); + Lisp_Vector *de = XVECTOR (entry); EMACS_INT len = vector_length (de); int elt; @@ -1534,12 +1523,25 @@ add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type, { struct window *w = XWINDOW (data->window); + /* If window faces changed, and glyph instance is text, then + glyph sizes might have changed too */ + invalidate_glyph_geometry_maybe (gb->glyph, w); + + /* This makes sure the glyph is in the cachels. + + #### We do this to make sure the glyph is in the glyph cachels, + so that the dirty flag can be reset after redisplay has + finished. We should do this some other way, maybe by iterating + over the window cache of subwindows. */ + get_glyph_cachel_index (w, gb->glyph); + /* A nil extent indicates a special glyph (ex. truncator). */ if (NILP (gb->extent) || (pos_type == BEGIN_GLYPHS && extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT) || (pos_type == END_GLYPHS && - extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)) + extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT) + || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS) { struct rune rb; int width; @@ -1547,11 +1549,13 @@ add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type, int ascent, descent; Lisp_Object baseline; Lisp_Object face; + Lisp_Object instance; + face_index findex; if (cachel) width = cachel->width; else - width = glyph_width (gb->glyph, Qnil, data->findex, data->window); + width = glyph_width (gb->glyph, data->window); if (!width) return NULL; @@ -1614,9 +1618,8 @@ add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type, } else { - ascent = glyph_ascent (gb->glyph, Qnil, data->findex, data->window); - descent = glyph_descent (gb->glyph, Qnil, data->findex, - data->window); + ascent = glyph_ascent (gb->glyph, data->window); + descent = glyph_descent (gb->glyph, data->window); } baseline = glyph_baseline (gb->glyph, data->window); @@ -1659,10 +1662,32 @@ add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type, face = glyph_face (gb->glyph, data->window); if (NILP (face)) - rb.findex = data->findex; + findex = data->findex; else - rb.findex = get_builtin_face_cache_index (w, face); + findex = get_builtin_face_cache_index (w, face); + + instance = glyph_image_instance (gb->glyph, data->window, + ERROR_ME_NOT, 1); + if (TEXT_IMAGE_INSTANCEP (instance)) + { + Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance); + face_index orig_findex = data->findex; + Bytind orig_bufpos = data->bi_bufpos; + Bytind orig_start_col_enabled = data->bi_start_col_enabled; + + data->findex = findex; + data->bi_start_col_enabled = 0; + if (!allow_cursor) + data->bi_bufpos = 0; + add_bufbyte_string_runes (data, XSTRING_DATA (string), + XSTRING_LENGTH (string), 0); + data->findex = orig_findex; + data->bi_bufpos = orig_bufpos; + data->bi_start_col_enabled = orig_start_col_enabled; + return NULL; + } + rb.findex = findex; rb.xpos = data->pixpos; rb.width = width; rb.bufpos = 0; /* glyphs are never "at" anywhere */ @@ -1673,13 +1698,6 @@ add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type, else rb.endpos = 0; rb.type = RUNE_DGLYPH; - /* #### Ben sez: this is way bogus if the glyph is a string. - You should not make the output routines have to cope with - this. The string could contain Mule characters, or non- - printable characters, or characters to be passed through - the display table, or non-character objects (when this gets - implemented), etc. Instead, this routine here should parse - the string into a series of runes. */ rb.object.dglyph.glyph = gb->glyph; rb.object.dglyph.extent = gb->extent; rb.object.dglyph.xoffset = xoffset; @@ -1882,6 +1900,7 @@ create_text_block (struct window *w, struct display_line *dl, dl->used_prop_data = 0; dl->num_chars = 0; + dl->line_continuation = 0; xzero (data); data.ef = extent_fragment_new (w->buffer, f); @@ -2472,11 +2491,12 @@ done: /* data.bi_bufpos is already at the start of the next line. */ + dl->line_continuation = 1; gb.glyph = Vcontinuation_glyph; cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); } - add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1, cachel); + add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b) && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n') @@ -2518,7 +2538,7 @@ done: { struct rune *rb = Dynarr_atp (db->runes, elt); - if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ') + if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' ')) || rb->type == RUNE_BLANK) { dl->bounds.left_white += rb->width; @@ -2538,8 +2558,7 @@ done: { struct rune *rb = Dynarr_atp (db->runes, elt); - if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100 - && isspace (rb->object.chr.ch)) + if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph)) && !rb->type == RUNE_BLANK) { dl->bounds.right_white = rb->xpos + rb->width; @@ -2724,8 +2743,26 @@ add_margin_runes (struct display_line *dl, struct display_block *db, int start, ? dl->left_glyphs : dl->right_glyphs); int elt, end; - int xpos = start; int reverse; + struct window *w = XWINDOW (window); + struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); + pos_data data; + + xzero (data); + data.d = d; + data.window = window; + data.db = db; + data.dl = dl; + data.pixpos = start; + data.cursor_type = NO_CURSOR; + data.cursor_x = -1; + data.last_charset = Qunbound; + data.last_findex = DEFAULT_INDEX; + data.result_str = Qnil; + data.string = Qnil; + data.new_ascent = dl->ascent; + data.new_descent = dl->descent; if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS) || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS)) @@ -2754,79 +2791,31 @@ add_margin_runes (struct display_line *dl, struct display_block *db, int start, || (side == RIGHT_GLYPHS && extent_end_glyph_layout (XEXTENT (gb->extent)) == layout))) { - struct rune rb; - - rb.width = gb->width; - rb.findex = gb->findex; - rb.xpos = xpos; - rb.bufpos = -1; - rb.endpos = 0; - rb.type = RUNE_DGLYPH; - rb.object.dglyph.glyph = gb->glyph; - rb.object.dglyph.extent = gb->extent; - rb.object.dglyph.xoffset = 0; - rb.cursor_type = CURSOR_OFF; - - Dynarr_add (db->runes, rb); - xpos += rb.width; + data.findex = gb->findex; + data.max_pixpos = data.pixpos + gb->width; + add_glyph_rune (&data, gb, side, 0, NULL); count--; gb->active = 0; - - if (glyph_contrib_p (gb->glyph, window)) - { - unsigned short ascent, descent; - Lisp_Object baseline = glyph_baseline (gb->glyph, window); - - ascent = glyph_ascent (gb->glyph, Qnil, gb->findex, window); - descent = glyph_descent (gb->glyph, Qnil, gb->findex, window); - - /* A pixmap that has not had a baseline explicitly set. - We use the existing ascent / descent ratio of the - line. */ - if (NILP (baseline)) - { - int gheight = ascent + descent; - int line_height = dl->ascent + dl->descent; - int pix_ascent, pix_descent; - - pix_descent = (int) (gheight * dl->descent) / line_height; - pix_ascent = gheight - pix_descent; - - dl->ascent = max ((int) dl->ascent, pix_ascent); - dl->descent = max ((int) dl->descent, pix_descent); - } - - /* A string so determine contribution normally. */ - else if (EQ (baseline, Qt)) - { - dl->ascent = max (dl->ascent, ascent); - dl->descent = max (dl->descent, descent); - } - - /* A pixmap with an explicitly set baseline. We determine the - contribution here. */ - else if (INTP (baseline)) - { - int height = ascent + descent; - int pix_ascent, pix_descent; - - pix_ascent = height * XINT (baseline) / 100; - pix_descent = height - pix_ascent; - - dl->ascent = max ((int) dl->ascent, pix_ascent); - dl->descent = max ((int) dl->descent, pix_descent); - } - - /* Otherwise something is screwed up. */ - else - abort (); - } } (reverse ? elt-- : elt++); } - return xpos; + if (data.max_pixmap_height) + { + int height = data.new_ascent + data.new_descent; + int pix_ascent, pix_descent; + + pix_descent = data.max_pixmap_height * data.new_descent / height; + pix_ascent = data.max_pixmap_height - pix_descent; + data.new_ascent = max (data.new_ascent, pix_ascent); + data.new_descent = max (data.new_descent, pix_descent); + } + + dl->ascent = data.new_ascent; + dl->descent = data.new_descent; + + return data.pixpos; } /* Add a blank to a margin display block. */ @@ -2892,7 +2881,7 @@ create_left_glyph_block (struct window *w, struct display_line *dl, { int width; - width = glyph_width (gb->glyph, Qnil, gb->findex, window); + width = glyph_width (gb->glyph, window); if (white_in_start - width >= left_in_end) { @@ -2943,7 +2932,7 @@ create_left_glyph_block (struct window *w, struct display_line *dl, if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN) { - gb->width = glyph_width (gb->glyph, Qnil, gb->findex, window); + gb->width = glyph_width (gb->glyph, window); used_in += gb->width; Dynarr_add (ib, *gb); } @@ -3012,7 +3001,7 @@ create_left_glyph_block (struct window *w, struct display_line *dl, if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN) { - int width = glyph_width (gb->glyph, Qnil, gb->findex, window); + int width = glyph_width (gb->glyph, window); if (used_out) { @@ -3054,7 +3043,7 @@ create_left_glyph_block (struct window *w, struct display_line *dl, if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN) { - int width = glyph_width (gb->glyph, Qnil, gb->findex, window); + int width = glyph_width (gb->glyph, window); if (out_end + width <= in_out_start) { @@ -3211,7 +3200,7 @@ create_right_glyph_block (struct window *w, struct display_line *dl) if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE) { - int width = glyph_width (gb->glyph, Qnil, gb->findex, window); + int width = glyph_width (gb->glyph, window); if (white_in_end + width <= dl->bounds.right_in) { @@ -3261,7 +3250,7 @@ create_right_glyph_block (struct window *w, struct display_line *dl) if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN) { - gb->width = glyph_width (gb->glyph, Qnil, gb->findex, window); + gb->width = glyph_width (gb->glyph, window); used_in += gb->width; Dynarr_add (ib, *gb); } @@ -3325,7 +3314,7 @@ create_right_glyph_block (struct window *w, struct display_line *dl) if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN) { - int width = glyph_width (gb->glyph, Qnil, gb->findex, window); + int width = glyph_width (gb->glyph, window); if (used_out) { @@ -3366,7 +3355,7 @@ create_right_glyph_block (struct window *w, struct display_line *dl) if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN) { - int width = glyph_width (gb->glyph, Qnil, gb->findex, window); + int width = glyph_width (gb->glyph, window); if (out_start - width >= in_out_end) { @@ -3482,110 +3471,8 @@ create_right_glyph_block (struct window *w, struct display_line *dl) /* */ /***************************************************************************/ -/* Ensure that the given display line DL accurately represents the - modeline for the given window. */ - -static void -generate_modeline (struct window *w, struct display_line *dl, int type) -{ - struct buffer *b = XBUFFER (w->buffer); - struct frame *f = XFRAME (w->frame); - struct device *d = XDEVICE (f->device); - - /* Unlike display line and rune pointers, this one can't change underneath - our feet. */ - struct display_block *db = get_display_block_from_line (dl, TEXT); - int max_pixpos, min_pixpos, ypos_adj; - Lisp_Object font_inst; - - /* This will actually determine incorrect inside boundaries for the - modeline since it ignores the margins. However being aware of this fact - we never use those values anywhere so it doesn't matter. */ - dl->bounds = calculate_display_line_boundaries (w, 1); - - /* We are generating a modeline. */ - dl->modeline = 1; - dl->cursor_elt = -1; - - /* Reset the runes on the modeline. */ - Dynarr_reset (db->runes); - - if (!WINDOW_HAS_MODELINE_P (w)) - { - struct rune rb; - - /* If there is a horizontal scrollbar, don't add anything. */ - if (window_scrollbar_height (w)) - return; - - dl->ascent = DEVMETH (d, divider_height, ()); - dl->descent = 0; - /* The modeline is at the bottom of the gutters. */ - dl->ypos = WINDOW_BOTTOM (w); - - /* adjust for the bottom gutter */ - if (window_is_lowest (w)) - dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f); - - rb.findex = MODELINE_INDEX; - rb.xpos = dl->bounds.left_out; - rb.width = dl->bounds.right_out - dl->bounds.left_out; - rb.bufpos = 0; - rb.endpos = 0; - rb.type = RUNE_HLINE; - rb.object.hline.thickness = 1; - rb.object.hline.yoffset = 0; - rb.cursor_type = NO_CURSOR; - - if (!EQ (Qzero, w->modeline_shadow_thickness) - && FRAME_WIN_P (f)) - { - int shadow_thickness = MODELINE_SHADOW_THICKNESS (w); - - dl->ypos -= shadow_thickness; - rb.xpos += shadow_thickness; - rb.width -= 2 * shadow_thickness; - } - - Dynarr_add (db->runes, rb); - return; - } - - /* !!#### not right; needs to compute the max height of - all the charsets */ - font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii); - - dl->ascent = XFONT_INSTANCE (font_inst)->ascent; - dl->descent = XFONT_INSTANCE (font_inst)->descent; - - min_pixpos = dl->bounds.left_out; - max_pixpos = dl->bounds.right_out; - - if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f)) - { - int shadow_thickness = MODELINE_SHADOW_THICKNESS (w); - - ypos_adj = shadow_thickness; - min_pixpos += shadow_thickness; - max_pixpos -= shadow_thickness; - } - else - ypos_adj = 0; - - generate_formatted_string_db (b->modeline_format, - b->generated_modeline_string, w, dl, db, - MODELINE_INDEX, min_pixpos, max_pixpos, type); - - /* The modeline is at the bottom of the gutters. We have to wait to - set this until we've generated the modeline in order to account - for any embedded faces. */ - dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; - /* adjust for the bottom gutter */ - if (window_is_lowest (w)) - dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f); -} - -static void +/* This function is also used in frame.c by `generate_title_string' */ +void generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, struct window *w, struct display_line *dl, struct display_block *db, face_index findex, @@ -3596,6 +3483,7 @@ generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, pos_data data; int c_pixpos; + Charcount offset = 0; xzero (data); data.d = d; @@ -3616,9 +3504,14 @@ generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, Dynarr_reset (formatted_string_extent_start_dynarr); Dynarr_reset (formatted_string_extent_end_dynarr); - /* This recursively builds up the modeline. */ + /* result_str is nil when we're building a frame or icon title. Otherwise, + we're building a modeline, so the offset starts at the modeline + horizontal scrolling amount */ + if (! NILP (result_str)) + offset = w->modeline_hscroll; generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0, - max_pixpos - min_pixpos, findex, type); + max_pixpos - min_pixpos, findex, type, &offset, + Qnil); if (Dynarr_length (db->runes)) { @@ -3650,6 +3543,8 @@ generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, Bufbyte *strdata; struct buffer *buf = XBUFFER (WINDOW_BUFFER (w)); + in_modeline_generation = 1; + detach_all_extents (result_str); resize_string (XSTRING (result_str), -1, data.bytepos - XSTRING_LENGTH (result_str)); @@ -3661,8 +3556,9 @@ generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR) { len += (set_charptr_emchar - (strdata + len, Dynarr_atp (db->runes, - elt)->object.chr.ch)); + (strdata + len, + CHARC_TO_CHAR (Dynarr_atp (db->runes, + elt)->object.cglyph))); } } @@ -3686,16 +3582,113 @@ generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, Dynarr_at (formatted_string_extent_end_dynarr, elt), result_str); } + + in_modeline_generation = 0; + } +} + +/* Ensure that the given display line DL accurately represents the + modeline for the given window. */ +static void +generate_modeline (struct window *w, struct display_line *dl, int type) +{ + struct buffer *b = XBUFFER (w->buffer); + struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); + + /* Unlike display line and rune pointers, this one can't change underneath + our feet. */ + struct display_block *db = get_display_block_from_line (dl, TEXT); + int max_pixpos, min_pixpos, ypos_adj; + Lisp_Object font_inst; + + /* This will actually determine incorrect inside boundaries for the + modeline since it ignores the margins. However being aware of this fact + we never use those values anywhere so it doesn't matter. */ + dl->bounds = calculate_display_line_boundaries (w, 1); + + /* We are generating a modeline. */ + dl->modeline = 1; + dl->cursor_elt = -1; + + /* Reset the runes on the modeline. */ + Dynarr_reset (db->runes); + + if (!WINDOW_HAS_MODELINE_P (w)) + { + struct rune rb; + + /* If there is a horizontal scrollbar, don't add anything. */ + if (window_scrollbar_height (w)) + return; + + dl->ascent = DEVMETH (d, divider_height, ()); + dl->descent = 0; + /* The modeline is at the bottom of the gutters. */ + dl->ypos = WINDOW_BOTTOM (w); + + rb.findex = MODELINE_INDEX; + rb.xpos = dl->bounds.left_out; + rb.width = dl->bounds.right_out - dl->bounds.left_out; + rb.bufpos = 0; + rb.endpos = 0; + rb.type = RUNE_HLINE; + rb.object.hline.thickness = 1; + rb.object.hline.yoffset = 0; + rb.cursor_type = NO_CURSOR; + + if (!EQ (Qzero, w->modeline_shadow_thickness) + && FRAME_WIN_P (f)) + { + int shadow_thickness = MODELINE_SHADOW_THICKNESS (w); + + dl->ypos -= shadow_thickness; + rb.xpos += shadow_thickness; + rb.width -= 2 * shadow_thickness; + } + + Dynarr_add (db->runes, rb); + return; + } + + /* !!#### not right; needs to compute the max height of + all the charsets */ + font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii); + + dl->ascent = XFONT_INSTANCE (font_inst)->ascent; + dl->descent = XFONT_INSTANCE (font_inst)->descent; + + min_pixpos = dl->bounds.left_out; + max_pixpos = dl->bounds.right_out; + + if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f)) + { + int shadow_thickness = MODELINE_SHADOW_THICKNESS (w); + + ypos_adj = shadow_thickness; + min_pixpos += shadow_thickness; + max_pixpos -= shadow_thickness; } + else + ypos_adj = 0; + + generate_formatted_string_db (b->modeline_format, + b->generated_modeline_string, w, dl, db, + MODELINE_INDEX, min_pixpos, max_pixpos, type); + + /* The modeline is at the bottom of the gutters. We have to wait to + set this until we've generated the modeline in order to account + for any embedded faces. */ + dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; } static Charcount -add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, +add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str, Charcount pos, Charcount min_pos, Charcount max_pos) { /* This function has been Mule-ized. */ Charcount end; - CONST Bufbyte *cur_pos = str; + const Bufbyte *cur_pos = str; struct display_block *db = data->db; data->blank_width = space_width (XWINDOW (data->window)); @@ -3703,13 +3696,13 @@ add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, add_blank_rune (data, NULL, 0); end = (Dynarr_length (db->runes) + - bytecount_to_charcount (str, strlen ((CONST char *) str))); + bytecount_to_charcount (str, strlen ((const char *) str))); if (max_pos != -1) end = min (max_pos, end); while (pos < end && *cur_pos) { - CONST Bufbyte *old_cur_pos = cur_pos; + const Bufbyte *old_cur_pos = cur_pos; int succeeded; data->ch = charptr_emchar (cur_pos); @@ -3734,7 +3727,8 @@ add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, modeline extents. */ static Charcount add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, - Charcount pos, Charcount min_pos, Charcount max_pos) + Charcount pos, Charcount min_pos, + Charcount max_pos, Lisp_Object extent) { /* This function has been Mule-ized. */ Charcount end; @@ -3750,7 +3744,7 @@ add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, end = min (max_pos, end); gb.glyph = glyph; - gb.extent = Qnil; + gb.extent = extent; add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); pos++; @@ -3777,7 +3771,8 @@ static Charcount generate_fstring_runes (struct window *w, pos_data *data, Charcount pos, Charcount min_pos, Charcount max_pos, Lisp_Object elt, int depth, int max_pixsize, - face_index findex, int type) + face_index findex, int type, Charcount *offset, + Lisp_Object cur_ext) { /* This function has been Mule-ized. */ /* #### The other losing things in this function are: @@ -3809,13 +3804,22 @@ tail_recurse: if (this != last) { - /* The string is just a string. */ + /* No %-construct */ Charcount size = - bytecount_to_charcount (last, this - last) + pos; - Charcount tmp_max = (max_pos == -1 ? size : min (size, max_pos)); + bytecount_to_charcount (last, this - last); + + if (size <= *offset) + *offset -= size; + else + { + Charcount tmp_max = (max_pos == -1 ? pos + size - *offset : + min (pos + size - *offset, max_pos)); + const Bufbyte *tmp_last = charptr_n_addr (last, *offset); - pos = add_string_to_fstring_db_runes (data, last, pos, pos, - tmp_max); + pos = add_string_to_fstring_db_runes (data, tmp_last, + pos, pos, tmp_max); + *offset = 0; + } } else /* *this == '%' */ { @@ -3840,7 +3844,7 @@ tail_recurse: pos = generate_fstring_runes (w, data, pos, spec_width, max_pos, Vglobal_mode_string, depth, max_pixsize, findex, - type); + type, offset, cur_ext); } else if (*this == '-') { @@ -3867,17 +3871,35 @@ tail_recurse: while (num_to_add--) pos = add_string_to_fstring_db_runes - (data, (CONST Bufbyte *) "-", pos, pos, max_pos); + (data, (const Bufbyte *) "-", pos, pos, max_pos); } else if (*this != 0) { - Bufbyte *str; Emchar ch = charptr_emchar (this); + Bufbyte *str; + Charcount size; + decode_mode_spec (w, ch, type); str = Dynarr_atp (mode_spec_bufbyte_string, 0); - pos = add_string_to_fstring_db_runes (data,str, pos, pos, - max_pos); + size = bytecount_to_charcount + /* Skip the null character added by `decode_mode_spec' */ + (str, Dynarr_length (mode_spec_bufbyte_string)) - 1; + + if (size <= *offset) + *offset -= size; + else + { + const Bufbyte *tmp_str = charptr_n_addr (str, *offset); + + /* #### NOTE: I don't understand why a tmp_max is not + computed and used here as in the plain string case + above. -- dv */ + pos = add_string_to_fstring_db_runes (data, tmp_str, + pos, pos, + max_pos); + *offset = 0; + } } /* NOT this++. There could be any sort of character at @@ -3903,13 +3925,26 @@ tail_recurse: if (!UNBOUNDP (tem)) { - /* If value is a string, output that string literally: + /* If value is a string, output that string literally: don't check for % within it. */ if (STRINGP (tem)) { - pos = - add_string_to_fstring_db_runes - (data, XSTRING_DATA (tem), pos, min_pos, max_pos); + Bufbyte *str = XSTRING_DATA (tem); + Charcount size = XSTRING_CHAR_LENGTH (tem); + + if (size <= *offset) + *offset -= size; + else + { + const Bufbyte *tmp_str = charptr_n_addr (str, *offset); + + /* #### NOTE: I don't understand why a tmp_max is not + computed and used here as in the plain string case + above. -- dv */ + pos = add_string_to_fstring_db_runes (data, tmp_str, pos, + min_pos, max_pos); + *offset = 0; + } } /* Give up right away for nil or t. */ else if (!EQ (tem, elt)) @@ -3934,50 +3969,53 @@ tail_recurse: else if (CONSP (elt)) { /* A cons cell: four distinct cases. - * If first element is a string or a cons, process all the elements - * and effectively concatenate them. - * If first element is a negative number, truncate displaying cdr to - * at most that many characters. If positive, pad (with spaces) - * to at least that many characters. - * If first element is a symbol, process the cadr or caddr recursively - * according to whether the symbol's value is non-nil or nil. - * If first element is a face, process the cdr recursively - * without altering the depth. + * - If first element is a string or a cons, process all the elements + * and effectively concatenate them. + * - If first element is a negative number, truncate displaying cdr to + * at most that many characters. If positive, pad (with spaces) + * to at least that many characters. + * - If first element is another symbol, process the cadr or caddr + * recursively according to whether the symbol's value is non-nil or + * nil. + * - If first element is an extent, process the cdr recursively + * and handle the extent's face. */ + Lisp_Object car, tem; car = XCAR (elt); if (SYMBOLP (car)) - { - elt = XCDR (elt); - if (!CONSP (elt)) - goto invalid; - tem = symbol_value_in_buffer (car, w->buffer); - /* elt is now the cdr, and we know it is a cons cell. - Use its car if CAR has a non-nil value. */ - if (!UNBOUNDP (tem)) - { - if (!NILP (tem)) - { - elt = XCAR (elt); - goto tail_recurse; - } - } - /* Symbol's value is nil (or symbol is unbound) - * Get the cddr of the original list - * and if possible find the caddr and use that. - */ - elt = XCDR (elt); - if (NILP (elt)) - ; - else if (!CONSP (elt)) - goto invalid; - else - { - elt = XCAR (elt); - goto tail_recurse; - } - } + { + elt = XCDR (elt); + if (!CONSP (elt)) + goto invalid; + + tem = symbol_value_in_buffer (car, w->buffer); + /* elt is now the cdr, and we know it is a cons cell. + Use its car if CAR has a non-nil value. */ + if (!UNBOUNDP (tem)) + { + if (!NILP (tem)) + { + elt = XCAR (elt); + goto tail_recurse; + } + } + /* Symbol's value is nil (or symbol is unbound) + * Get the cddr of the original list + * and if possible find the caddr and use that. + */ + elt = XCDR (elt); + if (NILP (elt)) + ; + else if (!CONSP (elt)) + goto invalid; + else + { + elt = XCAR (elt); + goto tail_recurse; + } + } else if (INTP (car)) { Charcount lim = XINT (car); @@ -4016,13 +4054,14 @@ tail_recurse: else if (STRINGP (car) || CONSP (car)) { int limit = 50; + /* LIMIT is to protect against circular lists. */ while (CONSP (elt) && --limit > 0 && (pos < max_pos || max_pos == -1)) { pos = generate_fstring_runes (w, data, pos, pos, max_pos, - XCAR (elt), depth, - max_pixsize, findex, type); + XCAR (elt), depth, max_pixsize, + findex, type, offset, cur_ext); elt = XCDR (elt); } } @@ -4061,7 +4100,8 @@ tail_recurse: data->findex = new_findex; pos = generate_fstring_runes (w, data, pos, pos, max_pos, XCDR (elt), depth - 1, - max_pixsize, new_findex, type); + max_pixsize, new_findex, type, + offset, car); data->findex = old_findex; Dynarr_add (formatted_string_extent_dynarr, ext); Dynarr_add (formatted_string_extent_start_dynarr, start); @@ -4071,57 +4111,46 @@ tail_recurse: } else if (GLYPHP (elt)) { - pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos); + /* Glyphs are considered as one character with respect to the modeline + horizontal scrolling facility. -- dv */ + if (*offset > 0) + *offset -= 1; + else + pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos, + cur_ext); } else { invalid: - pos = - add_string_to_fstring_db_runes - (data, (CONST Bufbyte *) GETTEXT ("*invalid*"), pos, min_pos, - max_pos); + { + char *str = GETTEXT ("*invalid*"); + Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */ + + if (size <= *offset) + *offset -= size; + else + { + const Bufbyte *tmp_str = + charptr_n_addr ((const Bufbyte *) str, *offset); + + /* #### NOTE: I don't understand why a tmp_max is not computed and + used here as in the plain string case above. -- dv */ + pos = add_string_to_fstring_db_runes (data, tmp_str, pos, + min_pos, max_pos); + *offset = 0; + } + } } if (min_pos > pos) { - add_string_to_fstring_db_runes (data, (CONST Bufbyte *) "", pos, min_pos, - -1); + add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos, + min_pos, -1); } return pos; } -/* The caller is responsible for freeing the returned string. */ -Bufbyte * -generate_formatted_string (struct window *w, Lisp_Object format_str, - Lisp_Object result_str, face_index findex, int type) -{ - struct display_line *dl; - struct display_block *db; - int elt = 0; - - dl = &formatted_string_display_line; - db = get_display_block_from_line (dl, TEXT); - Dynarr_reset (db->runes); - - generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, - -1, type); - - Dynarr_reset (formatted_string_emchar_dynarr); - while (elt < Dynarr_length (db->runes)) - { - if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR) - Dynarr_add (formatted_string_emchar_dynarr, - Dynarr_atp (db->runes, elt)->object.chr.ch); - elt++; - } - - return - convert_emchar_string_into_malloced_string - ( Dynarr_atp (formatted_string_emchar_dynarr, 0), - Dynarr_length (formatted_string_emchar_dynarr), 0); -} - /* Update just the modeline. Assumes the desired display structs. If they do not have a modeline block, it does nothing. */ static void @@ -4250,7 +4279,7 @@ create_string_text_block (struct window *w, Lisp_Object disp_string, against this case. */ struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0; struct device *d = XDEVICE (f->device); - struct Lisp_String* s = XSTRING (disp_string); + Lisp_String* s = XSTRING (disp_string); /* we're working with these a lot so precalculate them */ Bytecount slen = XSTRING_LENGTH (disp_string); @@ -4262,9 +4291,9 @@ create_string_text_block (struct window *w, Lisp_Object disp_string, int truncate_win = b ? window_truncation_on (w) : 0; int end_glyph_width = 0; - /* we're going to ditch selective display for static text, its an - FSF thing and invisble extents are the way to go - here. Implementing it also relies on a number of buffer-specific + /* We're going to ditch selective display for static text, it's an + FSF thing and invisible extents are the way to go here. + Implementing it also relies on a number of buffer-specific functions that we don't have the luxury of being able to use here. */ @@ -4330,6 +4359,7 @@ create_string_text_block (struct window *w, Lisp_Object disp_string, dl->used_prop_data = 0; dl->num_chars = 0; + dl->line_continuation = 0; /* set up faces to use for clearing areas, used by output_display_line */ @@ -4722,6 +4752,7 @@ done: /* data.bi_bufpos is already at the start of the next line. */ + dl->line_continuation = 1; gb.glyph = Vcontinuation_glyph; cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); } @@ -4731,7 +4762,7 @@ done: if (truncate_win && data.bi_bufpos == bi_string_zv) { - CONST Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv); + const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv); DEC_CHARPTR (endb); if (charptr_emchar (endb) != '\n') { @@ -4756,7 +4787,7 @@ done: { struct rune *rb = Dynarr_atp (db->runes, elt); - if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ') + if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' ')) || rb->type == RUNE_BLANK) { dl->bounds.left_white += rb->width; @@ -4776,8 +4807,7 @@ done: { struct rune *rb = Dynarr_atp (db->runes, elt); - if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100 - && isspace (rb->object.chr.ch)) + if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph)) && !rb->type == RUNE_BLANK) { dl->bounds.right_white = rb->xpos + rb->width; @@ -5063,6 +5093,7 @@ regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type) int ypos = WINDOW_TEXT_TOP (w); int yend; /* set farther down */ int yclip = WINDOW_TEXT_TOP_CLIP (w); + int force; prop_block_dynarr *prop; layout_bounds bounds; @@ -5116,7 +5147,14 @@ regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type) else prop = 0; - while (ypos < yend) + /* When we are computing things for scrolling purposes, make + sure at least one line is always generated */ + force = (type == CMOTION_DISP); + + /* Make sure this is set always */ + /* Note the conversion at end */ + w->window_end_pos[type] = start_pos; + while (ypos < yend || force) { struct display_line dl; struct display_line *dlp; @@ -5169,7 +5207,7 @@ regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type) the top clip and the bottom clip. */ visible_height -= (dlp->clip + dlp->top_clip); - if (visible_height < VERTICAL_CLIP (w, 1)) + if (visible_height < VERTICAL_CLIP (w, 1) && !force) { if (local) free_display_line (dlp); @@ -5213,16 +5251,22 @@ regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type) generate_display_line call. */ if (start_pos > BUF_ZV (b)) break; + + force = 0; } if (prop) Dynarr_free (prop); /* #### More not quite right, but close enough. */ - /* #### Ben sez: apparently window_end_pos[] is measured + /* Ben sez: apparently window_end_pos[] is measured as the number of characters between the window end and the end of the buffer? This seems rather weirdo. What's - the justification for this? */ + the justification for this? + + JV sez: Because BUF_Z (b) would be a good initial value, however + that can change. This representation allows initalizing with 0. + */ w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type]; if (need_modeline) @@ -5553,20 +5597,9 @@ regenerate_window_incrementally (struct window *w, Bufpos startp, assert (cdl->end_bufpos == ddl->end_bufpos); assert (cdl->offset == ddl->offset); - /* If the last rune is already a continuation glyph, fail. - #### We should be able to handle this better. */ - { - struct display_block *db = get_display_block_from_line (ddl, TEXT); - if (Dynarr_length (db->runes)) - { - struct rune *rb = - Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); - - if (rb->type == RUNE_DGLYPH - && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph)) - return 0; - } - } + /* If the line continues to next display line, fail. */ + if (ddl->line_continuation) + return 0; /* If the line was generated using propagation data, fail. */ if (ddl->used_prop_data) @@ -5584,19 +5617,9 @@ regenerate_window_incrementally (struct window *w, Bufpos startp, return 0; } - /* If the last rune is now a continuation glyph, fail. */ - { - struct display_block *db = get_display_block_from_line (ddl, TEXT); - if (Dynarr_length (db->runes)) - { - struct rune *rb = - Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); - - if (rb->type == RUNE_DGLYPH - && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph)) - return 0; - } - } + /* If the line continues to next display line, fail. */ + if (ddl->line_continuation) + return 0; /* If any line position parameters have changed or a cursor has disappeared or disappeared, fail. */ @@ -5900,7 +5923,7 @@ redisplay_window (Lisp_Object window, int skip_selected) the cache purely because glyphs have changed - this is now handled by the dirty flag.*/ if ((!echo_active && b != window_display_buffer (w)) - || !Dynarr_length (w->glyph_cachels)) + || !Dynarr_length (w->glyph_cachels) || f->faces_changed) reset_glyph_cachels (w); else mark_glyph_cachels_as_not_updated (w); @@ -5972,7 +5995,7 @@ redisplay_window (Lisp_Object window, int skip_selected) && !(MINI_WINDOW_P (w) && f->buffers_changed) && !f->frame_changed && !truncation_changed - /* check whether start is really at the begining of a line GE */ + /* check whether start is really at the beginning of a line GE */ && (!w->start_at_line_beg || beginning_of_line_p (b, startp)) ) { @@ -5986,7 +6009,7 @@ redisplay_window (Lisp_Object window, int skip_selected) && !f->faces_changed && !f->glyphs_changed && !f->subwindows_changed - && !f->subwindows_state_changed + /* && !f->subwindows_state_changed*/ && !f->point_changed && !f->windows_structure_changed) { @@ -6008,7 +6031,7 @@ redisplay_window (Lisp_Object window, int skip_selected) && !f->faces_changed && !f->glyphs_changed && !f->subwindows_changed - && !f->subwindows_state_changed + /* && !f->subwindows_state_changed*/ && !f->windows_structure_changed) { if (point_visible (w, pointm, CURRENT_DISP) @@ -6067,7 +6090,7 @@ redisplay_window (Lisp_Object window, int skip_selected) && !f->faces_changed && !f->glyphs_changed && !f->subwindows_changed - && !f->subwindows_state_changed + /* && !f->subwindows_state_changed*/ && !f->windows_structure_changed && !f->frame_changed && !truncation_changed @@ -6164,7 +6187,9 @@ regeneration_done: somewhere else once tty updates occur on a per-frame basis. */ mark_face_cachels_as_clean (w); - /* The glyph cachels only get dirty if someone changed something. */ + /* The glyph cachels only get dirty if someone changed something. + Since redisplay has now effectively ended we can reset the dirty + flag since everything must be up-to-date. */ if (glyphs_changed) mark_glyph_cachels_as_clean (w); @@ -6247,7 +6272,7 @@ call_redisplay_end_triggers (struct window *w, void *closure) /* Ensure that all windows on the given frame are correctly displayed. */ -static int +int redisplay_frame (struct frame *f, int preemption_check) { struct device *d = XDEVICE (f->device); @@ -6264,6 +6289,16 @@ redisplay_frame (struct frame *f, int preemption_check) return 1; } + if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0)) + { + Lisp_Object frame; + + f->old_buffer_alist = Freplace_list (f->old_buffer_alist, + f->buffer_alist); + XSETFRAME (frame, f); + va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame); + } + /* Before we put a hold on frame size changes, attempt to process any which are already pending. */ if (f->size_change_pending) @@ -6289,40 +6324,33 @@ redisplay_frame (struct frame *f, int preemption_check) being handled. */ update_frame_menubars (f); #endif /* HAVE_MENUBARS */ - /* widgets are similar to menus in that they can call lisp to - determine activation etc. Therefore update them before we get - into redisplay. This is primarily for connected widgets such as - radio buttons. */ - update_frame_subwindows (f); #ifdef HAVE_TOOLBARS /* Update the toolbars. */ update_frame_toolbars (f); #endif /* HAVE_TOOLBARS */ + /* Gutter update proper has to be done inside display when no frame + size changes can occur, thus we separately update the gutter + geometry here if it needs it. */ + update_frame_gutter_geometry (f); /* If we clear the frame we have to force its contents to be redrawn. */ if (f->clear) f->frame_changed = 1; - /* invalidate the subwindow cache. We use subwindows_changed here to - cause subwindows to get instantiated. This is because + /* Invalidate the subwindow caches. We use subwindows_changed here + to cause subwindows to get instantiated. This is because subwindows_state_changed is less strict - dealing with things like the clicked state of button. We have to do this before redisplaying the gutters as subwindows get unmapped in the process.*/ - if (!Dynarr_length (f->subwindow_cachels) - || f->subwindows_changed - || f->faces_changed - || f->frame_changed) + if (f->frame_changed) + reset_frame_subwindow_instance_cache (f); + + if (f->frame_changed || f->subwindows_changed) { - reset_subwindow_cachels (f); /* we have to do this so the gutter gets regenerated. */ reset_gutter_display_lines (f); } - else - mark_subwindow_cachels_as_not_updated (f); - /* We can now update the gutters, safe in the knowledge that our - efforts won't get undone. */ - update_frame_gutters (f); hold_frame_size_changes (); @@ -6350,10 +6378,22 @@ redisplay_frame (struct frame *f, int preemption_check) #### If a frame-size change does occur we should probably actually be preempting redisplay. */ + MAYBE_DEVMETH (d, frame_output_begin, (f)); + + /* We can now update the gutters, safe in the knowledge that our + efforts won't get undone. */ + + /* This can call lisp, but redisplay is protected by binding + inhibit_quit. More importantly the code involving display lines + *assumes* that GC will not happen and so does not GCPRO + anything. Since we use this code the whole time with the gutters + we cannot allow GC to happen when manipulating the gutters. */ + update_frame_gutters (f); + /* Erase the frame before outputting its contents. */ if (f->clear) { - DEVMETH (d, clear_frame, (f)); + MAYBE_DEVMETH (d, clear_frame, (f)); } /* Do the selected window first. */ @@ -6362,11 +6402,7 @@ redisplay_frame (struct frame *f, int preemption_check) /* Then do the rest. */ redisplay_windows (f->root_window, 1); - /* We now call the output_end routine for tty frames. We delay - doing so in order to avoid cursor flicker. So much for 100% - encapsulation. */ - if (FRAME_TTY_P (f)) - DEVMETH (d, output_end, (d)); + MAYBE_DEVMETH (d, frame_output_end, (f)); update_frame_title (f); @@ -6389,16 +6425,27 @@ redisplay_frame (struct frame *f, int preemption_check) return 0; } -/* Ensure that all frames on the given device are correctly displayed. */ +/* Ensure that all frames on the given device are correctly displayed. + If AUTOMATIC is non-zero, and the device implementation indicates + no automatic redisplay, as printers do, then the device is not + redisplayed. AUTOMATIC is set to zero when called from lisp + functions (redraw-device) and (redisplay-device), and to non-zero + when called from "lazy" redisplay(); +*/ static int -redisplay_device (struct device *d) +redisplay_device (struct device *d, int automatic) { Lisp_Object frame, frmcons; int preempted = 0; int size_change_failed = 0; struct frame *f; + if (automatic + && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ()) + & XDEVIMPF_NO_AUTO_REDISPLAY)) + return 0; + if (DEVICE_STREAM_P (d)) /* nothing to do */ return 0; @@ -6513,7 +6560,7 @@ redisplay_without_hooks (void) if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d)) { - preempted = redisplay_device (d); + preempted = redisplay_device (d, 1); if (preempted) { @@ -6627,7 +6674,7 @@ static void decode_mode_spec (struct window *w, Emchar spec, int type) { Lisp_Object obj = Qnil; - CONST char *str = NULL; + const char *str = NULL; struct buffer *b = XBUFFER (w->buffer); Dynarr_reset (mode_spec_bufbyte_string); @@ -6656,7 +6703,7 @@ decode_mode_spec (struct window *w, Emchar spec, int type) long_to_string (buf, col); Dynarr_add_many (mode_spec_bufbyte_string, - (CONST Bufbyte *) buf, strlen (buf)); + (const Bufbyte *) buf, strlen (buf)); goto decode_mode_spec_done; } @@ -6993,7 +7040,9 @@ mark_glyph_block_dynarr (glyph_block_dynarr *gba) } } -static void +/* See the comment in image_instantiate_cache_result as to why marking + the glyph will also mark the image_instance. */ +void mark_redisplay_structs (display_line_dynarr *dla) { display_line *dl = Dynarr_atp (dla, 0); @@ -7053,6 +7102,7 @@ mark_redisplay (void) struct frame *f = XFRAME (XCAR (frmcons)); update_frame_window_mirror (f); mark_window_mirror (f->root_mirror); + mark_gutters (f); } } @@ -7489,11 +7539,18 @@ point_would_be_visible (struct window *w, Bufpos startp, Bufpos point) displayed. The end of the last line is also know as the window end position. + WARNING: It is possible that redisplay failed to layout any lines for the + windows. Under normal circumstances this is rare. However it seems that it + does occur in the following situation: A mouse event has come in and we + need to compute its location in a window. That code (in + pixel_to_glyph_translation) already can handle 0 as an error return value. + #### With a little work this could probably be reworked as just a call to start_with_line_at_pixpos. */ static Bufpos -start_end_of_last_line (struct window *w, Bufpos startp, int end) +start_end_of_last_line (struct window *w, Bufpos startp, int end, + int may_error) { struct buffer *b = XBUFFER (w->buffer); line_start_cache_dynarr *cache = w->line_start_cache; @@ -7513,7 +7570,7 @@ start_end_of_last_line (struct window *w, Bufpos startp, int end) start_elt = point_in_line_start_cache (w, cur_start, 0); if (start_elt == -1) - abort (); /* this had better never happen */ + return may_error ? 0 : startp; while (1) { @@ -7577,7 +7634,7 @@ start_end_of_last_line (struct window *w, Bufpos startp, int end) Bufpos start_of_last_line (struct window *w, Bufpos startp) { - return start_end_of_last_line (w, startp, 0); + return start_end_of_last_line (w, startp, 0 , 0); } /* For the given window W, if display starts at STARTP, what will be @@ -7587,9 +7644,16 @@ start_of_last_line (struct window *w, Bufpos startp) Bufpos end_of_last_line (struct window *w, Bufpos startp) { - return start_end_of_last_line (w, startp, 1); + return start_end_of_last_line (w, startp, 1, 0); +} + +static Bufpos +end_of_last_line_may_error (struct window *w, Bufpos startp) +{ + return start_end_of_last_line (w, startp, 1, 1); } + /* For window W, what does the starting position have to be so that the line containing POINT will cover pixel position PIXPOS. */ @@ -7773,7 +7837,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, validate_line_start_cache (w); w->line_cache_validation_override++; - updating_line_start_cache = 1; if (from < BUF_BEGV (b)) from = BUF_BEGV (b); @@ -7782,7 +7845,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, if (from > to) { - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7795,7 +7857,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, /* Check to see if the desired range is already in the cache. */ if (from >= low_bound && to <= high_bound) { - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7824,7 +7885,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, update_internal_cache_list (w, DESIRED_DISP); if (!Dynarr_length (internal_cache)) { - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7852,7 +7912,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, { Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), Dynarr_length (internal_cache)); - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7861,7 +7920,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, the bounds of the DESIRED structs in the first place. */ if (start >= low_bound && end <= high_bound) { - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7884,7 +7942,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, Dynarr_reset (cache); Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), Dynarr_length (internal_cache)); - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7910,7 +7967,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, Dynarr_reset (cache); Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), Dynarr_length (internal_cache)); - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7919,7 +7975,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, Dynarr_length (internal_cache) - ic_elt); } - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -7939,23 +7994,9 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, update_internal_cache_list (w, CMOTION_DISP); /* If this assert is triggered then regenerate_window failed - to layout a single line. That is not supposed to be - possible because we impose a minimum height on the buffer - and override vertical clip when we are in here. */ - /* #### Ah, but it is because the window may temporarily - exist but not have any lines at all if the minibuffer is - real big. Look into that situation better. */ - if (!Dynarr_length (internal_cache)) - { - if (old_lb == -1 && low_bound == -1) - { - updating_line_start_cache = 0; - w->line_cache_validation_override--; - return; - } - - assert (Dynarr_length (internal_cache)); - } + to layout a single line. This is not possible since we + force at least a single line to be layout for CMOTION_DISP */ + assert (Dynarr_length (internal_cache)); assert (startp == Dynarr_atp (internal_cache, 0)->start); ic_elt = Dynarr_length (internal_cache) - 1; @@ -8001,7 +8042,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, startp = new_startp; if (startp > BUF_ZV (b)) { - updating_line_start_cache = 0; w->line_cache_validation_override--; return; } @@ -8035,7 +8075,6 @@ update_line_start_cache (struct window *w, Bufpos from, Bufpos to, while (to > high_bound); } - updating_line_start_cache = 0; w->line_cache_validation_override--; assert (to <= high_bound); } @@ -8672,7 +8711,7 @@ pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord, } else if (past_end || (rb->type == RUNE_CHAR - && rb->object.chr.ch == '\n')) + && CHARC_ASCII_EQ (rb->object.cglyph, '\n'))) { (*row)--; /* At this point we may have glyphs in the right @@ -8743,7 +8782,7 @@ pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord, if (!MARKERP ((*w)->start[CURRENT_DISP])) *closest = 0; else - *closest = end_of_last_line (*w, + *closest = end_of_last_line_may_error (*w, marker_position ((*w)->start[CURRENT_DISP])); *col = 0; UPDATE_CACHE_RETURN; @@ -8776,6 +8815,9 @@ Ensure that all minibuffers are correctly showing the echo area. if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f)) { Lisp_Object window = FRAME_MINIBUF_WINDOW (f); + + MAYBE_DEVMETH (d, frame_output_begin, (f)); + /* * If the frame size has changed, there may be random * chud on the screen left from previous messages @@ -8784,19 +8826,15 @@ Ensure that all minibuffers are correctly showing the echo area. */ if (f->echo_area_garbaged) { - DEVMETH (d, clear_frame, (f)); + MAYBE_DEVMETH (d, clear_frame, (f)); f->echo_area_garbaged = 0; } redisplay_window (window, 0); + MAYBE_DEVMETH (d, frame_output_end, (f)); + call_redisplay_end_triggers (XWINDOW (window), 0); } } - - /* We now call the output_end routine for tty frames. We delay - doing so in order to avoid cursor flicker. So much for 100% - encapsulation. */ - if (DEVICE_TTY_P (d)) - DEVMETH (d, output_end, (d)); } return Qnil; @@ -8831,6 +8869,9 @@ input and is guaranteed to proceed to completion. f->clear = 1; redisplay_frame (f, 1); + /* See the comment in Fredisplay_frame. */ + RESET_CHANGED_SET_FLAGS; + return unbind_to (count, Qnil); } @@ -8858,6 +8899,15 @@ input and is guaranteed to proceed to completion. redisplay_frame (f, 1); + /* If we don't reset the global redisplay flags here, subsequent + changes to the display will not get registered by redisplay + because it thinks it already has registered changes. If you + really knew what you were doing you could confuse redisplay by + calling Fredisplay_frame while updating another frame. We assume + that if you know what you are doing you will not be that + stupid. */ + RESET_CHANGED_SET_FLAGS; + return unbind_to (count, Qnil); } @@ -8885,7 +8935,10 @@ input and is guaranteed to proceed to completion. { XFRAME (XCAR (frmcons))->clear = 1; } - redisplay_device (d); + redisplay_device (d, 0); + + /* See the comment in Fredisplay_frame. */ + RESET_CHANGED_SET_FLAGS; return unbind_to (count, Qnil); } @@ -8912,7 +8965,10 @@ input and is guaranteed to proceed to completion. disable_preemption++; } - redisplay_device (d); + redisplay_device (d, 0); + + /* See the comment in Fredisplay_frame. */ + RESET_CHANGED_SET_FLAGS; return unbind_to (count, Qnil); } @@ -9092,14 +9148,18 @@ init_redisplay (void) if (!initialized) #endif { - cmotion_display_lines = Dynarr_new (display_line); - mode_spec_bufbyte_string = Dynarr_new (Bufbyte); - formatted_string_emchar_dynarr = Dynarr_new (Emchar); - formatted_string_extent_dynarr = Dynarr_new (EXTENT); - formatted_string_extent_start_dynarr = Dynarr_new (Bytecount); - formatted_string_extent_end_dynarr = Dynarr_new (Bytecount); - internal_cache = Dynarr_new (line_start_cache); - xzero (formatted_string_display_line); + if (!cmotion_display_lines) + cmotion_display_lines = Dynarr_new (display_line); + if (!mode_spec_bufbyte_string) + mode_spec_bufbyte_string = Dynarr_new (Bufbyte); + if (!formatted_string_extent_dynarr) + formatted_string_extent_dynarr = Dynarr_new (EXTENT); + if (!formatted_string_extent_start_dynarr) + formatted_string_extent_start_dynarr = Dynarr_new (Bytecount); + if (!formatted_string_extent_end_dynarr) + formatted_string_extent_end_dynarr = Dynarr_new (Bytecount); + if (!internal_cache) + internal_cache = Dynarr_new (line_start_cache); } /* window system is nil when in -batch mode */ @@ -9172,6 +9232,8 @@ syms_of_redisplay (void) defsymbol (&Qbar_cursor, "bar-cursor"); defsymbol (&Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions"); + defsymbol (&Qtop_bottom, "top-bottom"); + defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook"); DEFSUBR (Fredisplay_echo_area); DEFSUBR (Fredraw_frame); @@ -9183,15 +9245,8 @@ syms_of_redisplay (void) } void -reinit_vars_of_redisplay (void) -{ - updating_line_start_cache = 0; -} - -void vars_of_redisplay (void) { - reinit_vars_of_redisplay (); #if 0 staticpro (&last_arrow_position); @@ -9236,7 +9291,9 @@ See also `overlay-arrow-string'. Voverlay_arrow_position = Qnil; DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /* -String to display as an arrow. See also `overlay-arrow-position'. +String or glyph to display as an arrow. See also `overlay-arrow-position'. +\(Note that despite the name of this variable, it can be set to a glyph as +well as a string.) */ , redisplay_variable_changed); Voverlay_arrow_string = Qnil; @@ -9260,10 +9317,19 @@ If this is zero, point is always centered after it moves off screen. redisplay_variable_changed); truncate_partial_width_windows = 1; - DEFVAR_BOOL ("visible-bell", &visible_bell /* -*Non-nil means try to flash the frame to represent a bell. + DEFVAR_LISP ("visible-bell", &Vvisible_bell /* +*Non-nil substitutes a visual signal for the audible bell. + +Default behavior is to flash the whole screen. On some platforms, +special effects are available using the following values: + +'display Flash the whole screen (ie, the default behavior). +'top-bottom Flash only the top and bottom lines of the selected frame. + +When effects are unavailable on a platform, the visual bell is the +default, whole screen. (Currently only X supports any special effects.) */ ); - visible_bell = 0; + Vvisible_bell = Qnil; DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /* *Non-nil means no need to redraw entire frame after suspending. @@ -9314,17 +9380,22 @@ Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2. #ifndef INHIBIT_REDISPLAY_HOOKS xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /* Function or functions to run before every redisplay. -Functions on this hook must be careful to avoid signalling errors! */ ); Vpre_redisplay_hook = Qnil; xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /* Function or functions to run after every redisplay. -Functions on this hook must be careful to avoid signalling errors! */ ); Vpost_redisplay_hook = Qnil; #endif /* INHIBIT_REDISPLAY_HOOKS */ + DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /* +Function or functions to call when a frame's buffer list has changed. +This is called during redisplay, before redisplaying each frame. +Functions on this hook are called with one argument, the frame. +*/ ); + Vbuffer_list_changed_hook = Qnil; + DEFVAR_INT ("display-warning-tick", &display_warning_tick /* Bump this to tell the C code to call `display-warning-buffer' at next redisplay. You should not normally change this; the function @@ -9383,10 +9454,10 @@ This is a specifier; use `set-specifier' to change it. Vleft_margin_width = Fmake_specifier (Qnatnum); set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero))); set_specifier_caching (Vleft_margin_width, - slot_offset (struct window, left_margin_width), + offsetof (struct window, left_margin_width), some_window_value_changed, - slot_offset (struct frame, left_margin_width), - margin_width_changed_in_frame); + offsetof (struct frame, left_margin_width), + margin_width_changed_in_frame, 0); DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /* *Width of right margin. @@ -9395,10 +9466,10 @@ This is a specifier; use `set-specifier' to change it. Vright_margin_width = Fmake_specifier (Qnatnum); set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero))); set_specifier_caching (Vright_margin_width, - slot_offset (struct window, right_margin_width), + offsetof (struct window, right_margin_width), some_window_value_changed, - slot_offset (struct frame, right_margin_width), - margin_width_changed_in_frame); + offsetof (struct frame, right_margin_width), + margin_width_changed_in_frame, 0); DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /* *Minimum ascent height of lines. @@ -9407,9 +9478,9 @@ This is a specifier; use `set-specifier' to change it. Vminimum_line_ascent = Fmake_specifier (Qnatnum); set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero))); set_specifier_caching (Vminimum_line_ascent, - slot_offset (struct window, minimum_line_ascent), + offsetof (struct window, minimum_line_ascent), some_window_value_changed, - 0, 0); + 0, 0, 0); DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /* *Minimum descent height of lines. @@ -9418,9 +9489,9 @@ This is a specifier; use `set-specifier' to change it. Vminimum_line_descent = Fmake_specifier (Qnatnum); set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero))); set_specifier_caching (Vminimum_line_descent, - slot_offset (struct window, minimum_line_descent), + offsetof (struct window, minimum_line_descent), some_window_value_changed, - 0, 0); + 0, 0, 0); DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /* *Non-nil means use the left outside margin as extra whitespace when @@ -9430,9 +9501,9 @@ This is a specifier; use `set-specifier' to change it. Vuse_left_overflow = Fmake_specifier (Qboolean); set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil))); set_specifier_caching (Vuse_left_overflow, - slot_offset (struct window, use_left_overflow), + offsetof (struct window, use_left_overflow), some_window_value_changed, - 0, 0); + 0, 0, 0); DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /* *Non-nil means use the right outside margin as extra whitespace when @@ -9442,9 +9513,9 @@ This is a specifier; use `set-specifier' to change it. Vuse_right_overflow = Fmake_specifier (Qboolean); set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil))); set_specifier_caching (Vuse_right_overflow, - slot_offset (struct window, use_right_overflow), + offsetof (struct window, use_right_overflow), some_window_value_changed, - 0, 0); + 0, 0, 0); DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /* *Non-nil means the text cursor is visible (this is usually the case). @@ -9453,8 +9524,8 @@ This is a specifier; use `set-specifier' to change it. Vtext_cursor_visible_p = Fmake_specifier (Qboolean); set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt))); set_specifier_caching (Vtext_cursor_visible_p, - slot_offset (struct window, text_cursor_visible_p), + offsetof (struct window, text_cursor_visible_p), text_cursor_visible_p_changed, - 0, 0); + 0, 0, 0); }