comparison src/redisplay-msw.c @ 227:0e522484dd2a r20-5b12

Import from CVS: tag r20-5b12
author cvs
date Mon, 13 Aug 2007 10:12:37 +0200
parents 2c611d1463a6
children 41f2f0e326e9
comparison
equal deleted inserted replaced
226:eea38c7ad7b4 227:0e522484dd2a
287 287
288 if (!IMAGE_INSTANCEP (bg_pmap) 288 if (!IMAGE_INSTANCEP (bg_pmap)
289 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) 289 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
290 bg_pmap = Qnil; 290 bg_pmap = Qnil;
291 291
292 FillRect (FRAME_MSWINDOWS_DC (f), &rect, 292 /* #### This deals only with solid colors */
293 COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background))); 293 mswindows_update_gc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil,
294 cachel->background, Qnil, Qnil);
295 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
294 } 296 }
295 297
296 298
297 /***************************************************************************** 299 /*****************************************************************************
298 mswindows_output_cursor 300 mswindows_output_cursor
305 int width, struct rune *rb) 307 int width, struct rune *rb)
306 { 308 {
307 struct frame *f = XFRAME (w->frame); 309 struct frame *f = XFRAME (w->frame);
308 struct device *d = XDEVICE (f->device); 310 struct device *d = XDEVICE (f->device);
309 struct face_cachel *cachel; 311 struct face_cachel *cachel;
310 Lisp_Object font; 312 Lisp_Object font = Qnil;
311 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); 313 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
312 HBRUSH brush; 314 HBRUSH brush;
313 HDC hdc = FRAME_MSWINDOWS_DC (f); 315 HDC hdc = FRAME_MSWINDOWS_DC (f);
314 int real_char_p = (rb->type == RUNE_CHAR && rb->object.chr.ch != '\n'); 316 int real_char_p = (rb->type == RUNE_CHAR && rb->object.chr.ch != '\n');
317 char *p_char = NULL;
318 int n_char = 0;
315 RECT rect = { xpos, 319 RECT rect = { xpos,
316 dl->ypos - dl->ascent, 320 dl->ypos - dl->ascent,
317 xpos + width, 321 xpos + width,
318 dl->ypos + dl->descent - dl->clip}; 322 dl->ypos + dl->descent - dl->clip};
319 323
329 333
330 /* XXX MULE: Need to know the charset! */ 334 /* XXX MULE: Need to know the charset! */
331 font = FACE_CACHEL_FONT (cachel, Vcharset_ascii); 335 font = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
332 } 336 }
333 337
334 /* Clear the area */ 338
339 if (focus && real_char_p)
340 {
341 p_char = (char*) &rb->object.chr.ch;
342 n_char = 1;
343 }
344
345 cachel = WINDOW_FACE_CACHEL (w,
346 get_builtin_face_cache_index (w, Vtext_cursor_face));
347 mswindows_update_gc (hdc, font, cachel->foreground,
348 cachel->background, Qnil, Qnil);
349 ExtTextOut (FRAME_MSWINDOWS_DC (f), xpos, dl->ypos, ETO_OPAQUE,
350 &rect, p_char, n_char, NULL);
351
335 if (focus) 352 if (focus)
336 cachel = WINDOW_FACE_CACHEL (w, 353 return;
337 get_builtin_face_cache_index (w, Vtext_cursor_face)); 354
338 else if (!real_char_p) 355 InflateRect (&rect, -1, -1);
339 cachel = WINDOW_FACE_CACHEL (w, rb->findex);
340
341 brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background));
342 FillRect (hdc, &rect, brush);
343 356
344 if (real_char_p) 357 if (real_char_p)
345 { 358 {
346 /* XXX FIXME: Need to clip if dl->clip!=0. How rare is this case? */ 359 p_char = (char*) &rb->object.chr.ch;
347 /* Output the underlying character */ 360 n_char = 1;
348 mswindows_update_gc (hdc, font, cachel->foreground, 361 }
349 cachel->background, Qnil, Qnil); 362
350 TextOut(hdc, xpos, dl->ypos, (char*) &rb->object.chr.ch, 1); 363 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? rb->findex
351 } 364 : get_builtin_face_cache_index (w, Vdefault_face)));
352 365 mswindows_update_gc (hdc, Qnil, cachel->foreground,
353 if (!focus) 366 cachel->background, Qnil, Qnil);
354 { 367 ExtTextOut (FRAME_MSWINDOWS_DC (f), xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED,
355 /* Draw hollow rectangle in cursor's background color */ 368 &rect, p_char, n_char, NULL);
356 cachel = WINDOW_FACE_CACHEL (w,
357 get_builtin_face_cache_index (w, Vtext_cursor_face));
358 brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background));
359 FrameRect (hdc, &rect, brush);
360 }
361 } 369 }
362 370
363 371
364 /***************************************************************************** 372 /*****************************************************************************
365 mswindows_output_string 373 mswindows_output_string
435 for (i = 0; i < nruns; i++) 443 for (i = 0; i < nruns; i++)
436 { 444 {
437 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); 445 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset);
438 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); 446 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font);
439 int this_width; 447 int this_width;
440 int need_clipping;
441 RECT rect = { clip_start, dl->ypos - dl->ascent, 448 RECT rect = { clip_start, dl->ypos - dl->ascent,
442 clip_end, dl->ypos + dl->descent - dl->clip }; 449 clip_end, dl->ypos + dl->descent - dl->clip };
443 HRGN region;
444 450
445 if (EQ (font, Vthe_null_font_instance)) 451 if (EQ (font, Vthe_null_font_instance))
446 continue; 452 continue;
447 453
448 mswindows_update_gc (hdc, font, cachel->foreground, 454 mswindows_update_gc (hdc, font, cachel->foreground,
449 cachel->background, Qnil, Qnil); 455 NILP(bg_pmap) ? cachel->background : Qnil,
456 Qnil, Qnil);
450 457
451 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); 458 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i);
452 need_clipping = (dl->clip || clip_start > xpos || 459
453 clip_end < xpos + this_width); 460 /* #### bg_pmap should be output here */
454
455 if (need_clipping)
456 {
457 region = CreateRectRgn (rect.left, rect.top,
458 rect.right, rect.bottom);
459 SelectClipRgn (hdc, region);
460 }
461
462 /* TextOut only clears the area equal to the height of
463 the given font. It is possible that a font is being displayed
464 on a line taller than it is, so this would cause us to fail to
465 clear some areas. */
466 if (fi->ascent < dl->ascent || fi->descent < dl->descent-dl->clip)
467 FillRect (hdc, &rect,
468 COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background)));
469 461
470 assert (runs[i].dimension == 1); /* XXX FIXME */ 462 assert (runs[i].dimension == 1); /* XXX FIXME */
471 TextOut(hdc, xpos, dl->ypos, (char *) runs[i].ptr, runs[i].len); 463 ExtTextOut (hdc, xpos, dl->ypos,
464 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED,
465 &rect, (char *) runs[i].ptr, runs[i].len, NULL);
472 466
473 /* XXX FIXME? X does underline/strikethrough here 467 /* XXX FIXME? X does underline/strikethrough here
474 we will do it as part of face's font */ 468 we will do it as part of face's font */
475 469
476 if (need_clipping)
477 {
478 SelectClipRgn (hdc, NULL);
479 DeleteObject (region);
480 }
481
482 xpos += this_width; 470 xpos += this_width;
483 } 471 }
484 } 472 }
473
474
475 #ifdef HAVE_SCROLLBARS
476 /*
477 * This function paints window's deadbox, a rectangle between window
478 * borders and two short edges of both scrollbars.
479 *
480 * Function checks whether deadbox intersects with the rectangle pointed
481 * to by PRC, and paints only the intersection
482 */
483 static void
484 mswindows_redisplay_deadbox_maybe (CONST struct window *w,
485 CONST RECT* prc)
486 {
487 int sbh = window_scrollbar_height (w);
488 int sbw = window_scrollbar_width (w);
489 RECT rect_dead, rect_paint;
490 struct frame *f;
491 if (sbh == 0 || sbw == 0)
492 return;
493
494 f = XFRAME (WINDOW_FRAME (w));
495 if (f->scrollbar_on_left)
496 {
497 rect_dead.left = WINDOW_LEFT (w);
498 rect_dead.right = WINDOW_LEFT (w) + sbw;
499 }
500 else
501 {
502 rect_dead.left = WINDOW_RIGHT (w) - sbw;
503 rect_dead.right = WINDOW_RIGHT (w);
504 }
505
506 if (f->scrollbar_on_top)
507 {
508 rect_dead.top = WINDOW_TOP (w);
509 rect_dead.bottom = WINDOW_TOP (w) + sbh;
510 }
511 else
512 {
513 int modh = window_modeline_height (w);
514 rect_dead.top = WINDOW_BOTTOM (w) - modh - sbh;
515 rect_dead.bottom = WINDOW_BOTTOM (w) - modh;
516 }
517
518 if (IntersectRect (&rect_paint, &rect_dead, prc))
519 FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint,
520 (HBRUSH)GetClassLong (FRAME_MSWINDOWS_HANDLE(f), GCL_HBRBACKGROUND));
521 }
522
523 #endif /* HAVE_SCROLLBARS */
485 524
486 /***************************************************************************** 525 /*****************************************************************************
487 mswindows_redraw_exposed_window 526 mswindows_redraw_exposed_window
488 527
489 Given a bounding box for an area that needs to be redrawn, determine 528 Given a bounding box for an area that needs to be redrawn, determine
495 mswindows_redraw_exposed_window (struct window *w, int x, int y, int width, 534 mswindows_redraw_exposed_window (struct window *w, int x, int y, int width,
496 int height) 535 int height)
497 { 536 {
498 struct frame *f = XFRAME (w->frame); 537 struct frame *f = XFRAME (w->frame);
499 int line; 538 int line;
500 int start_x, start_y, end_x, end_y;
501 int orig_windows_structure_changed; 539 int orig_windows_structure_changed;
540 RECT rect_window = { WINDOW_LEFT (w), WINDOW_TOP (w),
541 WINDOW_RIGHT (w), WINDOW_BOTTOM (w) };
542 RECT rect_expose = { x, y, x + width, y + height };
543 RECT rect_draw;
502 544
503 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); 545 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
504 546
505 if (!NILP (w->vchild)) 547 if (!NILP (w->vchild))
506 { 548 {
512 mswindows_redraw_exposed_windows (w->hchild, x, y, width, height); 554 mswindows_redraw_exposed_windows (w->hchild, x, y, width, height);
513 return; 555 return;
514 } 556 }
515 557
516 /* If the window doesn't intersect the exposed region, we're done here. */ 558 /* If the window doesn't intersect the exposed region, we're done here. */
517 if (x >= WINDOW_RIGHT (w) || (x + width) <= WINDOW_LEFT (w) 559 if (!IntersectRect (&rect_draw, &rect_window, &rect_expose))
518 || y >= WINDOW_BOTTOM (w) || (y + height) <= WINDOW_TOP (w))
519 {
520 return; 560 return;
521 } 561
522 else 562 /* We do this to make sure that the 3D modelines get redrawn if
523 { 563 they are in the exposed region. */
524 start_x = max (WINDOW_LEFT (w), x); 564 orig_windows_structure_changed = f->windows_structure_changed;
525 end_x = min (WINDOW_RIGHT (w), (x + width)); 565 f->windows_structure_changed = 1;
526 start_y = max (WINDOW_TOP (w), y);
527 end_y = min (WINDOW_BOTTOM (w), y + height);
528
529 /* We do this to make sure that the 3D modelines get redrawn if
530 they are in the exposed region. */
531 orig_windows_structure_changed = f->windows_structure_changed;
532 f->windows_structure_changed = 1;
533 }
534 566
535 if (window_needs_vertical_divider (w)) 567 if (window_needs_vertical_divider (w))
536 { 568 {
537 mswindows_output_vertical_divider (w, 0); 569 mswindows_output_vertical_divider (w, 0);
538 } 570 }
541 { 573 {
542 struct display_line *cdl = Dynarr_atp (cdla, line); 574 struct display_line *cdl = Dynarr_atp (cdla, line);
543 int top_y = cdl->ypos - cdl->ascent; 575 int top_y = cdl->ypos - cdl->ascent;
544 int bottom_y = cdl->ypos + cdl->descent; 576 int bottom_y = cdl->ypos + cdl->descent;
545 577
546 if (bottom_y >= start_y) 578 if (bottom_y >= rect_draw.top)
547 { 579 {
548 if (top_y > end_y) 580 if (top_y > rect_draw.bottom)
549 { 581 {
550 if (line == 0) 582 if (line == 0)
551 continue; 583 continue;
552 else 584 else
553 break; 585 break;
554 } 586 }
555 else 587 else
556 { 588 {
557 output_display_line (w, 0, cdla, line, start_x, end_x); 589 output_display_line (w, 0, cdla, line,
590 rect_draw.left, rect_draw.right);
558 } 591 }
559 } 592 }
560 } 593 }
561 594
562 f->windows_structure_changed = orig_windows_structure_changed; 595 f->windows_structure_changed = orig_windows_structure_changed;
563 596
564 /* If there have never been any face cache_elements created, then this 597 /* If there have never been any face cache_elements created, then this
565 expose event doesn't actually have anything to do. */ 598 expose event doesn't actually have anything to do. */
566 if (Dynarr_largest (w->face_cachels)) 599 if (Dynarr_largest (w->face_cachels))
567 redisplay_clear_bottom_of_window (w, cdla, start_y, end_y); 600 redisplay_clear_bottom_of_window (w, cdla, rect_draw.top, rect_draw.bottom);
601
602 #ifdef HAVE_SCROLLBARS
603 mswindows_redisplay_deadbox_maybe (w, &rect_expose);
604 #endif
568 } 605 }
569 606
570 /***************************************************************************** 607 /*****************************************************************************
571 mswindows_redraw_exposed_windows 608 mswindows_redraw_exposed_windows
572 609
975 rect.bottom = WINDOW_BOTTOM (w) - modeline_height; 1012 rect.bottom = WINDOW_BOTTOM (w) - modeline_height;
976 1013
977 /* Draw the divider line */ 1014 /* Draw the divider line */
978 color = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); 1015 color = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX);
979 mswindows_update_gc(FRAME_MSWINDOWS_DC(f), Qnil, Qnil, color, Qnil, Qnil); 1016 mswindows_update_gc(FRAME_MSWINDOWS_DC(f), Qnil, Qnil, color, Qnil, Qnil);
980 brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (color)); 1017 ExtTextOut (FRAME_MSWINDOWS_DC(f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
981 FillRect (FRAME_MSWINDOWS_DC(f), &rect, brush);
982 if (shadow_width) 1018 if (shadow_width)
983 DrawEdge (FRAME_MSWINDOWS_DC(f), &rect, 1019 DrawEdge (FRAME_MSWINDOWS_DC(f), &rect,
984 shadow_width==1 ? BDR_RAISEDINNER : EDGE_RAISED, 1020 shadow_width==1 ? BDR_RAISEDINNER : EDGE_RAISED,
985 BF_TOP|BF_RIGHT|BF_LEFT); 1021 BF_TOP|BF_RIGHT|BF_LEFT);
986 } 1022 }
1090 mswindows_update_gc (FRAME_MSWINDOWS_DC(f), Qnil, fcolor, bcolor, background_pixmap, Qnil); 1126 mswindows_update_gc (FRAME_MSWINDOWS_DC(f), Qnil, fcolor, bcolor, background_pixmap, Qnil);
1091 } 1127 }
1092 1128
1093 /* XX FIXME: Get brush from background_pixmap here */ 1129 /* XX FIXME: Get brush from background_pixmap here */
1094 assert(0); 1130 assert(0);
1131 FillRect (FRAME_MSWINDOWS_DC(f), &rect, brush);
1095 } 1132 }
1096 else 1133 else
1097 { 1134 {
1098 Lisp_Object color = (w ? WINDOW_FACE_CACHEL_BACKGROUND (w, findex) : 1135 Lisp_Object color = (w ? WINDOW_FACE_CACHEL_BACKGROUND (w, findex) :
1099 FACE_BACKGROUND (Vdefault_face, locale)); 1136 FACE_BACKGROUND (Vdefault_face, locale));
1100 brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (color)); 1137 mswindows_update_gc(FRAME_MSWINDOWS_DC(f), Qnil, Qnil, color, Qnil, Qnil);
1101 } 1138 ExtTextOut (FRAME_MSWINDOWS_DC(f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
1102 1139 }
1103 FillRect (FRAME_MSWINDOWS_DC(f), &rect, brush); 1140
1104 } 1141 #ifdef HAVE_SCROLLBARS
1105 1142 if (WINDOWP (locale))
1143 mswindows_redisplay_deadbox_maybe (w, &rect);
1144 #endif
1145 }
1106 1146
1107 /***************************************************************************** 1147 /*****************************************************************************
1108 mswindows_clear_to_window_end 1148 mswindows_clear_to_window_end
1109 1149
1110 Clear the area between ypos1 and ypos2. Each margin area and the 1150 Clear the area between ypos1 and ypos2. Each margin area and the