xserver: Branch 'master' - 17 commits

Keith Packard keithp at kemper.freedesktop.org
Thu Jan 20 21:14:20 PST 2011


 configure.ac           |    4 
 hw/xwin/InitOutput.c   |   13 +-
 hw/xwin/Makefile.am    |    1 
 hw/xwin/man/XWin.man   |   85 ++++++++++---
 hw/xwin/win.h          |   56 +++++++-
 hw/xwin/wincreatewnd.c |   48 +++----
 hw/xwin/windialogs.c   |   13 --
 hw/xwin/winmonitors.c  |   92 ++++++++++++++
 hw/xwin/winmonitors.h  |   14 ++
 hw/xwin/winnativegdi.c |   37 ++---
 hw/xwin/winpfbdd.c     |  108 ++++++++---------
 hw/xwin/winprocarg.c   |  131 +++++++-------------
 hw/xwin/winrandr.c     |  302 ++++++++++++++++++++++++++++++++++++++----------
 hw/xwin/winscrinit.c   |   66 +++++-----
 hw/xwin/winshaddd.c    |  164 ++++++++++----------------
 hw/xwin/winshadddnl.c  |  152 ++++++++++--------------
 hw/xwin/winshadgdi.c   |  124 +++++++++----------
 hw/xwin/winvalargs.c   |    8 -
 hw/xwin/winwindow.c    |    1 
 hw/xwin/winwndproc.c   |  307 ++++++++++++++++++++++++++++---------------------
 20 files changed, 1026 insertions(+), 700 deletions(-)

New commits:
commit 24ce650cf4f0c6fa72faecd38c53d40703e6c959
Merge: bbdf81a... 09fd010...
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Jan 20 21:11:53 2011 -0800

    Merge remote branch 'jturney/jturney-framebuffer-resize-for-master'

commit 09fd010902fad56735b8069b1becb80d85bd6a35
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Sep 29 22:54:22 2010 +0100

    Cygwin/X: DirectDraw engines shouldn't try to blit if the surface wasn't allocated
    
    Fix winShadowUpdateDD(|NL) so we don't try to blit to primary surface if it didn't get allocated
    
    (Intel drivers, in particular, seem to like to issue a WM_DISPLAYCHANGE during a suspend/resume
    cycle, but not allow surface to be allocated right then)
    
    Also:
    Use winReleasePrimarySurfaceShadowDD(|NL) in winFreeFBShadowDD(|NL) rather than open coding it
    Don't mess about recreating surface if we're going to resize it anyhow
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index b14d0a9..00d7a37 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -514,25 +514,16 @@ winFreeFBShadowDD (ScreenPtr pScreen)
       pScreenPriv->pddsShadow = NULL;
     }
 
-  /* Detach the clipper from the primary surface and release the clipper. */
+  /* Detach the clipper from the primary surface and release the primary surface, if there is one */
+  winReleasePrimarySurfaceShadowDD(pScreen);
+
+  /* Release the clipper object */
   if (pScreenPriv->pddcPrimary)
     {
-      /* Detach the clipper */
-      IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
-				      NULL);
-
-      /* Release the clipper object */
       IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
       pScreenPriv->pddcPrimary = NULL;
     }
 
-  /* Release the primary surface, if there is one */
-  if (pScreenPriv->pddsPrimary)
-    {
-      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
-      pScreenPriv->pddsPrimary = NULL;
-    }
-
   /* Free the DirectDraw2 object, if there is one */
   if (pScreenPriv->pdd2)
     {
@@ -577,6 +568,10 @@ winShadowUpdateDD (ScreenPtr pScreen,
   if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
       || pScreenPriv->fBadDepth) return;
 
+  /* Return immediately if we didn't get needed surfaces */
+  if (!pScreenPriv->pddsPrimary || !pScreenPriv->pddsShadow)
+    return;
+
   /* Get the origin of the window in the screen coords */
   ptOrigin.x = pScreenInfo->dwXOffset;
   ptOrigin.y = pScreenInfo->dwYOffset;
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index c74a2ff..0a0b4ae 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -546,25 +546,16 @@ winFreeFBShadowDDNL(ScreenPtr pScreen)
       pScreenPriv->pddsShadow4 = NULL;
     }
 
-  /* Detach the clipper from the primary surface and release the clipper. */
+  /* Detach the clipper from the primary surface and release the primary surface, if there is one */
+  winReleasePrimarySurfaceShadowDDNL(pScreen);
+
+  /* Release the clipper object */
   if (pScreenPriv->pddcPrimary)
     {
-      /* Detach the clipper */
-      IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
-				      NULL);
-
-      /* Release the clipper object */
       IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
       pScreenPriv->pddcPrimary = NULL;
     }
 
-  /* Release the primary surface, if there is one */
-  if (pScreenPriv->pddsPrimary4)
-    {
-      IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
-      pScreenPriv->pddsPrimary4 = NULL;
-    }
-
   /* Free the DirectDraw4 object, if there is one */
   if (pScreenPriv->pdd4)
     {
@@ -658,6 +649,10 @@ winShadowUpdateDDNL (ScreenPtr pScreen,
   if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
       || pScreenPriv->fBadDepth) return;
 
+  /* Return immediately if we didn't get needed surfaces */
+  if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4)
+    return;
+
   /* Get the origin of the window in the screen coords */
   ptOrigin.x = pScreenInfo->dwXOffset;
   ptOrigin.y = pScreenInfo->dwYOffset;
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index dd8f27e..bccd6f9 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -231,18 +231,7 @@ winWindowProc (HWND hwnd, UINT message,
         (this is probably usually the case so that might be an
         overoptimization)
       */
-
-      /*
-       * We can simply recreate the same-sized primary surface when
-       * the display dimensions change.
-       */
 	{
-
-#if CYGDEBUG
-	  winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated "
-		  "primary surface\n");
-#endif
-
 	  /*
              In rootless modes which are monitor or virtual desktop size
              use RandR to resize the X screen
@@ -311,13 +300,8 @@ winWindowProc (HWND hwnd, UINT message,
           else
             {
               /*
-                If we get here, we are either windowed and using the GDI engine
-                or windowed and non-fullscreen using any engine
-              */
-
-              /*
-               * For ddraw engines, we need to (try to) recreate the same-sized primary surface
-               * when display dimensions change (but not depth, that is disruptive)
+               * We can simply recreate the same-sized primary surface when
+               * the display dimensions change.
                */
 
               /*
commit 625ab9701fd75b879c1dafc05fa979591eea87c0
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Aug 31 13:45:43 2010 +0100

    Cygwin/X: Simplify and consolidate reporting of the bpp value we are going to use
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winnativegdi.c b/hw/xwin/winnativegdi.c
index b0a551a..4d7afe8 100644
--- a/hw/xwin/winnativegdi.c
+++ b/hw/xwin/winnativegdi.c
@@ -301,28 +301,9 @@ winAdjustVideoModeNativeGDI (ScreenPtr pScreen)
       break;
   }
 
-  /* GDI cannot change the screen depth */
-  if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
-    {
-      /* No -depth parameter passed, let the user know the depth being used */
-      ErrorF ("winAdjustVideoModeNativeGDI - Using Windows display "
-	      "depth of %d bits per pixel, %d depth\n",
-	      (int) dwBPP, (int) pScreenInfo->dwDepth);
-
-      /* Use GDI's depth */
-      pScreenInfo->dwBPP = dwBPP;
-    }
-  else if (dwBPP != pScreenInfo->dwBPP)
-    {
-      /* Warn user if GDI depth is different than -depth parameter */
-      ErrorF ("winAdjustVideoModeNativeGDI - Command line bpp: %d, "\
-	      "using bpp: %d\n",
-	      (int) pScreenInfo->dwBPP, (int) dwBPP);
+  /* GDI cannot change the screen depth, so we'll use GDI's depth */
+  pScreenInfo->dwBPP = dwBPP;
 
-      /* We'll use GDI's depth */
-      pScreenInfo->dwBPP = dwBPP;
-    }
-  
   /* Release our DC */
   ReleaseDC (NULL, hdc);
 
diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c
index 4145717..c0bca71 100644
--- a/hw/xwin/winpfbdd.c
+++ b/hw/xwin/winpfbdd.c
@@ -436,33 +436,13 @@ winAdjustVideoModePrimaryDD (ScreenPtr pScreen)
   dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
 
   /* DirectDraw can only change the depth in fullscreen mode */
-  if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
+  if (!(pScreenInfo->fFullScreen &&
+        (pScreenInfo->dwBPP != WIN_DEFAULT_BPP)))
     {
-      /* No -depth parameter passed, let the user know the depth being used */
-      ErrorF ("winAdjustVideoModePrimaryDD - Using Windows display "
-	      "depth of %d bits per pixel\n", (int) dwBPP);
-
-      /* Use GDI's depth */
+      /* Otherwise, We'll use GDI's depth */
       pScreenInfo->dwBPP = dwBPP;
     }
-  else if (pScreenInfo->fFullScreen
-	   && pScreenInfo->dwBPP != dwBPP)
-    {
-      /* FullScreen, and GDI depth differs from -depth parameter */
-      ErrorF ("winAdjustVideoModePrimaryDD - FullScreen, using command "
-	      "line depth: %d\n", (int) pScreenInfo->dwBPP);
-    }
-  else if (dwBPP != pScreenInfo->dwBPP)
-    {
-      /* Windowed, and GDI depth differs from -depth parameter */
-      ErrorF ("winAdjustVideoModePrimaryDD - Windowed, command line "
-	      "depth: %d, using depth: %d\n",
-	      (int) pScreenInfo->dwBPP, (int) dwBPP);
 
-      /* We'll use GDI's depth */
-      pScreenInfo->dwBPP = dwBPP;
-    }
-  
   /* Release our DC */
   ReleaseDC (NULL, hdc);
 
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 699ed94..691237e 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -91,6 +91,7 @@ winScreenInit (int index,
   winScreenInfoPtr      pScreenInfo = &g_ScreenInfo[index];
   winPrivScreenPtr	pScreenPriv;
   HDC			hdc;
+  DWORD dwInitialBPP;
 
 #if CYGDEBUG || YES
   winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n",
@@ -127,12 +128,29 @@ winScreenInit (int index,
     }
 
   /* Horribly misnamed function: Allow engine to adjust BPP for screen */
+  dwInitialBPP = pScreenInfo->dwBPP;
+
   if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen))
     {
       ErrorF ("winScreenInit - winAdjustVideoMode () failed\n");
       return FALSE;
     }
 
+  if (dwInitialBPP == WIN_DEFAULT_BPP)
+    {
+      /* No -depth parameter was passed, let the user know the depth being used */
+      ErrorF ("winScreenInit - Using Windows display depth of %d bits per pixel\n", (int) pScreenInfo->dwBPP);
+    }
+  else if (dwInitialBPP != pScreenInfo->dwBPP)
+    {
+      /* Warn user if engine forced a depth different to -depth parameter */
+      ErrorF ("winScreenInit - Command line depth of %d bpp overidden by engine, using %d bpp\n", (int) dwInitialBPP, (int) pScreenInfo->dwBPP);
+    }
+  else
+    {
+      ErrorF ("winScreenInit - Using command line depth of %d bpp\n", (int) pScreenInfo->dwBPP);
+    }
+
   /* Check for supported display depth */
   if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1))))
     {
diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index b551bef..b14d0a9 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -909,31 +909,13 @@ winAdjustVideoModeShadowDD (ScreenPtr pScreen)
   dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
 
   /* DirectDraw can only change the depth in fullscreen mode */
-  if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
+  if (!(pScreenInfo->fFullScreen &&
+        (pScreenInfo->dwBPP != WIN_DEFAULT_BPP)))
     {
-      /* No -depth parameter passed, let the user know the depth being used */
-      ErrorF ("winAdjustVideoModeShadowDD - Using Windows display "
-	      "depth of %d bits per pixel\n", (int) dwBPP);
-
-      /* Use GDI's depth */
+      /* Otherwise, We'll use GDI's depth */
       pScreenInfo->dwBPP = dwBPP;
     }
-  else if (pScreenInfo->fFullScreen
-	   && pScreenInfo->dwBPP != dwBPP)
-    {
-      /* FullScreen, and GDI depth differs from -depth parameter */
-      ErrorF ("winAdjustVideoModeShadowDD - FullScreen, using command line "
-	      "bpp: %d\n", (int) pScreenInfo->dwBPP);
-    }
-  else if (dwBPP != pScreenInfo->dwBPP)
-    {
-      /* Windowed, and GDI depth differs from -depth parameter */
-      ErrorF ("winAdjustVideoModeShadowDD - Windowed, command line bpp: "
-	      "%d, using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP);
 
-      /* We'll use GDI's depth */
-      pScreenInfo->dwBPP = dwBPP;
-    }
   /* Release our DC */
   ReleaseDC (NULL, hdc);
   return TRUE;
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index 52a4ce2..c74a2ff 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -983,30 +983,10 @@ winAdjustVideoModeShadowDDNL (ScreenPtr pScreen)
   dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
 
   /* DirectDraw can only change the depth in fullscreen mode */
-  if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
+  if (!(pScreenInfo->fFullScreen &&
+        (pScreenInfo->dwBPP != WIN_DEFAULT_BPP)))
     {
-      /* No -depth parameter passed, let the user know the depth being used */
-      winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - Using Windows display "
-	      "depth of %d bits per pixel\n", (int) dwBPP);
-
-      /* Use GDI's depth */
-      pScreenInfo->dwBPP = dwBPP;
-    }
-  else if (pScreenInfo->fFullScreen
-	   && pScreenInfo->dwBPP != dwBPP)
-    {
-      /* FullScreen, and GDI depth differs from -depth parameter */
-      winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - FullScreen, using command "
-	      "line bpp: %d\n", (int) pScreenInfo->dwBPP);
-    }
-  else if (dwBPP != pScreenInfo->dwBPP)
-    {
-      /* Windowed, and GDI depth differs from -depth parameter */
-      winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - Windowed, command line "
-	      "bpp: %d, using bpp: %d\n",
-	      (int) pScreenInfo->dwBPP, (int) dwBPP);
-
-      /* We'll use GDI's depth */
+      /* Otherwise, We'll use GDI's depth */
       pScreenInfo->dwBPP = dwBPP;
     }
 
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index e9c51ee..4990376 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -798,26 +798,9 @@ winAdjustVideoModeShadowGDI (ScreenPtr pScreen)
   /* Query GDI for current display depth */
   dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
 
