/* * XextRemoveDisplay - remove the indicated display from the extension object */ int XextRemoveDisplay (XExtensionInfo *extinfo, Display *dpy) { XExtDisplayInfo *dpyinfo, *prev; /* * locate this display and its back link so that it can be removed */ _XLockMutex(_Xglobal_lock); prev = NULL; for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { if (dpyinfo->display == dpy) break; prev = dpyinfo; } if (!dpyinfo) { _XUnlockMutex(_Xglobal_lock); return 0; /* hmm, actually an error */ } /* * remove the display from the list; handles going to zero */ if (prev) prev->next = dpyinfo->next; else extinfo->head = dpyinfo->next; extinfo->ndisplays--; if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */ _XUnlockMutex(_Xglobal_lock); Xfree ((char *) dpyinfo); return 1; }
/* * XextFindDisplay - look for a display in this extension; keeps a cache * of the most-recently used for efficiency. */ XExtDisplayInfo *XextFindDisplay (XExtensionInfo *extinfo, Display *dpy) { register XExtDisplayInfo *dpyinfo; /* * see if this was the most recently accessed display */ if ((dpyinfo = extinfo->cur)&& dpyinfo->display == dpy) return dpyinfo; /* * look for display in list */ _XLockMutex(_Xglobal_lock); for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { if (dpyinfo->display == dpy) { extinfo->cur = dpyinfo; /* cache most recently used */ _XUnlockMutex(_Xglobal_lock); return dpyinfo; } } _XUnlockMutex(_Xglobal_lock); return NULL; }
/* * XFixesExtFindDisplay - look for a display in this extension; keeps a * cache of the most-recently used for efficiency. (Replaces * XextFindDisplay.) */ static XFixesExtDisplayInfo * XFixesExtFindDisplay (XFixesExtInfo *extinfo, Display *dpy) { XFixesExtDisplayInfo *info; /* * see if this was the most recently accessed display */ if ((info = extinfo->cur) && info->display == dpy) return info; /* * look for display in list */ _XLockMutex(_Xglobal_lock); for (info = extinfo->head; info; info = info->next) { if (info->display == dpy) { extinfo->cur = info; /* cache most recently used */ _XUnlockMutex(_Xglobal_lock); return info; } } _XUnlockMutex(_Xglobal_lock); return NULL; }
void XSetAuthorization ( char *name, int namelen, /* *len are lengths of name and data */ char *data, int datalen) /* name/data are NULL or arbitrary array of bytes */ { char *tmpname, *tmpdata; _XLockMutex(_Xglobal_lock); if (xauth_name) Xfree (xauth_name); /* free any existing data */ if (xauth_data) Xfree (xauth_data); xauth_name = xauth_data = NULL; /* mark it no longer valid */ xauth_namelen = xauth_datalen = 0; _XUnlockMutex(_Xglobal_lock); if (namelen < 0) namelen = 0; /* check for bogus inputs */ if (datalen < 0) datalen = 0; /* maybe should return? */ if (namelen > 0) { /* try to allocate space */ tmpname = Xmalloc ((unsigned) namelen); if (!tmpname) return; memcpy (tmpname, name, namelen); } else { tmpname = NULL; } if (datalen > 0) { tmpdata = Xmalloc ((unsigned) datalen); if (!tmpdata) { if (tmpname) (void) Xfree (tmpname); return; } memcpy (tmpdata, data, datalen); } else { tmpdata = NULL; } _XLockMutex(_Xglobal_lock); xauth_name = tmpname; /* and store the suckers */ xauth_namelen = namelen; if (tmpname) { xauth_names = &xauth_name; xauth_lengths = &xauth_namelen; xauth_names_length = 1; } else { xauth_names = default_xauth_names; xauth_lengths = default_xauth_lengths; xauth_names_length = NUM_DEFAULT_AUTH; } xauth_data = tmpdata; xauth_datalen = datalen; _XUnlockMutex(_Xglobal_lock); return; }
/* hook to delete XMesaDisplay on XDestroyDisplay */ extern void xmesa_close_display(Display *display) { XMesaExtDisplayInfo *info, *prev; /* These assertions are not valid since screen creation can fail and result * in an empty list assert(MesaExtInfo.ndisplays > 0); assert(MesaExtInfo.head); */ _XLockMutex(_Xglobal_lock); /* first find display */ prev = NULL; for (info = MesaExtInfo.head; info; info = info->next) { if (info->display == display) { prev = info; break; } } if (info == NULL) { /* no display found */ _XUnlockMutex(_Xglobal_lock); return; } /* remove display entry from list */ if (prev != MesaExtInfo.head) { prev->next = info->next; } else { MesaExtInfo.head = info->next; } MesaExtInfo.ndisplays--; _XUnlockMutex(_Xglobal_lock); /* don't forget to clean up mesaDisplay */ XMesaDisplay xmdpy = &info->mesaDisplay; /** * XXX: Don't destroy the screens here, since there may still * be some dangling screen pointers that are used after this point * if (xmdpy->screen) { * xmdpy->screen->destroy(xmdpy->screen); * } */ if (xmdpy->smapi->destroy) xmdpy->smapi->destroy(xmdpy->smapi); free(xmdpy->smapi); XFree((char *) info); }
/* * XRenderExtAddDisplay - add a display to this extension. (Replaces * XextAddDisplay) */ static XRenderExtDisplayInfo * XRenderExtAddDisplay (XRenderExtInfo *extinfo, Display *dpy, char *ext_name) { XRenderExtDisplayInfo *dpyinfo; dpyinfo = (XRenderExtDisplayInfo *) Xmalloc (sizeof (XRenderExtDisplayInfo)); if (!dpyinfo) return NULL; dpyinfo->display = dpy; dpyinfo->info = NULL; if (XRenderHasDepths (dpy)) dpyinfo->codes = XInitExtension (dpy, ext_name); else dpyinfo->codes = NULL; /* * if the server has the extension, then we can initialize the * appropriate function vectors */ if (dpyinfo->codes) { XESetCloseDisplay (dpy, dpyinfo->codes->extension, XRenderCloseDisplay); } else { /* 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, XRenderCloseDisplay); } /* * 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; }
static int XRenderDepthCheckErrorHandler (Display *dpy, XErrorEvent *evt) { if (evt->request_code == X_CreatePixmap && evt->error_code == BadValue) { DepthCheckPtr d; _XLockMutex(_Xglobal_lock); for (d = depthChecks; d; d = d->next) if (d->dpy == dpy) { if ((long) (evt->serial - d->serial) >= 0) d->missing |= DEPTH_MASK(evt->resourceid); break; } _XUnlockMutex (_Xglobal_lock); } return 0; }
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; }
XLCd _XOpenLC( char *name) { XLCd lcd; XlcLoaderList loader; XLCdList cur; #if !defined(X_LOCALE) int len; char sinamebuf[256]; char* siname = sinamebuf; #endif if (name == NULL) { name = setlocale (LC_CTYPE, (char *)NULL); #if !defined(X_LOCALE) /* * _XlMapOSLocaleName will return the same string or a substring * of name, so strlen(name) is okay */ if ((len = strlen(name)) >= sizeof sinamebuf) { siname = Xmalloc (len + 1); if (siname == NULL) return NULL; } name = _XlcMapOSLocaleName(name, siname); #endif } _XLockMutex(_Xi18n_lock); /* * search for needed lcd, if found return it */ for (cur = lcd_list; cur; cur = cur->next) { if (!strcmp (cur->lcd->core->name, name)) { lcd = cur->lcd; cur->ref_count++; goto found; } } if (!loader_list) _XlcInitLoader(); /* * not there, so try to get and add to list */ for (loader = loader_list; loader; loader = loader->next) { lcd = (*loader->proc)(name); if (lcd) { cur = (XLCdList) Xmalloc (sizeof(XLCdListRec)); if (cur) { cur->lcd = lcd; cur->ref_count = 1; cur->next = lcd_list; lcd_list = cur; } else { (*lcd->methods->close)(lcd); lcd = (XLCd) NULL; } goto found; } } lcd = NULL; found: _XUnlockMutex(_Xi18n_lock); #if !defined(X_LOCALE) if (siname != sinamebuf) Xfree(siname); #endif return lcd; }
/* * XCompositeExtAddDisplay - add a display to this extension. (Replaces * XextAddDisplay) */ static XCompositeExtDisplayInfo * XCompositeExtAddDisplay (XCompositeExtInfo *extinfo, Display *dpy, const char *ext_name) { XCompositeExtDisplayInfo *info; info = (XCompositeExtDisplayInfo *) Xmalloc (sizeof (XCompositeExtDisplayInfo)); if (!info) return NULL; info->display = dpy; info->codes = XInitExtension (dpy, ext_name); /* * if the server has the extension, then we can initialize the * appropriate function vectors */ if (info->codes) { xCompositeQueryVersionReply rep; xCompositeQueryVersionReq *req; XESetCloseDisplay (dpy, info->codes->extension, XCompositeCloseDisplay); /* * Get the version info */ LockDisplay (dpy); GetReq (CompositeQueryVersion, req); req->reqType = info->codes->major_opcode; req->compositeReqType = X_CompositeQueryVersion; req->majorVersion = COMPOSITE_MAJOR; req->minorVersion = COMPOSITE_MINOR; if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { UnlockDisplay (dpy); SyncHandle (); Xfree(info); return NULL; } info->major_version = rep.majorVersion; info->minor_version = rep.minorVersion; UnlockDisplay (dpy); SyncHandle (); } else { /* 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(info); return NULL; } XESetCloseDisplay (dpy, codes->extension, XCompositeCloseDisplay); } /* * now, chain it onto the list */ _XLockMutex(_Xglobal_lock); info->next = extinfo->head; extinfo->head = info; extinfo->cur = info; extinfo->ndisplays++; _XUnlockMutex(_Xglobal_lock); return info; }
int XSaveContext( Display *display, register XID rid, register XContext context, _Xconst char* data) { DB *pdb; register DB db; TableEntry *head; register TableEntry entry; #ifdef MOTIFBC if (!display) { pdb = &NullDB; db = *pdb; } else #endif { LockDisplay(display); pdb = &display->context_db; db = *pdb; UnlockDisplay(display); } if (!db) { db = Xmalloc(sizeof(DBRec)); if (!db) return XCNOMEM; db->mask = INITHASHMASK; db->table = Xcalloc(db->mask + 1, sizeof(TableEntry)); if (!db->table) { Xfree((char *)db); return XCNOMEM; } db->numentries = 0; _XCreateMutex(&db->linfo); #ifdef MOTIFBC if (!display) *pdb = db; else #endif { LockDisplay(display); *pdb = db; display->free_funcs->context_db = _XFreeContextDB; UnlockDisplay(display); } } _XLockMutex(&db->linfo); head = &Hash(db, rid, context); _XUnlockMutex(&db->linfo); for (entry = *head; entry; entry = entry->next) { if (entry->rid == rid && entry->context == context) { entry->data = (XPointer)data; return 0; } } entry = Xmalloc(sizeof(TableEntryRec)); if (!entry) return XCNOMEM; entry->rid = rid; entry->context = context; entry->data = (XPointer)data; entry->next = *head; *head = entry; _XLockMutex(&db->linfo); db->numentries++; if (db->numentries > (db->mask << 2)) ResizeTable(db); _XUnlockMutex(&db->linfo); return 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; }
static XMesaDisplay xmesa_init_display( Display *display ) { static mtx_t init_mutex = _MTX_INITIALIZER_NP; XMesaDisplay xmdpy; XMesaExtDisplayInfo *info; if (display == NULL) { return NULL; } mtx_lock(&init_mutex); /* Look for XMesaDisplay which corresponds to this display */ info = MesaExtInfo.head; while(info) { if (info->display == display) { /* Found it */ mtx_unlock(&init_mutex); return &info->mesaDisplay; } info = info->next; } /* Not found. Create new XMesaDisplay */ /* first allocate X-related resources and hook destroy callback */ /* allocate mesa display info */ info = (XMesaExtDisplayInfo *) Xmalloc(sizeof(XMesaExtDisplayInfo)); if (info == NULL) { mtx_unlock(&init_mutex); return NULL; } info->display = display; xmdpy = &info->mesaDisplay; /* to be filled out below */ xmdpy->display = display; xmdpy->pipe = NULL; xmdpy->smapi = CALLOC_STRUCT(st_manager); if (!xmdpy->smapi) { Xfree(info); mtx_unlock(&init_mutex); return NULL; } xmdpy->screen = driver.create_pipe_screen(display); if (!xmdpy->screen) { free(xmdpy->smapi); Xfree(info); mtx_unlock(&init_mutex); return NULL; } /* At this point, both smapi and screen are known to be valid */ xmdpy->smapi->screen = xmdpy->screen; xmdpy->smapi->get_param = xmesa_get_param; (void) mtx_init(&xmdpy->mutex, mtx_plain); /* chain to the list of displays */ _XLockMutex(_Xglobal_lock); info->next = MesaExtInfo.head; MesaExtInfo.head = info; MesaExtInfo.ndisplays++; _XUnlockMutex(_Xglobal_lock); mtx_unlock(&init_mutex); return xmdpy; }
/* * 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; }
static Bool XRenderHasDepths (Display *dpy) { int s; for (s = 0; s < ScreenCount (dpy); s++) { CARD32 depths = 0; CARD32 missing; Screen *scr = ScreenOfDisplay (dpy, s); int d; for (d = 0; d < scr->ndepths; d++) depths |= DEPTH_MASK(scr->depths[d].depth); missing = ~depths & REQUIRED_DEPTHS; if (missing) { DepthCheckRec dc, **dp; XErrorHandler previousHandler; /* * Ok, this is ugly. It should be sufficient at this * point to just return False, but Xinerama is broken at * this point and only advertises depths which have an * associated visual. Of course, the other depths still * work, but the only way to find out is to try them. */ dc.dpy = dpy; dc.missing = 0; dc.serial = XNextRequest (dpy); _XLockMutex(_Xglobal_lock); dc.next = depthChecks; depthChecks = &dc; _XUnlockMutex (_Xglobal_lock); /* * I suspect this is not really thread safe, but Xlib doesn't * provide a lot of options here */ previousHandler = XSetErrorHandler (XRenderDepthCheckErrorHandler); /* * Try each missing depth and see if pixmap creation succeeds */ for (d = 1; d <= 32; d++) /* don't check depth 1 == Xcursor recurses... */ if ((missing & DEPTH_MASK(d)) && d != 1) { Pixmap p; p = XCreatePixmap (dpy, RootWindow (dpy, s), 1, 1, d); XFreePixmap (dpy, p); } XSync (dpy, False); XSetErrorHandler (previousHandler); /* * Unhook from the list of depth check records */ _XLockMutex(_Xglobal_lock); for (dp = &depthChecks; *dp; dp = &(*dp)->next) { if (*dp == &dc) { *dp = dc.next; break; } } _XUnlockMutex (_Xglobal_lock); if (dc.missing) return False; } } return True; }
int /*ARGSUSED*/ XGetErrorDatabaseText( Display *dpy, register _Xconst char *name, register _Xconst char *type, _Xconst char *defaultp, char *buffer, int nbytes) { static XrmDatabase db = NULL; XrmString type_str; XrmValue result; char temp[BUFSIZ]; char* tptr; unsigned long tlen; if (nbytes == 0) return 0; if (!db) { /* the Xrm routines expect to be called with the global mutex unlocked. */ XrmDatabase temp_db; int do_destroy; const char *dbname; XrmInitialize(); #ifdef WIN32 dbname = getenv("XERRORDB"); if (!dbname) dbname = ERRORDB; #else dbname = ERRORDB; #endif temp_db = XrmGetFileDatabase(dbname); _XLockMutex(_Xglobal_lock); if (!db) { db = temp_db; do_destroy = 0; } else do_destroy = 1; /* we didn't need to get it after all */ _XUnlockMutex(_Xglobal_lock); if (do_destroy) XrmDestroyDatabase(temp_db); } if (db) { tlen = strlen (name) + strlen (type) + 2; if (tlen <= sizeof(temp)) tptr = temp; else tptr = Xmalloc (tlen); if (tptr) { sprintf(tptr, "%s.%s", name, type); XrmGetResource(db, tptr, "ErrorType.ErrorNumber", &type_str, &result); if (tptr != temp) Xfree (tptr); } else { result.addr = (XPointer) NULL; } } else result.addr = (XPointer)NULL; if (!result.addr) { result.addr = (XPointer) defaultp; result.size = strlen(defaultp) + 1; } (void) strncpy (buffer, (char *) result.addr, nbytes); if (result.size > nbytes) buffer[nbytes-1] = '\0'; return 0; }