#ifdef GLX_USE_APPLEGL
#include <pthread.h>
-#include "apple_glx_drawable.h"
-#include "glx_error.h"
+#include "apple/apple_glx_drawable.h"
#endif
+#include "glx_error.h"
+
#define WARN_ONCE_GLX_1_3(a, b) { \
static int warned=1; \
if(warned) { \
{
struct glx_display *priv = __glXInitialize(dpy);
- if (priv->minorVersion < 3) {
+ if (priv && 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",
* \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,
CARD8 opcode;
int i;
- if ((dpy == NULL) || (drawable == 0)) {
+ if ((priv == NULL) || (dpy == NULL) || (drawable == 0)) {
return;
}
return 0;
}
-static void
+static GLboolean
CreateDRIDrawable(Display *dpy, struct glx_config *config,
XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs)
__GLXDRIdrawable *pdraw;
struct glx_screen *psc;
+ if (priv == NULL) {
+ fprintf(stderr, "failed to create drawable\n");
+ return GL_FALSE;
+ }
+
psc = priv->screens[config->screen];
if (psc->driScreen == NULL)
- return;
+ return GL_TRUE;
pdraw = psc->driScreen->createDrawable(psc, drawable,
glxdrawable, config);
if (pdraw == NULL) {
fprintf(stderr, "failed to create drawable\n");
- return;
+ return GL_FALSE;
}
if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
(*pdraw->destroyDrawable) (pdraw);
- return; /* FIXME: Check what we're supposed to do here... */
+ return GL_FALSE;
}
pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);
+
+ return GL_TRUE;
}
static void
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
XID xid;
- if (pdraw != NULL) {
+ if (priv != NULL && pdraw != NULL) {
xid = pdraw->xDrawable;
(*pdraw->destroyDrawable) (pdraw);
__glxHashDelete(priv->drawHash, drawable);
#else
-static void
+static GLboolean
CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig,
XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs)
{
+ return GL_TRUE;
}
static void
* 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,
unsigned int num_attributes;
GLboolean use_glx_1_3;
- if ((dpy == NULL) || (drawable == 0)) {
+#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;
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) {
length = reply.length;
if (length) {
num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
- data = (CARD32 *) Xmalloc(length * sizeof(CARD32));
+ data = malloc(length * sizeof(CARD32));
if (data == NULL) {
/* Throw data on the floor */
_XEatData(dpy, length);
}
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
- {
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
-
- if (pdraw != NULL && !pdraw->textureTarget)
+ if (pdraw != NULL) {
+ if (!pdraw->textureTarget)
pdraw->textureTarget =
determineTextureTarget((const int *) data, num_attributes);
- if (pdraw != NULL && !pdraw->textureFormat)
+ if (!pdraw->textureFormat)
pdraw->textureFormat =
determineTextureFormat((const int *) data, num_attributes);
}
#endif
- Xfree(data);
+ free(data);
}
}
return 0;
}
+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();
+}
+
/**
* Create a non-pbuffer GLX drawable.
- *
- * \todo
- * This function needs to be modified to work with direct-rendering drivers.
*/
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) {
if (!opcode)
return None;
+ glxDraw = malloc(sizeof(*glxDraw));
+ if (!glxDraw)
+ return None;
+
LockDisplay(dpy);
GetReqExtra(GLXCreateWindow, 8 * i, req);
data = (CARD32 *) (req + 1);
req->screen = config->screen;
req->fbconfig = config->fbconfigID;
req->window = drawable;
- req->glxwindow = XAllocID(dpy);
+ req->glxwindow = xid = XAllocID(dpy);
req->numAttribs = i;
if (attrib_list)
UnlockDisplay(dpy);
SyncHandle();
- CreateDRIDrawable(dpy, config, drawable, req->glxwindow, attrib_list, i);
+ 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 req->glxwindow;
+ return xid;
}
static void
DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
{
- xGLXDestroyPbufferReq *req;
- CARD8 opcode;
-
if ((dpy == NULL) || (drawable == 0)) {
return;
}
+ protocolDestroyDrawable(dpy, drawable, glxCode);
- opcode = __glXSetupForCommand(dpy);
- if (!opcode)
- return;
-
- LockDisplay(dpy);
-
- GetReq(GLXDestroyPbuffer, req);
- req->reqType = opcode;
- req->glxCode = glxCode;
- req->pbuffer = (GLXPbuffer) drawable;
-
- UnlockDisplay(dpy);
- SyncHandle();
-
+ DestroyGLXDrawable(dpy, drawable);
DestroyDRIDrawable(dpy, drawable, GL_FALSE);
return;
* \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, struct glx_config *config,
CARD8 opcode;
unsigned int i;
Pixmap pixmap;
+ GLboolean glx_1_3 = GL_FALSE;
+
+ if (priv == NULL)
+ return None;
i = 0;
if (attrib_list) {
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);
pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
width, height, config->rgbBits);
- CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i);
+ 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;
}
struct glx_display *priv = __glXInitialize(dpy);
CARD8 opcode;
- if ((dpy == NULL) || (drawable == 0)) {
+ if ((priv == NULL) || (dpy == NULL) || (drawable == 0)) {
return;
}
/**
* Create a new pbuffer.
*/
-_X_EXPORT GLXPbufferSGIX
+_GLX_PUBLIC GLXPbufferSGIX
glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config,
unsigned int width, unsigned int height,
int *attrib_list)
/**
* Create a new pbuffer.
*/
-_X_EXPORT GLXPbuffer
+_GLX_PUBLIC GLXPbuffer
glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list)
{
int i, width, height;
/**
* Destroy an existing pbuffer.
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf)
{
#ifdef GLX_USE_APPLEGL
/**
* Query an attribute of a drawable.
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXQueryDrawable(Display * dpy, GLXDrawable drawable,
int attribute, unsigned int *value)
{
/**
* Query an attribute of a pbuffer.
*/
-_X_EXPORT int
+_GLX_PUBLIC int
glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable,
int attribute, unsigned int *value)
{
/**
* Select the event mask for a drawable.
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask)
{
#ifdef GLX_USE_APPLEGL
/**
* Get the selected event mask for a drawable.
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask)
{
#ifdef GLX_USE_APPLEGL
__glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes,
true);
#else
- unsigned int value;
+ unsigned int value = 0;
/* The non-sense with value is required because on LP64 platforms
}
-_X_EXPORT GLXPixmap
+_GLX_PUBLIC GLXPixmap
glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap,
const int *attrib_list)
{
WARN_ONCE_GLX_1_3(dpy, __func__);
#ifdef GLX_USE_APPLEGL
- const struct glx_config *modes = (const __GLcontextModes *) config;
+ const struct glx_config *modes = (const struct glx_config *) config;
if (apple_glx_pixmap_create(dpy, modes->screen, pixmap, modes))
return None;
}
-_X_EXPORT GLXWindow
+_GLX_PUBLIC GLXWindow
glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
const int *attrib_list)
{
return None;
}
- XFree(visinfo);
+ free(visinfo);
return win;
#else
}
-_X_EXPORT void
+_GLX_PUBLIC void
glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
{
WARN_ONCE_GLX_1_3(dpy, __func__);
}
-_X_EXPORT void
+_GLX_PUBLIC void
glXDestroyWindow(Display * dpy, GLXWindow win)
{
WARN_ONCE_GLX_1_3(dpy, __func__);
#endif
}
-#ifndef GLX_USE_APPLEGL
-_X_EXPORT
+_GLX_PUBLIC
GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
(Display * dpy, GLXPbufferSGIX pbuf),
(dpy, pbuf), glXDestroyPbuffer)
-_X_EXPORT
+_GLX_PUBLIC
GLX_ALIAS_VOID(glXSelectEventSGIX,
(Display * dpy, GLXDrawable drawable,
unsigned long mask), (dpy, drawable, mask), glXSelectEvent)
-_X_EXPORT
+_GLX_PUBLIC
GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
(Display * dpy, GLXDrawable drawable,
unsigned long *mask), (dpy, drawable, mask),
glXGetSelectedEvent)
-#endif