diff options
author | Keith Packard <keithp@keithp.com> | 2011-01-20 21:11:53 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-01-20 21:11:53 -0800 |
commit | 24ce650cf4f0c6fa72faecd38c53d40703e6c959 (patch) | |
tree | 819bd145f19183f9eeda93de650cd3be14a8a6e9 | |
parent | bbdf81a056be0ea645da17a642dad5eadef3a906 (diff) | |
parent | 09fd010902fad56735b8069b1becb80d85bd6a35 (diff) |
Merge remote branch 'jturney/jturney-framebuffer-resize-for-master'
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | hw/xwin/InitOutput.c | 13 | ||||
-rw-r--r-- | hw/xwin/Makefile.am | 1 | ||||
-rw-r--r-- | hw/xwin/man/XWin.man | 85 | ||||
-rw-r--r-- | hw/xwin/win.h | 56 | ||||
-rw-r--r-- | hw/xwin/wincreatewnd.c | 48 | ||||
-rw-r--r-- | hw/xwin/windialogs.c | 13 | ||||
-rw-r--r-- | hw/xwin/winmonitors.c | 92 | ||||
-rw-r--r-- | hw/xwin/winmonitors.h | 14 | ||||
-rw-r--r-- | hw/xwin/winnativegdi.c | 37 | ||||
-rw-r--r-- | hw/xwin/winpfbdd.c | 108 | ||||
-rw-r--r-- | hw/xwin/winprocarg.c | 131 | ||||
-rw-r--r-- | hw/xwin/winrandr.c | 302 | ||||
-rw-r--r-- | hw/xwin/winscrinit.c | 66 | ||||
-rw-r--r-- | hw/xwin/winshaddd.c | 164 | ||||
-rw-r--r-- | hw/xwin/winshadddnl.c | 152 | ||||
-rw-r--r-- | hw/xwin/winshadgdi.c | 124 | ||||
-rw-r--r-- | hw/xwin/winvalargs.c | 8 | ||||
-rw-r--r-- | hw/xwin/winwindow.c | 1 | ||||
-rw-r--r-- | hw/xwin/winwndproc.c | 307 |
20 files changed, 1026 insertions, 700 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..7faed0170 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 @@ -823,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"); @@ -836,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/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/man/XWin.man b/hw/xwin/man/XWin.man index 51268f69a..e7933c9c8 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 @@ -190,15 +232,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" @@ -322,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 44307813c..3f40fdbe0 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 */ @@ -276,8 +273,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); @@ -315,6 +316,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 @@ -369,6 +376,15 @@ typedef struct { } winCursorRec; /* + * Resize modes + */ +typedef enum { + notAllowed, + resizeWithScrollbars, + resizeWithRandr +} winResizeMode; + +/* * Screen information structure that we need before privates are available * in the server startup sequence. */ @@ -381,12 +397,12 @@ typedef struct Bool fUserGaveHeightAndWidth; DWORD dwScreen; + + int iMonitor; DWORD dwUserWidth; DWORD dwUserHeight; DWORD dwWidth; DWORD dwHeight; - DWORD dwWidth_mm; - DWORD dwHeight_mm; DWORD dwPaddedWidth; /* Did the user specify a screen position? */ @@ -431,7 +447,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 */ @@ -473,11 +489,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; @@ -493,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; @@ -543,7 +555,9 @@ typedef struct _winPrivScreenRec /* Engine specific functions */ winAllocateFBProcPtr pwinAllocateFB; + winFreeFBProcPtr pwinFreeFB; winShadowUpdateProcPtr pwinShadowUpdate; + winInitScreenProcPtr pwinInitScreen; winCloseScreenProcPtr pwinCloseScreen; winInitVisualsProcPtr pwinInitVisuals; winAdjustVideoModeProcPtr pwinAdjustVideoMode; @@ -588,6 +602,12 @@ typedef struct _winPrivScreenRec SetShapeProcPtr SetShape; winCursorRec cursor; + +#ifdef XWIN_NATIVEGDI + RealizeFontPtr RealizeFont; + UnrealizeFontPtr UnrealizeFont; +#endif + } winPrivScreenRec; @@ -1452,6 +1472,18 @@ void winInitializeScreens(int maxscreens); /* + * winrandr.c + */ +Bool +winRandRInit (ScreenPtr pScreen); +void +winDoRandRScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); + +/* * END DDX and DIX Function Prototypes */ diff --git a/hw/xwin/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/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/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> + 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/winnativegdi.c b/hw/xwin/winnativegdi.c index b8d2d351b..4d7afe898 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; @@ -289,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); @@ -506,7 +499,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 7859c6b19..c0bca71e3 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); @@ -422,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); @@ -653,8 +647,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,10 +658,17 @@ 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; + 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/winprocarg.c b/hw/xwin/winprocarg.c index 1ce5c2dca..ddfe1f5b7 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 @@ -143,6 +95,7 @@ winInitializeScreenDefaults(void) if (monitorResolution == 0) monitorResolution = WIN_DEFAULT_DPI; + defaultScreenInfo.iMonitor = 1; defaultScreenInfo.dwWidth = dwWidth; defaultScreenInfo.dwHeight = dwHeight; defaultScreenInfo.dwUserWidth = dwWidth; @@ -171,11 +124,9 @@ winInitializeScreenDefaults(void) #endif defaultScreenInfo.fMultipleMonitors = FALSE; defaultScreenInfo.fLessPointer = FALSE; - defaultScreenInfo.fScrollbars = FALSE; + defaultScreenInfo.iResizeMode = notAllowed; 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; @@ -368,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; @@ -420,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; } @@ -449,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; } @@ -500,17 +454,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; @@ -717,12 +660,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 /* @@ -1233,24 +1215,3 @@ winLogVersionInfo (void) ErrorF ("%s\n\n", BUILDERSTRING); ErrorF ("Contact: %s\n", BUILDERADDR); } - -/* - * getMonitorInfo - callback function used to return information from the enumeration of monitors attached - */ - -wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data) -{ - struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data; - // only get data for monitor number specified in <data> - data->monitorNum++; - if (data->monitorNum == data->requestedMonitor) - { - data->bMonitorSpecifiedExists = TRUE; - data->monitorOffsetX = rect->left; - data->monitorOffsetY = rect->top; - data->monitorHeight = rect->bottom - rect->top; - data->monitorWidth = rect->right - rect->left; - return FALSE; - } - return TRUE; -} diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c index 7b5b1359c..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,101 +21,280 @@ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - *Except as contained in this notice, the name of Harold L Hunt II + *Except as contained in this notice, the name of the author(s) *shall not be used in advertising or otherwise to promote the sale, use *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. + *from the author(s) * * Authors: Harold L Hunt II + * Jon TURNEY */ #ifdef HAVE_XWIN_CONFIG_H #include <xwin-config.h> #endif #include "win.h" +#include "mivalidate.h" // for union _Validate used by windowstr.h + +#ifndef RANDR_12_INTERFACE +#error X server must have RandR 1.2 interface +#endif /* - * Local prototypes + * Answer queries about the RandR features supported. */ static Bool -winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations); +winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations) +{ + winDebug ("winRandRGetInfo ()\n"); -static Bool -winRandRSetConfig (ScreenPtr pScreen, - Rotation rotateKind, - int rate, - RRScreenSizePtr pSize); + /* Don't support rotations */ + *pRotations = RR_Rotate_0; -Bool -winRandRInit (ScreenPtr pScreen); + /* + The screen doesn't have to be limited to the actual + monitor size (we can have scrollbars :-), so what is + the upper limit? + */ + RRScreenSetSizeRange(pScreen, 0, 0, 4096, 4096); + + return TRUE; +} /* - * Answer queries about the RandR features supported. + Copied from the xfree86 DDX + + Why can't this be in DIX? + Does union _Validate vary depending on DDX?? */ +static void +xf86SetRootClip (ScreenPtr pScreen, Bool enable) +{ + WindowPtr pWin = pScreen->root; + WindowPtr pChild; + Bool WasViewable = (Bool)(pWin->viewable); + Bool anyMarked = FALSE; + WindowPtr pLayerWin; + BoxRec box; -static Bool -winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations) + if (WasViewable) + { + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) + { + (void) (*pScreen->MarkOverlappedWindows)(pChild, + pChild, + &pLayerWin); + } + (*pScreen->MarkWindow) (pWin); + anyMarked = TRUE; + if (pWin->valdata) + { + if (HasBorder (pWin)) + { + RegionPtr borderVisible; + + borderVisible = REGION_CREATE(pScreen, NullBox, 1); + REGION_SUBTRACT(pScreen, borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + } + pWin->valdata->before.resized = TRUE; + } + } + + /* + * Use REGION_BREAK to avoid optimizations in ValidateTree + * that assume the root borderClip can't change well, normally + * it doesn't...) + */ + if (enable) + { + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + REGION_INIT (pScreen, &pWin->winSize, &box, 1); + REGION_INIT (pScreen, &pWin->borderSize, &box, 1); + if (WasViewable) + REGION_RESET(pScreen, &pWin->borderClip, &box); + pWin->drawable.width = pScreen->width; + pWin->drawable.height = pScreen->height; + REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); + } + else + { + REGION_EMPTY(pScreen, &pWin->borderClip); + REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); + } + + ResizeChildrenWinSize (pWin, 0, 0, 0, 0); + + if (WasViewable) + { + if (pWin->firstChild) + { + anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, + pWin->firstChild, + (WindowPtr *)NULL); + } + else + { + (*pScreen->MarkWindow) (pWin); + anyMarked = TRUE; + } + + + if (anyMarked) + (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); + } + + if (WasViewable) + { + if (anyMarked) + (*pScreen->HandleExposures)(pWin); + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); + } + if (pWin->realized) + WindowsRestructured (); + FlushAllOutput (); +} + +/* + +*/ +void +winDoRandRScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight) { winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - int n; - Rotation rotateKind; - RRScreenSizePtr pSize; + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + WindowPtr pRoot = pScreen->root; - winDebug ("winRandRGetInfo ()\n"); + // Prevent screen updates while we change things around + xf86SetRootClip(pScreen, FALSE); - /* Don't support rotations, yet */ - *pRotations = RR_Rotate_0; + /* Update the screen size as requested */ + pScreenInfo->dwWidth = width; + pScreenInfo->dwHeight = height; - /* Bail if no depth has a visual associated with it */ - for (n = 0; n < pScreen->numDepths; n++) - if (pScreen->allowedDepths[n].numVids) - break; - if (n == pScreen->numDepths) - return FALSE; + /* Reallocate the framebuffer used by the drawing engine */ + (*pScreenPriv->pwinFreeFB)(pScreen); + if (!(*pScreenPriv->pwinAllocateFB)(pScreen)) + { + ErrorF ("winDoRandRScreenSetSize - Could not reallocate framebuffer\n"); + } - /* Only one allowed rotation for now */ - rotateKind = RR_Rotate_0; + pScreen->width = width; + pScreen->height = height; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; - /* - * Register supported sizes. This can be called many times, but - * we only support one size for now. - */ - pSize = RRRegisterSize (pScreen, - pScreenInfo->dwWidth, - pScreenInfo->dwHeight, - pScreenInfo->dwWidth_mm, - pScreenInfo->dwHeight_mm); - - /* Tell RandR what the current config is */ - RRSetCurrentConfig (pScreen, - rotateKind, - 0, /* refresh rate, not needed */ - pSize); - - return TRUE; -} + /* Update the screen pixmap to point to the new framebuffer */ + winUpdateFBPointer(pScreen, pScreenInfo->pfb); + + // pScreen->devPrivate == pScreen->GetScreenPixmap(screen) ? + // resize the root window + //pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL); + // does this emit a ConfigureNotify?? + // Restore the ability to update screen, now with new dimensions + xf86SetRootClip(pScreen, TRUE); + + // and arrange for it to be repainted + miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); + + /* Indicate that a screen size change took place */ + RRScreenSizeNotify(pScreen); +} /* - * Respond to resize/rotate request from either X Server or X client app + * Respond to resize request */ - -static Bool -winRandRSetConfig (ScreenPtr pScreen, - Rotation rotateKind, - int rate, - RRScreenSizePtr pSize) +static +Bool +winRandRScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD16 pixWidth, + CARD16 pixHeight, + CARD32 mmWidth, + CARD32 mmHeight) { - winDebug ("winRandRSetConfig ()\n"); + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + winDebug ("winRandRScreenSetSize ()\n"); + + /* + It doesn't currently make sense to allow resize in fullscreen mode + (we'd actually have to list the supported resolutions) + */ + if (pScreenInfo->fFullScreen) + { + ErrorF ("winRandRScreenSetSize - resize not supported in fullscreen mode\n"); + return FALSE; + } + + /* + Client resize requests aren't allowed in rootless modes, even if + the X screen is monitor or virtual desktop size, we'd need to + resize the native display size + */ + if (FALSE +#ifdef XWIN_MULTIWINDOWEXTWM + || pScreenInfo->fMWExtWM +#endif + || pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + || pScreenInfo->fMultiWindow +#endif + ) + { + ErrorF ("winRandRScreenSetSize - resize not supported in rootless modes\n"); + return FALSE; + } + + winDoRandRScreenSetSize(pScreen, width, height, mmWidth, mmHeight); + + /* Cause the native window for the screen to resize itself */ + { + DWORD dwStyle, dwExStyle; + RECT rcClient; + + rcClient.left = 0; + rcClient.top = 0; + rcClient.right = width; + rcClient.bottom = height; + + ErrorF ("winRandRScreenSetSize new client area w: %d h: %d\n", width, height); + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr(pScreenPriv->hwndScreen, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr(pScreenPriv->hwndScreen, GWL_STYLE); + + /* + * Calculate the window size needed for the given client area + * adjusting for any decorations it will have + */ + AdjustWindowRectEx(&rcClient, dwStyle, FALSE, dwExStyle); + + ErrorF ("winRandRScreenSetSize new window area w: %ld h: %ld\n", rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); + + SetWindowPos(pScreenPriv->hwndScreen, NULL, + 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, + SWP_NOZORDER | SWP_NOMOVE); + } return TRUE; } - /* * Initialize the RandR layer. */ @@ -122,8 +302,7 @@ winRandRSetConfig (ScreenPtr pScreen, Bool winRandRInit (ScreenPtr pScreen) { - rrScrPrivPtr pRRScrPriv; - + rrScrPrivPtr pRRScrPriv; winDebug ("winRandRInit ()\n"); if (!RRScreenInit (pScreen)) @@ -135,7 +314,10 @@ winRandRInit (ScreenPtr pScreen) /* Set some RandR function pointers */ pRRScrPriv = rrGetScrPriv (pScreen); pRRScrPriv->rrGetInfo = winRandRGetInfo; - pRRScrPriv->rrSetConfig = winRandRSetConfig; + pRRScrPriv->rrSetConfig = NULL; + pRRScrPriv->rrScreenSetSize = winRandRScreenSetSize; + pRRScrPriv->rrCrtcSet = NULL; + pRRScrPriv->rrCrtcSetGamma = NULL; return TRUE; } diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c index 21036f46c..691237e6f 100644 --- a/hw/xwin/winscrinit.c +++ b/hw/xwin/winscrinit.c @@ -69,10 +69,6 @@ winMWExtWMProcs = { * Prototypes */ -Bool -winRandRInit (ScreenPtr pScreen); - - /* * Local functions */ @@ -95,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", @@ -130,13 +127,30 @@ winScreenInit (int index, return FALSE; } - /* Adjust the video mode for our engine type */ + /* 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)))) { @@ -155,13 +169,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 */ @@ -175,13 +196,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 ... @@ -190,30 +207,14 @@ 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 - { - 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); /* 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,14 +280,15 @@ winFinishScreenInitFB (int index, #endif /* Create framebuffer */ - if (!(*pScreenPriv->pwinAllocateFB) (pScreen)) + if (!(*pScreenPriv->pwinInitScreen) (pScreen)) { ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n"); return FALSE; } /* - * 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; @@ -294,7 +296,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/winshaddd.c b/hw/xwin/winshaddd.c index 4e284b9c1..00d7a379f 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,48 @@ 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 primary surface, if there is one */ + winReleasePrimarySurfaceShadowDD(pScreen); + + /* Release the clipper object */ + if (pScreenPriv->pddcPrimary) + { + IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); + pScreenPriv->pddcPrimary = 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. @@ -529,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; @@ -647,25 +690,20 @@ 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); } } +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 +730,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 +764,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); @@ -909,43 +904,12 @@ 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; - } - - /* 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); @@ -1370,7 +1334,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..0a0b4ae13 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,49 @@ 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 primary surface, if there is one */ + winReleasePrimarySurfaceShadowDDNL(pScreen); + + /* Release the clipper object */ + if (pScreenPriv->pddcPrimary) + { + IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); + pScreenPriv->pddcPrimary = 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) /* @@ -605,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; @@ -720,6 +768,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 +804,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 +838,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); @@ -964,45 +978,13 @@ 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 */ + /* 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 */ - 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 */ - 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); @@ -1382,7 +1364,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..499037656 100644 --- a/hw/xwin/winshadgdi.c +++ b/hw/xwin/winshadgdi.c @@ -338,37 +338,20 @@ winAllocateFBShadowGDI (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - BITMAPINFOHEADER *pbmih = NULL; 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)); - 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, @@ -449,25 +432,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)) - { - ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n"); - return FALSE; - } - #ifdef XWIN_MULTIWINDOW /* Redraw all windows */ if (pScreenInfo->fMultiWindow) @@ -477,6 +441,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 +578,41 @@ 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); + + /* 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); +} + /* See Porting Layer Definition - p. 33 */ /* * We wrap whatever CloseScreen procedure was specified by fb; @@ -632,9 +643,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 +675,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); @@ -791,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; @@ -1235,7 +1225,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; diff --git a/hw/xwin/winvalargs.c b/hw/xwin/winvalargs.c index 357d3d70a..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"); @@ -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/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); diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index 6d2270a20..bccd6f9f2 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" /* @@ -148,6 +149,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,150 +175,153 @@ 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, - wParam); ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " - "new height: %d\n", - LOWORD (lParam), HIWORD (lParam)); - - /* - * 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 - */ + "new height: %d new bpp: %d\n", + LOWORD (lParam), HIWORD (lParam), wParam); /* * Check for a disruptive change in depth. * We can only display a message for a disruptive depth change, * we cannot do anything to correct the situation. */ - if ((s_pScreenInfo->dwBPP != wParam) - && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL + /* + XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT) + has changed as well... + */ + 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"); - - /* Display Exit dialog */ - winDisplayDepthChangeDialog (s_pScreenPriv); - - /* Flag that we have an invalid screen depth */ - s_pScreenPriv->fBadDepth = TRUE; - - /* Minimize the display window */ - ShowWindow (hwnd, SW_MINIMIZE); - } + )) + { + /* Cannot display the visual until the depth is restored */ + ErrorF ("winWindowProc - Disruptive change in depth\n"); + + /* Display depth change dialog */ + winDisplayDepthChangeDialog (s_pScreenPriv); + + /* Flag that we have an invalid screen depth */ + s_pScreenPriv->fBadDepth = TRUE; + + /* 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; + } + /* - * 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)) + 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) + */ { /* - * 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"); + 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 - - /* Create the new primary surface */ - (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); - -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " - "primary surface\n"); + || s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + || s_pScreenInfo->fMultiWindow #endif - -#if 0 - /* Multi-Window mode uses RandR for resizes */ - if (s_pScreenInfo->fMultiWindow) + )) { - RRSetScreenConfig (); + DWORD dwWidth, dwHeight; + + if (s_pScreenInfo->fMultipleMonitors) + { + /* resize to new virtual desktop size */ + dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); + } + else + { + /* resize to new size of specified monitor */ + struct GetMonitorInfoData data; + if (QueryMonitor(s_pScreenInfo->iMonitor, &data)) + { + if (data.bMonitorSpecifiedExists == TRUE) + { + dwWidth = data.monitorWidth; + dwHeight = data.monitorHeight; + /* + XXX: monitor may have changed position, + so we might need to update xinerama data + */ + } + else + { + ErrorF ("Monitor number %d no longer exists!\n", s_pScreenInfo->iMonitor); + } + } + } + + /* + XXX: probably a small bug here: we don't compute the work area + and allow for task bar + + XXX: generally, we don't allow for the task bar being moved after + the server is started + */ + + /* Set screen size to match new size, if it is different to current */ + if ((s_pScreenInfo->dwWidth != dwWidth) || + (s_pScreenInfo->dwHeight != dwHeight)) + { + winDoRandRScreenSetSize(s_pScreen, + dwWidth, + dwHeight, + (dwWidth * 25.4) / monitorResolution, + (dwHeight * 25.4) / monitorResolution); + } } -#endif - } - else - { -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not " - "change\n"); -#endif + else + { + /* + * We can simply recreate the same-sized primary surface when + * 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). + */ + + 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); + } } - /* 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: @@ -323,8 +334,8 @@ winWindowProc (HWND hwnd, UINT message, winDebug ("winWindowProc - WM_SIZE\n"); #endif - /* Break if we do not use scrollbars */ - if (!s_pScreenInfo->fScrollbars + /* Break if we do not allow resizing */ + if ((s_pScreenInfo->iResizeMode == notAllowed) || !s_pScreenInfo->fDecoration #ifdef XWIN_MULTIWINDOWEXTWM || s_pScreenInfo->fMWExtWM @@ -340,6 +351,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). @@ -357,10 +379,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) @@ -416,6 +434,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; @@ -599,7 +648,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 |