aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/glx/indirect.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/glx/indirect.c')
-rw-r--r--xorg-server/hw/xwin/glx/indirect.c587
1 files changed, 399 insertions, 188 deletions
diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c
index 3f34146e5..9dd9660ce 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,14 +120,17 @@ 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;
@@ -146,7 +156,9 @@ struct __GLXWinScreen {
/* wrapped screen functions */
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
+ DestroyWindowProcPtr DestroyWindow;
CopyWindowProcPtr CopyWindow;
+ PositionWindowProcPtr PositionWindow;
};
struct __GLXWinConfig {
@@ -159,12 +171,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 };
@@ -212,6 +246,7 @@ glxWinInitDebugSettings(void)
glxWinDebugSettings.enableWGLcallTrace = 1;
}
}
+#endif
static
const char *
@@ -238,6 +273,8 @@ glxWinErrorMessage(void)
static void pfdOut(const PIXELFORMATDESCRIPTOR * pfd);
+#ifdef _DEBUG
+
#define DUMP_PFD_FLAG(flag) \
if (pfd->dwFlags & flag) { \
ErrorF("%s%s", pipesym, #flag); \
@@ -389,6 +426,7 @@ fbConfigsDump(unsigned int n, __GLXconfig * c)
c = c->next;
}
}
+#endif
/* ---------------------------------------------------------------------- */
/*
@@ -410,11 +448,13 @@ 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);
+ HWND * hwnd);
static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable * draw);
static void glxWinCreateConfigs(HDC dc, glxWinScreen * screen);
@@ -440,6 +480,7 @@ __GLXprovider __glXWGLProvider = {
void
glxWinPushNativeProvider(void)
{
+ if (g_fNativeGl)
GlxPushProvider(&__glXWGLProvider);
}
@@ -468,6 +509,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
*/
@@ -486,7 +537,8 @@ glxLogExtensions(const char *prefix, const char *extensions)
strl = strtok(str, " ");
if (strl == NULL)
strl = "";
- ErrorF("%s%s", prefix, strl);
+ winDebug("%s%s", prefix, strl);
+
length = strlen(prefix) + strlen(strl);
while (1) {
@@ -495,20 +547,20 @@ glxLogExtensions(const char *prefix, const char *extensions)
break;
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);
}
@@ -527,7 +579,9 @@ glxWinScreenProbe(ScreenPtr pScreen)
GLWIN_DEBUG_MSG("glxWinScreenProbe");
+#ifdef _DEBUG
glxWinInitDebugSettings();
+#endif
if (pScreen == NULL)
return NULL;
@@ -546,24 +600,23 @@ glxWinScreenProbe(ScreenPtr pScreen)
/* 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);
}
@@ -571,7 +624,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);
@@ -584,16 +637,20 @@ 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));
+ winDebug("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION));
+ winDebug("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR));
gl_renderer = (const char *) glGetStringWrapperNonstatic(GL_RENDERER);
- ErrorF("GL_RENDERER: %s\n", gl_renderer);
+ winDebug("GL_RENDERER: %s\n", gl_renderer);
gl_extensions = (const char *) glGetStringWrapperNonstatic(GL_EXTENSIONS);
glxLogExtensions("GL_EXTENSIONS: ", gl_extensions);
wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
@@ -767,8 +824,10 @@ glxWinScreenProbe(ScreenPtr pScreen)
ReleaseDC(hwnd, hdc);
DestroyWindow(hwnd);
+#ifdef _DEBUG
// dump out fbConfigs now fbConfigIds and visualIDs have been assigned
fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs);
+#endif
/* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */
screen->RealizeWindow = pScreen->RealizeWindow;
@@ -777,6 +836,10 @@ 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;
return &screen->base;
}
@@ -792,6 +855,7 @@ glxWinRealizeWindow(WindowPtr pWin)
Bool result;
ScreenPtr pScreen = pWin->drawable.pScreen;
glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+ winWindowPriv(pWin);
GLWIN_DEBUG_MSG("glxWinRealizeWindow");
@@ -799,7 +863,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;
}
@@ -832,20 +901,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;
}
@@ -858,8 +999,6 @@ glxWinUnrealizeWindow(WindowPtr pWin)
static GLboolean
glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable * base)
{
- HDC dc;
- HWND hwnd;
BOOL ret;
__GLXWinDrawable *draw = (__GLXWinDrawable *) base;
@@ -880,13 +1019,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) {
ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage());
@@ -940,6 +1073,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");
@@ -954,13 +1088,11 @@ glxWinCreateDrawable(ClientPtr client,
{
__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);
@@ -1030,28 +1162,25 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
__GLXconfig *config = gc->base.config;
GLXWinConfig *winConfig = (GLXWinConfig *) config;
- 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;
+ 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
+ */
+ /*
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:
@@ -1083,8 +1212,10 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
return FALSE;
}
+#ifdef _DEBUG
if (glxWinDebugSettings.dumpPFD)
pfdOut(&pfd);
+#endif
if (bppOverride) {
GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n",
@@ -1104,6 +1235,7 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
("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());
return FALSE;
@@ -1113,31 +1245,60 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
int pixelFormat =
fbConfigToPixelFormatIndex(hdc, gc->base.config,
drawableTypeOverride, winScreen);
- 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);
+ if (pixelFormat != 0) {
+ GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
- if (!SetPixelFormat(hdc, pixelFormat, NULL)) {
+ 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) {
@@ -1164,45 +1325,53 @@ glxWinMakeDC(__GLXWinContext * gc, __GLXWinDrawable * draw, HDC * hdc,
return NULL;
}
- *hdc = GetDC(*hwnd);
+ if (!gc->hDC)
+ {
+ winWindowPriv(pWin);
+
+ hdc = GetDC(*hwnd);
- if (*hdc == NULL)
- ErrorF("GetDC error: %s\n", glxWinErrorMessage());
+ 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);
- /* Check if the hwnd has changed... */
- if (*hwnd != 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;
@@ -1213,10 +1382,12 @@ glxWinMakeDC(__GLXWinContext * gc, __GLXWinDrawable * draw, HDC * hdc,
}
}
+#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
@@ -1259,7 +1430,6 @@ glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable * draw)
static void
glxWinDeferredCreateContext(__GLXWinContext * gc, __GLXWinDrawable * draw)
{
- HDC dc;
HWND hwnd;
GLWIN_DEBUG_MSG
@@ -1292,13 +1462,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)) {
ErrorF
@@ -1310,7 +1483,7 @@ glxWinDeferredCreateContext(__GLXWinContext * gc, __GLXWinDrawable * draw)
pixelFormat =
fbConfigToPixelFormatIndex(screenDC, gc->base.config,
- GLX_DRAWABLE_PBUFFER, winScreen);
+ GLX_PBUFFER_BIT, winScreen);
if (pixelFormat == 0) {
ErrorF("wglChoosePixelFormat error: %s\n",
glxWinErrorMessage());
@@ -1321,7 +1494,6 @@ glxWinDeferredCreateContext(__GLXWinContext * gc, __GLXWinDrawable * draw)
wglCreatePbufferARBWrapper(screenDC, pixelFormat,
draw->base.pDraw->width,
draw->base.pDraw->height, NULL);
- ReleaseDC(NULL, screenDC);
if (draw->hPbuffer == NULL) {
ErrorF("wglCreatePbufferARBWrapper error: %s\n",
@@ -1376,6 +1548,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) {
@@ -1403,11 +1577,12 @@ 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;
}
@@ -1417,7 +1592,7 @@ glxWinDeferredCreateContext(__GLXWinContext * gc, __GLXWinDrawable * draw)
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);
@@ -1439,34 +1614,25 @@ glxWinContextMakeCurrent(__GLXcontext * base)
{
__GLXWinContext *gc = (__GLXWinContext *) base;
BOOL ret;
- HDC drawDC;
- HDC readDC = NULL;
- __GLXdrawable *drawPriv;
- __GLXdrawable *readPriv = NULL;
- HWND hDrawWnd;
- HWND hReadWnd;
-
- GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc,
- gc->ctx);
+ __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);
}
+ _glapi_set_dispatch(gc->Dispatch);
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;
}
@@ -1477,16 +1643,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());
@@ -1494,18 +1659,27 @@ glxWinContextMakeCurrent(__GLXcontext * base)
}
else {
/* Otherwise, just use wglMakeCurrent */
- ret = wglMakeCurrent(drawDC, gc->ctx);
- if (!ret) {
- ErrorF("wglMakeCurrent error: %s\n", glxWinErrorMessage());
+ 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) {
+ 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;
}
@@ -1513,25 +1687,34 @@ glxWinContextMakeCurrent(__GLXcontext * base)
static int
glxWinContextLoseCurrent(__GLXcontext * base)
{
- BOOL ret;
+ BOOL ret=TRUE;
__GLXWinContext *gc = (__GLXWinContext *) base;
+ __GLXWinDrawable *drawPriv = (__GLXWinDrawable *)gc->base.drawPriv;
- GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc,
- gc->ctx);
+#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 */
+ if (drawPriv) drawPriv->drawContext = NULL;
+
+ 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;
}
- return TRUE;
+ base->isCurrent=FALSE; /* It looks like glx is not doing this */
+ _glapi_set_dispatch(NULL);
+
+ return ret;
}
static int
@@ -1558,27 +1741,35 @@ glxWinContextDestroy(__GLXcontext * base)
__GLXWinContext *gc = (__GLXWinContext *) 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());
- }
+ 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);
+ _glapi_set_dispatch(NULL);
}
}
@@ -1610,9 +1801,12 @@ 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();
GLWIN_DEBUG_MSG("GLXcontext %p created", context);
@@ -1625,6 +1819,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)
@@ -1661,16 +1866,26 @@ fbConfigToPixelFormat(__GLXconfig * mode, PIXELFORMATDESCRIPTOR * pfdret,
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 +
@@ -1843,8 +2058,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)) {
@@ -1910,25 +2127,24 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen)
/* EXT_visual_info / GLX 1.2 */
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;
- }
- }
- else {
- c->base.visualType = GLX_TRUE_COLOR;
+ 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;
@@ -2130,7 +2346,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;
@@ -2180,14 +2399,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: