/* ** 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; }
/* * XextAddDisplay - add a display to this extension */ XExtDisplayInfo *XextAddDisplay ( XExtensionInfo *extinfo, Display *dpy, _Xconst char *ext_name, XExtensionHooks *hooks, int nevents, XPointer data) { XExtDisplayInfo *dpyinfo; dpyinfo = (XExtDisplayInfo *) Xmalloc (sizeof (XExtDisplayInfo)); if (!dpyinfo) return NULL; dpyinfo->display = dpy; dpyinfo->data = data; dpyinfo->codes = XInitExtension (dpy, ext_name); /* * if the server has the extension, then we can initialize the * appropriate function vectors */ if (dpyinfo->codes) { int i, j; for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) { XESetWireToEvent (dpy, j, hooks->wire_to_event); XESetEventToWire (dpy, j, hooks->event_to_wire); } /* register extension for XGE */ if (strcmp(ext_name, GE_NAME)) xgeExtRegister(dpy, dpyinfo->codes->major_opcode, hooks); if (hooks->create_gc) XESetCreateGC (dpy, dpyinfo->codes->extension, hooks->create_gc); if (hooks->copy_gc) XESetCopyGC (dpy, dpyinfo->codes->extension, hooks->copy_gc); if (hooks->flush_gc) XESetFlushGC (dpy, dpyinfo->codes->extension, hooks->flush_gc); if (hooks->free_gc) XESetFreeGC (dpy, dpyinfo->codes->extension, hooks->free_gc); if (hooks->create_font) XESetCreateFont (dpy, dpyinfo->codes->extension, hooks->create_font); if (hooks->free_font) XESetFreeFont (dpy, dpyinfo->codes->extension, hooks->free_font); if (hooks->close_display) XESetCloseDisplay (dpy, dpyinfo->codes->extension, hooks->close_display); if (hooks->error) XESetError (dpy, dpyinfo->codes->extension, hooks->error); if (hooks->error_string) XESetErrorString (dpy, dpyinfo->codes->extension, hooks->error_string); } else if (hooks->close_display) { /* The server doesn't have this extension. * Use a private Xlib-internal extension to hang the close_display * hook on so that the "cache" (extinfo->cur) is properly cleaned. * (XBUG 7955) */ XExtCodes *codes = XAddExtension(dpy); if (!codes) { XFree(dpyinfo); return NULL; } XESetCloseDisplay (dpy, codes->extension, hooks->close_display); } /* * now, chain it onto the list */ _XLockMutex(_Xglobal_lock); dpyinfo->next = extinfo->head; extinfo->head = dpyinfo; extinfo->cur = dpyinfo; extinfo->ndisplays++; _XUnlockMutex(_Xglobal_lock); return dpyinfo; }