PUBLIC GLXWindow glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, const int *attrib_list) { WARN_ONCE_GLX_1_3(dpy, __func__); #ifdef GLX_USE_APPLEGL XWindowAttributes xwattr; XVisualInfo *visinfo; (void) attrib_list; /*unused according to GLX 1.4 */ XGetWindowAttributes(dpy, win, &xwattr); visinfo = glXGetVisualFromFBConfig(dpy, config); if (NULL == visinfo) { __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateWindow, false); return None; } if (visinfo->visualid != XVisualIDFromVisual(xwattr.visual)) { __glXSendError(dpy, BadMatch, 0, X_GLXCreateWindow, true); return None; } XFree(visinfo); return win; #else return CreateDrawable(dpy, (__GLcontextModes *) config, (Drawable) win, attrib_list, X_GLXCreateWindow); #endif }
/** * Get the selected event mask for a drawable. */ PUBLIC void glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask) { #ifdef GLX_USE_APPLEGL XWindowAttributes xwattr; if (apple_glx_pbuffer_get_event_mask(drawable, mask)) return; /*done */ /* * The spec allows a window, but currently there are no valid * events for a window, so do nothing, but set the mask to 0. */ if (XGetWindowAttributes(dpy, drawable, &xwattr)) { /* The window is valid, so set the mask to 0. */ *mask = 0; return; /*done */ } /* The drawable seems to be invalid. Report an error. */ __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes, true); #else unsigned int value; /* The non-sense with value is required because on LP64 platforms * sizeof(unsigned int) != sizeof(unsigned long). On little-endian * we could just type-cast the pointer, but why? */ GetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value); *mask = value; #endif }
/** * Select the event mask for a drawable. */ PUBLIC void glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask) { #ifdef GLX_USE_APPLEGL XWindowAttributes xwattr; if (apple_glx_pbuffer_set_event_mask(drawable, mask)) return; /*done */ /* * The spec allows a window, but currently there are no valid * events for a window, so do nothing. */ if (XGetWindowAttributes(dpy, drawable, &xwattr)) return; /*done */ /* The drawable seems to be invalid. Report an error. */ __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXChangeDrawableAttributes, false); #else CARD32 attribs[2]; attribs[0] = (CARD32) GLX_EVENT_MASK; attribs[1] = (CARD32) mask; ChangeDrawableAttribute(dpy, drawable, attribs, 1); #endif }
PUBLIC void glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) { WARN_ONCE_GLX_1_3(dpy, __func__); #ifdef GLX_USE_APPLEGL if (apple_glx_pixmap_destroy(dpy, pixmap)) __glXSendError(dpy, GLXBadPixmap, pixmap, X_GLXDestroyPixmap, false); #else DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap); #endif }
/** * Destroy an existing pbuffer. */ PUBLIC void glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) { #ifdef GLX_USE_APPLEGL if (apple_glx_pbuffer_destroy(dpy, pbuf)) { __glXSendError(dpy, GLXBadPbuffer, pbuf, X_GLXDestroyPbuffer, false); } #else DestroyPbuffer(dpy, pbuf); #endif }
/** * Create a new pbuffer. */ PUBLIC GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list) { int i, width, height; #ifdef GLX_USE_APPLEGL GLXPbuffer result; int errorcode; #endif width = 0; height = 0; WARN_ONCE_GLX_1_3(dpy, __func__); #ifdef GLX_USE_APPLEGL for (i = 0; attrib_list[i]; ++i) { switch (attrib_list[i]) { case GLX_PBUFFER_WIDTH: width = attrib_list[i + 1]; ++i; break; case GLX_PBUFFER_HEIGHT: height = attrib_list[i + 1]; ++i; break; case GLX_LARGEST_PBUFFER: /* This is a hint we should probably handle, but how? */ ++i; break; case GLX_PRESERVED_CONTENTS: /* The contents are always preserved with AppleSGLX with CGL. */ ++i; break; default: return None; } } if (apple_glx_pbuffer_create(dpy, config, width, height, &errorcode, &result)) { /* * apple_glx_pbuffer_create only sets the errorcode to core X11 * errors. */ __glXSendError(dpy, errorcode, 0, X_GLXCreatePbuffer, true); return None; } return result; #else for (i = 0; attrib_list[i * 2]; i++) { switch (attrib_list[i * 2]) { case GLX_PBUFFER_WIDTH: width = attrib_list[i * 2 + 1]; break; case GLX_PBUFFER_HEIGHT: height = attrib_list[i * 2 + 1]; break; } } return (GLXPbuffer) CreatePbuffer(dpy, (__GLcontextModes *) config, width, height, attrib_list, GL_TRUE); #endif }
/** * 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; }