changeset 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 0ac12485616c
children a48ef26d87ee
files src/ChangeLog src/redisplay-msw.c
diffstat 2 files changed, 57 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Mar 12 18:30:05 2010 -0600
+++ b/src/ChangeLog	Fri Mar 12 20:19:10 2010 -0600
@@ -1,3 +1,18 @@
+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.
+
 2010-03-06  Ben Wing  <ben@xemacs.org>
 
 	* frame.c (change_frame_size_1):
--- a/src/redisplay-msw.c	Fri Mar 12 18:30:05 2010 -0600
+++ b/src/redisplay-msw.c	Fri Mar 12 20:19:10 2010 -0600
@@ -633,6 +633,17 @@
   SelectObject (hcompdc, old);
 }
 
+/* Return x MOD y, but the result is guaranteed positive */
+
+static int
+posmod (int x, int y)
+{
+  int retval = x % y;
+  if (retval < 0)
+    retval += y;
+  return retval;
+}
+
 /* X gc's have this nice property that setting the bg pixmap will
  * output it offset relative to the window. Windows doesn't have this
  * feature so we have to emulate this by outputting multiple pixmaps.
@@ -642,13 +653,15 @@
 mswindows_output_dibitmap_region (struct frame *f, 
 				  Lisp_Image_Instance *p,
 				  struct display_box *db,
-				  struct display_glyph_area *dga)
+				  struct display_glyph_area *dga,
+				  int absolute)
 {
   struct display_box xdb = { db->xpos, db->ypos, db->width, db->height };
   struct display_glyph_area xdga
     = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p),
 	IMAGE_INSTANCE_PIXMAP_HEIGHT (p) };
   int pxoffset = 0, pyoffset = 0;
+  int absolute_pxoffset = 0, absolute_pyoffset = 0;
 
   if (dga)
     {	
@@ -658,16 +671,30 @@
   else if (!redisplay_normalize_glyph_area (&xdb, &xdga))
     return;
 
+  if (absolute)
+    {
+      POINT point;
+      point.x = 0;
+      point.y = 0;
+      if (ScreenToClient (FRAME_MSWINDOWS_HANDLE (f), &point))
+	{
+	  absolute_pxoffset = point.x;
+	  absolute_pyoffset = point.y;
+	}
+    }
+
   /* when doing a bg pixmap do a partial pixmap first so that we
      blt whole pixmaps thereafter */
   xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) -
-		      db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
+		     posmod (db->ypos - absolute_pyoffset,
+			     IMAGE_INSTANCE_PIXMAP_HEIGHT (p)));
 
   while (xdga.height > 0)
     {
       xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)),
 			IMAGE_INSTANCE_PIXMAP_WIDTH (p) -
-			db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p));
+			posmod (db->xpos - absolute_pxoffset,
+				IMAGE_INSTANCE_PIXMAP_WIDTH (p)));
       pxoffset = 0;
       while (xdga.width > 0)
 	{
@@ -675,9 +702,13 @@
 	  xdb.ypos = db->ypos + pyoffset;
 	    /* do we need to offset the pixmap vertically? this is necessary
 	       for background pixmaps. */
-	  xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
-	  xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p);
-	  /* the width is handled by mswindows_output_pixmap_region */
+	  xdga.xoffset = posmod (xdb.xpos - absolute_pxoffset,
+				 IMAGE_INSTANCE_PIXMAP_WIDTH (p));
+	  xdga.yoffset = posmod (xdb.ypos - absolute_pyoffset,
+				 IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
+	  /* [[ the width is handled by mswindows_output_pixmap_region ]]
+	     #### -- What is the correct meaning of this comment?  There is
+	     no mswindows_output_pixmap_region(). --ben*/
 	  mswindows_output_dibitmap (f, p, &xdb, &xdga);
 	  pxoffset += xdga.width;
 	  xdga.width = min ((db->width - pxoffset),
@@ -711,7 +742,9 @@
 		       WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil);
 
   if (bg_pixmap)
-    mswindows_output_dibitmap_region (f, p, db, dga);
+    mswindows_output_dibitmap_region
+      (f, p, db, dga,
+       EQ (WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT (w, findex), Qabsolute));
   else
     mswindows_output_dibitmap (f, p, db, dga);
 }
@@ -1216,9 +1249,6 @@
 			Lisp_Object background_pixmap,
 			Lisp_Object background_placement)
 {
-  /* #### FIXME: don't know how to handle background_placement in mswindows.
-     -- dvl */
-
   RECT rect = { x, y, x+width, y+height };
   HDC hdc = get_frame_dc (f, 1);
 
@@ -1228,7 +1258,8 @@
       mswindows_update_dc (hdc,
 			   fcolor, bcolor, background_pixmap);
       mswindows_output_dibitmap_region 
-	( f, XIMAGE_INSTANCE (background_pixmap), &db, 0);
+	(f, XIMAGE_INSTANCE (background_pixmap), &db, 0,
+	 EQ (background_placement, Qabsolute));
     }
   else
     {