Mercurial > hg > xemacs-beta
comparison src/redisplay-msw.c @ 5138:6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-03-12 Ben Wing <ben@xemacs.org>
* redisplay-msw.c:
* redisplay-msw.c (mswindows_output_dibitmap_region):
* redisplay-msw.c (mswindows_output_pixmap):
* redisplay-msw.c (mswindows_clear_region):
Have a crack at implementing the `absolute' property for
background pixmaps. It seems to work; however, things don't
work quite right in relation to window sizing/moving. In particular,
ideally when you move the window the background should stay in place
but it doesn't; instead it moves, and when you hit C-l it gets
redrawn in the "proper" place. When resizing you get some serious
jitter, apparently as first the image gets moved then redrawn in
the correct offset position. #### Not sure how to fix this.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 12 Mar 2010 20:19:10 -0600 |
parents | 5502045ec510 |
children | 97eb4942aec8 |
comparison
equal
deleted
inserted
replaced
5137:0ac12485616c | 5138:6d13ad8ed3b2 |
---|---|
631 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); | 631 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); |
632 | 632 |
633 SelectObject (hcompdc, old); | 633 SelectObject (hcompdc, old); |
634 } | 634 } |
635 | 635 |
636 /* Return x MOD y, but the result is guaranteed positive */ | |
637 | |
638 static int | |
639 posmod (int x, int y) | |
640 { | |
641 int retval = x % y; | |
642 if (retval < 0) | |
643 retval += y; | |
644 return retval; | |
645 } | |
646 | |
636 /* X gc's have this nice property that setting the bg pixmap will | 647 /* X gc's have this nice property that setting the bg pixmap will |
637 * output it offset relative to the window. Windows doesn't have this | 648 * output it offset relative to the window. Windows doesn't have this |
638 * feature so we have to emulate this by outputting multiple pixmaps. | 649 * feature so we have to emulate this by outputting multiple pixmaps. |
639 * This is only used for background pixmaps. Normal pixmaps are | 650 * This is only used for background pixmaps. Normal pixmaps are |
640 * outputted once and are scrollable */ | 651 * outputted once and are scrollable */ |
641 static void | 652 static void |
642 mswindows_output_dibitmap_region (struct frame *f, | 653 mswindows_output_dibitmap_region (struct frame *f, |
643 Lisp_Image_Instance *p, | 654 Lisp_Image_Instance *p, |
644 struct display_box *db, | 655 struct display_box *db, |
645 struct display_glyph_area *dga) | 656 struct display_glyph_area *dga, |
657 int absolute) | |
646 { | 658 { |
647 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; | 659 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; |
648 struct display_glyph_area xdga | 660 struct display_glyph_area xdga |
649 = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), | 661 = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), |
650 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; | 662 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; |
651 int pxoffset = 0, pyoffset = 0; | 663 int pxoffset = 0, pyoffset = 0; |
664 int absolute_pxoffset = 0, absolute_pyoffset = 0; | |
652 | 665 |
653 if (dga) | 666 if (dga) |
654 { | 667 { |
655 xdga.width = dga->width; | 668 xdga.width = dga->width; |
656 xdga.height = dga->height; | 669 xdga.height = dga->height; |
657 } | 670 } |
658 else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) | 671 else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) |
659 return; | 672 return; |
660 | 673 |
674 if (absolute) | |
675 { | |
676 POINT point; | |
677 point.x = 0; | |
678 point.y = 0; | |
679 if (ScreenToClient (FRAME_MSWINDOWS_HANDLE (f), &point)) | |
680 { | |
681 absolute_pxoffset = point.x; | |
682 absolute_pyoffset = point.y; | |
683 } | |
684 } | |
685 | |
661 /* when doing a bg pixmap do a partial pixmap first so that we | 686 /* when doing a bg pixmap do a partial pixmap first so that we |
662 blt whole pixmaps thereafter */ | 687 blt whole pixmaps thereafter */ |
663 xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - | 688 xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - |
664 db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | 689 posmod (db->ypos - absolute_pyoffset, |
690 IMAGE_INSTANCE_PIXMAP_HEIGHT (p))); | |
665 | 691 |
666 while (xdga.height > 0) | 692 while (xdga.height > 0) |
667 { | 693 { |
668 xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), | 694 xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), |
669 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - | 695 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - |
670 db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 696 posmod (db->xpos - absolute_pxoffset, |
697 IMAGE_INSTANCE_PIXMAP_WIDTH (p))); | |
671 pxoffset = 0; | 698 pxoffset = 0; |
672 while (xdga.width > 0) | 699 while (xdga.width > 0) |
673 { | 700 { |
674 xdb.xpos = db->xpos + pxoffset; | 701 xdb.xpos = db->xpos + pxoffset; |
675 xdb.ypos = db->ypos + pyoffset; | 702 xdb.ypos = db->ypos + pyoffset; |
676 /* do we need to offset the pixmap vertically? this is necessary | 703 /* do we need to offset the pixmap vertically? this is necessary |
677 for background pixmaps. */ | 704 for background pixmaps. */ |
678 xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | 705 xdga.xoffset = posmod (xdb.xpos - absolute_pxoffset, |
679 xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p); | 706 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); |
680 /* the width is handled by mswindows_output_pixmap_region */ | 707 xdga.yoffset = posmod (xdb.ypos - absolute_pyoffset, |
708 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
709 /* [[ the width is handled by mswindows_output_pixmap_region ]] | |
710 #### -- What is the correct meaning of this comment? There is | |
711 no mswindows_output_pixmap_region(). --ben*/ | |
681 mswindows_output_dibitmap (f, p, &xdb, &xdga); | 712 mswindows_output_dibitmap (f, p, &xdb, &xdga); |
682 pxoffset += xdga.width; | 713 pxoffset += xdga.width; |
683 xdga.width = min ((db->width - pxoffset), | 714 xdga.width = min ((db->width - pxoffset), |
684 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 715 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); |
685 } | 716 } |
709 mswindows_update_dc (hdc, | 740 mswindows_update_dc (hdc, |
710 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), | 741 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), |
711 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); | 742 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); |
712 | 743 |
713 if (bg_pixmap) | 744 if (bg_pixmap) |
714 mswindows_output_dibitmap_region (f, p, db, dga); | 745 mswindows_output_dibitmap_region |
746 (f, p, db, dga, | |
747 EQ (WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT (w, findex), Qabsolute)); | |
715 else | 748 else |
716 mswindows_output_dibitmap (f, p, db, dga); | 749 mswindows_output_dibitmap (f, p, db, dga); |
717 } | 750 } |
718 | 751 |
719 #ifdef HAVE_SCROLLBARS | 752 #ifdef HAVE_SCROLLBARS |
1214 int width, int height, Lisp_Object fcolor, | 1247 int width, int height, Lisp_Object fcolor, |
1215 Lisp_Object bcolor, | 1248 Lisp_Object bcolor, |
1216 Lisp_Object background_pixmap, | 1249 Lisp_Object background_pixmap, |
1217 Lisp_Object background_placement) | 1250 Lisp_Object background_placement) |
1218 { | 1251 { |
1219 /* #### FIXME: don't know how to handle background_placement in mswindows. | |
1220 -- dvl */ | |
1221 | |
1222 RECT rect = { x, y, x+width, y+height }; | 1252 RECT rect = { x, y, x+width, y+height }; |
1223 HDC hdc = get_frame_dc (f, 1); | 1253 HDC hdc = get_frame_dc (f, 1); |
1224 | 1254 |
1225 if (!NILP (background_pixmap)) | 1255 if (!NILP (background_pixmap)) |
1226 { | 1256 { |
1227 struct display_box db = { x, y, width, height }; | 1257 struct display_box db = { x, y, width, height }; |
1228 mswindows_update_dc (hdc, | 1258 mswindows_update_dc (hdc, |
1229 fcolor, bcolor, background_pixmap); | 1259 fcolor, bcolor, background_pixmap); |
1230 mswindows_output_dibitmap_region | 1260 mswindows_output_dibitmap_region |
1231 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); | 1261 (f, XIMAGE_INSTANCE (background_pixmap), &db, 0, |
1262 EQ (background_placement, Qabsolute)); | |
1232 } | 1263 } |
1233 else | 1264 else |
1234 { | 1265 { |
1235 mswindows_update_dc (hdc, Qnil, fcolor, Qnil); | 1266 mswindows_update_dc (hdc, Qnil, fcolor, Qnil); |
1236 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); | 1267 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |