static __GLXDRIdrawable * FetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, GLXContext gc) { __GLXdisplayPrivate *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; __GLXscreenConfigs *psc; if (priv == NULL) return NULL; psc = &priv->screenConfigs[gc->screen]; if (psc->drawHash == NULL) return NULL; if (__glxHashLookup(psc->drawHash, glxDrawable, (void *) &pdraw) == 0) return pdraw; pdraw = psc->driScreen->createDrawable(psc, glxDrawable, glxDrawable, gc->mode); if (__glxHashInsert(psc->drawHash, glxDrawable, pdraw)) { (*pdraw->destroyDrawable) (pdraw); return NULL; } return pdraw; }
static GLboolean CreateDRIDrawable(Display *dpy, struct glx_config *config, XID drawable, XID glxdrawable, const int *attrib_list, size_t num_attribs) { struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; struct glx_screen *psc; psc = priv->screens[config->screen]; if (psc->driScreen == NULL) return GL_TRUE; pdraw = psc->driScreen->createDrawable(psc, drawable, glxdrawable, config); if (pdraw == NULL) { fprintf(stderr, "failed to create drawable\n"); return GL_FALSE; } if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) { (*pdraw->destroyDrawable) (pdraw); return GL_FALSE; } pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs); pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs); return GL_TRUE; }
_X_HIDDEN __GLXDRIdrawable * driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable) { struct glx_display *const priv = __glXInitialize(gc->psc->dpy); __GLXDRIdrawable *pdraw; struct glx_screen *psc; if (priv == NULL) return NULL; psc = priv->screens[gc->screen]; if (priv->drawHash == NULL) return NULL; if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) { pdraw->refcount ++; return pdraw; } pdraw = psc->driScreen->createDrawable(psc, glxDrawable, glxDrawable, gc->config); if (pdraw == NULL) { ErrorMessageF("failed to create drawable\n"); return NULL; } if (__glxHashInsert(priv->drawHash, glxDrawable, pdraw)) { (*pdraw->destroyDrawable) (pdraw); return NULL; } pdraw->refcount = 1; return pdraw; }
/* ** Setup for sending a GLX command on dpy. Make sure the extension is ** initialized. Try to avoid calling __glXInitialize as its kinda slow. */ _X_HIDDEN CARD8 __glXSetupForCommand(Display * dpy) { struct glx_context *gc; struct glx_display *priv; /* If this thread has a current context, flush its rendering commands */ gc = __glXGetCurrentContext(); if (gc->currentDpy) { /* Flush rendering buffer of the current context, if any */ (void) __glXFlushRenderBuffer(gc, gc->pc); if (gc->currentDpy == dpy) { /* Use opcode from gc because its right */ return gc->majorOpcode; } else { /* ** Have to get info about argument dpy because it might be to ** a different server */ } } /* Forced to lookup extension via the slow initialize route */ priv = __glXInitialize(dpy); if (!priv) { return 0; } return priv->majorOpcode; }
static int64_t dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, int64_t remainder) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy); __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display; int64_t ret; #ifdef __DRI2_FLUSH if (pdraw->psc->f) (*pdraw->psc->f->flush)(pdraw->driDrawable); #endif /* Old servers don't send invalidate events */ if (!pdp->invalidateAvailable) dri2InvalidateBuffers(dpyPriv->dpy, pdraw->drawable); /* Old servers can't handle swapbuffers */ if (!pdp->swapAvailable) { dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); return 0; } #ifdef X_DRI2SwapBuffers DRI2SwapBuffers(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor, remainder, &ret); #endif return ret; }
void __glXSendError(Display * dpy, int_fast8_t errorCode, uint_fast32_t resourceID, uint_fast16_t minorCode, bool coreX11error) { struct glx_display *glx_dpy = __glXInitialize(dpy); struct glx_context *gc = __glXGetCurrentContext(); xError error; assert(glx_dpy); assert(gc); LockDisplay(dpy); error.type = X_Error; if (coreX11error) { error.errorCode = errorCode; } else { error.errorCode = glx_dpy->codes->first_error + errorCode; } error.sequenceNumber = dpy->request; error.resourceID = resourceID; error.minorCode = minorCode; error.majorCode = gc ? gc->majorOpcode : 0; _XError(dpy, &error); UnlockDisplay(dpy); }
/* We don't actually support this. It doesn't make sense for clients to * send each other GLX events. */ static Status __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire) { struct glx_display *glx_dpy = __glXInitialize(dpy); if (glx_dpy == NULL) return False; switch (event->type) { case GLX_DAMAGED: break; case GLX_SAVED: break; case GLX_EXCHANGE_COMPLETE_INTEL: break; case GLX_COPY_COMPLETE_INTEL: break; case GLX_FLIP_COMPLETE_INTEL: break; default: /* client doesn't support server event */ break; } return Success; }
static boolean x11_screen_init_glx(struct x11_screen *xscr) { if (!xscr->glx_dpy) xscr->glx_dpy = __glXInitialize(xscr->dpy); return (xscr->glx_dpy != NULL); }
static Bool __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) { struct glx_display *glx_dpy = __glXInitialize(dpy); if (glx_dpy == NULL) return False; switch ((wire->u.u.type & 0x7f) - glx_dpy->codes->first_event) { case GLX_PbufferClobber: { GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event; xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire; aevent->event_type = awire->type; aevent->serial = awire->sequenceNumber; aevent->event_type = awire->event_type; aevent->draw_type = awire->draw_type; aevent->drawable = awire->drawable; aevent->buffer_mask = awire->buffer_mask; aevent->aux_buffer = awire->aux_buffer; aevent->x = awire->x; aevent->y = awire->y; aevent->width = awire->width; aevent->height = awire->height; aevent->count = awire->count; return True; } case GLX_BufferSwapComplete: { GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire; struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable); aevent->event_type = awire->event_type; aevent->drawable = awire->drawable; aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; if (!glxDraw) return False; if (awire->sbc < glxDraw->lastEventSbc) glxDraw->eventSbcWrap += 0x100000000; glxDraw->lastEventSbc = awire->sbc; aevent->sbc = awire->sbc + glxDraw->eventSbcWrap; return True; } default: /* client doesn't support server event */ break; } return False; }
/** * Emit a warning when clients use GLX 1.3 functions on pre-1.3 systems. */ static void warn_GLX_1_3(Display * dpy, const char *function_name) { __GLXdisplayPrivate *priv = __glXInitialize(dpy); if (priv->minorVersion < 3) { fprintf(stderr, "WARNING: Application calling GLX 1.3 function \"%s\" " "when GLX 1.3 is not supported! This is an application bug!\n", function_name); } }
/** * This is called from src/glx/dri2.c. */ void dri2InvalidateBuffers(Display *dpy, XID drawable) { __GLXdisplayPrivate *priv = __glXInitialize(dpy); struct x11_screen *xscr = NULL; if (priv && priv->xscr) xscr = priv->xscr; if (!xscr || !xscr->dri_invalidate_buffers) return; xscr->dri_invalidate_buffers(xscr, drawable, xscr->dri_user_data); }
static void dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate) { __GLXDRIdrawablePrivate *pdraw = loaderPrivate; __GLXdisplayPrivate *priv = __glXInitialize(pdraw->base.psc->dpy); __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv->dri2Display; /* Old servers don't send invalidate events */ if (!pdp->invalidateAvailable) dri2InvalidateBuffers(priv->dpy, pdraw->base.drawable); dri2WaitGL(loaderPrivate); }
/** * Change a drawable's attribute. * * This function is used to implement \c glXSelectEvent and * \c glXSelectEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static void ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, const CARD32 * attribs, size_t num_attribs) { __GLXdisplayPrivate *priv = __glXInitialize(dpy); CARD32 *output; CARD8 opcode; if ((dpy == NULL) || (drawable == 0)) { return; } opcode = __glXSetupForCommand(dpy); if (!opcode) return; LockDisplay(dpy); if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXChangeDrawableAttributesReq *req; GetReqExtra(GLXChangeDrawableAttributes, 8 + (8 * num_attribs), req); output = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = X_GLXChangeDrawableAttributes; req->drawable = drawable; req->numAttribs = (CARD32) num_attribs; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra(GLXVendorPrivateWithReply, 4 + (8 * num_attribs), vpreq); output = (CARD32 *) (vpreq + 1); vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX; output[0] = (CARD32) drawable; output++; } (void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs); UnlockDisplay(dpy); SyncHandle(); return; }
static void DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) { struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); XID xid; if (pdraw != NULL) { xid = pdraw->xDrawable; (*pdraw->destroyDrawable) (pdraw); __glxHashDelete(priv->drawHash, drawable); if (destroy_xdrawable) XFreePixmap(priv->dpy, xid); } }
static __GLXDRIdrawable * dri2CreateDrawable(__GLXscreenConfigs * psc, XID xDrawable, GLXDrawable drawable, const __GLcontextModes * modes) { __GLXDRIdrawablePrivate *pdraw; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; __GLXdisplayPrivate *dpyPriv; __GLXDRIdisplayPrivate *pdp; pdraw = Xmalloc(sizeof(*pdraw)); if (!pdraw) return NULL; pdraw->base.destroyDrawable = dri2DestroyDrawable; pdraw->base.xDrawable = xDrawable; pdraw->base.drawable = drawable; pdraw->base.psc = psc; pdraw->bufferCount = 0; pdraw->swap_interval = 1; pdraw->have_back = 0; DRI2CreateDrawable(psc->dpy, xDrawable); dpyPriv = __glXInitialize(psc->dpy); pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;; /* Create a new drawable */ pdraw->base.driDrawable = (*psc->dri2->createNewDrawable) (psc->__driScreen, config->driConfig, pdraw); if (!pdraw->base.driDrawable) { DRI2DestroyDrawable(psc->dpy, xDrawable); Xfree(pdraw); return NULL; } #ifdef X_DRI2SwapInterval /* * Make sure server has the same swap interval we do for the new * drawable. */ if (pdp->swapAvailable) DRI2SwapInterval(psc->dpy, xDrawable, pdraw->swap_interval); #endif return &pdraw->base; }
/** * Destroy a pbuffer. * * This function is used to implement \c glXDestroyPbuffer and * \c glXDestroyGLXPbufferSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. */ static void DestroyPbuffer(Display * dpy, GLXDrawable drawable) { struct glx_display *priv = __glXInitialize(dpy); CARD8 opcode; if ((dpy == NULL) || (drawable == 0)) { return; } opcode = __glXSetupForCommand(dpy); if (!opcode) return; LockDisplay(dpy); if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXDestroyPbufferReq *req; GetReq(GLXDestroyPbuffer, req); req->reqType = opcode; req->glxCode = X_GLXDestroyPbuffer; req->pbuffer = (GLXPbuffer) drawable; } else { xGLXVendorPrivateWithReplyReq *vpreq; CARD32 *data; GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq); data = (CARD32 *) (vpreq + 1); data[0] = (CARD32) drawable; vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX; } UnlockDisplay(dpy); SyncHandle(); DestroyDRIDrawable(dpy, drawable, GL_TRUE); return; }
/** * Destroy a non-pbuffer GLX drawable. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static void DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) { xGLXDestroyPbufferReq *req; CARD8 opcode; if ((dpy == NULL) || (drawable == 0)) { return; } opcode = __glXSetupForCommand(dpy); if (!opcode) return; LockDisplay(dpy); GetReqExtra(GLXDestroyPbuffer, 4, req); req->reqType = opcode; req->glxCode = glxCode; req->pbuffer = (GLXPbuffer) drawable; UnlockDisplay(dpy); SyncHandle(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) { int screen; __GLXdisplayPrivate *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs *psc = &priv->screenConfigs[screen]; if (pdraw != NULL) { (*pdraw->destroyDrawable) (pdraw); __glxHashDelete(psc->drawHash, drawable); } } #endif return; }
/* * Return pointer to the __GLXvisualConfig specified by dpy, scrn and vid. * Return NULL if not found. */ static __GLXvisualConfig * __driFindGlxConfig(Display *dpy, int scrn, VisualID vid) { __GLXdisplayPrivate *priv; __GLXscreenConfigs *glxScrnConfigs; __GLXvisualConfig *glxConfigs; int numConfigs, i; priv = __glXInitialize(dpy); assert(priv); glxScrnConfigs = priv->screenConfigs; assert(glxScrnConfigs); numConfigs = glxScrnConfigs[scrn].numConfigs; glxConfigs = glxScrnConfigs[scrn].configs; for (i = 0; i < numConfigs; i++) { if (glxConfigs[i].vid == vid) { return glxConfigs +i; } } return NULL; }
/** * Get a drawable's attribute. * * This function is used to implement \c glXGetSelectedEvent and * \c glXGetSelectedEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. * * \todo * The number of attributes returned is likely to be small, probably less than * 10. Given that, this routine should try to use an array on the stack to * capture the reply rather than always calling Xmalloc. */ static int GetDrawableAttribute(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { struct glx_display *priv; xGLXGetDrawableAttributesReply reply; CARD32 *data; CARD8 opcode; unsigned int length; unsigned int i; unsigned int num_attributes; GLboolean use_glx_1_3; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) __GLXDRIdrawable *pdraw; #endif if (dpy == NULL) return 0; /* Page 38 (page 52 of the PDF) of glxencode1.3.pdf says: * * "If drawable is not a valid GLX drawable, a GLXBadDrawable error is * generated." */ if (drawable == 0) { __glXSendError(dpy, GLXBadDrawable, 0, X_GLXGetDrawableAttributes, false); return 0; } priv = __glXInitialize(dpy); if (priv == NULL) return 0; use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3)); *value = 0; opcode = __glXSetupForCommand(dpy); if (!opcode) return 0; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) pdraw = GetGLXDRIDrawable(dpy, drawable); if (attribute == GLX_BACK_BUFFER_AGE_EXT) { struct glx_context *gc = __glXGetCurrentContext(); struct glx_screen *psc; /* The GLX_EXT_buffer_age spec says: * * "If querying GLX_BACK_BUFFER_AGE_EXT and <draw> is not bound to * the calling thread's current context a GLXBadDrawable error is * generated." */ if (pdraw == NULL || gc == &dummyContext || gc->currentDpy != dpy || (gc->currentDrawable != drawable && gc->currentReadable != drawable)) { __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes, false); return 0; } psc = pdraw->psc; if (psc->driScreen->getBufferAge != NULL) *value = psc->driScreen->getBufferAge(pdraw); return 0; } #endif LockDisplay(dpy); if (use_glx_1_3) { xGLXGetDrawableAttributesReq *req; GetReq(GLXGetDrawableAttributes, req); req->reqType = opcode; req->glxCode = X_GLXGetDrawableAttributes; req->drawable = drawable; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq); data = (CARD32 *) (vpreq + 1); data[0] = (CARD32) drawable; vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX; } _XReply(dpy, (xReply *) & reply, 0, False); if (reply.type == X_Error) { UnlockDisplay(dpy); SyncHandle(); return 0; } length = reply.length; if (length) { num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2; data = malloc(length * sizeof(CARD32)); if (data == NULL) { /* Throw data on the floor */ _XEatData(dpy, length); } else { _XRead(dpy, (char *) data, length * sizeof(CARD32)); /* Search the set of returned attributes for the attribute requested by * the caller. */ for (i = 0; i < num_attributes; i++) { if (data[i * 2] == attribute) { *value = data[(i * 2) + 1]; break; } } #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) if (pdraw != NULL) { if (!pdraw->textureTarget) pdraw->textureTarget = determineTextureTarget((const int *) data, num_attributes); if (!pdraw->textureFormat) pdraw->textureFormat = determineTextureFormat((const int *) data, num_attributes); } #endif free(data); } } UnlockDisplay(dpy); SyncHandle(); return 0; }
/** * Called via eglInitialize(), xdri_dpy->API.Initialize(). */ static EGLBoolean xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *minor, EGLint *major) { struct xdri_egl_display *xdri_dpy; __GLXdisplayPrivate *dpyPriv; __GLXDRIdisplay *driDisplay; __GLXscreenConfigs *psc; EGLint first_id = 1; int scr; xdri_dpy = CALLOC_STRUCT(xdri_egl_display); if (!xdri_dpy) return _eglError(EGL_BAD_ALLOC, "eglInitialize"); xdri_dpy->dpy = (Display *) dpy->NativeDisplay; if (!xdri_dpy->dpy) { xdri_dpy->dpy = XOpenDisplay(NULL); if (!xdri_dpy->dpy) { free(xdri_dpy); return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } } dpyPriv = __glXInitialize(xdri_dpy->dpy); if (!dpyPriv) { _eglLog(_EGL_WARNING, "failed to create GLX display"); free(xdri_dpy); return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } driDisplay = __driCreateDisplay(dpyPriv, NULL); if (!driDisplay) { _eglLog(_EGL_WARNING, "failed to create DRI display"); free(xdri_dpy); return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } scr = DefaultScreen(xdri_dpy->dpy); psc = &dpyPriv->screenConfigs[scr]; xdri_dpy->dpyPriv = dpyPriv; xdri_dpy->driDisplay = driDisplay; xdri_dpy->psc = psc; xdri_dpy->scr = scr; psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv); if (!psc->driScreen) { _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr); free(xdri_dpy); return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } /* add visuals and fbconfigs */ first_id = create_configs(dpy, psc->visuals, first_id); create_configs(dpy, psc->configs, first_id); dpy->DriverData = xdri_dpy; dpy->ClientAPIsMask = (EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT); /* we're supporting EGL 1.4 */ *minor = 1; *major = 4; return EGL_TRUE; }
/** * Create a pbuffer. * * This function is used to implement \c glXCreatePbuffer and * \c glXCreateGLXPbufferSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static GLXDrawable CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, unsigned int width, unsigned int height, const int *attrib_list, GLboolean size_in_attribs) { __GLXdisplayPrivate *priv = __glXInitialize(dpy); GLXDrawable id = 0; CARD32 *data; CARD8 opcode; unsigned int i; i = 0; if (attrib_list) { while (attrib_list[i * 2]) i++; } opcode = __glXSetupForCommand(dpy); if (!opcode) return None; LockDisplay(dpy); id = XAllocID(dpy); if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXCreatePbufferReq *req; unsigned int extra = (size_in_attribs) ? 0 : 2; GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req); data = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = X_GLXCreatePbuffer; req->screen = (CARD32) fbconfig->screen; req->fbconfig = fbconfig->fbconfigID; req->pbuffer = (GLXPbuffer) id; req->numAttribs = (CARD32) (i + extra); if (!size_in_attribs) { data[(2 * i) + 0] = GLX_PBUFFER_WIDTH; data[(2 * i) + 1] = width; data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT; data[(2 * i) + 3] = height; data += 4; } } else { xGLXVendorPrivateReq *vpreq; GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq); data = (CARD32 *) (vpreq + 1); vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivate; vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX; data[0] = (CARD32) fbconfig->screen; data[1] = (CARD32) fbconfig->fbconfigID; data[2] = (CARD32) id; data[3] = (CARD32) width; data[4] = (CARD32) height; data += 5; } (void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i); UnlockDisplay(dpy); SyncHandle(); return id; }
/** * Create a non-pbuffer GLX drawable. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static GLXDrawable CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, Drawable drawable, const int *attrib_list, CARD8 glxCode) { xGLXCreateWindowReq *req; CARD32 *data; unsigned int i; CARD8 opcode; i = 0; if (attrib_list) { while (attrib_list[i * 2] != None) i++; } opcode = __glXSetupForCommand(dpy); if (!opcode) return None; LockDisplay(dpy); GetReqExtra(GLXCreateWindow, 8 * i, req); data = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = glxCode; req->screen = (CARD32) fbconfig->screen; req->fbconfig = fbconfig->fbconfigID; req->window = (CARD32) drawable; req->glxwindow = (GLXWindow) XAllocID(dpy); req->numAttribs = (CARD32) i; if (attrib_list) memcpy(data, attrib_list, 8 * i); UnlockDisplay(dpy); SyncHandle(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) do { /* FIXME: Maybe delay __DRIdrawable creation until the drawable * is actually bound to a context... */ __GLXdisplayPrivate *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; __GLXscreenConfigs *psc; psc = &priv->screenConfigs[fbconfig->screen]; if (psc->driScreen == NULL) break; pdraw = psc->driScreen->createDrawable(psc, drawable, req->glxwindow, fbconfig); if (pdraw == NULL) { fprintf(stderr, "failed to create drawable\n"); break; } if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) { (*pdraw->destroyDrawable) (pdraw); return None; /* FIXME: Check what we're supposed to do here... */ } pdraw->textureTarget = determineTextureTarget(attrib_list, i); pdraw->textureFormat = determineTextureFormat(attrib_list, i); } while (0); #endif return (GLXDrawable) req->glxwindow; }
/** * Get a drawable's attribute. * * This function is used to implement \c glXGetSelectedEvent and * \c glXGetSelectedEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. * * \todo * The number of attributes returned is likely to be small, probably less than * 10. Given that, this routine should try to use an array on the stack to * capture the reply rather than always calling Xmalloc. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static int GetDrawableAttribute(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { __GLXdisplayPrivate *priv; xGLXGetDrawableAttributesReply reply; CARD32 *data; CARD8 opcode; unsigned int length; unsigned int i; unsigned int num_attributes; GLboolean use_glx_1_3; if ((dpy == NULL) || (drawable == 0)) { return 0; } priv = __glXInitialize(dpy); use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3)); *value = 0; opcode = __glXSetupForCommand(dpy); if (!opcode) return 0; LockDisplay(dpy); if (use_glx_1_3) { xGLXGetDrawableAttributesReq *req; GetReqExtra(GLXGetDrawableAttributes, 4, req); req->reqType = opcode; req->glxCode = X_GLXGetDrawableAttributes; req->drawable = drawable; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq); data = (CARD32 *) (vpreq + 1); data[0] = (CARD32) drawable; vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX; } _XReply(dpy, (xReply *) & reply, 0, False); if (reply.type == X_Error) { UnlockDisplay(dpy); SyncHandle(); return 0; } length = reply.length; if (length) { num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2; data = (CARD32 *) Xmalloc(length * sizeof(CARD32)); if (data == NULL) { /* Throw data on the floor */ _XEatData(dpy, length); } else { _XRead(dpy, (char *) data, length * sizeof(CARD32)); /* Search the set of returned attributes for the attribute requested by * the caller. */ for (i = 0; i < num_attributes; i++) { if (data[i * 2] == attribute) { *value = data[(i * 2) + 1]; break; } } #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); if (pdraw != NULL && !pdraw->textureTarget) pdraw->textureTarget = determineTextureTarget((const int *) data, num_attributes); if (pdraw != NULL && !pdraw->textureFormat) pdraw->textureFormat = determineTextureFormat((const int *) data, num_attributes); } #endif Xfree(data); } } UnlockDisplay(dpy); SyncHandle(); return 0; }
/** * Sends a GLX protocol message to the specified display to make the context * and the drawables current. * * \param dpy Display to send the message to. * \param opcode Major opcode value for the display. * \param gc_id Context tag for the context to be made current. * \param draw Drawable ID for the "draw" drawable. * \param read Drawable ID for the "read" drawable. * \param reply Space to store the X-server's reply. * * \warning * This function assumes that \c dpy is locked with \c LockDisplay on entry. */ static Bool SendMakeCurrentRequest(Display * dpy, CARD8 opcode, GLXContextID gc_id, GLXContextTag gc_tag, GLXDrawable draw, GLXDrawable read, xGLXMakeCurrentReply * reply) { Bool ret; LockDisplay(dpy); if (draw == read) { xGLXMakeCurrentReq *req; GetReq(GLXMakeCurrent, req); req->reqType = opcode; req->glxCode = X_GLXMakeCurrent; req->drawable = draw; req->context = gc_id; req->oldContextTag = gc_tag; } else { __GLXdisplayPrivate *priv = __glXInitialize(dpy); /* If the server can support the GLX 1.3 version, we should * perfer that. Not only that, some servers support GLX 1.3 but * not the SGI extension. */ if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXMakeContextCurrentReq *req; GetReq(GLXMakeContextCurrent, req); req->reqType = opcode; req->glxCode = X_GLXMakeContextCurrent; req->drawable = draw; req->readdrawable = read; req->context = gc_id; req->oldContextTag = gc_tag; } else { xGLXVendorPrivateWithReplyReq *vpreq; xGLXMakeCurrentReadSGIReq *req; GetReqExtra(GLXVendorPrivateWithReply, sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq, vpreq); req = (xGLXMakeCurrentReadSGIReq *) vpreq; req->reqType = opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_MakeCurrentReadSGI; req->drawable = draw; req->readable = read; req->context = gc_id; req->oldContextTag = gc_tag; } } ret = _XReply(dpy, (xReply *) reply, 0, False); UnlockDisplay(dpy); SyncHandle(); return ret; }
/** * Get a drawable's attribute. * * This function is used to implement \c glXGetSelectedEvent and * \c glXGetSelectedEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. * * \todo * The number of attributes returned is likely to be small, probably less than * 10. Given that, this routine should try to use an array on the stack to * capture the reply rather than always calling Xmalloc. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static int GetDrawableAttribute( Display *dpy, GLXDrawable drawable, int attribute, unsigned int *value ) { __GLXdisplayPrivate *priv = __glXInitialize(dpy); xGLXGetDrawableAttributesReply reply; CARD32 * data; unsigned int length; unsigned int i; unsigned int num_attributes; GLboolean use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3)); if ( (dpy == NULL) || (drawable == 0) ) { return 0; } LockDisplay(dpy); if ( use_glx_1_3 ) { xGLXGetDrawableAttributesReq *req; GetReqExtra( GLXGetDrawableAttributes, 4, req ); req->reqType = __glXSetupForCommand(dpy); req->glxCode = X_GLXGetDrawableAttributes; req->drawable = drawable; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra( GLXVendorPrivateWithReply, 4, vpreq ); data = (CARD32 *) (vpreq + 1); data[0] = (CARD32) drawable; vpreq->reqType = __glXSetupForCommand(dpy); vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX; } _XReply(dpy, (xReply*) &reply, 0, False); length = reply.length; num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2; data = (CARD32 *) Xmalloc( length * sizeof(CARD32) ); if ( data == NULL ) { /* Throw data on the floor */ _XEatData(dpy, length); } else { _XRead(dpy, (char *)data, length * sizeof(CARD32) ); } UnlockDisplay(dpy); SyncHandle(); /* Search the set of returned attributes for the attribute requested by * the caller. */ for ( i = 0 ; i < num_attributes ; i++ ) { if ( data[i*2] == attribute ) { *value = data[ (i*2) + 1 ]; break; } } Xfree( data ); return 0; }
/** * Change a drawable's attribute. * * This function is used to implement \c glXSelectEvent and * \c glXSelectEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. */ static void ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, const CARD32 * attribs, size_t num_attribs) { struct glx_display *priv = __glXInitialize(dpy); #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw; #endif CARD32 *output; CARD8 opcode; int i; if ((dpy == NULL) || (drawable == 0)) { return; } opcode = __glXSetupForCommand(dpy); if (!opcode) return; LockDisplay(dpy); if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXChangeDrawableAttributesReq *req; GetReqExtra(GLXChangeDrawableAttributes, 8 * num_attribs, req); output = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = X_GLXChangeDrawableAttributes; req->drawable = drawable; req->numAttribs = (CARD32) num_attribs; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra(GLXVendorPrivateWithReply, 8 + (8 * num_attribs), vpreq); output = (CARD32 *) (vpreq + 1); vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX; output[0] = (CARD32) drawable; output[1] = num_attribs; output += 2; } (void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs); UnlockDisplay(dpy); SyncHandle(); #ifdef GLX_DIRECT_RENDERING pdraw = GetGLXDRIDrawable(dpy, drawable); if (!pdraw) return; for (i = 0; i < num_attribs; i++) { switch(attribs[i * 2]) { case GLX_EVENT_MASK: /* Keep a local copy for masking out DRI2 proto events as needed */ pdraw->eventMask = attribs[i * 2 + 1]; break; } } #endif return; }
/** * Create a pbuffer. * * This function is used to implement \c glXCreatePbuffer and * \c glXCreateGLXPbufferSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. */ static GLXDrawable CreatePbuffer(Display * dpy, struct glx_config *config, unsigned int width, unsigned int height, const int *attrib_list, GLboolean size_in_attribs) { struct glx_display *priv = __glXInitialize(dpy); GLXDrawable id = 0; CARD32 *data; CARD8 opcode; unsigned int i; Pixmap pixmap; GLboolean glx_1_3 = GL_FALSE; i = 0; if (attrib_list) { while (attrib_list[i * 2]) i++; } opcode = __glXSetupForCommand(dpy); if (!opcode) return None; LockDisplay(dpy); id = XAllocID(dpy); if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXCreatePbufferReq *req; unsigned int extra = (size_in_attribs) ? 0 : 2; glx_1_3 = GL_TRUE; GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req); data = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = X_GLXCreatePbuffer; req->screen = config->screen; req->fbconfig = config->fbconfigID; req->pbuffer = id; req->numAttribs = i + extra; if (!size_in_attribs) { data[(2 * i) + 0] = GLX_PBUFFER_WIDTH; data[(2 * i) + 1] = width; data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT; data[(2 * i) + 3] = height; data += 4; } } else { xGLXVendorPrivateReq *vpreq; GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq); data = (CARD32 *) (vpreq + 1); vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivate; vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX; data[0] = config->screen; data[1] = config->fbconfigID; data[2] = id; data[3] = width; data[4] = height; data += 5; } (void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i); UnlockDisplay(dpy); SyncHandle(); pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen), width, height, config->rgbBits); if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) { CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX; XFreePixmap(dpy, pixmap); protocolDestroyDrawable(dpy, id, o); id = None; } return id; }