# HG changeset patch # User Ben Wing # Date 1268446750 21600 # Node ID 6d13ad8ed3b27485135b249c0d0310c7bf5e2c04 # Parent 0ac12485616c7088cf12e7ff44df9a96a2110770 implement absolute background-placement for Windows, sort of -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-03-12 Ben Wing * 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. diff -r 0ac12485616c -r 6d13ad8ed3b2 src/ChangeLog --- 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 + + * 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 * frame.c (change_frame_size_1): diff -r 0ac12485616c -r 6d13ad8ed3b2 src/redisplay-msw.c --- 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 {