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;
}
Exemplo n.º 2
0
/*
** 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;
}