-  /* GDI cannot change the screen depth */
-  if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
-    {
-      /* No -depth parameter passed, let the user know the depth being used */
-      ErrorF ("winAdjustVideoModeShadowGDI - Using Windows display "
-	      "depth of %d bits per pixel\n", (int) dwBPP);
-
-      /* Use GDI's depth */
-      pScreenInfo->dwBPP = dwBPP;
-    }
-  else if (dwBPP != pScreenInfo->dwBPP)
-    {
-      /* Warn user if GDI depth is different than -depth parameter */
-      ErrorF ("winAdjustVideoModeShadowGDI - Command line bpp: %d, "\
-	      "using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP);
+  /* GDI cannot change the screen depth, so always use GDI's depth */
+  pScreenInfo->dwBPP = dwBPP;
 
-      /* We'll use GDI's depth */
-      pScreenInfo->dwBPP = dwBPP;
-    }
-  
   /* Release our DC */
   ReleaseDC (NULL, hdc);
   hdc = NULL;
commit 3f7339a7c5d3dcd05909b041865125f4cb6fa29e
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Aug 31 10:13:01 2010 +0100

    Cygwin/X: Deal with RANDR depth changes correctly in ShadowGDI drawing engine
    
    Make ShadowGDI drawing engine only change the size of the screen
    pixmap/shadow framebuffer on an RANDR change, not the bpp/depth
    as well.
    
    The server requires the screen pixmap's depth to be invariant.
    
    Other drawing engines aren't quite as affected by this issue as
    they won't draw to the display, if it has changed colour depth,
    but probably still need some attention.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 96a868e..3f40fdb 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -504,7 +504,8 @@ typedef struct _winPrivScreenRec
   HDC			hdcScreen;
   HDC			hdcShadow;
   HWND			hwndScreen;
-  
+  BITMAPINFOHEADER      *pbmih;
+
   /* Privates used by shadow fb and primary fb DirectDraw servers */
   LPDIRECTDRAW		pdd;
   LPDIRECTDRAWSURFACE2	pddsPrimary;
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index f505ddd..699ed94 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -126,7 +126,7 @@ winScreenInit (int index,
       return FALSE;
     }
 
-  /* Adjust the video mode for our engine type */
+  /* Horribly misnamed function: Allow engine to adjust BPP for screen */
   if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen))
     {
       ErrorF ("winScreenInit - winAdjustVideoMode () failed\n");
@@ -269,7 +269,8 @@ winFinishScreenInitFB (int index,
     }
 
   /*
-   * Grab the number of bits that are used to represent color in each pixel.
+   * Calculate the number of bits that are used to represent color in each pixel,
+   * the color depth for the screen
    */
   if (pScreenInfo->dwBPP == 8)
     pScreenInfo->dwDepth = 8;
@@ -277,7 +278,7 @@ winFinishScreenInitFB (int index,
     pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask)
       + winCountBits (pScreenPriv->dwGreenMask)
       + winCountBits (pScreenPriv->dwBlueMask);
-  
+
   winErrorFVerb (2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n",
 	  (unsigned int) pScreenPriv->dwRedMask,
 	  (unsigned int) pScreenPriv->dwGreenMask,
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index 721234e..e9c51ee 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -338,33 +338,20 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
 {
   winScreenPriv(pScreen);
   winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
-  BITMAPINFOHEADER	*pbmih = NULL;
   DIBSECTION		dibsection;
   Bool			fReturn = TRUE;
 
-  /* Allocate bitmap info header */
-  pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
-				      + 256 * sizeof (RGBQUAD));
-  if (pbmih == NULL)
-    {
-      ErrorF ("winAllocateFBShadowGDI - malloc () failed\n");
-      return FALSE;
-    }
-
-  /* Query the screen format */
-  fReturn = winQueryScreenDIBFormat (pScreen, pbmih);
-
   /* Describe shadow bitmap to be created */
-  pbmih->biWidth = pScreenInfo->dwWidth;
-  pbmih->biHeight = -pScreenInfo->dwHeight;
-  
+  pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
+  pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
+
   ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
 	  "depth: %d\n",
-	  (int) pbmih->biWidth, (int) -pbmih->biHeight, pbmih->biBitCount);
+	  (int) pScreenPriv->pbmih->biWidth, (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
 
   /* Create a DI shadow bitmap with a bit pointer */
   pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen,
-					      (BITMAPINFO *) pbmih,
+					      (BITMAPINFO *) pScreenPriv->pbmih,
 					      DIB_RGB_COLORS,
 					      (VOID**) &pScreenInfo->pfb,
 					      NULL,
@@ -445,13 +432,6 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
 	  (int) pScreenInfo->dwStride);
 #endif
 
-  /* Determine our color masks */
-  if (!winQueryRGBBitsAndMasks (pScreen))
-    {
-      ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n");
-      return FALSE;
-    }
-
 #ifdef XWIN_MULTIWINDOW
   /* Redraw all windows */
   if (pScreenInfo->fMultiWindow)
@@ -607,6 +587,29 @@ winInitScreenShadowGDI (ScreenPtr pScreen)
   pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
   pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
 
+  /* Allocate bitmap info header */
+  pScreenPriv->pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+                                                   + 256 * sizeof (RGBQUAD));
+  if (pScreenPriv->pbmih == NULL)
+    {
+      ErrorF ("winInitScreenShadowGDI - malloc () failed\n");
+      return FALSE;
+    }
+
+  /* Query the screen format */
+  if (!winQueryScreenDIBFormat (pScreen, pScreenPriv->pbmih))
+    {
+      ErrorF ("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
+      return FALSE;
+    }
+
+  /* Determine our color masks */
+  if (!winQueryRGBBitsAndMasks (pScreen))
+    {
+      ErrorF ("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
+      return FALSE;
+    }
+
   return winAllocateFBShadowGDI(pScreen);
 }
 
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 80f5e1a..dd8f27e 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -183,28 +183,6 @@ winWindowProc (HWND hwnd, UINT message,
 	      LOWORD (lParam), HIWORD (lParam), wParam);
 
       /*
-       * TrueColor --> TrueColor depth changes are disruptive for:
-       *	Windowed:
-       *		Shadow DirectDraw
-       *		Shadow DirectDraw Non-Locking
-       *		Primary DirectDraw
-       *
-       * TrueColor --> TrueColor depth changes are non-optimal for:
-       *	Windowed:
-       *		Shadow GDI
-       *
-       *	FullScreen:
-       *		Shadow GDI
-       *
-       * TrueColor --> PseudoColor or vice versa are disruptive for:
-       *	Windowed:
-       *		Shadow DirectDraw
-       *		Shadow DirectDraw Non-Locking
-       *		Primary DirectDraw
-       *		Shadow GDI
-       */
-
-      /*
        * Check for a disruptive change in depth.
        * We can only display a message for a disruptive depth change,
        * we cannot do anything to correct the situation.
@@ -213,31 +191,38 @@ winWindowProc (HWND hwnd, UINT message,
         XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT)
         has changed as well...
       */
-      if ((s_pScreenInfo->dwBPP != GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL))
-	  && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
-	      || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
+      if (s_pScreenInfo->dwBPP != GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL))
+        {
+          if ((s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
+               || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
 #ifdef XWIN_PRIMARYFB
-	      || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
+               || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
 #endif
-	      ))
-	{
-	  /* Cannot display the visual until the depth is restored */
-	  ErrorF ("winWindowProc - Disruptive change in depth\n");
+               ))
+            {
+              /* Cannot display the visual until the depth is restored */
+              ErrorF ("winWindowProc - Disruptive change in depth\n");
 
-	  /* Display depth change dialog */
-	  winDisplayDepthChangeDialog (s_pScreenPriv);
+              /* Display depth change dialog */
+              winDisplayDepthChangeDialog (s_pScreenPriv);
 
-	  /* Flag that we have an invalid screen depth */
-	  s_pScreenPriv->fBadDepth = TRUE;
+              /* Flag that we have an invalid screen depth */
+              s_pScreenPriv->fBadDepth = TRUE;
 
-	  /* Minimize the display window */
-	  ShowWindow (hwnd, SW_MINIMIZE);
-	}
+              /* Minimize the display window */
+              ShowWindow (hwnd, SW_MINIMIZE);
+            }
+          else
+            {
+              /* For GDI, performance may suffer until original depth is restored */
+              ErrorF ("winWindowProc - Performance may be non-optimal after change in depth\n");
+            }
+        }
       else
-	{
-	  /* Flag that we have a valid screen depth */
-	  s_pScreenPriv->fBadDepth = FALSE;
-	}
+        {
+          /* Flag that we have a valid screen depth */
+          s_pScreenPriv->fBadDepth = FALSE;
+        }
 
       /*
         If we could cheaply check if this WM_DISPLAYCHANGE change
commit 8b22f83113fbdc09b932b5ad7e44f629fc15e3b5
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Aug 30 17:17:57 2010 +0100

    Cygwin/X: Use winUpdateFBPointer() in winshaddd.c rather than duplicating it inline
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index e23e100..b551bef 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -695,22 +695,7 @@ winShadowUpdateDD (ScreenPtr pScreen,
 	      "%s file to " BUILDERADDR "\n", g_pszLogFile);
 
       /* Location of shadow framebuffer has changed */
-      pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface;
-      
-      /* Update the screen pixmap */
-      if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate,
-					  pScreen->width,
-					  pScreen->height,
-					  pScreen->rootDepth,
-					  BitsPerPixel (pScreen->rootDepth),
-					  PixmapBytePad (pScreenInfo->dwStride,
-							 pScreenInfo->dwBPP),
-					  pScreenInfo->pfb))
-	{
-	  ErrorF ("winShadowUpdateDD - Bits changed, could not "
-		  "notify fb.\n");
-	  return;
-	}
+      winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
     }
 }
 
commit 8385c426f86e9955e9e570a46f75bddd3c10ca01
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Aug 10 21:55:15 2010 +0100

    Cygwin/X: Remove WIN_DIB_MAXIMUM_SIZE check
    
    This is only relevant to pre-NT versions of Windows, which are all EOL.
    
    Also, it's in the wrong place now as framebuffer can get resized.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 2eea345..96a868e 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -74,9 +74,6 @@
 #endif
 #define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH	FALSE
 
-#define WIN_DIB_MAXIMUM_SIZE	0x08000000 /* 16 MB on Windows 95, 98, Me */
-#define WIN_DIB_MAXIMUM_SIZE_MB (WIN_DIB_MAXIMUM_SIZE / 8 / 1024 / 1024)
-
 /*
  * Windows only supports 256 color palettes
  */
diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index 45d1548..e23e100 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -949,19 +949,6 @@ winAdjustVideoModeShadowDD (ScreenPtr pScreen)
       /* We'll use GDI's depth */
       pScreenInfo->dwBPP = dwBPP;
     }
-  
-  /* See if the shadow bitmap will be larger than the DIB size limit */
-  if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP
-      >= WIN_DIB_MAXIMUM_SIZE)
-    {
-      ErrorF ("winAdjustVideoModeShadowDD - Requested DirectDraw surface "
-	      "will be larger than %d MB.  The surface may fail to be "
-	      "allocated on Windows 95, 98, or Me, due to a %d MB limit in "
-	      "DIB size.  This limit does not apply to Windows NT/2000, and "
-	      "this message may be ignored on those platforms.\n",
-	      WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB);
-    }
-
   /* Release our DC */
   ReleaseDC (NULL, hdc);
   return TRUE;
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index dd2e9b5..52a4ce2 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -1010,18 +1010,6 @@ winAdjustVideoModeShadowDDNL (ScreenPtr pScreen)
       pScreenInfo->dwBPP = dwBPP;
     }
 
-  /* See if the shadow bitmap will be larger than the DIB size limit */
-  if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP
-      >= WIN_DIB_MAXIMUM_SIZE)
-    {
-      winErrorFVerb (1, "winAdjustVideoModeShadowDDNL - Requested DirectDraw surface "
-	      "will be larger than %d MB.  The surface may fail to be "
-	      "allocated on Windows 95, 98, or Me, due to a %d MB limit in "
-	      "DIB size.  This limit does not apply to Windows NT/2000, and "
-	      "this message may be ignored on those platforms.\n",
-	      WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB);
-    }
-  
   /* Release our DC */
   ReleaseDC (NULL, hdc);
 
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index a165d80..721234e 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -445,18 +445,6 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
 	  (int) pScreenInfo->dwStride);
 #endif
 
-  /* See if the shadow bitmap will be larger than the DIB size limit */
-  if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP
-      >= WIN_DIB_MAXIMUM_SIZE)
-    {
-      ErrorF ("winAllocateFBShadowGDI - Requested DIB (bitmap) "
-	      "will be larger than %d MB.  The surface may fail to be "
-	      "allocated on Windows 95, 98, or Me, due to a %d MB limit in "
-	      "DIB size.  This limit does not apply to Windows NT/2000, and "
-	      "this message may be ignored on those platforms.\n",
-	      WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB);
-    }
-
   /* Determine our color masks */
   if (!winQueryRGBBitsAndMasks (pScreen))
     {
commit 981ad1f364cf4fe8008c0f3592eb0f73dd14a118
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Aug 10 16:24:57 2010 +0100

    Cygwin/X: Fix a typo in command line argument validation code
    
    Fortunately, these swapped constants are benign as they have the same
    value, 0
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winvalargs.c b/hw/xwin/winvalargs.c
index 6680aba..04db777 100644
--- a/hw/xwin/winvalargs.c
+++ b/hw/xwin/winvalargs.c
@@ -154,8 +154,8 @@ winValidateArgs (void)
       
       /* Check for !fullscreen and any fullscreen-only parameters */
       if (!g_ScreenInfo[i].fFullScreen
-	  && (g_ScreenInfo[i].dwRefreshRate != WIN_DEFAULT_BPP
-	      || g_ScreenInfo[i].dwBPP != WIN_DEFAULT_REFRESH))
+	  && (g_ScreenInfo[i].dwRefreshRate != WIN_DEFAULT_REFRESH
+	      || g_ScreenInfo[i].dwBPP != WIN_DEFAULT_BPP))
 	{
 	  ErrorF ("winValidateArgs - -refresh and -depth are only valid "
 		  "with -fullscreen.\n");
commit 5390b494672393506466d8afdb9b146b0e585cc0
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Aug 10 13:16:13 2010 +0100

    Cygwin/X: Don't turn off -multiplemonitors when all monitors don't have the same pixel format when using shadow GDI engine
    
    Don't turn off -multiplemonitors when all monitors don't have the
    same pixel format and when using shadow GDI engine, just warn that
    performance may be degraded
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index e0686e2..f505ddd 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -151,13 +151,20 @@ winScreenInit (int index,
    * Check that all monitors have the same display depth if we are using
    * multiple monitors
    */
-  if (pScreenInfo->fMultipleMonitors 
+  if (pScreenInfo->fMultipleMonitors
       && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT))
     {
       ErrorF ("winScreenInit - Monitors do not all have same pixel format / "
-	      "display depth.\n"
-	      "Using primary display only.\n");
-      pScreenInfo->fMultipleMonitors = FALSE;
+	      "display depth.\n");
+      if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI)
+        {
+          ErrorF ("winScreenInit - Performance may suffer off primary display.\n");
+        }
+      else
+        {
+          ErrorF ("winScreenInit - Using primary display only.\n");
+          pScreenInfo->fMultipleMonitors = FALSE;
+        }
     }
 
   /* Create display window */
commit 33106e1e807a828208b306512e78c5e3e93960d3
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Mar 30 19:49:41 2010 +0100

    Cygwin/X: Generate RANDR change on WM_DISPLAYCHANGE for rootless modes
    
    When RANDR resizing is enabled, generate an internal RANDR change when
    WM_DISPLAYCHANGE occurs in rootless modes for screens which occupy an
    entire monitor or the virtual desktop.
    
    Store the monitor number and use that to handle WM_DISPLAYCHANGE for a
    screen specified with '-screen @monitor'
    
    In rooted mode, WM_DISPLAYCHANGE isn't relevant (except where display
    depth changes may cause problems). (A maximized screen window will get
    WM_SIZE to adjust it to the new monitor size)
    
    In rooted fullscreen mode, WM_DISPLAYCHANGE shouldn't be seen, as we
    have the resolution we have selected for the fullscreen session)
    (Could client randr requests be handled in fullscreen to cause a change
    of the fullscreen resolution? )
    
    Don't bother do a RANDR resize if the dimensions aren't actually changing
    when WM_DISPLAYCHANGE is sent (should handle WM_DISPLAYCHANGE to size 0x0
    that the intel driver seems to like to send)
    
    Various debug output improvements
    
    Also, remove the note that XWin can't handle display mode changes from
    the man page
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 39cdf5e..e7933c9 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -376,12 +376,9 @@ X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(__filemansuffix__), s
 
 .SH BUGS
 .I XWin
-and this man page still have many limitations.  Some of the more obvious
-ones are:
-.br
-- The display mode can not be changed once the X server has started.
-.br
-- The \fIXWin\fP software is continuously developing; it is therefore possible that
+and this man page still have many limitations.
+
+The \fIXWin\fP software is continuously developing; it is therefore possible that
 this man page is not up to date.  It is always prudent to
 look also at the output of \fIXWin -help\fP in order to
 check the options that are operative.
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index bbc0f2f..2eea345 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -400,6 +400,8 @@ typedef struct
   Bool			fUserGaveHeightAndWidth;
 
   DWORD			dwScreen;
+
+  int			iMonitor;
   DWORD			dwUserWidth;
   DWORD			dwUserHeight;
   DWORD			dwWidth;
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index e4c52ef..ddfe1f5 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -95,6 +95,7 @@ winInitializeScreenDefaults(void)
   if (monitorResolution == 0)
     monitorResolution = WIN_DEFAULT_DPI;
 
+  defaultScreenInfo.iMonitor = 1;
   defaultScreenInfo.dwWidth  = dwWidth;
   defaultScreenInfo.dwHeight = dwHeight;
   defaultScreenInfo.dwUserWidth  = dwWidth;
@@ -318,6 +319,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
 		  iArgsProcessed = 3;
 		  g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
 		  g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
+		  g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
 		  g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth;
 		  g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight;
 		  g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth;
@@ -370,6 +372,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
                       "Querying monitors is not supported on NT4 and Win95\n");
           } else if (data.bMonitorSpecifiedExists == TRUE) 
           {
+			g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
 			g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX;
 			g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY;
 		  }
@@ -399,6 +402,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
         {
 		  winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
 		  g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
+		  g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
 		  g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
 		  g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
 		}
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 04a3a6b..80f5e1a 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -40,6 +40,7 @@
 #include "winprefs.h"
 #include "winconfig.h"
 #include "winmsg.h"
