summaryrefslogtreecommitdiff
path: root/GL/glx/glxext.c
diff options
context:
space:
mode:
Diffstat (limited to 'GL/glx/glxext.c')
-rw-r--r--GL/glx/glxext.c213
1 files changed, 104 insertions, 109 deletions
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index fa1382983..e4ad47803 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -23,6 +23,7 @@
#include <dix-config.h>
#endif
+#include <string.h>
#include "glxserver.h"
#include <windowstr.h>
#include <propertyst.h>
@@ -31,19 +32,12 @@
#include "unpack.h"
#include "glxutil.h"
#include "glxext.h"
-#include "micmap.h"
-
-void GlxWrapInitVisuals(miInitVisualsProcPtr *);
-void GlxSetVisualConfigs(int nconfigs,
- __GLXvisualConfig *configs, void **privates);
-
-static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+static Bool inDispatch;
/*
** Forward declarations.
*/
-static int __glXSwapDispatch(ClientPtr);
static int __glXDispatch(ClientPtr);
/*
@@ -52,8 +46,7 @@ static int __glXDispatch(ClientPtr);
static void ResetExtension(ExtensionEntry* extEntry)
{
__glXFlushContextCache();
- (*__glXExt->resetExtension)();
- __glXScreenReset();
+ __glXResetScreens();
}
/*
@@ -159,24 +152,64 @@ static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
}
/*
+** Destroy routine that gets called when a drawable is freed. A drawable
+** contains the ancillary buffers needed for rendering.
+*/
+static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
+{
+ __GLXcontext *cx, *cx1;
+
+ /*
+ ** Use glxPriv->type to figure out what kind of drawable this is. Don't
+ ** use glxPriv->pDraw->type because by the time this routine is called,
+ ** the pDraw might already have been freed.
+ */
+ if (glxPriv->type == DRAWABLE_WINDOW) {
+ /*
+ ** When a window is destroyed, notify all context bound to
+ ** it, that there are no longer bound to anything.
+ */
+ for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
+ cx1 = cx->nextDrawPriv;
+ cx->pendingState |= __GLX_PENDING_DESTROY;
+ }
+
+ for (cx = glxPriv->readGlxc; cx; cx = cx1) {
+ cx1 = cx->nextReadPriv;
+ cx->pendingState |= __GLX_PENDING_DESTROY;
+ }
+ }
+
+ __glXUnrefDrawable(glxPriv);
+
+ return True;
+}
+
+/*
** Free a context.
*/
GLboolean __glXFreeContext(__GLXcontext *cx)
{
if (cx->idExists || cx->isCurrent) return GL_FALSE;
- if (!cx->isDirect) {
- if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
- return GL_FALSE;
- }
- }
if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
if (cx->selectBuf) __glXFree(cx->selectBuf);
- __glXFree(cx);
if (cx == __glXLastContext) {
__glXFlushContextCache();
}
+ /* We can get here through both regular dispatching from
+ * __glXDispatch() or as a callback from the resource manager. In
+ * the latter case we need to lift the DRI lock manually. */
+
+ if (!inDispatch)
+ __glXleaveServer();
+
+ cx->destroy(cx);
+
+ if (!inDispatch)
+ __glXenterServer();
+
return GL_TRUE;
}
@@ -240,13 +273,14 @@ void GlxExtensionInit(void)
__glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
__glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
__glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+ __glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
/*
** Add extension to server extensions.
*/
extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
__GLX_NUMBER_ERRORS, __glXDispatch,
- __glXSwapDispatch, ResetExtension,
+ __glXDispatch, ResetExtension,
StandardMinorOpcode);
if (!extEntry) {
FatalError("__glXExtensionInit: AddExtensions failed\n");
@@ -280,53 +314,7 @@ void GlxExtensionInit(void)
/*
** Initialize screen specific data.
*/
- __glXScreenInit(screenInfo.numScreens);
-}
-
-/************************************************************************/
-
-Bool __glXCoreType(void)
-{
- return __glXExt->type;
-}
-
-/************************************************************************/
-
-void GlxSetVisualConfigs(int nconfigs,
- __GLXvisualConfig *configs, void **privates)
-{
- (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
-}
-
-static miInitVisualsProcPtr saveInitVisualsProc;
-
-Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
- int *nvisualp, int *ndepthp,
- int *rootDepthp, VisualID *defaultVisp,
- unsigned long sizes, int bitsPerRGB,
- int preferredVis)
-{
- Bool ret;
-
- if (saveInitVisualsProc) {
- ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
- rootDepthp, defaultVisp, sizes, bitsPerRGB,
- preferredVis);
- if (!ret)
- return False;
- }
- (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
- defaultVisp, sizes, bitsPerRGB);
- return True;
-}
-
-void
-GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
-{
- saveInitVisualsProc = *initVisProc;
- *initVisProc = GlxInitVisuals;
- /* HACK: this shouldn't be done here but it's the earliest time */
- __glXExt = __glXglDDXExtensionInfo(); /* from GLcore */
+ __glXInitScreens();
}
/************************************************************************/
@@ -377,7 +365,7 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
/* Make this context the current one for the GL. */
if (!cx->isDirect) {
- if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+ if (!(*cx->forceCurrent)(cx)) {
/* Bind failed, and set the error code. Bummer */
cl->client->errorValue = cx->id;
*error = __glXBadContextState;
@@ -393,12 +381,51 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
/*
** Top level dispatcher; all commands are executed from here down.
*/
+
+/* I cried when I wrote this. Damn you XAA! */
+
+static void
+__glXnopEnterServer(void)
+{
+}
+
+static void
+__glXnopLeaveServer(void)
+{
+}
+
+static void (*__glXenterServerFunc)(void) = __glXnopEnterServer;
+static void (*__glXleaveServerFunc)(void) = __glXnopLeaveServer;
+
+void __glXsetEnterLeaveServerFuncs(void (*enter)(void),
+ void (*leave)(void))
+{
+ __glXenterServerFunc = enter;
+ __glXleaveServerFunc = leave;
+}
+
+
+void __glXenterServer(void)
+{
+ (*__glXenterServerFunc)();
+}
+
+void __glXleaveServer(void)
+{
+ (*__glXleaveServerFunc)();
+}
+
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
static int __glXDispatch(ClientPtr client)
{
REQUEST(xGLXSingleReq);
CARD8 opcode;
int (*proc)(__GLXclientState *cl, GLbyte *pc);
__GLXclientState *cl;
+ int retval;
opcode = stuff->glxCode;
cl = __glXClients[client->index];
@@ -443,54 +470,22 @@ static int __glXDispatch(ClientPtr client)
/*
** Use the opcode to index into the procedure table.
*/
- proc = __glXSingleTable[opcode];
- return (*proc)(cl, (GLbyte *) stuff);
-}
+ if (client->swapped)
+ proc = __glXSwapSingleTable[opcode];
+ else
+ proc = __glXSingleTable[opcode];
-static int __glXSwapDispatch(ClientPtr client)
-{
- REQUEST(xGLXSingleReq);
- CARD8 opcode;
- int (*proc)(__GLXclientState *cl, GLbyte *pc);
- __GLXclientState *cl;
+ __glXleaveServer();
- opcode = stuff->glxCode;
- cl = __glXClients[client->index];
- if (!cl) {
- cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
- __glXClients[client->index] = cl;
- if (!cl) {
- return BadAlloc;
- }
- __glXMemset(cl, 0, sizeof(__GLXclientState));
- }
-
- if (!cl->inUse) {
- /*
- ** This is first request from this client. Associate a resource
- ** with the client so we will be notified when the client dies.
- */
- XID xid = FakeClientID(client->index);
- if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
- return BadAlloc;
- }
- ResetClientState(client->index);
- cl->inUse = GL_TRUE;
- cl->client = client;
- }
+ inDispatch = True;
- /*
- ** Check for valid opcode.
- */
- if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
- return BadRequest;
- }
+ retval = proc(cl, (GLbyte *) stuff);
- /*
- ** Use the opcode to index into the procedure table.
- */
- proc = __glXSwapSingleTable[opcode];
- return (*proc)(cl, (GLbyte *) stuff);
+ inDispatch = False;
+
+ __glXenterServer();
+
+ return retval;
}
int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)