Merge branch 'glsl-to-tgsi'
[mesa.git] / src / gallium / state_trackers / glx / xlib / glx_api.c
index f2881b9a31e16b8ac0dc9be3a57c74e77204e198..a7aafd846cdfbe700b81b392fab5a8559f6f2380 100644 (file)
 #include "GL/glx.h"
 
 #include "xm_api.h"
-#include "main/context.h"
-#include "main/config.h"
-#include "main/macros.h"
-#include "main/imports.h"
-#include "main/version.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
 
 
 /* This indicates the client-side GLX API and GLX encoder version. */
@@ -53,9 +46,6 @@
 #define SERVER_MAJOR_VERSION 1
 #define SERVER_MINOR_VERSION 4
 
-/* This is appended onto the glXGetClient/ServerString version strings. */
-#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING
-
 /* Who implemented this GLX? */
 #define VENDOR "Brian Paul"
 
@@ -280,7 +270,7 @@ default_depth_bits(void)
    int zBits;
    const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS");
    if (zEnv)
-      zBits = _mesa_atoi(zEnv);
+      zBits = atoi(zEnv);
    else
       zBits = DEFAULT_SOFTWARE_DEPTH_BITS;
    return zBits;
@@ -292,7 +282,7 @@ default_alpha_bits(void)
    int aBits;
    const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS");
    if (aEnv)
-      aBits = _mesa_atoi(aEnv);
+      aBits = atoi(aEnv);
    else
       aBits = 0;
    return aBits;
@@ -442,17 +432,17 @@ get_env_visual(Display *dpy, int scr, const char *varname)
       return NULL;
    }
 
-   _mesa_strncpy( value, _mesa_getenv(varname), 100 );
+   strncpy( value, _mesa_getenv(varname), 100 );
    value[99] = 0;
 
    sscanf( value, "%s %d", type, &depth );
 
-   if (_mesa_strcmp(type,"TrueColor")==0)          xclass = TrueColor;
-   else if (_mesa_strcmp(type,"DirectColor")==0)   xclass = DirectColor;
-   else if (_mesa_strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
-   else if (_mesa_strcmp(type,"StaticColor")==0)   xclass = StaticColor;
-   else if (_mesa_strcmp(type,"GrayScale")==0)     xclass = GrayScale;
-   else if (_mesa_strcmp(type,"StaticGray")==0)    xclass = StaticGray;
+   if (strcmp(type,"TrueColor")==0)          xclass = TrueColor;
+   else if (strcmp(type,"DirectColor")==0)   xclass = DirectColor;
+   else if (strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
+   else if (strcmp(type,"StaticColor")==0)   xclass = StaticColor;
+   else if (strcmp(type,"GrayScale")==0)     xclass = GrayScale;
+   else if (strcmp(type,"StaticGray")==0)    xclass = StaticGray;
 
    if (xclass>-1 && depth>0) {
       vis = get_visual( dpy, scr, depth, xclass );
@@ -606,8 +596,8 @@ destroy_visuals_on_display(Display *dpy)
 static int
 close_display_callback(Display *dpy, XExtCodes *codes)
 {
-   destroy_visuals_on_display(dpy);
    xmesa_destroy_buffers_on_display(dpy);
+   destroy_visuals_on_display(dpy);
    return 0;
 }
 
@@ -644,6 +634,7 @@ register_with_display(Display *dpy)
       XExtCodes *c = XAddExtension(dpy);
       ext = dpy->ext_procs;  /* new extension is at head of list */
       assert(c->extension == ext->codes.extension);
+      (void) c;
       ext->name = _mesa_strdup(extName);
       ext->close_display = close_display_callback;
    }
@@ -688,6 +679,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
    int desiredVisualID = -1;
    int numAux = 0;
 
+   xmesa_init( dpy );
+
    parselist = list;
 
    while (*parselist) {
@@ -871,16 +864,19 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             parselist++;
             break;
          case GLX_FBCONFIG_ID:
+         case GLX_VISUAL_ID:
             if (!fbConfig)
                return NULL;
             parselist++;
             desiredVisualID = *parselist++;
             break;
          case GLX_X_RENDERABLE:
+         case GLX_MAX_PBUFFER_WIDTH:
+         case GLX_MAX_PBUFFER_HEIGHT:
+         case GLX_MAX_PBUFFER_PIXELS:
             if (!fbConfig)
-               return NULL;
-            parselist += 2;
-            /* ignore */
+               return NULL; /* invalid config option */
+            parselist += 2; /* ignore the parameter */
             break;
 
 #ifdef GLX_EXT_texture_from_pixmap
@@ -940,9 +936,6 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
          /* give the visual some useful GLX attributes */
          double_flag = GL_TRUE;
          rgb_flag = GL_TRUE;
-         depth_size = default_depth_bits();
-         stencil_size = STENCIL_BITS;
-         /* XXX accum??? */
       }
    }
    else if (level==0) {
@@ -1006,7 +999,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
 }
 
 
-XVisualInfo *
+PUBLIC XVisualInfo *
 glXChooseVisual( Display *dpy, int screen, int *list )
 {
    XMesaVisual xmvis;
@@ -1017,9 +1010,9 @@ glXChooseVisual( Display *dpy, int screen, int *list )
    xmvis = choose_visual(dpy, screen, list, GL_FALSE);
    if (xmvis) {
       /* create a new vishandle - the cached one may be stale */
-      xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
+      xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
       if (xmvis->vishandle) {
-         _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
+         memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
       }
       return xmvis->vishandle;
    }
@@ -1028,15 +1021,18 @@ glXChooseVisual( Display *dpy, int screen, int *list )
 }
 
 
-GLXContext
-glXCreateContext( Display *dpy, XVisualInfo *visinfo,
-                  GLXContext share_list, Bool direct )
+/**
+ * Helper function used by other glXCreateContext functions.
+ */
+static GLXContext
+create_context(Display *dpy, XMesaVisual xmvis,
+               XMesaContext shareCtx, Bool direct,
+               unsigned major, unsigned minor,
+               unsigned profileMask, unsigned contextFlags)
 {
-   XMesaVisual xmvis;
    GLXContext glxCtx;
-   GLXContext shareCtx = share_list;
 
-   if (!dpy || !visinfo)
+   if (!dpy || !xmvis)
       return 0;
 
    glxCtx = CALLOC_STRUCT(__GLXcontextRec);
@@ -1048,29 +1044,41 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
    XMesaGarbageCollect();
 #endif
 
+   glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx, major, minor,
+                                             profileMask, contextFlags);
+   if (!glxCtx->xmesaContext) {
+      free(glxCtx);
+      return NULL;
+   }
+
+   glxCtx->isDirect = DEFAULT_DIRECT;
+   glxCtx->currentDpy = dpy;
+   glxCtx->xid = (XID) glxCtx;  /* self pointer */
+
+   return glxCtx;
+}
+
+
+PUBLIC GLXContext
+glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+                  GLXContext shareCtx, Bool direct )
+{
+   XMesaVisual xmvis;
+
    xmvis = find_glx_visual( dpy, visinfo );
    if (!xmvis) {
       /* This visual wasn't found with glXChooseVisual() */
       xmvis = create_glx_visual( dpy, visinfo );
       if (!xmvis) {
          /* unusable visual */
-         _mesa_free(glxCtx);
          return NULL;
       }
    }
 
-   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
-                                   shareCtx ? shareCtx->xmesaContext : NULL);
-   if (!glxCtx->xmesaContext) {
-      _mesa_free(glxCtx);
-      return NULL;
-   }
-
-   glxCtx->isDirect = DEFAULT_DIRECT;
-   glxCtx->currentDpy = dpy;
-   glxCtx->xid = (XID) glxCtx;  /* self pointer */
-
-   return glxCtx;
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
@@ -1083,7 +1091,7 @@ static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
 
 
 /* GLX 1.3 and later */
-Bool
+PUBLIC Bool
 glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
                        GLXDrawable read, GLXContext ctx )
 {
@@ -1179,21 +1187,21 @@ glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
 }
 
 
-Bool
+PUBLIC Bool
 glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
 {
    return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
 }
 
 
-GLXContext
+PUBLIC GLXContext
 glXGetCurrentContext(void)
 {
    return GetCurrentContext();
 }
 
 
-Display *
+PUBLIC Display *
 glXGetCurrentDisplay(void)
 {
    GLXContext glxCtx = glXGetCurrentContext();
@@ -1202,14 +1210,14 @@ glXGetCurrentDisplay(void)
 }
 
 
-Display *
+PUBLIC Display *
 glXGetCurrentDisplayEXT(void)
 {
    return glXGetCurrentDisplay();
 }
 
 
-GLXDrawable
+PUBLIC GLXDrawable
 glXGetCurrentDrawable(void)
 {
    GLXContext gc = glXGetCurrentContext();
@@ -1217,7 +1225,7 @@ glXGetCurrentDrawable(void)
 }
 
 
-GLXDrawable
+PUBLIC GLXDrawable
 glXGetCurrentReadDrawable(void)
 {
    GLXContext gc = glXGetCurrentContext();
@@ -1225,14 +1233,14 @@ glXGetCurrentReadDrawable(void)
 }
 
 
-GLXDrawable
+PUBLIC GLXDrawable
 glXGetCurrentReadDrawableSGI(void)
 {
    return glXGetCurrentReadDrawable();
 }
 
 
-GLXPixmap
+PUBLIC GLXPixmap
 glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
 {
    XMesaVisual v;
@@ -1257,7 +1265,7 @@ glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
 
 /*** GLX_MESA_pixmap_colormap ***/
 
-GLXPixmap
+PUBLIC GLXPixmap
 glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
                         Pixmap pixmap, Colormap cmap )
 {
@@ -1281,7 +1289,7 @@ glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
 }
 
 
-void
+PUBLIC void
 glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
@@ -1294,7 +1302,7 @@ glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
 }
 
 
-void
+PUBLIC void
 glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
                 unsigned long mask )
 {
@@ -1302,13 +1310,13 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
    XMesaContext xm_dst = dst->xmesaContext;
    (void) dpy;
    if (MakeCurrent_PrevContext == src) {
-      _mesa_Flush();
+      glFlush();
    }
-   st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
+   XMesaCopyContext(xm_src, xm_dst, mask);
 }
 
 
-Bool
+PUBLIC Bool
 glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
 {
    int op, ev, err;
@@ -1323,7 +1331,7 @@ glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
 }
 
 
-void
+PUBLIC void
 glXDestroyContext( Display *dpy, GLXContext ctx )
 {
    GLXContext glxCtx = ctx;
@@ -1335,11 +1343,11 @@ glXDestroyContext( Display *dpy, GLXContext ctx )
    MakeCurrent_PrevReadBuffer = 0;
    XMesaDestroyContext( glxCtx->xmesaContext );
    XMesaGarbageCollect();
-   _mesa_free(glxCtx);
+   free(glxCtx);
 }
 
 
-Bool
+PUBLIC Bool
 glXIsDirect( Display *dpy, GLXContext ctx )
 {
    GLXContext glxCtx = ctx;
@@ -1349,7 +1357,7 @@ glXIsDirect( Display *dpy, GLXContext ctx )
 
 
 
-void
+PUBLIC void
 glXSwapBuffers( Display *dpy, GLXDrawable drawable )
 {
    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
@@ -1376,9 +1384,9 @@ glXSwapBuffers( Display *dpy, GLXDrawable drawable )
 
 /*** GLX_MESA_copy_sub_buffer ***/
 
-void
-glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
-                           int x, int y, int width, int height )
+PUBLIC void
+glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
+                     int x, int y, int width, int height)
 {
    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
    if (buffer) {
@@ -1390,7 +1398,7 @@ glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
 }
 
 
-Bool
+PUBLIC Bool
 glXQueryVersion( Display *dpy, int *maj, int *min )
 {
    (void) dpy;
@@ -1607,7 +1615,7 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
 }
 
 
-int
+PUBLIC int
 glXGetConfig( Display *dpy, XVisualInfo *visinfo,
                    int attrib, int *value )
 {
@@ -1637,7 +1645,7 @@ glXGetConfig( Display *dpy, XVisualInfo *visinfo,
 }
 
 
-void
+PUBLIC void
 glXWaitGL( void )
 {
    XMesaContext xmesa = XMesaGetCurrentContext();
@@ -1646,7 +1654,7 @@ glXWaitGL( void )
 
 
 
-void
+PUBLIC void
 glXWaitX( void )
 {
    XMesaContext xmesa = XMesaGetCurrentContext();
@@ -1663,7 +1671,7 @@ get_extensions( void )
 
 
 /* GLX 1.1 and later */
-const char *
+PUBLIC const char *
 glXQueryExtensionsString( Display *dpy, int screen )
 {
    (void) dpy;
@@ -1674,12 +1682,12 @@ glXQueryExtensionsString( Display *dpy, int screen )
 
 
 /* GLX 1.1 and later */
-const char *
+PUBLIC const char *
 glXQueryServerString( Display *dpy, int screen, int name )
 {
    static char version[1000];
-   _mesa_sprintf(version, "%d.%d %s",
-                 SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
+   sprintf(version, "%d.%d %s",
+          SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, xmesa_get_name());
 
    (void) dpy;
    (void) screen;
@@ -1699,12 +1707,12 @@ glXQueryServerString( Display *dpy, int screen, int name )
 
 
 /* GLX 1.1 and later */
-const char *
+PUBLIC const char *
 glXGetClientString( Display *dpy, int name )
 {
    static char version[1000];
-   _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
-                 CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
+   sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
+          CLIENT_MINOR_VERSION, xmesa_get_name());
 
    (void) dpy;
 
@@ -1727,9 +1735,9 @@ glXGetClientString( Display *dpy, int name )
  */
 
 
-int
-glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
-                           int attribute, int *value )
+PUBLIC int
+glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
+                     int attribute, int *value)
 {
    XMesaVisual v = (XMesaVisual) config;
    (void) dpy;
@@ -1742,7 +1750,7 @@ glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
 }
 
 
-GLXFBConfig *
+PUBLIC GLXFBConfig *
 glXGetFBConfigs( Display *dpy, int screen, int *nelements )
 {
    XVisualInfo *visuals, visTemplate;
@@ -1754,13 +1762,17 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements )
    visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
    if (*nelements > 0) {
       XMesaVisual *results;
-      results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual));
+      results = (XMesaVisual *) malloc(*nelements * sizeof(XMesaVisual));
       if (!results) {
          *nelements = 0;
          return NULL;
       }
       for (i = 0; i < *nelements; i++) {
          results[i] = create_glx_visual(dpy, visuals + i);
+         if (!results[i]) {
+            *nelements = i;
+            break;
+         }
       }
       return (GLXFBConfig *) results;
    }
@@ -1768,9 +1780,9 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements )
 }
 
 
-GLXFBConfig *
-glXChooseFBConfig( Display *dpy, int screen,
-                        const int *attribList, int *nitems )
+PUBLIC GLXFBConfig *
+glXChooseFBConfig(Display *dpy, int screen,
+                  const int *attribList, int *nitems)
 {
    XMesaVisual xmvis;
 
@@ -1781,7 +1793,7 @@ glXChooseFBConfig( Display *dpy, int screen,
 
    xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
    if (xmvis) {
-      GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual));
+      GLXFBConfig *config = (GLXFBConfig *) malloc(sizeof(XMesaVisual));
       if (!config) {
          *nitems = 0;
          return NULL;
@@ -1797,7 +1809,7 @@ glXChooseFBConfig( Display *dpy, int screen,
 }
 
 
-XVisualInfo *
+PUBLIC XVisualInfo *
 glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
 {
    if (dpy && config) {
@@ -1806,9 +1818,9 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
       return xmvis->vishandle;
 #else
       /* create a new vishandle - the cached one may be stale */
-      xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
+      xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
       if (xmvis->vishandle) {
-         _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
+         memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
       }
       return xmvis->vishandle;
 #endif
@@ -1819,9 +1831,9 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
 }
 
 
-GLXWindow
-glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
-                      const int *attribList )
+PUBLIC GLXWindow
+glXCreateWindow(Display *dpy, GLXFBConfig config, Window win,
+                const int *attribList)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf;
@@ -1839,7 +1851,7 @@ glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
 }
 
 
-void
+PUBLIC void
 glXDestroyWindow( Display *dpy, GLXWindow window )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
@@ -1850,9 +1862,9 @@ glXDestroyWindow( Display *dpy, GLXWindow window )
 
 
 /* XXX untested */
-GLXPixmap
-glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
-                      const int *attribList )
+PUBLIC GLXPixmap
+glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap,
+                const int *attribList)
 {
    XMesaVisual v = (XMesaVisual) config;
    XMesaBuffer b;
@@ -1960,7 +1972,7 @@ glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
 }
 
 
-void
+PUBLIC void
 glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
@@ -1970,9 +1982,8 @@ glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
 }
 
 
-GLXPbuffer
-glXCreatePbuffer( Display *dpy, GLXFBConfig config,
-                       const int *attribList )
+PUBLIC GLXPbuffer
+glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf;
@@ -2033,7 +2044,7 @@ glXCreatePbuffer( Display *dpy, GLXFBConfig config,
 }
 
 
-void
+PUBLIC void
 glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
@@ -2043,9 +2054,9 @@ glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
 }
 
 
-void
-glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
-                       unsigned int *value )
+PUBLIC void
+glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
+                 unsigned int *value)
 {
    GLuint width, height;
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
@@ -2089,41 +2100,24 @@ glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
 }
 
 
-GLXContext
+PUBLIC GLXContext
 glXCreateNewContext( Display *dpy, GLXFBConfig config,
-                          int renderType, GLXContext shareList, Bool direct )
+                     int renderType, GLXContext shareCtx, Bool direct )
 {
-   GLXContext glxCtx;
-   GLXContext shareCtx = shareList;
    XMesaVisual xmvis = (XMesaVisual) config;
 
    if (!dpy || !config ||
        (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
       return 0;
 
-   glxCtx = CALLOC_STRUCT(__GLXcontextRec);
-   if (!glxCtx)
-      return 0;
-
-   /* deallocate unused windows/buffers */
-   XMesaGarbageCollect();
-
-   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
-                                   shareCtx ? shareCtx->xmesaContext : NULL);
-   if (!glxCtx->xmesaContext) {
-      _mesa_free(glxCtx);
-      return NULL;
-   }
-
-   glxCtx->isDirect = DEFAULT_DIRECT;
-   glxCtx->currentDpy = dpy;
-   glxCtx->xid = (XID) glxCtx;  /* self pointer */
-
-   return glxCtx;
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
-int
+PUBLIC int
 glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
 {
    GLXContext glxCtx = ctx;
@@ -2152,7 +2146,7 @@ glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
 }
 
 
-void
+PUBLIC void
 glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
@@ -2161,9 +2155,8 @@ glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
 }
 
 
-void
-glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
-                          unsigned long *mask )
+PUBLIC void
+glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
    if (xmbuf)
@@ -2176,7 +2169,7 @@ glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
 
 /*** GLX_SGI_swap_control ***/
 
-int
+PUBLIC int
 glXSwapIntervalSGI(int interval)
 {
    (void) interval;
@@ -2189,7 +2182,7 @@ glXSwapIntervalSGI(int interval)
 
 static unsigned int FrameCounter = 0;
 
-int
+PUBLIC int
 glXGetVideoSyncSGI(unsigned int *count)
 {
    /* this is a bogus implementation */
@@ -2197,7 +2190,7 @@ glXGetVideoSyncSGI(unsigned int *count)
    return 0;
 }
 
-int
+PUBLIC int
 glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 {
    if (divisor <= 0 || remainder < 0)
@@ -2214,8 +2207,9 @@ glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 
 /*** GLX_SGI_make_current_read ***/
 
-Bool
-glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+PUBLIC Bool
+glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read,
+                      GLXContext ctx)
 {
    return glXMakeContextCurrent( dpy, draw, read, ctx );
 }
@@ -2232,8 +2226,9 @@ glXGetCurrentReadDrawableSGI(void)
 /*** GLX_SGIX_video_source ***/
 #if defined(_VL_H)
 
-GLXVideoSourceSGIX
-glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
+PUBLIC GLXVideoSourceSGIX
+glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server,
+                            VLPath path, int nodeClass, VLNode drainNode)
 {
    (void) dpy;
    (void) screen;
@@ -2244,7 +2239,7 @@ glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath pa
    return 0;
 }
 
-void
+PUBLIC void
 glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
 {
    (void) dpy;
@@ -2256,21 +2251,21 @@ glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
 
 /*** GLX_EXT_import_context ***/
 
-void
+PUBLIC void
 glXFreeContextEXT(Display *dpy, GLXContext context)
 {
    (void) dpy;
    (void) context;
 }
 
-GLXContextID
+PUBLIC GLXContextID
 glXGetContextIDEXT(const GLXContext context)
 {
    (void) context;
    return 0;
 }
 
-GLXContext
+PUBLIC GLXContext
 glXImportContextEXT(Display *dpy, GLXContextID contextID)
 {
    (void) dpy;
@@ -2278,8 +2273,9 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID)
    return 0;
 }
 
-int
-glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
+PUBLIC int
+glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,
+                       int *value)
 {
    (void) dpy;
    (void) context;
@@ -2292,21 +2288,25 @@ glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *val
 
 /*** GLX_SGIX_fbconfig ***/
 
-int
-glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
+PUBLIC int
+glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
+                         int attribute, int *value)
 {
    return glXGetFBConfigAttrib(dpy, config, attribute, value);
 }
 
-GLXFBConfigSGIX *
-glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
+PUBLIC GLXFBConfigSGIX *
+glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list,
+                      int *nelements)
 {
-   return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements);
+   return (GLXFBConfig *) glXChooseFBConfig(dpy, screen,
+                                            attrib_list, nelements);
 }
 
 
-GLXPixmap
-glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
+PUBLIC GLXPixmap
+glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
+                                 Pixmap pixmap)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
@@ -2314,43 +2314,32 @@ glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pi
 }
 
 
-GLXContext
-glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
+PUBLIC GLXContext
+glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
+                               int renderType, GLXContext shareCtx,
+                               Bool direct)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
-   GLXContext glxCtx;
-   GLXContext shareCtx = share_list;
 
