/** * 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; for ( i = 0 ; attrib_list[i * 2] != None ; i++ ) /* empty */ ; LockDisplay(dpy); GetReqExtra( GLXCreateWindow, 20 + (8 * i), req ); data = (CARD32 *) (req + 1); req->reqType = __glXSetupForCommand(dpy); req->glxCode = glxCode; req->screen = (CARD32) fbconfig->screen; req->fbconfig = fbconfig->fbconfigID; req->window = (GLXPbuffer) drawable; req->numAttribs = (CARD32) i; UnlockDisplay(dpy); SyncHandle(); return drawable; }
static int indirect_bind_context(struct glx_context *gc, struct glx_context *old, GLXDrawable draw, GLXDrawable read) { GLXContextTag tag; __GLXattribute *state; Display *dpy = gc->psc->dpy; int opcode = __glXSetupForCommand(dpy); Bool sent; if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) { tag = old->currentContextTag; old->currentContextTag = 0; } else { tag = 0; } sent = SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, &gc->currentContextTag); if (!IndirectAPI) IndirectAPI = __glXNewIndirectAPI(); _glapi_set_dispatch(IndirectAPI); state = gc->client_state_private; if (state->array_state == NULL) { glGetString(GL_EXTENSIONS); glGetString(GL_VERSION); __glXInitVertexArrayState(gc); } return !sent; }
/** * 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(); return; }
/** * 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; if ( (dpy == NULL) || (drawable == 0) ) { 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 = __glXSetupForCommand(dpy); 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 = __glXSetupForCommand(dpy); 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; }
/** * Create a non-pbuffer GLX drawable. */ static GLXDrawable CreateDrawable(Display *dpy, struct glx_config *config, Drawable drawable, const int *attrib_list, CARD8 glxCode) { xGLXCreateWindowReq *req; struct glx_drawable *glxDraw; CARD32 *data; unsigned int i; CARD8 opcode; GLXDrawable xid; i = 0; if (attrib_list) { while (attrib_list[i * 2] != None) i++; } opcode = __glXSetupForCommand(dpy); if (!opcode) return None; glxDraw = malloc(sizeof(*glxDraw)); if (!glxDraw) return None; LockDisplay(dpy); GetReqExtra(GLXCreateWindow, 8 * i, req); data = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = glxCode; req->screen = config->screen; req->fbconfig = config->fbconfigID; req->window = drawable; req->glxwindow = xid = XAllocID(dpy); req->numAttribs = i; if (attrib_list) memcpy(data, attrib_list, 8 * i); UnlockDisplay(dpy); SyncHandle(); if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) { free(glxDraw); return None; } if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) { if (glxCode == X_GLXCreatePixmap) glxCode = X_GLXDestroyPixmap; else glxCode = X_GLXDestroyWindow; protocolDestroyDrawable(dpy, xid, glxCode); xid = None; } return xid; }
/** * 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. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static void DestroyPbuffer( Display * dpy, GLXDrawable drawable ) { __GLXdisplayPrivate *priv = __glXInitialize(dpy); if ( (dpy == NULL) || (drawable == 0) ) { return; } LockDisplay(dpy); if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { xGLXDestroyPbufferReq * req; GetReqExtra( GLXDestroyPbuffer, 4, req ); req->reqType = __glXSetupForCommand(dpy); 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 = __glXSetupForCommand(dpy); vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX; } UnlockDisplay(dpy); SyncHandle(); return; }
static void __glXGenerateError(Display * dpy, XID resource, BYTE errorCode, CARD16 minorCode) { xError error; error.errorCode = errorCode; error.resourceID = resource; error.sequenceNumber = dpy->request; error.type = X_Error; error.majorCode = __glXSetupForCommand(dpy); error.minorCode = minorCode; _XError(dpy, &error); }
static void protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode) { xGLXDestroyPbufferReq *req; CARD8 opcode; opcode = __glXSetupForCommand(dpy); if (!opcode) return; LockDisplay(dpy); GetReq(GLXDestroyPbuffer, req); req->reqType = opcode; req->glxCode = glxCode; req->pbuffer = (GLXPbuffer) drawable; UnlockDisplay(dpy); SyncHandle(); }
/** * 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; }
/** * 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 = (GLXPbuffer) drawable; req->glxwindow = (GLXWindow) XAllocID(dpy); req->numAttribs = (CARD32) i; memcpy( data, attrib_list, 8 * i ); UnlockDisplay(dpy); SyncHandle(); return (GLXDrawable)req->glxwindow; }
/** * 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; }
state = gc->client_state_private; if (state->array_state == NULL) { glGetString(GL_EXTENSIONS); glGetString(GL_VERSION); __glXInitVertexArrayState(gc); } return !sent; } static void indirect_unbind_context(struct glx_context *gc, struct glx_context *new) { Display *dpy = gc->psc->dpy; int opcode = __glXSetupForCommand(dpy); if (gc == new) return; /* We are either switching to no context, away from a indirect * context to a direct context or from one dpy to another and have * to send a request to the dpy to unbind the previous context. */ if (!new || new->isDirect || new->psc->dpy != dpy) { SendMakeCurrentRequest(dpy, opcode, None, gc->currentContextTag, None, None, NULL); gc->currentContextTag = 0; } }
/** * 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; }
/** * Make a particular context current. * * \note This is in this file so that it can access dummyContext. */ static Bool MakeContextCurrent(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext gc) { const GLXContext oldGC = __glXGetCurrentContext(); #ifdef GLX_USE_APPLEGL bool error = apple_glx_make_current_context(dpy, (oldGC && oldGC != &dummyContext) ? oldGC->apple : NULL, gc ? gc->apple : NULL, draw); apple_glx_diagnostic("%s: error %s\n", __func__, error ? "YES" : "NO"); if(error) return GL_FALSE; #else xGLXMakeCurrentReply reply; const CARD8 opcode = __glXSetupForCommand(dpy); const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext)) ? opcode : __glXSetupForCommand(oldGC->currentDpy); Bool bindReturnValue; __GLXattribute *state; if (!opcode || !oldOpcode) { return GL_FALSE; } /* Make sure that the new context has a nonzero ID. In the request, * a zero context ID is used only to mean that we bind to no current * context. */ if ((gc != NULL) && (gc->xid == None)) { return GL_FALSE; } if (gc == NULL && (draw != None || read != None)) { __glXGenerateError(dpy, gc, (draw != None) ? draw : read, BadMatch, X_GLXMakeContextCurrent); return False; } if (gc != NULL && (draw == None || read == None)) { __glXGenerateError(dpy, gc, None, BadMatch, X_GLXMakeContextCurrent); return False; } _glapi_check_multithread(); if (gc != NULL && gc->thread_id != 0 && gc->thread_id != _glthread_GetID()) { __glXGenerateError(dpy, gc, gc->xid, BadAccess, X_GLXMakeContextCurrent); return False; } #ifdef GLX_DIRECT_RENDERING /* Bind the direct rendering context to the drawable */ if (gc && gc->driContext) { __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc); __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc); if ((pdraw == NULL) || (pread == NULL)) { __glXGenerateError(dpy, gc, (pdraw == NULL) ? draw : read, GLXBadDrawable, X_GLXMakeContextCurrent); return False; } bindReturnValue = (gc->driContext->bindContext) (gc->driContext, pdraw, pread); } else if (!gc && oldGC && oldGC->driContext) { bindReturnValue = True; } else #endif { /* Send a glXMakeCurrent request to bind the new context. */ bindReturnValue = SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None, ((dpy != oldGC->currentDpy) || oldGC->isDirect) ? None : oldGC->currentContextTag, draw, read, &reply); } if (!bindReturnValue) { return False; } #ifdef GLX_DIRECT_RENDERING if ((dpy != oldGC->currentDpy || (gc && gc->driContext)) && !oldGC->isDirect && oldGC != &dummyContext) { #else if ((dpy != oldGC->currentDpy) && oldGC != &dummyContext) { #endif xGLXMakeCurrentReply dummy_reply; /* We are either switching from one dpy to another and have to * send a request to the previous dpy to unbind the previous * context, or we are switching away from a indirect context to * a direct context and have to send a request to the dpy to * unbind the previous context. */ (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None, oldGC->currentContextTag, None, None, &dummy_reply); } #ifdef GLX_DIRECT_RENDERING else if (oldGC->driContext && oldGC != gc) { oldGC->driContext->unbindContext(oldGC->driContext); } #endif #endif /* GLX_USE_APPLEGL */ /* Update our notion of what is current */ __glXLock(); if (gc == oldGC) { /* Even though the contexts are the same the drawable might have * changed. Note that gc cannot be the dummy, and that oldGC * cannot be NULL, therefore if they are the same, gc is not * NULL and not the dummy. */ if(gc) { gc->currentDrawable = draw; gc->currentReadable = read; } } else { if (oldGC != &dummyContext) { /* Old current context is no longer current to anybody */ oldGC->currentDpy = 0; oldGC->currentDrawable = None; oldGC->currentReadable = None; oldGC->currentContextTag = 0; oldGC->thread_id = 0; #ifdef GLX_USE_APPLEGL /* * At this point we should check if the context has been * through glXDestroyContext, and redestroy it if so. */ if(oldGC->do_destroy) { __glXUnlock(); /* glXDestroyContext uses the same global lock. */ glXDestroyContext(dpy, oldGC); __glXLock(); #else if (oldGC->xid == None) { /* We are switching away from a context that was * previously destroyed, so we need to free the memory * for the old handle. */ #ifdef GLX_DIRECT_RENDERING /* Destroy the old direct rendering context */ if (oldGC->driContext) { oldGC->driContext->destroyContext(oldGC->driContext, oldGC->psc, oldGC->createDpy); oldGC->driContext = NULL; } #endif __glXFreeContext(oldGC); #endif /* GLX_USE_APPLEGL */ } } if (gc) { __glXSetCurrentContext(gc); gc->currentDpy = dpy; gc->currentDrawable = draw; gc->currentReadable = read; #ifndef GLX_USE_APPLEGL gc->thread_id = _glthread_GetID(); #ifdef GLX_DIRECT_RENDERING if (!gc->driContext) { #endif if (!IndirectAPI) IndirectAPI = __glXNewIndirectAPI(); _glapi_set_dispatch(IndirectAPI); #ifdef GLX_USE_APPLEGL do { extern void XAppleDRIUseIndirectDispatch(void); XAppleDRIUseIndirectDispatch(); } while (0); #endif state = (__GLXattribute *) (gc->client_state_private); gc->currentContextTag = reply.contextTag; if (state->array_state == NULL) { (void) glGetString(GL_EXTENSIONS); (void) glGetString(GL_VERSION); __glXInitVertexArrayState(gc); } #ifdef GLX_DIRECT_RENDERING } else { gc->currentContextTag = -1; } #endif #endif /* GLX_USE_APPLEGL */ } else { __glXSetCurrentContextNull(); } } __glXUnlock(); return GL_TRUE; } PUBLIC Bool glXMakeCurrent(Display * dpy, GLXDrawable draw, GLXContext gc) { return MakeContextCurrent(dpy, draw, draw, gc); } PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI, (Display * dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent) PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent, (Display * dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent)
/** * 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; }
/** * 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; }
static Bool SendMakeCurrentRequest(Display * dpy, GLXContextID gc_id, GLXContextTag gc_tag, GLXDrawable draw, GLXDrawable read, GLXContextTag *out_tag) { xGLXMakeCurrentReply reply; Bool ret; int opcode = __glXSetupForCommand(dpy); 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 { struct glx_display *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); if (out_tag) *out_tag = reply.contextTag; UnlockDisplay(dpy); SyncHandle(); return ret; }
/** * 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; }
/** * 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; }