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);