glx: fix GLXChangeDrawableAttributesSGIX request
[mesa.git] / src / glx / glxext.c
index b02755a6c2c861252733cedf1370a5366c6ed90f..c5e9d0510b68ff61aaafdbe5af4fb912f7df0932 100644 (file)
@@ -41,7 +41,6 @@
 #include "glxclient.h"
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
-#include <X11/extensions/dri2proto.h>
 #ifdef GLX_USE_APPLEGL
 #include "apple_glx.h"
 #include "apple_visual.h"
@@ -56,7 +55,7 @@
 
 
 #ifdef DEBUG
-void __glXDumpDrawBuffer(__GLXcontext * ctx);
+void __glXDumpDrawBuffer(struct glx_context * ctx);
 #endif
 
 /*
@@ -68,7 +67,7 @@ _X_HIDDEN int __glXDebug = 0;
 /* Extension required boiler plate */
 
 static const char __glXExtensionName[] = GLX_EXTENSION_NAME;
-static __GLXdisplayPrivate *glx_displays;
+  static struct glx_display *glx_displays;
 
 static /* const */ char *error_list[] = {
    "GLXBadContext",
@@ -107,7 +106,7 @@ XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
 static Bool
 __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 {
-   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);
+     struct glx_display *glx_dpy = __glXInitialize(dpy);
 
    if (glx_dpy == NULL)
       return False;
@@ -131,16 +130,6 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
       aevent->count = awire->count;
       return True;
    }
-   /* No easy symbol to test for this, as GLX_BufferSwapComplete is
-    * defined in the local glx.h header, but the
-    * xGLXBufferSwapComplete typedef is only available in new versions
-    * of the external glxproto.h header, which doesn't have any
-    * testable versioning define.
-    *
-    * I'll use the related DRI2 define, in the hope that we won't
-    * receive these events unless we know how to ask for them:
-    */
-#ifdef X_DRI2SwapBuffers
    case GLX_BufferSwapComplete:
    {
       GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
@@ -152,7 +141,6 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
       aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
       return True;
    }
-#endif
    default:
       /* client doesn't support server event */
       break;
@@ -167,7 +155,7 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 static Status
 __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
 {
-   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);
+     struct glx_display *glx_dpy = __glXInitialize(dpy);
 
    if (glx_dpy == NULL)
       return False;
@@ -197,15 +185,15 @@ __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
 ** __glXScreenConfigs.
 */
 static void
-FreeScreenConfigs(__GLXdisplayPrivate * priv)
+FreeScreenConfigs(struct glx_display * priv)
 {
-   __GLXscreenConfigs *psc;
+   struct glx_screen *psc;
    GLint i, screens;
 
    /* Free screen configuration information */
    screens = ScreenCount(priv->dpy);
    for (i = 0; i < screens; i++) {
-      psc = priv->screenConfigs[i];
+      psc = priv->screens[i];
       if (psc->configs) {
         glx_config_destroy_list(psc->configs);
          if (psc->effectiveGLXexts)
@@ -228,32 +216,17 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)
       Xfree(psc);
 #endif
    }
-   XFree((char *) priv->screenConfigs);
-   priv->screenConfigs = NULL;
+   XFree((char *) priv->screens);
+   priv->screens = NULL;
 }
 
-/*
-** Release the private memory referred to in a display private
-** structure.  The caller will free the extension structure.
-*/
-static int
-__glXCloseDisplay(Display * dpy, XExtCodes * codes)
+static void
+glx_display_free(struct glx_display *priv)
 {
-   __GLXdisplayPrivate *priv, **prev;
-   GLXContext gc;
-
-   _XLockMutex(_Xglobal_lock);
-   prev = &glx_displays;
-   for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) {
-      if (priv->dpy == dpy) {
-        (*prev)->next = priv->next;
-        break;
-      }
-   }
-   _XUnlockMutex(_Xglobal_lock);
+   struct glx_context *gc;
 
    gc = __glXGetCurrentContext();
-   if (dpy == gc->currentDpy) {
+   if (priv->dpy == gc->currentDpy) {
       gc->vtable->destroy(gc);
       __glXSetCurrentContextNull();
    }
@@ -264,9 +237,9 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes)
    if (priv->serverGLXversion)
       Xfree((char *) priv->serverGLXversion);
 
+#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    __glxHashDestroy(priv->drawHash);
 
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    /* Free the direct rendering per display data */
    if (priv->driswDisplay)
       (*priv->driswDisplay->destroyDisplay) (priv->driswDisplay);
@@ -282,6 +255,24 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes)
 #endif
 
    Xfree((char *) priv);
+}
+
+static int
+__glXCloseDisplay(Display * dpy, XExtCodes * codes)
+{
+   struct glx_display *priv, **prev;
+
+   _XLockMutex(_Xglobal_lock);
+   prev = &glx_displays;
+   for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) {
+      if (priv->dpy == dpy) {
+        (*prev) = priv->next;
+        break;
+      }
+   }
+   _XUnlockMutex(_Xglobal_lock);
+
+   glx_display_free(priv);
 
    return 1;
 }
@@ -646,8 +637,8 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
 }
 
 static GLboolean
-getVisualConfigs(__GLXscreenConfigs *psc,
-                __GLXdisplayPrivate *priv, int screen)
+getVisualConfigs(struct glx_screen *psc,
+                 struct glx_display *priv, int screen)
 {
    xGLXGetVisualConfigsReq *req;
    xGLXGetVisualConfigsReply reply;
@@ -675,7 +666,7 @@ getVisualConfigs(__GLXscreenConfigs *psc,
 }
 
 static GLboolean
-getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
+ getFBConfigs(struct glx_screen *psc, struct glx_display *priv, int screen)
 {
    xGLXGetFBConfigsReq *fb_req;
    xGLXGetFBConfigsSGIXReq *sgi_req;
@@ -722,8 +713,8 @@ getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
 }
 
 _X_HIDDEN Bool
-glx_screen_init(__GLXscreenConfigs *psc,
-               int screen, __GLXdisplayPrivate * priv)
+glx_screen_init(struct glx_screen *psc,
+                int screen, struct glx_display * priv)
 {
    /* Initialize per screen dynamic client GLX extensions */
    psc->ext_list_first_time = GL_TRUE;
@@ -742,17 +733,17 @@ glx_screen_init(__GLXscreenConfigs *psc,
 ** If that works then fetch the per screen configs data.
 */
 static Bool
-AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
+AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv)
 {
-   __GLXscreenConfigs *psc;
+   struct glx_screen *psc;
    GLint i, screens;
 
    /*
     ** First allocate memory for the array of per screen configs.
     */
    screens = ScreenCount(dpy);
-   priv->screenConfigs = Xmalloc(screens * sizeof *priv->screenConfigs);
-   if (!priv->screenConfigs)
+   priv->screens = Xmalloc(screens * sizeof *priv->screens);
+   if (!priv->screens)
       return GL_FALSE;
 
    priv->serverGLXversion =
@@ -771,10 +762,14 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
         psc = (*priv->driDisplay->createScreen) (i, priv);
       if (psc == NULL && priv->driswDisplay)
         psc = (*priv->driswDisplay->createScreen) (i, priv);
+#endif
+#if defined(GLX_USE_APPLEGL)
+      if (psc == NULL && priv->appleglDisplay)
+        psc = (*priv->appleglDisplay->createScreen) (i, priv);
 #endif
       if (psc == NULL)
         psc = indirect_create_screen(i, priv);
-      priv->screenConfigs[i] = psc;
+      priv->screens[i] = psc;
    }
    SyncHandle();
    return GL_TRUE;
@@ -783,10 +778,10 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
 /*
 ** Initialize the client side extension code.
 */
-_X_HIDDEN __GLXdisplayPrivate *
+ _X_HIDDEN struct glx_display *
 __glXInitialize(Display * dpy)
 {
-   __GLXdisplayPrivate *dpyPriv;
+   struct glx_display *dpyPriv, *d;
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    Bool glx_direct, glx_accel;
 #endif
@@ -801,6 +796,9 @@ __glXInitialize(Display * dpy)
       }
    }
 
+   /* Drop the lock while we create the display private. */
+   _XUnlockMutex(_Xglobal_lock);
+
    dpyPriv = Xcalloc(1, sizeof *dpyPriv);
    if (!dpyPriv)
       return NULL;
@@ -853,7 +851,7 @@ __glXInitialize(Display * dpy)
 #endif
 
 #ifdef GLX_USE_APPLEGL
-   if (apple_init_glx(dpy)) {
+   if (!applegl_create_display(dpyPriv)) {
       Xfree(dpyPriv);
       return NULL;
    }
@@ -866,6 +864,18 @@ __glXInitialize(Display * dpy)
    if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1)
       __glXClientInfo(dpy, dpyPriv->majorOpcode);
 
+   /* Grab the lock again and add the dispay private, unless somebody
+    * beat us to initializing on this display in the meantime. */
+   _XLockMutex(_Xglobal_lock);
+
+   for (d = glx_displays; d; d = d->next) {
+      if (d->dpy == dpy) {
+        _XUnlockMutex(_Xglobal_lock);
+        glx_display_free(dpyPriv);
+        return d;
+      }
+   }
+
    dpyPriv->next = glx_displays;
    glx_displays = dpyPriv;
 
@@ -881,8 +891,8 @@ __glXInitialize(Display * dpy)
 _X_HIDDEN CARD8
 __glXSetupForCommand(Display * dpy)
 {
-   GLXContext gc;
-   __GLXdisplayPrivate *priv;
+    struct glx_context *gc;
+    struct glx_display *priv;
 
    /* If this thread has a current context, flush its rendering commands */
    gc = __glXGetCurrentContext();
@@ -921,7 +931,7 @@ __glXSetupForCommand(Display * dpy)
  * \c pc parameter.
  */
 _X_HIDDEN GLubyte *
-__glXFlushRenderBuffer(__GLXcontext * ctx, GLubyte * pc)
+__glXFlushRenderBuffer(struct glx_context * ctx, GLubyte * pc)
 {
    Display *const dpy = ctx->currentDpy;
 #ifdef USE_XCB
@@ -972,7 +982,7 @@ __glXFlushRenderBuffer(__GLXcontext * ctx, GLubyte * pc)
  * \param dataLen        Size, in bytes, of the command data.
  */
 _X_HIDDEN void
-__glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber,
+__glXSendLargeChunk(struct glx_context * gc, GLint requestNumber,
                     GLint totalRequests, const GLvoid * data, GLint dataLen)
 {
    Display *dpy = gc->currentDpy;
@@ -1021,7 +1031,7 @@ __glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber,
  * \param dataLen    Size, in bytes, of the command data.
  */
 _X_HIDDEN void
-__glXSendLargeCommand(__GLXcontext * ctx,
+__glXSendLargeCommand(struct glx_context * ctx,
                       const GLvoid * header, GLint headerLen,
                       const GLvoid * data, GLint dataLen)
 {
@@ -1063,7 +1073,7 @@ __glXSendLargeCommand(__GLXcontext * ctx,
 
 #ifdef DEBUG
 _X_HIDDEN void
-__glXDumpDrawBuffer(__GLXcontext * ctx)
+__glXDumpDrawBuffer(struct glx_context * ctx)
 {
    GLubyte *p = ctx->buf;
    GLubyte *end = ctx->pc;