summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2010-11-03 13:52:21 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2010-11-03 13:52:21 +0000
commit89912be98de63c48e8e950d227f81ef518839465 (patch)
treee570b1768fcfcfd137624156765b514be123cc83
parent9940ecd26c51296993e8dddc09f6a7267046aa90 (diff)
parentbb88e266c36c3a95a16e61e7562a4602f5d8cdfd (diff)
Merge branch 'nontoplevelwin-aiglx' into cygwin-release-1.9
-rw-r--r--hw/xwin/glx/Makefile.am6
-rwxr-xr-xhw/xwin/glx/indirect.c52
-rw-r--r--hw/xwin/glx/wgl_ext_api.c13
-rw-r--r--hw/xwin/glx/winpriv.c43
-rw-r--r--hw/xwin/win.h3
-rw-r--r--hw/xwin/winmultiwindowwindow.c253
-rw-r--r--hw/xwin/winmultiwindowwndproc.c53
-rwxr-xr-xhw/xwin/winwin32rootless.c2
-rw-r--r--hw/xwin/winwindow.h4
9 files changed, 356 insertions, 73 deletions
diff --git a/hw/xwin/glx/Makefile.am b/hw/xwin/glx/Makefile.am
index a00f70e0e..e66dac235 100644
--- a/hw/xwin/glx/Makefile.am
+++ b/hw/xwin/glx/Makefile.am
@@ -16,7 +16,11 @@ if XWIN_MULTIWINDOWEXTWM
DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM
endif
-DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM)
+if XWIN_GLX_WINDOWS
+DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS
+endif
+
+DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM) $(DEFS_GLX_WINDOWS)
INCLUDES = -I$(top_srcdir)/miext/rootless
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index b745b5b63..9f2021c37 100755
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -49,8 +49,17 @@
- pbuffer clobbering: we don't get async notification, but can we arrange to emit the
event when we notice it's been clobbered? at the very least, check if it's been clobbered
before using it?
- - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure
- with privates?) Or are they created inside the GLX core as well?
+ - XGetImage() doesn't work on pixmaps; need to do more work to make the format and location
+ of the native pixmap compatible
+ - implement GLX_EXT_texture_from_pixmap in terms of WGL_ARB_render_texture
+ (not quite straightforward as we will have to create a pbuffer and copy the pixmap texture
+ into it)
+*/
+
+/*
+ Assumptions:
+ - the __GLXConfig * we get handed back ones we are made (so we can extend the structure
+ with privates) and never get created inside the GLX core
*/
/*
@@ -211,22 +220,25 @@ static
const char *glxWinErrorMessage(void)
{
static char errorbuffer[1024];
+ unsigned int last_error = GetLastError();
if (!FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ last_error,
+ 0,
(LPTSTR) &errorbuffer,
sizeof(errorbuffer),
NULL ))
{
- snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError());
+ snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error (%08x)", last_error);
}
- if (errorbuffer[strlen(errorbuffer)-1] == '\n')
+ if ((errorbuffer[strlen(errorbuffer)-1] == '\n') || (errorbuffer[strlen(errorbuffer)-1] == '\r'))
errorbuffer[strlen(errorbuffer)-1] = 0;
+ sprintf(errorbuffer + strlen(errorbuffer) -1, " (%08x)", last_error);
+
return errorbuffer;
}
@@ -992,7 +1004,7 @@ int glxWinReleaseTexImage(__GLXcontext *baseContext,
* lists with the old one...
*/
-static void
+static Bool
glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride)
{
__GLXscreen *screen = gc->base.pGlxScreen;
@@ -1014,10 +1026,10 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable
if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL))
{
ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
- return;
+ return FALSE;
}
- return;
+ return TRUE;
}
/*
@@ -1049,7 +1061,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable
if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride))
{
ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n");
- return;
+ return FALSE;
}
if (glxWinDebugSettings.dumpPFD)
@@ -1065,7 +1077,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable
if (pixelFormat == 0)
{
ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage());
- return;
+ return FALSE;
}
GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
@@ -1074,7 +1086,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable
if (!SetPixelFormat(hdc, pixelFormat, &pfd))
{
ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
- return;
+ return FALSE;
}
}
else
@@ -1083,7 +1095,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable
if (pixelFormat == 0)
{
ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
- return;
+ return FALSE;
}
GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
@@ -1092,9 +1104,11 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable
if (!SetPixelFormat(hdc, pixelFormat, NULL))
{
ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
- return;
+ return FALSE;
}
}
+
+ return TRUE;
}
static HDC
@@ -1145,7 +1159,13 @@ glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd)
gc->hwnd = *hwnd;
/* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */
- glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT);
+ if (!glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT))
+ {
+ ErrorF("glxWinSetPixelFormat error: %s\n", glxWinErrorMessage());
+ ReleaseDC(*hwnd, *hdc);
+ *hdc = NULL;
+ return NULL;
+ }
}
}
break;
diff --git a/hw/xwin/glx/wgl_ext_api.c b/hw/xwin/glx/wgl_ext_api.c
index 4b8359fb1..9d69051c4 100644
--- a/hw/xwin/glx/wgl_ext_api.c
+++ b/hw/xwin/glx/wgl_ext_api.c
@@ -43,17 +43,14 @@
static type type##proc = NULL;
#define PRERESOLVE(type, symbol) \
- type##proc = (type)wglGetProcAddress(symbol); \
- if (type##proc == NULL) \
- ErrorF("wglwrap: Can't resolve \"%s\"\n", symbol); \
- else \
- ErrorF("wglwrap: Resolved \"%s\"\n", symbol);
+ type##proc = (type)wglGetProcAddress(symbol);
#define RESOLVE_RET(type, symbol, retval) \
if (type##proc == NULL) { \
- __glXErrorCallBack(0); \
- return retval; \
- }
+ ErrorF("wglwrap: Can't resolve \"%s\"\n", symbol); \
+ __glXErrorCallBack(0); \
+ return retval; \
+ }
#define RESOLVE(procname, symbol) RESOLVE_RET(procname, symbol,)
diff --git a/hw/xwin/glx/winpriv.c b/hw/xwin/glx/winpriv.c
index a35392b26..72d65bc14 100644
--- a/hw/xwin/glx/winpriv.c
+++ b/hw/xwin/glx/winpriv.c
@@ -13,13 +13,47 @@
void
winCreateWindowsWindow (WindowPtr pWin);
+
+static
+void
+winCreateWindowsWindowHierarchy(WindowPtr pWin)
+{
+ winWindowPriv(pWin);
+
+ winDebug("winCreateWindowsWindowHierarchy - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
+
+ /* recursively ensure parent window exists if it's not the root window */
+ if (pWin->parent)
+ {
+ if (pWin->parent != pWin->drawable.pScreen->root)
+ winCreateWindowsWindowHierarchy(pWin->parent);
+ }
+
+ /* ensure this window exists */
+ if (pWinPriv->hWnd == NULL)
+ {
+ winCreateWindowsWindow(pWin);
+
+ /* ... and if it's already been mapped, make sure it's visible */
+ if (pWin->mapped)
+ {
+ /* Display the window without activating it */
+ if (pWin->drawable.class != InputOnly)
+ ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ /* Send first paint message */
+ UpdateWindow (pWinPriv->hWnd);
+ }
+ }
+}
+
/**
* Return size and handles of a window.
* If pWin is NULL, then the information for the root window is requested.
*/
HWND winGetWindowInfo(WindowPtr pWin)
{
- winDebug("%s: pWin=%p\n", __FUNCTION__, pWin);
+ winTrace("%s: pWin %p XID 0x%x\n", __FUNCTION__, pWin, pWin->drawable.id);
/* a real window was requested */
if (pWin != NULL)
@@ -53,14 +87,17 @@ HWND winGetWindowInfo(WindowPtr pWin)
if (pWinPriv->hWnd == NULL)
{
- winCreateWindowsWindow(pWin);
- ErrorF("winGetWindowInfo: forcing window to exist...\n");
+ ErrorF("winGetWindowInfo: forcing window to exist\n");
+ winCreateWindowsWindowHierarchy(pWin);
}
if (pWinPriv->hWnd != NULL)
{
/* copy window handle */
hwnd = pWinPriv->hWnd;
+
+ /* mark GLX active on that hwnd */
+ pWinPriv->fWglUsed = TRUE;
}
return hwnd;
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 44659abaf..9af046b56 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1318,6 +1318,9 @@ winAdjustXWindow (WindowPtr pWin, HWND hwnd);
LRESULT CALLBACK
winTopLevelWindowProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK
+winChildWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
#endif
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 64aaf8262..f6cdf873e 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -65,10 +65,27 @@ winUpdateWindowsWindow (WindowPtr pWin);
static void
winFindWindow (pointer value, XID id, pointer cdata);
+static Bool
+isToplevelWindow(WindowPtr pWin)
+{
+ assert(pWin->parent); /* root window isn't expected here */
+
+ /* If the immediate parent is the root window, this is a top-level window */
+ if ((pWin->parent) && (pWin->parent->parent == NULL))
+ {
+ assert(pWin->parent == pWin->drawable.pScreen->root);
+ return TRUE;
+ }
+
+ /* otherwise, a child window */
+ return FALSE;
+}
+
static
void winInitMultiWindowClass(void)
{
static wATOM atomXWinClass=0;
+ static wATOM atomXWinChildClass = 0;
WNDCLASSEX wcx;
if (atomXWinClass==0)
@@ -88,11 +105,34 @@ void winInitMultiWindowClass(void)
wcx.hIconSm = g_hSmallIconX;
#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
+ ErrorF ("winInitMultiWindowClass - Creating class: %s\n", WINDOW_CLASS_X);
#endif
atomXWinClass = RegisterClassEx (&wcx);
}
+
+ if (atomXWinChildClass==0)
+ {
+ /* Setup our window class */
+ wcx.cbSize=sizeof(WNDCLASSEX);
+ wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
+ wcx.lpfnWndProc = winChildWindowProc;
+ wcx.cbClsExtra = 0;
+ wcx.cbWndExtra = 0;
+ wcx.hInstance = g_hInstance;
+ wcx.hIcon = g_hIconX;
+ wcx.hCursor = 0;
+ wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = WINDOW_CLASS_X_CHILD;
+ wcx.hIconSm = g_hSmallIconX;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winInitMultiWindowClass - Creating class: %s\n", WINDOW_CLASS_X_CHILD);
+#endif
+
+ atomXWinChildClass = RegisterClassEx (&wcx);
+ }
}
/*
@@ -120,7 +160,10 @@ winCreateWindowMultiWindow (WindowPtr pWin)
pWinPriv->hWnd = NULL;
pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
pWinPriv->fXKilled = FALSE;
-
+#ifdef XWIN_GLX_WINDOWS
+ pWinPriv->fWglUsed = FALSE;
+#endif
+
return fResult;
}
@@ -204,6 +247,30 @@ winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
return fResult;
}
+ if (!isToplevelWindow(pWin))
+ {
+ POINT parentOrigin;
+
+ /* Get the X and Y location of the X window */
+ iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ /* Get the height and width of the X window */
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* Convert screen coordinates into client area co-ordinates of the parent */
+ parentOrigin.x = 0;
+ parentOrigin.y = 0;
+ ClientToScreen(GetParent(hWnd), &parentOrigin);
+
+ MoveWindow (hWnd,
+ iX - parentOrigin.x, iY - parentOrigin.y, iWidth, iHeight,
+ TRUE);
+
+ return fResult;
+ }
+
/* Get the Windows window style and extended style */
dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
@@ -484,13 +551,8 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
#endif
}
-
-/*
- * winCreateWindowsWindow - Create a Windows window associated with an X window
- */
-
-void
-winCreateWindowsWindow (WindowPtr pWin)
+static void
+winCreateWindowsTopLevelWindow (WindowPtr pWin)
{
int iX, iY;
int iWidth;
@@ -506,9 +568,7 @@ winCreateWindowsWindow (WindowPtr pWin)
winInitMultiWindowClass();
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
-#endif
+ winDebug("winCreateWindowsTopLevelWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
@@ -527,7 +587,7 @@ winCreateWindowsWindow (WindowPtr pWin)
iY = CW_USEDEFAULT;
}
- winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+ winDebug("winCreateWindowsTopLevelWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
if (winMultiWindowGetTransientFor (pWin, &pDaddy))
{
@@ -570,7 +630,7 @@ winCreateWindowsWindow (WindowPtr pWin)
iHeight = rc.bottom - rc.top;
iWidth = rc.right - rc.left;
- winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+ winDebug("winCreateWindowsTopLevelWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
/* Create the window */
hWnd = CreateWindowExA (dwExStyle, /* Extended styles */
@@ -587,11 +647,13 @@ winCreateWindowsWindow (WindowPtr pWin)
pWin); /* ScreenPrivates */
if (hWnd == NULL)
{
- ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
+ ErrorF ("winCreateWindowsTopLevelWindow - CreateWindowExA () failed: %d\n",
(int) GetLastError ());
}
pWinPriv->hWnd = hWnd;
+ winDebug("winCreateWindowsTopLevelWindow - hwnd 0x%08x\n", hWnd);
+
/* Set application or .XWinrc defined Icons */
winSelectIcons(pWin, &hIcon, &hIconSmall);
if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
@@ -620,6 +682,84 @@ winCreateWindowsWindow (WindowPtr pWin)
(*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
}
+static void
+winCreateWindowsChildWindow(WindowPtr pWin)
+{
+ int iX, iY, iWidth, iHeight;
+ HWND hWnd;
+ WindowPtr pParent = pWin->parent;
+ DWORD dwStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED;
+ DWORD dwExStyle = WS_EX_TRANSPARENT;
+ /*
+ WS_DISABLED means child window never gains the input focus, so only the
+ top-level window needs deal with passing input to the X server
+
+ WS_EX_TRANSPARENT ensures that the contents of the top-level
+ Windows window (which will contain all non-OpenGL drawing for the hierarchy)
+ can be seen through any intermediate child windows which have nothing
+ drawn to them
+ */
+ winPrivWinPtr pParentPriv, pWinPriv;
+
+ winDebug("winCreateWindowsChildWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
+
+ winInitMultiWindowClass();
+
+ assert(pParent);
+
+ pParentPriv = winGetWindowPriv(pParent);
+ pWinPriv = winGetWindowPriv(pWin);
+
+ iX = pWin->drawable.x - pParent->drawable.x;
+ iY = pWin->drawable.y - pParent->drawable.y;
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ winDebug("winCreateWindowsChildWindow - parent pWin:%08x XID:0x%08x hWnd:0x%08x\n", pParent, pParent->drawable.id, pParentPriv->hWnd);
+ winDebug("winCreateWindowsChildWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+
+ /* Create the window */
+ hWnd = CreateWindowExA (dwExStyle, /* Extended styles */
+ WINDOW_CLASS_X_CHILD, /* Class name */
+ WINDOW_TITLE_X, /* Window name */
+ dwStyle, /* Styles */
+ iX, /* Horizontal position */
+ iY, /* Vertical position */
+ iWidth, /* Right edge */
+ iHeight, /* Bottom edge */
+ pParentPriv->hWnd, /* parent window */
+ (HMENU) NULL, /* No menu */
+ GetModuleHandle(NULL),/* Instance handle */
+ pWin); /* ScreenPrivates */
+ if (hWnd == NULL)
+ {
+ ErrorF ("winCreateWindowsChildWindow - CreateWindowExA () failed: %d\n",
+ (int) GetLastError ());
+ }
+ winDebug("winCreateWindowsChildWindow - hwnd 0x%08x\n", hWnd);
+ pWinPriv->hWnd = hWnd;
+
+ SetProp(hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
+}
+
+/*
+ * winCreateWindowsWindow - Create a Windows window associated with an X window
+ */
+
+void
+winCreateWindowsWindow (WindowPtr pWin)
+{
+ winDebug("winCreateWindowsWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
+
+ if (isToplevelWindow(pWin))
+ {
+ winCreateWindowsTopLevelWindow(pWin);
+ }
+ else
+ {
+ winCreateWindowsChildWindow(pWin);
+ }
+}
Bool winInDestroyWindowsWindow = FALSE;
/*
@@ -635,9 +775,7 @@ winDestroyWindowsWindow (WindowPtr pWin)
HICON hIcon;
HICON hIconSm;
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winDestroyWindowsWindow\n");
-#endif
+ winDebug("winDestroyWindowsWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
/* Bail out if the Windows window handle is invalid */
if (pWinPriv->hWnd == NULL)
@@ -657,6 +795,11 @@ winDestroyWindowsWindow (WindowPtr pWin)
/* Null our handle to the Window so referencing it will cause an error */
pWinPriv->hWnd = NULL;
+#ifdef XWIN_GLX_WINDOWS
+ /* No longer note WGL used on this window */
+ pWinPriv->fWglUsed = FALSE;
+#endif
+
/* Destroy any icons we created for this window */
winDestroyIcon(hIcon);
winDestroyIcon(hIconSm);
@@ -672,9 +815,7 @@ winDestroyWindowsWindow (WindowPtr pWin)
winInDestroyWindowsWindow = oldstate;
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("-winDestroyWindowsWindow\n");
-#endif
+ winDebug("winDestroyWindowsWindow - done\n");
}
@@ -687,36 +828,52 @@ static void
winUpdateWindowsWindow (WindowPtr pWin)
{
winWindowPriv(pWin);
- HWND hWnd = pWinPriv->hWnd;
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winUpdateWindowsWindow\n");
#endif
- /* Check if the Windows window's parents have been destroyed */
- if (pWin->parent != NULL
- && pWin->parent->parent == NULL
- && pWin->mapped)
- {
- /* Create the Windows window if it has been destroyed */
- if (hWnd == NULL)
- {
- winCreateWindowsWindow (pWin);
- assert (pWinPriv->hWnd != NULL);
- }
-
- /* Display the window without activating it */
- if (pWin->drawable.class != InputOnly)
- ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+ /* Ignore the root window */
+ if (pWin->parent == NULL)
+ return;
- /* Send first paint message */
- UpdateWindow (pWinPriv->hWnd);
- }
- else if (hWnd != NULL)
+ /* If it's mapped */
+ if (pWin->mapped)
{
- /* Destroy the Windows window if its parents are destroyed */
- winDestroyWindowsWindow (pWin);
- assert (pWinPriv->hWnd == NULL);
+ /* If it's a top-level window */
+ if (isToplevelWindow(pWin))
+ {
+ /* Create the Windows window if needed */
+ if (pWinPriv->hWnd == NULL)
+ {
+ winCreateWindowsWindow (pWin);
+ assert (pWinPriv->hWnd != NULL);
+ }
+ }
+ /* It's not a top-level window, but we created a window for GLX */
+ else if (pWinPriv->hWnd)
+ {
+ winPrivWinPtr pParentPriv = winGetWindowPriv(pWin->parent);
+
+ /* XXX: This really belongs in winReparentWindow ??? */
+ /* XXX: this assumes parent window has been made to exist */
+ assert(pParentPriv->hWnd);
+
+ /* Ensure we have the correct parent and position if reparented */
+ SetParent(pWinPriv->hWnd, pParentPriv->hWnd);
+ SetWindowPos(pWinPriv->hWnd, NULL, pWin->drawable.x - pWin->parent->drawable.x, pWin->drawable.y - pWin->parent->drawable.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
+ }
+
+ /* If it's top level, or a GLX window which has already been created getting mapped, show it */
+ if (pWinPriv->hWnd != NULL)
+ {
+ /* Display the window without activating it */
+ if (pWin->drawable.class != InputOnly)
+ ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ /* Send first paint message */
+ UpdateWindow (pWinPriv->hWnd);
+ }
}
#if CYGMULTIWINDOW_DEBUG
@@ -964,6 +1121,14 @@ winAdjustXWindow (WindowPtr pWin, HWND hwnd)
ErrorF ("winAdjustXWindow\n");
#endif
+ if (!isToplevelWindow(pWin))
+ {
+#if 1
+ ErrorF ("winAdjustXWindow - immediately return because not a top-level window\n");
+#endif
+ return 0;
+ }
+
if (IsIconic (hwnd))
{
#if CYGWINDOWING_DEBUG
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 7b054aaec..6bdef6b6a 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -481,6 +481,20 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
return 0;
}
+#ifdef XWIN_GLX_WINDOWS
+ if (pWinPriv->fWglUsed)
+ {
+ /*
+ For regions which are being drawn by GL, the shadow framebuffer doesn't have the
+ correct bits, so don't bitblt from the shadow framebuffer
+
+ XXX: For now, just leave it alone, but ideally we want to send an expose event to
+ the window so it really redraws the affected region...
+ */
+ ValidateRect(hwnd, &(ps.rcPaint));
+ }
+ else
+#endif
/* Try to copy from the shadow buffer */
if (!BitBlt (hdcUpdate,
ps.rcPaint.left, ps.rcPaint.top,
@@ -1112,3 +1126,42 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
winReorderWindowsMultiWindow();
return ret;
}
+
+/*
+ * winChildWindowProc - Window procedure for all top-level Windows windows.
+ */
+
+LRESULT CALLBACK
+winChildWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+#if CYGDEBUG
+ winDebugWin32Message("winChildWindowProc", hwnd, message, wParam, lParam);
+#endif
+
+ switch (message)
+ {
+ case WM_ERASEBKGND:
+ return TRUE;
+
+ case WM_PAINT:
+ /*
+ We don't have the bits to draw into the window, they went straight into the OpenGL
+ surface
+
+ XXX: For now, just leave it alone, but ideally we want to send an expose event to
+ the window so it really redraws the affected region...
+ */
+ {
+ PAINTSTRUCT ps;
+ HDC hdcUpdate;
+ hdcUpdate = BeginPaint(hwnd, &ps);
+ ValidateRect(hwnd, &(ps.rcPaint));
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ /* XXX: this is exactly what DefWindowProc does? */
+ }
+
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 6a8d91c1e..f3105265e 100755
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -284,7 +284,7 @@ winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
strcat (pszClass, pszWindowID);
#if CYGMULTIWINDOW_DEBUG
- winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
+ winDebug ("winMWExtWMCreateFrame - Creating class: %s\n", pszClass);
#endif
/* Setup our window class */
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index ebe43091f..d12f1d5ce 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -49,6 +49,7 @@
#define WINDOW_TITLE_XDMCP "%s:%s.%d"
#define WIN_SCR_PROP "cyg_screen_prop rl"
#define WINDOW_CLASS_X "cygwin/x X rl"
+#define WINDOW_CLASS_X_CHILD "cygwin/x X child"
#define WINDOW_TITLE_X PROJECT_NAME " X"
#define WIN_WINDOW_PROP "cyg_window_prop_rl"
#ifdef HAS_DEVWINDOWS
@@ -80,6 +81,9 @@ typedef struct
winPrivScreenPtr pScreenPriv;
Bool fXKilled;
HDWP hDwp;
+#ifdef XWIN_GLX_WINDOWS
+ Bool fWglUsed;
+#endif
/* Privates used by primary fb DirectDraw server */
LPDDSURFACEDESC pddsdPrimary;