comparison src/redisplay-msw.c @ 440:8de8e3f6228a r21-2-28

Import from CVS: tag r21-2-28
author cvs
date Mon, 13 Aug 2007 11:33:38 +0200
parents 3ecd8885ac67
children abe6d1db359e
comparison
equal deleted inserted replaced
439:357dd071b03c 440:8de8e3f6228a
44 #include "gutter.h" 44 #include "gutter.h"
45 #include "redisplay.h" 45 #include "redisplay.h"
46 #include "sysdep.h" 46 #include "sysdep.h"
47 #include "window.h" 47 #include "window.h"
48 48
49 #include "windows.h"
50 #ifdef MULE 49 #ifdef MULE
51 #include "mule-ccl.h" 50 #include "mule-ccl.h"
52 #include "mule-charset.h" 51 #include "mule-charset.h"
53 #endif 52 #endif
54 53
55 #define MSWINDOWS_EOL_CURSOR_WIDTH 5 54 #define MSWINDOWS_EOL_CURSOR_WIDTH 5
56 55
57 /* 56 /*
58 * Random forward declarations 57 * Random forward declarations
59 */ 58 */
60 static void mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, 59 static void mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg,
61 Lisp_Object bg, Lisp_Object bg_pmap); 60 Lisp_Object bg_pmap);
61 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font,
62 int under, int strike);
62 static void mswindows_output_vertical_divider (struct window *w, int clear); 63 static void mswindows_output_vertical_divider (struct window *w, int clear);
63 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, 64 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x,
64 int y, int width, int height); 65 int y, int width, int height);
65 static void mswindows_output_dibitmap (struct frame *f, 66 static void mswindows_output_dibitmap (struct frame *f,
66 struct Lisp_Image_Instance *p, 67 Lisp_Image_Instance *p,
67 struct display_box* db, 68 struct display_box* db,
68 struct display_glyph_area* dga); 69 struct display_glyph_area* dga);
69 70
70 typedef struct textual_run 71 typedef struct textual_run
71 { 72 {
181 static int 182 static int
182 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, 183 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel,
183 textual_run *run) 184 textual_run *run)
184 { 185 {
185 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); 186 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset);
186 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); 187 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst);
187 SIZE size; 188 SIZE size;
188 189
189 if (!fi->proportional_p || !hdc) 190 if (!fi->proportional_p || !hdc)
190 return (fi->width * run->len); 191 return (fi->width * run->len);
191 else 192 else
192 { 193 {
193 assert(run->dimension == 1); /* #### FIXME! */ 194 assert(run->dimension == 1); /* #### FIXME! */
194 mswindows_update_dc (hdc, font_inst, Qnil, Qnil, Qnil); 195 mswindows_set_dc_font (hdc, font_inst,
196 cachel->underline, cachel->strikethru);
195 GetTextExtentPoint32 (hdc, run->ptr, run->len, &size); 197 GetTextExtentPoint32 (hdc, run->ptr, run->len, &size);
196 return(size.cx); 198 return(size.cx);
197 } 199 }
198 } 200 }
199 201
202 /*
203 * Given F, retrieve device context. F can be a display frame, or
204 * a print job.
205 */
206 static HDC
207 get_frame_dc (struct frame *f)
208 {
209 if (FRAME_MSWINDOWS_P (f))
210 return FRAME_MSWINDOWS_DC (f);
211 else
212 return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
213 }
214
215 /*
216 * Given F, retrieve compatible device context. F can be a display
217 * frame, or a print job.
218 */
219 static HDC
220 get_frame_compdc (struct frame *f)
221 {
222 if (FRAME_MSWINDOWS_P (f))
223 return FRAME_MSWINDOWS_CDC (f);
224 else
225 return FRAME_MSPRINTER_CDC (f);
226 }
200 227
201 /***************************************************************************** 228 /*****************************************************************************
202 mswindows_update_dc 229 mswindows_update_dc
203 230
204 Given a number of parameters munge the DC so it has those properties. 231 Given a number of parameters munge the DC so it has those properties.
205 ****************************************************************************/ 232 ****************************************************************************/
206 static void 233 static void
207 mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, 234 mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg,
208 Lisp_Object bg, Lisp_Object bg_pmap) 235 Lisp_Object bg_pmap)
209 { 236 {
210 if (!NILP (font))
211 SelectObject(hdc, FONT_INSTANCE_MSWINDOWS_HFONT (XFONT_INSTANCE (font)));
212
213
214 if (!NILP (fg)) 237 if (!NILP (fg))
215 { 238 {
216 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR 239 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR
217 (XCOLOR_INSTANCE (fg))); 240 (XCOLOR_INSTANCE (fg)));
218 } 241 }
242
219 if (!NILP (bg)) 243 if (!NILP (bg))
220 { 244 {
221 SetBkMode (hdc, OPAQUE); 245 SetBkMode (hdc, OPAQUE);
222 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg))); 246 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg)));
223 } 247 }
225 { 249 {
226 SetBkMode (hdc, TRANSPARENT); 250 SetBkMode (hdc, TRANSPARENT);
227 } 251 }
228 } 252 }
229 253
230 254 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font,
231 /***************************************************************************** 255 int under, int strike)
232 mswindows_apply_face_effects 256 {
233 257 SelectObject(hdc, mswindows_get_hfont (XFONT_INSTANCE (font),
234 Draw underline and strikeout as if this was X. 258 under, strike));
235 #### On mswindows this really should be done as part of drawing the font. 259 }
236 The line width used is chosen arbitrarily from the font height.
237 ****************************************************************************/
238 static void
239 mswindows_apply_face_effects (HDC hdc, struct display_line *dl, int xpos,
240 int width, struct Lisp_Font_Instance *fi,
241 struct face_cachel *cachel,
242 struct face_cachel *color_cachel)
243 {
244 int yclip;
245 HBRUSH brush, oldbrush;
246 RECT rect;
247
248 brush = CreateSolidBrush (COLOR_INSTANCE_MSWINDOWS_COLOR (
249 XCOLOR_INSTANCE (color_cachel->foreground)));
250 if (brush)
251 {
252 yclip = dl->ypos + dl->descent - dl->clip;
253 rect.left = xpos;
254 rect.right = xpos + width;
255 oldbrush = SelectObject (hdc, brush);
256
257 if (cachel->underline)
258 {
259 rect.top = dl->ypos + dl->descent/2;
260 rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1);
261 if (rect.bottom <= yclip)
262 FillRect (hdc, &rect, brush);
263 }
264 if (cachel->strikethru)
265 {
266 rect.top = dl->ypos + dl->descent - (dl->ascent + dl->descent)/2;
267 rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1);
268 if (rect.bottom <= yclip)
269 FillRect (hdc, &rect, brush);
270 }
271
272 SelectObject (hdc, oldbrush);
273 DeleteObject (brush);
274 }
275 }
276
277 260
278 /***************************************************************************** 261 /*****************************************************************************
279 mswindows_output_hline 262 mswindows_output_hline
280 263
281 Output a horizontal line in the foreground of its face. 264 Output a horizontal line in the foreground of its face.
295 static void 278 static void
296 mswindows_output_blank (struct window *w, struct display_line *dl, 279 mswindows_output_blank (struct window *w, struct display_line *dl,
297 struct rune *rb, int start_pixpos) 280 struct rune *rb, int start_pixpos)
298 { 281 {
299 struct frame *f = XFRAME (w->frame); 282 struct frame *f = XFRAME (w->frame);
283 HDC hdc = get_frame_dc (f);
300 RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), 284 RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl),
301 rb->xpos+rb->width, 285 rb->xpos+rb->width,
302 DISPLAY_LINE_YEND (dl) }; 286 DISPLAY_LINE_YEND (dl) };
303 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); 287 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex);
304 288
319 redisplay_calculate_display_boxes (dl, rb->xpos, 303 redisplay_calculate_display_boxes (dl, rb->xpos,
320 /*rb->object.dglyph.xoffset*/ 0, 304 /*rb->object.dglyph.xoffset*/ 0,
321 start_pixpos, rb->width, 305 start_pixpos, rb->width,
322 &db, &dga); 306 &db, &dga);
323 /* blank the background in the appropriate color */ 307 /* blank the background in the appropriate color */
324 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, 308 mswindows_update_dc (hdc, cachel->foreground,
325 cachel->background, Qnil); 309 cachel->background, Qnil);
326 redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, 310 redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex,
327 0, 0, 0, TRUE); 311 0, 0, 0, TRUE);
328 } 312 }
329 else 313 else
330 { 314 {
331 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, 315 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil);
332 cachel->background, Qnil); 316 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 } 317 }
337 } 318 }
338 319
339 320
340 /***************************************************************************** 321 /*****************************************************************************
350 struct frame *f = XFRAME (w->frame); 331 struct frame *f = XFRAME (w->frame);
351 struct device *d = XDEVICE (f->device); 332 struct device *d = XDEVICE (f->device);
352 struct face_cachel *cachel=0; 333 struct face_cachel *cachel=0;
353 Lisp_Object font = Qnil; 334 Lisp_Object font = Qnil;
354 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); 335 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
355 HDC hdc = FRAME_MSWINDOWS_DC (f); 336 HDC hdc = get_frame_dc (f);
356 unsigned int face_index=0; 337 unsigned int local_face_index=0;
357 char *p_char = NULL; 338 char *p_char = NULL;
358 int n_char = 0; 339 int n_char = 0;
359 RECT rect = { xpos, 340 RECT rect = { xpos,
360 DISPLAY_LINE_YPOS (dl), 341 DISPLAY_LINE_YPOS (dl),
361 xpos + width, 342 xpos + width,
390 struct face_cachel *color_cachel; 371 struct face_cachel *color_cachel;
391 372
392 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar 373 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar
393 or when we need to erase the cursor. Output nothing at eol if bar 374 or when we need to erase the cursor. Output nothing at eol if bar
394 cursor */ 375 cursor */
395 face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); 376 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face);
396 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? 377 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ?
397 findex : face_index)); 378 findex : local_face_index));
398 mswindows_update_dc (hdc, font, color_cachel->foreground, 379 mswindows_update_dc (hdc, color_cachel->foreground,
399 color_cachel->background, Qnil); 380 color_cachel->background, Qnil);
381 if (real_char_p)
382 mswindows_set_dc_font (hdc, font,
383 cachel->underline, cachel->strikethru);
384
400 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL); 385 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL);
401 if (real_char_p && (cachel->underline || cachel->strikethru))
402 mswindows_apply_face_effects (hdc, dl, xpos, width,
403 XFONT_INSTANCE (font),
404 cachel, color_cachel);
405 } 386 }
406 387
407 if (!cursor_p) 388 if (!cursor_p)
408 return; 389 return;
409 390
410 if (focus && bar_p) 391 if (focus && bar_p)
411 { 392 {
412 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); 393 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width));
413 face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); 394 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face);
414 cachel = WINDOW_FACE_CACHEL (w, face_index); 395 cachel = WINDOW_FACE_CACHEL (w, local_face_index);
415 mswindows_update_dc (hdc, Qnil, Qnil, cachel->background, Qnil); 396 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil);
416 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); 397 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL);
417 } 398 }
418 else if (!focus) 399 else if (!focus)
419 { 400 {
420 /* Now have real character drawn in its own color. We deflate 401 /* Now have real character drawn in its own color. We deflate
426 { 407 {
427 p_char = (char*) &ch; 408 p_char = (char*) &ch;
428 n_char = 1; 409 n_char = 1;
429 } 410 }
430 411
431 face_index = get_builtin_face_cache_index (w, Vdefault_face); 412 local_face_index = get_builtin_face_cache_index (w, Vdefault_face);
432 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : face_index)); 413 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index));
433 mswindows_update_dc (hdc, Qnil, cachel->foreground, 414 mswindows_update_dc (hdc,
434 cachel->background, Qnil); 415 cachel->foreground, cachel->background, Qnil);
435 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, 416 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED,
436 &rect, p_char, n_char, NULL); 417 &rect, p_char, n_char, NULL);
437 if (cachel->underline || cachel->strikethru)
438 mswindows_apply_face_effects (hdc, dl, xpos+1, width-2,
439 XFONT_INSTANCE (font),
440 cachel, cachel);
441 } 418 }
442 } 419 }
443 420
444 421
445 /***************************************************************************** 422 /*****************************************************************************
464 CLIP_START Clip everything left of this X position. 441 CLIP_START Clip everything left of this X position.
465 WIDTH Clip everything right of XPOS + WIDTH. 442 WIDTH Clip everything right of XPOS + WIDTH.
466 FINDEX Index for the face cache element describing how to display 443 FINDEX Index for the face cache element describing how to display
467 the text. 444 the text.
468 ****************************************************************************/ 445 ****************************************************************************/
469 void 446 static void
470 mswindows_output_string (struct window *w, struct display_line *dl, 447 mswindows_output_string (struct window *w, struct display_line *dl,
471 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, 448 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start,
472 int width, face_index findex, 449 int width, face_index findex,
473 int cursor, int cursor_start, int cursor_width, 450 int cursor, int cursor_start, int cursor_width,
474 int cursor_height) 451 int cursor_height)
475 { 452 {
476 struct frame *f = XFRAME (w->frame); 453 struct frame *f = XFRAME (w->frame);
477 /* struct device *d = XDEVICE (f->device);*/ 454 /* struct device *d = XDEVICE (f->device);*/
478 Lisp_Object window; 455 Lisp_Object window;
479 HDC hdc = FRAME_MSWINDOWS_DC (f); 456 HDC hdc = get_frame_dc (f);
480 int clip_end; 457 int clip_end;
481 Lisp_Object bg_pmap; 458 Lisp_Object bg_pmap;
482 int len = Dynarr_length (buf); 459 int len = Dynarr_length (buf);
483 unsigned char *text_storage = (unsigned char *) alloca (2 * len); 460 unsigned char *text_storage = (unsigned char *) alloca (2 * len);
484 textual_run *runs = alloca_array (textual_run, len); 461 textual_run *runs = alloca_array (textual_run, len);
529 struct display_box db; 506 struct display_box db;
530 struct display_glyph_area dga; 507 struct display_glyph_area dga;
531 redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, 508 redisplay_calculate_display_boxes (dl, xpos + xoffset, 0,
532 clip_start, width, &db, &dga); 509 clip_start, width, &db, &dga);
533 /* blank the background in the appropriate color */ 510 /* blank the background in the appropriate color */
534 mswindows_update_dc (hdc, Qnil, cachel->foreground, 511 mswindows_update_dc (hdc,
535 cachel->background, Qnil); 512 cachel->foreground, cachel->background, Qnil);
536 redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, 513 redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex,
537 0, 0, 0, TRUE); 514 0, 0, 0, TRUE);
538 /* output pixmap calls this so we have to recall to get correct 515 /* output pixmap calls this so we have to recall to get correct
539 references */ 516 references */
540 cachel = WINDOW_FACE_CACHEL (w, findex); 517 cachel = WINDOW_FACE_CACHEL (w, findex);
544 Dynarr_length (buf)); 521 Dynarr_length (buf));
545 522
546 for (i = 0; i < nruns; i++) 523 for (i = 0; i < nruns; i++)
547 { 524 {
548 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); 525 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset);
549 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); 526 Lisp_Font_Instance *fi = XFONT_INSTANCE (font);
550 int this_width; 527 int this_width;
551 528
552 if (EQ (font, Vthe_null_font_instance)) 529 if (EQ (font, Vthe_null_font_instance))
553 continue; 530 continue;
554 531
555 mswindows_update_dc (hdc, font, cachel->foreground, 532 mswindows_update_dc (hdc, cachel->foreground,
556 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); 533 NILP(bg_pmap) ? cachel->background : Qnil, Qnil);
534 mswindows_set_dc_font (hdc, font, cachel->underline, cachel->strikethru);
557 535
558 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); 536 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i);
559 537
560 /* cope with fonts taller than lines */ 538 /* cope with fonts taller than lines */
561 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) 539 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip))
577 assert (runs[i].dimension == 1); /* #### FIXME: Broken when Mule? */ 555 assert (runs[i].dimension == 1); /* #### FIXME: Broken when Mule? */
578 ExtTextOut (hdc, xpos, dl->ypos, 556 ExtTextOut (hdc, xpos, dl->ypos,
579 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, 557 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED,
580 &rect, (char *) runs[i].ptr, runs[i].len, NULL); 558 &rect, (char *) runs[i].ptr, runs[i].len, NULL);
581 559
582 /* #### X does underline/strikethrough here so we do the same.
583 On mswindows, underline/strikethrough really belongs to the font */
584 if (cachel->underline || cachel->strikethru)
585 mswindows_apply_face_effects (hdc, dl, xpos, this_width, fi,
586 cachel, cachel);
587 xpos += this_width; 560 xpos += this_width;
588 } 561 }
589 } 562 }
590 563
591 static void 564 static void
592 mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, 565 mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p,
593 struct display_box* db, 566 struct display_box* db,
594 struct display_glyph_area* dga) 567 struct display_glyph_area* dga)
595 { 568 {
596 HDC hdc = FRAME_MSWINDOWS_DC (f); 569 HDC hdc = get_frame_dc (f);
570 HDC hcompdc = get_frame_compdc (f);
597 HGDIOBJ old=NULL; 571 HGDIOBJ old=NULL;
598 COLORREF bgcolor = GetBkColor (hdc); 572 COLORREF bgcolor = GetBkColor (hdc);
599 573
600 /* first blt the mask */ 574 /* first blt the mask */
601 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) 575 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
604 col.rgbBlue = GetBValue (bgcolor); 578 col.rgbBlue = GetBValue (bgcolor);
605 col.rgbRed = GetRValue (bgcolor); 579 col.rgbRed = GetRValue (bgcolor);
606 col.rgbGreen = GetGValue (bgcolor); 580 col.rgbGreen = GetGValue (bgcolor);
607 col.rgbReserved = 0; 581 col.rgbReserved = 0;
608 582
609 old = SelectObject (FRAME_MSWINDOWS_CDC (f), 583 old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p));
610 IMAGE_INSTANCE_MSWINDOWS_MASK (p));
611 584
612 SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); 585 SetDIBColorTable (hcompdc, 1, 1, &col);
613 586
614 BitBlt (hdc, 587 BitBlt (hdc,
615 db->xpos, db->ypos, 588 db->xpos, db->ypos,
616 dga->width, dga->height, 589 dga->width, dga->height,
617 FRAME_MSWINDOWS_CDC (f), 590 hcompdc,
618 dga->xoffset, dga->yoffset, 591 dga->xoffset, dga->yoffset,
619 SRCCOPY); 592 SRCCOPY);
620 593
621 SelectObject (FRAME_MSWINDOWS_CDC (f), old); 594 SelectObject (hcompdc, old);
622 } 595 }
623 596
624 /* Now blt the bitmap itself, or one of its slices. */ 597 /* Now blt the bitmap itself, or one of its slices. */
625 old = SelectObject (FRAME_MSWINDOWS_CDC (f), 598 old = SelectObject (hcompdc,
626 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE 599 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE
627 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p))); 600 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)));
628 601
629 BitBlt (hdc, 602 BitBlt (hdc,
630 db->xpos, db->ypos, 603 db->xpos, db->ypos,
631 dga->width, dga->height, 604 dga->width, dga->height,
632 FRAME_MSWINDOWS_CDC (f), 605 hcompdc,
633 dga->xoffset, dga->yoffset, 606 dga->xoffset, dga->yoffset,
634 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); 607 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY);
635 608
636 SelectObject (FRAME_MSWINDOWS_CDC (f),old); 609 SelectObject (hcompdc, old);
637 } 610 }
638 611
639 /* X gc's have this nice property that setting the bg pixmap will 612 /* X gc's have this nice property that setting the bg pixmap will
640 * output it offset relative to the window. Windows doesn't have this 613 * output it offset relative to the window. Windows doesn't have this
641 * feature so we have to emulate this by outputting multiple pixmaps. 614 * feature so we have to emulate this by outputting multiple pixmaps.
642 * This is only used for background pixmaps. Normal pixmaps are 615 * This is only used for background pixmaps. Normal pixmaps are
643 * outputted once and are scrollable */ 616 * outputted once and are scrollable */
644 static void 617 static void
645 mswindows_output_dibitmap_region (struct frame *f, 618 mswindows_output_dibitmap_region (struct frame *f,
646 struct Lisp_Image_Instance *p, 619 Lisp_Image_Instance *p,
647 struct display_box *db, 620 struct display_box *db,
648 struct display_glyph_area *dga) 621 struct display_glyph_area *dga)
649 { 622 {
650 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; 623 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height };
651 struct display_glyph_area xdga 624 struct display_glyph_area xdga
700 struct display_box *db, struct display_glyph_area *dga, 673 struct display_box *db, struct display_glyph_area *dga,
701 face_index findex, int cursor_start, int cursor_width, 674 face_index findex, int cursor_start, int cursor_width,
702 int cursor_height, int bg_pixmap) 675 int cursor_height, int bg_pixmap)
703 { 676 {
704 struct frame *f = XFRAME (w->frame); 677 struct frame *f = XFRAME (w->frame);
705 HDC hdc = FRAME_MSWINDOWS_DC (f); 678 HDC hdc = get_frame_dc (f);
706 679
707 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); 680 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
708 Lisp_Object window; 681 Lisp_Object window;
709 682
710 XSETWINDOW (window, w); 683 XSETWINDOW (window, w);
711 684
712 /* Output the pixmap. Have to do this as many times as is required 685 /* Output the pixmap. Have to do this as many times as is required
713 to fill the given area */ 686 to fill the given area */
714 mswindows_update_dc (hdc, Qnil, 687 mswindows_update_dc (hdc,
715 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), 688 WINDOW_FACE_CACHEL_FOREGROUND (w, findex),
716 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); 689 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil);
717 690
718 if (bg_pixmap) 691 if (bg_pixmap)
719 mswindows_output_dibitmap_region (f, p, db, dga); 692 mswindows_output_dibitmap_region (f, p, db, dga);
751 rect_dead.bottom = rect_dead.top + sbh; 724 rect_dead.bottom = rect_dead.top + sbh;
752 725
753 if (IntersectRect (&rect_paint, &rect_dead, prc)) 726 if (IntersectRect (&rect_paint, &rect_dead, prc))
754 { 727 {
755 struct frame *f = XFRAME (WINDOW_FRAME (w)); 728 struct frame *f = XFRAME (WINDOW_FRAME (w));
756 FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint, 729 FillRect (get_frame_dc (f), &rect_paint,
757 (HBRUSH) (COLOR_BTNFACE+1)); 730 (HBRUSH) (COLOR_BTNFACE+1));
758 } 731 }
759 } 732 }
760 733
761 #endif /* HAVE_SCROLLBARS */ 734 #endif /* HAVE_SCROLLBARS */
930 border |= BF_RIGHT; 903 border |= BF_RIGHT;
931 904
932 { 905 {
933 RECT rect = { x, y, x + width, y + height }; 906 RECT rect = { x, y, x + width, y + height };
934 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); 907 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
935 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); 908 HDC hdc = get_frame_dc (f);
936 909
937 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, border); 910 mswindows_update_dc (hdc, Qnil, color, Qnil);
911 DrawEdge (hdc, &rect, edge, border);
938 } 912 }
939 } 913 }
940 914
941 915
942 /***************************************************************************** 916 /*****************************************************************************
988 962
989 static int 963 static int
990 mswindows_flash (struct device *d) 964 mswindows_flash (struct device *d)
991 { 965 {
992 struct frame *f = device_selected_frame (d); 966 struct frame *f = device_selected_frame (d);
967 HDC hdc = get_frame_dc (f);
993 RECT rc; 968 RECT rc;
994 969
995 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc); 970 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc);
996 InvertRect (FRAME_MSWINDOWS_DC (f), &rc); 971 InvertRect (hdc, &rc);
997 GdiFlush (); 972 GdiFlush ();
998 Sleep (25); 973 Sleep (25);
999 InvertRect (FRAME_MSWINDOWS_DC (f), &rc); 974 InvertRect (hdc, &rc);
1000 975
1001 return 1; 976 return 1;
1002 } 977 }
1003 978
1004 static void 979 static void
1137 } 1112 }
1138 } 1113 }
1139 else if (rb->type == RUNE_DGLYPH) 1114 else if (rb->type == RUNE_DGLYPH)
1140 { 1115 {
1141 Lisp_Object instance; 1116 Lisp_Object instance;
1142 struct display_box db; 1117 struct display_box dbox;
1143 struct display_glyph_area dga; 1118 struct display_glyph_area dga;
1144 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, 1119 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset,
1145 start_pixpos, rb->width, 1120 start_pixpos, rb->width,
1146 &db, &dga); 1121 &dbox, &dga);
1147 1122
1148 XSETWINDOW (window, w); 1123 XSETWINDOW (window, w);
1149 instance = glyph_image_instance (rb->object.dglyph.glyph, 1124 instance = glyph_image_instance (rb->object.dglyph.glyph,
1150 window, ERROR_ME_NOT, 1); 1125 window, ERROR_ME_NOT, 1);
1151 findex = rb->findex; 1126 findex = rb->findex;
1174 } 1149 }
1175 break; 1150 break;
1176 1151
1177 case IMAGE_MONO_PIXMAP: 1152 case IMAGE_MONO_PIXMAP:
1178 case IMAGE_COLOR_PIXMAP: 1153 case IMAGE_COLOR_PIXMAP:
1179 redisplay_output_pixmap (w, instance, &db, &dga, findex, 1154 redisplay_output_pixmap (w, instance, &dbox, &dga, findex,
1180 cursor_start, cursor_width, 1155 cursor_start, cursor_width,
1181 cursor_height, 0); 1156 cursor_height, 0);
1182 if (rb->cursor_type == CURSOR_ON) 1157 if (rb->cursor_type == CURSOR_ON)
1183 mswindows_output_cursor (w, dl, xpos, cursor_width, 1158 mswindows_output_cursor (w, dl, xpos, cursor_width,
1184 findex, 0, 1); 1159 findex, 0, 1);
1187 case IMAGE_POINTER: 1162 case IMAGE_POINTER:
1188 abort (); 1163 abort ();
1189 1164
1190 case IMAGE_SUBWINDOW: 1165 case IMAGE_SUBWINDOW:
1191 case IMAGE_WIDGET: 1166 case IMAGE_WIDGET:
1192 redisplay_output_subwindow (w, instance, &db, &dga, findex, 1167 redisplay_output_subwindow (w, instance, &dbox, &dga, findex,
1193 cursor_start, cursor_width, 1168 cursor_start, cursor_width,
1194 cursor_height); 1169 cursor_height);
1195 if (rb->cursor_type == CURSOR_ON) 1170 if (rb->cursor_type == CURSOR_ON)
1196 mswindows_output_cursor (w, dl, xpos, cursor_width, 1171 mswindows_output_cursor (w, dl, xpos, cursor_width,
1197 findex, 0, 1); 1172 findex, 0, 1);
1198 break; 1173 break;
1199 1174
1200 case IMAGE_LAYOUT: 1175 case IMAGE_LAYOUT:
1201 redisplay_output_layout (w, instance, &db, &dga, findex, 1176 redisplay_output_layout (w, instance, &dbox, &dga, findex,
1202 cursor_start, cursor_width, 1177 cursor_start, cursor_width,
1203 cursor_height); 1178 cursor_height);
1204 if (rb->cursor_type == CURSOR_ON) 1179 if (rb->cursor_type == CURSOR_ON)
1205 mswindows_output_cursor (w, dl, xpos, cursor_width, 1180 mswindows_output_cursor (w, dl, xpos, cursor_width,
1206 findex, 0, 1); 1181 findex, 0, 1);
1244 ****************************************************************************/ 1219 ****************************************************************************/
1245 static void 1220 static void
1246 mswindows_output_vertical_divider (struct window *w, int clear_unused) 1221 mswindows_output_vertical_divider (struct window *w, int clear_unused)
1247 { 1222 {
1248 struct frame *f = XFRAME (w->frame); 1223 struct frame *f = XFRAME (w->frame);
1224 HDC hdc = get_frame_dc (f);
1249 RECT rect; 1225 RECT rect;
1250 int spacing = XINT (w->vertical_divider_spacing); 1226 int spacing = XINT (w->vertical_divider_spacing);
1251 int shadow = XINT (w->vertical_divider_shadow_thickness); 1227 int shadow = XINT (w->vertical_divider_shadow_thickness);
1252 int abs_shadow = abs (shadow); 1228 int abs_shadow = abs (shadow);
1253 int line_width = XINT (w->vertical_divider_line_width); 1229 int line_width = XINT (w->vertical_divider_line_width);
1258 /* Clear left and right spacing areas */ 1234 /* Clear left and right spacing areas */
1259 if (spacing) 1235 if (spacing)
1260 { 1236 {
1261 rect.top = y1; 1237 rect.top = y1;
1262 rect.bottom = y2; 1238 rect.bottom = y2;
1263 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, 1239 mswindows_update_dc (hdc, Qnil,
1264 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); 1240 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil);
1265 rect.right = WINDOW_RIGHT (w); 1241 rect.right = WINDOW_RIGHT (w);
1266 rect.left = rect.right - spacing; 1242 rect.left = rect.right - spacing;
1267 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1243 ExtTextOut (hdc, 0, 0, ETO_OPAQUE,
1268 &rect, NULL, 0, NULL); 1244 &rect, NULL, 0, NULL);
1269 rect.left = div_left; 1245 rect.left = div_left;
1270 rect.right = div_left + spacing; 1246 rect.right = div_left + spacing;
1271 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1247 ExtTextOut (hdc, 0, 0, ETO_OPAQUE,
1272 &rect, NULL, 0, NULL); 1248 &rect, NULL, 0, NULL);
1273 } 1249 }
1274 1250
1275 /* Clear divider face */ 1251 /* Clear divider face */
1276 rect.top = y1 + abs_shadow; 1252 rect.top = y1 + abs_shadow;
1279 rect.right = rect.left + line_width; 1255 rect.right = rect.left + line_width;
1280 if (rect.left < rect.right) 1256 if (rect.left < rect.right)
1281 { 1257 {
1282 face_index div_face 1258 face_index div_face
1283 = get_builtin_face_cache_index (w, Vvertical_divider_face); 1259 = get_builtin_face_cache_index (w, Vvertical_divider_face);
1284 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, 1260 mswindows_update_dc (hdc, Qnil,
1285 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); 1261 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil);
1286 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1262 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
1287 &rect, NULL, 0, NULL);
1288 } 1263 }
1289 1264
1290 /* Draw a shadow around the divider */ 1265 /* Draw a shadow around the divider */
1291 if (shadow != 0) 1266 if (shadow != 0)
1292 { 1267 {
1293 /* #### This will be fixed to support arbitrary thickness */ 1268 /* #### This will be fixed to support arbitrary thickness */
1294 InflateRect (&rect, abs_shadow, abs_shadow); 1269 InflateRect (&rect, abs_shadow, abs_shadow);
1295 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, 1270 DrawEdge (hdc, &rect,
1296 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); 1271 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT);
1297 } 1272 }
1298 } 1273 }
1299 1274
1300 /**************************************************************************** 1275 /****************************************************************************
1305 ****************************************************************************/ 1280 ****************************************************************************/
1306 static int 1281 static int
1307 mswindows_text_width (struct frame *f, struct face_cachel *cachel, 1282 mswindows_text_width (struct frame *f, struct face_cachel *cachel,
1308 CONST Emchar *str, Charcount len) 1283 CONST Emchar *str, Charcount len)
1309 { 1284 {
1285 HDC hdc = get_frame_dc (f);
1310 int width_so_far = 0; 1286 int width_so_far = 0;
1311 unsigned char *text_storage = (unsigned char *) alloca (2 * len); 1287 unsigned char *text_storage = (unsigned char *) alloca (2 * len);
1312 textual_run *runs = alloca_array (textual_run, len); 1288 textual_run *runs = alloca_array (textual_run, len);
1313 int nruns; 1289 int nruns;
1314 int i; 1290 int i;
1315 1291
1316 nruns = separate_textual_runs (text_storage, runs, str, len); 1292 nruns = separate_textual_runs (text_storage, runs, str, len);
1317 1293
1318 for (i = 0; i < nruns; i++) 1294 for (i = 0; i < nruns; i++)
1319 width_so_far += mswindows_text_width_single_run (FRAME_MSWINDOWS_DC (f), 1295 width_so_far += mswindows_text_width_single_run (hdc,
1320 cachel, runs + i); 1296 cachel, runs + i);
1321 1297
1322 return width_so_far; 1298 return width_so_far;
1323 } 1299 }
1324 1300
1334 face_index findex, int x, int y, 1310 face_index findex, int x, int y,
1335 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, 1311 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor,
1336 Lisp_Object background_pixmap) 1312 Lisp_Object background_pixmap)
1337 { 1313 {
1338 RECT rect = { x, y, x+width, y+height }; 1314 RECT rect = { x, y, x+width, y+height };
1315 HDC hdc = get_frame_dc (f);
1339 1316
1340 if (!NILP (background_pixmap)) 1317 if (!NILP (background_pixmap))
1341 { 1318 {
1342 struct display_box db = { x, y, width, height }; 1319 struct display_box db = { x, y, width, height };
1343 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), 1320 mswindows_update_dc (hdc,
1344 Qnil, fcolor, bcolor, background_pixmap); 1321 fcolor, bcolor, background_pixmap);
1345 mswindows_output_dibitmap_region 1322 mswindows_output_dibitmap_region
1346 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); 1323 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0);
1347 } 1324 }
1348 else 1325 else
1349 { 1326 {
1350 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, fcolor, Qnil); 1327 mswindows_update_dc (hdc, Qnil, fcolor, Qnil);
1351 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 1328 ExtTextOut (hdc, 0, 0, ETO_OPAQUE,
1352 &rect, NULL, 0, NULL); 1329 &rect, NULL, 0, NULL);
1353 } 1330 }
1354 1331
1355 #ifdef HAVE_SCROLLBARS 1332 #ifdef HAVE_SCROLLBARS
1356 if (WINDOWP (locale)) 1333 if (WINDOWP (locale))
1372 /************************************************************************/ 1349 /************************************************************************/
1373 1350
1374 void 1351 void
1375 console_type_create_redisplay_mswindows (void) 1352 console_type_create_redisplay_mswindows (void)
1376 { 1353 {
1377 /* redisplay methods */ 1354 /* redisplay methods - display*/
1378 CONSOLE_HAS_METHOD (mswindows, text_width); 1355 CONSOLE_HAS_METHOD (mswindows, text_width);
1379 CONSOLE_HAS_METHOD (mswindows, output_display_block); 1356 CONSOLE_HAS_METHOD (mswindows, output_display_block);
1380 CONSOLE_HAS_METHOD (mswindows, divider_height); 1357 CONSOLE_HAS_METHOD (mswindows, divider_height);
1381 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width); 1358 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width);
1382 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider); 1359 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider);
1387 CONSOLE_HAS_METHOD (mswindows, flash); 1364 CONSOLE_HAS_METHOD (mswindows, flash);
1388 CONSOLE_HAS_METHOD (mswindows, ring_bell); 1365 CONSOLE_HAS_METHOD (mswindows, ring_bell);
1389 CONSOLE_HAS_METHOD (mswindows, bevel_area); 1366 CONSOLE_HAS_METHOD (mswindows, bevel_area);
1390 CONSOLE_HAS_METHOD (mswindows, output_string); 1367 CONSOLE_HAS_METHOD (mswindows, output_string);
1391 CONSOLE_HAS_METHOD (mswindows, output_pixmap); 1368 CONSOLE_HAS_METHOD (mswindows, output_pixmap);
1392 } 1369
1370 /* redisplay methods - printer */
1371 CONSOLE_INHERITS_METHOD (msprinter, mswindows, text_width);
1372 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_display_block);
1373 CONSOLE_INHERITS_METHOD (msprinter, mswindows, divider_height);
1374 CONSOLE_INHERITS_METHOD (msprinter, mswindows, eol_cursor_width);
1375 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_vertical_divider);
1376 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_region);
1377 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_frame);
1378 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_begin);
1379 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_end);
1380 CONSOLE_INHERITS_METHOD (msprinter, mswindows, bevel_area);
1381 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_string);
1382 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_pixmap);
1383 }