comparison src/redisplay-msw.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents aabb7f5b1c81
children 2f8bb876ab1d
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
24 24
25 /* Authorship: 25 /* Authorship:
26 26
27 Chuck Thompson 27 Chuck Thompson
28 Lots of work done by Ben Wing for Mule 28 Lots of work done by Ben Wing for Mule
29 Partially rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. 29
30 */ 30 Partially rewritten for mswindows by Jonathan Harris, November 1997
31 for 21.0. */
31 32
32 #include <config.h> 33 #include <config.h>
33 #include "lisp.h" 34 #include "lisp.h"
34 35
35 #include "console-msw.h" 36 #include "console-msw.h"
39 #include "debug.h" 40 #include "debug.h"
40 #include "events.h" 41 #include "events.h"
41 #include "faces.h" 42 #include "faces.h"
42 #include "frame.h" 43 #include "frame.h"
43 #include "glyphs-msw.h" 44 #include "glyphs-msw.h"
45 #include "gutter.h"
44 #include "redisplay.h" 46 #include "redisplay.h"
45 #include "sysdep.h" 47 #include "sysdep.h"
46 #include "window.h" 48 #include "window.h"
47 49
48 #include "windows.h"
49 #ifdef MULE 50 #ifdef MULE
50 #include "mule-ccl.h" 51 #include "mule-ccl.h"
51 #include "mule-charset.h" 52 #include "mule-charset.h"
52 #endif 53 #endif
53 54
54 #define MSWINDOWS_EOL_CURSOR_WIDTH 5 55 #define MSWINDOWS_EOL_CURSOR_WIDTH 5
55 56
56 /* 57 /*
57 * Random forward declarations 58 * Random forward declarations
58 */ 59 */
59 static void mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, 60 static void mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg,
60 Lisp_Object bg, Lisp_Object bg_pmap); 61 Lisp_Object bg_pmap);
62 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font,
63 int under, int strike);
61 static void mswindows_output_vertical_divider (struct window *w, int clear); 64 static void mswindows_output_vertical_divider (struct window *w, int clear);
62 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, 65 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x,
63 int y, int width, int height); 66 int y, int width, int height);
64 static void mswindows_output_dibitmap (struct frame *f, 67 static void mswindows_output_dibitmap (struct frame *f,
65 struct Lisp_Image_Instance *p, 68 Lisp_Image_Instance *p,
66 int x, int y, 69 struct display_box* db,
67 int clip_x, int clip_y, 70 struct display_glyph_area* dga);
68 int clip_width, int clip_height,
69 int width, int height,
70 int pixmap_offset,
71 int offset_bitmap);
72 static void mswindows_output_pixmap (struct window *w, struct display_line *dl,
73 Lisp_Object image_instance, int xpos,
74 int xoffset, int start_pixpos, int width,
75 face_index findex, int cursor_start,
76 int cursor_width, int cursor_height,
77 int offset_bitmap);
78 71
79 typedef struct textual_run 72 typedef struct textual_run
80 { 73 {
81 Lisp_Object charset; 74 Lisp_Object charset;
82 unsigned char *ptr; 75 unsigned char *ptr;
97 Returns the number of runs actually used. */ 90 Returns the number of runs actually used. */
98 91
99 static int 92 static int
100 separate_textual_runs (unsigned char *text_storage, 93 separate_textual_runs (unsigned char *text_storage,
101 textual_run *run_storage, 94 textual_run *run_storage,
102 CONST Emchar *str, Charcount len) 95 const Emchar *str, Charcount len)
103 { 96 {
104 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a 97 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a
105 possible valid charset when 98 possible valid charset when
106 MULE is not defined */ 99 MULE is not defined */
107 int runs_so_far = 0; 100 int runs_so_far = 0;
163 { 156 {
164 char_converter.reg[0] = XCHARSET_ID (charset); 157 char_converter.reg[0] = XCHARSET_ID (charset);
165 char_converter.reg[1] = byte1; 158 char_converter.reg[1] = byte1;
166 char_converter.reg[2] = byte2; 159 char_converter.reg[2] = byte2;
167 char_converter.ic = 0; /* start at beginning each time */ 160 char_converter.ic = 0; /* start at beginning each time */
168 ccl_driver (&char_converter, 0, 0, 0, 0); 161 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING);
169 byte1 = char_converter.reg[1]; 162 byte1 = char_converter.reg[1];
170 byte2 = char_converter.reg[2]; 163 byte2 = char_converter.reg[2];
171 } 164 }
172 #endif 165 #endif
173 *text_storage++ = (unsigned char) byte1; 166 *text_storage++ = (unsigned char) byte1;
190 static int 183 static int
191 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, 184 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel,
192 textual_run *run) 185 textual_run *run)
193 { 186 {
194 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); 187 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset);
195 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); 188 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst);
196 SIZE size; 189 SIZE size;
197 190
198 if (!fi->proportional_p || !hdc) 191 if (!fi->proportional_p || !hdc)
199 return (fi->width * run->len); 192 return (fi->width * run->len);
200 else 193 else
201 { 194 {
202 assert(run->dimension == 1); /* #### FIXME! */ 195 assert(run->dimension == 1); /* #### FIXME! */
203 mswindows_update_dc (hdc, font_inst, Qnil, Qnil, Qnil); 196 mswindows_set_dc_font (hdc, font_inst,
197 cachel->underline, cachel->strikethru);
204 GetTextExtentPoint32 (hdc, run->ptr, run->len, &size); 198 GetTextExtentPoint32 (hdc, run->ptr, run->len, &size);
205 return(size.cx); 199 return(size.cx);
206 } 200 }
207 } 201 }
208 202
203 /*
204 * Given F, retrieve device context. F can be a display frame, or
205 * a print job.
206 */
207 INLINE HDC
208 get_frame_dc (struct frame *f)
209 {
210 if (FRAME_MSWINDOWS_P (f))
211 return FRAME_MSWINDOWS_DC (f);
212 else
213 {
214 if (!FRAME_MSPRINTER_PAGE_STARTED (f))
215 msprinter_start_page (f);
216 return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
217 }
218 }
219
220 /*
221 * Given F, retrieve compatible device context. F can be a display
222 * frame, or a print job.
223 */
224 INLINE HDC
225 get_frame_compdc (struct frame *f)
226 {
227 if (FRAME_MSWINDOWS_P (f))
228 return FRAME_MSWINDOWS_CDC (f);
229 else
230 return FRAME_MSPRINTER_CDC (f);
231 }
209 232
210 /***************************************************************************** 233 /*****************************************************************************
211 mswindows_update_dc 234 mswindows_update_dc
212 235
213 Given a number of parameters munge the DC so it has those properties. 236 Given a number of parameters munge the DC so it has those properties.
214 ****************************************************************************/ 237 ****************************************************************************/
215 static void 238 static void
216 mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, 239 mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg,
217 Lisp_Object bg, Lisp_Object bg_pmap) 240 Lisp_Object bg_pmap)
218 { 241 {
219 if (!NILP (font))
220 SelectObject(hdc, FONT_INSTANCE_MSWINDOWS_HFONT (XFONT_INSTANCE (font)));
221
222
223 if (!NILP (fg)) 242 if (!NILP (fg))
224 { 243 {
225 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR 244 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR
226 (XCOLOR_INSTANCE (fg))); 245 (XCOLOR_INSTANCE (fg)));
227 } 246 }
247
228 if (!NILP (bg)) 248 if (!NILP (bg))
229 { 249 {
230 SetBkMode (hdc, OPAQUE); 250 SetBkMode (hdc, OPAQUE);
231 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg))); 251 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg)));
232 } 252 }
234 { 254 {
235 SetBkMode (hdc, TRANSPARENT); 255 SetBkMode (hdc, TRANSPARENT);
236 } 256 }
237 } 257 }
238 258
239 259 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font,
240 /***************************************************************************** 260 int under, int strike)
241 mswindows_apply_face_effects 261 {
242 262 SelectObject(hdc, mswindows_get_hfont (XFONT_INSTANCE (font),
243 Draw underline and strikeout as if this was X. 263 under, strike));
244 #### On mswindows this really should be done as part of drawing the font. 264 }
245 The line width used is chosen arbitrarily from the font height.
246 ****************************************************************************/
247 static void
248 mswindows_apply_face_effects (HDC hdc, struct display_line *dl, int xpos,
249 int width, struct Lisp_Font_Instance *fi,
250 struct face_cachel *cachel,
251 struct face_cachel *color_cachel)
252 {
253 int yclip;
254 HBRUSH brush, oldbrush;
255 RECT rect;
256
257 brush = CreateSolidBrush (COLOR_INSTANCE_MSWINDOWS_COLOR (
258 XCOLOR_INSTANCE (color_cachel->foreground)));
259 if (brush)
260 {
261 yclip = dl->ypos + dl->descent - dl->clip;
262 rect.left = xpos;
263 rect.right = xpos + width;
264 oldbrush = SelectObject (hdc, brush);
265
266 if (cachel->underline)
267 {
268 rect.top = dl->ypos + dl->descent/2;
269 rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1);
270 if (rect.bottom <= yclip)
271 FillRect (hdc, &rect, brush);
272 }
273 if (cachel->strikethru)
274 {
275 rect.top = dl->ypos + dl->descent - (dl->ascent + dl->descent)/2;
276 rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1);
277 if (rect.bottom <= yclip)
278 FillRect (hdc, &rect, brush);
279 }
280
281 SelectObject (hdc, oldbrush);
282 DeleteObject (brush);
283 }
284 }
285
286 265
287 /***************************************************************************** 266 /*****************************************************************************
288 mswindows_output_hline 267 mswindows_output_hline
289 268
290 Output a horizontal line in the foreground of its face. 269 Output a horizontal line in the foreground of its face.
300 279
301 Output a blank by clearing the area it covers in the background color 280 Output a blank by clearing the area it covers in the background color
302 of its face. 281 of its face.
303 ****************************************************************************/ 282 ****************************************************************************/
304 static void 283 static void
305 mswindows_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos) 284 mswindows_output_blank (struct window *w, struct display_line *dl,
285 struct rune *rb, int start_pixpos)
306 { 286 {
307 struct frame *f = XFRAME (w->frame); 287 struct frame *f = XFRAME (w->frame);
308 RECT rect = { rb->xpos, dl->ypos-dl->ascent, 288 HDC hdc = get_frame_dc (f);
309 rb->xpos+rb->width, dl->ypos+dl->descent-dl->clip }; 289 RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl),
290 rb->xpos+rb->width,
291 DISPLAY_LINE_YEND (dl) };
310 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); 292 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex);
311 293
312 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); 294 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex);
295
296 /* Unmap all subwindows in the area we are going to blank. */
297 redisplay_unmap_subwindows_maybe (f, rb->xpos, DISPLAY_LINE_YPOS (dl),
298 rb->width, DISPLAY_LINE_HEIGHT (dl));
313 299
314 if (!IMAGE_INSTANCEP (bg_pmap) 300 if (!IMAGE_INSTANCEP (bg_pmap)
315 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) 301 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
316 bg_pmap = Qnil; 302 bg_pmap = Qnil;
317 303
318 if (!NILP(bg_pmap)) 304 if (!NILP(bg_pmap))
319 { 305 {
306 struct display_box db;
307 struct display_glyph_area dga;
308 redisplay_calculate_display_boxes (dl, rb->xpos,
309 /*rb->object.dglyph.xoffset*/ 0,
310 start_pixpos, rb->width,
311 &db, &dga);
320 /* blank the background in the appropriate color */ 312 /* blank the background in the appropriate color */
321 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, 313 mswindows_update_dc (hdc, cachel->foreground,
322 cachel->background, Qnil); 314 cachel->background, Qnil);
323 315 redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex,
324 mswindows_output_pixmap (w, dl, bg_pmap,
325 rb->xpos, 0 /*rb->object.dglyph.xoffset*/,
326 start_pixpos, rb->width, rb->findex,
327 0, 0, 0, TRUE); 316 0, 0, 0, TRUE);
328 } 317 }
329 else 318 else
330 { 319 {
331 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, 320 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil);
332 cachel->background, Qnil); 321 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
333
334 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE,
335 &rect, NULL, 0, NULL);
336 } 322 }
337 } 323 }
338 324
339 325
340 /***************************************************************************** 326 /*****************************************************************************
350 struct frame *f = XFRAME (w->frame); 336 struct frame *f = XFRAME (w->frame);
351 struct device *d = XDEVICE (f->device); 337 struct device *d = XDEVICE (f->device);
352 struct face_cachel *cachel=0; 338 struct face_cachel *cachel=0;
353 Lisp_Object font = Qnil; 339 Lisp_Object font = Qnil;
354 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); 340 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
355 HDC hdc = FRAME_MSWINDOWS_DC (f); 341 HDC hdc = get_frame_dc (f);
356 unsigned int face_index=0; 342 unsigned int local_face_index=0;
357 char *p_char = NULL; 343 char *p_char = NULL;
358 int n_char = 0; 344 int n_char = 0;
359 RECT rect = { xpos, 345 RECT rect = { xpos,
360 dl->ypos - dl->ascent, 346 DISPLAY_LINE_YPOS (dl),
361 xpos + width, 347 xpos + width,
362 dl->ypos + dl->descent - dl->clip}; 348 DISPLAY_LINE_YEND (dl) };
363 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, 349 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor,
364 WINDOW_BUFFER (w)); 350 WINDOW_BUFFER (w));
365 int bar_p = image_p || !NILP (bar); 351 int bar_p = image_p || !NILP (bar);
366 int cursor_p = !NILP (w->text_cursor_visible_p); 352 int cursor_p = !NILP (w->text_cursor_visible_p);
367 int real_char_p = ch != 0; 353 int real_char_p = ch != 0;
368 354
355 /* Unmap all subwindows in the area we are going to blank. */
356 redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl),
357 width, DISPLAY_LINE_HEIGHT (dl));
358
369 if (real_char_p) 359 if (real_char_p)
370 { 360 {
371 /* Use the font from the underlying character */ 361 /* Use the font from the underlying character */
372 cachel = WINDOW_FACE_CACHEL (w, findex); 362 cachel = WINDOW_FACE_CACHEL (w, findex);
373 363
386 struct face_cachel *color_cachel; 376 struct face_cachel *color_cachel;
387 377
388 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar 378 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar
389 or when we need to erase the cursor. Output nothing at eol if bar 379 or when we need to erase the cursor. Output nothing at eol if bar
390 cursor */ 380 cursor */
391 face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); 381 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face);
392 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? 382 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ?
393 findex : face_index)); 383 findex : local_face_index));
394 mswindows_update_dc (hdc, font, color_cachel->foreground, 384 mswindows_update_dc (hdc, color_cachel->foreground,
395 color_cachel->background, Qnil); 385 color_cachel->background, Qnil);
386 if (real_char_p)
387 mswindows_set_dc_font (hdc, font,
388 cachel->underline, cachel->strikethru);
389
396 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL); 390 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL);
397 if (real_char_p && (cachel->underline || cachel->strikethru))
398 mswindows_apply_face_effects (hdc, dl, xpos, width,
399 XFONT_INSTANCE (font),
400 cachel, color_cachel);
401 } 391 }
402 392
403 if (!cursor_p) 393 if (!cursor_p)
404 return; 394 return;
405 395
406 if (focus && bar_p) 396 if (focus && bar_p)
407 { 397 {
408 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); 398 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width));
409 face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); 399 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face);
410 cachel = WINDOW_FACE_CACHEL (w, face_index); 400 cachel = WINDOW_FACE_CACHEL (w, local_face_index);
411 mswindows_update_dc (hdc, Qnil, Qnil, cachel->background, Qnil); 401 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil);
412 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); 402 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL);
413 } 403 }
414 else if (!focus) 404 else if (!focus)
415 { 405 {
416 /* Now have real character drawn in its own color. We deflate 406 /* Now have real character drawn in its own color. We deflate
422 { 412 {
423 p_char = (char*) &ch; 413 p_char = (char*) &ch;
424 n_char = 1; 414 n_char = 1;
425 } 415 }
426 416
427 face_index = get_builtin_face_cache_index (w, Vdefault_face); 417 local_face_index = get_builtin_face_cache_index (w, Vdefault_face);
428 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : face_index)); 418 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index));
429 mswindows_update_dc (hdc, Qnil, cachel->foreground, 419 mswindows_update_dc (hdc,
430 cachel->background, Qnil); 420 cachel->foreground, cachel->background, Qnil);
431 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, 421 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED,
432 &rect, p_char, n_char, NULL); 422 &rect, p_char, n_char, NULL);
433 if (cachel->underline || cachel->strikethru)
434 mswindows_apply_face_effects (hdc, dl, xpos+1, width-2,
435 XFONT_INSTANCE (font),
436 cachel, cachel);
437 } 423 }
438 } 424 }
439 425
440 426
441 /***************************************************************************** 427 /*****************************************************************************
460 CLIP_START Clip everything left of this X position. 446 CLIP_START Clip everything left of this X position.
461 WIDTH Clip everything right of XPOS + WIDTH. 447 WIDTH Clip everything right of XPOS + WIDTH.
462 FINDEX Index for the face cache element describing how to display 448 FINDEX Index for the face cache element describing how to display
463 the text. 449 the text.
464 ****************************************************************************/ 450 ****************************************************************************/
465 void 451 static void
466 mswindows_output_string (struct window *w, struct display_line *dl, 452 mswindows_output_string (struct window *w, struct display_line *dl,
467 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, 453 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start,
468 int width, face_index findex) 454 int width, face_index findex,
455 int cursor, int cursor_start, int cursor_width,
456 int cursor_height)
469 { 457 {
470 struct frame *f = XFRAME (w->frame); 458 struct frame *f = XFRAME (w->frame);
471 /* struct device *d = XDEVICE (f->device);*/ 459 /* struct device *d = XDEVICE (f->device);*/
472 Lisp_Object window; 460 Lisp_Object window;
473 HDC hdc = FRAME_MSWINDOWS_DC (f); 461 HDC hdc = get_frame_dc (f);
474 int clip_end; 462 int clip_end;
475 Lisp_Object bg_pmap; 463 Lisp_Object bg_pmap;
476 int len = Dynarr_length (buf); 464 int len = Dynarr_length (buf);
477 unsigned char *text_storage = (unsigned char *) alloca (2 * len); 465 unsigned char *text_storage = (unsigned char *) alloca (2 * len);
478 textual_run *runs = alloca_array (textual_run, len); 466 textual_run *runs = alloca_array (textual_run, len);
502 xpos -= xoffset; 490 xpos -= xoffset;
503 491
504 /* sort out the destination rectangle */ 492 /* sort out the destination rectangle */
505 height = DISPLAY_LINE_HEIGHT (dl); 493 height = DISPLAY_LINE_HEIGHT (dl);
506 rect.left = clip_start; 494 rect.left = clip_start;
507 rect.top = dl->ypos - dl->ascent; 495 rect.top = DISPLAY_LINE_YPOS (dl);
508 rect.right = clip_end; 496 rect.right = clip_end;
509 rect.bottom = height + dl->ypos - dl->ascent; 497 rect.bottom = rect.top + height;
498
499 /* make sure the area we are about to display is subwindow free. */
500 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl),
501 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl));
510 502
511 /* output the background pixmap if there is one */ 503 /* output the background pixmap if there is one */
512 bg_pmap = cachel->background_pixmap; 504 bg_pmap = cachel->background_pixmap;
513 if (!IMAGE_INSTANCEP (bg_pmap) 505 if (!IMAGE_INSTANCEP (bg_pmap)
514 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) 506 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
515 bg_pmap = Qnil; 507 bg_pmap = Qnil;
516 508
517 if (!NILP(bg_pmap)) 509 if (!NILP(bg_pmap))
518 { 510 {
511 struct display_box db;
512 struct display_glyph_area dga;
513 redisplay_calculate_display_boxes (dl, xpos + xoffset, 0,
514 clip_start, width, &db, &dga);
519 /* blank the background in the appropriate color */ 515 /* blank the background in the appropriate color */
520 mswindows_update_dc (hdc, Qnil, cachel->foreground, 516 mswindows_update_dc (hdc,
521 cachel->background, Qnil); 517 cachel->foreground, cachel->background, Qnil);
522 518 redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex,
523 mswindows_output_pixmap (w, dl, bg_pmap,
524 xpos, xoffset,
525 clip_start, width, findex,
526 0, 0, 0, TRUE); 519 0, 0, 0, TRUE);
527 /* output pixmap calls this so we have to recall to get correct 520 /* output pixmap calls this so we have to recall to get correct
528 references */ 521 references */
529 cachel = WINDOW_FACE_CACHEL (w, findex); 522 cachel = WINDOW_FACE_CACHEL (w, findex);
530 } 523 }
533 Dynarr_length (buf)); 526 Dynarr_length (buf));
534 527
535 for (i = 0; i < nruns; i++) 528 for (i = 0; i < nruns; i++)
536 { 529 {
537 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); 530 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset);
538 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); 531 Lisp_Font_Instance *fi = XFONT_INSTANCE (font);
539 int this_width; 532 int this_width;
540 533
541 if (EQ (font, Vthe_null_font_instance)) 534 if (EQ (font, Vthe_null_font_instance))
542 continue; 535 continue;
543 536
544 mswindows_update_dc (hdc, font, cachel->foreground, 537 mswindows_update_dc (hdc, cachel->foreground,
545 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); 538 NILP(bg_pmap) ? cachel->background : Qnil, Qnil);
539 mswindows_set_dc_font (hdc, font, cachel->underline, cachel->strikethru);
546 540
547 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); 541 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i);
548 542
549 /* cope with fonts taller than lines */ 543 /* cope with fonts taller than lines */
550 if ((int) fi->height < (int) (height + dl->clip)) 544 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip))
551 { 545 {
552 int clear_start = max (xpos, clip_start); 546 int clear_start = max (xpos, clip_start);
553 int clear_end = min (xpos + this_width, clip_end); 547 int clear_end = min (xpos + this_width, clip_end);
554 548
555 { 549 {
556 redisplay_clear_region (window, findex, clear_start, 550 redisplay_clear_region (window, findex, clear_start,
557 dl->ypos - dl->ascent, 551 DISPLAY_LINE_YPOS (dl),
558 clear_end - clear_start, 552 clear_end - clear_start,
559 height); 553 height);
560 /* output pixmap calls this so we have to recall to get correct 554 /* output pixmap calls this so we have to recall to get correct
561 references */ 555 references */
562 cachel = WINDOW_FACE_CACHEL (w, findex); 556 cachel = WINDOW_FACE_CACHEL (w, findex);
566 assert (runs[i].dimension == 1); /* #### FIXME: Broken when Mule? */ 560 assert (runs[i].dimension == 1); /* #### FIXME: Broken when Mule? */
567 ExtTextOut (hdc, xpos, dl->ypos, 561 ExtTextOut (hdc, xpos, dl->ypos,
568 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, 562 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED,
569 &rect, (char *) runs[i].ptr, runs[i].len, NULL); 563 &rect, (char *) runs[i].ptr, runs[i].len, NULL);
570 564
571 /* #### X does underline/strikethrough here so we do the same.
572 On mswindows, underline/strikethrough really belongs to the font */
573 if (cachel->underline || cachel->strikethru)
574 mswindows_apply_face_effects (hdc, dl, xpos, this_width, fi,
575 cachel, cachel);
576 xpos += this_width; 565 xpos += this_width;
577 } 566 }
578 } 567 }
579 568
580 static void 569 static void
581 mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, 570 mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p,
582 int x, int y, 571 struct display_box* db,
583 int clip_x, int clip_y, 572 struct display_glyph_area* dga)
584 int clip_width, int clip_height, 573 {
585 int width, int height, int pixmap_offset, 574 HDC hdc = get_frame_dc (f);
586 int offset_bitmap) 575 HDC hcompdc = get_frame_compdc (f);
587 {
588 HDC hdc = FRAME_MSWINDOWS_DC (f);
589 HGDIOBJ old=NULL; 576 HGDIOBJ old=NULL;
590 COLORREF bgcolor = GetBkColor (hdc); 577 COLORREF bgcolor = GetBkColor (hdc);
591 int need_clipping = (clip_x || clip_y);
592 int yoffset=0;
593 int xoffset=0;
594
595 /* do we need to offset the pixmap vertically? this is necessary
596 for background pixmaps. */
597 if (offset_bitmap)
598 {
599 yoffset = y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
600 xoffset = x % IMAGE_INSTANCE_PIXMAP_WIDTH (p);
601 /* the width is handled by mswindows_output_pixmap_region */
602 }
603
604 if (need_clipping)
605 {
606 }
607 578
608 /* first blt the mask */ 579 /* first blt the mask */
609 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) 580 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
610 { 581 {
611 RGBQUAD col; 582 RGBQUAD col;
612 col.rgbBlue = GetBValue (bgcolor); 583 col.rgbBlue = GetBValue (bgcolor);
613 col.rgbRed = GetRValue (bgcolor); 584 col.rgbRed = GetRValue (bgcolor);
614 col.rgbGreen = GetGValue (bgcolor); 585 col.rgbGreen = GetGValue (bgcolor);
615 col.rgbReserved = 0; 586 col.rgbReserved = 0;
616 587
617 old = SelectObject (FRAME_MSWINDOWS_CDC (f), 588 old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p));
618 IMAGE_INSTANCE_MSWINDOWS_MASK (p));
619 589
620 SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); 590 SetDIBColorTable (hcompdc, 1, 1, &col);
621 591
622 BitBlt (hdc, 592 BitBlt (hdc,
623 x,y, 593 db->xpos, db->ypos,
624 width, height, 594 dga->width, dga->height,
625 FRAME_MSWINDOWS_CDC (f), 595 hcompdc,
626 xoffset,yoffset, 596 dga->xoffset, dga->yoffset,
627 SRCCOPY); 597 SRCCOPY);
628 598
629 SelectObject (FRAME_MSWINDOWS_CDC (f), old); 599 SelectObject (hcompdc, old);
630 } 600 }
631 601
632 /* now blt the bitmap itself. */ 602 /* Now blt the bitmap itself, or one of its slices. */
633 old = SelectObject (FRAME_MSWINDOWS_CDC (f), 603 old = SelectObject (hcompdc,
634 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); 604 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE
605 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)));
635 606
636 BitBlt (hdc, 607 BitBlt (hdc,
637 x,y, 608 db->xpos, db->ypos,
638 width, height, 609 dga->width, dga->height,
639 FRAME_MSWINDOWS_CDC (f), 610 hcompdc,
640 xoffset, yoffset, 611 dga->xoffset, dga->yoffset,
641 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); 612 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY);
642 613
643 SelectObject (FRAME_MSWINDOWS_CDC (f),old); 614 SelectObject (hcompdc, old);
644 615 }
645 if (need_clipping) 616
646 { 617 /* X gc's have this nice property that setting the bg pixmap will
647 }
648 }
649
650 /*
651 * X gc's have this nice property that setting the bg pixmap will
652 * output it offset relative to the window. Windows doesn't have this 618 * output it offset relative to the window. Windows doesn't have this
653 * feature so we have to emulate this by outputting multiple pixmaps 619 * feature so we have to emulate this by outputting multiple pixmaps.
654 */ 620 * This is only used for background pixmaps. Normal pixmaps are
621 * outputted once and are scrollable */
655 static void 622 static void
656 mswindows_output_dibitmap_region (struct frame *f, 623 mswindows_output_dibitmap_region (struct frame *f,
657 struct Lisp_Image_Instance *p, 624 Lisp_Image_Instance *p,
658 int x, int y, 625 struct display_box *db,
659 int clip_x, int clip_y, 626 struct display_glyph_area *dga)
660 int clip_width, int clip_height, 627 {
661 int width, int height, int pixmap_offset, 628 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height };
662 int offset_bitmap) 629 struct display_glyph_area xdga
663 { 630 = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p),
664 int pwidth = min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)); 631 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) };
665 int pheight = min (height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
666 int pxoffset = 0, pyoffset = 0; 632 int pxoffset = 0, pyoffset = 0;
633
634 if (dga)
635 {
636 xdga.width = dga->width;
637 xdga.height = dga->height;
638 }
639 else if (!redisplay_normalize_glyph_area (&xdb, &xdga))
640 return;
667 641
668 /* when doing a bg pixmap do a partial pixmap first so that we 642 /* when doing a bg pixmap do a partial pixmap first so that we
669 blt whole pixmaps thereafter */ 643 blt whole pixmaps thereafter */
670 644 xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) -
671 if (offset_bitmap) 645 db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
672 { 646
673 pheight = min (pheight, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - 647 while (xdga.height > 0)
674 y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); 648 {
675 } 649 xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)),
676 650 IMAGE_INSTANCE_PIXMAP_WIDTH (p) -
677 while (pheight > 0) 651 db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p));
678 { 652 pxoffset = 0;
679 if (offset_bitmap) 653 while (xdga.width > 0)
680 { 654 {
681 pwidth = min (min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), 655 xdb.xpos = db->xpos + pxoffset;
682 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - 656 xdb.ypos = db->ypos + pyoffset;
683 x % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); 657 /* do we need to offset the pixmap vertically? this is necessary
684 pxoffset = 0; 658 for background pixmaps. */
659 xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
660 xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p);
661 /* the width is handled by mswindows_output_pixmap_region */
662 mswindows_output_dibitmap (f, p, &xdb, &xdga);
663 pxoffset += xdga.width;
664 xdga.width = min ((db->width - pxoffset),
665 IMAGE_INSTANCE_PIXMAP_WIDTH (p));
685 } 666 }
686 while (pwidth > 0) 667 pyoffset += xdga.height;
687 { 668 xdga.height = min ((db->height - pyoffset),
688 mswindows_output_dibitmap (f, p, 669 IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
689 x + pxoffset, y + pyoffset, 670 }
690 clip_x, clip_y, 671 }
691 clip_width, clip_height, 672
692 pwidth, pheight, pixmap_offset, 673 /* Output a pixmap at the desired location.
693 offset_bitmap); 674 DB normalized display_box.
694 pxoffset += pwidth; 675 DGA normalized display_glyph_area. */
695 pwidth = min ((width-pxoffset), 676 static void
696 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); 677 mswindows_output_pixmap (struct window *w, Lisp_Object image_instance,
697 } 678 struct display_box *db, struct display_glyph_area *dga,
698 pyoffset += pheight; 679 face_index findex, int cursor_start, int cursor_width,
699 pheight = min ((height-pyoffset), 680 int cursor_height, int bg_pixmap)
700 IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
701 }
702 }
703
704 static void
705 mswindows_output_pixmap (struct window *w, struct display_line *dl,
706 Lisp_Object image_instance, int xpos, int xoffset,
707 int start_pixpos, int width, face_index findex,
708 int cursor_start, int cursor_width, int cursor_height,
709 int offset_bitmap)
710 { 681 {
711 struct frame *f = XFRAME (w->frame); 682 struct frame *f = XFRAME (w->frame);
712 HDC hdc = FRAME_MSWINDOWS_DC (f); 683 HDC hdc = get_frame_dc (f);
713 684
714 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); 685 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
715 Lisp_Object window; 686 Lisp_Object window;
716 687
717 int lheight = DISPLAY_LINE_HEIGHT (dl);
718 int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight :
719 IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
720 int clip_x, clip_y, clip_width, clip_height;
721
722 /* The pixmap_offset is used to center the pixmap on lines which are
723 shorter than it is. This results in odd effects when scrolling
724 pixmaps off of the bottom. Let's try not using it. */
725 #if 0
726 int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2;
727 #else
728 int pixmap_offset = 0;
729 #endif
730
731 XSETWINDOW (window, w); 688 XSETWINDOW (window, w);
732
733 if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset)
734 {
735 if (start_pixpos > xpos && start_pixpos > xpos + width)
736 return;
737
738 clip_x = xoffset;
739 clip_width = width;
740 if (start_pixpos > xpos)
741 {
742 clip_x += (start_pixpos - xpos);
743 clip_width -= (start_pixpos - xpos);
744 }
745 }
746 else
747 {
748 clip_x = 0;
749 clip_width = 0;
750 }
751
752 /* Place markers for possible future functionality (clipping the top
753 half instead of the bottom half; think pixel scrolling). */
754 clip_y = 0;
755 clip_height = pheight;
756
757 /* Clear the area the pixmap is going into. The pixmap itself will
758 always take care of the full width. We don't want to clear where
759 it is going to go in order to avoid flicker. So, all we have to
760 take care of is any area above or below the pixmap. */
761 /* #### We take a shortcut for now. We know that since we have
762 pixmap_offset hardwired to 0 that the pixmap is against the top
763 edge so all we have to worry about is below it. */
764 /* #### Unless the pixmap has a mask in which case we have to clear
765 the whole damn thing since we can't yet clear just the area not
766 included in the mask. */
767 if (((int) (dl->ypos - dl->ascent + pheight) <
768 (int) (dl->ypos + dl->descent - dl->clip))
769 || IMAGE_INSTANCE_MSWINDOWS_MASK (p))
770 {
771 int clear_x, clear_y, clear_width, clear_height;
772
773 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
774 {
775 clear_y = dl->ypos - dl->ascent;
776 clear_height = lheight;
777 }
778 else
779 {
780 clear_y = dl->ypos - dl->ascent + pheight;
781 clear_height = lheight - pheight;
782 }
783
784 if (start_pixpos >= 0 && start_pixpos > xpos)
785 {
786 clear_x = start_pixpos;
787 clear_width = xpos + width - start_pixpos;
788 }
789 else
790 {
791 clear_x = xpos;
792 clear_width = width;
793 }
794
795 if (!offset_bitmap) /* i.e. not a bg pixmap */
796 redisplay_clear_region (window, findex, clear_x, clear_y,
797 clear_width, clear_height);
798 }
799 689
800 /* Output the pixmap. Have to do this as many times as is required 690 /* Output the pixmap. Have to do this as many times as is required
801 to fill the given area */ 691 to fill the given area */
802 mswindows_update_dc (hdc, Qnil, 692 mswindows_update_dc (hdc,
803 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), 693 WINDOW_FACE_CACHEL_FOREGROUND (w, findex),
804 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); 694 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil);
805 695
806 mswindows_output_dibitmap_region (f, p, xpos - xoffset, 696 if (bg_pixmap)
807 dl->ypos - dl->ascent, 697 mswindows_output_dibitmap_region (f, p, db, dga);
808 clip_x, clip_y, clip_width, clip_height, 698 else
809 width + xoffset, pheight, pixmap_offset, 699 mswindows_output_dibitmap (f, p, db, dga);
810 offset_bitmap);
811 } 700 }
812 701
813 #ifdef HAVE_SCROLLBARS 702 #ifdef HAVE_SCROLLBARS
814 /* 703 /*
815 * This function paints window's deadbox, a rectangle between window 704 * This function paints window's deadbox, a rectangle between window
817 * 706 *
818 * Function checks whether deadbox intersects with the rectangle pointed 707 * Function checks whether deadbox intersects with the rectangle pointed
819 * to by PRC, and paints only the intersection 708 * to by PRC, and paints only the intersection
820 */ 709 */
821 static void 710 static void
822 mswindows_redisplay_deadbox_maybe (struct window *w, CONST RECT* prc) 711 mswindows_redisplay_deadbox_maybe (struct window *w, const RECT* prc)
823 { 712 {
824 int sbh = window_scrollbar_height (w); 713 int sbh = window_scrollbar_height (w);
825 int sbw = window_scrollbar_width (w); 714 int sbw = window_scrollbar_width (w);
826 RECT rect_dead, rect_paint; 715 RECT rect_dead, rect_paint;
827 if (sbh == 0 || sbw == 0) 716 if (sbh == 0 || sbw == 0)
840 rect_dead.bottom = rect_dead.top + sbh; 729 rect_dead.bottom = rect_dead.top + sbh;
841 730
842 if (IntersectRect (&rect_paint, &rect_dead, prc)) 731 if (IntersectRect (&rect_paint, &rect_dead, prc))
843 { 732 {
844 struct frame *f = XFRAME (WINDOW_FRAME (w)); 733 struct frame *f = XFRAME (WINDOW_FRAME (w));
845 FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint, 734 FillRect (get_frame_dc (f), &rect_paint,
846 (HBRUSH) (COLOR_BTNFACE+1)); 735 (HBRUSH) (COLOR_BTNFACE+1));
847 } 736 }
848 } 737 }
849 738
850 #endif /* HAVE_SCROLLBARS */ 739 #endif /* HAVE_SCROLLBARS */
897 } 786 }
898 787
899 for (line = 0; line < Dynarr_length (cdla); line++) 788 for (line = 0; line < Dynarr_length (cdla); line++)
900 { 789 {
901 struct display_line *cdl = Dynarr_atp (cdla, line); 790 struct display_line *cdl = Dynarr_atp (cdla, line);
902 int top_y = cdl->ypos - cdl->ascent; 791
903 int bottom_y = cdl->ypos + cdl->descent; 792 if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl)
904 793 >= rect_draw.top)
905 if (bottom_y >= rect_draw.top)
906 { 794 {
907 if (top_y > rect_draw.bottom) 795 if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom)
908 { 796 {
909 if (line == 0) 797 if (line == 0)
910 continue; 798 continue;
911 else 799 else
912 break; 800 break;
963 /* #### We would rather put these off as well but there is currently 851 /* #### We would rather put these off as well but there is currently
964 no combination of flags which will force an unchanged toolbar to 852 no combination of flags which will force an unchanged toolbar to
965 redraw anyhow. */ 853 redraw anyhow. */
966 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); 854 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height));
967 #endif 855 #endif
856 redraw_exposed_gutters (f, x, y, width, height);
968 857
969 if (!f->window_face_cache_reset) 858 if (!f->window_face_cache_reset)
970 { 859 {
971 mswindows_redraw_exposed_windows (f->root_window, x, y, width, height); 860 mswindows_redraw_exposed_windows (f->root_window, x, y, width, height);
972 GdiFlush(); 861 GdiFlush();
975 MARK_FRAME_CHANGED (f); 864 MARK_FRAME_CHANGED (f);
976 } 865 }
977 866
978 867
979 /***************************************************************************** 868 /*****************************************************************************
980 mswindows_bevel_modeline 869 mswindows_bevel_area
981 870
982 Draw a 3d border around the modeline on window W. 871 Draw a 3d border around the specified area on window W.
983 ****************************************************************************/ 872 ****************************************************************************/
984 static void 873 static void
985 mswindows_bevel_modeline (struct window *w, struct display_line *dl) 874 mswindows_bevel_area (struct window *w, face_index findex, int x, int y,
875 int width, int height, int thickness,
876 int edges, enum edge_style style)
986 { 877 {
987 struct frame *f = XFRAME (w->frame); 878 struct frame *f = XFRAME (w->frame);
988 Lisp_Object color;
989 int shadow_width = MODELINE_SHADOW_THICKNESS (w);
990 RECT rect = { WINDOW_MODELINE_LEFT (w),
991 dl->ypos - dl->ascent - shadow_width,
992 WINDOW_MODELINE_RIGHT (w),
993 dl->ypos + dl->descent + shadow_width};
994 UINT edge; 879 UINT edge;
995 880 UINT border = 0;
996 color = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); 881
997 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); 882 if (style == EDGE_ETCHED_IN)
998 883 edge = EDGE_ETCHED;
999 if (XINT (w->modeline_shadow_thickness) < 0) 884 else if (style == EDGE_ETCHED_OUT)
1000 shadow_width = -shadow_width; 885 edge = EDGE_BUMP;
1001 886 else if (style == EDGE_BEVEL_IN)
1002 if (shadow_width < -1) 887 {
1003 edge = EDGE_SUNKEN; 888 if (thickness == 1)
1004 else if (shadow_width < 0) 889 edge = BDR_SUNKENINNER;
1005 edge = BDR_SUNKENINNER; 890 else
1006 else if (shadow_width == 1) 891 edge = EDGE_SUNKEN;
1007 edge = BDR_RAISEDINNER; 892 }
1008 else 893 else /* EDGE_BEVEL_OUT */
1009 edge = EDGE_RAISED; 894 {
1010 895 if (thickness == 1)
1011 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, BF_RECT); 896 edge = BDR_RAISEDINNER;
897 else
898 edge = EDGE_RAISED;
899 }
900
901 if (edges & EDGE_TOP)
902 border |= BF_TOP;
903 if (edges & EDGE_LEFT)
904 border |= BF_LEFT;
905 if (edges & EDGE_BOTTOM)
906 border |= BF_BOTTOM;
907 if (edges & EDGE_RIGHT)
908 border |= BF_RIGHT;
909
910 {
911 RECT rect = { x, y, x + width, y + height };
912 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
913 HDC hdc = get_frame_dc (f);
914
915 mswindows_update_dc (hdc, Qnil, color, Qnil);
916 DrawEdge (hdc, &rect, edge, border);
917 }
1012 } 918 }
1013 919
1014 920
1015 /***************************************************************************** 921 /*****************************************************************************
1016 Display methods 922 Display methods
1061 967
1062 static int 968 static int
1063 mswindows_flash (struct device *d) 969 mswindows_flash (struct device *d)
1064 { 970 {
1065 struct frame *f = device_selected_frame (d); 971 struct frame *f = device_selected_frame (d);
972 HDC hdc = get_frame_dc (f);
1066 RECT rc; 973 RECT rc;
1067 974
1068 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc); 975 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc);
1069 InvertRect (FRAME_MSWINDOWS_DC (f), &rc); 976 InvertRect (hdc, &rc);
1070 GdiFlush (); 977 GdiFlush ();
1071 Sleep (25); 978 Sleep (25);
1072 InvertRect (FRAME_MSWINDOWS_DC (f), &rc); 979 InvertRect (hdc, &rc);
1073 980
1074 return 1; 981 return 1;
1075 } 982 }
1076 983
1077 static void 984 static void
1108 MULE is not defined */ 1015 MULE is not defined */
1109 XSETWINDOW (window, w); 1016 XSETWINDOW (window, w);
1110 rb = Dynarr_atp (rba, start); 1017 rb = Dynarr_atp (rba, start);
1111 1018
1112 if (!rb) 1019 if (!rb)
1113 {
1114 /* Nothing to do so don't do anything. */ 1020 /* Nothing to do so don't do anything. */
1115 return; 1021 return;
1116 } 1022
1117 else 1023 findex = rb->findex;
1118 { 1024 xpos = rb->xpos;
1119 findex = rb->findex; 1025 width = 0;
1120 xpos = rb->xpos; 1026 if (rb->type == RUNE_CHAR)
1121 width = 0; 1027 charset = CHAR_CHARSET (rb->object.chr.ch);
1122 if (rb->type == RUNE_CHAR)
1123 charset = CHAR_CHARSET (rb->object.chr.ch);
1124 }
1125 1028
1126 if (end < 0) 1029 if (end < 0)
1127 end = Dynarr_length (rba); 1030 end = Dynarr_length (rba);
1128 Dynarr_reset (buf); 1031 Dynarr_reset (buf);
1129 1032
1142 else 1045 else
1143 { 1046 {
1144 if (Dynarr_length (buf)) 1047 if (Dynarr_length (buf))
1145 { 1048 {
1146 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, 1049 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width,
1147 findex); 1050 findex, 0, 0, 0, 0);
1148 xpos = rb->xpos; 1051 xpos = rb->xpos;
1149 width = 0; 1052 width = 0;
1150 } 1053 }
1151 Dynarr_reset (buf); 1054 Dynarr_reset (buf);
1152 width = 0; 1055 width = 0;
1176 elt++; 1079 elt++;
1177 } 1080 }
1178 else if (rb->object.chr.ch == '\n') 1081 else if (rb->object.chr.ch == '\n')
1179 { 1082 {
1180 /* Clear in case a cursor was formerly here. */ 1083 /* Clear in case a cursor was formerly here. */
1181 int height = DISPLAY_LINE_HEIGHT (dl); 1084 redisplay_clear_region (window, findex, xpos,
1182 1085 DISPLAY_LINE_YPOS (dl),
1183 redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, 1086 rb->width, DISPLAY_LINE_HEIGHT (dl));
1184 rb->width, height);
1185 elt++; 1087 elt++;
1186 } 1088 }
1187 } 1089 }
1188 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) 1090 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE)
1189 { 1091 {
1215 } 1117 }
1216 } 1118 }
1217 else if (rb->type == RUNE_DGLYPH) 1119 else if (rb->type == RUNE_DGLYPH)
1218 { 1120 {
1219 Lisp_Object instance; 1121 Lisp_Object instance;
1122 struct display_box dbox;
1123 struct display_glyph_area dga;
1124 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset,
1125 start_pixpos, rb->width,
1126 &dbox, &dga);
1220 1127
1221 XSETWINDOW (window, w); 1128 XSETWINDOW (window, w);
1222 instance = glyph_image_instance (rb->object.dglyph.glyph, 1129 instance = glyph_image_instance (rb->object.dglyph.glyph,
1223 window, ERROR_ME_NOT, 1); 1130 window, ERROR_ME_NOT, 1);
1224 findex = rb->findex; 1131 findex = rb->findex;
1239 mswindows_output_cursor (w, dl, xpos, cursor_width, 1146 mswindows_output_cursor (w, dl, xpos, cursor_width,
1240 findex, Dynarr_at (buf, 0), 0); 1147 findex, Dynarr_at (buf, 0), 0);
1241 else /* #### redisplay-x passes -1 as the width: why ? */ 1148 else /* #### redisplay-x passes -1 as the width: why ? */
1242 mswindows_output_string (w, dl, buf, xpos, 1149 mswindows_output_string (w, dl, buf, xpos,
1243 rb->object.dglyph.xoffset, 1150 rb->object.dglyph.xoffset,
1244 start_pixpos, rb->width, findex); 1151 start_pixpos, rb->width, findex,
1152 0, 0, 0, 0);
1245 Dynarr_reset (buf); 1153 Dynarr_reset (buf);
1246 } 1154 }
1247 break; 1155 break;
1248 1156
1249 case IMAGE_MONO_PIXMAP: 1157 case IMAGE_MONO_PIXMAP:
1250 case IMAGE_COLOR_PIXMAP: 1158 case IMAGE_COLOR_PIXMAP:
1251 mswindows_output_pixmap (w, dl, instance, xpos, 1159 redisplay_output_pixmap (w, instance, &dbox, &dga, findex,
1252 rb->object.dglyph.xoffset, start_pixpos, 1160 cursor_start, cursor_width,
1253 rb->width, findex, cursor_start, 1161 cursor_height, 0);
1254 cursor_width, cursor_height, 0);
1255 if (rb->cursor_type == CURSOR_ON) 1162 if (rb->cursor_type == CURSOR_ON)
1256 mswindows_output_cursor (w, dl, xpos, cursor_width, 1163 mswindows_output_cursor (w, dl, xpos, cursor_width,
1257 findex, 0, 1); 1164 findex, 0, 1);
1258 break; 1165 break;
1259 1166
1260 case IMAGE_POINTER: 1167 case IMAGE_POINTER:
1261 abort (); 1168 abort ();
1262 1169
1263 case IMAGE_SUBWINDOW: 1170 case IMAGE_SUBWINDOW:
1264 case IMAGE_WIDGET: 1171 case IMAGE_WIDGET:
1265 redisplay_output_subwindow (w, dl, instance, xpos, 1172 redisplay_output_subwindow (w, instance, &dbox, &dga, findex,
1266 rb->object.dglyph.xoffset, start_pixpos, 1173 cursor_start, cursor_width,
1267 rb->width, findex, cursor_start, 1174 cursor_height);
1268 cursor_width, cursor_height); 1175 if (rb->cursor_type == CURSOR_ON)
1176 mswindows_output_cursor (w, dl, xpos, cursor_width,
1177 findex, 0, 1);
1178 break;
1179
1180 case IMAGE_LAYOUT:
1181 redisplay_output_layout (w, instance, &dbox, &dga, findex,
1182 cursor_start, cursor_width,
1183 cursor_height);
1269 if (rb->cursor_type == CURSOR_ON) 1184 if (rb->cursor_type == CURSOR_ON)
1270 mswindows_output_cursor (w, dl, xpos, cursor_width, 1185 mswindows_output_cursor (w, dl, xpos, cursor_width,
1271 findex, 0, 1); 1186 findex, 0, 1);
1272 break; 1187 break;
1273 1188
1286 abort (); 1201 abort ();
1287 } 1202 }
1288 } 1203 }
1289 1204
1290 if (Dynarr_length (buf)) 1205 if (Dynarr_length (buf))
1291 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex); 1206 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex,
1207 0, 0, 0, 0);
1292 1208
1293 if (dl->modeline 1209 if (dl->modeline
1294 && !EQ (Qzero, w->modeline_shadow_thickness) 1210 && !EQ (Qzero, w->modeline_shadow_thickness)
1295 && (f->clear 1211 && (f->clear
1296 || f->windows_structure_changed 1212 || f->windows_structure_changed
1297 || w->shadow_thickness_changed)) 1213 || w->shadow_thickness_changed))
1298 mswindows_bevel_modeline (w, dl); 1214 bevel_modeline (w, dl);
1299 1215
1300 Dynarr_free (buf); 1216 Dynarr_free (buf);
1301 } 1217 }
1302 1218
1303 1219
1308 ****************************************************************************/ 1224 ****************************************************************************/
1309 static void 1225 static void
1310 mswindows_output_vertical_divider (struct window *w, int clear_unused) 1226 mswindows_output_vertical_divider (struct window *w, int clear_unused)
1311 { 1227 {
1312 struct frame *f = XFRAME (w->frame); 1228 struct frame *f = XFRAME (w->frame);
1229 HDC hdc = get_frame_dc (f);
1313 RECT rect; 1230 RECT rect;
1314 int spacing = XINT (w->vertical_divider_spacing); 1231 int spacing = XINT (w->vertical_divider_spacing);
1315 int shadow = XINT (w->vertical_divider_shadow_thickness); 1232 int shadow = XINT (w->vertical_divider_shadow_thickness);
1316 int abs_shadow = abs (shadow); 1233 int abs_shadow = abs (shadow);
1317 int line_width = XINT (w->vertical_divider_line_width); 1234 int line_width = XINT (w->vertical_divider_line_width);
1318 int div_left = WINDOW_RIGHT (w) - window_divider_width (w); 1235 int div_left = WINDOW_RIGHT (w) - window_divider_width (w);
1236 int y1 = WINDOW_TOP (w) + FRAME_TOP_GUTTER_BOUNDS (f);
1237 int y2 = WINDOW_BOTTOM (w) + FRAME_BOTTOM_GUTTER_BOUNDS (f);
1319 1238
1320 /* Clear left and right spacing areas */ 1239 /* Clear left and right spacing areas */
1321 if (spacing) 1240 if (spacing)
1322 { 1241 {
1323 rect.top = WINDOW_TOP (w); 1242 rect.top = y1;
1324 rect.bottom = WINDOW_BOTTOM (w); 1243 rect.bottom = y2;
1325 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, 1244 mswindows_update_dc (hdc, Qnil,
1326 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); 1245 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil);
1327 rect.right = WINDOW_RIGHT (w); 1246 rect.right = WINDOW_RIGHT (w);
1328 rect.left = rect.right - spacing; 1247 rect.left = rect.right - spacing;
1329 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1248 ExtTextOut (hdc, 0, 0, ETO_OPAQUE,
1330 &rect, NULL, 0, NULL); 1249 &rect, NULL, 0, NULL);
1331 rect.left = div_left; 1250 rect.left = div_left;
1332 rect.right = div_left + spacing; 1251 rect.right = div_left + spacing;
1333 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1252 ExtTextOut (hdc, 0, 0, ETO_OPAQUE,
1334 &rect, NULL, 0, NULL); 1253 &rect, NULL, 0, NULL);
1335 } 1254 }
1336 1255
1337 /* Clear divider face */ 1256 /* Clear divider face */
1338 rect.top = WINDOW_TOP (w) + abs_shadow; 1257 rect.top = y1 + abs_shadow;
1339 rect.bottom = WINDOW_BOTTOM (w) - abs_shadow; 1258 rect.bottom = y2 - abs_shadow;
1340 rect.left = div_left + spacing + abs_shadow; 1259 rect.left = div_left + spacing + abs_shadow;
1341 rect.right = rect.left + line_width; 1260 rect.right = rect.left + line_width;
1342 if (rect.left < rect.right) 1261 if (rect.left < rect.right)
1343 { 1262 {
1344 face_index div_face 1263 face_index div_face
1345 = get_builtin_face_cache_index (w, Vvertical_divider_face); 1264 = get_builtin_face_cache_index (w, Vvertical_divider_face);
1346 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, 1265 mswindows_update_dc (hdc, Qnil,
1347 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); 1266 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil);
1348 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1267 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
1349 &rect, NULL, 0, NULL);
1350 } 1268 }
1351 1269
1352 /* Draw a shadow around the divider */ 1270 /* Draw a shadow around the divider */
1353 if (shadow != 0) 1271 if (shadow != 0)
1354 { 1272 {
1355 /* #### This will be fixed to support arbitrary thickness */ 1273 /* #### This will be fixed to support arbitrary thickness */
1356 InflateRect (&rect, abs_shadow, abs_shadow); 1274 InflateRect (&rect, abs_shadow, abs_shadow);
1357 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, 1275 DrawEdge (hdc, &rect,
1358 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); 1276 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT);
1359 } 1277 }
1360 } 1278 }
1361 1279
1362 /**************************************************************************** 1280 /****************************************************************************
1365 Given a string and a face, return the string's length in pixels when 1283 Given a string and a face, return the string's length in pixels when
1366 displayed in the font associated with the face. 1284 displayed in the font associated with the face.
1367 ****************************************************************************/ 1285 ****************************************************************************/
1368 static int 1286 static int
1369 mswindows_text_width (struct frame *f, struct face_cachel *cachel, 1287 mswindows_text_width (struct frame *f, struct face_cachel *cachel,
1370 CONST Emchar *str, Charcount len) 1288 const Emchar *str, Charcount len)
1371 { 1289 {
1290 HDC hdc = get_frame_dc (f);
1372 int width_so_far = 0; 1291 int width_so_far = 0;
1373 unsigned char *text_storage = (unsigned char *) alloca (2 * len); 1292 unsigned char *text_storage = (unsigned char *) alloca (2 * len);
1374 textual_run *runs = alloca_array (textual_run, len); 1293 textual_run *runs = alloca_array (textual_run, len);
1375 int nruns; 1294 int nruns;
1376 int i; 1295 int i;
1377 1296
1378 nruns = separate_textual_runs (text_storage, runs, str, len); 1297 nruns = separate_textual_runs (text_storage, runs, str, len);
1379 1298
1380 for (i = 0; i < nruns; i++) 1299 for (i = 0; i < nruns; i++)
1381 width_so_far += mswindows_text_width_single_run (FRAME_MSWINDOWS_DC (f), 1300 width_so_far += mswindows_text_width_single_run (hdc,
1382 cachel, runs + i); 1301 cachel, runs + i);
1383 1302
1384 return width_so_far; 1303 return width_so_far;
1385 } 1304 }
1386 1305
1396 face_index findex, int x, int y, 1315 face_index findex, int x, int y,
1397 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, 1316 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor,
1398 Lisp_Object background_pixmap) 1317 Lisp_Object background_pixmap)
1399 { 1318 {
1400 RECT rect = { x, y, x+width, y+height }; 1319 RECT rect = { x, y, x+width, y+height };
1320 HDC hdc = get_frame_dc (f);
1401 1321
1402 if (!NILP (background_pixmap)) 1322 if (!NILP (background_pixmap))
1403 { 1323 {
1404 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), 1324 struct display_box db = { x, y, width, height };
1405 Qnil, fcolor, bcolor, background_pixmap); 1325 mswindows_update_dc (hdc,
1406 1326 fcolor, bcolor, background_pixmap);
1407 mswindows_output_dibitmap_region 1327 mswindows_output_dibitmap_region
1408 ( f, XIMAGE_INSTANCE (background_pixmap), 1328 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0);
1409 x, y, 0, 0, 0, 0, width, height, 0, TRUE);
1410 } 1329 }
1411 else 1330 else
1412 { 1331 {
1413 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, fcolor, Qnil); 1332 mswindows_update_dc (hdc, Qnil, fcolor, Qnil);
1414 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1333 ExtTextOut (hdc, 0, 0, ETO_OPAQUE,
1415 &rect, NULL, 0, NULL); 1334 &rect, NULL, 0, NULL);
1416 } 1335 }
1417 1336
1418 #ifdef HAVE_SCROLLBARS 1337 #ifdef HAVE_SCROLLBARS
1419 if (WINDOWP (locale)) 1338 if (WINDOWP (locale))
1420 mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect); 1339 mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect);
1421 #endif 1340 #endif
1422 } 1341 }
1423 1342
1424 /*****************************************************************************
1425 mswindows_clear_to_window_end
1426
1427 Clear the area between ypos1 and ypos2. Each margin area and the
1428 text area is handled separately since they may each have their own
1429 background color.
1430 ****************************************************************************/
1431 static void
1432 mswindows_clear_to_window_end (struct window *w, int ypos1, int ypos2)
1433 {
1434 int height = ypos2 - ypos1;
1435
1436 if (height)
1437 {
1438 struct frame *f = XFRAME (w->frame);
1439 Lisp_Object window;
1440 int bflag = (window_needs_vertical_divider (w) ? 0 : 1);
1441 layout_bounds bounds;
1442
1443 bounds = calculate_display_line_boundaries (w, bflag);
1444 XSETWINDOW (window, w);
1445
1446 if (window_is_leftmost (w))
1447 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f),
1448 ypos1, FRAME_BORDER_WIDTH (f), height);
1449
1450 if (bounds.left_in - bounds.left_out > 0)
1451 redisplay_clear_region (window,
1452 get_builtin_face_cache_index (w, Vleft_margin_face),
1453 bounds.left_out, ypos1,
1454 bounds.left_in - bounds.left_out, height);
1455
1456 if (bounds.right_in - bounds.left_in > 0)
1457 redisplay_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1,
1458 bounds.right_in - bounds.left_in, height);
1459
1460 if (bounds.right_out - bounds.right_in > 0)
1461 redisplay_clear_region (window,
1462 get_builtin_face_cache_index (w, Vright_margin_face),
1463 bounds.right_in, ypos1,
1464 bounds.right_out - bounds.right_in, height);
1465
1466 if (window_is_rightmost (w))
1467 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f),
1468 ypos1, FRAME_BORDER_WIDTH (f), height);
1469 }
1470
1471 }
1472
1473
1474 /* XXX Implement me! */ 1343 /* XXX Implement me! */
1475 static void 1344 static void
1476 mswindows_clear_frame (struct frame *f) 1345 mswindows_clear_frame (struct frame *f)
1477 { 1346 {
1478 GdiFlush(); 1347 GdiFlush();
1485 /************************************************************************/ 1354 /************************************************************************/
1486 1355
1487 void 1356 void
1488 console_type_create_redisplay_mswindows (void) 1357 console_type_create_redisplay_mswindows (void)
1489 { 1358 {
1490 /* redisplay methods */ 1359 /* redisplay methods - display*/
1491 CONSOLE_HAS_METHOD (mswindows, text_width); 1360 CONSOLE_HAS_METHOD (mswindows, text_width);
1492 CONSOLE_HAS_METHOD (mswindows, output_display_block); 1361 CONSOLE_HAS_METHOD (mswindows, output_display_block);
1493 CONSOLE_HAS_METHOD (mswindows, divider_height); 1362 CONSOLE_HAS_METHOD (mswindows, divider_height);
1494 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width); 1363 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width);
1495 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider); 1364 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider);
1496 CONSOLE_HAS_METHOD (mswindows, clear_to_window_end);
1497 CONSOLE_HAS_METHOD (mswindows, clear_region); 1365 CONSOLE_HAS_METHOD (mswindows, clear_region);
1498 CONSOLE_HAS_METHOD (mswindows, clear_frame); 1366 CONSOLE_HAS_METHOD (mswindows, clear_frame);
1499 CONSOLE_HAS_METHOD (mswindows, output_begin); 1367 CONSOLE_HAS_METHOD (mswindows, output_begin);
1500 CONSOLE_HAS_METHOD (mswindows, output_end); 1368 CONSOLE_HAS_METHOD (mswindows, output_end);
1501 CONSOLE_HAS_METHOD (mswindows, flash); 1369 CONSOLE_HAS_METHOD (mswindows, flash);
1502 CONSOLE_HAS_METHOD (mswindows, ring_bell); 1370 CONSOLE_HAS_METHOD (mswindows, ring_bell);
1503 } 1371 CONSOLE_HAS_METHOD (mswindows, bevel_area);
1372 CONSOLE_HAS_METHOD (mswindows, output_string);
1373 CONSOLE_HAS_METHOD (mswindows, output_pixmap);
1374
1375 /* redisplay methods - printer */
1376 CONSOLE_INHERITS_METHOD (msprinter, mswindows, text_width);
1377 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_display_block);
1378 CONSOLE_INHERITS_METHOD (msprinter, mswindows, divider_height);
1379 CONSOLE_INHERITS_METHOD (msprinter, mswindows, eol_cursor_width);
1380 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_vertical_divider);
1381 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_region);
1382 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_frame);
1383 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_begin);
1384 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_end);
1385 CONSOLE_INHERITS_METHOD (msprinter, mswindows, bevel_area);
1386 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_string);
1387 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_pixmap);
1388 }