From 708d0b9781c6f3f0c0ae7052f45223b1c2524809 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 13 Oct 2009 14:48:17 +0100 Subject: [PATCH 01/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- configure.ac | 4 ++-- hw/xwin/InitOutput.c | 3 +++ hw/xwin/man/XWin.man | 26 +++++++++++++++++++------- hw/xwin/win.h | 12 ++++++++++++ hw/xwin/winpfbdd.c | 8 ++++++++ hw/xwin/winwindow.c | 1 + 6 files changed, 45 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 45286eaf4..120321e7c 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 38a658d77..bf04cf13f 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 51268f69a..76abdca09 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 44307813c..6ac48c5e9 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 7859c6b19..8251a3722 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 783760f4b..7975d71a9 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); From df518001271dbc0c49935350b755f0c0562cdb92 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 13 Oct 2009 14:47:33 +0100 Subject: [PATCH 02/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/win.h | 6 +++ hw/xwin/winnativegdi.c | 14 +++++ hw/xwin/winpfbdd.c | 74 ++++++++++++++----------- hw/xwin/winscrinit.c | 6 +-- hw/xwin/winshaddd.c | 115 ++++++++++++++++++++++----------------- hw/xwin/winshadddnl.c | 119 ++++++++++++++++++++++++----------------- hw/xwin/winshadgdi.c | 38 +++++++++---- 7 files changed, 229 insertions(+), 143 deletions(-) diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 6ac48c5e9..3c706c409 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 b8d2d351b..b0a551a5c 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 8251a3722..41457170a 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 21036f46c..bf6181add 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 4e284b9c1..45d15482c 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 82fe4be36..dd2e9b57a 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 4971851e5..a165d801e 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; From a46146af5f6c2d96728c43f0df369ea00bcae017 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Thu, 1 Apr 2010 21:00:43 +0100 Subject: [PATCH 03/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/win.h | 2 -- hw/xwin/winprocarg.c | 13 ------------- hw/xwin/winrandr.c | 4 ++-- hw/xwin/winscrinit.c | 4 ---- 4 files changed, 2 insertions(+), 21 deletions(-) diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 3c706c409..8b7b69990 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 1ce5c2dca..c93169676 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 7b5b1359c..fd1d97ea4 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 bf6181add..46f6693bd 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 From 73b02e964787ea9fb2d139dc781c9b2495ccb031 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Fri, 12 Feb 2010 12:29:30 +0000 Subject: [PATCH 04/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/win.h | 5 ---- hw/xwin/windialogs.c | 13 ++++---- hw/xwin/winscrinit.c | 12 -------- hw/xwin/winwndproc.c | 70 ++++++++++++++++---------------------------- 4 files changed, 31 insertions(+), 69 deletions(-) diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 8b7b69990..ceb001cd6 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 679b3fab5..c3a149762 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 46f6693bd..74ca11557 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 6d2270a20..7983e9aa4 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); @@ -284,33 +288,9 @@ winWindowProc (HWND hwnd, UINT message, { RRSetScreenConfig (); } -#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: From 46c57788539d8a5f0246528b4f88ad4ed6d867d1 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 23 Feb 2010 15:44:36 +0000 Subject: [PATCH 05/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/Makefile.am | 1 + hw/xwin/winmonitors.c | 92 +++++++++++++++++++++++++++++++++++++++++++ hw/xwin/winmonitors.h | 14 +++++++ hw/xwin/winprocarg.c | 71 +-------------------------------- 4 files changed, 108 insertions(+), 70 deletions(-) create mode 100644 hw/xwin/winmonitors.c create mode 100644 hw/xwin/winmonitors.h diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am index f6a75df2c..ce2edb2e6 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 000000000..63af803d0 --- /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->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 000000000..180566b00 --- /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 c93169676..fe9d7c28d 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->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; -} From 873abef315f5d947b864428891381bff539c5869 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 30 Mar 2010 20:07:19 +0100 Subject: [PATCH 06/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/InitOutput.c | 10 ++++----- hw/xwin/man/XWin.man | 50 ++++++++++++++++++++++++++++++++++++++---- hw/xwin/win.h | 11 +++++++++- hw/xwin/wincreatewnd.c | 48 ++++++++++++++++++++-------------------- hw/xwin/winprocarg.c | 43 ++++++++++++++++++++++++++++++++++-- hw/xwin/winvalargs.c | 4 ++-- hw/xwin/winwndproc.c | 4 ++-- 7 files changed, 130 insertions(+), 40 deletions(-) diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c index bf04cf13f..7faed0170 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@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 76abdca09..39cdf5ef0 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 ceb001cd6..0df1d27fc 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -378,6 +378,15 @@ typedef struct { miPointerSpriteFuncPtr spriteFuncs; } 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 0c342e1ae..755373965 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 fe9d7c28d..e4c52ef94 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 357d3d70a..6680aba67 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 7983e9aa4..27fc840b5 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 From 85c497a8b6c488ef9ea2c6d7b49e6f9b992fb4a2 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 30 Mar 2010 20:48:10 +0100 Subject: [PATCH 07/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/win.h | 12 ++ hw/xwin/winrandr.c | 306 ++++++++++++++++++++++++++++++++++--------- hw/xwin/winscrinit.c | 4 - 3 files changed, 256 insertions(+), 66 deletions(-) diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 0df1d27fc..bbc0f2fbf 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -1471,6 +1471,18 @@ winInitCursor (ScreenPtr pScreen); 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 fd1d97ea4..248404800 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,35 +21,24 @@ *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 #endif #include "win.h" +#include "mivalidate.h" // for union _Validate used by windowstr.h - -/* - * Local prototypes - */ - -static Bool -winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations); - -static Bool -winRandRSetConfig (ScreenPtr pScreen, - Rotation rotateKind, - int rate, - RRScreenSizePtr pSize); - -Bool -winRandRInit (ScreenPtr pScreen); +#ifndef RANDR_12_INTERFACE +#error X server must have RandR 1.2 interface +#endif /* @@ -58,63 +48,253 @@ winRandRInit (ScreenPtr pScreen); static Bool winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations) { - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - int n; - Rotation rotateKind; - RRScreenSizePtr pSize; - winDebug ("winRandRGetInfo ()\n"); - /* Don't support rotations, yet */ + /* Don't support rotations */ *pRotations = RR_Rotate_0; - /* 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; - - /* Only one allowed rotation for now */ - rotateKind = RR_Rotate_0; - /* - * 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); + 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); - /* Tell RandR what the current config is */ - RRSetCurrentConfig (pScreen, - rotateKind, - 0, /* refresh rate, not needed */ - pSize); - return TRUE; } /* - * Respond to resize/rotate request from either X Server or X client app - */ + Copied from the xfree86 DDX -static Bool -winRandRSetConfig (ScreenPtr pScreen, - Rotation rotateKind, - int rate, - RRScreenSizePtr pSize) + Why can't this be in DIX? + Does union _Validate vary depending on DDX?? + */ +static void +xf86SetRootClip (ScreenPtr pScreen, Bool enable) { - winDebug ("winRandRSetConfig ()\n"); + WindowPtr pWin = pScreen->root; + WindowPtr pChild; + Bool WasViewable = (Bool)(pWin->viewable); + Bool anyMarked = FALSE; + WindowPtr pLayerWin; + BoxRec box; + + 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; + WindowPtr pRoot = pScreen->root; + + // Prevent screen updates while we change things around + xf86SetRootClip(pScreen, FALSE); + + /* Update the screen size as requested */ + pScreenInfo->dwWidth = width; + pScreenInfo->dwHeight = height; + + /* Reallocate the framebuffer used by the drawing engine */ + (*pScreenPriv->pwinFreeFB)(pScreen); + if (!(*pScreenPriv->pwinAllocateFB)(pScreen)) + { + ErrorF ("winDoRandRScreenSetSize - Could not reallocate framebuffer\n"); + } + + pScreen->width = width; + pScreen->height = height; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + + /* 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 request + */ +static +Bool +winRandRScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD16 pixWidth, + CARD16 pixHeight, + CARD32 mmWidth, + CARD32 mmHeight) +{ + 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 74ca11557..e0686e2c4 100644 --- a/hw/xwin/winscrinit.c +++ b/hw/xwin/winscrinit.c @@ -69,10 +69,6 @@ winMWExtWMProcs = { * Prototypes */ -Bool -winRandRInit (ScreenPtr pScreen); - - /* * Local functions */ From bbc511e80b2a9365f6a1528bc1595772f83be654 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 15 Feb 2010 13:42:04 +0000 Subject: [PATCH 08/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winwndproc.c | 48 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index 27fc840b5..04a3a6b86 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; From 33106e1e807a828208b306512e78c5e3e93960d3 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 30 Mar 2010 19:49:41 +0100 Subject: [PATCH 09/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/man/XWin.man | 9 +-- hw/xwin/win.h | 2 + hw/xwin/winprocarg.c | 4 ++ hw/xwin/winwndproc.c | 128 ++++++++++++++++++++++++++++++++----------- 4 files changed, 104 insertions(+), 39 deletions(-) diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man index 39cdf5ef0..e7933c9c8 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 bbc0f2fbf..2eea345e5 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 e4c52ef94..ddfe1f5b7 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 04a3a6b86..80f5e1a7b 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) - { - RRSetScreenConfig (); - } + /* + 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 + )) + { + 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); + } + } + 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; From 5390b494672393506466d8afdb9b146b0e585cc0 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 10 Aug 2010 13:16:13 +0100 Subject: [PATCH 10/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winscrinit.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c index e0686e2c4..f505dddca 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 */ From 981ad1f364cf4fe8008c0f3592eb0f73dd14a118 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 10 Aug 2010 16:24:57 +0100 Subject: [PATCH 11/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winvalargs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xwin/winvalargs.c b/hw/xwin/winvalargs.c index 6680aba67..04db777b0 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"); From 8385c426f86e9955e9e570a46f75bddd3c10ca01 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 10 Aug 2010 21:55:15 +0100 Subject: [PATCH 12/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/win.h | 3 --- hw/xwin/winshaddd.c | 13 ------------- hw/xwin/winshadddnl.c | 12 ------------ hw/xwin/winshadgdi.c | 12 ------------ 4 files changed, 40 deletions(-) diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 2eea345e5..96a868e22 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 45d15482c..e23e10067 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 dd2e9b57a..52a4ce26d 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 a165d801e..721234eee 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)) { From 8b22f83113fbdc09b932b5ad7e44f629fc15e3b5 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 30 Aug 2010 17:17:57 +0100 Subject: [PATCH 13/16] Cygwin/X: Use winUpdateFBPointer() in winshaddd.c rather than duplicating it inline Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winshaddd.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c index e23e10067..b551bef7e 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); } } From 3f7339a7c5d3dcd05909b041865125f4cb6fa29e Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 31 Aug 2010 10:13:01 +0100 Subject: [PATCH 14/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/win.h | 3 +- hw/xwin/winscrinit.c | 7 +++-- hw/xwin/winshadgdi.c | 53 ++++++++++++++++++----------------- hw/xwin/winwndproc.c | 67 +++++++++++++++++--------------------------- 4 files changed, 60 insertions(+), 70 deletions(-) diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 96a868e22..3f40fdbe0 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 f505dddca..699ed949e 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 721234eee..e9c51ee64 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 80f5e1a7b..dd8f27edb 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -182,28 +182,6 @@ winWindowProc (HWND hwnd, UINT message, "new height: %d new bpp: %d\n", 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, @@ -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 From 625ab9701fd75b879c1dafc05fa979591eea87c0 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 31 Aug 2010 13:45:43 +0100 Subject: [PATCH 15/16] Cygwin/X: Simplify and consolidate reporting of the bpp value we are going to use Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winnativegdi.c | 23 ++--------------------- hw/xwin/winpfbdd.c | 26 +++----------------------- hw/xwin/winscrinit.c | 18 ++++++++++++++++++ hw/xwin/winshaddd.c | 24 +++--------------------- hw/xwin/winshadddnl.c | 26 +++----------------------- hw/xwin/winshadgdi.c | 21 ++------------------- 6 files changed, 31 insertions(+), 107 deletions(-) diff --git a/hw/xwin/winnativegdi.c b/hw/xwin/winnativegdi.c index b0a551a5c..4d7afe898 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); + /* GDI cannot change the screen depth, so we'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; - /* 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); - - /* 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 41457170a..c0bca71e3 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 699ed949e..691237e6f 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 b551bef7e..b14d0a962 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 52a4ce26d..c74a2ff14 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 e9c51ee64..499037656 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); + /* GDI cannot change the screen depth, so always use GDI's depth */ + pScreenInfo->dwBPP = 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); - - /* We'll use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - /* Release our DC */ ReleaseDC (NULL, hdc); hdc = NULL; From 09fd010902fad56735b8069b1becb80d85bd6a35 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 29 Sep 2010 22:54:22 +0100 Subject: [PATCH 16/16] 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 Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winshaddd.c | 21 ++++++++------------- hw/xwin/winshadddnl.c | 21 ++++++++------------- hw/xwin/winwndproc.c | 20 ++------------------ 3 files changed, 18 insertions(+), 44 deletions(-) diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c index b14d0a962..00d7a379f 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 c74a2ff14..0a0b4ae13 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 dd8f27edb..bccd6f9f2 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. */ /*