X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fredisplay-msw.c;h=17394f4ad906a88ed8bde8185f9326619f99e46b;hb=afed98d731d87fc438f5d936e1a862388a0519fc;hp=9caf8f7dc584aba304ebc082db40ae60070cc14c;hpb=762383636a99307282c2d93d26c35c046ec24da1;p=chise%2Fxemacs-chise.git.1 diff --git a/src/redisplay-msw.c b/src/redisplay-msw.c index 9caf8f7..17394f4 100644 --- a/src/redisplay-msw.c +++ b/src/redisplay-msw.c @@ -26,9 +26,8 @@ Boston, MA 02111-1307, USA. */ Chuck Thompson Lots of work done by Ben Wing for Mule - - Partially rewritten for mswindows by Jonathan Harris, November 1997 - for 21.0. */ + Partially rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. + */ #include #include "lisp.h" @@ -42,11 +41,11 @@ Boston, MA 02111-1307, USA. */ #include "faces.h" #include "frame.h" #include "glyphs-msw.h" -#include "gutter.h" #include "redisplay.h" #include "sysdep.h" #include "window.h" +#include "windows.h" #ifdef MULE #include "mule-ccl.h" #include "mule-charset.h" @@ -55,19 +54,29 @@ Boston, MA 02111-1307, USA. */ #define MSWINDOWS_EOL_CURSOR_WIDTH 5 /* - * Random forward declarations + * Random forward delarations */ -static void mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, - Lisp_Object bg_pmap); -static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, - int under, int strike); +static void mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, + Lisp_Object bg, Lisp_Object bg_pmap); +static void mswindows_clear_region (Lisp_Object locale, face_index findex, + int x, int y, int width, int height); static void mswindows_output_vertical_divider (struct window *w, int clear); static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, int y, int width, int height); static void mswindows_output_dibitmap (struct frame *f, - Lisp_Image_Instance *p, - struct display_box* db, - struct display_glyph_area* dga); + struct Lisp_Image_Instance *p, + int x, int y, + int clip_x, int clip_y, + int clip_width, int clip_height, + int width, int height, + int pixmap_offset, + int offset_bitmap); +static void mswindows_output_pixmap (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, + int offset_bitmap); typedef struct textual_run { @@ -92,7 +101,7 @@ typedef struct textual_run static int separate_textual_runs (unsigned char *text_storage, textual_run *run_storage, - const Emchar *str, Charcount len) + CONST Emchar *str, Charcount len) { Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a possible valid charset when @@ -158,7 +167,7 @@ separate_textual_runs (unsigned char *text_storage, char_converter.reg[1] = byte1; char_converter.reg[2] = byte2; char_converter.ic = 0; /* start at beginning each time */ - ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); + ccl_driver (&char_converter, 0, 0, 0, 0); byte1 = char_converter.reg[1]; byte2 = char_converter.reg[2]; } @@ -185,7 +194,7 @@ mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, textual_run *run) { Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); - Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); + struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); SIZE size; if (!fi->proportional_p || !hdc) @@ -193,44 +202,12 @@ mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, else { assert(run->dimension == 1); /* #### FIXME! */ - mswindows_set_dc_font (hdc, font_inst, - cachel->underline, cachel->strikethru); + mswindows_update_dc (hdc, font_inst, Qnil, Qnil, Qnil); GetTextExtentPoint32 (hdc, run->ptr, run->len, &size); return(size.cx); } } -/* - * Given F, retrieve device context. F can be a display frame, or - * a print job. For a print job, page is also started when printer's - * device context is first time requested. - */ -static HDC -get_frame_dc (struct frame *f, int start_page_p) -{ - if (FRAME_MSWINDOWS_P (f)) - return FRAME_MSWINDOWS_DC (f); - else - { - if (start_page_p && !FRAME_MSPRINTER_PAGE_STARTED (f)) - msprinter_start_page (f); - return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))); - } -} - -/* - * Given F, retrieve compatible device context. F can be a display - * frame, or a print job. - */ -static HDC -get_frame_compdc (struct frame *f) -{ - struct device *d = XDEVICE (FRAME_DEVICE (f)); - if (DEVICE_MSWINDOWS_P (d)) - return DEVICE_MSWINDOWS_HCDC (d); - else - return DEVICE_MSPRINTER_HCDC (d); -} /***************************************************************************** mswindows_update_dc @@ -238,15 +215,18 @@ get_frame_compdc (struct frame *f) Given a number of parameters munge the DC so it has those properties. ****************************************************************************/ static void -mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, - Lisp_Object bg_pmap) +mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, + Lisp_Object bg, Lisp_Object bg_pmap) { + if (!NILP (font)) + SelectObject(hdc, FONT_INSTANCE_MSWINDOWS_HFONT (XFONT_INSTANCE (font))); + + if (!NILP (fg)) { SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (fg))); } - if (!NILP (bg)) { SetBkMode (hdc, OPAQUE); @@ -258,13 +238,54 @@ mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, } } -static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, - int under, int strike) + +/***************************************************************************** + mswindows_apply_face_effects + + Draw underline and strikeout as if this was X. + #### On mswindows this really should be done as part of drawing the font. + The line width used is chosen arbitrarily from the font height. + ****************************************************************************/ +static void +mswindows_apply_face_effects (HDC hdc, struct display_line *dl, int xpos, + int width, struct Lisp_Font_Instance *fi, + struct face_cachel *cachel, + struct face_cachel *color_cachel) { - SelectObject(hdc, mswindows_get_hfont (XFONT_INSTANCE (font), - under, strike)); + int yclip; + HBRUSH brush, oldbrush; + RECT rect; + + brush = CreateSolidBrush (COLOR_INSTANCE_MSWINDOWS_COLOR ( + XCOLOR_INSTANCE (color_cachel->foreground))); + if (brush) + { + yclip = dl->ypos + dl->descent - dl->clip; + rect.left = xpos; + rect.right = xpos + width; + oldbrush = SelectObject (hdc, brush); + + if (cachel->underline) + { + rect.top = dl->ypos + dl->descent/2; + rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1); + if (rect.bottom <= yclip) + FillRect (hdc, &rect, brush); + } + if (cachel->strikethru) + { + rect.top = dl->ypos + dl->descent - (dl->ascent + dl->descent)/2; + rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1); + if (rect.bottom <= yclip) + FillRect (hdc, &rect, brush); + } + + SelectObject (hdc, oldbrush); + DeleteObject (brush); + } } + /***************************************************************************** mswindows_output_hline @@ -283,44 +304,37 @@ mswindows_output_hline (struct window *w, struct display_line *dl, struct rune * of its face. ****************************************************************************/ static void -mswindows_output_blank (struct window *w, struct display_line *dl, - struct rune *rb, int start_pixpos) +mswindows_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos) { struct frame *f = XFRAME (w->frame); - HDC hdc = get_frame_dc (f, 1); - RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), - rb->xpos+rb->width, - DISPLAY_LINE_YEND (dl) }; + RECT rect = { rb->xpos, dl->ypos-dl->ascent, + rb->xpos+rb->width, dl->ypos+dl->descent-dl->clip }; struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); - - /* Unmap all subwindows in the area we are going to blank. */ - redisplay_unmap_subwindows_maybe (f, rb->xpos, DISPLAY_LINE_YPOS (dl), - rb->width, DISPLAY_LINE_HEIGHT (dl)); - + if (!IMAGE_INSTANCEP (bg_pmap) || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) bg_pmap = Qnil; if (!NILP(bg_pmap)) { - struct display_box db; - struct display_glyph_area dga; - redisplay_calculate_display_boxes (dl, rb->xpos, - /*rb->object.dglyph.xoffset*/ 0, - start_pixpos, rb->width, - &db, &dga); /* blank the background in the appropriate color */ - mswindows_update_dc (hdc, cachel->foreground, + mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, cachel->background, Qnil); - redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, + + mswindows_output_pixmap (w, dl, bg_pmap, + rb->xpos, 0 /*rb->object.dglyph.xoffset*/, + start_pixpos, rb->width, rb->findex, 0, 0, 0, TRUE); } else { - mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); - ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); + mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, + cachel->background, Qnil); + + ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, + &rect, NULL, 0, NULL); } } @@ -337,27 +351,23 @@ mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, { struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); - struct face_cachel *cachel=0; + struct face_cachel *cachel; Lisp_Object font = Qnil; int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); - HDC hdc = get_frame_dc (f, 1); - unsigned int local_face_index=0; + HDC hdc = FRAME_MSWINDOWS_DC (f); + unsigned int face_index=0; char *p_char = NULL; int n_char = 0; RECT rect = { xpos, - DISPLAY_LINE_YPOS (dl), + dl->ypos - dl->ascent, xpos + width, - DISPLAY_LINE_YEND (dl) }; + dl->ypos + dl->descent - dl->clip}; Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, WINDOW_BUFFER (w)); int bar_p = image_p || !NILP (bar); int cursor_p = !NILP (w->text_cursor_visible_p); int real_char_p = ch != 0; - /* Unmap all subwindows in the area we are going to blank. */ - redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl), - width, DISPLAY_LINE_HEIGHT (dl)); - if (real_char_p) { /* Use the font from the underlying character */ @@ -380,16 +390,16 @@ mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, /* Use cursor fg/bg for block cursor, or character fg/bg for the bar or when we need to erase the cursor. Output nothing at eol if bar cursor */ - local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); + face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? - findex : local_face_index)); - mswindows_update_dc (hdc, color_cachel->foreground, + findex : face_index)); + mswindows_update_dc (hdc, font, color_cachel->foreground, color_cachel->background, Qnil); - if (real_char_p) - mswindows_set_dc_font (hdc, font, - cachel->underline, cachel->strikethru); - ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL); + if (real_char_p && (cachel->underline || cachel->strikethru)) + mswindows_apply_face_effects (hdc, dl, xpos, width, + XFONT_INSTANCE (font), + cachel, color_cachel); } if (!cursor_p) @@ -398,9 +408,9 @@ mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, if (focus && bar_p) { rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); - local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); - cachel = WINDOW_FACE_CACHEL (w, local_face_index); - mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); + face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); + cachel = WINDOW_FACE_CACHEL (w, face_index); + mswindows_update_dc (hdc, Qnil, Qnil, cachel->background, Qnil); ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); } else if (!focus) @@ -416,12 +426,16 @@ mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, n_char = 1; } - local_face_index = get_builtin_face_cache_index (w, Vdefault_face); - cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index)); - mswindows_update_dc (hdc, - cachel->foreground, cachel->background, Qnil); + face_index = get_builtin_face_cache_index (w, Vdefault_face); + cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : face_index)); + mswindows_update_dc (hdc, Qnil, cachel->foreground, + cachel->background, Qnil); ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, &rect, p_char, n_char, NULL); + if (cachel->underline || cachel->strikethru) + mswindows_apply_face_effects (hdc, dl, xpos+1, width-2, + XFONT_INSTANCE (font), + cachel, cachel); } } @@ -450,17 +464,15 @@ mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, FINDEX Index for the face cache element describing how to display the text. ****************************************************************************/ -static void +void mswindows_output_string (struct window *w, struct display_line *dl, - Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, - int width, face_index findex, - int cursor, int cursor_start, int cursor_width, - int cursor_height) + Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, + int width, face_index findex) { struct frame *f = XFRAME (w->frame); /* struct device *d = XDEVICE (f->device);*/ Lisp_Object window; - HDC hdc = get_frame_dc (f, 1); + HDC hdc = FRAME_MSWINDOWS_DC (f); int clip_end; Lisp_Object bg_pmap; int len = Dynarr_length (buf); @@ -492,15 +504,11 @@ mswindows_output_string (struct window *w, struct display_line *dl, xpos -= xoffset; /* sort out the destination rectangle */ - height = DISPLAY_LINE_HEIGHT (dl); + height = dl->ascent + dl->descent - dl->clip; rect.left = clip_start; - rect.top = DISPLAY_LINE_YPOS (dl); + rect.top = dl->ypos - dl->ascent; rect.right = clip_end; - rect.bottom = rect.top + height; - - /* make sure the area we are about to display is subwindow free. */ - redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), - clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); + rect.bottom = height + dl->ypos - dl->ascent; /* output the background pixmap if there is one */ bg_pmap = cachel->background_pixmap; @@ -510,14 +518,13 @@ mswindows_output_string (struct window *w, struct display_line *dl, if (!NILP(bg_pmap)) { - struct display_box db; - struct display_glyph_area dga; - redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, - clip_start, width, &db, &dga); /* blank the background in the appropriate color */ - mswindows_update_dc (hdc, - cachel->foreground, cachel->background, Qnil); - redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, + mswindows_update_dc (hdc, Qnil, cachel->foreground, + cachel->background, Qnil); + + mswindows_output_pixmap (w, dl, bg_pmap, + xpos, xoffset, + clip_start, width, findex, 0, 0, 0, TRUE); /* output pixmap calls this so we have to recall to get correct references */ @@ -530,27 +537,26 @@ mswindows_output_string (struct window *w, struct display_line *dl, for (i = 0; i < nruns; i++) { Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); - Lisp_Font_Instance *fi = XFONT_INSTANCE (font); + struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); int this_width; if (EQ (font, Vthe_null_font_instance)) continue; - mswindows_update_dc (hdc, cachel->foreground, + mswindows_update_dc (hdc, font, cachel->foreground, NILP(bg_pmap) ? cachel->background : Qnil, Qnil); - mswindows_set_dc_font (hdc, font, cachel->underline, cachel->strikethru); this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); /* cope with fonts taller than lines */ - if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) + if ((int) fi->height < (int) (height + dl->clip)) { int clear_start = max (xpos, clip_start); int clear_end = min (xpos + this_width, clip_end); { - redisplay_clear_region (window, findex, clear_start, - DISPLAY_LINE_YPOS (dl), + mswindows_clear_region (window, findex, clear_start, + dl->ypos - dl->ascent, clear_end - clear_start, height); /* output pixmap calls this so we have to recall to get correct @@ -564,25 +570,43 @@ mswindows_output_string (struct window *w, struct display_line *dl, NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, &rect, (char *) runs[i].ptr, runs[i].len, NULL); + /* #### X does underline/strikethrough here so we do the same. + On mswindows, underline/strikethrough really belongs to the font */ + if (cachel->underline || cachel->strikethru) + mswindows_apply_face_effects (hdc, dl, xpos, this_width, fi, + cachel, cachel); xpos += this_width; } } static void -mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, - struct display_box* db, - struct display_glyph_area* dga) +mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, + int x, int y, + int clip_x, int clip_y, + int clip_width, int clip_height, + int width, int height, int pixmap_offset, + int offset_bitmap) { - HDC hdc = get_frame_dc (f, 1); - HDC hcompdc = get_frame_compdc (f); + HDC hdc = FRAME_MSWINDOWS_DC (f); HGDIOBJ old=NULL; COLORREF bgcolor = GetBkColor (hdc); - const int real_x = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (p); - const int real_y = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (p); - const int surface_x = IMAGE_INSTANCE_PIXMAP_WIDTH (p); - const int surface_y = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); + int need_clipping = (clip_x || clip_y); + int yoffset=0; + int xoffset=0; + /* do we need to offset the pixmap vertically? this is necessary + for background pixmaps. */ + if (offset_bitmap) + { + yoffset = y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); + xoffset = x % IMAGE_INSTANCE_PIXMAP_WIDTH (p); + /* the width is handled by mswindows_output_pixmap_region */ + } - /* first blit the mask */ + if (need_clipping) + { + } + + /* first blt the mask */ if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) { RGBQUAD col; @@ -591,124 +615,200 @@ mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, col.rgbGreen = GetGValue (bgcolor); col.rgbReserved = 0; - old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p)); + old = SelectObject (FRAME_MSWINDOWS_CDC (f), + IMAGE_INSTANCE_MSWINDOWS_MASK (p)); - SetDIBColorTable (hcompdc, 1, 1, &col); - - StretchBlt (hdc, - db->xpos, db->ypos, - dga->width, dga->height, - hcompdc, - MulDiv (dga->xoffset, real_x, surface_x), - MulDiv (dga->yoffset, real_y, surface_y), - MulDiv (dga->width, real_x, surface_x), - MulDiv (dga->height, real_y, surface_y), - SRCCOPY); - - SelectObject (hcompdc, old); + SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); + + BitBlt (hdc, + x,y, + width, height, + FRAME_MSWINDOWS_CDC (f), + xoffset,yoffset, + SRCCOPY); + + SelectObject (FRAME_MSWINDOWS_CDC (f), old); } - /* Now blit the bitmap itself, or one of its slices. */ - old = SelectObject (hcompdc, - IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE - (p, IMAGE_INSTANCE_PIXMAP_SLICE (p))); - - StretchBlt (hdc, - db->xpos, db->ypos, - dga->width, dga->height, - hcompdc, - MulDiv (dga->xoffset, real_x, surface_x), - MulDiv (dga->yoffset, real_y, surface_y), - MulDiv (dga->width, real_x, surface_x), - MulDiv (dga->height, real_y, surface_y), - IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); - - SelectObject (hcompdc, old); + /* now blt the bitmap itself. */ + old = SelectObject (FRAME_MSWINDOWS_CDC (f), + IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); + + BitBlt (hdc, + x,y, + width, height, + FRAME_MSWINDOWS_CDC (f), + xoffset, yoffset, + IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); + + SelectObject (FRAME_MSWINDOWS_CDC (f),old); + + if (need_clipping) + { + } } -/* X gc's have this nice property that setting the bg pixmap will +/* + * X gc's have this nice property that setting the bg pixmap will * output it offset relative to the window. Windows doesn't have this - * feature so we have to emulate this by outputting multiple pixmaps. - * This is only used for background pixmaps. Normal pixmaps are - * outputted once and are scrollable */ + * feature so we have to emulate this by outputting multiple pixmaps + */ static void mswindows_output_dibitmap_region (struct frame *f, - Lisp_Image_Instance *p, - struct display_box *db, - struct display_glyph_area *dga) + struct Lisp_Image_Instance *p, + int x, int y, + int clip_x, int clip_y, + int clip_width, int clip_height, + int width, int height, int pixmap_offset, + int offset_bitmap) { - struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; - struct display_glyph_area xdga - = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), - IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; + int pwidth = min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)); + int pheight = min (height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); int pxoffset = 0, pyoffset = 0; - if (dga) - { - xdga.width = dga->width; - xdga.height = dga->height; - } - else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) - return; - /* when doing a bg pixmap do a partial pixmap first so that we blt whole pixmaps thereafter */ - xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - - db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); - while (xdga.height > 0) + if (offset_bitmap) { - xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), + pheight = min (pheight, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - + y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); + } + + while (pheight > 0) + { + if (offset_bitmap) + { + pwidth = min (min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), IMAGE_INSTANCE_PIXMAP_WIDTH (p) - - db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); - pxoffset = 0; - while (xdga.width > 0) + x % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); + pxoffset = 0; + } + while (pwidth > 0) { - xdb.xpos = db->xpos + pxoffset; - xdb.ypos = db->ypos + pyoffset; - /* do we need to offset the pixmap vertically? this is necessary - for background pixmaps. */ - xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); - xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p); - /* the width is handled by mswindows_output_pixmap_region */ - mswindows_output_dibitmap (f, p, &xdb, &xdga); - pxoffset += xdga.width; - xdga.width = min ((db->width - pxoffset), - IMAGE_INSTANCE_PIXMAP_WIDTH (p)); + mswindows_output_dibitmap (f, p, + x + pxoffset, y + pyoffset, + clip_x, clip_y, + clip_width, clip_height, + pwidth, pheight, pixmap_offset, + offset_bitmap); + pxoffset += pwidth; + pwidth = min ((width-pxoffset), + IMAGE_INSTANCE_PIXMAP_WIDTH (p)); } - pyoffset += xdga.height; - xdga.height = min ((db->height - pyoffset), - IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); + pyoffset += pheight; + pheight = min ((height-pyoffset), + IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); } } -/* Output a pixmap at the desired location. - DB normalized display_box. - DGA normalized display_glyph_area. */ static void -mswindows_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 bg_pixmap) +mswindows_output_pixmap (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, + int offset_bitmap) { struct frame *f = XFRAME (w->frame); - HDC hdc = get_frame_dc (f, 1); + HDC hdc = FRAME_MSWINDOWS_DC (f); - Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); + 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_PIXMAP_HEIGHT (p) > lheight ? lheight : + IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); + int clip_x, clip_y, clip_width, clip_height; + + /* The pixmap_offset is used to center the pixmap on lines which are + shorter than it is. This results in odd effects when scrolling + pixmaps off of the bottom. Let's try not using it. */ +#if 0 + int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2; +#else + int pixmap_offset = 0; +#endif + XSETWINDOW (window, w); + if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset) + { + if (start_pixpos > xpos && start_pixpos > xpos + width) + return; + + clip_x = xoffset; + clip_width = width; + if (start_pixpos > xpos) + { + clip_x += (start_pixpos - xpos); + clip_width -= (start_pixpos - xpos); + } + } + else + { + clip_x = 0; + clip_width = 0; + } + + /* Place markers for possible future functionality (clipping the top + half instead of the bottom half; think pixel scrolling). */ + clip_y = 0; + clip_height = pheight; + + /* 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. */ + /* #### We take a shortcut for now. We know that since we have + pixmap_offset hardwired to 0 that the pixmap is against the top + edge so all we have to worry about is below it. */ + /* #### Unless 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 (((int) (dl->ypos - dl->ascent + pheight) < + (int) (dl->ypos + dl->descent - dl->clip)) + || IMAGE_INSTANCE_MSWINDOWS_MASK (p)) + { + int clear_x, clear_y, clear_width, clear_height; + + if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) + { + clear_y = dl->ypos - dl->ascent; + clear_height = lheight; + } + else + { + clear_y = dl->ypos - dl->ascent + pheight; + 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; + } + + if (!offset_bitmap) /* i.e. not a bg pixmap */ + mswindows_clear_region (window, findex, clear_x, clear_y, + clear_width, clear_height); + } + /* Output the pixmap. Have to do this as many times as is required to fill the given area */ - mswindows_update_dc (hdc, + mswindows_update_dc (hdc, Qnil, WINDOW_FACE_CACHEL_FOREGROUND (w, findex), WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); - if (bg_pixmap) - mswindows_output_dibitmap_region (f, p, db, dga); - else - mswindows_output_dibitmap (f, p, db, dga); + mswindows_output_dibitmap_region (f, p, xpos - xoffset, + dl->ypos - dl->ascent, + clip_x, clip_y, clip_width, clip_height, + width + xoffset, pheight, pixmap_offset, + offset_bitmap); } #ifdef HAVE_SCROLLBARS @@ -720,7 +820,7 @@ mswindows_output_pixmap (struct window *w, Lisp_Object image_instance, * to by PRC, and paints only the intersection */ static void -mswindows_redisplay_deadbox_maybe (struct window *w, const RECT* prc) +mswindows_redisplay_deadbox_maybe (struct window *w, CONST RECT* prc) { int sbh = window_scrollbar_height (w); int sbw = window_scrollbar_width (w); @@ -743,7 +843,7 @@ mswindows_redisplay_deadbox_maybe (struct window *w, const RECT* prc) if (IntersectRect (&rect_paint, &rect_dead, prc)) { struct frame *f = XFRAME (WINDOW_FRAME (w)); - FillRect (get_frame_dc (f, 1), &rect_paint, + FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint, (HBRUSH) (COLOR_BTNFACE+1)); } } @@ -800,11 +900,12 @@ mswindows_redraw_exposed_window (struct window *w, int x, int y, int width, for (line = 0; line < Dynarr_length (cdla); line++) { struct display_line *cdl = Dynarr_atp (cdla, line); + int top_y = cdl->ypos - cdl->ascent; + int bottom_y = cdl->ypos + cdl->descent; - if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl) - >= rect_draw.top) + if (bottom_y >= rect_draw.top) { - if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom) + if (top_y > rect_draw.bottom) { if (line == 0) continue; @@ -865,7 +966,6 @@ mswindows_redraw_exposed_area (struct frame *f, int x, int y, int width, int hei redraw anyhow. */ MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); #endif - redraw_exposed_gutters (f, x, y, width, height); if (!f->window_face_cache_reset) { @@ -878,55 +978,38 @@ mswindows_redraw_exposed_area (struct frame *f, int x, int y, int width, int hei /***************************************************************************** - mswindows_bevel_area + mswindows_bevel_modeline - Draw a 3d border around the specified area on window W. + Draw a 3d border around the modeline on window W. ****************************************************************************/ static void -mswindows_bevel_area (struct window *w, face_index findex, int x, int y, - int width, int height, int thickness, - int edges, enum edge_style style) +mswindows_bevel_modeline (struct window *w, struct display_line *dl) { struct frame *f = XFRAME (w->frame); + Lisp_Object color; + int shadow_width = MODELINE_SHADOW_THICKNESS (w); + RECT rect = { WINDOW_MODELINE_LEFT (w), + dl->ypos - dl->ascent - shadow_width, + WINDOW_MODELINE_RIGHT (w), + dl->ypos + dl->descent + shadow_width}; UINT edge; - UINT border = 0; - if (style == EDGE_ETCHED_IN) - edge = EDGE_ETCHED; - else if (style == EDGE_ETCHED_OUT) - edge = EDGE_BUMP; - else if (style == EDGE_BEVEL_IN) - { - if (thickness == 1) - edge = BDR_SUNKENINNER; - else - edge = EDGE_SUNKEN; - } - else /* EDGE_BEVEL_OUT */ - { - if (thickness == 1) - edge = BDR_RAISEDINNER; - else - edge = EDGE_RAISED; - } + color = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); + mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); + + if (XINT (w->modeline_shadow_thickness) < 0) + shadow_width = -shadow_width; - if (edges & EDGE_TOP) - border |= BF_TOP; - if (edges & EDGE_LEFT) - border |= BF_LEFT; - if (edges & EDGE_BOTTOM) - border |= BF_BOTTOM; - if (edges & EDGE_RIGHT) - border |= BF_RIGHT; - - { - RECT rect = { x, y, x + width, y + height }; - Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); - HDC hdc = get_frame_dc (f, 1); - - mswindows_update_dc (hdc, Qnil, color, Qnil); - DrawEdge (hdc, &rect, edge, border); - } + if (shadow_width < -1) + edge = EDGE_SUNKEN; + else if (shadow_width < 0) + edge = BDR_SUNKENINNER; + else if (shadow_width == 1) + edge = BDR_RAISEDINNER; + else + edge = EDGE_RAISED; + + DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, BF_RECT); } @@ -957,37 +1040,22 @@ mswindows_eol_cursor_width (void) } /***************************************************************************** - mswindows_frame_output_begin + mswindows_output_begin Perform any necessary initialization prior to an update. ****************************************************************************/ static void -mswindows_frame_output_begin (struct frame *f) +mswindows_output_begin (struct device *d) { } /***************************************************************************** - mswindows_frame_output_end + mswindows_output_end Perform any necessary flushing of queues when an update has completed. ****************************************************************************/ static void -mswindows_frame_output_end (struct frame *f) -{ - HDWP hdwp = FRAME_MSWINDOWS_DATA (f)->hdwp; - - if (hdwp != 0) - { - EndDeferWindowPos (hdwp); - FRAME_MSWINDOWS_DATA (f)->hdwp = 0; - } - - GdiFlush(); -} - -/* Printer version is more lightweight. */ -static void -msprinter_frame_output_end (struct frame *f) +mswindows_output_end (struct device *d) { GdiFlush(); } @@ -996,14 +1064,13 @@ static int mswindows_flash (struct device *d) { struct frame *f = device_selected_frame (d); - HDC hdc = get_frame_dc (f, 1); RECT rc; GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc); - InvertRect (hdc, &rc); + InvertRect (FRAME_MSWINDOWS_DC (f), &rc); GdiFlush (); Sleep (25); - InvertRect (hdc, &rc); + InvertRect (FRAME_MSWINDOWS_DC (f), &rc); return 1; } @@ -1020,7 +1087,7 @@ mswindows_ring_bell (struct device *d, int volume, int pitch, int duration) Given a display line, a block number for that start line, output all runes between start and end in the specified display block. - Ripped off with minimal thought from the corresponding X routine. + Ripped off with mininmal thought from the corresponding X routine. ****************************************************************************/ static void mswindows_output_display_block (struct window *w, struct display_line *dl, int block, @@ -1044,14 +1111,18 @@ mswindows_output_display_block (struct window *w, struct display_line *dl, int b rb = Dynarr_atp (rba, start); if (!rb) + { /* Nothing to do so don't do anything. */ return; - - findex = rb->findex; - xpos = rb->xpos; - width = 0; - if (rb->type == RUNE_CHAR) - charset = CHAR_CHARSET (rb->object.chr.ch); + } + else + { + findex = rb->findex; + xpos = rb->xpos; + width = 0; + if (rb->type == RUNE_CHAR) + charset = CHAR_CHARSET (rb->object.chr.ch); + } if (end < 0) end = Dynarr_length (rba); @@ -1074,7 +1145,7 @@ mswindows_output_display_block (struct window *w, struct display_line *dl, int b if (Dynarr_length (buf)) { mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, - findex, 0, 0, 0, 0); + findex); xpos = rb->xpos; width = 0; } @@ -1108,9 +1179,10 @@ mswindows_output_display_block (struct window *w, struct display_line *dl, int b else if (rb->object.chr.ch == '\n') { /* Clear in case a cursor was formerly here. */ - redisplay_clear_region (window, findex, xpos, - DISPLAY_LINE_YPOS (dl), - rb->width, DISPLAY_LINE_HEIGHT (dl)); + int height = dl->ascent + dl->descent - dl->clip; + + mswindows_clear_region (window, findex, xpos, dl->ypos - dl->ascent, + rb->width, height); elt++; } } @@ -1146,12 +1218,6 @@ mswindows_output_display_block (struct window *w, struct display_line *dl, int b else if (rb->type == RUNE_DGLYPH) { Lisp_Object instance; - struct display_box dbox; - struct display_glyph_area dga; - - redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, - start_pixpos, rb->width, - &dbox, &dga); XSETWINDOW (window, w); instance = glyph_image_instance (rb->object.dglyph.glyph, @@ -1159,52 +1225,54 @@ mswindows_output_display_block (struct window *w, struct display_line *dl, int b findex = rb->findex; if (IMAGE_INSTANCEP (instance)) - { - switch (XIMAGE_INSTANCE_TYPE (instance)) + switch (XIMAGE_INSTANCE_TYPE (instance)) + { + case IMAGE_TEXT: { - case IMAGE_MONO_PIXMAP: - case IMAGE_COLOR_PIXMAP: - redisplay_output_pixmap (w, instance, &dbox, &dga, findex, - cursor_start, cursor_width, - cursor_height, 0); - if (rb->cursor_type == CURSOR_ON) - mswindows_output_cursor (w, dl, xpos, cursor_width, - findex, 0, 1); - break; - - case IMAGE_WIDGET: - if (EQ (XIMAGE_INSTANCE_WIDGET_TYPE (instance), - Qlayout)) - { - redisplay_output_layout (w, instance, &dbox, &dga, findex, - cursor_start, cursor_width, - cursor_height); - if (rb->cursor_type == CURSOR_ON) - mswindows_output_cursor (w, dl, xpos, cursor_width, - findex, 0, 1); - break; - } - case IMAGE_SUBWINDOW: - redisplay_output_subwindow (w, instance, &dbox, &dga, findex, - cursor_start, cursor_width, - cursor_height); + /* #### This is way losing. See the comment in + add_glyph_rune(). */ + Lisp_Object string = + XIMAGE_INSTANCE_TEXT_STRING (instance); + convert_bufbyte_string_into_emchar_dynarr + (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); + if (rb->cursor_type == CURSOR_ON) mswindows_output_cursor (w, dl, xpos, cursor_width, - findex, 0, 1); - break; - - case IMAGE_NOTHING: - /* nothing is as nothing does */ - break; - - case IMAGE_TEXT: - case IMAGE_POINTER: - default: - abort (); + findex, Dynarr_at (buf, 0), 0); + else /* #### redisplay-x passes -1 as the width: why ? */ + mswindows_output_string (w, dl, buf, xpos, + rb->object.dglyph.xoffset, + start_pixpos, rb->width, findex); + Dynarr_reset (buf); } - IMAGE_INSTANCE_OPTIMIZE_OUTPUT - (XIMAGE_INSTANCE (instance)) = 0; - } + break; + + case IMAGE_MONO_PIXMAP: + case IMAGE_COLOR_PIXMAP: + mswindows_output_pixmap (w, dl, instance, xpos, + rb->object.dglyph.xoffset, start_pixpos, + rb->width, findex, cursor_start, + cursor_width, cursor_height, 0); + if (rb->cursor_type == CURSOR_ON) + mswindows_output_cursor (w, dl, xpos, cursor_width, + findex, 0, 1); + break; + + case IMAGE_POINTER: + abort (); + + case IMAGE_SUBWINDOW: + /* #### implement me */ + break; + + case IMAGE_NOTHING: + /* nothing is as nothing does */ + break; + + default: + abort (); + } + xpos += rb->width; elt++; } @@ -1214,15 +1282,14 @@ mswindows_output_display_block (struct window *w, struct display_line *dl, int b } if (Dynarr_length (buf)) - mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, - 0, 0, 0, 0); + mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex); if (dl->modeline && !EQ (Qzero, w->modeline_shadow_thickness) && (f->clear || f->windows_structure_changed || w->shadow_thickness_changed)) - bevel_modeline (w, dl); + mswindows_bevel_modeline (w, dl); Dynarr_free (buf); } @@ -1237,53 +1304,51 @@ static void mswindows_output_vertical_divider (struct window *w, int clear_unused) { struct frame *f = XFRAME (w->frame); - HDC hdc = get_frame_dc (f, 1); RECT rect; int spacing = XINT (w->vertical_divider_spacing); int shadow = XINT (w->vertical_divider_shadow_thickness); int abs_shadow = abs (shadow); int line_width = XINT (w->vertical_divider_line_width); int div_left = WINDOW_RIGHT (w) - window_divider_width (w); - int y1 = WINDOW_TOP (w); - int y2 = WINDOW_BOTTOM (w); /* Clear left and right spacing areas */ if (spacing) { - rect.top = y1; - rect.bottom = y2; - mswindows_update_dc (hdc, Qnil, + rect.top = WINDOW_TOP (w); + rect.bottom = WINDOW_BOTTOM (w); + mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); rect.right = WINDOW_RIGHT (w); rect.left = rect.right - spacing; - ExtTextOut (hdc, 0, 0, ETO_OPAQUE, + ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); rect.left = div_left; rect.right = div_left + spacing; - ExtTextOut (hdc, 0, 0, ETO_OPAQUE, + ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); } /* Clear divider face */ - rect.top = y1 + abs_shadow; - rect.bottom = y2 - abs_shadow; + rect.top = WINDOW_TOP (w) + abs_shadow; + rect.bottom = WINDOW_BOTTOM (w) - abs_shadow; rect.left = div_left + spacing + abs_shadow; rect.right = rect.left + line_width; if (rect.left < rect.right) { face_index div_face = get_builtin_face_cache_index (w, Vvertical_divider_face); - mswindows_update_dc (hdc, Qnil, + mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); - ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); + ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, + &rect, NULL, 0, NULL); } /* Draw a shadow around the divider */ if (shadow != 0) { - /* #### This will be fixed to support arbitrary thickness */ + /* #### This will be fixed to support arbitrary thichkness */ InflateRect (&rect, abs_shadow, abs_shadow); - DrawEdge (hdc, &rect, + DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); } } @@ -1296,9 +1361,8 @@ mswindows_output_vertical_divider (struct window *w, int clear_unused) ****************************************************************************/ static int mswindows_text_width (struct frame *f, struct face_cachel *cachel, - const Emchar *str, Charcount len) + CONST Emchar *str, Charcount len) { - HDC hdc = get_frame_dc (f, 0); int width_so_far = 0; unsigned char *text_storage = (unsigned char *) alloca (2 * len); textual_run *runs = alloca_array (textual_run, len); @@ -1308,7 +1372,7 @@ mswindows_text_width (struct frame *f, struct face_cachel *cachel, nruns = separate_textual_runs (text_storage, runs, str, len); for (i = 0; i < nruns; i++) - width_so_far += mswindows_text_width_single_run (hdc, + width_so_far += mswindows_text_width_single_run (FRAME_MSWINDOWS_DC (f), cachel, runs + i); return width_so_far; @@ -1322,35 +1386,140 @@ mswindows_text_width (struct frame *f, struct face_cachel *cachel, given face. ****************************************************************************/ static void -mswindows_clear_region (Lisp_Object locale, struct device* d, struct frame* f, - face_index findex, int x, int y, - int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, - Lisp_Object background_pixmap) +mswindows_clear_region (Lisp_Object locale, face_index findex, int x, int y, + int width, int height) { + struct window *w; + struct frame *f; + Lisp_Object background_pixmap = Qunbound; + Lisp_Object temp; RECT rect = { x, y, x+width, y+height }; - HDC hdc = get_frame_dc (f, 1); - if (!NILP (background_pixmap)) + if (!(width && height)) /* We often seem to get called with width==0 */ + return; + + if (WINDOWP (locale)) + { + w = XWINDOW (locale); + f = XFRAME (w->frame); + } + else if (FRAMEP (locale)) + { + w = NULL; + f = XFRAME (locale); + } + else + abort (); + + if (w) { - struct display_box db = { x, y, width, height }; - mswindows_update_dc (hdc, - fcolor, bcolor, background_pixmap); + 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)) + { + Lisp_Object fcolor, bcolor; + + 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); + } + + mswindows_update_dc (FRAME_MSWINDOWS_DC (f), + Qnil, fcolor, bcolor, background_pixmap); + mswindows_output_dibitmap_region - ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); + ( f, XIMAGE_INSTANCE (background_pixmap), + x, y, 0, 0, 0, 0, width, height, 0, TRUE); } else { - mswindows_update_dc (hdc, Qnil, fcolor, Qnil); - ExtTextOut (hdc, 0, 0, ETO_OPAQUE, - &rect, NULL, 0, NULL); + Lisp_Object color = (w ? WINDOW_FACE_CACHEL_BACKGROUND (w, findex) : + FACE_BACKGROUND (Vdefault_face, locale)); + mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); + ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); } #ifdef HAVE_SCROLLBARS if (WINDOWP (locale)) - mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect); + mswindows_redisplay_deadbox_maybe (w, &rect); #endif } +/***************************************************************************** + mswindows_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. + ****************************************************************************/ +static void +mswindows_clear_to_window_end (struct window *w, int ypos1, int ypos2) +{ + int height = ypos2 - ypos1; + + if (height) + { + struct frame *f = XFRAME (w->frame); + Lisp_Object window; + int bflag = (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)) + mswindows_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f), + ypos1, FRAME_BORDER_WIDTH (f), height); + + if (bounds.left_in - bounds.left_out > 0) + mswindows_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) + mswindows_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1, + bounds.right_in - bounds.left_in, height); + + if (bounds.right_out - bounds.right_in > 0) + mswindows_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)) + mswindows_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f), + ypos1, FRAME_BORDER_WIDTH (f), height); + } + +} + + /* XXX Implement me! */ static void mswindows_clear_frame (struct frame *f) @@ -1367,33 +1536,17 @@ mswindows_clear_frame (struct frame *f) void console_type_create_redisplay_mswindows (void) { - /* redisplay methods - display*/ + /* redisplay methods */ CONSOLE_HAS_METHOD (mswindows, text_width); CONSOLE_HAS_METHOD (mswindows, output_display_block); CONSOLE_HAS_METHOD (mswindows, divider_height); CONSOLE_HAS_METHOD (mswindows, eol_cursor_width); CONSOLE_HAS_METHOD (mswindows, output_vertical_divider); + CONSOLE_HAS_METHOD (mswindows, clear_to_window_end); CONSOLE_HAS_METHOD (mswindows, clear_region); CONSOLE_HAS_METHOD (mswindows, clear_frame); - CONSOLE_HAS_METHOD (mswindows, frame_output_begin); - CONSOLE_HAS_METHOD (mswindows, frame_output_end); + CONSOLE_HAS_METHOD (mswindows, output_begin); + CONSOLE_HAS_METHOD (mswindows, output_end); CONSOLE_HAS_METHOD (mswindows, flash); CONSOLE_HAS_METHOD (mswindows, ring_bell); - CONSOLE_HAS_METHOD (mswindows, bevel_area); - CONSOLE_HAS_METHOD (mswindows, output_string); - CONSOLE_HAS_METHOD (mswindows, output_pixmap); - - /* redisplay methods - printer */ - CONSOLE_HAS_METHOD (msprinter, frame_output_end); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, text_width); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_display_block); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, divider_height); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, eol_cursor_width); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_vertical_divider); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_region); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_frame); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, frame_output_begin); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, bevel_area); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_string); - CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_pixmap); }