+#include "winmonitors.h"
 #include "inputstr.h"
 
 /*
@@ -177,12 +178,9 @@ winWindowProc (HWND hwnd, UINT message,
 	  break;
 	}
 
-      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new bpp: %d\n",
-	      wParam);
-
       ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
-	      "new height: %d\n",
-	      LOWORD (lParam), HIWORD (lParam));
+	      "new height: %d new bpp: %d\n",
+	      LOWORD (lParam), HIWORD (lParam), wParam);
 
       /*
        * TrueColor --> TrueColor depth changes are disruptive for:
@@ -254,41 +252,105 @@ winWindowProc (HWND hwnd, UINT message,
        * the display dimensions change.
        */
 	{
-	  /*
-	   * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
-	   * and CreatePrimarySurface function pointers to point
-	   * to the no operation function, NoopDDA.  This allows us
-	   * to blindly call these functions, even if they are not
-	   * relevant to the current engine (e.g., Shadow GDI).
-	   */
-
-#if CYGDEBUG
-	  winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n");
-#endif
-
-	  /* Release the old primary surface */
-	  (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
-
-#if CYGDEBUG
-	  winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released "
-		  "primary surface\n");
-#endif
-
-	  /* Create the new primary surface */
-	  (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
 
 #if CYGDEBUG
 	  winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated "
 		  "primary surface\n");
 #endif
 
-#if 0
-	  /* Multi-Window mode uses RandR for resizes */
-	  if (s_pScreenInfo->fMultiWindow)
+	  /*
+             In rootless modes which are monitor or virtual desktop size
+             use RandR to resize the X screen
+          */
+          if ((!s_pScreenInfo->fUserGaveHeightAndWidth) &&
+              (s_pScreenInfo->iResizeMode == resizeWithRandr) &&
+              (FALSE
+#ifdef XWIN_MULTIWINDOWEXTWM
+               || s_pScreenInfo->fMWExtWM
+#endif
+               || s_pScreenInfo->fRootless
+#ifdef XWIN_MULTIWINDOW
+               || s_pScreenInfo->fMultiWindow
+#endif
+               ))
 	    {
-	      RRSetScreenConfig ();
+              DWORD dwWidth, dwHeight;
+
+              if (s_pScreenInfo->fMultipleMonitors)
+                {
+                  /* resize to new virtual desktop size */
+                  dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+                  dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+                }
+              else
+                {
+                  /* resize to new size of specified monitor */
+                  struct GetMonitorInfoData data;
+                  if (QueryMonitor(s_pScreenInfo->iMonitor, &data))
+                    {
+                      if (data.bMonitorSpecifiedExists == TRUE)
+                        {
+                          dwWidth = data.monitorWidth;
+                          dwHeight = data.monitorHeight;
+                          /*
+                             XXX: monitor may have changed position,
+                             so we might need to update xinerama data
+                          */
+                        }
+                      else
+                        {
+                          ErrorF ("Monitor number %d no longer exists!\n", s_pScreenInfo->iMonitor);
+                        }
+                    }
+                }
+
+              /*
+                XXX: probably a small bug here: we don't compute the work area
+                and allow for task bar
+
+                XXX: generally, we don't allow for the task bar being moved after
+                the server is started
+               */
+
+              /* Set screen size to match new size, if it is different to current */
+              if ((s_pScreenInfo->dwWidth != dwWidth) ||
+                  (s_pScreenInfo->dwHeight != dwHeight))
+                {
+                  winDoRandRScreenSetSize(s_pScreen,
+                                          dwWidth,
+                                          dwHeight,
+                                          (dwWidth * 25.4) / monitorResolution,
+                                          (dwHeight * 25.4) / monitorResolution);
+                }
 	    }
-#endif
+          else
+            {
+              /*
+                If we get here, we are either windowed and using the GDI engine
+                or windowed and non-fullscreen using any engine
+              */
+
+              /*
+               * For ddraw engines, we need to (try to) recreate the same-sized primary surface
+               * when display dimensions change (but not depth, that is disruptive)
+               */
+
+              /*
+               * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
+               * and CreatePrimarySurface function pointers to point
+               * to the no operation function, NoopDDA.  This allows us
+               * to blindly call these functions, even if they are not
+               * relevant to the current engine (e.g., Shadow GDI).
+               */
+
+              winDebug ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n");
+
+              /* Release the old primary surface */
+              (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
+
+              /* Create the new primary surface */
+              (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
+            }
 	}
 
       break;
commit bbc511e80b2a9365f6a1528bc1595772f83be654
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Feb 15 13:42:04 2010 +0000

    Cygwin/X: Make WM_SIZE use RandR resizing when -resize=randr
    
    To avoid recursion, WM_SIZE requests shouldn't generate XRANDR requests
    when no change is neeeded.
    
    We do the actual resize on WM_EXITSIZEMOVE, as resizing occurs in
    a modal loop, to avoid a backlog of resize events building up as
    the X server doesn't get a change to process anything until the resize
    is completed.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 27fc840..04a3a6b 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -303,7 +303,7 @@ winWindowProc (HWND hwnd, UINT message,
 	winDebug ("winWindowProc - WM_SIZE\n");
 #endif
 
-	/* Break if we do not use scrollbars */
+	/* Break if we do not allow resizing */
 	if ((s_pScreenInfo->iResizeMode == notAllowed)
 	    || !s_pScreenInfo->fDecoration
 #ifdef XWIN_MULTIWINDOWEXTWM
@@ -320,6 +320,17 @@ winWindowProc (HWND hwnd, UINT message,
 	if (wParam == SIZE_MINIMIZED)
 	  return 0;
 
+        ErrorF ("winWindowProc - WM_SIZE - new client area w: %d h: %d\n",
+                LOWORD (lParam), HIWORD (lParam));
+
+        if (s_pScreenInfo->iResizeMode == resizeWithRandr)
+          {
+            /* Actual resizing is done on WM_EXITSIZEMOVE */
+            return 0;
+          }
+
+        /* Otherwise iResizeMode == resizeWithScrollbars */
+
 	/*
 	 * Get the size of the whole window, including client area,
 	 * scrollbars, and non-client area decorations (caption, borders).
@@ -337,10 +348,6 @@ winWindowProc (HWND hwnd, UINT message,
 	iWidth = rcWindow.right - rcWindow.left;
 	iHeight = rcWindow.bottom - rcWindow.top;
 
-	ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, "
-		"new client area w: %d h: %d\n",
-		iWidth, iHeight, LOWORD (lParam), HIWORD (lParam));
-
 	/* Subtract the frame size from the window size. */
 	iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME);
 	iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME)
@@ -396,6 +403,37 @@ winWindowProc (HWND hwnd, UINT message,
       }
       return 0;
 
+    case WM_ENTERSIZEMOVE:
+      ErrorF("winWindowProc - WM_ENTERSIZEMOVE\n");
+      break;
+
+    case WM_EXITSIZEMOVE:
+      ErrorF("winWindowProc - WM_EXITSIZEMOVE\n");
+
+      if (s_pScreenInfo->iResizeMode == resizeWithRandr)
+        {
+          /* Set screen size to match new client area, if it is different to current */
+          RECT rcClient;
+          DWORD dwWidth, dwHeight;
+
+          GetClientRect (hwnd, &rcClient);
+          dwWidth = rcClient.right - rcClient.left;
+          dwHeight = rcClient.bottom - rcClient.top;
+
+          if ((s_pScreenInfo->dwWidth != dwWidth) ||
+              (s_pScreenInfo->dwHeight != dwHeight))
+            {
+              /* mm = dots * (25.4 mm / inch) / (dots / inch) */
+              winDoRandRScreenSetSize(s_pScreen,
+                                      dwWidth,
+                                      dwHeight,
+                                      (dwWidth * 25.4) / monitorResolution,
+                                      (dwHeight * 25.4) / monitorResolution);
+            }
+        }
+
+      break;
+
     case WM_VSCROLL:
       {
 	SCROLLINFO		si;
commit 85c497a8b6c488ef9ea2c6d7b49e6f9b992fb4a2
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Mar 30 20:48:10 2010 +0100

    Cygwin/X: Implement framebuffer resizing in RANDR extension
    
    Implement framebuffer resizing in RANDR extension:
    
    Resize the frame buffer, the screen's root window and the native window
    containing the root window image.
    
    Correctly allow for decorations in new native window size when resizing native window
    to fit the new framebuffer size with AdjustWindowRectEx()
    
    Update physical size info for a screen when it is changed by RANDR
    
    Forbid client-requested RANDR changes in fullscreen and rootless modes
    
    Only resize window on an external RandR request, to avoid recursing on
    a WM_SIZE requested resize.
    
    Also, add prototypes for winRandRInit() and winDoRandRScreenSetSize() to header file
    
    Also, update the author list and copyright for winrandr.c
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 0df1d27..bbc0f2f 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1472,6 +1472,18 @@ void
 winInitializeScreens(int maxscreens);
 
 /*
+ * winrandr.c
+ */
+Bool
+winRandRInit (ScreenPtr pScreen);
+void
+winDoRandRScreenSetSize (ScreenPtr  pScreen,
+                         CARD16	    width,
+                         CARD16	    height,
+                         CARD32	    mmWidth,
+                         CARD32	    mmHeight);
+
+/*
  * END DDX and DIX Function Prototypes
  */
 
diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c
index fd1d97e..2484048 100644
--- a/hw/xwin/winrandr.c
+++ b/hw/xwin/winrandr.c
@@ -1,8 +1,9 @@
 /*
  *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) 2009-2010 Jon TURNEY
  *
  *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
+ *a copy of this software and associated documentation files (the
  *"Software"), to deal in the Software without restriction, including
  *without limitation the rights to use, copy, modify, merge, publish,
  *distribute, sublicense, and/or sell copies of the Software, and to
@@ -20,101 +21,280 @@
  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- *Except as contained in this notice, the name of Harold L Hunt II
+ *Except as contained in this notice, the name of the author(s)
  *shall not be used in advertising or otherwise to promote the sale, use
  *or other dealings in this Software without prior written authorization
- *from Harold L Hunt II.
+ *from the author(s)
  *
  * Authors:	Harold L Hunt II
+ *              Jon TURNEY
  */
 
 #ifdef HAVE_XWIN_CONFIG_H
 #include <xwin-config.h>
 #endif
 #include "win.h"
+#include "mivalidate.h" // for union _Validate used by windowstr.h
+
+#ifndef RANDR_12_INTERFACE
+#error X server must have RandR 1.2 interface
+#endif
 
 
 /*
- * Local prototypes
+ * Answer queries about the RandR features supported.
  */
 
 static Bool
-winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations);
+winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
+{
+  winDebug ("winRandRGetInfo ()\n");
 
-static Bool
-winRandRSetConfig (ScreenPtr		pScreen,
-		   Rotation		rotateKind,
-		   int			rate,
-		   RRScreenSizePtr	pSize);
+  /* Don't support rotations */
+  *pRotations = RR_Rotate_0;
 
-Bool
-winRandRInit (ScreenPtr pScreen);
+  /*
+    The screen doesn't have to be limited to the actual
+    monitor size (we can have scrollbars :-), so what is
+    the upper limit?
+  */
+  RRScreenSetSizeRange(pScreen, 0, 0, 4096, 4096);
+
+  return TRUE;
+}
 
 
 /*
- * Answer queries about the RandR features supported.
+  Copied from the xfree86 DDX
+
+  Why can't this be in DIX?
+  Does union _Validate vary depending on DDX??
  */
+static void
+xf86SetRootClip (ScreenPtr pScreen, Bool enable)
+{
+    WindowPtr	pWin = pScreen->root;
+    WindowPtr	pChild;
+    Bool	WasViewable = (Bool)(pWin->viewable);
+    Bool	anyMarked = FALSE;
+    WindowPtr   pLayerWin;
+    BoxRec	box;
 
-static Bool
-winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
+    if (WasViewable)
+    {
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	{
+	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
+						     pChild,
+						     &pLayerWin);
+	}
+	(*pScreen->MarkWindow) (pWin);
+	anyMarked = TRUE;
+	if (pWin->valdata)
+	{
+	    if (HasBorder (pWin))
+	    {
+		RegionPtr	borderVisible;
+
+		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				&pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	    pWin->valdata->before.resized = TRUE;
+	}
+    }
+
+    /*
+     * Use REGION_BREAK to avoid optimizations in ValidateTree
+     * that assume the root borderClip can't change well, normally
+     * it doesn't...)
+     */
+    if (enable)
+    {
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pScreen->width;
+	box.y2 = pScreen->height;
+	REGION_INIT (pScreen, &pWin->winSize, &box, 1);
+	REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
+	if (WasViewable)
+	    REGION_RESET(pScreen, &pWin->borderClip, &box);
+	pWin->drawable.width = pScreen->width;
+	pWin->drawable.height = pScreen->height;
+        REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+    }
+    else
+    {
+	REGION_EMPTY(pScreen, &pWin->borderClip);
+	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+    }
+
+    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pWin->firstChild)
+	{
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+							   pWin->firstChild,
+							   (WindowPtr *)NULL);
+	}
+	else
+	{
+	    (*pScreen->MarkWindow) (pWin);
+	    anyMarked = TRUE;
+	}
+
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+    }
+
+    if (WasViewable)
+    {
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pWin);
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+    FlushAllOutput ();
+}
+
+/*
+
+*/
+void
+winDoRandRScreenSetSize (ScreenPtr  pScreen,
+                         CARD16	    width,
+                         CARD16	    height,
+                         CARD32	    mmWidth,
+                         CARD32	    mmHeight)
 {
   winScreenPriv(pScreen);
-  winScreenInfo			*pScreenInfo = pScreenPriv->pScreenInfo;
-  int				n;
-  Rotation			rotateKind;
-  RRScreenSizePtr		pSize;
+  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+  WindowPtr pRoot = pScreen->root;
 
-  winDebug ("winRandRGetInfo ()\n");
+  // Prevent screen updates while we change things around
+  xf86SetRootClip(pScreen, FALSE);
 
-  /* Don't support rotations, yet */
-  *pRotations = RR_Rotate_0;
+  /* Update the screen size as requested */
+  pScreenInfo->dwWidth = width;
+  pScreenInfo->dwHeight = height;
 
-  /* Bail if no depth has a visual associated with it */
-  for (n = 0; n < pScreen->numDepths; n++)
-    if (pScreen->allowedDepths[n].numVids)
-      break;
-  if (n == pScreen->numDepths)
-    return FALSE;
+  /* Reallocate the framebuffer used by the drawing engine */
+  (*pScreenPriv->pwinFreeFB)(pScreen);
+  if (!(*pScreenPriv->pwinAllocateFB)(pScreen))
+    {
+      ErrorF ("winDoRandRScreenSetSize - Could not reallocate framebuffer\n");
+    }
 
-  /* Only one allowed rotation for now */
-  rotateKind = RR_Rotate_0;
+  pScreen->width = width;
+  pScreen->height = height;
+  pScreen->mmWidth = mmWidth;
+  pScreen->mmHeight = mmHeight;
 
-  /*
-   * Register supported sizes.  This can be called many times, but
-   * we only support one size for now.
-   */
-  pSize = RRRegisterSize (pScreen,
-			  pScreenInfo->dwWidth,
-			  pScreenInfo->dwHeight,
-                          (pScreenInfo->dwWidth / monitorResolution) * 25.4,
-                          (pScreenInfo->dwHeight / monitorResolution) * 25.4);
-
-  /* Tell RandR what the current config is */
-  RRSetCurrentConfig (pScreen,
-		      rotateKind,
-		      0, /* refresh rate, not needed */
-		      pSize);
-  
-  return TRUE;
-}
+  /* Update the screen pixmap to point to the new framebuffer */
+  winUpdateFBPointer(pScreen, pScreenInfo->pfb);
+
+  // pScreen->devPrivate == pScreen->GetScreenPixmap(screen) ?
+  // resize the root window
+  //pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL);
+  // does this emit a ConfigureNotify??
 
+  // Restore the ability to update screen, now with new dimensions
+  xf86SetRootClip(pScreen, TRUE);
+
+  // and arrange for it to be repainted
+  miPaintWindow(pRoot, &pRoot->borderClip,  PW_BACKGROUND);
+
+  /* Indicate that a screen size change took place */
+  RRScreenSizeNotify(pScreen);
+}
 
 /*
- * Respond to resize/rotate request from either X Server or X client app
+ * Respond to resize request
  */
