@@ -, +, @@ --- hw/xwin/Makefile.am | 1 + hw/xwin/glx/winpriv.c | 115 +++++++++++++++++++++++++++++++++++-------- hw/xwin/win.h | 12 +++++ hw/xwin/winscrinit.c | 53 ++++++++++++-------- hw/xwin/winwindowedwindow.c | 114 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 253 insertions(+), 42 deletions(-) create mode 100644 hw/xwin/winwindowedwindow.c --- a/hw/xwin/Makefile.am +++ a/hw/xwin/Makefile.am @@ -107,6 +107,7 @@ SRCS = InitInput.c \ winvalargs.c \ winwakeup.c \ winwindow.c \ + winwindowedwindow.c \ winwndproc.c \ ddraw.h \ winclipboard.h \ --- a/hw/xwin/glx/winpriv.c +++ a/hw/xwin/glx/winpriv.c @@ -47,6 +47,54 @@ winCreateWindowsWindowHierarchy(WindowPtr pWin) } } +static +void +winCreateWindowedWindow(WindowPtr pWin, winPrivScreenPtr pWinScreen) +{ + winWindowPriv(pWin); + + // create window class if needed +#define WIN_GL_WINDOW_CLASS "cygwin/x X child GL window" + { + static wATOM glChildWndClass = 0; + if (glChildWndClass == 0) + { + WNDCLASSEX wc; + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = DefWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = 0; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = WIN_GL_WINDOW_CLASS; + wc.hIconSm = 0; + RegisterClassEx (&wc); + } + } + + // ensure this window exists */ + if (pWinPriv->hWnd == NULL) + { + int ExtraClass = (pWin->realized) ? WS_VISIBLE : 0; + pWinPriv->hWnd = CreateWindowExA(WS_EX_TRANSPARENT, + WIN_GL_WINDOW_CLASS, + "", + WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED | ExtraClass, + pWin->drawable.x, + pWin->drawable.y, + pWin->drawable.width, + pWin->drawable.height, + pWinScreen->hwndScreen, + (HMENU) NULL, + g_hInstance, + NULL); + } +} + /** * Return size and handles of a window. * If pWin is NULL, then the information for the root window is requested. @@ -62,7 +110,6 @@ HWND winGetWindowInfo(WindowPtr pWin) ScreenPtr pScreen = pWin->drawable.pScreen; winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); winScreenInfoPtr pScreenInfo = NULL; - HWND hwnd = NULL; if (pWinScreen == NULL) { @@ -70,21 +117,18 @@ HWND winGetWindowInfo(WindowPtr pWin) return NULL; } - hwnd = pWinScreen->hwndScreen; + winWindowPriv(pWin); + if (pWinPriv == NULL) + { + ErrorF("winGetWindowInfo: window has no privates\n"); + return pWinScreen->hwndScreen; + } pScreenInfo = pWinScreen->pScreenInfo; #ifdef XWIN_MULTIWINDOW /* check for multiwindow mode */ if (pScreenInfo->fMultiWindow) { - winWindowPriv(pWin); - - if (pWinPriv == NULL) - { - ErrorF("winGetWindowInfo: window has no privates\n"); - return hwnd; - } - if (pWinPriv->hWnd == NULL) { ErrorF("winGetWindowInfo: forcing window to exist\n"); @@ -93,15 +137,13 @@ HWND winGetWindowInfo(WindowPtr pWin) if (pWinPriv->hWnd != NULL) { - /* copy window handle */ - hwnd = pWinPriv->hWnd; - /* mark GLX active on that hwnd */ pWinPriv->fWglUsed = TRUE; } - return hwnd; + return pWinPriv->hWnd; } + else #endif #ifdef XWIN_MULTIWINDOWEXTWM /* check for multiwindow external wm mode */ @@ -110,19 +152,39 @@ HWND winGetWindowInfo(WindowPtr pWin) win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); - if (pRLWinPriv == NULL) { + if (pRLWinPriv == NULL) + { ErrorF("winGetWindowInfo: window has no privates\n"); - return hwnd; + return pWinScreen->hwndScreen; } - if (pRLWinPriv->hWnd != NULL) + return pRLWinPriv->hWnd; + } + else +#endif + /* check for windowed mode */ + if (TRUE +#ifdef XWIN_MULTIWINDOW + && !pScreenInfo->fMultiWindow +#endif +#ifdef XWIN_MULTIWINDOWEXTWM + && !pScreenInfo->fMWExtWM +#endif + && !pScreenInfo->fRootless) + { + if (pWinPriv->hWnd == NULL) + { + winCreateWindowedWindow(pWin, pWinScreen); + } + + if (pWinPriv->hWnd != NULL) { - /* copy window handle */ - hwnd = pRLWinPriv->hWnd; + /* mark GLX active on that hwnd */ + pWinPriv->fWglUsed = TRUE; } - return hwnd; + + return pWinPriv->hWnd; } -#endif } else { @@ -159,5 +221,16 @@ winCheckScreenAiglxIsSupported(ScreenPtr pScreen) return TRUE; #endif + if (TRUE +#ifdef XWIN_MULTIWINDOW + && !pScreenInfo->fMultiWindow +#endif +#ifdef XWIN_MULTIWINDOWEXTWM + && !pScreenInfo->fMWExtWM +#endif + && !pScreenInfo->fRootless) + return TRUE; + return FALSE; + /* I think that adds up to return !pScreenInfo->fRootless :-) */ } --- a/hw/xwin/win.h +++ a/hw/xwin/win.h @@ -1310,6 +1310,18 @@ int winAdjustXWindow (WindowPtr pWin, HWND hwnd); #endif +/* + * winwindowedwindow.c + */ +Bool +winMapWindowWindowed (WindowPtr pWin); + +Bool +winPositionWindowWindowed (WindowPtr pWin, int x, int y); + +Bool +winDestroyWindowWindowed (WindowPtr pWin); + #ifdef XWIN_MULTIWINDOW /* --- a/hw/xwin/winscrinit.c +++ a/hw/xwin/winscrinit.c @@ -459,10 +459,7 @@ winFinishScreenInitFB (int index, } #endif - /* Handle rootless mode */ - if (pScreenInfo->fRootless) - { - /* Define the WRAP macro temporarily for local use */ + /* Define the WRAP macro temporarily for local use */ #define WRAP(a) \ if (pScreen->a) { \ pScreenPriv->a = pScreen->a; \ @@ -471,6 +468,9 @@ winFinishScreenInitFB (int index, pScreenPriv->a = NULL; \ } + /* Handle rootless mode */ + if (pScreenInfo->fRootless) + { /* Save a pointer to each lower-level window procedure */ WRAP(CreateWindow); WRAP(DestroyWindow); @@ -488,25 +488,11 @@ winFinishScreenInitFB (int index, pScreen->RealizeWindow = winMapWindowRootless; pScreen->UnrealizeWindow = winUnmapWindowRootless; pScreen->SetShape = winSetShapeRootless; - - /* Undefine the WRAP macro, as it is not needed elsewhere */ -#undef WRAP } - - #ifdef XWIN_MULTIWINDOW /* Handle multi window mode */ else if (pScreenInfo->fMultiWindow) { - /* Define the WRAP macro temporarily for local use */ -#define WRAP(a) \ - if (pScreen->a) { \ - pScreenPriv->a = pScreen->a; \ - } else { \ - winDebug("null screen fn " #a "\n"); \ - pScreenPriv->a = NULL; \ - } - /* Save a pointer to each lower-level window procedure */ WRAP(CreateWindow); WRAP(DestroyWindow); @@ -534,11 +520,36 @@ winFinishScreenInitFB (int index, pScreen->MoveWindow = winMoveWindowMultiWindow; pScreen->CopyWindow = winCopyWindowMultiWindow; pScreen->SetShape = winSetShapeMultiWindow; - - /* Undefine the WRAP macro, as it is not needed elsewhere */ -#undef WRAP } #endif +#ifdef XWIN_MULTIWINDOWEXTWM + else if (pScreenInfo->fMWExtWM) + { + /* Doesn't need any screen window procedures, uses rootless frame procedures */ + } +#endif + else + /* Handle windowed mode */ + { + /* At the moment, only need to do something special to help WGL mdoe */ + if (g_fNativeGl) + { + /* WRAP(CreateWindow); */ + WRAP(DestroyWindow); + WRAP(RealizeWindow); + /* WRAP(UnrealizeWindow); */ + WRAP(PositionWindow); + + /* pScreen->CreateWindow = winCreateWindowWindowed; */ + pScreen->DestroyWindow = winDestroyWindowWindowed; + pScreen->PositionWindow = winPositionWindowWindowed; + pScreen->RealizeWindow = winMapWindowWindowed; + /* pScreen->UnrealizeWindow = winUnmapWindowWindowed; */ + } + } + + /* Undefine the WRAP macro, as it is not needed elsewhere */ +#undef WRAP /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */ pScreenPriv->CloseScreen = pScreen->CloseScreen; --- a/hw/xwin/winwindowedwindow.c +++ a/hw/xwin/winwindowedwindow.c @@ -0,0 +1,114 @@ +/* + File: winwindowedwindow.c + Purpose: Screen window functions for windowed mode + + Permission is hereby granted, free of charge, to any person obtaining 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 permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" + +/* + At the moment, these only need to do do things when the window is an AIGLX + window +*/ + +/* + * MapWindow - See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowWindowed(WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + + winDebug("winMapWindowWindowed: pWin: %08x\n", pWin); + + WIN_UNWRAP(RealizeWindow); + fResult = (*pScreen->RealizeWindow)(pWin); + WIN_WRAP(RealizeWindow, winMapWindowWindowed); + + /* Check if we need to show the window */ + if (pWinPriv->fWglUsed && pWinPriv->hWnd) + ShowWindow(pWinPriv->hWnd, SW_SHOW); + + return fResult; +} + +/* + * PositionWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winPositionWindowWindowed(WindowPtr pWin, int x, int y) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + + WIN_UNWRAP(PositionWindow); + fResult = (*pScreen->PositionWindow)(pWin, x, y); + WIN_WRAP(PositionWindow, winPositionWindowWindowed); + + if (pWinPriv->fWglUsed && pWinPriv->hWnd) + { + MoveWindow(pWinPriv->hWnd, + pWin->drawable.x, + pWin->drawable.y, + pWin->drawable.width, + pWin->drawable.height, + FALSE); + } + + return fResult; +} + +/* + * DestroyWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winDestroyWindowWindowed(WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + + WIN_UNWRAP(DestroyWindow); + fResult = (*pScreen->DestroyWindow)(pWin); + WIN_WRAP(DestroyWindow, winDestroyWindowWindowed); + + if (pWinPriv->fWglUsed && pWinPriv->hWnd) + { + DestroyWindow(pWinPriv->hWnd); + pWinPriv->hWnd = NULL; + pWinPriv->fWglUsed = FALSE; + } + + return fResult; +} --