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

This commit is contained in:
Keith Packard 2011-01-20 21:11:53 -08:00
commit 24ce650cf4
20 changed files with 1031 additions and 705 deletions

View File

@ -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])

View File

@ -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");

View File

@ -87,6 +87,7 @@ SRCS = InitInput.c \
winkeybd.c \
winkeyhook.c \
winmisc.c \
winmonitors.c \
winmouse.c \
winmsg.c \
winmultiwindowclass.c \

View File

@ -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.

View File

@ -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
@ -368,6 +375,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.
@ -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;
@ -1451,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
*/

View File

@ -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,

View File

@ -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");

92
hw/xwin/winmonitors.c Normal file
View File

@ -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;
}

14
hw/xwin/winmonitors.h Normal file
View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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 <xwin-config.h>
#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_mm,
pScreenInfo->dwHeight_mm);
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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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 */
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;
}
/* 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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -58,6 +58,7 @@ winReshapeRootless (WindowPtr pWin);
Bool
winCreateWindowNativeGDI (WindowPtr pWin)
{
Bool fResult = TRUE;
ScreenPtr pScreen = pWin->drawable.pScreen;
winWindowPriv(pWin);
winScreenPriv(pScreen);

View File

@ -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
#ifdef XWIN_PRIMARYFB
|| 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);
}
else
{
/* 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))
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
#endif
))
{
/* 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;
}
/*
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");
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
/* Release the old primary surface */
(*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
#if CYGDEBUG
winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released "
"primary surface\n");
|| s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOW
|| s_pScreenInfo->fMultiWindow
#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 ();
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