-
-static Bool
-winRandRSetConfig (ScreenPtr		pScreen,
-		   Rotation		rotateKind,
-		   int			rate,
-		   RRScreenSizePtr	pSize)
+static
+Bool
+winRandRScreenSetSize (ScreenPtr  pScreen,
+		       CARD16	    width,
+		       CARD16	    height,
+		       CARD16       pixWidth,
+		       CARD16       pixHeight,
+		       CARD32	    mmWidth,
+		       CARD32	    mmHeight)
 {
-  winDebug ("winRandRSetConfig ()\n");
+  winScreenPriv(pScreen);
+  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+  winDebug ("winRandRScreenSetSize ()\n");
+
+  /*
+    It doesn't currently make sense to allow resize in fullscreen mode
+    (we'd actually have to list the supported resolutions)
+  */
+  if (pScreenInfo->fFullScreen)
+    {
+      ErrorF ("winRandRScreenSetSize - resize not supported in fullscreen mode\n");
+      return FALSE;
+    }
+
+  /*
+    Client resize requests aren't allowed in rootless modes, even if
+    the X screen is monitor or virtual desktop size, we'd need to
+    resize the native display size
+  */
+  if (FALSE
+#ifdef XWIN_MULTIWINDOWEXTWM
+      || pScreenInfo->fMWExtWM
+#endif
+      || pScreenInfo->fRootless
+#ifdef XWIN_MULTIWINDOW
+      || pScreenInfo->fMultiWindow
+#endif
+      )
+    {
+      ErrorF ("winRandRScreenSetSize - resize not supported in rootless modes\n");
+      return FALSE;
+    }
+
+  winDoRandRScreenSetSize(pScreen, width, height, mmWidth, mmHeight);
+
+  /* Cause the native window for the screen to resize itself */
+  {
+    DWORD dwStyle, dwExStyle;
+    RECT rcClient;
+
+    rcClient.left = 0;
+    rcClient.top = 0;
+    rcClient.right = width;
+    rcClient.bottom = height;
+
+    ErrorF ("winRandRScreenSetSize new client area w: %d h: %d\n", width, height);
+
+    /* Get the Windows window style and extended style */
+    dwExStyle = GetWindowLongPtr(pScreenPriv->hwndScreen, GWL_EXSTYLE);
+    dwStyle = GetWindowLongPtr(pScreenPriv->hwndScreen, GWL_STYLE);
+
+    /*
+     * Calculate the window size needed for the given client area
+     * adjusting for any decorations it will have
+     */
+    AdjustWindowRectEx(&rcClient, dwStyle, FALSE, dwExStyle);
+
+    ErrorF ("winRandRScreenSetSize new window area w: %ld h: %ld\n", rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
+
+    SetWindowPos(pScreenPriv->hwndScreen, NULL,
+                 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
+                 SWP_NOZORDER | SWP_NOMOVE);
+  }
 
   return TRUE;
 }
 
-
 /*
  * Initialize the RandR layer.
  */
@@ -122,8 +302,7 @@ winRandRSetConfig (ScreenPtr		pScreen,
 Bool
 winRandRInit (ScreenPtr pScreen)
 {
-  rrScrPrivPtr		pRRScrPriv;
-
+  rrScrPrivPtr pRRScrPriv;
   winDebug ("winRandRInit ()\n");
 
   if (!RRScreenInit (pScreen))
@@ -135,7 +314,10 @@ winRandRInit (ScreenPtr pScreen)
   /* Set some RandR function pointers */
   pRRScrPriv = rrGetScrPriv (pScreen);
   pRRScrPriv->rrGetInfo = winRandRGetInfo;
-  pRRScrPriv->rrSetConfig = winRandRSetConfig;
+  pRRScrPriv->rrSetConfig = NULL;
+  pRRScrPriv->rrScreenSetSize = winRandRScreenSetSize;
+  pRRScrPriv->rrCrtcSet = NULL;
+  pRRScrPriv->rrCrtcSetGamma = NULL;
 
   return TRUE;
 }
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 74ca115..e0686e2 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -69,10 +69,6 @@ winMWExtWMProcs = {
  * Prototypes
  */
 
-Bool
-winRandRInit (ScreenPtr pScreen);
-
-
 /*
  * Local functions
  */
commit 873abef315f5d947b864428891381bff539c5869
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Mar 30 20:07:19 2010 +0100

    Cygwin/X: Add -resize command line option
    
    Add -resize command line option to configure how native window sizing frame
    is used.
    
    In additions to the existing fixed and scrollbars modes, add a new mode to
    allow framebuffer to be resized using native window frame
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index bf04cf1..7faed01 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -826,6 +826,11 @@ winUseMsg (void)
 	  "\tSpecify an optional refresh rate to use in fullscreen mode\n"
 	  "\twith a DirectDraw engine.\n");
 
+  ErrorF ("-resize=none|scrollbars|randr"
+	  "\tIn windowed mode, [don't] allow resizing of the window. 'scrollbars'\n"
+	  "\tmode gives the window scrollbars as needed, 'randr' mode uses the RANR\n"
+	  "\textension to resize the X screen.\n");
+
   ErrorF ("-rootless\n"
 	  "\tRun the server in rootless mode.\n");
 
@@ -839,11 +844,6 @@ winUseMsg (void)
       "\t -screen 0 1024x768 at 3        ; 3rd monitor size 1024x768\n"
       "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n");
 
-  ErrorF ("-scrollbars\n"
-	  "\tIn windowed mode, allow screens bigger than the Windows desktop.\n"
-	  "\tMoreover, if the window has decorations, one can now resize\n"
-	  "\tit.\n");
-
   ErrorF ("-silent-dup-error\n"
 	  "\tIf another instance of " EXECUTABLE_NAME " with the same display number is running\n"
 	  "\texit silently and don't display any error message.\n");
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 76abdca..39cdf5e 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -103,7 +103,7 @@ Examples:
 
 .SH OPTIONS CONTROLLING THE APPEARANCE OF THE X SCREEN WINDOWS
 These parameters only apply to windowed mode screens i.e. not
-in \fB-multwindow\fP or \fB-rootless\fP mode
+in \fB-multiwindow\fP or \fB-rootless\fP mode.
 .TP 8
 .B "\-fullscreen"
 The X server window takes the full screen, covering completely the
@@ -115,10 +115,52 @@ etc.
 This parameter is ignored when the \fB\-fullscreen\fP parameter is specified.
 .TP 8
 .B \-scrollbars
-In windowed mode, allow screens bigger than the \fIWindows\fP desktop.
-Moreover, if the window has decorations, one can now resize it.
-This parameter is ignored when the \fB\-fullscreen\fP parameter is specified.
+Alternative name for \fB\-resize=scrollbars\fP.
+
+.SH OPTIONS CONTROLLING RESIZE BEHAVIOUR
+.TP 8
+.B \-resize[=none|scrollbars|randr]
+Select the resize mode of an X screen.
+
+.RS
+.IP \fB\-resize=none\fP 8
+(default). The screen is not resizable.
+
+In windowed mode, if the window has decorations, a fixed frame is used.
+
+.IP \fB\-resize=scrollbars\fP 8
+The screen window is resizeable, but the screen is not resizable.
+
+In windowed mode, if the window has decorations, a resizing frame is used.
+Scrollbars are drawn when needed to allow the entire X screen
+to viewed by adjusting them.
 
+This also permits screens bigger than the \fIWindows\fP virtual desktop to be used.
+
+This parameter is ignored in \fB-multiwindow\fP or \fB-rootless\fP mode.
+Alternative name is \fB\-scrollbars\fP.
+
+.IP \fB\-resize=randr\fP 8
+The screen is resizable and the screen window is resizeable.
+
+In windowed mode, if the window has decorations, a resizing frame is used.
+
+Resizing the  \fIWindows\fP window will use the RANDR extension to change
+the size of the X screen.  Likewise, changing the size of
+the X screen using the RANDR extension will cause the size
+of the \fIWindows\fP window containing the X screen to be changed.
+
+In \fB-multiwindow\fP or \fB-rootless\fP mode, if the X screen is
+of the same dimensions as a Windows monitor or the virtual desktop,
+the X server will respond to the WM_DISPLAYCHANGED sent when those
+dimensions change by resizing the X screen.  Changing the size
+of the X screen using the RANDR extension is not permitted.
+
+The maximum dimensions of the screen are the dimensions of the \fIWindows\fP virtual desktop.
+
+.IP \fB\--resize\fP 8
+on its own is equivalent to \fB\--resize=randr\fP
+.RE
 
 .SH OPTIONS CONTROLLING WINDOWS INTEGRATION
 .TP 8
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index ceb001c..0df1d27 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -379,6 +379,15 @@ typedef struct {
 } winCursorRec;
 
 /*
+ * Resize modes
+ */
+typedef enum {
+  notAllowed,
+  resizeWithScrollbars,
+  resizeWithRandr
+} winResizeMode;
+
+/*
  * Screen information structure that we need before privates are available
  * in the server startup sequence.
  */
@@ -439,7 +448,7 @@ typedef struct
 #endif
   Bool                  fMultipleMonitors;
   Bool			fLessPointer;
-  Bool			fScrollbars;
+  winResizeMode		iResizeMode;
   Bool			fNoTrayIcon;
   int			iE3BTimeout;
   /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */
diff --git a/hw/xwin/wincreatewnd.c b/hw/xwin/wincreatewnd.c
index 0c342e1..7553739 100644
--- a/hw/xwin/wincreatewnd.c
+++ b/hw/xwin/wincreatewnd.c
@@ -192,7 +192,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
           fForceShowWindow = TRUE;
         } 
         dwWindowStyle |= WS_CAPTION;
-        if (pScreenInfo->fScrollbars)
+        if (pScreenInfo->iResizeMode != notAllowed)
             dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX;
     }
   else
@@ -233,6 +233,22 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
       iPosY = rcWorkArea.top;
     }
 
+  /* Clean up the scrollbars flag, if necessary */
+  if ((!pScreenInfo->fDecoration
+#ifdef XWIN_MULTIWINDOWEXTWM
+       || pScreenInfo->fMWExtWM
+#endif
+       || pScreenInfo->fRootless
+#ifdef XWIN_MULTIWINDOW
+       || pScreenInfo->fMultiWindow
+#endif
+       )
+      && (pScreenInfo->iResizeMode == resizeWithScrollbars))
+    {
+      /* We cannot have scrollbars if we do not have a window border */
+      pScreenInfo->iResizeMode = notAllowed;
+    }
+
   /* Did the user specify a height and width? */
   if (pScreenInfo->fUserGaveHeightAndWidth)
     {
@@ -256,12 +272,12 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
 #if CYGDEBUG
 	  winDebug ("winCreateBoundingWindowWindowed - Window has decoration\n");
 #endif
-	  /* Are we using scrollbars? */
-	  if (pScreenInfo->fScrollbars)
+
+          /* Are we resizable */
+          if (pScreenInfo->iResizeMode != notAllowed)
 	    {
 #if CYGDEBUG
-	      winDebug ("winCreateBoundingWindowWindowed - Window has "
-		      "scrollbars\n");
+	      winDebug ("winCreateBoundingWindowWindowed - Window is resizable\n");
 #endif
 
 	      iWidth += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
@@ -271,8 +287,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
 	  else
 	    {
 #if CYGDEBUG
-	      winDebug ("winCreateBoundingWindowWindowed - Window does not have "
-		      "scrollbars\n");
+	      winDebug ("winCreateBoundingWindowWindowed - Window is not resizable\n");
 #endif
 
 	      iWidth += 2 * GetSystemMetrics (SM_CXFIXEDFRAME);
@@ -296,22 +311,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
 	}
     }
 
-  /* Clean up the scrollbars flag, if necessary */
-  if ((!pScreenInfo->fDecoration
-#ifdef XWIN_MULTIWINDOWEXTWM
-       || pScreenInfo->fMWExtWM
-#endif
-       || pScreenInfo->fRootless
-#ifdef XWIN_MULTIWINDOW
-       || pScreenInfo->fMultiWindow
-#endif
-       )
-      && pScreenInfo->fScrollbars)
-    {
-      /* We cannot have scrollbars if we do not have a window border */
-      pScreenInfo->fScrollbars = FALSE;
-    }
- 
+  /* Make sure window is no bigger than work area */
   if (TRUE 
 #ifdef XWIN_MULTIWINDOWEXTWM
        && !pScreenInfo->fMWExtWM
@@ -396,7 +396,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
 	  rcClient.bottom, rcClient.top);
   
   /* We adjust the visual size if the user did not specify it */
-  if (!(pScreenInfo->fScrollbars && pScreenInfo->fUserGaveHeightAndWidth))
+  if (!((pScreenInfo->iResizeMode == resizeWithScrollbars) && pScreenInfo->fUserGaveHeightAndWidth))
     {
       /*
        * User did not give a height and width with scrollbars enabled,
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index fe9d7c2..e4c52ef 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -123,7 +123,7 @@ winInitializeScreenDefaults(void)
 #endif
   defaultScreenInfo.fMultipleMonitors = FALSE;
   defaultScreenInfo.fLessPointer = FALSE;
-  defaultScreenInfo.fScrollbars = FALSE;
+  defaultScreenInfo.iResizeMode = notAllowed;
   defaultScreenInfo.fNoTrayIcon = FALSE;
   defaultScreenInfo.iE3BTimeout = WIN_E3B_OFF;
   defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
@@ -656,12 +656,51 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-scrollbars"))
     {
-      screenInfoPtr->fScrollbars = TRUE;
+
+      screenInfoPtr->iResizeMode = resizeWithScrollbars;
 
       /* Indicate that we have processed this argument */
       return 1;
     }
 
+  /*
+   * Look for the '-resize' argument
+   */
+  if (IS_OPTION ("-resize") || IS_OPTION ("-noresize") ||
+      (strncmp(argv[i], "-resize=",strlen("-resize=")) == 0))
+    {
+      winResizeMode mode;
+
+      if (IS_OPTION ("-resize"))
+        mode = resizeWithRandr;
+      else if (IS_OPTION ("-noresize"))
+        mode = notAllowed;
+      else if (strncmp(argv[i], "-resize=",strlen("-resize=")) == 0)
+        {
+          char *option = argv[i] + strlen("-resize=");
+          if (strcmp(option, "randr") == 0)
+            mode = resizeWithRandr;
+          else if (strcmp(option, "scrollbars") == 0)
+            mode = resizeWithScrollbars;
+          else if (strcmp(option, "none") == 0)
+            mode = notAllowed;
+          else
+            {
+              ErrorF ("ddxProcessArgument - resize - Invalid resize mode %s\n", option);
+              return 0;
+            }
+        }
+      else
+        {
+          ErrorF ("ddxProcessArgument - resize - Invalid resize option %s\n", argv[i]);
+          return 0;
+        }
+
+      screenInfoPtr->iResizeMode = mode;
+
+      /* Indicate that we have processed this argument */
+      return 1;
+    }
 
 #ifdef XWIN_CLIPBOARD
   /*
diff --git a/hw/xwin/winvalargs.c b/hw/xwin/winvalargs.c
index 357d3d7..6680aba 100644
--- a/hw/xwin/winvalargs.c
+++ b/hw/xwin/winvalargs.c
@@ -164,12 +164,12 @@ winValidateArgs (void)
 
       /* Check for fullscreen and any non-fullscreen parameters */
       if (g_ScreenInfo[i].fFullScreen
-	  && (g_ScreenInfo[i].fScrollbars
+	  && ((g_ScreenInfo[i].iResizeMode != notAllowed)
 	      || !g_ScreenInfo[i].fDecoration
 	      || g_ScreenInfo[i].fLessPointer))
 	{
 	  ErrorF ("winValidateArgs - -fullscreen is invalid with "
-		  "-scrollbars, -nodecoration, or -lesspointer.\n");
+		  "-scrollbars, -resize, -nodecoration, or -lesspointer.\n");
 	  return FALSE;
 	}
     }
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 7983e9a..27fc840 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -304,7 +304,7 @@ winWindowProc (HWND hwnd, UINT message,
 #endif
 
 	/* Break if we do not use scrollbars */
-	if (!s_pScreenInfo->fScrollbars
+	if ((s_pScreenInfo->iResizeMode == notAllowed)
 	    || !s_pScreenInfo->fDecoration
 #ifdef XWIN_MULTIWINDOWEXTWM
 	    || s_pScreenInfo->fMWExtWM
@@ -579,7 +579,7 @@ winWindowProc (HWND hwnd, UINT message,
 
 	/* Can't do anything without screen info */
 	if (s_pScreenInfo == NULL
-	    || !s_pScreenInfo->fScrollbars
+	    || (s_pScreenInfo->iResizeMode != resizeWithScrollbars)
 	    || s_pScreenInfo->fFullScreen
 	    || !s_pScreenInfo->fDecoration
 #ifdef XWIN_MULTIWINDOWEXTWM
commit 46c57788539d8a5f0246528b4f88ad4ed6d867d1
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Feb 23 15:44:36 2010 +0000

    Cygwin/X: Move QueryMonitor() out of windprocarg.c
    
    Move QueryMonitor() out of windprocarg.c into a new file, winmonitors.c,
    as we use to use it from other places as well
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index f6a75df..ce2edb2 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -87,6 +87,7 @@ SRCS =	InitInput.c \
 	winkeybd.c \
 	winkeyhook.c \
 	winmisc.c \
+	winmonitors.c \
 	winmouse.c \
 	winmsg.c \
 	winmultiwindowclass.c \
diff --git a/hw/xwin/winmonitors.c b/hw/xwin/winmonitors.c
new file mode 100644
index 0000000..63af803
--- /dev/null
+++ b/hw/xwin/winmonitors.c
@@ -0,0 +1,92 @@
+/*
+
+Copyright 1993, 1998  The Open Group
+Copyright (C) Colin Harrison 2005-2008
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+
+#include "win.h"
+#include "winmonitors.h"
+
+/*
+ * getMonitorInfo - callback function used to return information from the enumeration of monitors attached
+ */
+
+static
+wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data)
+{
+  struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data;
+  // only get data for monitor number specified in <data>
+  data->monitorNum++;
+  if (data->monitorNum == data->requestedMonitor)
+  {
+	data->bMonitorSpecifiedExists = TRUE;
+	data->monitorOffsetX = rect->left;
+	data->monitorOffsetY = rect->top;
+	data->monitorHeight  = rect->bottom - rect->top;
+	data->monitorWidth   = rect->right  - rect->left;
+    return FALSE;
+  }
+  return TRUE;
+}
+
+typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
+ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors;
+
+wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data);
+
+Bool QueryMonitor(int index, struct GetMonitorInfoData *data)
+{
+    /* Load EnumDisplayMonitors from DLL */
+    HMODULE user32;
+    FARPROC func;
+    user32 = LoadLibrary("user32.dll");
+    if (user32 == NULL)
+    {
+        winW32Error(2, "Could not open user32.dll");
+        return FALSE;
+    }
+    func = GetProcAddress(user32, "EnumDisplayMonitors");
+    if (func == NULL)
+    {
+        winW32Error(2, "Could not resolve EnumDisplayMonitors: ");
+        return FALSE;
+    }
+    _EnumDisplayMonitors = (ENUMDISPLAYMONITORSPROC)func;
+
+    /* prepare data */
+    if (data == NULL)
+        return FALSE;
+    memset(data, 0, sizeof(*data));
+    data->requestedMonitor = index;
+
+    /* query information */
+    _EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data);
+
+    /* cleanup */
+    FreeLibrary(user32);
+    return TRUE;
+}
diff --git a/hw/xwin/winmonitors.h b/hw/xwin/winmonitors.h
new file mode 100644
index 0000000..180566b
--- /dev/null
+++ b/hw/xwin/winmonitors.h
@@ -0,0 +1,14 @@
+
+/* data returned for monitor information */
+struct GetMonitorInfoData {
+    int  requestedMonitor;
+    int  monitorNum;
+    Bool bUserSpecifiedMonitor;
+    Bool bMonitorSpecifiedExists;
+    int  monitorOffsetX;
+    int  monitorOffsetY;
+    int  monitorHeight;
+    int  monitorWidth;
+};
+
+Bool QueryMonitor(int index, struct GetMonitorInfoData *data);
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index c931696..fe9d7c2 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -35,6 +35,7 @@ from The Open Group.
 #include "win.h"
 #include "winconfig.h"
 #include "winmsg.h"
+#include "winmonitors.h"
 
 /*
  * References to external symbols
@@ -44,55 +45,6 @@ from The Open Group.
 extern Bool			g_fUnicodeClipboard;
 extern Bool			g_fClipboard;
 #endif
-/* globals required by callback function for monitor information */
-struct GetMonitorInfoData {
-    int  requestedMonitor;
-    int  monitorNum;
-    Bool bUserSpecifiedMonitor;
-    Bool bMonitorSpecifiedExists;
-    int  monitorOffsetX;
-    int  monitorOffsetY;
-    int  monitorHeight;
-    int  monitorWidth;
-};
-
-typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
-ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors;
-
-wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data);
-
-static Bool QueryMonitor(int index, struct GetMonitorInfoData *data)
-{
-    /* Load EnumDisplayMonitors from DLL */
-    HMODULE user32;
-    FARPROC func;
-    user32 = LoadLibrary("user32.dll");
-    if (user32 == NULL)
-    {
-        winW32Error(2, "Could not open user32.dll");
-        return FALSE;
-    }
-    func = GetProcAddress(user32, "EnumDisplayMonitors");
-    if (func == NULL)
-    {
-        winW32Error(2, "Could not resolve EnumDisplayMonitors: ");
-        return FALSE;
-    }
-    _EnumDisplayMonitors = (ENUMDISPLAYMONITORSPROC)func;
-    
-    /* prepare data */
-    if (data == NULL)
-        return FALSE;
-    memset(data, 0, sizeof(*data));
-    data->requestedMonitor = index;
-
-    /* query information */
-    _EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data);
-
-    /* cleanup */
-    FreeLibrary(user32);
-    return TRUE;
-}
 
 /*
  * Function prototypes
@@ -1220,24 +1172,3 @@ winLogVersionInfo (void)
   ErrorF ("%s\n\n", BUILDERSTRING);
   ErrorF ("Contact: %s\n", BUILDERADDR);
 }
-
-/*
- * getMonitorInfo - callback function used to return information from the enumeration of monitors attached
- */
-
-wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data) 
-{
-  struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data;
-  // only get data for monitor number specified in <data>
-  data->monitorNum++;
-  if (data->monitorNum == data->requestedMonitor) 
-  {
-	data->bMonitorSpecifiedExists = TRUE;
-	data->monitorOffsetX = rect->left;
-	data->monitorOffsetY = rect->top;
-	data->monitorHeight  = rect->bottom - rect->top;
-	data->monitorWidth   = rect->right  - rect->left;
-    return FALSE;
-  }
-  return TRUE;
-}
commit 73b02e964787ea9fb2d139dc781c9b2495ccb031
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Feb 12 12:29:30 2010 +0000

    Cygwin/X: Remove an attempt at detecting if WM_DISPLAYCHANGE affects the X screen
    
    Remove an attempt at the rather difficult optimization of detecting
    if WM_DISPLAYCHANGE affects any of the monitors which intersect the
    native window for the X screen.
    
    We'll always act as if it does, which it probably usually the case.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 8b7b699..ceb001c 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -481,11 +481,6 @@ typedef struct _winPrivScreenRec
   /* Handle to icons that must be freed */
   HICON			hiconNotifyIcon;
 
