void DRISurfaceNotify(xp_surface_id id, int kind) { DRIDrawablePrivPtr pDRIDrawablePriv = NULL; DRISurfaceNotifyArg arg; arg.id = id; arg.kind = kind; if (surface_hash != NULL) { pDRIDrawablePriv = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(id), NULL); } if (pDRIDrawablePriv == NULL) return; if (kind == AppleDRISurfaceNotifyDestroyed) { pDRIDrawablePriv->sid = 0; x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id)); } x_hook_run(pDRIDrawablePriv->notifiers, &arg); if (kind == AppleDRISurfaceNotifyDestroyed) { /* Kill off the handle. */ FreeResourceByType(pDRIDrawablePriv->pDraw->id, DRIDrawablePrivResType, FALSE); } }
/* * Given the id of a physical window, try to find the top-level (or root) * X window that it represents. */ WindowPtr xprGetXWindowFromAppKit(int windowNumber) { RootlessWindowRec *winRec; Bool ret; xp_window_id wid; if (window_hash == NULL) return FALSE; /* need to lock, since this function can be called by any thread */ pthread_mutex_lock(&window_hash_mutex); if (xp_lookup_native_window(windowNumber, &wid)) ret = xprGetXWindow(wid) != NULL; else ret = FALSE; pthread_mutex_unlock(&window_hash_mutex); if (!ret) return NULL; winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); return winRec != NULL ? winRec->win : NULL; }
/* * Note: this also cleans up the hash table in addition to notifying clients. * The sid/surface-id should not be used after this, because it will be * invalid. */ void DRISurfaceNotify(xp_surface_id id, int kind) { DRIDrawablePrivPtr pDRIDrawablePriv = NULL; DRISurfaceNotifyArg arg; arg.id = id; arg.kind = kind; if (surface_hash != NULL) { pDRIDrawablePriv = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(id), NULL); } if (pDRIDrawablePriv == NULL) return; if (kind == AppleDRISurfaceNotifyDestroyed) { x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id)); } x_hook_run(pDRIDrawablePriv->notifiers, &arg); if (kind == AppleDRISurfaceNotifyDestroyed) { xp_error error; error = xp_destroy_surface(pDRIDrawablePriv->sid); if(error) ErrorF("%s: xp_destroy_surface failed: %d\n", __func__, error); /* Guard against reuse, even though we are freeing after this. */ pDRIDrawablePriv->sid = 0; FreeResourceByType(pDRIDrawablePriv->pDraw->id, DRIDrawablePrivResType, FALSE); } }
/* * Given the id of a physical window, try to find the top-level (or root) * X window that it represents. */ WindowPtr xprGetXWindow(xp_window_id wid) { RootlessWindowRec *winRec; if (window_hash == NULL) return NULL; winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); return winRec != NULL ? winRec->win : NULL; }
Bool DRIDrawablePrivDelete(pointer pResource, XID id) { DrawablePtr pDrawable = (DrawablePtr)pResource; DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen); DRIDrawablePrivPtr pDRIDrawablePriv = NULL; WindowPtr pWin = NULL; PixmapPtr pPix = NULL; if (pDrawable->type == DRAWABLE_WINDOW) { pWin = (WindowPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); } else if (pDrawable->type == DRAWABLE_PIXMAP) { pPix = (PixmapPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); } if (pDRIDrawablePriv == NULL) { return DRIFreePixmapImp(pDrawable); } if (pDRIDrawablePriv->drawableIndex != -1) { /* release drawable table entry */ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL; } if (pDRIDrawablePriv->sid != 0) { xp_destroy_surface(pDRIDrawablePriv->sid); x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid)); } if (pDRIDrawablePriv->notifiers != NULL) x_hook_free(pDRIDrawablePriv->notifiers); xfree(pDRIDrawablePriv); if (pDrawable->type == DRAWABLE_WINDOW) { dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL); } else if (pDrawable->type == DRAWABLE_PIXMAP) { dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL); } --pDRIPriv->nrWindows; return TRUE; }
static int ProcAppleDRICreateSurface(ClientPtr client) { xAppleDRICreateSurfaceReply rep; DrawablePtr pDrawable; xp_surface_id sid; unsigned int key[2]; int rc; REQUEST(xAppleDRICreateSurfaceReq); REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, DixReadAccess); if (rc != Success) return rc; rep.key_0 = rep.key_1 = rep.uid = 0; if (!DRICreateSurface(screenInfo.screens[stuff->screen], (Drawable)stuff->drawable, pDrawable, stuff->client_id, &sid, key, surface_notify, x_cvt_uint_to_vptr(client->index))) { return BadValue; } rep.key_0 = key[0]; rep.key_1 = key[1]; rep.uid = sid; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.key_0); swapl(&rep.key_1); swapl(&rep.uid); } WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep); return Success; }
Bool DRICreateSurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, xp_client_id client_id, xp_surface_id *surface_id, unsigned int ret_key[2], void (*notify) (void *arg, void *data), void *notify_data) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); xp_window_id wid = 0; DRIDrawablePrivPtr pDRIDrawablePriv; if (pDrawable->type == DRAWABLE_WINDOW) { pDRIDrawablePriv = CreateSurfaceForWindow(pScreen, (WindowPtr)pDrawable, &wid); if(NULL == pDRIDrawablePriv) return FALSE; /*error*/ } #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 else if (pDrawable->type == DRAWABLE_PIXMAP) { pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen, (PixmapPtr)pDrawable); if(NULL == pDRIDrawablePriv) return FALSE; /*error*/ } #endif else { /* for GLX 1.3, a PBuffer */ /* NOT_DONE */ return FALSE; } /* Finish initialization of new surfaces */ if (pDRIDrawablePriv->refCount == 0) { unsigned int key[2] = {0}; xp_error err; /* try to give the client access to the surface */ if (client_id != 0) { /* * Xplugin accepts a 0 wid if the surface id is offscreen, such * as for a pixmap. */ err = xp_export_surface(wid, pDRIDrawablePriv->sid, client_id, key); if (err != Success) { xp_destroy_surface(pDRIDrawablePriv->sid); xfree(pDRIDrawablePriv); /* * Now set the dix privates to NULL that were previously set. * This prevents reusing an invalid pointer. */ if(pDrawable->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDrawable; dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL); } else if(pDrawable->type == DRAWABLE_PIXMAP) { PixmapPtr pPix = (PixmapPtr)pDrawable; dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL); } return FALSE; } } pDRIDrawablePriv->key[0] = key[0]; pDRIDrawablePriv->key[1] = key[1]; ++pDRIPriv->nrWindows; /* and stash it by surface id */ if (surface_hash == NULL) surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL); x_hash_table_insert(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid), pDRIDrawablePriv); /* track this in case this window is destroyed */ AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable); /* Initialize shape */ DRIUpdateSurface(pDRIDrawablePriv, pDrawable); } pDRIDrawablePriv->refCount++; *surface_id = pDRIDrawablePriv->sid; if (ret_key != NULL) { ret_key[0] = pDRIDrawablePriv->key[0]; ret_key[1] = pDRIDrawablePriv->key[1]; } if (notify != NULL) { pDRIDrawablePriv->notifiers = x_hook_add(pDRIDrawablePriv->notifiers, notify, notify_data); } return TRUE; }