X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fredisplay-msw.c;h=62ddcebfb3f2185e46e95c98512e9b0b4bc16adf;hp=17394f4ad906a88ed8bde8185f9326619f99e46b;hb=a5812bf2ff9a9cf40f4ff78dcb83f5b4c295bd18;hpb=ccce6217f84987dff10ed3d2b60b9f0f65d8f25a diff --git a/src/redisplay-msw.c b/src/redisplay-msw.c index 17394f4..62ddceb 100644 --- a/src/redisplay-msw.c +++ b/src/redisplay-msw.c @@ -26,8 +26,9 @@ 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" @@ -41,42 +42,32 @@ 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" +#include "character.h" #endif #define MSWINDOWS_EOL_CURSOR_WIDTH 5 /* - * Random forward delarations + * Random forward declarations */ -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_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_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, - 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); + Lisp_Image_Instance *p, + struct display_box* db, + struct display_glyph_area* dga); typedef struct textual_run { @@ -101,7 +92,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 @@ -143,9 +134,9 @@ separate_textual_runs (unsigned char *text_storage, #ifdef MULE { Lisp_Object ccl_prog = XCHARSET_CCL_PROGRAM (charset); - need_ccl_conversion = !NILP (ccl_prog); - if (need_ccl_conversion) - setup_ccl_program (&char_converter, ccl_prog); + if ((!NILP (ccl_prog)) + && (setup_ccl_program (&char_converter, ccl_prog) >= 0)) + need_ccl_conversion = 1; } #endif } @@ -167,7 +158,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_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); byte1 = char_converter.reg[1]; byte2 = char_converter.reg[2]; } @@ -194,7 +185,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); - struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); + Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); SIZE size; if (!fi->proportional_p || !hdc) @@ -202,12 +193,44 @@ mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, else { assert(run->dimension == 1); /* #### FIXME! */ - mswindows_update_dc (hdc, font_inst, Qnil, Qnil, Qnil); + mswindows_set_dc_font (hdc, font_inst, + cachel->underline, cachel->strikethru); 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 @@ -215,18 +238,15 @@ mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, Given a number of parameters munge the DC so it has those properties. ****************************************************************************/ static void -mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, - Lisp_Object bg, Lisp_Object bg_pmap) +mswindows_update_dc (HDC hdc, 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); @@ -238,54 +258,13 @@ mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, } } - -/***************************************************************************** - 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) +static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, + int under, int 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); - } + SelectObject(hdc, mswindows_get_hfont (XFONT_INSTANCE (font), + under, strike)); } - /***************************************************************************** mswindows_output_hline @@ -304,37 +283,45 @@ 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); - RECT rect = { rb->xpos, dl->ypos-dl->ascent, - rb->xpos+rb->width, dl->ypos+dl->descent-dl->clip }; + HDC hdc = get_frame_dc (f, 1); + RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), + rb->xpos+rb->width, + DISPLAY_LINE_YEND (dl) }; 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, + /*rb->object.dglyph.yoffset*/ 0, + start_pixpos, rb->width, + &db, &dga); /* blank the background in the appropriate color */ - mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, + mswindows_update_dc (hdc, cachel->foreground, cachel->background, Qnil); - - mswindows_output_pixmap (w, dl, bg_pmap, - rb->xpos, 0 /*rb->object.dglyph.xoffset*/, - start_pixpos, rb->width, rb->findex, + redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, 0, 0, 0, TRUE); } else { - 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); + mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); + ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); } } @@ -351,23 +338,27 @@ 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; + struct face_cachel *cachel=0; Lisp_Object font = Qnil; int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); - HDC hdc = FRAME_MSWINDOWS_DC (f); - unsigned int face_index=0; + HDC hdc = get_frame_dc (f, 1); + unsigned int local_face_index=0; char *p_char = NULL; int n_char = 0; RECT rect = { xpos, - dl->ypos - dl->ascent, + DISPLAY_LINE_YPOS (dl), xpos + width, - dl->ypos + dl->descent - dl->clip}; + DISPLAY_LINE_YEND (dl) }; 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 */ @@ -390,16 +381,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 */ - face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); + local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? - findex : face_index)); - mswindows_update_dc (hdc, font, color_cachel->foreground, + findex : local_face_index)); + mswindows_update_dc (hdc, 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) @@ -408,9 +399,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)); - 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); + 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); ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); } else if (!focus) @@ -426,16 +417,12 @@ mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, n_char = 1; } - 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); + 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); 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); } } @@ -464,15 +451,17 @@ 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. ****************************************************************************/ -void +static 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) + 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) { struct frame *f = XFRAME (w->frame); /* struct device *d = XDEVICE (f->device);*/ Lisp_Object window; - HDC hdc = FRAME_MSWINDOWS_DC (f); + HDC hdc = get_frame_dc (f, 1); int clip_end; Lisp_Object bg_pmap; int len = Dynarr_length (buf); @@ -504,11 +493,15 @@ mswindows_output_string (struct window *w, struct display_line *dl, xpos -= xoffset; /* sort out the destination rectangle */ - height = dl->ascent + dl->descent - dl->clip; + height = DISPLAY_LINE_HEIGHT (dl); rect.left = clip_start; - rect.top = dl->ypos - dl->ascent; + rect.top = DISPLAY_LINE_YPOS (dl); rect.right = clip_end; - rect.bottom = height + dl->ypos - dl->ascent; + 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)); /* output the background pixmap if there is one */ bg_pmap = cachel->background_pixmap; @@ -518,13 +511,14 @@ 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, 0, + clip_start, width, &db, &dga); /* blank the background in the appropriate color */ - mswindows_update_dc (hdc, Qnil, cachel->foreground, - cachel->background, Qnil); - - mswindows_output_pixmap (w, dl, bg_pmap, - xpos, xoffset, - clip_start, width, findex, + mswindows_update_dc (hdc, + cachel->foreground, cachel->background, Qnil); + redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, 0, 0, 0, TRUE); /* output pixmap calls this so we have to recall to get correct references */ @@ -537,26 +531,27 @@ 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); - struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); + Lisp_Font_Instance *fi = XFONT_INSTANCE (font); int this_width; if (EQ (font, Vthe_null_font_instance)) continue; - mswindows_update_dc (hdc, font, cachel->foreground, + mswindows_update_dc (hdc, 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)) + if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) { int clear_start = max (xpos, clip_start); int clear_end = min (xpos + this_width, clip_end); { - mswindows_clear_region (window, findex, clear_start, - dl->ypos - dl->ascent, + redisplay_clear_region (window, findex, clear_start, + DISPLAY_LINE_YPOS (dl), clear_end - clear_start, height); /* output pixmap calls this so we have to recall to get correct @@ -570,245 +565,165 @@ 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, 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) +mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, + struct display_box* db, + struct display_glyph_area* dga) { - HDC hdc = FRAME_MSWINDOWS_DC (f); + HDC hdc = get_frame_dc (f, 1); + HDC hcompdc = get_frame_compdc (f); HGDIOBJ old=NULL; - COLORREF bgcolor = GetBkColor (hdc); - 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 */ - } + 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); - if (need_clipping) - { - } - - /* first blt the mask */ + /* first blit the mask */ if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) { - RGBQUAD col; - col.rgbBlue = GetBValue (bgcolor); - col.rgbRed = GetRValue (bgcolor); - col.rgbGreen = GetGValue (bgcolor); - col.rgbReserved = 0; - - old = SelectObject (FRAME_MSWINDOWS_CDC (f), - IMAGE_INSTANCE_MSWINDOWS_MASK (p)); - - SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); - - BitBlt (hdc, - x,y, - width, height, - FRAME_MSWINDOWS_CDC (f), - xoffset,yoffset, - SRCCOPY); + RGBQUAD bg; + COLORREF bgcolor; - SelectObject (FRAME_MSWINDOWS_CDC (f), old); + old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p)); + + if (IMAGE_INSTANCE_TYPE (p) == IMAGE_MONO_PIXMAP) + { + COLORREF fgcolor; + RGBQUAD fg; + + fgcolor = GetTextColor (hdc); + fg.rgbBlue = GetBValue (fgcolor); + fg.rgbRed = GetRValue (fgcolor); + fg.rgbGreen = GetGValue (fgcolor); + fg.rgbReserved = 0; + SetDIBColorTable (hcompdc, 0, 1, &fg); + } + + bgcolor = GetBkColor (hdc); + bg.rgbBlue = GetBValue (bgcolor); + bg.rgbRed = GetRValue (bgcolor); + bg.rgbGreen = GetGValue (bgcolor); + bg.rgbReserved = 0; + SetDIBColorTable (hcompdc, 1, 1, &bg); + + 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); } - /* 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) - { - } + /* 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); } -/* - * 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 - */ + * 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 */ static void mswindows_output_dibitmap_region (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) + Lisp_Image_Instance *p, + struct display_box *db, + struct display_glyph_area *dga) { - int pwidth = min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)); - int pheight = min (height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); + 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 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)); - if (offset_bitmap) - { - pheight = min (pheight, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - - y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); - } - - while (pheight > 0) + while (xdga.height > 0) { - if (offset_bitmap) - { - pwidth = min (min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), + xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), IMAGE_INSTANCE_PIXMAP_WIDTH (p) - - x % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); - pxoffset = 0; - } - while (pwidth > 0) + db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); + pxoffset = 0; + while (xdga.width > 0) { - 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)); + 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)); } - pyoffset += pheight; - pheight = min ((height-pyoffset), - IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); + pyoffset += xdga.height; + xdga.height = min ((db->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, 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) +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) { struct frame *f = XFRAME (w->frame); - HDC hdc = FRAME_MSWINDOWS_DC (f); + HDC hdc = get_frame_dc (f, 1); - struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); + 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, Qnil, + mswindows_update_dc (hdc, WINDOW_FACE_CACHEL_FOREGROUND (w, findex), WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); - 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); + if (bg_pixmap) + mswindows_output_dibitmap_region (f, p, db, dga); + else + mswindows_output_dibitmap (f, p, db, dga); } #ifdef HAVE_SCROLLBARS @@ -820,7 +735,7 @@ mswindows_output_pixmap (struct window *w, struct display_line *dl, * 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); @@ -843,7 +758,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 (FRAME_MSWINDOWS_DC (f), &rect_paint, + FillRect (get_frame_dc (f, 1), &rect_paint, (HBRUSH) (COLOR_BTNFACE+1)); } } @@ -900,12 +815,11 @@ 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 (bottom_y >= rect_draw.top) + if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl) + >= rect_draw.top) { - if (top_y > rect_draw.bottom) + if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom) { if (line == 0) continue; @@ -966,6 +880,7 @@ 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) { @@ -978,38 +893,55 @@ mswindows_redraw_exposed_area (struct frame *f, int x, int y, int width, int hei /***************************************************************************** - mswindows_bevel_modeline + mswindows_bevel_area - Draw a 3d border around the modeline on window W. + Draw a 3d border around the specified area on window W. ****************************************************************************/ static void -mswindows_bevel_modeline (struct window *w, struct display_line *dl) +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) { 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; - 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 (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; + } - 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); + 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); + } } @@ -1040,22 +972,38 @@ mswindows_eol_cursor_width (void) } /***************************************************************************** - mswindows_output_begin + mswindows_frame_output_begin Perform any necessary initialization prior to an update. ****************************************************************************/ static void -mswindows_output_begin (struct device *d) +mswindows_frame_output_begin (struct frame *f) { } /***************************************************************************** - mswindows_output_end + mswindows_frame_output_end Perform any necessary flushing of queues when an update has completed. ****************************************************************************/ static void -mswindows_output_end (struct device *d) +mswindows_frame_output_end (struct frame *f) +{ +#ifdef DEFER_WINDOW_POS + HDWP hdwp = FRAME_MSWINDOWS_DATA (f)->hdwp; + + if (hdwp != 0) + { + EndDeferWindowPos (hdwp); + FRAME_MSWINDOWS_DATA (f)->hdwp = 0; + } +#endif + GdiFlush(); +} + +/* Printer version is more lightweight. */ +static void +msprinter_frame_output_end (struct frame *f) { GdiFlush(); } @@ -1064,13 +1012,14 @@ 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 (FRAME_MSWINDOWS_DC (f), &rc); + InvertRect (hdc, &rc); GdiFlush (); Sleep (25); - InvertRect (FRAME_MSWINDOWS_DC (f), &rc); + InvertRect (hdc, &rc); return 1; } @@ -1087,7 +1036,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 mininmal thought from the corresponding X routine. + Ripped off with minimal thought from the corresponding X routine. ****************************************************************************/ static void mswindows_output_display_block (struct window *w, struct display_line *dl, int block, @@ -1111,18 +1060,14 @@ 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; - } - else - { - findex = rb->findex; - xpos = rb->xpos; - width = 0; - if (rb->type == RUNE_CHAR) - charset = CHAR_CHARSET (rb->object.chr.ch); - } + + 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); @@ -1145,7 +1090,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); + findex, 0, 0, 0, 0); xpos = rb->xpos; width = 0; } @@ -1179,10 +1124,9 @@ 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. */ - int height = dl->ascent + dl->descent - dl->clip; - - mswindows_clear_region (window, findex, xpos, dl->ypos - dl->ascent, - rb->width, height); + redisplay_clear_region (window, findex, xpos, + DISPLAY_LINE_YPOS (dl), + rb->width, DISPLAY_LINE_HEIGHT (dl)); elt++; } } @@ -1218,6 +1162,12 @@ 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, + rb->object.dglyph.yoffset, + start_pixpos, rb->width, &dbox, &dga); XSETWINDOW (window, w); instance = glyph_image_instance (rb->object.dglyph.glyph, @@ -1225,54 +1175,52 @@ 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)) - { - case IMAGE_TEXT: + { + switch (XIMAGE_INSTANCE_TYPE (instance)) { - /* #### 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); - + 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, 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); + findex, 0, 1); + break; + + case IMAGE_WIDGET: + if (EQ (XIMAGE_INSTANCE_WIDGET_TYPE (instance), + Qlayout)) + { + redisplay_output_layout (window, 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); + 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 (); } - 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 (); - } - + IMAGE_INSTANCE_OPTIMIZE_OUTPUT + (XIMAGE_INSTANCE (instance)) = 0; + } xpos += rb->width; elt++; } @@ -1282,14 +1230,15 @@ 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); + mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, + 0, 0, 0, 0); if (dl->modeline && !EQ (Qzero, w->modeline_shadow_thickness) && (f->clear || f->windows_structure_changed || w->shadow_thickness_changed)) - mswindows_bevel_modeline (w, dl); + bevel_modeline (w, dl); Dynarr_free (buf); } @@ -1304,51 +1253,53 @@ 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 = WINDOW_TOP (w); - rect.bottom = WINDOW_BOTTOM (w); - mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, + rect.top = y1; + rect.bottom = y2; + mswindows_update_dc (hdc, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); rect.right = WINDOW_RIGHT (w); rect.left = rect.right - spacing; - ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, + ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); rect.left = div_left; rect.right = div_left + spacing; - ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, + ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); } /* Clear divider face */ - rect.top = WINDOW_TOP (w) + abs_shadow; - rect.bottom = WINDOW_BOTTOM (w) - abs_shadow; + rect.top = y1 + abs_shadow; + rect.bottom = y2 - 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 (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, + mswindows_update_dc (hdc, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); - ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, - &rect, NULL, 0, NULL); + ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); } /* Draw a shadow around the divider */ if (shadow != 0) { - /* #### This will be fixed to support arbitrary thichkness */ + /* #### This will be fixed to support arbitrary thickness */ InflateRect (&rect, abs_shadow, abs_shadow); - DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, + DrawEdge (hdc, &rect, shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); } } @@ -1361,8 +1312,9 @@ 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); @@ -1372,7 +1324,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 (FRAME_MSWINDOWS_DC (f), + width_so_far += mswindows_text_width_single_run (hdc, cachel, runs + i); return width_so_far; @@ -1386,140 +1338,35 @@ mswindows_text_width (struct frame *f, struct face_cachel *cachel, given face. ****************************************************************************/ static void -mswindows_clear_region (Lisp_Object locale, face_index findex, int x, int y, - int width, int height) +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) { - 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 (!(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) + if (!NILP (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); - + struct display_box db = { x, y, width, height }; + mswindows_update_dc (hdc, + fcolor, bcolor, background_pixmap); mswindows_output_dibitmap_region - ( f, XIMAGE_INSTANCE (background_pixmap), - x, y, 0, 0, 0, 0, width, height, 0, TRUE); + ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); } else { - 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); + mswindows_update_dc (hdc, Qnil, fcolor, Qnil); + ExtTextOut (hdc, 0, 0, ETO_OPAQUE, + &rect, NULL, 0, NULL); } #ifdef HAVE_SCROLLBARS if (WINDOWP (locale)) - mswindows_redisplay_deadbox_maybe (w, &rect); + mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &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) @@ -1536,17 +1383,33 @@ mswindows_clear_frame (struct frame *f) void console_type_create_redisplay_mswindows (void) { - /* redisplay methods */ + /* redisplay methods - display*/ 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, output_begin); - CONSOLE_HAS_METHOD (mswindows, output_end); + CONSOLE_HAS_METHOD (mswindows, frame_output_begin); + CONSOLE_HAS_METHOD (mswindows, frame_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); }