-  /* Last width, height, and depth of the Windows display */
-  DWORD			dwLastWindowsWidth;
-  DWORD			dwLastWindowsHeight;
-  DWORD			dwLastWindowsBitsPixel;
-
   /* Palette management */
   ColormapPtr		pcmapInstalled;
 
diff --git a/hw/xwin/windialogs.c b/hw/xwin/windialogs.c
index 679b3fa..c3a1497 100644
--- a/hw/xwin/windialogs.c
+++ b/hw/xwin/windialogs.c
@@ -482,11 +482,11 @@ winChangeDepthDlgProc (HWND hwndDialog, UINT message,
 
 #if CYGDEBUG
       winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, "
-	      "last bpp: %d\n",
+	      "current bpp: %d\n",
 	      s_pScreenInfo->dwBPP,
-	      s_pScreenPriv->dwLastWindowsBitsPixel);
+              GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL));
 #endif
-      
+
       winInitDialog( hwndDialog );
 
       return TRUE;
@@ -494,14 +494,13 @@ winChangeDepthDlgProc (HWND hwndDialog, UINT message,
     case WM_DISPLAYCHANGE:
 #if CYGDEBUG
       winDebug ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, "
-	      "last bpp: %d, new bpp: %d\n",
+	      "new bpp: %d\n",
 	      s_pScreenInfo->dwBPP,
-	      s_pScreenPriv->dwLastWindowsBitsPixel,
-	      wParam);
+              GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL));
 #endif
 
       /* Dismiss the dialog if the display returns to the original depth */
-      if (wParam == s_pScreenInfo->dwBPP)
+      if (GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL) == s_pScreenInfo->dwBPP)
 	{
 	  ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n");
 
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 46f6693..74ca115 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -175,13 +175,9 @@ winScreenInit (int index,
   /* Get a device context */
   hdc = GetDC (pScreenPriv->hwndScreen);
 
-  /* Store the initial height, width, and depth of the display */
   /* Are we using multiple monitors? */
   if (pScreenInfo->fMultipleMonitors)
     {
-      pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
-      pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
-
       /* 
        * In this case, some of the defaults set in
        * winInitializeScreenDefaults() are not correct ...
@@ -192,14 +188,6 @@ winScreenInit (int index,
 	  pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
 	}
     }
-  else
-    {
-      pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
-      pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
-    }
-
-  /* Save the original bits per pixel */
-  pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL);
 
   /* Release the device context */
   ReleaseDC (pScreenPriv->hwndScreen, hdc);
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 6d2270a..7983e9a 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -148,6 +148,13 @@ winWindowProc (HWND hwnd, UINT message,
       return 0;
 
     case WM_DISPLAYCHANGE:
+      /*
+        WM_DISPLAYCHANGE seems to be sent when the monitor layout or
+        any monitor's resolution or depth changes, but it's lParam and
+        wParam always indicate the resolution and bpp for the primary
+        monitor (so ignore that as we could be on any monitor...)
+       */
+
       /* We cannot handle a display mode change during initialization */
       if (s_pScreenInfo == NULL)
 	FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display "
@@ -167,22 +174,10 @@ winWindowProc (HWND hwnd, UINT message,
 #endif
 	      ))
 	{
-	  /* 
-	   * Store the new display dimensions and depth.
-	   * We do this here for future compatibility in case we
-	   * ever allow switching from fullscreen to windowed mode.
-	   */
-	  s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
-	  s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
-	  s_pScreenPriv->dwLastWindowsBitsPixel
-	    = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);	  
 	  break;
 	}
-      
-      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, "
-	      "new bpp: %d\n",
-	      (int) s_pScreenInfo->dwBPP,
-	      (int) s_pScreenPriv->dwLastWindowsBitsPixel,
+
+      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new bpp: %d\n",
 	      wParam);
 
       ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
@@ -216,7 +211,11 @@ winWindowProc (HWND hwnd, UINT message,
        * We can only display a message for a disruptive depth change,
        * we cannot do anything to correct the situation.
        */
-      if ((s_pScreenInfo->dwBPP != wParam)
+      /*
+        XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT)
+        has changed as well...
+      */
+      if ((s_pScreenInfo->dwBPP != GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL))
 	  && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
 	      || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
 #ifdef XWIN_PRIMARYFB
@@ -227,7 +226,7 @@ winWindowProc (HWND hwnd, UINT message,
 	  /* Cannot display the visual until the depth is restored */
 	  ErrorF ("winWindowProc - Disruptive change in depth\n");
 
-	  /* Display Exit dialog */
+	  /* Display depth change dialog */
 	  winDisplayDepthChangeDialog (s_pScreenPriv);
 
 	  /* Flag that we have an invalid screen depth */
@@ -241,14 +240,19 @@ winWindowProc (HWND hwnd, UINT message,
 	  /* Flag that we have a valid screen depth */
 	  s_pScreenPriv->fBadDepth = FALSE;
 	}
-      
+
+      /*
+        If we could cheaply check if this WM_DISPLAYCHANGE change
+        affects the monitor(s) which this X screen is displayed on
+        then we should do so here.  For the moment, assume it does.
+        (this is probably usually the case so that might be an
+        overoptimization)
+      */
+
       /*
-       * Check for a change in display dimensions.
        * We can simply recreate the same-sized primary surface when
        * the display dimensions change.
        */
-      if (s_pScreenPriv->dwLastWindowsWidth != LOWORD (lParam)
-	  || s_pScreenPriv->dwLastWindowsHeight != HIWORD (lParam))
 	{
 	  /*
 	   * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
@@ -261,7 +265,7 @@ winWindowProc (HWND hwnd, UINT message,
 #if CYGDEBUG
 	  winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n");
 #endif
-	  
+
 	  /* Release the old primary surface */
 	  (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
 
@@ -286,31 +290,7 @@ winWindowProc (HWND hwnd, UINT message,
 	    }
 #endif
 	}
-      else
-	{
-#if CYGDEBUG
-	  winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not "
-		  "change\n");
-#endif
-	}
 
-      /* Store the new display dimensions and depth */
-      if (s_pScreenInfo->fMultipleMonitors)
-	{
-	  s_pScreenPriv->dwLastWindowsWidth
-	    = GetSystemMetrics (SM_CXVIRTUALSCREEN);
-	  s_pScreenPriv->dwLastWindowsHeight
-	    = GetSystemMetrics (SM_CYVIRTUALSCREEN);
-	}
-      else
-	{
-	  s_pScreenPriv->dwLastWindowsWidth
-	    = GetSystemMetrics (SM_CXSCREEN);
-	  s_pScreenPriv->dwLastWindowsHeight
-	    = GetSystemMetrics (SM_CYSCREEN);
-	}
-      s_pScreenPriv->dwLastWindowsBitsPixel
-	= GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);
       break;
 
     case WM_SIZE:
commit a46146af5f6c2d96728c43f0df369ea00bcae017
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Apr 1 21:00:43 2010 +0100

    Cygwin/X: Rather than storing calculated physical display sizes, calculate them when needed
    
    (This stored calculation was wrong if -dpi came after -screen on the command
    line, anyhow)
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 3c706c4..8b7b699 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -395,8 +395,6 @@ typedef struct
   DWORD			dwUserHeight;
   DWORD			dwWidth;
   DWORD			dwHeight;
-  DWORD			dwWidth_mm;
-  DWORD			dwHeight_mm;
   DWORD			dwPaddedWidth;
 
   /* Did the user specify a screen position? */
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 1ce5c2d..c931696 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -174,8 +174,6 @@ winInitializeScreenDefaults(void)
   defaultScreenInfo.fScrollbars = FALSE;
   defaultScreenInfo.fNoTrayIcon = FALSE;
   defaultScreenInfo.iE3BTimeout = WIN_E3B_OFF;
-  defaultScreenInfo.dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) * 25.4;
-  defaultScreenInfo.dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) * 25.4;
   defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
   defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL;
   defaultScreenInfo.fIgnoreInput = FALSE;
