diff options
Diffstat (limited to 'xorg-server/hw/xwin/glx/indirect.c')
-rw-r--r-- | xorg-server/hw/xwin/glx/indirect.c | 576 |
1 files changed, 396 insertions, 180 deletions
diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c index 86fef55d1..7dc5f31b7 100644 --- a/xorg-server/hw/xwin/glx/indirect.c +++ b/xorg-server/hw/xwin/glx/indirect.c @@ -83,9 +83,16 @@ #include <glx/glxutil.h> #include <glx/extension_string.h> #include <GL/glxtokens.h> +#include <glx/glapitable.h> +#include <glx/glapi.h> #include <winpriv.h> #include <wgl_ext_api.h> +#include "win.h" +#include <winmsg.h> + +extern Bool g_fXdmcpEnabled; +extern Bool g_fNativeGl; #define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1])) @@ -113,15 +120,18 @@ typedef struct __GLXWinConfig GLXWinConfig; struct __GLXWinContext { __GLXcontext base; HGLRC ctx; /* Windows GL Context */ + HDC hDC; /* Windows device context */ + HDC hreadDC; /* Windows device read context */ __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */ HWND hwnd; /* For detecting when HWND has changed */ + HWND hreadwnd; + struct _glapi_table *Dispatch; }; struct __GLXWinDrawable { __GLXdrawable base; __GLXWinContext *drawContext; - __GLXWinContext *readContext; /* If this drawable is GLX_DRAWABLE_PBUFFER */ HPBUFFERARB hPbuffer; @@ -148,7 +158,9 @@ struct __GLXWinScreen /* wrapped screen functions */ RealizeWindowProcPtr RealizeWindow; UnrealizeWindowProcPtr UnrealizeWindow; + DestroyWindowProcPtr DestroyWindow; CopyWindowProcPtr CopyWindow; + PositionWindowProcPtr PositionWindow; }; struct __GLXWinConfig @@ -162,12 +174,34 @@ struct __GLXWinConfig * Various debug helpers */ -#define GLWIN_DEBUG_HWND(hwnd) \ - if (glxWinDebugSettings.dumpHWND) { \ - char buffer[1024]; \ - if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; \ - GLWIN_DEBUG_MSG("Got HWND %p for window '%s'", hwnd, buffer); \ - } +#ifdef _DEBUG +void GLWIN_DEBUG_HWND(HWND hwnd) +{ + if (glxWinDebugSettings.dumpHWND) + { + char buffer[1024]; + RECT Rect; + HDC hDc=GetDC(hwnd); + + if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; + GetWindowRect(hwnd,&Rect); + + GLWIN_DEBUG_MSG("Got HWND %p (hdc %p) for window '%s' (%d,%d,%d,%d)", hwnd, hDc, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom); + ReleaseDC(hwnd,hDc); + } +} + +void GLWIN_HDC_DEBUG_MSG(const char *Message, HDC hDc, HWND hwnd) +{ + char buffer[1024]; + RECT Rect; + + if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; + GetWindowRect(hwnd,&Rect); + + GLWIN_DEBUG_MSG("Got HDC %p (hwnd %p) for window '%s' (%d,%d,%d,%d)", hDc, hwnd, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom); + +} glxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0}; @@ -215,6 +249,7 @@ static void glxWinInitDebugSettings(void) glxWinDebugSettings.enableWGLcallTrace = 1; } } +#endif static const char *glxWinErrorMessage(void) @@ -244,6 +279,8 @@ const char *glxWinErrorMessage(void) static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd); +#ifdef _DEBUG + #define DUMP_PFD_FLAG(flag) \ if (pfd->dwFlags & flag) { \ ErrorF("%s%s", pipesym, #flag); \ @@ -391,6 +428,7 @@ fbConfigsDump(unsigned int n, __GLXconfig *c) c = c->next; } } +#endif /* ---------------------------------------------------------------------- */ /* @@ -411,9 +449,11 @@ static __GLXdrawable *glxWinCreateDrawable(ClientPtr client, static Bool glxWinRealizeWindow(WindowPtr pWin); static Bool glxWinUnrealizeWindow(WindowPtr pWin); +static Bool glxWinDestroyWindow(WindowPtr pWin); static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc); +static Bool glxWinPositionWindow(WindowPtr pWindow, int x, int y); -static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd); +static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd); static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw); static void glxWinCreateConfigs(HDC dc, glxWinScreen *screen); @@ -435,7 +475,8 @@ __GLXprovider __glXWGLProvider = { void glxWinPushNativeProvider(void) { - GlxPushProvider(&__glXWGLProvider); + if (g_fNativeGl) + GlxPushProvider(&__glXWGLProvider); } /* ---------------------------------------------------------------------- */ @@ -462,6 +503,16 @@ glxWinScreenSwapInterval(__GLXdrawable *drawable, int interval) return ret; } +static LRESULT CALLBACK GlxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg== WM_NCHITTEST) + { + return HTTRANSPARENT; + } + else + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + /* Report the extensions split and formatted to avoid overflowing a line */ @@ -479,7 +530,7 @@ glxLogExtensions(const char *prefix, const char *extensions) } strl = strtok(str, " "); - ErrorF("%s%s", prefix, strl); + winDebug("%s%s", prefix, strl); length = strlen(prefix) + strlen(strl); while (1) @@ -489,21 +540,21 @@ glxLogExtensions(const char *prefix, const char *extensions) if (length + strlen(strl) + 1 > 120) { - ErrorF("\n"); - ErrorF("%s",prefix); + winDebug("\n"); + winDebug("%s",prefix); length = strlen(prefix); } else { - ErrorF(" "); + winDebug(" "); length++; } - ErrorF("%s", strl); + winDebug("%s", strl); length = length + strlen(strl); } - ErrorF("\n"); + winDebug("\n"); free(str); } @@ -521,7 +572,9 @@ glxWinScreenProbe(ScreenPtr pScreen) GLWIN_DEBUG_MSG("glxWinScreenProbe"); +#ifdef _DEBUG glxWinInitDebugSettings(); +#endif if (pScreen == NULL) return NULL; @@ -544,27 +597,31 @@ glxWinScreenProbe(ScreenPtr pScreen) pScreen->UnrealizeWindow = glxWinUnrealizeWindow; screen->CopyWindow = pScreen->CopyWindow; pScreen->CopyWindow = glxWinCopyWindow; + screen->PositionWindow = pScreen->PositionWindow; + pScreen->PositionWindow = glxWinPositionWindow; + screen->DestroyWindow = pScreen->DestroyWindow; + pScreen->DestroyWindow = glxWinDestroyWindow; /* Dump out some useful information about the native renderer */ // create window class -#define WIN_GL_TEST_WINDOW_CLASS "XWinGLTest" { static wATOM glTestWndClass = 0; if (glTestWndClass == 0) { WNDCLASSEX wc; + glTestWndClass=1; wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = DefWindowProc; + wc.style = CS_OWNDC ; + wc.lpfnWndProc = GlxWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); + wc.hInstance = g_hInstance; wc.hIcon = 0; wc.hCursor = 0; - wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wc.hbrBackground = 0; wc.lpszMenuName = NULL; - wc.lpszClassName = WIN_GL_TEST_WINDOW_CLASS; + wc.lpszClassName = WIN_GL_WINDOW_CLASS; wc.hIconSm = 0; RegisterClassEx (&wc); } @@ -572,7 +629,7 @@ glxWinScreenProbe(ScreenPtr pScreen) // create an invisible window for a scratch DC hwnd = CreateWindowExA(0, - WIN_GL_TEST_WINDOW_CLASS, + WIN_GL_WINDOW_CLASS, "XWin GL Renderer Capabilities Test Window", 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); if (hwnd == NULL) @@ -583,15 +640,19 @@ glxWinScreenProbe(ScreenPtr pScreen) // we must set a pixel format before we can create a context, just use the first one... SetPixelFormat(hdc, 1, NULL); hglrc = wglCreateContext(hdc); - wglMakeCurrent(hdc, hglrc); + if (!wglMakeCurrent(hdc, hglrc)) + { + DWORD ErrorCode=GetLastError(); + ErrorF("wglMakeCurrent error: %x dc %p ctx %p\n", ErrorCode,hdc,hglrc); + } // initialize wgl extension proc pointers (don't call them before here...) // (but we need to have a current context for them to be resolvable) wglResolveExtensionProcs(); - ErrorF("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION)); - ErrorF("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR)); - ErrorF("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER)); + winDebug("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION)); + winDebug("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR)); + winDebug("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER)); gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS); glxLogExtensions("GL_EXTENSIONS: ", gl_extensions); wgl_extensions = wglGetExtensionsStringARBWrapper(hdc); @@ -715,8 +776,10 @@ glxWinScreenProbe(ScreenPtr pScreen) __glXScreenInit(&screen->base, pScreen); +#ifdef _DEBUG // dump out fbConfigs now fbConfigIds and visualIDs have been assigned fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs); +#endif // Override the GL extensions string set by __glXScreenInit() screen->base.GLextensions = strdup(gl_extensions); @@ -775,6 +838,7 @@ glxWinRealizeWindow(WindowPtr pWin) Bool result; ScreenPtr pScreen = pWin->drawable.pScreen; glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); + winWindowPriv(pWin); GLWIN_DEBUG_MSG("glxWinRealizeWindow"); @@ -782,7 +846,12 @@ glxWinRealizeWindow(WindowPtr pWin) pScreen->RealizeWindow = screenPriv->RealizeWindow; result = pScreen->RealizeWindow(pWin); pScreen->RealizeWindow = glxWinRealizeWindow; - + + // Check if ze need to move the window\n + if (pWinPriv->fWglUsed && pWinPriv->hWnd) + { + ShowWindow(pWinPriv->hWnd,SW_SHOWNOACTIVATE); + } return result; } @@ -818,20 +887,92 @@ glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) pScreen->CopyWindow = screenPriv->CopyWindow; pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc); pScreen->CopyWindow = glxWinCopyWindow; + +} + +static Bool +glxWinPositionWindow(WindowPtr pWin, int x, int y) +{ + Bool result; + ScreenPtr pScreen = pWin->drawable.pScreen; + glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); + winWindowPriv(pWin); + + pScreen->PositionWindow = screenPriv->PositionWindow; + result = pScreen->PositionWindow(pWin, x, y); + pScreen->PositionWindow = glxWinPositionWindow; + + if (pWinPriv->fWglUsed && pWinPriv->hWnd) + { + MoveWindow(pWinPriv->hWnd, + pWin->drawable.x, + pWin->drawable.y, + pWin->drawable.width, + pWin->drawable.height, + FALSE); + winDebug("Move window %x, %x, %d, %d, %d, %d\n",pWinPriv->hWnd,GetParent(pWinPriv->hWnd), pWin->drawable.x, pWin->drawable.y, pWin->drawable.width, pWin->drawable.height); + } + return result; } + static Bool glxWinUnrealizeWindow(WindowPtr pWin) { Bool result; ScreenPtr pScreen = pWin->drawable.pScreen; glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen); + winWindowPriv(pWin); GLWIN_DEBUG_MSG("glxWinUnrealizeWindow"); - pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow; - result = pScreen->UnrealizeWindow(pWin); - pScreen->UnrealizeWindow = glxWinUnrealizeWindow; + if (pWinPriv->fWglUsed && pWinPriv->hWnd) + { + ShowWindow(pWinPriv->hWnd,SW_HIDE); + result = TRUE; + } + else + { + pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow; + result = pScreen->UnrealizeWindow(pWin); + pScreen->UnrealizeWindow = glxWinUnrealizeWindow; + } + + + return result; +} + +static Bool +glxWinDestroyWindow(WindowPtr pWin) +{ + Bool result; + ScreenPtr pScreen = pWin->drawable.pScreen; + glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen); + __GLXWinDrawable *pGlxDraw; + winWindowPriv(pWin); + + GLWIN_DEBUG_MSG("glxWinDestroyWindow"); + + dixLookupResourceByType((pointer) &pGlxDraw, pWin->drawable.id, __glXDrawableRes, NullClient, DixUnknownAccess); + + if (pGlxDraw && pGlxDraw->drawContext) + { + if (pGlxDraw->drawContext->hwnd!=pWinPriv->hWnd) + ErrorF("Wrong assumption\n"); + glxWinReleaseDC(pGlxDraw->drawContext->hwnd, pGlxDraw->drawContext->hDC, pGlxDraw); + pGlxDraw->drawContext->hDC=NULL; + pGlxDraw->drawContext->hwnd=NULL; + } + if (pWinPriv->fWglUsed && pWinPriv->hWnd) + { + DestroyWindow(pWinPriv->hWnd); + pWinPriv->hWnd=NULL; + pWinPriv->fWglUsed=0; + } + + pScreen->DestroyWindow = screenPriv->DestroyWindow; + result = pScreen->DestroyWindow(pWin); + pScreen->DestroyWindow = glxWinDestroyWindow; return result; } @@ -844,8 +985,6 @@ glxWinUnrealizeWindow(WindowPtr pWin) static GLboolean glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base) { - HDC dc; - HWND hwnd; BOOL ret; __GLXWinDrawable *draw = (__GLXWinDrawable *)base; @@ -864,13 +1003,7 @@ glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base) */ assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base)); - dc = glxWinMakeDC(draw->drawContext, draw, &dc, &hwnd); - if (dc == NULL) - return GL_FALSE; - - ret = wglSwapLayerBuffers(dc, WGL_SWAP_MAIN_PLANE); - - glxWinReleaseDC(hwnd, dc, draw); + ret = SwapBuffers(draw->drawContext->hDC); if (!ret) { @@ -930,6 +1063,7 @@ glxWinDrawableDestroy(__GLXdrawable *base) } ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits; + glxPriv->base.pDraw->pScreen->DestroyPixmap((PixmapPtr)glxPriv->base.pDraw); /* Decrement reference count since we do not use it any more */ } GLWIN_DEBUG_MSG("glxWinDestroyDrawable"); @@ -938,22 +1072,20 @@ glxWinDrawableDestroy(__GLXdrawable *base) static __GLXdrawable * glxWinCreateDrawable(ClientPtr client, - __GLXscreen *screen, - DrawablePtr pDraw, - XID drawId, - int type, - XID glxDrawId, - __GLXconfig *conf) + __GLXscreen *screen, + DrawablePtr pDraw, + XID drawId, + int type, + XID glxDrawId, + __GLXconfig *conf) { __GLXWinDrawable *glxPriv; - glxPriv = malloc(sizeof *glxPriv); + glxPriv = calloc(1,sizeof(*glxPriv)); if (glxPriv == NULL) return NULL; - memset(glxPriv, 0, sizeof *glxPriv); - if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) { free(glxPriv); return NULL; @@ -1021,25 +1153,24 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable __GLXconfig *config = gc->base.config; GLXWinConfig *winConfig = (GLXWinConfig *)config; + + WindowPtr pWin; + __GLXWinDrawable *drawPriv = (__GLXWinDrawable *)gc->base.drawPriv; + pWin = (WindowPtr) drawPriv->base.pDraw; + { + winWindowPriv(pWin); + if (pWinPriv->OpenGlWindow) + { + ErrorF("Not Setting pixel format to %d on hdc %x for window %x (not allowed on windows)\n",winConfig->pixelFormatIndex,hdc,pWinPriv->hWnd); + return TRUE; /* Pixel format is already set on this window so it cannot be changed anymore */ + } + } GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex); /* Normally, we can just use the the pixelFormatIndex corresponding to the fbconfig which has been specified by the client */ - - if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) )) - || ((config->drawableType & drawableTypeOverride) == 0))) - { - if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL)) - { - ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return FALSE; - } - - return TRUE; - } - /* However, in certain special cases this pixel format will be incompatible with the use we are going to put it to, so we need to re-evaluate the pixel format to use: @@ -1072,8 +1203,10 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable return FALSE; } - if (glxWinDebugSettings.dumpPFD) +#ifdef _DEBUG + if (glxWinDebugSettings.dumpPFD) pfdOut(&pfd); +#endif if (bppOverride) { @@ -1091,6 +1224,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); + ErrorF("Setting pixel format 2 to %d on hdc %x\n",pixelFormat,hdc); if (!SetPixelFormat(hdc, pixelFormat, &pfd)) { ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); @@ -1100,29 +1234,62 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable else { int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen); - if (pixelFormat == 0) + if (pixelFormat != 0) { - ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); - return FALSE; - } - - GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); - ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); + GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); - if (!SetPixelFormat(hdc, pixelFormat, NULL)) - { - ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return FALSE; + ErrorF("Setting pixel format 3 to %d on hdc %x\n",pixelFormat,hdc); + if (!SetPixelFormat(hdc, pixelFormat, NULL)) + { + ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); + return FALSE; + } + return TRUE; } + else + { + /* There was an error choose some default for the moment */ + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 32, // 32-bit z-buffer + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + int iPixelFormat; + + // get the best available match of pixel format for the device context + iPixelFormat = ChoosePixelFormat(hdc, &pfd); + + ErrorF("Setting pixel format 4 to %d on hdc %x\n",iPixelFormat,hdc); + // make that the pixel format of the device context + if (!SetPixelFormat(hdc, iPixelFormat, &pfd)) + { + ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); + return FALSE; + } + } } - return TRUE; } static HDC -glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd) +glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd) { - *hdc = NULL; + HDC hdc = NULL; *hwnd = NULL; if (draw == NULL) @@ -1152,44 +1319,51 @@ glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd) return NULL; } - *hdc = GetDC(*hwnd); + if (!gc->hDC) + { + winWindowPriv(pWin); - if (*hdc == NULL) - ErrorF("GetDC error: %s\n", glxWinErrorMessage()); + hdc = GetDC(*hwnd); - /* Check if the hwnd has changed... */ - if (*hwnd != gc->hwnd) - { - if (glxWinDebugSettings.enableTrace) + if (hdc == NULL) + ErrorF("GetDC error: %s: hwnd %x, gc %p, gc->ctx %p ,gc->hwnd %p\n", glxWinErrorMessage(), *hwnd, gc, gc->ctx, gc->hwnd); + + glxWinSetPixelFormat(gc, hdc, 0, GLX_WINDOW_BIT); + pWinPriv->OpenGlWindow=TRUE; /* Identify it as an opengl window, also used to check if the pixel format is already set */ + gc->ctx = wglCreateContext(hdc); + } + +#ifdef _DEBUG + if (glxWinDebugSettings.enableTrace) GLWIN_DEBUG_HWND(*hwnd); GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, *hwnd); - gc->hwnd = *hwnd; +#endif + if (gc->hwnd!=*hwnd) + ErrorF("Window changed handle from %x to %x\n", gc->hwnd, *hwnd); - /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */ - if (!glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT)) - { - ErrorF("glxWinSetPixelFormat error: %s\n", glxWinErrorMessage()); - ReleaseDC(*hwnd, *hdc); - *hdc = NULL; - return NULL; - } - } + gc->hwnd = *hwnd; } break; case GLX_DRAWABLE_PBUFFER: { - *hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer); + hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer); - if (*hdc == NULL) + if (hdc == NULL) ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage()); + + gc->ctx = wglCreateContext(hdc); } break; case GLX_DRAWABLE_PIXMAP: { - *hdc = draw->dibDC; + hdc = draw->dibDC; +#ifdef _DEBUG + if (glxWinDebugSettings.dumpDC) + GLWIN_DEBUG_MSG("Got PIXMAP HDC %p for window %p", hdc, *hwnd); +#endif } break; @@ -1199,10 +1373,12 @@ glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd) } } +#ifdef _DEBUG if (glxWinDebugSettings.dumpDC) - GLWIN_DEBUG_MSG("Got HDC %p", *hdc); + GLWIN_HDC_DEBUG_MSG("Got HDC %p for window %p", hdc, *hwnd); +#endif - return *hdc; + return hdc; } static void @@ -1245,7 +1421,6 @@ glxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw) static void glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) { - HDC dc; HWND hwnd; GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw); @@ -1278,13 +1453,16 @@ glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) case GLX_DRAWABLE_PBUFFER: { + WindowPtr pWin = (WindowPtr) draw->base.pDraw; if (draw->hPbuffer == NULL) { __GLXscreen *screen; glxWinScreen *winScreen; int pixelFormat; // XXX: which DC are supposed to use??? - HDC screenDC = GetDC(NULL); + ScreenPtr pScreen = pWin->drawable.pScreen; + winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); + HDC screenDC=pWinScreen->hdcScreen; if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT)) { @@ -1294,7 +1472,7 @@ glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) screen = gc->base.pGlxScreen; winScreen = (glxWinScreen *)screen; - pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen); + pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_PBUFFER_BIT, winScreen); if (pixelFormat == 0) { ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); @@ -1302,7 +1480,6 @@ glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) } draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL); - ReleaseDC(NULL, screenDC); if (draw->hPbuffer == NULL) { @@ -1356,6 +1533,8 @@ glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr; ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits; + ((PixmapPtr)draw->base.pDraw)->refcnt++; /* Increment reference count to be sure it is not freed before the glxdrawable is destroyed */ + // Select the DIB into the DC draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB); if (!draw->hOldDIB) @@ -1378,12 +1557,13 @@ glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) } } - dc = glxWinMakeDC(gc, draw, &dc, &hwnd); - gc->ctx = wglCreateContext(dc); - glxWinReleaseDC(hwnd, dc, draw); + gc->hDC = glxWinMakeDC(gc, draw, &hwnd); if (gc->ctx == NULL) { + glxWinReleaseDC(hwnd, gc->hDC, draw); + gc->hDC=0; + ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage()); return; } @@ -1391,7 +1571,7 @@ glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw); // if the native context was created successfully, shareLists if needed - if (gc->ctx && gc->shareContext) + if (gc->ctx && gc->shareContext && gc->shareContext->ctx) { GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx); @@ -1414,35 +1594,26 @@ glxWinContextMakeCurrent(__GLXcontext *base) { __GLXWinContext *gc = (__GLXWinContext *)base; BOOL ret; - HDC drawDC; - HDC readDC = NULL; - __GLXdrawable *drawPriv; - __GLXdrawable *readPriv = NULL; - HWND hDrawWnd; - HWND hReadWnd; + __GLXWinDrawable *drawPriv; +#ifdef _DEBUG GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx); glWinCallDelta(); +#endif /* Keep a note of the last active context in the drawable */ - drawPriv = gc->base.drawPriv; - ((__GLXWinDrawable *)drawPriv)->drawContext = gc; + drawPriv = (__GLXWinDrawable *)gc->base.drawPriv; + drawPriv->drawContext = gc; if (gc->ctx == NULL) { - glxWinDeferredCreateContext(gc, (__GLXWinDrawable *)drawPriv); + glxWinDeferredCreateContext(gc, drawPriv); } if (gc->ctx == NULL) { ErrorF("glxWinContextMakeCurrent: Native context is NULL\n"); - return FALSE; - } - - drawDC = glxWinMakeDC(gc, (__GLXWinDrawable *)drawPriv, &drawDC, &hDrawWnd); - if (drawDC == NULL) - { - ErrorF("glxWinMakeDC failed for drawDC\n"); + drawPriv->drawContext = NULL; /* clear last active context because we return error */ return FALSE; } @@ -1454,16 +1625,15 @@ glxWinContextMakeCurrent(__GLXcontext *base) use the wglMakeContextCurrent extension to make the context current drawing to one DC and reading from the other */ - readPriv = gc->base.readPriv; - readDC = glxWinMakeDC(gc, (__GLXWinDrawable *)readPriv, &readDC, &hReadWnd); - if (readDC == NULL) + gc->hreadDC = glxWinMakeDC(gc, (__GLXWinDrawable *)gc->base.readPriv, &gc->hreadwnd); + if (gc->hreadDC == NULL) { ErrorF("glxWinMakeDC failed for readDC\n"); - glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv); + drawPriv->drawContext = NULL; /* clear last active context because we return error */ return FALSE; } - ret = wglMakeContextCurrentARBWrapper(drawDC, readDC, gc->ctx); + ret = wglMakeContextCurrentARBWrapper(gc->hDC, gc->hreadDC, gc->ctx); if (!ret) { ErrorF("wglMakeContextCurrentARBWrapper error: %s\n", glxWinErrorMessage()); @@ -1472,19 +1642,28 @@ glxWinContextMakeCurrent(__GLXcontext *base) else { /* Otherwise, just use wglMakeCurrent */ - ret = wglMakeCurrent(drawDC, gc->ctx); + if (!gc->hDC) + { + /* It probably has been release by loseCurrent, so create it again */ + gc->hDC = glxWinMakeDC(gc, drawPriv, &gc->hwnd); + } + ret = wglMakeCurrent(gc->hDC, gc->ctx); if (!ret) { - ErrorF("wglMakeCurrent error: %s\n", glxWinErrorMessage()); + DWORD ErrorCode=GetLastError(); + ErrorF("wglMakeCurrent error: %x dc %p ctx %p\n", ErrorCode,gc->hDC,gc->ctx); + if (!ErrorCode) + { + ErrorF("Error code was 0, assuming no error.\n"); + ret=TRUE; + } } } // apparently make current could fail if the context is current in a different thread, // but that shouldn't be able to happen in the current server... - - glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv); - if (readDC) - glxWinReleaseDC(hReadWnd, readDC, (__GLXWinDrawable *)readPriv); + if (!ret) + drawPriv->drawContext = NULL; /* clear last active context because we return error */ return ret; } @@ -1492,24 +1671,33 @@ glxWinContextMakeCurrent(__GLXcontext *base) static int glxWinContextLoseCurrent(__GLXcontext *base) { - BOOL ret; + BOOL ret=TRUE; __GLXWinContext *gc = (__GLXWinContext *)base; + __GLXWinDrawable *drawPriv = (__GLXWinDrawable *)gc->base.drawPriv; +#ifdef _DEBUG GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx); glWinCallDelta(); +#endif - /* - An error seems to be reported if we try to make no context current - if there is already no current context, so avoid doing that... - */ - if (__glXLastContext != NULL) - { - ret = wglMakeCurrent(NULL, NULL); /* We don't need a DC when setting no current context */ - if (!ret) - ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage()); - } + /* Clear the last active context in the drawable */ + drawPriv->drawContext = NULL; - return TRUE; + if (wglGetCurrentContext()==gc->ctx) + { + /* Only do this when we are sure we are currently the active, otherwise we are deactivating the wrong one (this is happening!!!) */ + ret = wglMakeCurrent(NULL, NULL); + if (!ret) + ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage()); + } + else + { + return FALSE; + } + + base->isCurrent=FALSE; /* It looks like glx is not doing this */ + + return ret; } static int @@ -1537,25 +1725,33 @@ glxWinContextDestroy(__GLXcontext *base) if (gc != NULL) { + __GLXWinDrawable *drawPriv = (__GLXWinDrawable *)gc->base.drawPriv; + GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx); if (gc->ctx) { + BOOL ret; /* It's bad style to delete the context while it's still current */ if (wglGetCurrentContext() == gc->ctx) - { - wglMakeCurrent(NULL, NULL); - } - { - BOOL ret = wglDeleteContext(gc->ctx); - if (!ret) - ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage()); + wglMakeCurrent(NULL, NULL); } + ret = wglDeleteContext(gc->ctx); + if (!ret) + ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage()); + if (drawPriv && gc->hDC) glxWinReleaseDC(gc->hwnd, gc->hDC, drawPriv); + if (gc->base.readPriv && gc->hreadDC) glxWinReleaseDC(gc->hreadwnd, gc->hreadDC, (__GLXWinDrawable *)gc->base.readPriv); + gc->hDC=NULL; + gc->hreadDC=NULL; gc->ctx = NULL; } + /* Clear the last active context in the drawable */ + if (drawPriv) drawPriv->drawContext = NULL; + + free(gc->Dispatch); free(gc); } } @@ -1589,8 +1785,11 @@ glxWinCreateContext(__GLXscreen *screen, context->base.pGlxScreen = screen; // actual native GL context creation is deferred until attach() - context->ctx = NULL; + //context->ctx = NULL; already done with memset context->shareContext = shareContext; + + context->Dispatch=calloc(sizeof(void*), (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS)); + _glapi_set_dispatch(context->Dispatch); glWinSetupDispatchTable(); @@ -1604,6 +1803,17 @@ glxWinCreateContext(__GLXscreen *screen, * Utility functions */ +static int GetShift(int Mask) +{ + int Shift=0; + while ((Mask&1)==0) + { + Shift++; + Mask>>=1; + } + return Shift; +} + static int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride) { @@ -1639,16 +1849,26 @@ fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int draw pfd.dwFlags |= PFD_DOUBLEBUFFER; } - pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits; pfd.cRedBits = mode->redBits; - pfd.cRedShift = 0; /* FIXME */ + pfd.cRedShift = GetShift(mode->redMask); pfd.cGreenBits = mode->greenBits; - pfd.cGreenShift = 0; /* FIXME */ + pfd.cGreenShift = GetShift(mode->greenMask); pfd.cBlueBits = mode->blueBits; - pfd.cBlueShift = 0; /* FIXME */ + pfd.cBlueShift = GetShift(mode->blueMask); pfd.cAlphaBits = mode->alphaBits; - pfd.cAlphaShift = 0; /* FIXME */ + pfd.cAlphaShift = GetShift(mode->alphaMask); + + if (mode->visualType = GLX_TRUE_COLOR) + { + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.dwVisibleMask = (pfd.cRedBits << pfd.cRedShift) | (pfd.cGreenBits << pfd.cGreenShift) | (pfd.cBlueBits << pfd.cBlueShift) | (pfd.cAlphaBits << pfd.cAlphaShift); + } + else + { + pfd.iPixelType = PFD_TYPE_COLORINDEX; + pfd.dwVisibleMask = mode->transparentIndex; + } pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits; pfd.cAccumRedBits = mode->accumRedBits; @@ -1814,8 +2034,10 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen *screen) break; } +#ifdef _DEBUG if (glxWinDebugSettings.dumpPFD) pfdOut(&pfd); +#endif if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) { @@ -1880,26 +2102,24 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen *screen) if (pfd.iPixelType == PFD_TYPE_COLORINDEX) { c->base.visualType = GLX_STATIC_COLOR; - - if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) - { - GLWIN_DEBUG_MSG("pixelFormat %d is PFD_TYPE_COLORINDEX, skipping", i+1); - continue; - } + c->base.transparentRed = GLX_NONE; + c->base.transparentGreen = GLX_NONE; + c->base.transparentBlue = GLX_NONE; + c->base.transparentAlpha = GLX_NONE; + c->base.transparentIndex = pfd.dwVisibleMask; + c->base.transparentPixel = GLX_TRANSPARENT_INDEX; } else { c->base.visualType = GLX_TRUE_COLOR; + c->base.transparentRed = (pfd.dwVisibleMask&c->base.redMask) >>pfd.cRedShift; + c->base.transparentGreen = (pfd.dwVisibleMask&c->base.greenMask)>>pfd.cGreenShift; + c->base.transparentBlue = (pfd.dwVisibleMask&c->base.blueMask) >>pfd.cBlueShift; + c->base.transparentAlpha = (pfd.dwVisibleMask&c->base.alphaMask)>>pfd.cAlphaShift; + c->base.transparentIndex = GLX_NONE; + c->base.transparentPixel = GLX_TRANSPARENT_RGB; } - // pfd.dwVisibleMask; ??? - c->base.transparentPixel = GLX_NONE; - c->base.transparentRed = GLX_NONE; - c->base.transparentGreen = GLX_NONE; - c->base.transparentBlue = GLX_NONE; - c->base.transparentAlpha = GLX_NONE; - c->base.transparentIndex = GLX_NONE; - /* ARB_multisample / SGIS_multisample */ c->base.sampleBuffers = 0; c->base.samples = 0; @@ -2101,7 +2321,10 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen) /* fill in configs */ for (i = 0; i < numConfigs; i++) { - int values[num_attrs]; + int sizevalues=num_attrs*sizeof(int); + int *values=(int*)_alloca(sizevalues); + + memset(values,0,sizevalues); c = &(result[i]); c->base.next = NULL; @@ -2140,13 +2363,6 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen) c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); c->base.rgbBits = 0; c->base.visualType = GLX_STATIC_COLOR; - - if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) - { - GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_COLORINDEX_ARB, skipping", i+1); - continue; - } - break; case WGL_TYPE_RGBA_FLOAT_ARB: |