2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
31 #ifdef HAVE_DMX_CONFIG_H
32 #include <dmx-config.h>
37 #include "glxserver.h"
38 #include <windowstr.h>
39 #include <propertyst.h>
41 #include "g_disptab.h"
44 #include "glxvisuals.h"
48 #include "glx_extinit.h"
51 ** Forward declarations.
53 static int __glXSwapDispatch(ClientPtr
);
54 static int __glXDispatch(ClientPtr
);
57 ** Called when the extension is reset.
60 ResetExtension(ExtensionEntry
* extEntry
)
62 __glXFlushContextCache();
68 ** Initialize the per-client context storage.
71 ResetClientState(int clientIndex
)
73 __GLXclientState
*cl
= __glXClients
[clientIndex
];
74 Display
**keep_be_displays
;
78 free(cl
->currentContexts
);
79 free(cl
->currentDrawables
);
80 free(cl
->largeCmdBuf
);
82 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
83 if (cl
->be_displays
[i
])
84 XCloseDisplay(cl
->be_displays
[i
]);
87 keep_be_displays
= cl
->be_displays
;
88 memset(cl
, 0, sizeof(__GLXclientState
));
89 cl
->be_displays
= keep_be_displays
;
91 free(cl
->GLClientextensions
);
93 memset(cl
->be_displays
, 0, screenInfo
.numScreens
* sizeof(Display
*));
97 ** This procedure is called when the client who created the context goes
98 ** away OR when glXDestroyContext is called. In either case, all we do is
99 ** flag that the ID is no longer valid, and (maybe) free the context.
103 ContextGone(__GLXcontext
* cx
, XID id
)
105 cx
->idExists
= GL_FALSE
;
106 if (!cx
->isCurrent
) {
107 __glXFreeContext(cx
);
114 ** Free a client's state.
117 ClientGone(int clientIndex
, XID id
)
120 __GLXclientState
*cl
= __glXClients
[clientIndex
];
125 ** Free all the contexts that are current for this client.
127 for (i
= 0; i
< cl
->numCurrentContexts
; i
++) {
128 cx
= cl
->currentContexts
[i
];
130 cx
->isCurrent
= GL_FALSE
;
132 __glXFreeContext(cx
);
137 ** Re-initialize the client state structure. Don't free it because
138 ** we'll probably get another client with this index and use the struct
139 ** again. There is a maximum of MAXCLIENTS of these structures.
141 ResetClientState(clientIndex
);
148 ** Free a GLX Pixmap.
151 __glXFreeGLXPixmap(__GLXpixmap
* pGlxPixmap
)
153 if (!pGlxPixmap
->idExists
&& !pGlxPixmap
->refcnt
) {
155 PixmapPtr pPixmap
= (PixmapPtr
) pGlxPixmap
->pDraw
;
158 ** The DestroyPixmap routine should decrement the refcount and free
159 ** only if it's zero.
161 (*pGlxPixmap
->pScreen
->DestroyPixmap
) (pPixmap
);
162 free(pGlxPixmap
->be_xids
);
169 PixmapGone(__GLXpixmap
* pGlxPixmap
, XID id
)
172 pGlxPixmap
->idExists
= False
;
173 __glXFreeGLXPixmap(pGlxPixmap
);
179 __glXFreeGLXWindow(__glXWindow
* pGlxWindow
)
181 if (!pGlxWindow
->idExists
&& !pGlxWindow
->refcnt
) {
182 WindowPtr pWindow
= (WindowPtr
) pGlxWindow
->pDraw
;
185 dixLookupResourceByType((pointer
) &ret
,
186 pWindow
->drawable
.id
, RT_WINDOW
,
187 NullClient
, DixUnknownAccess
);
188 if (ret
== pWindow
) {
189 (*pGlxWindow
->pScreen
->DestroyWindow
) (pWindow
);
197 WindowGone(__glXWindow
* pGlxWindow
, XID id
)
199 pGlxWindow
->idExists
= False
;
200 __glXFreeGLXWindow(pGlxWindow
);
204 __glXFreeGLXPbuffer(__glXPbuffer
* pGlxPbuffer
)
206 if (!pGlxPbuffer
->idExists
&& !pGlxPbuffer
->refcnt
) {
207 free(pGlxPbuffer
->be_xids
);
213 PbufferGone(__glXPbuffer
* pGlxPbuffer
, XID id
)
215 pGlxPbuffer
->idExists
= False
;
216 __glXFreeGLXPbuffer(pGlxPbuffer
);
223 __glXFreeContext(__GLXcontext
* cx
)
225 if (cx
->idExists
|| cx
->isCurrent
)
228 free(cx
->feedbackBuf
);
233 if (cx
->pGlxPixmap
) {
235 ** The previous drawable was a glx pixmap, release it.
237 cx
->pGlxPixmap
->refcnt
--;
238 __glXFreeGLXPixmap(cx
->pGlxPixmap
);
242 if (cx
->pGlxReadPixmap
) {
244 ** The previous drawable was a glx pixmap, release it.
246 cx
->pGlxReadPixmap
->refcnt
--;
247 __glXFreeGLXPixmap(cx
->pGlxReadPixmap
);
248 cx
->pGlxReadPixmap
= 0;
251 if (cx
->pGlxWindow
) {
253 ** The previous drawable was a glx window, release it.
255 cx
->pGlxWindow
->refcnt
--;
256 __glXFreeGLXWindow(cx
->pGlxWindow
);
260 if (cx
->pGlxReadWindow
) {
262 ** The previous drawable was a glx window, release it.
264 cx
->pGlxReadWindow
->refcnt
--;
265 __glXFreeGLXWindow(cx
->pGlxReadWindow
);
266 cx
->pGlxReadWindow
= 0;
271 if (cx
== __glXLastContext
) {
272 __glXFlushContextCache();
279 ** Initialize the GLX extension.
282 GlxExtensionInit(void)
284 ExtensionEntry
*extEntry
;
286 int glxSupported
= 1;
289 // do not initialize GLX extension if GLX is not supported
290 // by ALL back-end servers.
292 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
293 glxSupported
&= (dmxScreens
[i
].glxMajorOpcode
> 0);
296 if (!glxSupported
|| !dmxGLXProxy
) {
300 __glXContextRes
= CreateNewResourceType((DeleteType
) ContextGone
,
302 __glXClientRes
= CreateNewResourceType((DeleteType
) ClientGone
,
304 __glXPixmapRes
= CreateNewResourceType((DeleteType
) PixmapGone
,
306 __glXWindowRes
= CreateNewResourceType((DeleteType
) WindowGone
,
308 __glXPbufferRes
= CreateNewResourceType((DeleteType
) PbufferGone
,
311 if (!__glXContextRes
|| !__glXClientRes
|| !__glXPixmapRes
||
312 !__glXWindowRes
|| !__glXPbufferRes
)
316 ** Add extension to server extensions.
318 extEntry
= AddExtension(GLX_EXTENSION_NAME
, __GLX_NUMBER_EVENTS
,
319 __GLX_NUMBER_ERRORS
, __glXDispatch
,
320 __glXSwapDispatch
, ResetExtension
,
321 StandardMinorOpcode
);
323 FatalError("__glXExtensionInit: AddExtensions failed\n");
327 if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
328 ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
333 __glXerrorBase
= extEntry
->errorBase
;
334 __glXBadContext
= extEntry
->errorBase
+ GLXBadContext
;
335 __glXBadContextState
= extEntry
->errorBase
+ GLXBadContextState
;
336 __glXBadDrawable
= extEntry
->errorBase
+ GLXBadDrawable
;
337 __glXBadPixmap
= extEntry
->errorBase
+ GLXBadPixmap
;
338 __glXBadContextTag
= extEntry
->errorBase
+ GLXBadContextTag
;
339 __glXBadCurrentWindow
= extEntry
->errorBase
+ GLXBadCurrentWindow
;
340 __glXBadRenderRequest
= extEntry
->errorBase
+ GLXBadRenderRequest
;
341 __glXBadLargeRequest
= extEntry
->errorBase
+ GLXBadLargeRequest
;
342 __glXUnsupportedPrivateRequest
= extEntry
->errorBase
+
343 GLXUnsupportedPrivateRequest
;
344 __glXBadFBConfig
= extEntry
->errorBase
+ GLXBadFBConfig
;
345 __glXBadPbuffer
= extEntry
->errorBase
+ GLXBadPbuffer
;
348 ** Initialize table of client state. There is never a client 0.
350 for (i
= 1; i
<= MAXCLIENTS
; i
++) {
355 ** Initialize screen specific data.
357 __glXScreenInit(screenInfo
.numScreens
);
360 ** Initialize swap barrier support.
365 /************************************************************************/
373 /************************************************************************/
376 __glXFlushContextCache(void)
378 __glXLastContext
= 0;
381 /************************************************************************/
384 ** Top level dispatcher; all commands are executed from here down.
387 __glXDispatch(ClientPtr client
)
389 REQUEST(xGLXSingleReq
);
391 int (*proc
) (__GLXclientState
* cl
, GLbyte
* pc
);
392 __GLXclientState
*cl
;
394 opcode
= stuff
->glxCode
;
395 cl
= __glXClients
[client
->index
];
397 cl
= calloc(1, sizeof(__GLXclientState
));
398 __glXClients
[client
->index
] = cl
;
403 cl
->be_displays
= calloc(screenInfo
.numScreens
, sizeof(Display
*));
404 if (!cl
->be_displays
) {
412 ** This is first request from this client. Associate a resource
413 ** with the client so we will be notified when the client dies.
415 XID xid
= FakeClientID(client
->index
);
417 if (!AddResource(xid
, __glXClientRes
, (pointer
) (long) client
->index
)) {
420 ResetClientState(client
->index
);
421 cl
->largeCmdRequestsTotal
= 0;
427 ** Check for valid opcode.
429 if (opcode
>= __GLX_SINGLE_TABLE_SIZE
) {
434 ** Use the opcode to index into the procedure table.
436 proc
= __glXSingleTable
[opcode
];
437 return (*proc
) (cl
, (GLbyte
*) stuff
);
441 __glXSwapDispatch(ClientPtr client
)
443 REQUEST(xGLXSingleReq
);
445 int (*proc
) (__GLXclientState
* cl
, GLbyte
* pc
);
446 __GLXclientState
*cl
;
448 opcode
= stuff
->glxCode
;
449 cl
= __glXClients
[client
->index
];
451 cl
= calloc(1, sizeof(__GLXclientState
));
452 __glXClients
[client
->index
] = cl
;
457 cl
->be_displays
= calloc(screenInfo
.numScreens
, sizeof(Display
*));
458 if (!cl
->be_displays
) {
466 ** This is first request from this client. Associate a resource
467 ** with the client so we will be notified when the client dies.
469 XID xid
= FakeClientID(client
->index
);
471 if (!AddResource(xid
, __glXClientRes
, (pointer
) (long) client
->index
)) {
474 ResetClientState(client
->index
);
480 ** Check for valid opcode.
482 if (opcode
>= __GLX_SINGLE_TABLE_SIZE
) {
487 ** Use the opcode to index into the procedure table.
489 proc
= __glXSwapSingleTable
[opcode
];
490 return (*proc
) (cl
, (GLbyte
*) stuff
);
494 __glXNoSuchSingleOpcode(__GLXclientState
* cl
, GLbyte
* pc
)
500 __glXNoSuchRenderOpcode(GLbyte
* pc
)