@@ -500,17 +498,6 @@ ddxProcessArgument (int argc, char *argv[], int i)
 	  g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
 	}
 
-      /* Calculate the screen width and height in millimeters */
-      if (g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth)
-	{
-	  g_ScreenInfo[nScreenNum].dwWidth_mm
-	    = (g_ScreenInfo[nScreenNum].dwWidth
-	       / monitorResolution) * 25.4;
-	  g_ScreenInfo[nScreenNum].dwHeight_mm
-	    = (g_ScreenInfo[nScreenNum].dwHeight
-	       / monitorResolution) * 25.4;
-	}
-
       /* Flag that this screen was explicity specified by the user */
       g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE;
 
diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c
index 7b5b135..fd1d97e 100644
--- a/hw/xwin/winrandr.c
+++ b/hw/xwin/winrandr.c
@@ -86,8 +86,8 @@ winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
   pSize = RRRegisterSize (pScreen,
 			  pScreenInfo->dwWidth,
 			  pScreenInfo->dwHeight,
-			  pScreenInfo->dwWidth_mm,
-			  pScreenInfo->dwHeight_mm);
+                          (pScreenInfo->dwWidth / monitorResolution) * 25.4,
+                          (pScreenInfo->dwHeight / monitorResolution) * 25.4);
 
   /* Tell RandR what the current config is */
   RRSetCurrentConfig (pScreen,
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index bf6181a..46f6693 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -190,10 +190,6 @@ winScreenInit (int index,
 	{
 	  pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
 	  pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
-	  pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth /
-				     WIN_DEFAULT_DPI) * 25.4;
-	  pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight /
-				      WIN_DEFAULT_DPI) * 25.4;
 	}
     }
   else
commit df518001271dbc0c49935350b755f0c0562cdb92
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Oct 13 14:47:33 2009 +0100

    Cygwin/X: Refactor framebuffer allocation/release in drawing engines
    
    Refactor the drawing engines so we can explicitly allocate and release the framebuffer for a screen
    
    Move the setting of dwPaddedWidth into the DDNL engine, so it is updated when the framebuffer changes size
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 6ac48c5..3c706c4 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -276,8 +276,12 @@ static Atom func (void) {					\
 
 typedef Bool (*winAllocateFBProcPtr)(ScreenPtr);
 
+typedef void (*winFreeFBProcPtr)(ScreenPtr);
+
 typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr);
 
+typedef Bool (*winInitScreenProcPtr)(ScreenPtr);
+
 typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr);
 
 typedef Bool (*winInitVisualsProcPtr)(ScreenPtr);
@@ -549,7 +553,9 @@ typedef struct _winPrivScreenRec
   
   /* Engine specific functions */
   winAllocateFBProcPtr			pwinAllocateFB;
+  winFreeFBProcPtr			pwinFreeFB;
   winShadowUpdateProcPtr		pwinShadowUpdate;
+  winInitScreenProcPtr			pwinInitScreen;
   winCloseScreenProcPtr			pwinCloseScreen;
   winInitVisualsProcPtr			pwinInitVisuals;
   winAdjustVideoModeProcPtr		pwinAdjustVideoMode;
diff --git a/hw/xwin/winnativegdi.c b/hw/xwin/winnativegdi.c
index b8d2d35..b0a551a 100644
--- a/hw/xwin/winnativegdi.c
+++ b/hw/xwin/winnativegdi.c
@@ -92,6 +92,18 @@ winAllocateFBNativeGDI (ScreenPtr pScreen)
   return TRUE;
 }
 
+static void
+winFreeFBNativeGDI (ScreenPtr pScreen)
+{
+  FatalError ("winFreeFBNativeGDI\n");
+}
+
+
+static Bool
+winInitScreenNativeGDI(ScreenPtr pScreen)
+{
+  FatalError ("winInitScreenNativeGDI\n");
+}
 
 /*
  * We wrap whatever CloseScreen procedure was specified by fb;
@@ -506,7 +518,9 @@ winSetEngineFunctionsNativeGDI (ScreenPtr pScreen)
   
   /* Set our pointers */
   pScreenPriv->pwinAllocateFB = winAllocateFBNativeGDI;
+  pScreenPriv->pwinFreeFB = winFreeFBNativeGDI;
   pScreenPriv->pwinShadowUpdate = winShadowUpdateNativeGDI;
+  pScreenPriv->pwinInitScreen = winInitScreenNativeGDI;
   pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI;
   pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI;
   pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI;
diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c
index 8251a37..4145717 100644
--- a/hw/xwin/winpfbdd.c
+++ b/hw/xwin/winpfbdd.c
@@ -233,6 +233,45 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen)
   return TRUE;
 }
 
+static void
+winFreeFBPrimaryDD (ScreenPtr pScreen)
+{
+  winScreenPriv(pScreen);
+  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+  /* Free the offscreen surface, if there is one */
+  if (pScreenPriv->pddsOffscreen)
+    {
+      IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL);
+      IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen);
+      pScreenPriv->pddsOffscreen = NULL;
+    }
+
+  /* Release the primary surface, if there is one */
+  if (pScreenPriv->pddsPrimary)
+    {
+      IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL);
+      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
+      pScreenPriv->pddsPrimary = NULL;
+    }
+
+  /* Free the DirectDraw object, if there is one */
+  if (pScreenPriv->pdd)
+    {
+      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd);
+      IDirectDraw2_Release (pScreenPriv->pdd);
+      pScreenPriv->pdd = NULL;
+    }
+
+  /* Invalidate the ScreenInfo's fb pointer */
+  pScreenInfo->pfb = NULL;
+}
+
+static Bool
+winInitScreenPrimaryDD(ScreenPtr pScreen)
+{
+  return winAllocateFBPrimaryDD(pScreen);
+}
 
 /*
  * Call the wrapped CloseScreen function.
@@ -260,29 +299,7 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen)
   /* Delete the window property */
   RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
 
-  /* Free the offscreen surface, if there is one */
-  if (pScreenPriv->pddsOffscreen)
-    {
-      IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL);
-      IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen);
-      pScreenPriv->pddsOffscreen = NULL;
-    }
-
-  /* Release the primary surface, if there is one */
-  if (pScreenPriv->pddsPrimary)
-    {
-      IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL);
-      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
-      pScreenPriv->pddsPrimary = NULL;
-    }
-
-  /* Free the DirectDraw object, if there is one */
-  if (pScreenPriv->pdd)
-    {
-      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd);
-      IDirectDraw2_Release (pScreenPriv->pdd);
-      pScreenPriv->pdd = NULL;
-    }
+  winFreeFBPrimaryDD(pScreen);
 
   /* Delete tray icon, if we have one */
   if (!pScreenInfo->fNoTrayIcon)
@@ -305,9 +322,6 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen)
   /* Kill our screeninfo's pointer to the screen */
   pScreenInfo->pScreen = NULL;
 
-  /* Invalidate the ScreenInfo's fb pointer */
-  pScreenInfo->pfb = NULL;
-
   /* Free the screen privates for this screen */
   free ((pointer) pScreenPriv);
 
@@ -653,8 +667,9 @@ winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen)
   
   /* Set our pointers */
   pScreenPriv->pwinAllocateFB = winAllocateFBPrimaryDD;
-  pScreenPriv->pwinShadowUpdate
-    = (winShadowUpdateProcPtr) (void (*)(void))NoopDDA;
+  pScreenPriv->pwinFreeFB = winFreeFBPrimaryDD;
+  pScreenPriv->pwinShadowUpdate = (winShadowUpdateProcPtr) (void (*)(void))NoopDDA;
+  pScreenPriv->pwinInitScreen = winInitScreenPrimaryDD;
   pScreenPriv->pwinCloseScreen = winCloseScreenPrimaryDD;
   pScreenPriv->pwinInitVisuals = winInitVisualsPrimaryDD;
   pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModePrimaryDD;
@@ -663,8 +678,7 @@ winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen)
   else
     pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
   pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
-  pScreenPriv->pwinBltExposedRegions
-    = (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA;
+  pScreenPriv->pwinBltExposedRegions = (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA;
   pScreenPriv->pwinActivateApp = winActivateAppPrimaryDD;
   pScreenPriv->pwinRedrawScreen = NULL;
   pScreenPriv->pwinRealizeInstalledPalette = NULL;
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 21036f4..bf6181a 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -210,10 +210,6 @@ winScreenInit (int index,
     
   /* Clear the visuals list */
   miClearVisualTypes ();
-  
-  /* Set the padded screen width */
-  pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
-					      pScreenInfo->dwBPP);
 
   /* Call the engine dependent screen initialization procedure */
   if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv)))
@@ -279,7 +275,7 @@ winFinishScreenInitFB (int index,
 #endif
 
   /* Create framebuffer */
-  if (!(*pScreenPriv->pwinAllocateFB) (pScreen))
+  if (!(*pScreenPriv->pwinInitScreen) (pScreen))
     {
       ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n");
       return FALSE;
diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index 4e284b9..45d1548 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -239,9 +239,6 @@ winAllocateFBShadowDD (ScreenPtr pScreen)
   winDebug ("winAllocateFBShadowDD - Created a clipper\n");
 #endif
 
-  /* Get a device context for the screen  */
-  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
-
   /* Attach the clipper to our display window */
   ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
 				       0,
@@ -503,6 +500,57 @@ winAllocateFBShadowDD (ScreenPtr pScreen)
   return TRUE;
 }
 
+static void
+winFreeFBShadowDD (ScreenPtr pScreen)
+{
+  winScreenPriv(pScreen);
+  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+  /* Free the shadow surface, if there is one */
+  if (pScreenPriv->pddsShadow)
+    {
+      IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
+      IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
+      pScreenPriv->pddsShadow = NULL;
+    }
+
+  /* Detach the clipper from the primary surface and release the clipper. */
+  if (pScreenPriv->pddcPrimary)
+    {
+      /* Detach the clipper */
+      IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
+				      NULL);
+
+      /* Release the clipper object */
+      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
+      pScreenPriv->pddcPrimary = NULL;
+    }
+
+  /* Release the primary surface, if there is one */
+  if (pScreenPriv->pddsPrimary)
+    {
+      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
+      pScreenPriv->pddsPrimary = NULL;
+    }
+
+  /* Free the DirectDraw2 object, if there is one */
+  if (pScreenPriv->pdd2)
+    {
+      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
+      IDirectDraw2_Release (pScreenPriv->pdd2);
+      pScreenPriv->pdd2 = NULL;
+    }
+
+  /* Free the DirectDraw object, if there is one */
+  if (pScreenPriv->pdd)
+    {
+      IDirectDraw_Release (pScreenPriv->pdd);
+      pScreenPriv->pdd = NULL;
+    }
+
+  /* Invalidate the ScreenInfo's fb pointer */
+  pScreenInfo->pfb = NULL;
+}
 
 /*
  * Transfer the damaged regions of the shadow framebuffer to the display.
@@ -666,6 +714,16 @@ winShadowUpdateDD (ScreenPtr pScreen,
     }
 }
 
+static Bool
+winInitScreenShadowDD (ScreenPtr pScreen)
+{
+  winScreenPriv(pScreen);
+
+  /* Get a device context for the screen  */
+  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
+
+  return winAllocateFBShadowDD(pScreen);
+}
 
 /*
  * Call the wrapped CloseScreen function.
@@ -692,58 +750,18 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
   WIN_UNWRAP(CloseScreen);
   fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
 
+  winFreeFBShadowDD(pScreen);
+
   /* Free the screen DC */
   ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
 
   /* Delete the window property */
   RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
 
-  /* Free the shadow surface, if there is one */
-  if (pScreenPriv->pddsShadow)
-    {
-      IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
-      IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
-      pScreenPriv->pddsShadow = NULL;
-    }
-
-  /* Detach the clipper from the primary surface and release the clipper. */
-  if (pScreenPriv->pddcPrimary)
-    {
-      /* Detach the clipper */
-      IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
-				      NULL);
-
-      /* Release the clipper object */
-      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
-      pScreenPriv->pddcPrimary = NULL;
-    }
-
-  /* Release the primary surface, if there is one */
-  if (pScreenPriv->pddsPrimary)
-    {
-      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
-      pScreenPriv->pddsPrimary = NULL;
-    }
-
-  /* Free the DirectDraw2 object, if there is one */
-  if (pScreenPriv->pdd2)
-    {
-      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
-      IDirectDraw2_Release (pScreenPriv->pdd2);
-      pScreenPriv->pdd2 = NULL;
-    }
-
-  /* Free the DirectDraw object, if there is one */
-  if (pScreenPriv->pdd)
-    {
-      IDirectDraw_Release (pScreenPriv->pdd);
-      pScreenPriv->pdd = NULL;
-    }
-
   /* Delete tray icon, if we have one */
   if (!pScreenInfo->fNoTrayIcon)
     winDeleteNotifyIcon (pScreenPriv);
-  
+
   /* Free the exit confirmation dialog box, if it exists */
   if (g_hDlgExit != NULL)
     {
@@ -766,9 +784,6 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
   /* Kill our screeninfo's pointer to the screen */
   pScreenInfo->pScreen = NULL;
 
-  /* Invalidate the ScreenInfo's fb pointer */
-  pScreenInfo->pfb = NULL;
-
   /* Free the screen privates for this screen */
   free ((pointer) pScreenPriv);
 
@@ -1370,7 +1385,9 @@ winSetEngineFunctionsShadowDD (ScreenPtr pScreen)
   
   /* Set our pointers */
   pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD;
+  pScreenPriv->pwinFreeFB = winFreeFBShadowDD;
   pScreenPriv->pwinShadowUpdate = winShadowUpdateDD;
+  pScreenPriv->pwinInitScreen = winInitScreenShadowDD;
   pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD;
   pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD;
   pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD;
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index 82fe4be..dd2e9b5 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -237,6 +237,10 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
 	  pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth);
 #endif
 
