X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fredisplay-output.c;h=421acba663c2307f738139c593837d147cae1859;hb=44ea030ec31ae441e59974eb9f6b2a9404611cd8;hp=cfd1d2617be70b16ed5ec91de34172e70cc3b1a8;hpb=3062d425fac0473eb5aa2efc0bb002f6ce0cb028;p=chise%2Fxemacs-chise.git.1 diff --git a/src/redisplay-output.c b/src/redisplay-output.c index cfd1d26..6266fd5 100644 --- a/src/redisplay-output.c +++ b/src/redisplay-output.c @@ -2,7 +2,6 @@ Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. Copyright (C) 1995, 1996 Ben Wing. Copyright (C) 1996 Chuck Thompson. - Copyright (C) 1999 Andy Piper. This file is part of XEmacs. @@ -27,11 +26,9 @@ Boston, MA 02111-1307, USA. */ /* Author: Chuck Thompson */ -/* Heavily hacked for modularity, gutter and subwindow support by Andy - Piper. */ - #include #include "lisp.h" +#include "debug.h" #include "buffer.h" #include "window.h" @@ -40,25 +37,13 @@ Boston, MA 02111-1307, USA. */ #include "glyphs.h" #include "redisplay.h" #include "faces.h" -#include "gutter.h" + +#include "sysdep.h" static int compare_runes (struct window *w, struct rune *crb, struct rune *drb); static void redraw_cursor_in_window (struct window *w, int run_end_begin_glyphs); -static void redisplay_output_display_block (struct window *w, struct display_line *dl, - int block, int start, int end, int start_pixpos, - int cursor_start, int cursor_width, - int cursor_height); -static void redisplay_normalize_display_box (struct display_box* dest, - struct display_glyph_area* src); -static int redisplay_display_boxes_in_window_p (struct window* w, - struct display_box* db, - struct display_glyph_area* dga); -static void redisplay_clear_clipped_region (Lisp_Object locale, face_index findex, - struct display_box* dest, - struct display_glyph_area* glyphsrc, - int fullheight_p, Lisp_Object); /***************************************************************************** sync_rune_structs @@ -102,7 +87,7 @@ sync_rune_structs (struct window *w, rune_dynarr *cra, rune_dynarr *dra) For the given LINE in window W, make the current display line equal the desired display line. ****************************************************************************/ -void +static void sync_display_line_structs (struct window *w, int line, int do_blocks, display_line_dynarr *cdla, display_line_dynarr *ddla) @@ -182,7 +167,7 @@ sync_display_line_structs (struct window *w, int line, int do_blocks, /***************************************************************************** compare_runes - Compare two runes to see if each of their fields is equal. If so, + Compare to runes to see if each of their fields is equal. If so, return true otherwise return false. ****************************************************************************/ static int @@ -191,28 +176,10 @@ compare_runes (struct window *w, struct rune *crb, struct rune *drb) /* Do not compare the values of bufpos and endpos. They do not affect the display characteristics. */ - /* Note: (hanoi 6) spends 95% of its time in redisplay, and about - 30% here. Not using bitfields for rune.type alone gives a redisplay - speed up of 10%. - - #### In profile arcs run of a normal Gnus session this function - is run 6.76 million times, only to return 1 in 6.73 million of - those. - - In addition a quick look GCC sparc assembly shows that GCC is not - doing a good job here. - 1. The function is not inlined (too complicated?) - 2. It seems to be reloading the crb and drb variables all the - time. - 3. It doesn't seem to notice that the second half of these if's - are really a switch statement. - - So I (JV) conjecture - - #### It would really be worth it to arrange for this function to - be (almost) a single call to memcmp. */ - - if (crb->xpos != drb->xpos) + if ((crb->findex != drb->findex) || + (WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) + return 0; + else if (crb->xpos != drb->xpos) return 0; else if (crb->width != drb->width) return 0; @@ -223,78 +190,14 @@ compare_runes (struct window *w, struct rune *crb, struct rune *drb) else if (crb->type == RUNE_CHAR && (crb->object.chr.ch != drb->object.chr.ch)) return 0; - else if (crb->type == RUNE_HLINE && - (crb->object.hline.thickness != drb->object.hline.thickness || - crb->object.hline.yoffset != drb->object.hline.yoffset)) - return 0; else if (crb->type == RUNE_DGLYPH && (!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) || !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) || crb->object.dglyph.xoffset != drb->object.dglyph.xoffset)) return 0; - /* Only check dirtiness if we know something has changed. */ - else if (crb->type == RUNE_DGLYPH && - (XGLYPH_DIRTYP (crb->object.dglyph.glyph) || - crb->findex != drb->findex)) - { - /* We need some way of telling redisplay_output_layout () that the - only reason we are outputting it is because something has - changed internally. That way we can optimize whether we need - to clear the layout first and also only output the components - that have changed. The image_instance dirty flag and - display_hash are no good to us because these will invariably - have been set anyway if the layout has changed. So it looks - like we need yet another change flag that we can set here and - then clear in redisplay_output_layout (). */ - Lisp_Object window, image; - Lisp_Image_Instance* ii; - XSETWINDOW (window, w); - image = glyph_image_instance (crb->object.dglyph.glyph, - window, ERROR_ME_NOT, 1); - - if (!IMAGE_INSTANCEP (image)) - return 0; - ii = XIMAGE_INSTANCE (image); - - if (TEXT_IMAGE_INSTANCEP (image) && - (crb->findex != drb->findex || - WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) - return 0; - - /* It is quite common for the two glyphs to be EQ since in many - cases they will actually be the same object. This does not - mean, however, that nothing has changed. We therefore need to - check the current hash of the glyph against the last recorded - display hash and the pending display items. See - update_subwindow (). */ - if (image_instance_changed (image) || - crb->findex != drb->findex || - WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)) - { - /* We now now we are going to re-output the glyph, but since - this is for some internal reason not related to geometry - changes, send a hint to the output routines that they can - take some short cuts. This is most useful for - layouts. This flag should get reset by the output - routines. - - #### It is possible for us to get here when the - face_cachel is dirty. I do not know what the implications - of this are.*/ - IMAGE_INSTANCE_OPTIMIZE_OUTPUT (ii) = 1; - return 0; - } - else - return 1; - } - /* We now do this last so that glyph checks can do their own thing - for face changes. Face changes quite often happen when we are - trying to output something in the gutter, this would normally - lead to a lot of flashing. The indices can quite often be - different and yet the faces are the same, we do not want to - re-output in this instance. */ - else if (crb->findex != drb->findex || - WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)) + else if (crb->type == RUNE_HLINE && + (crb->object.hline.thickness != drb->object.hline.thickness || + crb->object.hline.yoffset != drb->object.hline.yoffset)) return 0; else return 1; @@ -402,6 +305,8 @@ compare_display_blocks (struct window *w, struct display_line *cdl, int cursor_height) { struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); + struct display_block *cdb, *ddb; int start_pos; int stop_pos; @@ -447,14 +352,8 @@ compare_display_blocks (struct window *w, struct display_line *cdl, force = 1; if (f->windows_structure_changed || - /* #### Why is this so? We have face cachels so that we don't - have to recalculate all the display blocks when faces - change. I have fixed this for glyphs and am inclined to think - that faces should "Just Work", but I'm not feeling brave - today. Maybe its because the face cachels represent merged - faces rather than simply instantiations in a particular - domain. */ f->faces_changed || + f->glyphs_changed || cdl->ypos != ddl->ypos || cdl->ascent != ddl->ascent || cdl->descent != ddl->descent || @@ -517,10 +416,10 @@ compare_display_blocks (struct window *w, struct display_line *cdl, stop_pos = elt + 1; } - redisplay_output_display_block (w, ddl, d_block, start_pos, - stop_pos, start_pixpos, - cursor_start, cursor_width, - cursor_height); + DEVMETH (d, output_display_block, (w, ddl, d_block, start_pos, + stop_pos, start_pixpos, + cursor_start, cursor_width, + cursor_height)); return 1; } @@ -536,12 +435,13 @@ static void clear_left_border (struct window *w, int y, int height) { struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); Lisp_Object window; XSETWINDOW (window, w); - redisplay_clear_region (window, DEFAULT_INDEX, - FRAME_LEFT_BORDER_START (f), y, - FRAME_BORDER_WIDTH (f), height); + DEVMETH (d, clear_region, (window, DEFAULT_INDEX, + FRAME_LEFT_BORDER_START (f), y, + FRAME_BORDER_WIDTH (f), height)); } /***************************************************************************** @@ -553,12 +453,13 @@ static void clear_right_border (struct window *w, int y, int height) { struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); Lisp_Object window; XSETWINDOW (window, w); - redisplay_clear_region (window, DEFAULT_INDEX, - FRAME_RIGHT_BORDER_START (f), - y, FRAME_BORDER_WIDTH (f), height); + DEVMETH (d, clear_region, (window, DEFAULT_INDEX, + FRAME_RIGHT_BORDER_START (f), + y, FRAME_BORDER_WIDTH (f), height)); } /***************************************************************************** @@ -575,6 +476,7 @@ output_display_line (struct window *w, display_line_dynarr *cdla, { struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); struct buffer *b = XBUFFER (w->buffer); struct buffer *old_b = window_display_buffer (w); struct display_line *cdl, *ddl; @@ -636,7 +538,7 @@ output_display_line (struct window *w, display_line_dynarr *cdla, a TEXT block. */ if (ddl->modeline) { - /* The shadow thickness check is necessary if only the sign of + /* The shadow thickness check is necesssary if only the sign of the size changed. */ if (cdba && !w->shadow_thickness_changed) { @@ -645,8 +547,8 @@ output_display_line (struct window *w, display_line_dynarr *cdla, } else { - redisplay_output_display_block (w, ddl, 0, 0, -1, start_pixpos, - 0, 0, 0); + DEVMETH (d, output_display_block, (w, ddl, 0, 0, -1, start_pixpos, + 0, 0, 0)); must_sync = 1; } @@ -691,46 +593,37 @@ output_display_line (struct window *w, display_line_dynarr *cdla, (cdl && (cdl->ypos != ddl->ypos || cdl->ascent != ddl->ascent || cdl->descent != ddl->descent || - cdl->top_clip != ddl->top_clip || cdl->clip != ddl->clip))) { int x, y, width, height; - face_index findex; + Lisp_Object face; must_sync = 1; x = start_pixpos; - y = DISPLAY_LINE_YPOS (ddl); + y = ddl->ypos - ddl->ascent; width = min (next_start_pixpos, block_end) - x; - height = DISPLAY_LINE_HEIGHT (ddl); + height = ddl->ascent + ddl->descent - ddl->clip; if (x < ddl->bounds.left_in) - { - findex = ddl->left_margin_findex ? - ddl->left_margin_findex - : get_builtin_face_cache_index (w, Vleft_margin_face); - } + face = Vleft_margin_face; else if (x < ddl->bounds.right_in) - { - /* no check here because DEFAULT_INDEX == 0 anyway */ - findex = ddl->default_findex; - } + face = Vdefault_face; else if (x < ddl->bounds.right_out) - { - findex = ddl->right_margin_findex ? - ddl->right_margin_findex - : get_builtin_face_cache_index (w, Vright_margin_face); - } + face = Vright_margin_face; else - findex = (face_index) -1; + face = Qnil; - if (findex != (face_index) -1) + if (!NILP (face)) { Lisp_Object window; XSETWINDOW (window, w); /* Clear the empty area. */ - redisplay_clear_region (window, findex, x, y, width, height); + DEVMETH (d, clear_region, + (window, get_builtin_face_cache_index (w, + face), + x, y, width, height)); /* Mark that we should clear the border. This is necessary because italic fonts may leave @@ -761,11 +654,7 @@ output_display_line (struct window *w, display_line_dynarr *cdla, region or if it was a block of a different type, then output the entire ddb. Otherwise, compare cdb and ddb and output only the changed region. */ - if (!force && cdb && ddb->type == cdb->type - /* If there was no buffer being display before the - compare anyway as we might be outputting a gutter. */ - && - (b == old_b || !old_b)) + if (!force && cdb && ddb->type == cdb->type && b == old_b) { must_sync |= compare_display_blocks (w, cdl, ddl, old_block, block, start_pixpos, @@ -797,11 +686,11 @@ output_display_line (struct window *w, display_line_dynarr *cdla, } must_sync = 1; - redisplay_output_display_block (w, ddl, block, first_elt, - last_elt, - start_pixpos, - cursor_start, cursor_width, - cursor_height); + DEVMETH (d, output_display_block, (w, ddl, block, first_elt, + last_elt, + start_pixpos, + cursor_start, cursor_width, + cursor_height)); } start_pixpos = next_start_pixpos; @@ -816,23 +705,19 @@ output_display_line (struct window *w, display_line_dynarr *cdla, if (f->windows_structure_changed || f->faces_changed || clear_border || f->clear) { - int y = DISPLAY_LINE_YPOS (ddl); - int height = DISPLAY_LINE_HEIGHT (ddl); + int y = ddl->ypos - ddl->ascent; + int height = ddl->ascent + ddl->descent - ddl->clip; - /* If we are in the gutter then we musn't clear the borders. */ - if (y >= WINDOW_TEXT_TOP (w) && (y + height) <= WINDOW_TEXT_BOTTOM (w)) + if (ddl->modeline) { - if (ddl->modeline) - { - y -= MODELINE_SHADOW_THICKNESS (w); - height += (2 * MODELINE_SHADOW_THICKNESS (w)); - } - - if (window_is_leftmost (w)) - clear_left_border (w, y, height); - if (window_is_rightmost (w)) - clear_right_border (w, y, height); + y -= MODELINE_SHADOW_THICKNESS (w); + height += (2 * MODELINE_SHADOW_THICKNESS (w)); } + + if (window_is_leftmost (w)) + clear_left_border (w, y, height); + if (window_is_rightmost (w)) + clear_right_border (w, y, height); } if (cdla) @@ -899,11 +784,16 @@ redisplay_move_cursor (struct window *w, Bufpos new_point, int no_output_end) } else { - { - MAYBE_DEVMETH (d, frame_output_begin, (f)); - MAYBE_DEVMETH (d, window_output_begin, (w)); - } - rb->cursor_type = CURSOR_OFF; + DEVMETH (d, output_begin, (d)); + + /* #### This is a gross kludge. Cursor handling is such a royal + pain in the ass. */ + if (rb->type == RUNE_DGLYPH && + (EQ (rb->object.dglyph.glyph, Vtruncation_glyph) || + EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))) + rb->cursor_type = NO_CURSOR; + else + rb->cursor_type = CURSOR_OFF; dl->cursor_elt = -1; output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); } @@ -917,10 +807,7 @@ redisplay_move_cursor (struct window *w, Bufpos new_point, int no_output_end) if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d)))) { if (!no_output_end) - { - MAYBE_DEVMETH (d, window_output_end, (w)); - MAYBE_DEVMETH (d, frame_output_end, (f)); - } + DEVMETH (d, output_end, (d)); return 1; } @@ -939,10 +826,7 @@ redisplay_move_cursor (struct window *w, Bufpos new_point, int no_output_end) output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); if (!no_output_end) - { - MAYBE_DEVMETH (d, window_output_end, (w)); - MAYBE_DEVMETH (d, frame_output_end, (f)); - } + DEVMETH (d, output_end, (d)); return 1; } else @@ -974,7 +858,7 @@ redisplay_move_cursor (struct window *w, Bufpos new_point, int no_output_end) } } - while (up ? (cur_dl < Dynarr_length (cla)) : (cur_dl >= 0)) + while ((up ? (cur_dl < Dynarr_length (cla)) : (cur_dl >= 0))) { dl = Dynarr_atp (cla, cur_dl); db = get_display_block_from_line (dl, TEXT); @@ -1006,10 +890,7 @@ redisplay_move_cursor (struct window *w, Bufpos new_point, int no_output_end) make_int (ADJ_BUFPOS), w->buffer); if (!no_output_end) - { - MAYBE_DEVMETH (d, window_output_end, (w)); - MAYBE_DEVMETH (d, frame_output_end, (f)); - } + DEVMETH (d, output_end, (d)); return 1; } @@ -1022,10 +903,7 @@ redisplay_move_cursor (struct window *w, Bufpos new_point, int no_output_end) } if (!no_output_end) - { - MAYBE_DEVMETH (d, window_output_end, (w)); - MAYBE_DEVMETH (d, frame_output_end, (f)); - } + DEVMETH (d, output_end, (d)); return 0; } #undef ADJ_BUFPOS @@ -1080,18 +958,12 @@ redraw_cursor_in_window (struct window *w, int run_end_begin_meths) (f, dl->ypos - 1, rb->xpos)); if (run_end_begin_meths) - { - MAYBE_DEVMETH (d, frame_output_begin, (f)); - MAYBE_DEVMETH (d, window_output_begin, (w)); - } + DEVMETH (d, output_begin, (d)); output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width); if (run_end_begin_meths) - { - MAYBE_DEVMETH (d, window_output_end, (w)); - MAYBE_DEVMETH (d, frame_output_end, (f)); - } + DEVMETH (d, output_end, (d)); } } @@ -1116,806 +988,12 @@ redisplay_redraw_cursor (struct frame *f, int run_end_begin_meths) redraw_cursor_in_window (XWINDOW (window), run_end_begin_meths); } -/**************************************************************************** - redisplay_output_display_block - - Given a display line, a block number for that start line, output all - runes between start and end in the specified display block. - ****************************************************************************/ -static void -redisplay_output_display_block (struct window *w, struct display_line *dl, int block, - int start, int end, int start_pixpos, int cursor_start, - int cursor_width, int cursor_height) -{ - struct frame *f = XFRAME (w->frame); - struct device *d = XDEVICE (f->device); - /* Temporarily disabled until generalization is done. */ -#if 0 - struct display_block *db = Dynarr_atp (dl->display_blocks, block); - rune_dynarr *rba = db->runes; - struct rune *rb; - int xpos, width; - rb = Dynarr_atp (rba, start); - - if (!rb) - /* Nothing to do so don't do anything. */ - return; - - xpos = max (start_pixpos, rb->xpos); - - if (end < 0) - end = Dynarr_length (rba); - - rb = Dynarr_atp (rba, end - 1); - width = rb->xpos + rb->width - xpos; -#endif - /* now actually output the block. */ - DEVMETH (d, output_display_block, (w, dl, block, start, - end, start_pixpos, - cursor_start, cursor_width, - cursor_height)); -} - -/**************************************************************************** - redisplay_unmap_subwindows - - Remove subwindows from the area in the box defined by the given - parameters. - ****************************************************************************/ -static void -redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height, - Lisp_Object ignored_window) -{ - Lisp_Object rest; - - LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) - { - Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest)); - if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) - && - IMAGE_INSTANCE_DISPLAY_X (ii) - + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) > x - && - IMAGE_INSTANCE_DISPLAY_X (ii) < x + width - && - IMAGE_INSTANCE_DISPLAY_Y (ii) - + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) > y - && - IMAGE_INSTANCE_DISPLAY_Y (ii) < y + height - && - !EQ (XCAR (rest), ignored_window)) - { - unmap_subwindow (XCAR (rest)); - } - } -} - -/**************************************************************************** - redisplay_unmap_subwindows_maybe - - Potentially subwindows from the area in the box defined by the given - parameters. - ****************************************************************************/ -void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height) -{ - if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))) - { - redisplay_unmap_subwindows (f, x, y, width, height, Qnil); - } -} - -static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width, - int height, Lisp_Object subwindow) -{ - if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))) - { - redisplay_unmap_subwindows (f, x, y, width, height, subwindow); - } -} - -/**************************************************************************** - redisplay_output_subwindow - - output a subwindow. This code borrows heavily from the pixmap stuff, - although is much simpler not needing to account for partial - pixmaps, backgrounds etc. - ****************************************************************************/ -void -redisplay_output_subwindow (struct window *w, - Lisp_Object image_instance, - struct display_box* db, struct display_glyph_area* dga, - face_index findex, int cursor_start, int cursor_width, - int cursor_height) -{ - Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); - Lisp_Object window; - struct display_glyph_area sdga; - - dga->height = IMAGE_INSTANCE_HEIGHT (p); - dga->width = IMAGE_INSTANCE_WIDTH (p); - - /* The first thing we are going to do is update the display - characteristics of the subwindow. This also clears the dirty - flags as a side effect. */ - redisplay_subwindow (image_instance); - - /* This makes the glyph area fit into the display area. */ - if (!redisplay_normalize_glyph_area (db, dga)) - return; - - XSETWINDOW (window, w); - - /* Clear the area the subwindow is going into. */ - redisplay_clear_clipped_region (window, findex, - db, dga, 0, image_instance); - - /* This shrinks the display box to exactly enclose the glyph - area. */ - redisplay_normalize_display_box (db, dga); - - /* if we can't view the whole window we can't view any of it. We - have to be careful here since we may be being asked to display - part of a subwindow, the rest of which is on-screen as well. We - need to allow this case and map the entire subwindow. We also - need to be careful since the subwindow could be outside the - window in the gutter or modeline - we also need to allow these - cases.*/ - sdga.xoffset = -dga->xoffset; - sdga.yoffset = -dga->yoffset; - sdga.height = IMAGE_INSTANCE_HEIGHT (p); - sdga.width = IMAGE_INSTANCE_WIDTH (p); - - if (redisplay_display_boxes_in_window_p (w, db, &sdga) == 0 - || - /* We only want to do full subwindow display for windows that - are completely in the gutter, otherwise we must clip to be - safe. */ - display_boxes_in_gutter_p (XFRAME (w->frame), db, &sdga) <= 0) - { - map_subwindow (image_instance, db->xpos, db->ypos, dga); - } - else - { - sdga.xoffset = sdga.yoffset = 0; - map_subwindow (image_instance, db->xpos - dga->xoffset, - db->ypos - dga->yoffset, &sdga); - } -} - -/**************************************************************************** - redisplay_output_layout - - Output a widget hierarchy. This can safely call itself recursively. - - The complexity of outputting layouts is deciding whether to do it or - not. Consider a layout enclosing some text, the text changes and is - marked as dirty, but the enclosing layout has not been marked as - dirty so no updates occur and the text will potentially be truncated. - Alternatively we hold a back pointer in the image instance to the - parent and mark the parent as dirty. But the layout code assumes that - if the layout is dirty then the whole layout should be redisplayed, - so we then get lots of flashing even though only the text has changed - size. Of course if the text shrinks in size then we do actually need - to redisplay the layout to repaint the exposed area. So what happens - if we make a non-structural change like changing color? Either we - redisplay everything, or we redisplay nothing. These are exactly the - issues lwlib has to grapple with. We really need to know what has - actually changed and make a layout decision based on that. We also - really need to know what has changed so that we can only make the - necessary changes in update_subwindow. This has all now been - implemented, Viva la revolution! - ****************************************************************************/ -void -redisplay_output_layout (Lisp_Object domain, - Lisp_Object image_instance, - struct display_box* db, struct display_glyph_area* dga, - face_index findex, int cursor_start, int cursor_width, - int cursor_height) -{ - Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); - Lisp_Object rest, window = DOMAIN_WINDOW (domain); - Emchar_dynarr *buf = Dynarr_new (Emchar); - struct window *w = XWINDOW (window); - struct device *d = DOMAIN_XDEVICE (domain); - int layout_height, layout_width; - - layout_height = glyph_height (image_instance, domain); - layout_width = glyph_width (image_instance, domain); - - dga->height = layout_height; - dga->width = layout_width; -#ifdef DEBUG_WIDGET_OUTPUT - printf ("outputing layout glyph %p\n", p); -#endif - /* This makes the glyph area fit into the display area. */ - if (!redisplay_normalize_glyph_area (db, dga)) - return; - - /* Highly dodgy optimization. We want to only output the whole - layout if we really have to. */ - if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p) - || IMAGE_INSTANCE_LAYOUT_CHANGED (p) - || IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) - || IMAGE_INSTANCE_SIZE_CHANGED (p) - || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) - { - /* First clear the area we are drawing into. This is the easiest - thing to do since we have many gaps that we have to make sure are - filled in. */ - redisplay_clear_clipped_region (window, findex, db, dga, 1, Qnil); - - /* Output a border if required */ - if (!NILP (IMAGE_INSTANCE_LAYOUT_BORDER (p))) - { - int edges = 0; - enum edge_style style; - int ypos = db->ypos; - int height = dga->height; - - if (dga->xoffset >= 0) - edges |= EDGE_LEFT; - if (dga->width - dga->xoffset == layout_width) - edges |= EDGE_RIGHT; - if (dga->yoffset >= 0) - edges |= EDGE_TOP; - if (dga->height - dga->yoffset == layout_height) - edges |= EDGE_BOTTOM; - - if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_in)) - style = EDGE_ETCHED_IN; - else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_out)) - style = EDGE_ETCHED_OUT; - else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qbevel_in)) - style = EDGE_BEVEL_IN; - else if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (p))) - { - style = EDGE_ETCHED_IN; - if (edges & EDGE_TOP) - { - ypos += XINT (IMAGE_INSTANCE_LAYOUT_BORDER (p)); - height -= XINT (IMAGE_INSTANCE_LAYOUT_BORDER (p)); - } - } - else - style = EDGE_BEVEL_OUT; - - MAYBE_DEVMETH (d, bevel_area, - (w, findex, db->xpos, - ypos, - dga->width, height, 2, edges, style)); - } - } - - /* This shrinks the display box to exactly enclose the glyph - area. */ - redisplay_normalize_display_box (db, dga); - - /* Flip through the widgets in the layout displaying as necessary */ - LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p)) - { - Lisp_Object child = glyph_image_instance (XCAR (rest), image_instance, - ERROR_ME_NOT, 1); - - struct display_box cdb; - /* For losing HP-UX */ - cdb.xpos = db->xpos; - cdb.ypos = db->ypos; - cdb.width = db->width; - cdb.height = db->height; - - /* First determine if the image is visible at all */ - if (IMAGE_INSTANCEP (child)) - { - Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child); - - /* The enclosing layout offsets are +ve at this point */ - struct display_glyph_area cdga; - cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset; - cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset; - cdga.width = glyph_width (child, image_instance); - cdga.height = glyph_height (child, image_instance); - - IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = - IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p); - - /* Although normalization is done by the output routines - we have to do it here so that they don't try and - clear all of db. This is true below also. */ - if (redisplay_normalize_glyph_area (&cdb, &cdga)) - { - redisplay_normalize_display_box (&cdb, &cdga); - /* Since the display boxes will now be totally in the - window if they are visible at all we can now check this easily. */ - if (cdb.xpos < db->xpos || cdb.ypos < db->ypos - || cdb.xpos + cdb.width > db->xpos + db->width - || cdb.ypos + cdb.height > db->ypos + db->height) - continue; - /* We have to invert the offset here as normalization - will have made them positive which the output - routines will treat as a truly +ve offset. */ - cdga.xoffset = -cdga.xoffset; - cdga.yoffset = -cdga.yoffset; - - switch (IMAGE_INSTANCE_TYPE (childii)) - { - case IMAGE_TEXT: - { - /* #### This is well hacked and could use some - generalisation.*/ - if (redisplay_normalize_glyph_area (&cdb, &cdga) - && - (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || - IMAGE_INSTANCE_DIRTYP (childii))) - { - struct display_line dl; /* this is fake */ - Lisp_Object string = - IMAGE_INSTANCE_TEXT_STRING (childii); - unsigned char charsets[NUM_LEADING_BYTES]; - struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); - - find_charsets_in_bufbyte_string (charsets, - XSTRING_DATA (string), - XSTRING_LENGTH (string)); - ensure_face_cachel_complete (cachel, window, charsets); - - convert_bufbyte_string_into_emchar_dynarr - (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); - - redisplay_normalize_display_box (&cdb, &cdga); - /* Offsets are now +ve again so be careful - when fixing up the display line. */ - xzero (dl); - /* Munge boxes into display lines. */ - dl.ypos = (cdb.ypos - cdga.yoffset) - + glyph_ascent (child, image_instance); - dl.ascent = glyph_ascent (child, image_instance); - dl.descent = glyph_descent (child, image_instance); - dl.top_clip = cdga.yoffset; - dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height); - /* output_string doesn't understand offsets in - the same way as other routines - we have to - add the offset to the width so that we - output the full string. */ - MAYBE_DEVMETH (d, output_string, (w, &dl, buf, cdb.xpos, - cdga.xoffset, cdb.xpos, - cdga.width + cdga.xoffset, - findex, 0, 0, 0, 0)); - Dynarr_reset (buf); - } - } - break; - - case IMAGE_MONO_PIXMAP: - case IMAGE_COLOR_PIXMAP: - if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) - || IMAGE_INSTANCE_DIRTYP (childii)) - redisplay_output_pixmap (w, child, &cdb, &cdga, findex, - 0, 0, 0, 0); - break; - - case IMAGE_WIDGET: - if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (childii), Qlayout)) - { - redisplay_output_layout (image_instance, child, &cdb, &cdga, findex, - 0, 0, 0); - break; - } - case IMAGE_SUBWINDOW: - if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || - IMAGE_INSTANCE_DIRTYP (childii)) - redisplay_output_subwindow (w, child, &cdb, &cdga, findex, - 0, 0, 0); - break; - - case IMAGE_NOTHING: - /* nothing is as nothing does */ - break; - - case IMAGE_POINTER: - default: - abort (); - } - } - IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = 0; - } - } - - /* Update any display properties. I'm not sure whether this actually - does anything for layouts except clear the changed flags. */ - redisplay_subwindow (image_instance); - - Dynarr_free (buf); -} - -/**************************************************************************** - redisplay_output_pixmap - - - output a pixmap. - ****************************************************************************/ -void -redisplay_output_pixmap (struct window *w, - Lisp_Object image_instance, - struct display_box* db, struct display_glyph_area* dga, - face_index findex, int cursor_start, int cursor_width, - int cursor_height, int offset_bitmap) -{ - struct frame *f = XFRAME (w->frame); - struct device *d = XDEVICE (f->device); - Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); - Lisp_Object window; - XSETWINDOW (window, w); - - dga->height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); - dga->width = IMAGE_INSTANCE_PIXMAP_WIDTH (p); - - /* This makes the glyph area fit into the display area. */ - if (!redisplay_normalize_glyph_area (db, dga)) - return; - - /* Clear the area the pixmap is going into. The pixmap itself will - always take care of the full width. We don't want to clear where - it is going to go in order to avoid flicker. So, all we have to - take care of is any area above or below the pixmap. If the pixmap - has a mask in which case we have to clear the whole damn thing - since we can't yet clear just the area not included in the - mask. */ - if (!offset_bitmap) - { - redisplay_clear_clipped_region (window, findex, - db, dga, - (IMAGE_INSTANCE_PIXMAP_MASK (p) != 0), - Qnil); - - /* This shrinks the display box to exactly enclose the glyph - area. */ - redisplay_normalize_display_box (db, dga); - } - assert (db->xpos >= 0 && db->ypos >= 0); - - MAYBE_DEVMETH (d, output_pixmap, (w, image_instance, - db, dga, - findex, cursor_start, - cursor_width, cursor_height, - offset_bitmap)); -} - -/**************************************************************************** - redisplay_clear_region - - Clear the area in the box defined by the given parameters using the - given face. This has been generalised so that subwindows can be - coped with effectively. - ****************************************************************************/ -void -redisplay_clear_region (Lisp_Object locale, face_index findex, int x, int y, - int width, int height) -{ - struct window *w = NULL; - struct frame *f = NULL; - struct device *d; - Lisp_Object background_pixmap = Qunbound; - Lisp_Object fcolor = Qnil, bcolor = Qnil; - - if (!width || !height) - return; - - if (WINDOWP (locale)) - { - w = XWINDOW (locale); - f = XFRAME (w->frame); - } - else if (FRAMEP (locale)) - { - w = NULL; - f = XFRAME (locale); - } - else - abort (); - - d = XDEVICE (f->device); - - /* if we have subwindows in the region we have to unmap them */ - redisplay_unmap_subwindows_maybe (f, x, y, width, height); - - /* #### This isn't quite right for when this function is called - from the toolbar code. */ - - /* Don't use a backing pixmap in the border area */ - if (x >= FRAME_LEFT_BORDER_END (f) - && x < FRAME_RIGHT_BORDER_START (f) - && y >= FRAME_TOP_BORDER_END (f) - && y < FRAME_BOTTOM_BORDER_START (f)) - { - Lisp_Object temp; - - if (w) - { - temp = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, findex); - - if (IMAGE_INSTANCEP (temp) - && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp))) - { - /* #### maybe we could implement such that a string - can be a background pixmap? */ - background_pixmap = temp; - } - } - else - { - temp = FACE_BACKGROUND_PIXMAP (Vdefault_face, locale); - - if (IMAGE_INSTANCEP (temp) - && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp))) - { - background_pixmap = temp; - } - } - } - - if (!UNBOUNDP (background_pixmap) && - XIMAGE_INSTANCE_PIXMAP_DEPTH (background_pixmap) == 0) - { - if (w) - { - fcolor = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); - bcolor = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); - } - else - { - fcolor = FACE_FOREGROUND (Vdefault_face, locale); - bcolor = FACE_BACKGROUND (Vdefault_face, locale); - } - } - else - { - fcolor = (w ? - WINDOW_FACE_CACHEL_BACKGROUND (w, findex) : - FACE_BACKGROUND (Vdefault_face, locale)); - - } - - if (UNBOUNDP (background_pixmap)) - background_pixmap = Qnil; - - DEVMETH (d, clear_region, - (locale, d, f, findex, x, y, width, height, fcolor, bcolor, background_pixmap)); -} - -/**************************************************************************** - redisplay_clear_clipped_region - - Clear the area in the dest display_box not covered by the src - display_glyph_area using the given face. This is a common occurrence - for images shorter than the display line. Clipping can be played - around with by altering these. glyphsrc should be normalized. - ****************************************************************************/ -static void -redisplay_clear_clipped_region (Lisp_Object window, face_index findex, - struct display_box* dest, struct display_glyph_area* glyphsrc, - int fullheight_p, Lisp_Object ignored_subwindow) -{ - /* assume dest->xpos >= 0 */ - int clear_x; - struct frame* f = XFRAME (XWINDOW (window)->frame); - - if (glyphsrc->xoffset > 0) - { - clear_x = dest->xpos + glyphsrc->xoffset; - } - else - { - clear_x = dest->xpos; - } - - /* If we need the whole height cleared then just do it. */ - if (fullheight_p) - { - redisplay_clear_region (window, findex, clear_x, dest->ypos, - glyphsrc->width, dest->height); - } - else - { - int yoffset = (glyphsrc->yoffset > 0 ? glyphsrc->yoffset : 0); - - /* We need to make sure that subwindows are unmapped from the - whole area. */ - redisplay_unmap_subwindows_except_us (f, clear_x, dest->ypos, - glyphsrc->width, dest->height, - ignored_subwindow); - /* first the top box */ - if (yoffset > 0) - { - redisplay_clear_region (window, findex, clear_x, dest->ypos, - glyphsrc->width, yoffset); - - } - /* Then the bottom box */ - if (yoffset + glyphsrc->height < dest->height) - { - redisplay_clear_region (window, findex, clear_x, - dest->ypos + yoffset + glyphsrc->height, - glyphsrc->width, - dest->height - (yoffset + glyphsrc->height)); - - } - } -} - -/***************************************************************************** - redisplay_normalize_glyph_area - redisplay_normalize_display_box - - Calculate the visible box for displaying src in dest. - ****************************************************************************/ -int -redisplay_normalize_glyph_area (struct display_box* dest, - struct display_glyph_area* glyphsrc) -{ - if (dest->xpos + glyphsrc->xoffset > dest->xpos + dest->width - || - dest->ypos + glyphsrc->yoffset > dest->ypos + dest->height - || - -glyphsrc->xoffset >= glyphsrc->width - || - -glyphsrc->yoffset >= glyphsrc->height - || - /* #### Not sure why this wasn't coped with before but normalizing - to zero width or height is definitely wrong. */ - (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width - && - dest->width - glyphsrc->xoffset <= 0) - || - (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height - && - dest->height - glyphsrc->yoffset <= 0)) - { - /* It's all clipped out */ - return 0; - } - - /* Horizontal offsets. This works because xoffset can be -ve as well as +ve */ - if (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width) - { - if (glyphsrc->xoffset > 0) - glyphsrc->width = dest->width - glyphsrc->xoffset; - else - glyphsrc->width = dest->width; - } - - if (glyphsrc->xoffset < 0) - glyphsrc->width += glyphsrc->xoffset; - - /* Vertical offsets. This works because yoffset can be -ve as well as +ve */ - if (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height) - { - if (glyphsrc->yoffset > 0) - glyphsrc->height = dest->height - glyphsrc->yoffset; - else - glyphsrc->height = dest->height; - } - - if (glyphsrc->yoffset < 0) - glyphsrc->height += glyphsrc->yoffset; - - return 1; -} - -static void -redisplay_normalize_display_box (struct display_box* dest, - struct display_glyph_area* glyphsrc) -{ - /* Adjust the destination area. At the end of this the destination - area will exactly enclose the glyph area. The only remaining - adjustment will be offsets into the glyph area. */ - - /* Horizontal adjustment. */ - if (glyphsrc->xoffset > 0) - { - dest->xpos += glyphsrc->xoffset; - dest->width -= glyphsrc->xoffset; - glyphsrc->xoffset = 0; - } - else - glyphsrc->xoffset = -glyphsrc->xoffset; - - if (glyphsrc->width < dest->width) - dest->width = glyphsrc->width; - - /* Vertical adjustment. */ - if (glyphsrc->yoffset > 0) - { - dest->ypos += glyphsrc->yoffset; - dest->height -= glyphsrc->yoffset; - glyphsrc->yoffset = 0; - } - else - glyphsrc->yoffset = -glyphsrc->yoffset; - - if (glyphsrc->height < dest->height) - dest->height = glyphsrc->height; -} - -/***************************************************************************** - redisplay_display_boxes_in_window_p - - Determine whether the required display_glyph_area is completely inside - the window. -1 means the display_box is not in the window. 1 means the - display_box and the display_glyph_area are in the window. 0 means - the display_box is in the window but the display_glyph_area is not. - ****************************************************************************/ -static int -redisplay_display_boxes_in_window_p (struct window* w, - struct display_box* db, - struct display_glyph_area* dga) -{ - int left = WINDOW_TEXT_LEFT (w); - int right = WINDOW_TEXT_RIGHT (w); - int top = WINDOW_TEXT_TOP (w); - int bottom = WINDOW_TEXT_BOTTOM (w); - - if (db->xpos < left || db->ypos < top - || db->xpos + db->width > right - || db->ypos + db->height > bottom) - /* We are not displaying in a window at all */ - return -1; - - if (db->xpos + dga->xoffset >= left - && - db->ypos + dga->yoffset >= top - && - db->xpos + dga->xoffset + dga->width <= right - && - db->ypos + dga->yoffset + dga->height <= bottom) - return 1; - - return 0; -} - -/***************************************************************************** - redisplay_calculate_display_boxes - - Convert from rune/display_line co-ordinates to display_box - co-ordinates. - ****************************************************************************/ -int -redisplay_calculate_display_boxes (struct display_line *dl, int xpos, - int xoffset, int start_pixpos, int width, - struct display_box* dest, - struct display_glyph_area* src) -{ - dest->xpos = xpos; - dest->ypos = DISPLAY_LINE_YPOS (dl); - dest->width = width; - dest->height = DISPLAY_LINE_HEIGHT (dl); - - src->xoffset = -xoffset; - src->yoffset = -dl->top_clip; - src->width = 0; - src->height = 0; - - if (start_pixpos >=0 && start_pixpos > xpos) - { - /* Oops, we're asking for a start outside of the displayable - area. */ - if (start_pixpos > xpos + width) - return 0; - dest->xpos = start_pixpos; - dest->width -= (start_pixpos - xpos); - /* Offsets are -ve when we want to clip pixels off the displayed - glyph. */ - src->xoffset -= (start_pixpos - xpos); - } - - return 1; -} - /***************************************************************************** redisplay_clear_top_of_window If window is topmost, clear the internal border above it. ****************************************************************************/ -void +static void redisplay_clear_top_of_window (struct window *w) { Lisp_Object window; @@ -1924,6 +1002,7 @@ redisplay_clear_top_of_window (struct window *w) if (!NILP (Fwindow_highest_p (window))) { struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); int x, y, width, height; x = w->pixel_left; @@ -1940,64 +1019,7 @@ redisplay_clear_top_of_window (struct window *w) y = FRAME_TOP_BORDER_START (f) - 1; height = FRAME_BORDER_HEIGHT (f) + 1; - redisplay_clear_region (window, DEFAULT_INDEX, x, y, width, height); - } -} - -/***************************************************************************** - redisplay_clear_to_window_end - - Clear the area between ypos1 and ypos2. Each margin area and the - text area is handled separately since they may each have their own - background color. - ****************************************************************************/ -void -redisplay_clear_to_window_end (struct window *w, int ypos1, int ypos2) -{ - struct frame *f = XFRAME (w->frame); - struct device *d = XDEVICE (f->device); - - if (HAS_DEVMETH_P (d, clear_to_window_end)) - DEVMETH (d, clear_to_window_end, (w, ypos1, ypos2)); - else - { - int height = ypos2 - ypos1; - - if (height) - { - Lisp_Object window; - int bflag = 0 ; /* (window_needs_vertical_divider (w) ? 0 : 1);*/ - layout_bounds bounds; - - bounds = calculate_display_line_boundaries (w, bflag); - XSETWINDOW (window, w); - - if (window_is_leftmost (w)) - redisplay_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f), - ypos1, FRAME_BORDER_WIDTH (f), height); - - if (bounds.left_in - bounds.left_out > 0) - redisplay_clear_region (window, - get_builtin_face_cache_index (w, Vleft_margin_face), - bounds.left_out, ypos1, - bounds.left_in - bounds.left_out, height); - - if (bounds.right_in - bounds.left_in > 0) - redisplay_clear_region (window, - DEFAULT_INDEX, - bounds.left_in, ypos1, - bounds.right_in - bounds.left_in, height); - - if (bounds.right_out - bounds.right_in > 0) - redisplay_clear_region (window, - get_builtin_face_cache_index (w, Vright_margin_face), - bounds.right_in, ypos1, - bounds.right_out - bounds.right_in, height); - - if (window_is_rightmost (w)) - redisplay_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f), - ypos1, FRAME_BORDER_WIDTH (f), height); - } + DEVMETH (d, clear_region, (window, DEFAULT_INDEX, x, y, width, height)); } } @@ -2013,6 +1035,7 @@ redisplay_clear_bottom_of_window (struct window *w, display_line_dynarr *ddla, int min_start, int max_end) { struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); int ypos1, ypos2; int ddla_len = Dynarr_length (ddla); @@ -2056,7 +1079,7 @@ redisplay_clear_bottom_of_window (struct window *w, display_line_dynarr *ddla, if (ypos2 <= ypos1) return; - redisplay_clear_to_window_end (w, ypos1, ypos2); + DEVMETH (d, clear_to_window_end, (w, ypos1, ypos2)); } /***************************************************************************** @@ -2076,7 +1099,7 @@ redisplay_update_line (struct window *w, int first_line, int last_line, display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); - MAYBE_DEVMETH (d, window_output_begin, (w)); + DEVMETH (d, output_begin, (d)); while (first_line <= last_line) { @@ -2152,7 +1175,6 @@ redisplay_update_line (struct window *w, int first_line, int last_line, larger impact on their sizing. */ /* #### See if we can get away with only calling this if max_line_len is greater than the window_char_width. */ - /* #### BILL!!! Should we do this for GTK as well? */ #if defined(HAVE_SCROLLBARS) && defined(HAVE_X_WINDOWS) { extern int stupid_vertical_scrollbar_drag_hack; @@ -2162,8 +1184,14 @@ redisplay_update_line (struct window *w, int first_line, int last_line, } #endif - redisplay_redraw_cursor (f, 0); - MAYBE_DEVMETH (d, window_output_end, (w)); + /* This has to be done after we've updated the values. We don't + call output_end for tty frames. Redisplay will do this after all + tty windows have been updated. This cuts down on cursor + flicker. */ + if (FRAME_TTY_P (f)) + redisplay_redraw_cursor (f, 0); + else + DEVMETH (d, output_end, (d)); } /***************************************************************************** @@ -2277,11 +1305,11 @@ redisplay_output_window (struct window *w) } /* Perform any output initialization. */ - MAYBE_DEVMETH (d, window_output_begin, (w)); + DEVMETH (d, output_begin, (d)); /* If the window's structure has changed clear the internal border above it if it is topmost (the function will check). */ - if (f->windows_structure_changed || f->faces_changed) + if (f->windows_structure_changed) redisplay_clear_top_of_window (w); /* Output each line. */ @@ -2300,7 +1328,7 @@ redisplay_output_window (struct window *w) if (window_needs_vertical_divider (w) && (f->windows_structure_changed || f->clear)) { - MAYBE_DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed)); + DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed)); } /* Clear the rest of the window, if necessary. */ @@ -2334,43 +1362,15 @@ redisplay_output_window (struct window *w) get invalidated when it should be. */ INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d); - redisplay_redraw_cursor (f, 0); - MAYBE_DEVMETH (d, window_output_end, (w)); + /* We don't call output_end for tty frames. Redisplay will do this + after all tty windows have been updated. This cuts down on + cursor flicker. */ + if (FRAME_TTY_P (f)) + redisplay_redraw_cursor (f, 0); + else + DEVMETH (d, output_end, (d)); #ifdef HAVE_SCROLLBARS update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0); #endif } - -/***************************************************************************** - bevel_modeline - - Draw a 3d border around the modeline on window W. - ****************************************************************************/ -void -bevel_modeline (struct window *w, struct display_line *dl) -{ - struct frame *f = XFRAME (w->frame); - struct device *d = XDEVICE (f->device); - int x, y, width, height; - int shadow_thickness = MODELINE_SHADOW_THICKNESS (w); - enum edge_style style; - - x = WINDOW_MODELINE_LEFT (w); - width = WINDOW_MODELINE_RIGHT (w) - x; - y = dl->ypos - dl->ascent - shadow_thickness; - height = dl->ascent + dl->descent + 2 * shadow_thickness; - - if (XINT (w->modeline_shadow_thickness) < 0) - { - style = EDGE_BEVEL_IN; - } - else - { - style = EDGE_BEVEL_OUT; - } - - MAYBE_DEVMETH (d, bevel_area, - (w, MODELINE_INDEX, x, y, width, height, shadow_thickness, - EDGE_ALL, style)); -}