xserver/GL/windows/indirect.c
Alexander Gottwald 596ca4e7e6 rename winErrorMessage to glWinErrorMessage print GetLastError() if
FormatMessage fails. This will at least give some information if the
    1024 byte buffer is to small for some messages
2004-04-27 21:19:21 +00:00

1519 lines
44 KiB
C
Executable file

/*
* GLX implementation that uses Windows OpenGL library
* (Indirect rendering path)
*
* Authors: Alexander Gottwald
*/
/*
* Portions of this file are copied from GL/apple/indirect.c,
* which contains the following copyright:
*
* Copyright (c) 2002 Greg Parker. All Rights Reserved.
* Copyright (c) 2002 Apple Computer, Inc.
*
* Portions of this file are copied from xf86glx.c,
* which contains the following copyright:
*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* 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 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 ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name(s) of the above copyright
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
#include "glwindows.h"
#include "../../hw/xwin/winpriv.h"
/* ggs: needed to call back to glx with visual configs */
extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **configprivs);
glWinDebugSettingsRec glWinDebugSettings = { 1, 0, 0, 0};
static void glWinInitDebugSettings(void)
{
char *envptr;
envptr = getenv("GLWIN_ENABLE_DEBUG");
if (envptr != NULL)
glWinDebugSettings.enableDebug = (atoi(envptr) == 1);
envptr = getenv("GLWIN_DUMP_PFD");
if (envptr != NULL)
glWinDebugSettings.dumpPFD = (atoi(envptr) == 1);
envptr = getenv("GLWIN_DUMP_HWND");
if (envptr != NULL)
glWinDebugSettings.dumpHWND = (atoi(envptr) == 1);
envptr = getenv("GLWIN_DUMP_DC");
if (envptr != NULL)
glWinDebugSettings.dumpDC = (atoi(envptr) == 1);
}
static char errorbuffer[1024];
const char *glWinErrorMessage(void)
{
if (!FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &errorbuffer,
sizeof(errorbuffer),
NULL ))
{
snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!\n", (unsigned)GetLastError());
}
return errorbuffer;
}
/*
* GLX implementation that uses Win32's OpenGL
*/
/*
* Server-side GLX uses these functions which are normally defined
* in the OpenGL SI.
*/
GLint __glEvalComputeK(GLenum target)
{
switch (target) {
case GL_MAP1_VERTEX_4:
case GL_MAP1_COLOR_4:
case GL_MAP1_TEXTURE_COORD_4:
case GL_MAP2_VERTEX_4:
case GL_MAP2_COLOR_4:
case GL_MAP2_TEXTURE_COORD_4:
return 4;
case GL_MAP1_VERTEX_3:
case GL_MAP1_TEXTURE_COORD_3:
case GL_MAP1_NORMAL:
case GL_MAP2_VERTEX_3:
case GL_MAP2_TEXTURE_COORD_3:
case GL_MAP2_NORMAL:
return 3;
case GL_MAP1_TEXTURE_COORD_2:
case GL_MAP2_TEXTURE_COORD_2:
return 2;
case GL_MAP1_TEXTURE_COORD_1:
case GL_MAP2_TEXTURE_COORD_1:
case GL_MAP1_INDEX:
case GL_MAP2_INDEX:
return 1;
default:
return 0;
}
}
GLuint __glFloorLog2(GLuint val)
{
int c = 0;
while (val > 1) {
c++;
val >>= 1;
}
return c;
}
/* some prototypes */
static Bool glWinScreenProbe(int screen);
static Bool glWinInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
int *nvisualp, int *ndepthp,
int *rootDepthp, VisualID *defaultVisp,
unsigned long sizes, int bitsPerRGB);
static void glWinSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
void **privates);
static __GLinterface *glWinCreateContext(__GLimports *imports,
__GLcontextModes *mode,
__GLinterface *shareGC);
static void glWinCreateBuffer(__GLXdrawablePrivate *glxPriv);
static void glWinResetExtension(void);
/*
* This structure is statically allocated in the __glXScreens[]
* structure. This struct is not used anywhere other than in
* __glXScreenInit to initialize each of the active screens
* (__glXActiveScreens[]). Several of the fields must be initialized by
* the screenProbe routine before they are copied to the active screens
* struct. In particular, the contextCreate, pGlxVisual, numVisuals,
* and numUsableVisuals fields must be initialized.
*/
__GLXscreenInfo __glDDXScreenInfo = {
glWinScreenProbe, /* Must be generic and handle all screens */
glWinCreateContext, /* Substitute screen's createContext routine */
glWinCreateBuffer, /* Substitute screen's createBuffer routine */
NULL, /* Set up pGlxVisual in probe */
NULL, /* Set up pVisualPriv in probe */
0, /* Set up numVisuals in probe */
0, /* Set up numUsableVisuals in probe */
"Vendor String", /* GLXvendor is overwritten by __glXScreenInit */
"Version String", /* GLXversion is overwritten by __glXScreenInit */
"Extensions String", /* GLXextensions is overwritten by __glXScreenInit */
NULL /* WrappedPositionWindow is overwritten */
};
__GLXextensionInfo __glDDXExtensionInfo = {
GL_CORE_WINDOWS,
glWinResetExtension,
glWinInitVisuals,
glWinSetVisualConfigs
};
/* prototypes */
static GLboolean glWinDestroyContext(__GLcontext *gc);
static GLboolean glWinLoseCurrent(__GLcontext *gc);
static GLboolean glWinMakeCurrent(__GLcontext *gc);
static GLboolean glWinShareContext(__GLcontext *gc, __GLcontext *gcShare);
static GLboolean glWinCopyContext(__GLcontext *dst, const __GLcontext *src,
GLuint mask);
static GLboolean glWinForceCurrent(__GLcontext *gc);
/* Drawing surface notification callbacks */
static GLboolean glWinNotifyResize(__GLcontext *gc);
static void glWinNotifyDestroy(__GLcontext *gc);
static void glWinNotifySwapBuffers(__GLcontext *gc);
/* Dispatch table override control for external agents like libGLS */
static struct __GLdispatchStateRec* glWinDispatchExec(__GLcontext *gc);
static void glWinBeginDispatchOverride(__GLcontext *gc);
static void glWinEndDispatchOverride(__GLcontext *gc);
/* Debug output */
static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd);
static __GLexports glWinExports = {
glWinDestroyContext,
glWinLoseCurrent,
glWinMakeCurrent,
glWinShareContext,
glWinCopyContext,
glWinForceCurrent,
glWinNotifyResize,
glWinNotifyDestroy,
glWinNotifySwapBuffers,
glWinDispatchExec,
glWinBeginDispatchOverride,
glWinEndDispatchOverride
};
glWinScreenRec glWinScreens[MAXSCREENS];
/* __GLdrawablePrivate->private */
typedef struct {
DrawablePtr pDraw;
/* xp_surface_id sid; */
} GLWinDrawableRec;
struct __GLcontextRec {
struct __GLinterfaceRec interface; /* required to be first */
HDC dc;
HGLRC ctx;
PIXELFORMATDESCRIPTOR pfd;
winWindowInfoRec winInfo;
int pixelFormat;
/* set when attached */
/* xp_surface_id sid; */
unsigned isAttached :1;
};
static HDC glWinMakeDC(__GLcontext *gc)
{
HDC dc;
if (gc->winInfo.hrgn == NULL)
{
GLWIN_DEBUG_MSG("Creating region from RECT(%ld,%ld,%ld,%ld):",
gc->winInfo.rect.left,
gc->winInfo.rect.top,
gc->winInfo.rect.right,
gc->winInfo.rect.bottom);
gc->winInfo.hrgn = CreateRectRgnIndirect(&gc->winInfo.rect);
GLWIN_DEBUG_MSG("%p\n", gc->winInfo.hrgn);
}
/*dc = GetDC(GetActiveWindow()); */
dc = GetDC(gc->winInfo.hwnd);
/*dc = GetDCEx(gc->winInfo.hwnd, gc->winInfo.hrgn,
DCX_WINDOW | DCX_NORESETATTRS ); */
/*dc = GetWindowDC(gc->winInfo.hwnd);*/
if (dc == NULL)
ErrorF("GetDC error: %s\n", glWinErrorMessage());
return dc;
}
static void unattach(__GLcontext *gc)
{
#if 0
BOOL ret;
GLWIN_DEBUG_MSG("unattach (ctx %p)\n", gc->ctx);
if (!gc->isAttached)
{
ErrorF("called unattach on an unattached context\n");
return;
}
if (gc->ctx)
{
ret = wglDeleteContext(gc->ctx);
if (!ret)
ErrorF("wglDeleteContext error: %s\n", glWinErrorMessage());
gc->ctx = NULL;
}
if (gc->winInfo.hrgn)
{
ret = DeleteObject(gc->winInfo.hrgn);
if (!ret)
ErrorF("DeleteObject error: %s\n", glWinErrorMessage());
gc->winInfo.hrgn = NULL;
}
#endif
gc->isAttached = 0;
}
static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv)
{
HDC dc;
#if 0
HGLRC old_ctx;
#endif
BOOL ret;
__GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
GLWIN_DEBUG_MSG("attach (ctx %p)\n", gc->ctx);
if (gc->isAttached)
{
ErrorF("called attach on an attached context\n");
return;
}
if (glxPriv->type == DRAWABLE_WINDOW)
{
WindowPtr pWin = (WindowPtr) glxPriv->pDraw;
winGetWindowInfo(pWin, &gc->winInfo);
}
if (glWinDebugSettings.dumpHWND)
GLWIN_DEBUG_MSG("Got HWND %p\n", gc->winInfo.hwnd);
dc = glWinMakeDC(gc);
gc->pixelFormat = ChoosePixelFormat(dc, &gc->pfd);
if (gc->pixelFormat == 0)
{
ErrorF("ChoosePixelFormat error: %s\n", glWinErrorMessage());
return;
}
ret = SetPixelFormat(dc, gc->pixelFormat, &gc->pfd);
if (!ret) {
ErrorF("SetPixelFormat error: %s\n", glWinErrorMessage());
}
#if 0
old_ctx = gc->ctx;
gc->ctx = wglCreateContext(dc);
if (gc->ctx == NULL) {
ErrorF("wglCreateContext error: %s\n", glWinErrorMessage());
ReleaseDC(gc->winInfo.hwnd, dc);
return;
}
if (old_ctx != NULL)
{
GLWIN_DEBUG_MSG("Copying context\n");
/* copy all rendering states to the new context */
ret = wglCopyContext(old_ctx, gc->ctx, GL_ALL_ATTRIB_BITS);
if (!ret)
ErrorF("wglCopyContext error: %s\n", glWinErrorMessage());
ret = wglDeleteContext(old_ctx);
if (!ret)
ErrorF("wglDeleteContext error: %s\n", glWinErrorMessage());
}
#endif
ReleaseDC(gc->winInfo.hwnd, dc);
gc->isAttached = 1;
}
static GLboolean glWinLoseCurrent(__GLcontext *gc)
{
/*GLWIN_DEBUG_MSG("glWinLoseCurrent (ctx %p)\n", gc->ctx);*/
__glXLastContext = NULL; /* Mesa does this; why? */
return GL_TRUE;
}
/* Context manipulation; return GL_FALSE on failure */
static GLboolean glWinDestroyContext(__GLcontext *gc)
{
GLWIN_DEBUG_MSG("glWinDestroyContext (ctx %p)\n", gc->ctx);
if (gc != NULL)
{
if (gc->isAttached)
unattach(gc);
if (gc->dc != NULL)
DeleteDC(gc->dc);
free(gc);
}
return GL_TRUE;
}
static GLboolean glWinMakeCurrent(__GLcontext *gc)
{
__GLdrawablePrivate *glPriv = gc->interface.imports.getDrawablePrivate(gc);
BOOL ret;
HDC dc;
/*GLWIN_DEBUG_MSG("glWinMakeCurrent (ctx %p)\n", gc->ctx);*/
if (!gc->isAttached)
attach(gc, glPriv);
dc = glWinMakeDC(gc);
/*if (glWinDebugSettings.dumpDC)*/
/* GLWIN_DEBUG_MSG("Got HDC %p\n", dc);*/
ret = wglMakeCurrent(dc, gc->ctx);
if (!ret)
ErrorF("glMakeCurrent error: %s\n", glWinErrorMessage());
ReleaseDC(gc->winInfo.hwnd, dc);
return ret?GL_TRUE:GL_FALSE;
}
static GLboolean glWinShareContext(__GLcontext *gc, __GLcontext *gcShare)
{
GLWIN_DEBUG_MSG("glWinShareContext unimplemented\n");
return GL_TRUE;
}
static GLboolean glWinCopyContext(__GLcontext *dst, const __GLcontext *src,
GLuint mask)
{
BOOL ret;
GLWIN_DEBUG_MSG("glWinCopyContext\n");
ret = wglCopyContext(src->ctx, dst->ctx, mask);
if (!ret)
{
ErrorF("wglCopyContext error: %s\n", glWinErrorMessage());
return GL_FALSE;
}
return GL_TRUE;
}
static GLboolean glWinForceCurrent(__GLcontext *gc)
{
BOOL ret;
HDC dc;
dc = glWinMakeDC(gc);
ret = wglMakeCurrent(dc, gc->ctx);
if (!ret)
ErrorF("wglSetCurrent error: %s\n", glWinErrorMessage());
ReleaseDC(gc->winInfo.hwnd, dc);
return ret?GL_TRUE:GL_FALSE;
}
/* Drawing surface notification callbacks */
static GLboolean glWinNotifyResize(__GLcontext *gc)
{
GLWIN_DEBUG_MSG("unimplemented glWinNotifyResize");
return GL_TRUE;
}
static void glWinNotifyDestroy(__GLcontext *gc)
{
GLWIN_DEBUG_MSG("unimplemented glWinNotifyDestroy");
}
static void glWinNotifySwapBuffers(__GLcontext *gc)
{
GLWIN_DEBUG_MSG("unimplemented glWinNotifySwapBuffers");
}
/* Dispatch table override control for external agents like libGLS */
static struct __GLdispatchStateRec* glWinDispatchExec(__GLcontext *gc)
{
GLWIN_DEBUG_MSG("unimplemented glWinDispatchExec");
return NULL;
}
static void glWinBeginDispatchOverride(__GLcontext *gc)
{
GLWIN_DEBUG_MSG("unimplemented glWinBeginDispatchOverride");
}
static void glWinEndDispatchOverride(__GLcontext *gc)
{
GLWIN_DEBUG_MSG("unimplemented glWinEndDispatchOverride");
}
#define DUMP_PFD_FLAG(flag) \
if (pfd->dwFlags & flag) { \
ErrorF("%s%s", pipesym, #flag); \
pipesym = " | "; \
}
static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd)
{
const char *pipesym = ""; /* will be set after first flag dump */
ErrorF("PIXELFORMATDESCRIPTOR:\n");
ErrorF("nSize = %u\n", pfd->nSize);
ErrorF("nVersion = %u\n", pfd->nVersion);
ErrorF("dwFlags = %lu = {", pfd->dwFlags);
DUMP_PFD_FLAG(PFD_MAIN_PLANE);
DUMP_PFD_FLAG(PFD_OVERLAY_PLANE);
DUMP_PFD_FLAG(PFD_UNDERLAY_PLANE);
DUMP_PFD_FLAG(PFD_DOUBLEBUFFER);
DUMP_PFD_FLAG(PFD_STEREO);
DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW);
DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP);
DUMP_PFD_FLAG(PFD_SUPPORT_GDI);
DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL);
DUMP_PFD_FLAG(PFD_GENERIC_FORMAT);
DUMP_PFD_FLAG(PFD_NEED_PALETTE);
DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE);
DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE);
DUMP_PFD_FLAG(PFD_SWAP_COPY);
DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS);
DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED);
DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE);
DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE);
DUMP_PFD_FLAG(PFD_STEREO_DONTCARE);
ErrorF("}\n");
ErrorF("iPixelType = %hhu = %s\n", pfd->iPixelType,
(pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX"));
ErrorF("cColorBits = %hhu\n", pfd->cColorBits);
ErrorF("cRedBits = %hhu\n", pfd->cRedBits);
ErrorF("cRedShift = %hhu\n", pfd->cRedShift);
ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits);
ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift);
ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits);
ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift);
ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits);
ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift);
ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits);
ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits);
ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits);
ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits);
ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits);
ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits);
ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits);
ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers);
ErrorF("iLayerType = %hhu\n", pfd->iLayerType);
ErrorF("bReserved = %hhu\n", pfd->bReserved);
ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask);
ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask);
ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask);
ErrorF("\n");
}
static int makeFormat(__GLcontextModes *mode, PIXELFORMATDESCRIPTOR *pfdret)
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
1, /* version number */
PFD_DRAW_TO_WINDOW | /* support window */
PFD_SUPPORT_OPENGL, /* support OpenGL */
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 */
0, /* 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 */
}, *result = &pfd;
/* disable anything but rgba. must get rgba to work first */
if (!mode->rgbMode)
return -1;
if (mode->stereoMode) {
result->dwFlags |= PFD_STEREO;
}
if (mode->doubleBufferMode) {
result->dwFlags |= PFD_DOUBLEBUFFER;
}
if (mode->colorIndexMode) {
/* ignored, see above */
result->iPixelType = PFD_TYPE_COLORINDEX;
result->cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
result->cRedBits = mode->redBits;
result->cRedShift = 0; /* FIXME */
result->cGreenBits = mode->greenBits;
result->cGreenShift = 0; /* FIXME */
result->cBlueBits = mode->blueBits;
result->cBlueShift = 0; /* FIXME */
result->cAlphaBits = mode->alphaBits;
result->cAlphaShift = 0; /* FIXME */
}
if (mode->rgbMode) {
result->iPixelType = PFD_TYPE_RGBA;
result->cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
result->cRedBits = mode->redBits;
result->cRedShift = 0; /* FIXME */
result->cGreenBits = mode->greenBits;
result->cGreenShift = 0; /* FIXME */
result->cBlueBits = mode->blueBits;
result->cBlueShift = 0; /* FIXME */
result->cAlphaBits = mode->alphaBits;
result->cAlphaShift = 0; /* FIXME */
}
if (mode->haveAccumBuffer) {
result->cAccumBits = mode->accumRedBits + mode->accumGreenBits
+ mode->accumBlueBits + mode->accumAlphaBits;
result->cAccumRedBits = mode->accumRedBits;
result->cAccumGreenBits = mode->accumGreenBits;
result->cAccumBlueBits = mode->accumBlueBits;
result->cAccumAlphaBits = mode->accumAlphaBits;
}
if (mode->haveDepthBuffer) {
result->cDepthBits = mode->depthBits;
}
if (mode->haveStencilBuffer) {
result->cStencilBits = mode->stencilBits;
}
/* result->cAuxBuffers = mode->numAuxBuffers; */
/* mode->level ignored */
/* mode->pixmapMode ? */
*pfdret = pfd;
return 0;
}
static __GLinterface *glWinCreateContext(__GLimports *imports,
__GLcontextModes *mode,
__GLinterface *shareGC)
{
__GLcontext *result;
BOOL ret;
HDC dc;
GLWIN_DEBUG_MSG("glWinCreateContext\n");
result = (__GLcontext *)calloc(1, sizeof(__GLcontext));
if (!result)
return NULL;
result->interface.imports = *imports;
result->interface.exports = glWinExports;
winGetWindowInfo(NULL, &result->winInfo);
if (glWinDebugSettings.dumpHWND)
GLWIN_DEBUG_MSG("Got HWND %p\n", result->winInfo.hwnd);
#if 1
/* get DC of XWin main window */
dc = GetDC(result->winInfo.hwnd);
result->dc = NULL;
#else
/* create a new DC */
dc = CreateDC("DISPLAY",NULL,NULL,NULL);
if (dc == NULL)
{
ErrorF("CreateDC error: %s\n", glWinErrorMessage());
free(result);
return NULL;
}
result->dc = dc;
#endif
if (glWinDebugSettings.dumpDC)
GLWIN_DEBUG_MSG("Got HDC %p\n", dc);
if (makeFormat(mode, &result->pfd))
{
ErrorF("makeFormat failed\n");
ReleaseDC(result->winInfo.hwnd, dc);
free(result);
return NULL;
}
if (glWinDebugSettings.dumpPFD)
pfdOut(&result->pfd);
result->pixelFormat = ChoosePixelFormat(dc, &result->pfd);
if (result->pixelFormat == 0)
{
ErrorF("ChoosePixelFormat error: %s\n", glWinErrorMessage());
ReleaseDC(result->winInfo.hwnd, dc);
free(result);
return NULL;
}
GLWIN_DEBUG_MSG("ChoosePixelFormat done (%d)\n", result->pixelFormat);
ret = SetPixelFormat(dc, result->pixelFormat, &result->pfd);
if (!ret) {
ErrorF("SetPixelFormat error: %s\n", glWinErrorMessage());
ReleaseDC(result->winInfo.hwnd, dc);
free(result);
return NULL;
}
result->ctx = wglCreateContext(dc);
result->isAttached = 0;
if (result->ctx == NULL) {
ErrorF("wglCreateContext error: %s\n", glWinErrorMessage());
ReleaseDC(result->winInfo.hwnd, dc);
free(result);
return NULL;
}
ReleaseDC(result->winInfo.hwnd, dc);
GLWIN_DEBUG_MSG("glWinCreateContext done\n");
return (__GLinterface *)result;
}
Bool
glWinRealizeWindow(WindowPtr pWin)
{
/* If this window has GL contexts, tell them to reattach */
Bool result;
ScreenPtr pScreen = pWin->drawable.pScreen;
glWinScreenRec *screenPriv = &glWinScreens[pScreen->myNum];
__GLXdrawablePrivate *glxPriv;
GLWIN_DEBUG_MSG("glWinRealizeWindow\n");
/* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */
pScreen->RealizeWindow = screenPriv->RealizeWindow;
result = pScreen->RealizeWindow(pWin);
pScreen->RealizeWindow = glWinRealizeWindow;
/* Re-attach this window's GL contexts, if any. */
glxPriv = __glXFindDrawablePrivate(pWin->drawable.id);
if (glxPriv) {
__GLXcontext *gx;
__GLcontext *gc;
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
GLWIN_DEBUG_MSG("glWinRealizeWindow is GL drawable!\n");
/* GL contexts bound to this window for drawing */
for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) {
gc = (__GLcontext *)gx->gc;
if (gc->isAttached)
unattach(gc);
attach(gc, glPriv);
}
/* GL contexts bound to this window for reading */
for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) {
gc = (__GLcontext *)gx->gc;
if (gc->isAttached)
unattach(gc);
attach(gc, glPriv);
}
}
return result;
}
void
glWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
ScreenPtr pScreen = pWindow->drawable.pScreen;
glWinScreenRec *screenPriv = &glWinScreens[pScreen->myNum];
__GLXdrawablePrivate *glxPriv;
/* Check if the window is attached and discard any drawing request */
glxPriv = __glXFindDrawablePrivate(pWindow->drawable.id);
if (glxPriv) {
__GLXcontext *gx;
/* GL contexts bound to this window for drawing */
for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) {
/*
GLWIN_DEBUG_MSG("glWinCopyWindow - calling glDrawBuffer\n");
glDrawBuffer(GL_FRONT);
*/
return;
}
/* GL contexts bound to this window for reading */
for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) {
return;
}
}
GLWIN_DEBUG_MSG("glWinCopyWindow - passing to hw layer\n");
pScreen->CopyWindow = screenPriv->CopyWindow;
pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
pScreen->CopyWindow = glWinCopyWindow;
}
Bool
glWinUnrealizeWindow(WindowPtr pWin)
{
/* If this window has GL contexts, tell them to unattach */
Bool result;
ScreenPtr pScreen = pWin->drawable.pScreen;
glWinScreenRec *screenPriv = &glWinScreens[pScreen->myNum];
__GLXdrawablePrivate *glxPriv;
GLWIN_DEBUG_MSG("glWinUnrealizeWindow\n");
/* The Aqua window may have already been destroyed (windows
* are unrealized from top down)
*/
/* Unattach this window's GL contexts, if any. */
glxPriv = __glXFindDrawablePrivate(pWin->drawable.id);
if (glxPriv) {
__GLXcontext *gx;
__GLcontext *gc;
GLWIN_DEBUG_MSG("glWinUnealizeWindow is GL drawable!\n");
/* GL contexts bound to this window for drawing */
for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) {
gc = (__GLcontext *)gx->gc;
unattach(gc);
}
/* GL contexts bound to this window for reading */
for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) {
gc = (__GLcontext *)gx->gc;
unattach(gc);
}
}
pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow;
result = pScreen->UnrealizeWindow(pWin);
pScreen->UnrealizeWindow = glWinUnrealizeWindow;
return result;
}
/*
* In the case the driver has no GLX visuals we'll use these.
* [0] = RGB, double buffered
* [1] = RGB, double buffered, stencil, accum
*/
/* Originally copied from Mesa */
static int numConfigs = 0;
static __GLXvisualConfig *visualConfigs = NULL;
static void **visualPrivates = NULL;
#define NUM_FALLBACK_CONFIGS 2
static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE_EXT, /* visualRating */
0, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
16, 16, 16, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE_EXT, /* visualRating */
0, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
}
};
static __GLXvisualConfig NullConfig = {
-1, /* vid */
-1, /* class */
False, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
False, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE_EXT, /* visualRating */
0, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
};
static inline int count_bits(uint32_t x)
{
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0f0f0f0f;
x = x + (x >> 8);
x = x + (x >> 16);
return x & 63;
}
/* Mostly copied from Mesa's xf86glx.c */
static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
VisualID *defaultVisp,
int ndepth, DepthPtr pdepth,
int rootDepth)
{
int numRGBconfigs;
int numCIconfigs;
int numVisuals = *nvisualp;
int numNewVisuals;
int numNewConfigs;
VisualPtr pVisual = *visualp;
VisualPtr pVisualNew = NULL;
VisualID *orig_vid = NULL;
__GLXvisualConfig *glXVisualPtr = NULL;
__GLXvisualConfig *pNewVisualConfigs = NULL;
void **glXVisualPriv;
void **pNewVisualPriv;
int found_default;
int i, j, k;
GLWIN_DEBUG_MSG("init_visuals\n");
if (numConfigs > 0)
numNewConfigs = numConfigs;
else
numNewConfigs = NUM_FALLBACK_CONFIGS;
/* Alloc space for the list of new GLX visuals */
pNewVisualConfigs = (__GLXvisualConfig *)
__glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
if (!pNewVisualConfigs) {
return FALSE;
}
/* Alloc space for the list of new GLX visual privates */
pNewVisualPriv = (void **) __glXMalloc(numNewConfigs * sizeof(void *));
if (!pNewVisualPriv) {
__glXFree(pNewVisualConfigs);
return FALSE;
}
/*
** If SetVisualConfigs was not called, then use default GLX
** visual configs.
*/
if (numConfigs == 0) {
memcpy(pNewVisualConfigs, FallbackConfigs,
NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
}
else {
/* copy driver's visual config info */
for (i = 0; i < numConfigs; i++) {
pNewVisualConfigs[i] = visualConfigs[i];
pNewVisualPriv[i] = visualPrivates[i];
}
}
/* Count the number of RGB and CI visual configs */
numRGBconfigs = 0;
numCIconfigs = 0;
for (i = 0; i < numNewConfigs; i++) {
if (pNewVisualConfigs[i].rgba)
numRGBconfigs++;
else
numCIconfigs++;
}
/* Count the total number of visuals to compute */
numNewVisuals = 0;
for (i = 0; i < numVisuals; i++) {
int count;
count = ((pVisual[i].class == TrueColor
|| pVisual[i].class == DirectColor)
? numRGBconfigs : numCIconfigs);
if (count == 0)
count = 1; /* preserve the existing visual */
numNewVisuals += count;
}
/* Reset variables for use with the next screen/driver's visual configs */
visualConfigs = NULL;
numConfigs = 0;
/* Alloc temp space for the list of orig VisualIDs for each new visual */
orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID));
if (!orig_vid) {
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisuals */
glXVisualPtr = (__GLXvisualConfig *)__glXMalloc(numNewVisuals *
sizeof(__GLXvisualConfig));
if (!glXVisualPtr) {
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisualPrivates */
glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *));
if (!glXVisualPriv) {
__glXFree(glXVisualPtr);
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the new list of the X server's visuals */
pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec));
if (!pVisualNew) {
__glXFree(glXVisualPriv);
__glXFree(glXVisualPtr);
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Initialize the new visuals */
found_default = FALSE;
for (i = j = 0; i < numVisuals; i++) {
int is_rgb = (pVisual[i].class == TrueColor ||
pVisual[i].class == DirectColor);
if (!is_rgb)
{
/* We don't support non-rgb visuals for GL. But we don't
want to remove them either, so just pass them through
with null glX configs */
pVisualNew[j] = pVisual[i];
pVisualNew[j].vid = FakeClientID(0);
/* Check for the default visual */
if (!found_default && pVisual[i].vid == *defaultVisp) {
*defaultVisp = pVisualNew[j].vid;
found_default = TRUE;
}
/* Save the old VisualID */
orig_vid[j] = pVisual[i].vid;
/* Initialize the glXVisual */
glXVisualPtr[j] = NullConfig;
glXVisualPriv[j] = NULL;
j++;
continue;
}
for (k = 0; k < numNewConfigs; k++) {
if (pNewVisualConfigs[k].rgba != is_rgb)
continue;
/* Initialize the new visual */
pVisualNew[j] = pVisual[i];
pVisualNew[j].vid = FakeClientID(0);
/* Check for the default visual */
if (!found_default && pVisual[i].vid == *defaultVisp) {
*defaultVisp = pVisualNew[j].vid;
found_default = TRUE;
}
/* Save the old VisualID */
orig_vid[j] = pVisual[i].vid;
/* Initialize the glXVisual */
glXVisualPtr[j] = pNewVisualConfigs[k];
glXVisualPtr[j].vid = pVisualNew[j].vid;
/*
* If the class is -1, then assume the X visual information
* is identical to what GLX needs, and take them from the X
* visual. NOTE: if class != -1, then all other fields MUST
* be initialized.
*/
if (glXVisualPtr[j].class == -1) {
glXVisualPtr[j].class = pVisual[i].class;
glXVisualPtr[j].redSize = count_bits(pVisual[i].redMask);
glXVisualPtr[j].greenSize = count_bits(pVisual[i].greenMask);
glXVisualPtr[j].blueSize = count_bits(pVisual[i].blueMask);
glXVisualPtr[j].alphaSize = glXVisualPtr[j].alphaSize;
glXVisualPtr[j].redMask = pVisual[i].redMask;
glXVisualPtr[j].greenMask = pVisual[i].greenMask;
glXVisualPtr[j].blueMask = pVisual[i].blueMask;
glXVisualPtr[j].alphaMask = glXVisualPtr[j].alphaMask;
glXVisualPtr[j].bufferSize = rootDepth;
}
/* Save the device-dependent private for this visual */
glXVisualPriv[j] = pNewVisualPriv[k];
j++;
}
}
assert(j <= numNewVisuals);
/* Save the GLX visuals in the screen structure */
glWinScreens[screenInfo.numScreens-1].num_vis = numNewVisuals;
glWinScreens[screenInfo.numScreens-1].glx_vis = glXVisualPtr;
glWinScreens[screenInfo.numScreens-1].priv = glXVisualPriv;
/* Set up depth's VisualIDs */
for (i = 0; i < ndepth; i++) {
int numVids = 0;
VisualID *pVids = NULL;
int k, n = 0;
/* Count the new number of VisualIDs at this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
numVids++;
/* Allocate a new list of VisualIDs for this depth */
pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID));
/* Initialize the new list of VisualIDs for this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
pVids[n++] = pVisualNew[k].vid;
/* Update this depth's list of VisualIDs */
__glXFree(pdepth[i].vids);
pdepth[i].vids = pVids;
pdepth[i].numVids = numVids;
}
/* Update the X server's visuals */
*nvisualp = numNewVisuals;
*visualp = pVisualNew;
/* Free the old list of the X server's visuals */
__glXFree(pVisual);
/* Clean up temporary allocations */
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
/* Free the private list created by DDX HW driver */
if (visualPrivates)
xfree(visualPrivates);
visualPrivates = NULL;
return TRUE;
}
static void fixup_visuals(int screen)
{
ScreenPtr pScreen = screenInfo.screens[screen];
glWinScreenRec *pScr = &glWinScreens[screen];
__GLXvisualConfig *pGLXVis = pScr->glx_vis;
VisualPtr pVis;
int i, j;
GLWIN_DEBUG_MSG("fixup_visuals\n");
for (i = 0; i < pScr->num_vis; i++, pGLXVis++) {
pVis = pScreen->visuals;
/* Find a visual that matches the GLX visual's class and size */
for (j = 0; j < pScreen->numVisuals; j++, pVis++) {
if (pVis->class == pGLXVis->class &&
pVis->nplanes == pGLXVis->bufferSize) {
/* Fixup the masks */
pGLXVis->redMask = pVis->redMask;
pGLXVis->greenMask = pVis->greenMask;
pGLXVis->blueMask = pVis->blueMask;
/* Recalc the sizes */
pGLXVis->redSize = count_bits(pGLXVis->redMask);
pGLXVis->greenSize = count_bits(pGLXVis->greenMask);
pGLXVis->blueSize = count_bits(pGLXVis->blueMask);
}
}
}
}
static void init_screen_visuals(int screen)
{
ScreenPtr pScreen = screenInfo.screens[screen];
__GLXvisualConfig *pGLXVis = glWinScreens[screen].glx_vis;
/* XMesaVisual *pXMesaVisual; */
VisualPtr pVis;
int *used;
int i, j;
GLWIN_DEBUG_MSG("init_screen_visuals\n");
/* Alloc space for the list of XMesa visuals */
#if 0
pXMesaVisual = (XMesaVisual *)__glXMalloc(MESAScreens[screen].num_vis *
sizeof(XMesaVisual));
__glXMemset(pXMesaVisual, 0,
MESAScreens[screen].num_vis * sizeof(XMesaVisual));
#endif
used = (int *)__glXMalloc(pScreen->numVisuals * sizeof(int));
__glXMemset(used, 0, pScreen->numVisuals * sizeof(int));
for (i = 0; i < glWinScreens[screen].num_vis; i++, pGLXVis++) {
pVis = pScreen->visuals;
for (j = 0; j < pScreen->numVisuals; j++, pVis++) {
if (pVis->class == pGLXVis->class &&
pVis->nplanes == pGLXVis->bufferSize &&
!used[j]) {
if (pVis->redMask == pGLXVis->redMask &&
pVis->greenMask == pGLXVis->greenMask &&
pVis->blueMask == pGLXVis->blueMask) {
/* Create the XMesa visual */
#if 0
pXMesaVisual[i] =
XMesaCreateVisual(pScreen,
pVis,
pGLXVis->rgba,
(pGLXVis->alphaSize > 0),
pGLXVis->doubleBuffer,
pGLXVis->stereo,
GL_TRUE, /* ximage_flag */
pGLXVis->depthSize,
pGLXVis->stencilSize,
pGLXVis->accumRedSize,
pGLXVis->accumGreenSize,
pGLXVis->accumBlueSize,
pGLXVis->accumAlphaSize,
0, /* numSamples */
pGLXVis->level,
pGLXVis->visualRating );
#endif
/* Set the VisualID */
pGLXVis->vid = pVis->vid;
/* Mark this visual used */
used[j] = 1;
break;
}
}
}
}
__glXFree(used);
/* glWinScreens[screen].xm_vis = pXMesaVisual; */
}
static Bool glWinScreenProbe(int screen)
{
ScreenPtr pScreen;
glWinScreenRec *screenPriv;
GLWIN_DEBUG_MSG("glWinScreenProbe\n");
/*
* Set up the current screen's visuals.
*/
__glDDXScreenInfo.pGlxVisual = glWinScreens[screen].glx_vis;
__glDDXScreenInfo.pVisualPriv = glWinScreens[screen].priv;
__glDDXScreenInfo.numVisuals =
__glDDXScreenInfo.numUsableVisuals = glWinScreens[screen].num_vis;
/*
* Set the current screen's createContext routine. This could be
* wrapped by a DDX GLX context creation routine.
*/
__glDDXScreenInfo.createContext = glWinCreateContext;
/*
* The ordering of the rgb compenents might have been changed by the
* driver after mi initialized them.
*/
fixup_visuals(screen);
/*
* Find the GLX visuals that are supported by this screen and create
* XMesa's visuals.
*/
init_screen_visuals(screen);
/* Wrap RealizeWindow and UnrealizeWindow on this screen */
pScreen = screenInfo.screens[screen];
screenPriv = &glWinScreens[screen];
screenPriv->RealizeWindow = pScreen->RealizeWindow;
pScreen->RealizeWindow = glWinRealizeWindow;
screenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
pScreen->UnrealizeWindow = glWinUnrealizeWindow;
screenPriv->CopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = glWinCopyWindow;
return TRUE;
}
static GLboolean glWinSwapBuffers(__GLXdrawablePrivate *glxPriv)
{
/* swap buffers on only *one* of the contexts
* (e.g. the last one for drawing)
*/
__GLcontext *gc = (__GLcontext *)glxPriv->drawGlxc->gc;
HDC dc;
BOOL ret;
if (gc != NULL && gc->ctx != NULL)
{
dc = glWinMakeDC(gc);
ret = SwapBuffers(dc);
if (!ret)
ErrorF("SwapBuffers failed: %s\n", glWinErrorMessage());
ReleaseDC(gc->winInfo.hwnd, dc);
if (!ret)
return GL_FALSE;
}
return GL_TRUE;
}
static void glWinDestroyDrawablePrivate(__GLdrawablePrivate *glPriv)
{
GLWIN_DEBUG_MSG("glWinDestroyDrawablePrivate\n");
/* It doesn't work to call DRIDestroySurface here, the drawable's
already gone.. But dri.c notices the window destruction and
frees the surface itself. */
free(glPriv->private);
glPriv->private = NULL;
}
static void glWinCreateBuffer(__GLXdrawablePrivate *glxPriv)
{
GLWinDrawableRec *winPriv = malloc(sizeof(GLWinDrawableRec));
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
/*winPriv->sid = 0; */
winPriv->pDraw = NULL;
GLWIN_DEBUG_MSG("glWinCreateBuffer\n");
/* replace swapBuffers (original is never called) */
glxPriv->swapBuffers = glWinSwapBuffers;
/* stash private data */
glPriv->private = winPriv;
glPriv->freePrivate = glWinDestroyDrawablePrivate;
}
static void glWinResetExtension(void)
{
GLWIN_DEBUG_MSG("glWinResetExtension\n");
}
/* based on code in apples/indirect.c which is based on i830_dri.c */
static void
glWinInitVisualConfigs(void)
{
int lclNumConfigs = 0;
__GLXvisualConfig *lclVisualConfigs = NULL;
void **lclVisualPrivates = NULL;
int depth, aux, buffers, stencil, accum;
int i = 0;
GLWIN_DEBUG_MSG("glWinInitVisualConfigs ");
/* count num configs:
2 Z buffer (0, 24 bit)
2 AUX buffer (0, 2)
2 buffers (single, double)
2 stencil (0, 8 bit)
2 accum (0, 64 bit)
= 32 configs */
lclNumConfigs = 2 * 2 * 2 * 2 * 2; /* 32 */
/* alloc */
lclVisualConfigs = xcalloc(sizeof(__GLXvisualConfig), lclNumConfigs);
lclVisualPrivates = xcalloc(sizeof(void *), lclNumConfigs);
/* fill in configs */
if (NULL != lclVisualConfigs) {
i = 0; /* current buffer */
for (depth = 0; depth < 2; depth++) {
for (aux = 0; aux < 2; aux++) {
for (buffers = 0; buffers < 2; buffers++) {
for (stencil = 0; stencil < 2; stencil++) {
for (accum = 0; accum < 2; accum++) {
lclVisualConfigs[i].vid = -1;
lclVisualConfigs[i].class = -1;
lclVisualConfigs[i].rgba = TRUE;
lclVisualConfigs[i].redSize = -1;
lclVisualConfigs[i].greenSize = -1;
lclVisualConfigs[i].blueSize = -1;
lclVisualConfigs[i].redMask = -1;
lclVisualConfigs[i].greenMask = -1;
lclVisualConfigs[i].blueMask = -1;
lclVisualConfigs[i].alphaMask = 0;
if (accum) {
lclVisualConfigs[i].accumRedSize = 16;
lclVisualConfigs[i].accumGreenSize = 16;
lclVisualConfigs[i].accumBlueSize = 16;
lclVisualConfigs[i].accumAlphaSize = 16;
}
else {
lclVisualConfigs[i].accumRedSize = 0;
lclVisualConfigs[i].accumGreenSize = 0;
lclVisualConfigs[i].accumBlueSize = 0;
lclVisualConfigs[i].accumAlphaSize = 0;
}
lclVisualConfigs[i].doubleBuffer = buffers ? TRUE : FALSE;
lclVisualConfigs[i].stereo = FALSE;
lclVisualConfigs[i].bufferSize = -1;
lclVisualConfigs[i].depthSize = depth? 24 : 0;
lclVisualConfigs[i].stencilSize = stencil ? 8 : 0;
lclVisualConfigs[i].auxBuffers = aux ? 2 : 0;
lclVisualConfigs[i].level = 0;
lclVisualConfigs[i].visualRating = GLX_NONE_EXT;
lclVisualConfigs[i].transparentPixel = 0;
lclVisualConfigs[i].transparentRed = 0;
lclVisualConfigs[i].transparentGreen = 0;
lclVisualConfigs[i].transparentBlue = 0;
lclVisualConfigs[i].transparentAlpha = 0;
lclVisualConfigs[i].transparentIndex = 0;
i++;
}
}
}
}
}
}
if (i != lclNumConfigs)
GLWIN_DEBUG_MSG("glWinInitVisualConfigs failed to alloc visual configs");
GlxSetVisualConfigs(lclNumConfigs, lclVisualConfigs, lclVisualPrivates);
}
/* Copied from Mesa */
static void glWinSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
void **privates)
{
GLWIN_DEBUG_MSG("glWinSetVisualConfigs\n");
numConfigs = nconfigs;
visualConfigs = configs;
visualPrivates = privates;
}
/* Copied from Mesa */
static Bool glWinInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
int *nvisualp, int *ndepthp,
int *rootDepthp, VisualID *defaultVisp,
unsigned long sizes, int bitsPerRGB)
{
glWinInitDebugSettings();
GLWIN_DEBUG_MSG("glWinInitVisuals\n");
if (0 == numConfigs) /* if no configs */
glWinInitVisualConfigs(); /* ensure the visula configs are setup */
/*
* Setup the visuals supported by this particular screen.
*/
return init_visuals(nvisualp, visualp, defaultVisp,
*ndepthp, *depthp, *rootDepthp);
}