+  /* Set the padded screen width */
+  pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
+					      pScreenInfo->dwBPP);
+
   /* Allocate memory for our shadow surface */
   lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
   if (lpSurface == NULL)
@@ -266,9 +270,6 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
   winDebug ("winAllocateFBShadowDDNL - Created a clipper\n");
 #endif
 
-  /* Get a device context for the screen  */
-  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
-
   /* Attach the clipper to our display window */
   ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
 				       0,
@@ -530,6 +531,58 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
   return TRUE;
 }
 
+static void
+winFreeFBShadowDDNL(ScreenPtr pScreen)
+{
+  winScreenPriv(pScreen);
+  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+  /* Free the shadow surface, if there is one */
+  if (pScreenPriv->pddsShadow4)
+    {
+      IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4);
+      free (pScreenInfo->pfb);
+      pScreenInfo->pfb = NULL;
+      pScreenPriv->pddsShadow4 = NULL;
+    }
+
+  /* Detach the clipper from the primary surface and release the clipper. */
+  if (pScreenPriv->pddcPrimary)
+    {
+      /* Detach the clipper */
+      IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
+				      NULL);
+
+      /* Release the clipper object */
+      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
+      pScreenPriv->pddcPrimary = NULL;
+    }
+
+  /* Release the primary surface, if there is one */
+  if (pScreenPriv->pddsPrimary4)
+    {
+      IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
+      pScreenPriv->pddsPrimary4 = NULL;
+    }
+
+  /* Free the DirectDraw4 object, if there is one */
+  if (pScreenPriv->pdd4)
+    {
+      IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4);
+      IDirectDraw4_Release (pScreenPriv->pdd4);
+      pScreenPriv->pdd4 = NULL;
+    }
+
+  /* Free the DirectDraw object, if there is one */
+  if (pScreenPriv->pdd)
+    {
+      IDirectDraw_Release (pScreenPriv->pdd);
+      pScreenPriv->pdd = NULL;
+    }
+
+  /* Invalidate the ScreenInfo's fb pointer */
+  pScreenInfo->pfb = NULL;
+}
 
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
 /*
@@ -720,6 +773,16 @@ winShadowUpdateDDNL (ScreenPtr pScreen,
     }
 }
 
+static Bool
+winInitScreenShadowDDNL(ScreenPtr pScreen)
+{
+  winScreenPriv(pScreen);
+
+  /* Get a device context for the screen  */
+  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
+
+  return winAllocateFBShadowDDNL(pScreen);
+}
 
 /*
  * Call the wrapped CloseScreen function.
@@ -746,55 +809,14 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)
   WIN_UNWRAP(CloseScreen);
   fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
 
+  winFreeFBShadowDDNL(pScreen);
+
   /* Free the screen DC */
   ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
 
   /* Delete the window property */
   RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
 
-  /* Free the shadow surface, if there is one */
-  if (pScreenPriv->pddsShadow4)
-    {
-      IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4);
-      free (pScreenInfo->pfb);
-      pScreenInfo->pfb = NULL;
-      pScreenPriv->pddsShadow4 = NULL;
-    }
-
-  /* Detach the clipper from the primary surface and release the clipper. */
-  if (pScreenPriv->pddcPrimary)
-    {
-      /* Detach the clipper */
-      IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
-				      NULL);
-
-      /* Release the clipper object */
-      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
-      pScreenPriv->pddcPrimary = NULL;
-    }
-
-  /* Release the primary surface, if there is one */
-  if (pScreenPriv->pddsPrimary4)
-    {
-      IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
-      pScreenPriv->pddsPrimary4 = NULL;
-    }
-
-  /* Free the DirectDraw4 object, if there is one */
-  if (pScreenPriv->pdd4)
-    {
-      IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4);
-      IDirectDraw4_Release (pScreenPriv->pdd4);
-      pScreenPriv->pdd4 = NULL;
-    }
-
-  /* Free the DirectDraw object, if there is one */
-  if (pScreenPriv->pdd)
-    {
-      IDirectDraw_Release (pScreenPriv->pdd);
-      pScreenPriv->pdd = NULL;
-    }
-
   /* Delete tray icon, if we have one */
   if (!pScreenInfo->fNoTrayIcon)
     winDeleteNotifyIcon (pScreenPriv);
@@ -821,9 +843,6 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)
   /* Kill our screeninfo's pointer to the screen */
   pScreenInfo->pScreen = NULL;
 
-  /* Invalidate the ScreenInfo's fb pointer */
-  pScreenInfo->pfb = NULL;
-
   /* Free the screen privates for this screen */
   free ((pointer) pScreenPriv);
 
@@ -1382,7 +1401,9 @@ winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen)
   
   /* Set our pointers */
   pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL;
+  pScreenPriv->pwinFreeFB = winFreeFBShadowDDNL;
   pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL;
+  pScreenPriv->pwinInitScreen = winInitScreenShadowDDNL;
   pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL;
   pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL;
   pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL;
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index 4971851..a165d80 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -342,10 +342,6 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
   DIBSECTION		dibsection;
   Bool			fReturn = TRUE;
 
-  /* Get device contexts for the screen and shadow bitmap */
-  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
-  pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
-
   /* Allocate bitmap info header */
   pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
 				      + 256 * sizeof (RGBQUAD));
@@ -477,6 +473,18 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
   return fReturn;
 }
 
+static void
+winFreeFBShadowGDI (ScreenPtr pScreen)
+{
+  winScreenPriv(pScreen);
+  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+  /* Free the shadow bitmap */
+  DeleteObject (pScreenPriv->hbmpShadow);
+
+  /* Invalidate the ScreenInfo's fb pointer */
+  pScreenInfo->pfb = NULL;
+}
 
 /*
  * Blit the damaged regions of the shadow fb to the screen
@@ -602,6 +610,18 @@ winShadowUpdateGDI (ScreenPtr pScreen,
 }
 
 
+static Bool
+winInitScreenShadowGDI (ScreenPtr pScreen)
+{
+  winScreenPriv(pScreen);
+
+  /* Get device contexts for the screen and shadow bitmap */
+  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
+  pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
+
+  return winAllocateFBShadowGDI(pScreen);
+}
+
 /* See Porting Layer Definition - p. 33 */
 /*
  * We wrap whatever CloseScreen procedure was specified by fb;
@@ -632,9 +652,8 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
 
   /* Free the shadow DC; which allows the bitmap to be freed */
   DeleteDC (pScreenPriv->hdcShadow);
-  
-  /* Free the shadow bitmap */
-  DeleteObject (pScreenPriv->hbmpShadow);
+
+  winFreeFBShadowGDI(pScreen);
 
   /* Free the screen DC */
   ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
@@ -665,9 +684,6 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
   /* Invalidate our screeninfo's pointer to the screen */
   pScreenInfo->pScreen = NULL;
 
-  /* Invalidate the ScreenInfo's fb pointer */
-  pScreenInfo->pfb = NULL;
-
   /* Free the screen privates for this screen */
   free ((pointer) pScreenPriv);
 
@@ -1235,7 +1251,9 @@ winSetEngineFunctionsShadowGDI (ScreenPtr pScreen)
   
   /* Set our pointers */
   pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
+  pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
   pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
+  pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
   pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
   pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
   pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
commit 708d0b9781c6f3f0c0ae7052f45223b1c2524809
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Oct 13 14:48:17 2009 +0100

    Cygwin/X: Enable building of nativegdi and primaryfb engines to avoid further rusting
    
    Some trivial build fixes required
    
    Also fill out all function pointers for primaryfb engine
    
    Also tidy up the man page section describing drawing engines.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/configure.ac b/configure.ac
index 45286ea..120321e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1903,8 +1903,8 @@ AM_CONDITIONAL(XWIN_MULTIWINDOW, [test "x$XWIN" = xyes])
 AM_CONDITIONAL(XWIN_MULTIWINDOWEXTWM, [test "x$XWIN" = xyes && test "x$WINDOWSWM" = xyes])
 AM_CONDITIONAL(XWIN_CLIPBOARD, [test "x$XWIN" = xyes])
 AM_CONDITIONAL(XWIN_GLX_WINDOWS, [test "x$XWIN" = xyes && false])
-AM_CONDITIONAL(XWIN_NATIVEGDI, [test "x$XWIN" = xyes && false])
-AM_CONDITIONAL(XWIN_PRIMARYFB, [test "x$XWIN" = xyes && false])
+AM_CONDITIONAL(XWIN_NATIVEGDI, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_PRIMARYFB, [test "x$XWIN" = xyes])
 AM_CONDITIONAL(XWIN_RANDR, [test "x$XWIN" = xyes])
 AM_CONDITIONAL(XWIN_XV, [test "x$XWIN" = xyes && test "x$XV" = xyes])
 
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 38a658d..bf04cf1 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -755,6 +755,9 @@ winUseMsg (void)
 	  "\t\t1 - Shadow GDI\n"
 	  "\t\t2 - Shadow DirectDraw\n"
 	  "\t\t4 - Shadow DirectDraw4 Non-Locking\n"
+#ifdef XWIN_PRIMARYFB
+	  "\t\t8 - Primary DirectDraw - obsolete\n"
+#endif
 #ifdef XWIN_NATIVEGDI
 	  "\t\t16 - Native GDI - experimental\n"
 #endif
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 51268f6..76abdca 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -190,15 +190,27 @@ respectively).
 .TP 8
 .B "\-engine \fIengine_type_id\fP"
 This option, which is intended for Cygwin/X developers,
-overrides the server's automatically selected engine type.  This
-parameter will be ignored if the specified engine type is not
-supported on the current system.  The supported engine type ids are 1
-- Shadow GDI, 2 - Shadow DirectDraw, and 4 - Shadow DirectDraw Non-Locking.
-Additionally, there are engines with type ids
-8 - Primary DirectDraw (obsolete) and 16 - Native GDI (experimental and barely functional).
-Default behavior is to determine the engine with optimum performance that
+overrides the server's automatically selected drawing engine type.  This
+parameter will be ignored if the specified drawing engine type is not
+supported on the current system.
+
+Default behavior is to select the drawing engine with optimum performance that
 supports the specified depth and window configuration.
 
+The engine type ids are:
+.RS
+.IP 1 4
+Shadow GDI
+.IP 2 4
+Shadow DirectDraw
+.IP 4 4
+Shadow DirectDraw Non-Locking
+.IP 8 4
+Primary DirectDraw (unsupported, obsolete)
+.IP 16 4
+Native GDI (unsupported, experimental and barely functional)
+.RE
+
 .SH FULLSCREEN OPTIONS
 .TP 8
 .B "\-depth \fIdepth\fP"
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 4430781..6ac48c5 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -315,6 +315,12 @@ typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin);
 
 typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr);
 
+#ifdef XWIN_NATIVEGDI
+/* Typedefs for native GDI wrappers */
+typedef Bool (*RealizeFontPtr) (ScreenPtr pScreen, FontPtr pFont);
+typedef Bool (*UnrealizeFontPtr)(ScreenPtr pScreen, FontPtr pFont);
+#endif
+
 
 /*
  * GC (graphics context) privates
@@ -588,6 +594,12 @@ typedef struct _winPrivScreenRec
   SetShapeProcPtr			SetShape;
 
   winCursorRec                          cursor;
+
+#ifdef XWIN_NATIVEGDI
+  RealizeFontPtr                        RealizeFont;
+  UnrealizeFontPtr                      UnrealizeFont;
+#endif
+
 } winPrivScreenRec;
 
 
diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c
index 7859c6b..8251a37 100644
--- a/hw/xwin/winpfbdd.c
+++ b/hw/xwin/winpfbdd.c
@@ -666,7 +666,15 @@ winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen)
   pScreenPriv->pwinBltExposedRegions
     = (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA;
   pScreenPriv->pwinActivateApp = winActivateAppPrimaryDD;
+  pScreenPriv->pwinRedrawScreen = NULL;
+  pScreenPriv->pwinRealizeInstalledPalette = NULL;
+  pScreenPriv->pwinInstallColormap = NULL;
+  pScreenPriv->pwinStoreColors = NULL;
+  pScreenPriv->pwinCreateColormap = NULL;
+  pScreenPriv->pwinDestroyColormap = NULL;
   pScreenPriv->pwinHotKeyAltTab = winHotKeyAltTabPrimaryDD;
+  pScreenPriv->pwinCreatePrimarySurface = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
+  pScreenPriv->pwinReleasePrimarySurface = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
 #ifdef XWIN_MULTIWINDOW
   pScreenPriv->pwinFinishCreateWindowsWindow =
     (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA;
diff --git a/hw/xwin/winwindow.c b/hw/xwin/winwindow.c
index 783760f..7975d71 100644
--- a/hw/xwin/winwindow.c
+++ b/hw/xwin/winwindow.c
@@ -58,6 +58,7 @@ winReshapeRootless (WindowPtr pWin);
 Bool
 winCreateWindowNativeGDI (WindowPtr pWin)
 {
+  Bool			fResult = TRUE;
   ScreenPtr		pScreen = pWin->drawable.pScreen;
   winWindowPriv(pWin);
   winScreenPriv(pScreen);


More information about the xorg-commit mailing list