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; }
/* ** Initialize the client side extension code. */ _X_HIDDEN struct glx_display * __glXInitialize(Display * dpy) { struct glx_display *dpyPriv, *d; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) Bool glx_direct, glx_accel; #endif int i; _XLockMutex(_Xglobal_lock); for (dpyPriv = glx_displays; dpyPriv; dpyPriv = dpyPriv->next) { if (dpyPriv->dpy == dpy) { _XUnlockMutex(_Xglobal_lock); return dpyPriv; } } /* Drop the lock while we create the display private. */ _XUnlockMutex(_Xglobal_lock); dpyPriv = calloc(1, sizeof *dpyPriv); if (!dpyPriv) return NULL; dpyPriv->codes = XInitExtension(dpy, __glXExtensionName); if (!dpyPriv->codes) { free(dpyPriv); _XUnlockMutex(_Xglobal_lock); return NULL; } dpyPriv->dpy = dpy; dpyPriv->majorOpcode = dpyPriv->codes->major_opcode; dpyPriv->serverGLXvendor = 0x0; dpyPriv->serverGLXversion = 0x0; /* See if the versions are compatible. This GLX implementation does not * work with servers that only support GLX 1.0. */ if (!QueryVersion(dpy, dpyPriv->majorOpcode, &dpyPriv->majorVersion, &dpyPriv->minorVersion) || (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion < 1)) { free(dpyPriv); _XUnlockMutex(_Xglobal_lock); return NULL; } for (i = 0; i < __GLX_NUMBER_EVENTS; i++) { XESetWireToEvent(dpy, dpyPriv->codes->first_event + i, __glXWireToEvent); XESetEventToWire(dpy, dpyPriv->codes->first_event + i, __glXEventToWire); } XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay); XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString); dpyPriv->glXDrawHash = __glxHashCreate(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL); glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL); dpyPriv->drawHash = __glxHashCreate(); /* ** Initialize the direct rendering per display data and functions. ** Note: This _must_ be done before calling any other DRI routines ** (e.g., those called in AllocAndFetchScreenConfigs). */ if (glx_direct && glx_accel) { #if defined(HAVE_DRI3) if (!getenv("LIBGL_DRI3_DISABLE")) dpyPriv->dri3Display = dri3_create_display(dpy); #endif dpyPriv->dri2Display = dri2CreateDisplay(dpy); dpyPriv->driDisplay = driCreateDisplay(dpy); } if (glx_direct) dpyPriv->driswDisplay = driswCreateDisplay(dpy); #endif #ifdef GLX_USE_APPLEGL if (!applegl_create_display(dpyPriv)) { free(dpyPriv); return NULL; } #endif if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { free(dpyPriv); return NULL; } __glX_send_client_info(dpyPriv); /* 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; _XUnlockMutex(_Xglobal_lock); return dpyPriv; }