-   glxCtx = CALLOC_STRUCT(__GLXcontextRec);
-   if (!glxCtx)
+   if (!dpy || !config ||
+       (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
       return 0;
 
-   /* deallocate unused windows/buffers */
-   XMesaGarbageCollect();
-
-   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
-                                   shareCtx ? shareCtx->xmesaContext : NULL);
-   if (!glxCtx->xmesaContext) {
-      _mesa_free(glxCtx);
-      return NULL;
-   }
-
-   glxCtx->isDirect = DEFAULT_DIRECT;
-   glxCtx->currentDpy = dpy;
-   glxCtx->xid = (XID) glxCtx;  /* self pointer */
-
-   return glxCtx;
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
-XVisualInfo *
+PUBLIC XVisualInfo *
 glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
 {
    return glXGetVisualFromFBConfig(dpy, config);
 }
 
 
-GLXFBConfigSGIX
+PUBLIC GLXFBConfigSGIX
 glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
 {
    XMesaVisual xmvis = find_glx_visual(dpy, vis);
@@ -2366,10 +2355,10 @@ glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
 
 /*** GLX_SGIX_pbuffer ***/
 
-GLXPbufferSGIX
+PUBLIC GLXPbufferSGIX
 glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
-                             unsigned int width, unsigned int height,
-                             int *attribList)
+                        unsigned int width, unsigned int height,
+                        int *attribList)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf;
@@ -2405,7 +2394,7 @@ glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
 }
 
 
-void
+PUBLIC void
 glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
@@ -2415,8 +2404,9 @@ glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
 }
 
 
-int
-glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
+PUBLIC int
+glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute,
+                       unsigned int *value)
 {
    const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
 
@@ -2448,7 +2438,7 @@ glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigne
 }
 
 
-void
+PUBLIC void
 glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
@@ -2459,8 +2449,9 @@ glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
 }
 
 
-void
-glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
+PUBLIC void
+glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
+                        unsigned long *mask)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
    if (xmbuf) {
@@ -2475,7 +2466,7 @@ glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
 
 /*** GLX_SGI_cushion ***/
 
-void
+PUBLIC void
 glXCushionSGI(Display *dpy, Window win, float cushion)
 {
    (void) dpy;
@@ -2487,8 +2478,9 @@ glXCushionSGI(Display *dpy, Window win, float cushion)
 
 /*** GLX_SGIX_video_resize ***/
 
-int
-glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
+PUBLIC int
+glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel,
+                           Window window)
 {
    (void) dpy;
    (void) screen;
@@ -2497,8 +2489,9 @@ glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window
    return 0;
 }
 
-int
-glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
+PUBLIC int
+glXChannelRectSGIX(Display *dpy, int screen, int channel,
+                   int x, int y, int w, int h)
 {
    (void) dpy;
    (void) screen;
@@ -2510,8 +2503,9 @@ glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, i
    return 0;
 }
 
-int
-glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
+PUBLIC int
+glXQueryChannelRectSGIX(Display *dpy, int screen, int channel,
+                        int *x, int *y, int *w, int *h)
 {
    (void) dpy;
    (void) screen;
@@ -2523,8 +2517,9 @@ glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, i
    return 0;
 }
 
-int
-glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
+PUBLIC int
+glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel,
+                          int *dx, int *dy, int *dw, int *dh)
 {
    (void) dpy;
    (void) screen;
@@ -2536,7 +2531,7 @@ glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *d
    return 0;
 }
 
