Mercurial > hg > xemacs-beta
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 |