X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fredisplay-output.c;h=ae041e927d11cf5007d8d73cbf42e1452a4d954d;hb=aa5b3d9f401a1e96e261cd3c60997544a8c87e1d;hp=6266fd5bef883c5ce2f4c0746cabfef3d1db5e6d;hpb=2e3e3f9ee27fec50f45c282d71eaddf7c673bc56;p=chise%2Fxemacs-chise.git diff --git a/src/redisplay-output.c b/src/redisplay-output.c index 6266fd5..ae041e9 100644 --- a/src/redisplay-output.c +++ b/src/redisplay-output.c @@ -28,7 +28,6 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" -#include "debug.h" #include "buffer.h" #include "window.h" @@ -38,12 +37,14 @@ Boston, MA 02111-1307, USA. */ #include "redisplay.h" #include "faces.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); /***************************************************************************** sync_rune_structs @@ -305,8 +306,6 @@ 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; @@ -416,10 +415,10 @@ compare_display_blocks (struct window *w, struct display_line *cdl, stop_pos = elt + 1; } - DEVMETH (d, output_display_block, (w, ddl, d_block, start_pos, - stop_pos, start_pixpos, - cursor_start, cursor_width, - cursor_height)); + redisplay_output_display_block (w, ddl, d_block, start_pos, + stop_pos, start_pixpos, + cursor_start, cursor_width, + cursor_height); return 1; } @@ -435,13 +434,12 @@ 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); - DEVMETH (d, clear_region, (window, DEFAULT_INDEX, - FRAME_LEFT_BORDER_START (f), y, - FRAME_BORDER_WIDTH (f), height)); + redisplay_clear_region (window, DEFAULT_INDEX, + FRAME_LEFT_BORDER_START (f), y, + FRAME_BORDER_WIDTH (f), height); } /***************************************************************************** @@ -453,13 +451,12 @@ 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); - DEVMETH (d, clear_region, (window, DEFAULT_INDEX, - FRAME_RIGHT_BORDER_START (f), - y, FRAME_BORDER_WIDTH (f), height)); + redisplay_clear_region (window, DEFAULT_INDEX, + FRAME_RIGHT_BORDER_START (f), + y, FRAME_BORDER_WIDTH (f), height); } /***************************************************************************** @@ -476,7 +473,6 @@ 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; @@ -538,7 +534,7 @@ output_display_line (struct window *w, display_line_dynarr *cdla, a TEXT block. */ if (ddl->modeline) { - /* The shadow thickness check is necesssary if only the sign of + /* The shadow thickness check is necessary if only the sign of the size changed. */ if (cdba && !w->shadow_thickness_changed) { @@ -547,8 +543,8 @@ output_display_line (struct window *w, display_line_dynarr *cdla, } else { - DEVMETH (d, output_display_block, (w, ddl, 0, 0, -1, start_pixpos, - 0, 0, 0)); + redisplay_output_display_block (w, ddl, 0, 0, -1, start_pixpos, + 0, 0, 0); must_sync = 1; } @@ -596,7 +592,7 @@ output_display_line (struct window *w, display_line_dynarr *cdla, cdl->clip != ddl->clip))) { int x, y, width, height; - Lisp_Object face; + face_index findex; must_sync = 1; x = start_pixpos; @@ -605,25 +601,33 @@ output_display_line (struct window *w, display_line_dynarr *cdla, height = ddl->ascent + ddl->descent - ddl->clip; if (x < ddl->bounds.left_in) - face = Vleft_margin_face; + { + findex = ddl->left_margin_findex ? + ddl->left_margin_findex + : get_builtin_face_cache_index (w, Vleft_margin_face); + } else if (x < ddl->bounds.right_in) - face = Vdefault_face; + { + /* no check here because DEFAULT_INDEX == 0 anyway */ + findex = ddl->default_findex; + } else if (x < ddl->bounds.right_out) - face = Vright_margin_face; + { + findex = ddl->right_margin_findex ? + ddl->right_margin_findex + : get_builtin_face_cache_index (w, Vright_margin_face); + } else - face = Qnil; + findex = (face_index) -1; - if (!NILP (face)) + if (findex != (face_index) -1) { Lisp_Object window; XSETWINDOW (window, w); /* Clear the empty area. */ - DEVMETH (d, clear_region, - (window, get_builtin_face_cache_index (w, - face), - x, y, width, height)); + redisplay_clear_region (window, findex, x, y, width, height); /* Mark that we should clear the border. This is necessary because italic fonts may leave @@ -686,13 +690,13 @@ output_display_line (struct window *w, display_line_dynarr *cdla, } must_sync = 1; - DEVMETH (d, output_display_block, (w, ddl, block, first_elt, - last_elt, - start_pixpos, - cursor_start, cursor_width, - cursor_height)); + redisplay_output_display_block (w, ddl, block, first_elt, + last_elt, + start_pixpos, + cursor_start, cursor_width, + cursor_height); } - + start_pixpos = next_start_pixpos; } } @@ -988,6 +992,242 @@ 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); + + 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) +{ + int elt; + + for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) + { + struct subwindow_cachel *cachel = + Dynarr_atp (f->subwindow_cachels, elt); + + if (cachel->being_displayed + && + cachel->x + cachel->width > x && cachel->x < x + width + && + cachel->y + cachel->height > y && cachel->y < y + height) + { + unmap_subwindow (cachel->subwindow); + } + } +} + +/**************************************************************************** + 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 (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) + { + redisplay_unmap_subwindows (f, x, y, width, height); + } +} + +/**************************************************************************** + 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, struct display_line *dl, + Lisp_Object image_instance, int xpos, int xoffset, + int start_pixpos, int width, face_index findex, + int cursor_start, int cursor_width, int cursor_height) +{ + struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); + Lisp_Object window; + + int lheight = dl->ascent + dl->descent - dl->clip; + int pheight = ((int) IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight ? lheight : + IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p)); + + XSETWINDOW (window, w); + + /* Clear the area the subwindow is going into. The subwindow 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 subwindow. Of + course this is rubbish if the subwindow has transparent areas + (for instance with frames). */ + /* #### We take a shortcut for now. We know that since we have + subwindow_offset hardwired to 0 that the subwindow is against the top + edge so all we have to worry about is below it. */ + if ((int) (dl->ypos - dl->ascent + pheight) < + (int) (dl->ypos + dl->descent - dl->clip)) + { + int clear_x, clear_width; + + int clear_y = dl->ypos - dl->ascent + pheight; + int clear_height = lheight - pheight; + + if (start_pixpos >= 0 && start_pixpos > xpos) + { + clear_x = start_pixpos; + clear_width = xpos + width - start_pixpos; + } + else + { + clear_x = xpos; + clear_width = width; + } + + redisplay_clear_region (window, findex, clear_x, clear_y, + clear_width, clear_height); + } +#if 0 + redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent, + width, lheight); +#endif + /* if we can't view the whole window we can't view any of it */ + if (IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight + || + IMAGE_INSTANCE_SUBWINDOW_WIDTH (p) > width) + { + redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent, + width, lheight); + unmap_subwindow (image_instance); + } + else + map_subwindow (image_instance, xpos - xoffset, dl->ypos - dl->ascent); +} + +/**************************************************************************** + 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 */ + if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) + { + redisplay_unmap_subwindows (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_top_of_window @@ -1002,7 +1242,6 @@ 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; @@ -1019,7 +1258,65 @@ redisplay_clear_top_of_window (struct window *w) y = FRAME_TOP_BORDER_START (f) - 1; height = FRAME_BORDER_HEIGHT (f) + 1; - DEVMETH (d, clear_region, (window, DEFAULT_INDEX, x, y, width, height)); + 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) + { + struct frame *f = XFRAME (w->frame); + 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); + } } } @@ -1079,7 +1376,7 @@ redisplay_clear_bottom_of_window (struct window *w, display_line_dynarr *ddla, if (ypos2 <= ypos1) return; - DEVMETH (d, clear_to_window_end, (w, ypos1, ypos2)); + redisplay_clear_to_window_end (w, ypos1, ypos2); } /***************************************************************************** @@ -1374,3 +1671,28 @@ redisplay_output_window (struct window *w) 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); + + 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) + shadow_thickness = - shadow_thickness; + + MAYBE_DEVMETH (d, bevel_area, + (w, MODELINE_INDEX, x, y, width, height, shadow_thickness)); +}