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.c192
1 files changed, 86 insertions, 106 deletions
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index 5b621d392..ad02a89e1 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -45,7 +45,6 @@ __GLXcontext *__glXLastContext;
** X resources.
*/
RESTYPE __glXContextRes;
-RESTYPE __glXClientRes;
RESTYPE __glXPixmapRes;
RESTYPE __glXDrawableRes;
RESTYPE __glXSwapBarrierRes;
@@ -55,11 +54,7 @@ RESTYPE __glXSwapBarrierRes;
*/
xGLXSingleReply __glXReply;
-/*
-** A set of state for each client. The 0th one is unused because client
-** indices start at 1, not 0.
-*/
-static __GLXclientState *__glXClients[MAXCLIENTS + 1];
+static int glxClientPrivateIndex;
/*
** Client that called into GLX dispatch.
@@ -77,29 +72,6 @@ static int __glXDispatch(ClientPtr);
static void ResetExtension(ExtensionEntry* extEntry)
{
__glXFlushContextCache();
- __glXResetScreens();
-}
-
-/*
-** Initialize the per-client context storage.
-*/
-static void ResetClientState(int clientIndex)
-{
- __GLXclientState *cl = __glXClients[clientIndex];
-
- if (cl->returnBuf) xfree(cl->returnBuf);
- if (cl->largeCmdBuf) xfree(cl->largeCmdBuf);
- if (cl->currentContexts) xfree(cl->currentContexts);
- memset(cl, 0, sizeof(__GLXclientState));
- /*
- ** By default, assume that the client supports
- ** GLX major version 1 minor version 0 protocol.
- */
- cl->GLClientmajorVersion = 1;
- cl->GLClientminorVersion = 0;
- if (cl->GLClientextensions)
- xfree(cl->GLClientextensions);
-
}
/*
@@ -130,39 +102,6 @@ static int ContextGone(__GLXcontext* cx, XID id)
}
/*
-** Free a client's state.
-*/
-static int ClientGone(int clientIndex, XID id)
-{
- __GLXcontext *cx;
- __GLXclientState *cl = __glXClients[clientIndex];
- int i;
-
- if (cl) {
- /*
- ** Free all the contexts that are current for this client.
- */
- for (i=0; i < cl->numCurrentContexts; i++) {
- cx = cl->currentContexts[i];
- if (cx) {
- cx->isCurrent = GL_FALSE;
- if (!cx->idExists) {
- __glXFreeContext(cx);
- }
- }
- }
- /*
- ** Re-initialize the client state structure. Don't free it because
- ** we'll probably get another client with this index and use the struct
- ** again. There is a maximum of MAXCLIENTS of these structures.
- */
- ResetClientState(clientIndex);
- }
-
- return True;
-}
-
-/*
** Free a GLX Pixmap.
*/
static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
@@ -309,22 +248,87 @@ int __glXError(int error)
return __glXErrorBase + error;
}
+__GLXclientState *
+glxGetClient(ClientPtr pClient)
+{
+ return (__GLXclientState *) pClient->devPrivates[glxClientPrivateIndex].ptr;
+}
+
+static void
+glxClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ __GLXclientState *cl = glxGetClient(pClient);
+ __GLXcontext *cx;
+ int i;
+
+ switch (pClient->clientState) {
+ case ClientStateRunning:
+ /*
+ ** By default, assume that the client supports
+ ** GLX major version 1 minor version 0 protocol.
+ */
+ cl->GLClientmajorVersion = 1;
+ cl->GLClientminorVersion = 0;
+ cl->client = pClient;
+ break;
+
+ case ClientStateGone:
+ for (i = 0; i < cl->numCurrentContexts; i++) {
+ cx = cl->currentContexts[i];
+ if (cx) {
+ cx->isCurrent = GL_FALSE;
+ if (!cx->idExists)
+ __glXFreeContext(cx);
+ }
+ }
+
+ if (cl->returnBuf) xfree(cl->returnBuf);
+ if (cl->largeCmdBuf) xfree(cl->largeCmdBuf);
+ if (cl->currentContexts) xfree(cl->currentContexts);
+ if (cl->GLClientextensions) xfree(cl->GLClientextensions);
+ break;
+
+ default:
+ break;
+ }
+}
+
/************************************************************************/
+static __GLXprovider *__glXProviderStack;
+
+void GlxPushProvider(__GLXprovider *provider)
+{
+ provider->next = __glXProviderStack;
+ __glXProviderStack = provider;
+}
+
/*
** Initialize the GLX extension.
*/
void GlxExtensionInit(void)
{
ExtensionEntry *extEntry;
+ ScreenPtr pScreen;
int i;
+ __GLXprovider *p;
__glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
- __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
__glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
__glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
__glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+ glxClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (glxClientPrivateIndex,
+ sizeof (__GLXclientState)))
+ return;
+ if (!AddCallback (&ClientStateCallback, glxClientCallback, 0))
+ return;
+
/*
** Add extension to server extensions.
*/
@@ -343,17 +347,17 @@ void GlxExtensionInit(void)
__glXErrorBase = extEntry->errorBase;
- /*
- ** Initialize table of client state. There is never a client 0.
- */
- for (i = 1; i <= MAXCLIENTS; i++) {
- __glXClients[i] = 0;
- }
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
- /*
- ** Initialize screen specific data.
- */
- __glXInitScreens();
+ for (p = __glXProviderStack; p != NULL; p = p->next) {
+ if (p->screenProbe(pScreen) != NULL)
+ LogMessage(X_INFO,
+ "GLX: Initialized %s GL provider for screen %d\n",
+ p->name, i);
+ break;
+ }
+ }
}
/************************************************************************/
@@ -421,11 +425,9 @@ void glxSuspendClients(void)
{
int i;
- for (i = 1; i <= MAXCLIENTS; i++) {
- if (__glXClients[i] == NULL || !__glXClients[i]->inUse)
- continue;
-
- IgnoreClient(__glXClients[i]->client);
+ for (i = 1; i < currentMaxClients; i++) {
+ if (glxGetClient(clients[i])->inUse)
+ IgnoreClient(clients[i]);
}
glxBlockClients = TRUE;
@@ -438,11 +440,9 @@ void glxResumeClients(void)
glxBlockClients = FALSE;
- for (i = 1; i <= MAXCLIENTS; i++) {
- if (__glXClients[i] == NULL || !__glXClients[i]->inUse)
- continue;
-
- AttendClient(__glXClients[i]->client);
+ for (i = 1; i < currentMaxClients; i++) {
+ if (glxGetClient(clients[i])->inUse)
+ AttendClient(clients[i]);
}
__glXleaveServer(GL_FALSE);
@@ -504,29 +504,9 @@ static int __glXDispatch(ClientPtr client)
int retval;
opcode = stuff->glxCode;
- cl = __glXClients[client->index];
- if (!cl) {
- cl = (__GLXclientState *) xalloc(sizeof(__GLXclientState));
- __glXClients[client->index] = cl;
- if (!cl) {
- return BadAlloc;
- }
- memset(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;
- }
+ cl = glxGetClient(client);
+ /* Mark it in use so we suspend it on VT switch. */
+ cl->inUse = TRUE;
/*
** If we're expecting a glXRenderLarge request, this better be one.