/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5.2
*
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2006 Brian Paul 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"),
#include "xfonts.h"
#include "xmesaP.h"
+#ifdef __VMS
+#define _mesa_sprintf sprintf
+#endif
/* This indicates the client-side GLX API and GLX encoder version. */
#define CLIENT_MAJOR_VERSION 1
"GLX_ARB_get_proc_address " \
"GLX_EXT_visual_info " \
"GLX_EXT_visual_rating " \
- "GLX_SGI_video_sync " \
+ /*"GLX_SGI_video_sync "*/ \
"GLX_SGIX_fbconfig " \
"GLX_SGIX_pbuffer "
#define DONT_CARE -1
-#define MAX_VISUALS 100
-static XMesaVisual VisualTable[MAX_VISUALS];
+static XMesaVisual *VisualTable = NULL;
static int NumVisuals = 0;
/* Create a new visual and add it to the list. */
- if (NumVisuals >= MAX_VISUALS) {
- _mesa_problem(NULL, "GLX Error: maximum number of visuals exceeded");
- return NULL;
- }
-
xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
stereoFlag, ximageFlag,
depth_size, stencil_size,
* if we need to search for it in find_glx_visual().
*/
xmvis->vishandle = vinfo;
+ /* Allocate more space for additional visual */
+ VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable,
+ sizeof(XMesaVisual) * NumVisuals,
+ sizeof(XMesaVisual) * (NumVisuals + 1));
/* add xmvis to the list */
VisualTable[NumVisuals] = xmvis;
NumVisuals++;
return zBits;
}
+static GLint
+default_alpha_bits(void)
+{
+ int aBits;
+ const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS");
+ if (aEnv)
+ aBits = _mesa_atoi(aEnv);
+ else
+ aBits = 0;
+ return aBits;
+}
+
+static GLint
+default_accum_bits(void)
+{
+ return 16;
+}
+
/*
{
int vislevel;
GLint zBits = default_depth_bits();
+ GLint accBits = default_accum_bits();
+ GLboolean alphaFlag = default_alpha_bits() > 0;
vislevel = level_of_visual( dpy, visinfo );
if (vislevel) {
/* can be done? They should use glXChooseVisual(). */
return save_glx_visual( dpy, visinfo,
GL_TRUE, /* rgb */
- GL_FALSE, /* alpha */
+ alphaFlag, /* alpha */
GL_TRUE, /* double */
GL_FALSE, /* stereo */
zBits,
STENCIL_BITS,
- ACCUM_BITS, /* r */
- ACCUM_BITS, /* g */
- ACCUM_BITS, /* b */
- ACCUM_BITS, /* a */
+ accBits, /* r */
+ accBits, /* g */
+ accBits, /* b */
+ accBits, /* a */
0, /* level */
0 /* numAux */
);
}
+/**********************************************************************/
+/*** Display-related functions ***/
+/**********************************************************************/
+
+
+/**
+ * Free all XMesaVisuals which are associated with the given display.
+ */
+static void
+destroy_visuals_on_display(Display *dpy)
+{
+ int i;
+ for (i = 0; i < NumVisuals; i++) {
+ if (VisualTable[i]->display == dpy) {
+ /* remove this visual */
+ int j;
+ free(VisualTable[i]);
+ for (j = i; j < NumVisuals - 1; j++)
+ VisualTable[j] = VisualTable[j + 1];
+ NumVisuals--;
+ }
+ }
+}
+
+
+/**
+ * Called from XCloseDisplay() to let us free our display-related data.
+ */
+static int
+close_display_callback(Display *dpy, XExtCodes *codes)
+{
+ destroy_visuals_on_display(dpy);
+ xmesa_destroy_buffers_on_display(dpy);
+ return 0;
+}
+
+
+/**
+ * Look for the named extension on given display and return a pointer
+ * to the _XExtension data, or NULL if extension not found.
+ */
+static _XExtension *
+lookup_extension(Display *dpy, const char *extName)
+{
+ _XExtension *ext;
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->name && strcmp(ext->name, extName) == 0) {
+ return ext;
+ }
+ }
+ return NULL;
+}
+
+
+/**
+ * Whenever we're given a new Display pointer, call this function to
+ * register our close_display_callback function.
+ */
+static void
+register_with_display(Display *dpy)
+{
+ const char *extName = "MesaGLX";
+ _XExtension *ext;
+
+ ext = lookup_extension(dpy, extName);
+ if (!ext) {
+ XExtCodes *c = XAddExtension(dpy);
+ ext = dpy->ext_procs; /* new extension is at head of list */
+ assert(c->extension == ext->codes.extension);
+ ext->name = _mesa_strdup(extName);
+ ext->close_display = close_display_callback;
+ }
+}
+
+
/**********************************************************************/
/*** Begin Fake GLX API Functions ***/
/**********************************************************************/
parselist++;
{
GLint size = *parselist++;
- alpha_flag = size>0 ? 1 : 0;
+ alpha_flag = size ? GL_TRUE : GL_FALSE;
}
break;
case GLX_DEPTH_SIZE:
* FBConfig attribs.
*/
case GLX_RENDER_TYPE:
+ if (!fbConfig)
+ return NULL;
parselist++;
if (*parselist == GLX_RGBA_BIT) {
rgb_flag = GL_TRUE;
parselist++;
break;
case GLX_DRAWABLE_TYPE:
+ if (!fbConfig)
+ return NULL;
parselist++;
if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) {
return NULL; /* bad bit */
parselist++;
break;
case GLX_FBCONFIG_ID:
+ if (!fbConfig)
+ return NULL;
parselist++;
- desiredVisualID = *parselist;
+ desiredVisualID = *parselist++;
+ break;
+ case GLX_X_RENDERABLE:
+ if (!fbConfig)
+ return NULL;
+ parselist += 2;
+ /* ignore */
break;
case None:
* return 16 to maintain performance with earlier versions of Mesa.
*/
if (depth_size > 24)
- depth_size = 31; /* 32 causes int overflow problems */
+ depth_size = 32;
else if (depth_size > 16)
depth_size = 24;
else if (depth_size > 0) {
depth_size = default_depth_bits();
}
+ if (!alpha_flag) {
+ alpha_flag = default_alpha_bits() > 0;
+ }
+
/* we only support one size of stencil and accum buffers. */
if (stencil_size > 0)
stencil_size = STENCIL_BITS;
if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 ||
accumAlphaSize > 0) {
- accumRedSize = ACCUM_BITS;
- accumGreenSize = ACCUM_BITS;
- accumBlueSize = ACCUM_BITS;
- accumAlphaSize = alpha_flag ? ACCUM_BITS : 0;
+ accumRedSize =
+ accumGreenSize =
+ accumBlueSize = default_accum_bits();
+ accumAlphaSize = alpha_flag ? accumRedSize : 0;
}
xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
static XVisualInfo *
Fake_glXChooseVisual( Display *dpy, int screen, int *list )
{
- XMesaVisual xmvis = choose_visual(dpy, screen, list, GL_FALSE);
- {
- int x;
- glXGetConfig(dpy, xmvis->vishandle, GLX_RED_SIZE, &x);
- }
+ XMesaVisual xmvis;
+
+ /* register ourselves as an extension on this display */
+ register_with_display(dpy);
+ xmvis = choose_visual(dpy, screen, list, GL_FALSE);
if (xmvis) {
#if 0
return xmvis->vishandle;
return 0;
/* deallocate unused windows/buffers */
+#if 0
XMesaGarbageCollect();
+#endif
xmvis = find_glx_visual( dpy, visinfo );
if (!xmvis) {
xmvis = create_glx_visual( dpy, visinfo );
if (!xmvis) {
/* unusable visual */
- FREE(glxCtx);
+ _mesa_free(glxCtx);
return NULL;
}
}
glxCtx->xmesaContext = XMesaCreateContext(xmvis,
shareCtx ? shareCtx->xmesaContext : NULL);
if (!glxCtx->xmesaContext) {
- FREE(glxCtx);
+ _mesa_free(glxCtx);
return NULL;
}
if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
((__GLXcontext *) ctx)->currentDpy = dpy;
((__GLXcontext *) ctx)->currentDrawable = draw;
-#ifndef GLX_BUILT_IN_XMESA
((__GLXcontext *) ctx)->currentReadable = read;
-#else
- __glXSetCurrentContext(ctx);
-#endif
return True;
}
else {
MakeCurrent_PrevReadable = 0;
MakeCurrent_PrevDrawBuffer = 0;
MakeCurrent_PrevReadBuffer = 0;
-#ifdef GLX_BUILT_IN_XMESA
- /* XXX bind dummy context with __glXSetCurrentContext(ctx); */
-#endif
return True;
}
else {
XMesaContext xm_src = fakeSrc->xmesaContext;
XMesaContext xm_dst = fakeDst->xmesaContext;
(void) dpy;
+ if (MakeCurrent_PrevContext == src) {
+ _mesa_Flush();
+ }
_mesa_copy_context( &(xm_src->mesa), &(xm_dst->mesa), (GLuint) mask );
}
MakeCurrent_PrevReadBuffer = 0;
XMesaDestroyContext( glxCtx->xmesaContext );
XMesaGarbageCollect();
+ _mesa_free(glxCtx);
}
/* A GLXPbuffer handle must be an X Drawable because that's what
* glXMakeCurrent takes.
*/
- return (GLXPbuffer) xmbuf->frontxrb->pixmap;
+ if (xmbuf)
+ return (GLXPbuffer) xmbuf->frontxrb->pixmap;
+ else
+ return 0;
}
glxCtx->xmesaContext = XMesaCreateContext(xmvis,
shareCtx ? shareCtx->xmesaContext : NULL);
if (!glxCtx->xmesaContext) {
- FREE(glxCtx);
+ _mesa_free(glxCtx);
return NULL;
}
/*** GLX_SGI_video_sync ***/
+static unsigned int FrameCounter = 0;
+
static int
Fake_glXGetVideoSyncSGI(unsigned int *count)
{
- (void) count;
+ /* this is a bogus implementation */
+ *count = FrameCounter++;
return 0;
}
static int
Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
- (void) divisor;
- (void) remainder;
- (void) count;
+ if (divisor <= 0 || remainder < 0)
+ return GLX_BAD_VALUE;
+ /* this is a bogus implementation */
+ FrameCounter++;
+ while (FrameCounter % divisor != remainder)
+ FrameCounter++;
+ *count = FrameCounter;
return 0;
}
glxCtx->xmesaContext = XMesaCreateContext(xmvis,
shareCtx ? shareCtx->xmesaContext : NULL);
if (!glxCtx->xmesaContext) {
- FREE(glxCtx);
+ _mesa_free(glxCtx);
return NULL;
}