X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fredisplay.c;h=6936acf95d2a06711e541d62553767a4ccd3fbfc;hb=f9fdf5a6cb58286f64f6f8bd0bfd2dab9b9b8816;hp=af19d9be086e88a5f9c6945edb4e97c1df8088d4;hpb=77dcef404dc78635f6ffa8f71a803d2bc7cc8921;p=chise%2Fxemacs-chise.git diff --git a/src/redisplay.c b/src/redisplay.c index af19d9b..6936acf 100644 --- a/src/redisplay.c +++ b/src/redisplay.c @@ -256,7 +256,8 @@ static prop_block_dynarr *add_glyph_rune (pos_data *data, struct glyph_cachel *cachel); static Bytind create_text_block (struct window *w, struct display_line *dl, Bytind bi_start_pos, int start_col, - prop_block_dynarr **prop, int type); + prop_block_dynarr **prop, + int type); static int create_overlay_glyph_block (struct window *w, struct display_line *dl); static void create_left_glyph_block (struct window *w, @@ -365,6 +366,11 @@ int frame_changed; int glyphs_changed; int glyphs_changed_set; +/* non-zero if any displayed subwindow is in need of updating + somewhere. */ +int subwindows_changed; +int subwindows_changed_set; + /* This variable is 1 if the icon has to be updated. It is set to 1 when `frame-icon-glyph' changes. */ int icon_changed; @@ -681,7 +687,8 @@ calculate_display_line_boundaries (struct window *w, int modeline) static Bufpos generate_display_line (struct window *w, struct display_line *dl, int bounds, Bufpos start_pos, int start_col, - prop_block_dynarr **prop, int type) + prop_block_dynarr **prop, + int type) { Bufpos ret_bufpos; int overlay_width; @@ -1233,66 +1240,12 @@ add_control_char_runes (pos_data *data, struct buffer *b) } } -/* Given a display table entry, call the appropriate functions to - display each element of the entry. */ - static prop_block_dynarr * -add_disp_table_entry_runes (pos_data *data, Lisp_Object entry) +add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry) { prop_block_dynarr *prop = NULL; - if (VECTORP (entry)) - { - struct Lisp_Vector *de = XVECTOR (entry); - long len = vector_length (de); - int elt; - - for (elt = 0; elt < len; elt++) - { - if (NILP (de->contents[elt])) - continue; - else if (STRINGP (de->contents[elt])) - { - prop = - add_bufbyte_string_runes - (data, - XSTRING_DATA (de->contents[elt]), - XSTRING_LENGTH (de->contents[elt]), - 0); - } - else if (GLYPHP (de->contents[elt])) - { - if (data->start_col) - data->start_col--; - - if (!data->start_col && data->bi_start_col_enabled) - { - prop = add_hscroll_rune (data); - } - else - { - struct glyph_block gb; - - gb.glyph = de->contents[elt]; - gb.extent = Qnil; - prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); - } - } - else if (CHAR_OR_CHAR_INTP (de->contents[elt])) - { - data->ch = XCHAR_OR_CHAR_INT (de->contents[elt]); - prop = add_emchar_rune (data); - } - /* Else blow it off because someone added a bad entry and we - don't have any safe way of signaling an error. */ - - /* #### Still need to add any remaining elements to the - propagation information. */ - if (prop) - return prop; - } - } - else if (STRINGP (entry)) + if (STRINGP (entry)) { prop = add_bufbyte_string_runes (data, XSTRING_DATA (entry), @@ -1322,10 +1275,79 @@ add_disp_table_entry_runes (pos_data *data, Lisp_Object entry) data->ch = XCHAR_OR_CHAR_INT (entry); prop = add_emchar_rune (data); } + else if (CONSP (entry)) + { + if (EQ (XCAR (entry), Qformat) + && CONSP (XCDR (entry)) + && STRINGP (XCAR (XCDR (entry)))) + { + Lisp_Object format = XCAR (XCDR (entry)); + Bytind len = XSTRING_LENGTH (format); + Bufbyte *src = XSTRING_DATA (format), *end = src + len; + Bufbyte *result = alloca_array (Bufbyte, len); + Bufbyte *dst = result; + + while (src < end) + { + Emchar c = charptr_emchar (src); + INC_CHARPTR (src); + if (c != '%' || src == end) + dst += set_charptr_emchar (dst, c); + else + { + c = charptr_emchar (src); + INC_CHARPTR (src); + switch (c) + { + /*case 'x': + dst += long_to_string_base ((char *)dst, data->ch, 16); + break;*/ + case '%': + dst += set_charptr_emchar (dst, '%'); + break; + } + } + } + prop = add_bufbyte_string_runes (data, result, dst - result, 0); + } + } /* Else blow it off because someone added a bad entry and we don't - have any safe way of signaling an error. Hey, this comment - sounds familiar. */ + have any safe way of signaling an error. */ + return prop; +} + +/* Given a display table entry, call the appropriate functions to + display each element of the entry. */ + +static prop_block_dynarr * +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); + EMACS_INT len = vector_length (de); + int elt; + + for (elt = 0; elt < len; elt++) + { + if (NILP (vector_data (de)[elt])) + continue; + else + prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]); + /* Else blow it off because someone added a bad entry and we + don't have any safe way of signaling an error. Hey, this + comment sounds familiar. */ + + /* #### Still need to add any remaining elements to the + propagation information. */ + if (prop) + return prop; + } + } + else + prop = add_disp_table_entry_runes_1 (data, entry); return prop; } @@ -1744,14 +1766,14 @@ add_glyph_runes (pos_data *data, int pos_type) static Bytind create_text_block (struct window *w, struct display_line *dl, Bytind bi_start_pos, int start_col, - prop_block_dynarr **prop, int type) + prop_block_dynarr **prop, + int type) { struct frame *f = XFRAME (w->frame); struct buffer *b = XBUFFER (w->buffer); struct device *d = XDEVICE (f->device); pos_data data; - struct Lisp_Vector *dt = 0; /* Don't display anything in the minibuffer if this window is not on a selected frame. We consider all other windows to be active @@ -1784,46 +1806,41 @@ create_text_block (struct window *w, struct display_line *dl, into a more general conversion mechanism. Ideally you could specify a Lisp function that converts characters, but this violates the Second Golden Rule and besides would - make things way way way way slow. An idea I like is to - be able to specify multiple display tables instead of just - one. Each display table can specify conversions for some - characters and leave others unchanged. The way the - character gets displayed is determined by the first display - table with a binding for that character. This way, you - could call a function `enable-hex-display' that adds a - pre-defined hex display-table (or maybe computes one if - you give weird parameters to the function) and adds it - to the list of display tables for the current buffer. - - Unfortunately there are still problems dealing with Mule - characters. For example, maybe I want to specify that - all extended characters (i.e. >= 256) are displayed in hex. - It's not reasonable to create a mapping for all possible - such characters, because there are about 2^19 of them. - One way of dealing with this is to extend the concept - of what a display table is. Currently it's only allowed - to be a 256-entry vector. Instead, it should be something - like: - - a) A 256-entry vector, for backward compatibility - b) Some sort of hash table, mapping characters to values - c) A list that specifies a range of values and the - mapping to provide for those values. - - Also, extend the concept of "mapping" to include a - printf-like spec. Then, you could make all extended - characters show up as hex with a display table like - - ((256 . 524288) . "%x") + make things way way way way slow. + + So instead, we extend the display-table concept, which was + historically limited to 256-byte vectors, to one of the + following: + + a) A 256-entry vector, for backward compatibility; + b) char-table, mapping characters to values; + c) range-table, mapping ranges of characters to values; + d) a list of the above. + + The (d) option allows you to specify multiple display tables + instead of just one. Each display table can specify conversions + for some characters and leave others unchanged. The way the + character gets displayed is determined by the first display table + with a binding for that character. This way, you could call a + function `enable-hex-display' that adds a hex display-table to + the list of display tables for the current buffer. + + #### ...not yet implemented... Also, we extend the concept of + "mapping" to include a printf-like spec. Thus you can make all + extended characters show up as hex with a display table like + this: + + #s(range-table data ((256 524288) (format "%x"))) Since more than one display table is possible, you have - great flexibility in mapping ranges of characters. - */ + great flexibility in mapping ranges of characters. */ Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow) ? XCHAR_OR_CHAR_INT (b->ctl_arrow) : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil)) ? 255 : 160)); + Lisp_Object face_dt, window_dt; + /* The text display block for this display line. */ struct display_block *db = get_display_block_from_line (dl, TEXT); @@ -1962,10 +1979,10 @@ create_text_block (struct window *w, struct display_line *dl, /* Remember that the extent-fragment routines deal in Bytind's. */ extent_fragment_update (w, data.ef, data.bi_bufpos); + get_display_tables (w, data.findex, &face_dt, &window_dt); + if (data.bi_bufpos == data.ef->end) no_more_frags = 1; - - dt = get_display_table (w, data.findex); } initial = 0; @@ -2077,16 +2094,17 @@ create_text_block (struct window *w, struct display_line *dl, else { + Lisp_Object entry = Qnil; /* Get the character at the current buffer position. */ data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos); + if (!NILP (face_dt) || !NILP (window_dt)) + entry = display_table_entry (data.ch, face_dt, window_dt); /* If there is a display table entry for it, hand it off to add_disp_table_entry_runes and let it worry about it. */ - if (dt && !NILP (DISP_CHAR_ENTRY (dt, data.ch))) + if (!NILP (entry) && !EQ (entry, make_char (data.ch))) { - *prop = - add_disp_table_entry_runes (&data, - DISP_CHAR_ENTRY (dt, data.ch)); + *prop = add_disp_table_entry_runes (&data, entry); if (*prop) goto done; @@ -4310,7 +4328,7 @@ regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type) } if (prop) - Dynarr_free (prop); + Dynarr_free (prop); /* #### More not quite right, but close enough. */ /* #### Ben sez: apparently window_end_pos[] is measured @@ -4625,11 +4643,9 @@ regenerate_window_incrementally (struct window *w, Bufpos startp, /* If the changes are below the visible area then if point hasn't moved return success otherwise fail in order to be safe. */ if (line > dla_end) - { - return regenerate_window_extents_only_changed (w, startp, pointm, - extent_beg_unchanged, - extent_end_unchanged); - } + return regenerate_window_extents_only_changed (w, startp, pointm, + extent_beg_unchanged, + extent_end_unchanged); else /* At this point we know what line the changes first affect. We now redraw that line. If the changes are contained within it @@ -4753,12 +4769,9 @@ regenerate_window_incrementally (struct window *w, Bufpos startp, && extent_end_unchanged != -1 && ((extent_beg_unchanged < ddl->bufpos) || (extent_end_unchanged > ddl->end_bufpos))) - { - return - regenerate_window_extents_only_changed (w, startp, pointm, - extent_beg_unchanged, - extent_end_unchanged); - } + return regenerate_window_extents_only_changed (w, startp, pointm, + extent_beg_unchanged, + extent_end_unchanged); else return 1; } @@ -5081,6 +5094,7 @@ redisplay_window (Lisp_Object window, int skip_selected) && !f->extents_changed && !f->faces_changed && !f->glyphs_changed + && !f->subwindows_changed && !f->point_changed && !f->windows_structure_changed) { @@ -5101,6 +5115,7 @@ redisplay_window (Lisp_Object window, int skip_selected) && !f->extents_changed && !f->faces_changed && !f->glyphs_changed + && !f->subwindows_changed && !f->windows_structure_changed) { if (point_visible (w, pointm, CURRENT_DISP) @@ -5158,6 +5173,7 @@ redisplay_window (Lisp_Object window, int skip_selected) && !f->clip_changed && !f->faces_changed && !f->glyphs_changed + && !f->subwindows_changed && !f->windows_structure_changed && !f->frame_changed && !truncation_changed @@ -5237,8 +5253,9 @@ regeneration_done: Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1 ? BUF_ZV (b) : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1); - - update_line_start_cache (w, start, end, pointm, 1); + /* Don't pollute the cache if not sure if we are correct */ + if (w->start_at_line_beg) + update_line_start_cache (w, start, end, pointm, 1); redisplay_output_window (w); /* * If we just displayed the echo area, the line start cache is @@ -5374,7 +5391,11 @@ 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); @@ -5412,7 +5433,20 @@ redisplay_frame (struct frame *f, int preemption_check) /* Erase the frame before outputting its contents. */ if (f->clear) - DEVMETH (d, clear_frame, (f)); + { + DEVMETH (d, clear_frame, (f)); + } + + /* invalidate the subwindow cache. we are going to reuse the glyphs + flag here to cause subwindows to get instantiated. This is + because subwindows changed is less strict - dealing with things + like the clicked state of button. */ + if (!Dynarr_length (f->subwindow_cachels) + || f->glyphs_changed + || f->frame_changed) + reset_subwindow_cachels (f); + else + mark_subwindow_cachels_as_not_updated (f); /* Do the selected window first. */ redisplay_window (FRAME_SELECTED_WINDOW (f), 0); @@ -5434,6 +5468,7 @@ redisplay_frame (struct frame *f, int preemption_check) f->faces_changed = 0; f->frame_changed = 0; f->glyphs_changed = 0; + f->subwindows_changed = 0; f->icon_changed = 0; f->menubar_changed = 0; f->modeline_changed = 0; @@ -5497,7 +5532,7 @@ redisplay_device (struct device *d) f->faces_changed || f->frame_changed || f->menubar_changed || f->modeline_changed || f->point_changed || f->size_changed || f->toolbar_changed || f->windows_changed || f->size_slipped || - f->windows_structure_changed || f->glyphs_changed) + f->windows_structure_changed || f->glyphs_changed || f->subwindows_changed) { preempted = redisplay_frame (f, 0); } @@ -5532,7 +5567,7 @@ redisplay_device (struct device *d) f->modeline_changed || f->point_changed || f->size_changed || f->toolbar_changed || f->windows_changed || f->windows_structure_changed || - f->glyphs_changed) + f->glyphs_changed || f->subwindows_changed) { preempted = redisplay_frame (f, 0); } @@ -5553,6 +5588,7 @@ redisplay_device (struct device *d) d->faces_changed = 0; d->frame_changed = 0; d->glyphs_changed = 0; + d->subwindows_changed = 0; d->icon_changed = 0; d->menubar_changed = 0; d->modeline_changed = 0; @@ -5598,7 +5634,7 @@ redisplay_without_hooks (void) !faces_changed && !frame_changed && !icon_changed && !menubar_changed && !modeline_changed && !point_changed && !size_changed && !toolbar_changed && !windows_changed && - !glyphs_changed && + !glyphs_changed && !subwindows_changed && !windows_structure_changed && !disable_preemption && preemption_count < max_preempts) goto done; @@ -5613,7 +5649,7 @@ redisplay_without_hooks (void) d->menubar_changed || d->modeline_changed || d->point_changed || d->size_changed || d->toolbar_changed || d->windows_changed || d->windows_structure_changed || - d->glyphs_changed) + d->glyphs_changed || d->subwindows_changed) { preempted = redisplay_device (d); @@ -5637,6 +5673,7 @@ redisplay_without_hooks (void) extents_changed = 0; frame_changed = 0; glyphs_changed = 0; + subwindows_changed = 0; icon_changed = 0; menubar_changed = 0; modeline_changed = 0; @@ -6242,7 +6279,7 @@ update_internal_cache_list (struct window *w, int type) else { struct line_start_cache lsc; - + lsc.start = dl->bufpos; lsc.end = dl->end_bufpos; lsc.height = dl->ascent + dl->descent;