-int
+PUBLIC int
 glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
 {
    (void) dpy;
@@ -2551,8 +2546,9 @@ glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
 /*** GLX_SGIX_dmbuffer **/
 
 #if defined(_DM_BUFFER_H_)
-Bool
-glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
+PUBLIC Bool
+glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer,
+                          DMparams *params, DMbuffer dmbuffer)
 {
    (void) dpy;
    (void) pbuffer;
@@ -2565,7 +2561,7 @@ glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params
 
 /*** GLX_SGIX_swap_group ***/
 
-void
+PUBLIC void
 glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
 {
    (void) dpy;
@@ -2577,7 +2573,7 @@ glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
 
 /*** GLX_SGIX_swap_barrier ***/
 
-void
+PUBLIC void
 glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
 {
    (void) dpy;
@@ -2585,7 +2581,7 @@ glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
    (void) barrier;
 }
 
-Bool
+PUBLIC Bool
 glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
 {
    (void) dpy;
@@ -2598,8 +2594,9 @@ glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
 
 /*** GLX_SUN_get_transparent_index ***/
 
-Status
-glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
+PUBLIC Status
+glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay,
+                          long *pTransparent)
 {
    (void) dpy;
    (void) overlay;
@@ -2616,7 +2613,7 @@ glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *p
  * Release the depth, stencil, accum buffers attached to a GLXDrawable
  * (a window or pixmap) prior to destroying the GLXDrawable.
  */
-Bool
+PUBLIC Bool
 glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, d);
@@ -2629,7 +2626,7 @@ glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
 
 /*** GLX_EXT_texture_from_pixmap ***/
 
-void
+PUBLIC void
 glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
                         const int *attrib_list)
 {
@@ -2638,10 +2635,105 @@ glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
       XMesaBindTexImage(dpy, b, buffer, attrib_list);
 }
 
-void
+PUBLIC void
 glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
    if (b)
       XMesaReleaseTexImage(dpy, b, buffer);
 }
+
+
+
+/*** GLX_ARB_create_context ***/
+
+GLXContext
+glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
+                           GLXContext shareCtx, Bool direct,
+                           const int *attrib_list)
+{
+   XMesaVisual xmvis = (XMesaVisual) config;
+   int majorVersion = 1, minorVersion = 0;
+   int contextFlags = 0x0;
+   int profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+   int renderType = GLX_RGBA_TYPE;
+   unsigned i;
+   Bool done = False;
+   const int contextFlagsAll = (GLX_CONTEXT_DEBUG_BIT_ARB |
+                                GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
+
+   /* parse attrib_list */
+   for (i = 0; !done && attrib_list[i]; i++) {
+      switch (attrib_list[i]) {
+      case GLX_CONTEXT_MAJOR_VERSION_ARB:
+         majorVersion = attrib_list[++i];
+         break;
+      case GLX_CONTEXT_MINOR_VERSION_ARB:
+         minorVersion = attrib_list[++i];
+         break;
+      case GLX_CONTEXT_FLAGS_ARB:
+         contextFlags = attrib_list[++i];
+         break;
+      case GLX_CONTEXT_PROFILE_MASK_ARB:
+         profileMask = attrib_list[++i];
+         break;
+      case GLX_RENDER_TYPE:
+         renderType = attrib_list[++i];
+         break;
+      case 0:
+         /* end of list */
+         done = True;
+         break;
+      default:
+         /* bad attribute */
+         /* XXX generate BadValue X Error */
+         return NULL;
+      }
+   }
+
+   /* check contextFlags */
+   if (contextFlags & ~contextFlagsAll) {
+      return NULL; /* generate BadValue X Error */
+   }
+
+   /* check profileMask */
+   if (profileMask != GLX_CONTEXT_CORE_PROFILE_BIT_ARB &&
+       profileMask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
+      return NULL; /* generate BadValue X Error */
+   }
+
+   /* check version (generate BadMatch if bad) */
+   switch (majorVersion) {
+   case 1:
+      if (minorVersion < 0 || minorVersion > 5)
+         return NULL;
+      break;
+   case 2:
+      if (minorVersion < 0 || minorVersion > 1)
+         return NULL;
+      break;
+   case 3:
+      if (minorVersion < 0 || minorVersion > 2)
+         return NULL;
+      break;
+   case 4:
+      if (minorVersion < 0 || minorVersion > 0)
+         return NULL;
+      break;
+   default:
+      return NULL;
+   }
+
+   if ((contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
+       majorVersion < 3)
+      return NULL; /* generate GLXBadProfileARB */
+
+   if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3)
+      return NULL; /* generate BadMatch */
+
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         majorVersion, minorVersion,
+                         profileMask, contextFlags);
+}