1706f2543Smrg/*
2706f2543Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3706f2543Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4706f2543Smrg *
5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6706f2543Smrg * copy of this software and associated documentation files (the "Software"),
7706f2543Smrg * to deal in the Software without restriction, including without limitation
8706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
10706f2543Smrg * Software is furnished to do so, subject to the following conditions:
11706f2543Smrg *
12706f2543Smrg * The above copyright notice including the dates of first publication and
13706f2543Smrg * either this permission notice or a reference to
14706f2543Smrg * http://oss.sgi.com/projects/FreeB/
15706f2543Smrg * shall be included in all copies or substantial portions of the Software.
16706f2543Smrg *
17706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18706f2543Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20706f2543Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23706f2543Smrg * SOFTWARE.
24706f2543Smrg *
25706f2543Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26706f2543Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27706f2543Smrg * other dealings in this Software without prior written authorization from
28706f2543Smrg * Silicon Graphics, Inc.
29706f2543Smrg */
30706f2543Smrg
31706f2543Smrg#ifdef HAVE_DMX_CONFIG_H
32706f2543Smrg#include <dmx-config.h>
33706f2543Smrg#endif
34706f2543Smrg
35706f2543Smrg#include "dmx.h"
36706f2543Smrg
37706f2543Smrg#include "glxserver.h"
38706f2543Smrg#include <windowstr.h>
39706f2543Smrg#include <propertyst.h>
40706f2543Smrg#include <os.h>
41706f2543Smrg#include "g_disptab.h"
42706f2543Smrg#include "glxutil.h"
43706f2543Smrg#include "glxext.h"
44706f2543Smrg#include "glxvisuals.h"
45706f2543Smrg#include "micmap.h"
46706f2543Smrg#include "glxswap.h"
47706f2543Smrg
48706f2543Smrg/*
49706f2543Smrg** Stubs to satisfy miinitext.c references.
50706f2543Smrg*/
51706f2543Smrgtypedef int __GLXprovider;
52706f2543Smrg__GLXprovider __glXDRISWRastProvider;
53706f2543Smrgvoid GlxPushProvider(__GLXprovider *provider) { }
54706f2543Smrg
55706f2543Smrg/*
56706f2543Smrg** Forward declarations.
57706f2543Smrg*/
58706f2543Smrgstatic int __glXSwapDispatch(ClientPtr);
59706f2543Smrgstatic int __glXDispatch(ClientPtr);
60706f2543Smrg
61706f2543Smrg/*
62706f2543Smrg** Called when the extension is reset.
63706f2543Smrg*/
64706f2543Smrgstatic void ResetExtension(ExtensionEntry* extEntry)
65706f2543Smrg{
66706f2543Smrg    __glXFlushContextCache();
67706f2543Smrg    __glXScreenReset();
68706f2543Smrg    SwapBarrierReset();
69706f2543Smrg}
70706f2543Smrg
71706f2543Smrg/*
72706f2543Smrg** Initialize the per-client context storage.
73706f2543Smrg*/
74706f2543Smrgstatic void ResetClientState(int clientIndex)
75706f2543Smrg{
76706f2543Smrg    __GLXclientState *cl = __glXClients[clientIndex];
77706f2543Smrg    Display **keep_be_displays;
78706f2543Smrg    int i;
79706f2543Smrg
80706f2543Smrg    free(cl->returnBuf);
81706f2543Smrg    free(cl->currentContexts);
82706f2543Smrg    free(cl->currentDrawables);
83706f2543Smrg    free(cl->largeCmdBuf);
84706f2543Smrg
85706f2543Smrg    for (i=0; i< screenInfo.numScreens; i++) {
86706f2543Smrg       if (cl->be_displays[i])
87706f2543Smrg	  XCloseDisplay( cl->be_displays[i] );
88706f2543Smrg    }
89706f2543Smrg
90706f2543Smrg    keep_be_displays = cl->be_displays;
91706f2543Smrg    memset(cl, 0, sizeof(__GLXclientState));
92706f2543Smrg    cl->be_displays = keep_be_displays;
93706f2543Smrg
94706f2543Smrg    /*
95706f2543Smrg    ** By default, assume that the client supports
96706f2543Smrg    ** GLX major version 1 minor version 0 protocol.
97706f2543Smrg    */
98706f2543Smrg    cl->GLClientmajorVersion = 1;
99706f2543Smrg    cl->GLClientminorVersion = 0;
100706f2543Smrg    free(cl->GLClientextensions);
101706f2543Smrg
102706f2543Smrg    memset(cl->be_displays, 0, screenInfo.numScreens * sizeof(Display *));
103706f2543Smrg}
104706f2543Smrg
105706f2543Smrg
106706f2543Smrg/*
107706f2543Smrg** This procedure is called when the client who created the context goes
108706f2543Smrg** away OR when glXDestroyContext is called.  In either case, all we do is
109706f2543Smrg** flag that the ID is no longer valid, and (maybe) free the context.
110706f2543Smrg** use.
111706f2543Smrg*/
112706f2543Smrgstatic int ContextGone(__GLXcontext* cx, XID id)
113706f2543Smrg{
114706f2543Smrg    cx->idExists = GL_FALSE;
115706f2543Smrg    if (!cx->isCurrent) {
116706f2543Smrg	__glXFreeContext(cx);
117706f2543Smrg    }
118706f2543Smrg
119706f2543Smrg    return True;
120706f2543Smrg}
121706f2543Smrg
122706f2543Smrg/*
123706f2543Smrg** Free a client's state.
124706f2543Smrg*/
125706f2543Smrgstatic int ClientGone(int clientIndex, XID id)
126706f2543Smrg{
127706f2543Smrg    __GLXcontext *cx;
128706f2543Smrg    __GLXclientState *cl = __glXClients[clientIndex];
129706f2543Smrg    int i;
130706f2543Smrg
131706f2543Smrg    if (cl) {
132706f2543Smrg	/*
133706f2543Smrg	** Free all the contexts that are current for this client.
134706f2543Smrg	*/
135706f2543Smrg	for (i=0; i < cl->numCurrentContexts; i++) {
136706f2543Smrg	    cx = cl->currentContexts[i];
137706f2543Smrg	    if (cx) {
138706f2543Smrg		cx->isCurrent = GL_FALSE;
139706f2543Smrg		if (!cx->idExists) {
140706f2543Smrg		    __glXFreeContext(cx);
141706f2543Smrg		}
142706f2543Smrg	    }
143706f2543Smrg	}
144706f2543Smrg	/*
145706f2543Smrg	** Re-initialize the client state structure.  Don't free it because
146706f2543Smrg	** we'll probably get another client with this index and use the struct
147706f2543Smrg	** again.  There is a maximum of MAXCLIENTS of these structures.
148706f2543Smrg	*/
149706f2543Smrg	ResetClientState(clientIndex);
150706f2543Smrg    }
151706f2543Smrg
152706f2543Smrg    return True;
153706f2543Smrg}
154706f2543Smrg
155706f2543Smrg/*
156706f2543Smrg** Free a GLX Pixmap.
157706f2543Smrg*/
158706f2543Smrgvoid __glXFreeGLXPixmap( __GLXpixmap *pGlxPixmap )
159706f2543Smrg{
160706f2543Smrg   if (!pGlxPixmap->idExists &&
161706f2543Smrg       !pGlxPixmap->refcnt) {
162706f2543Smrg
163706f2543Smrg       PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
164706f2543Smrg
165706f2543Smrg	/*
166706f2543Smrg	** The DestroyPixmap routine should decrement the refcount and free
167706f2543Smrg	** only if it's zero.
168706f2543Smrg	*/
169706f2543Smrg	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
170706f2543Smrg	free(pGlxPixmap->be_xids);
171706f2543Smrg	free(pGlxPixmap);
172706f2543Smrg    }
173706f2543Smrg
174706f2543Smrg}
175706f2543Smrg
176706f2543Smrgstatic int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
177706f2543Smrg{
178706f2543Smrg
179706f2543Smrg    pGlxPixmap->idExists = False;
180706f2543Smrg    __glXFreeGLXPixmap( pGlxPixmap );
181706f2543Smrg
182706f2543Smrg    return True;
183706f2543Smrg}
184706f2543Smrg
185706f2543Smrgvoid __glXFreeGLXWindow(__glXWindow *pGlxWindow)
186706f2543Smrg{
187706f2543Smrg    if (!pGlxWindow->idExists && !pGlxWindow->refcnt) {
188706f2543Smrg	WindowPtr pWindow = (WindowPtr) pGlxWindow->pDraw;
189706f2543Smrg	WindowPtr ret;
190706f2543Smrg
191706f2543Smrg	dixLookupResourceByType((pointer) &ret,
192706f2543Smrg				pWindow->drawable.id, RT_WINDOW,
193706f2543Smrg				NullClient, DixUnknownAccess);
194706f2543Smrg        if (ret == pWindow) {
195706f2543Smrg            (*pGlxWindow->pScreen->DestroyWindow)(pWindow);
196706f2543Smrg        }
197706f2543Smrg
198706f2543Smrg	free(pGlxWindow);
199706f2543Smrg    }
200706f2543Smrg}
201706f2543Smrg
202706f2543Smrgstatic void WindowGone(__glXWindow *pGlxWindow, XID id)
203706f2543Smrg{
204706f2543Smrg    pGlxWindow->idExists = False;
205706f2543Smrg    __glXFreeGLXWindow(pGlxWindow);
206706f2543Smrg}
207706f2543Smrg
208706f2543Smrgvoid __glXFreeGLXPbuffer(__glXPbuffer *pGlxPbuffer)
209706f2543Smrg{
210706f2543Smrg    if (!pGlxPbuffer->idExists && !pGlxPbuffer->refcnt) {
211706f2543Smrg        free(pGlxPbuffer->be_xids);
212706f2543Smrg        free(pGlxPbuffer);
213706f2543Smrg    }
214706f2543Smrg}
215706f2543Smrg
216706f2543Smrgstatic void PbufferGone(__glXPbuffer *pGlxPbuffer, XID id)
217706f2543Smrg{
218706f2543Smrg    pGlxPbuffer->idExists = False;
219706f2543Smrg    __glXFreeGLXPbuffer(pGlxPbuffer);
220706f2543Smrg}
221706f2543Smrg
222706f2543Smrg/*
223706f2543Smrg** Free a context.
224706f2543Smrg*/
225706f2543SmrgGLboolean __glXFreeContext(__GLXcontext *cx)
226706f2543Smrg{
227706f2543Smrg    if (cx->idExists || cx->isCurrent) return GL_FALSE;
228706f2543Smrg
229706f2543Smrg    free(cx->feedbackBuf);
230706f2543Smrg    free(cx->selectBuf);
231706f2543Smrg    free(cx->real_ids);
232706f2543Smrg    free(cx->real_vids);
233706f2543Smrg
234706f2543Smrg    if (cx->pGlxPixmap) {
235706f2543Smrg       /*
236706f2543Smrg	** The previous drawable was a glx pixmap, release it.
237706f2543Smrg	*/
238706f2543Smrg       cx->pGlxPixmap->refcnt--;
239706f2543Smrg       __glXFreeGLXPixmap( cx->pGlxPixmap );
240706f2543Smrg       cx->pGlxPixmap = 0;
241706f2543Smrg    }
242706f2543Smrg
243706f2543Smrg    if (cx->pGlxReadPixmap) {
244706f2543Smrg       /*
245706f2543Smrg	** The previous drawable was a glx pixmap, release it.
246706f2543Smrg	*/
247706f2543Smrg       cx->pGlxReadPixmap->refcnt--;
248706f2543Smrg       __glXFreeGLXPixmap( cx->pGlxReadPixmap );
249706f2543Smrg       cx->pGlxReadPixmap = 0;
250706f2543Smrg    }
251706f2543Smrg
252706f2543Smrg    if (cx->pGlxWindow) {
253706f2543Smrg       /*
254706f2543Smrg	** The previous drawable was a glx window, release it.
255706f2543Smrg	*/
256706f2543Smrg       cx->pGlxWindow->refcnt--;
257706f2543Smrg       __glXFreeGLXWindow( cx->pGlxWindow );
258706f2543Smrg       cx->pGlxWindow = 0;
259706f2543Smrg    }
260706f2543Smrg
261706f2543Smrg    if (cx->pGlxReadWindow) {
262706f2543Smrg       /*
263706f2543Smrg	** The previous drawable was a glx window, release it.
264706f2543Smrg	*/
265706f2543Smrg       cx->pGlxReadWindow->refcnt--;
266706f2543Smrg       __glXFreeGLXWindow( cx->pGlxReadWindow );
267706f2543Smrg       cx->pGlxReadWindow = 0;
268706f2543Smrg    }
269706f2543Smrg
270706f2543Smrg    free(cx);
271706f2543Smrg
272706f2543Smrg    if (cx == __glXLastContext) {
273706f2543Smrg	__glXFlushContextCache();
274706f2543Smrg    }
275706f2543Smrg
276706f2543Smrg    return GL_TRUE;
277706f2543Smrg}
278706f2543Smrg
279706f2543Smrg/*
280706f2543Smrg** Initialize the GLX extension.
281706f2543Smrg*/
282706f2543Smrgvoid GlxExtensionInit(void)
283706f2543Smrg{
284706f2543Smrg    ExtensionEntry *extEntry;
285706f2543Smrg    int i;
286706f2543Smrg    int glxSupported = 1;
287706f2543Smrg
288706f2543Smrg    /*
289706f2543Smrg    // do not initialize GLX extension if GLX is not supported
290706f2543Smrg    // by ALL back-end servers.
291706f2543Smrg    */
292706f2543Smrg    for (i=0; i<screenInfo.numScreens; i++) {
293706f2543Smrg       glxSupported &= (dmxScreens[i].glxMajorOpcode > 0);
294706f2543Smrg    }
295706f2543Smrg
296706f2543Smrg    if (!glxSupported || !dmxGLXProxy) {
297706f2543Smrg       return;
298706f2543Smrg    }
299706f2543Smrg
300706f2543Smrg    __glXContextRes = CreateNewResourceType((DeleteType)ContextGone,
301706f2543Smrg					    "GLXContext");
302706f2543Smrg    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone,
303706f2543Smrg					   "GLXClient");
304706f2543Smrg    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone,
305706f2543Smrg					   "GLXPixmap");
306706f2543Smrg    __glXWindowRes = CreateNewResourceType((DeleteType)WindowGone,
307706f2543Smrg					   "GLXWindow");
308706f2543Smrg    __glXPbufferRes = CreateNewResourceType((DeleteType)PbufferGone,
309706f2543Smrg					    "GLXPbuffer");
310706f2543Smrg
311706f2543Smrg    if (!__glXContextRes || !__glXClientRes || !__glXPixmapRes ||
312706f2543Smrg	!__glXWindowRes || !__glXPbufferRes)
313706f2543Smrg	return;
314706f2543Smrg
315706f2543Smrg    /*
316706f2543Smrg    ** Add extension to server extensions.
317706f2543Smrg    */
318706f2543Smrg    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
319706f2543Smrg			    __GLX_NUMBER_ERRORS, __glXDispatch,
320706f2543Smrg			    __glXSwapDispatch, ResetExtension,
321706f2543Smrg			    StandardMinorOpcode);
322706f2543Smrg    if (!extEntry) {
323706f2543Smrg	FatalError("__glXExtensionInit: AddExtensions failed\n");
324706f2543Smrg	return;
325706f2543Smrg    }
326706f2543Smrg    /*
327706f2543Smrg    if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
328706f2543Smrg	ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
329706f2543Smrg	return;
330706f2543Smrg    }
331706f2543Smrg    */
332706f2543Smrg
333706f2543Smrg    __glXerrorBase = extEntry->errorBase;
334706f2543Smrg    __glXBadContext = extEntry->errorBase + GLXBadContext;
335706f2543Smrg    __glXBadContextState = extEntry->errorBase + GLXBadContextState;
336706f2543Smrg    __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
337706f2543Smrg    __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
338706f2543Smrg    __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
339706f2543Smrg    __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
340706f2543Smrg    __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
341706f2543Smrg    __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
342706f2543Smrg    __glXUnsupportedPrivateRequest = extEntry->errorBase +
343706f2543Smrg      			GLXUnsupportedPrivateRequest;
344706f2543Smrg    __glXBadFBConfig = extEntry->errorBase + GLXBadFBConfig;
345706f2543Smrg    __glXBadPbuffer = extEntry->errorBase + GLXBadPbuffer;
346706f2543Smrg
347706f2543Smrg    /*
348706f2543Smrg    ** Initialize table of client state.  There is never a client 0.
349706f2543Smrg    */
350706f2543Smrg    for (i=1; i <= MAXCLIENTS; i++) {
351706f2543Smrg	__glXClients[i] = 0;
352706f2543Smrg    }
353706f2543Smrg
354706f2543Smrg    /*
355706f2543Smrg    ** Initialize screen specific data.
356706f2543Smrg    */
357706f2543Smrg    __glXScreenInit(screenInfo.numScreens);
358706f2543Smrg
359706f2543Smrg    /*
360706f2543Smrg    ** Initialize swap barrier support.
361706f2543Smrg    */
362706f2543Smrg    SwapBarrierInit();
363706f2543Smrg}
364706f2543Smrg
365706f2543Smrg/************************************************************************/
366706f2543Smrg
367706f2543SmrgBool __glXCoreType(void)
368706f2543Smrg{
369706f2543Smrg    return 0;
370706f2543Smrg}
371706f2543Smrg
372706f2543Smrg/************************************************************************/
373706f2543Smrg
374706f2543Smrgvoid __glXFlushContextCache(void)
375706f2543Smrg{
376706f2543Smrg    __glXLastContext = 0;
377706f2543Smrg}
378706f2543Smrg
379706f2543Smrg/************************************************************************/
380706f2543Smrg
381706f2543Smrg/*
382706f2543Smrg** Top level dispatcher; all commands are executed from here down.
383706f2543Smrg*/
384706f2543Smrgstatic int __glXDispatch(ClientPtr client)
385706f2543Smrg{
386706f2543Smrg    REQUEST(xGLXSingleReq);
387706f2543Smrg    CARD8 opcode;
388706f2543Smrg    int (*proc)(__GLXclientState *cl, GLbyte *pc);
389706f2543Smrg    __GLXclientState *cl;
390706f2543Smrg
391706f2543Smrg    opcode = stuff->glxCode;
392706f2543Smrg    cl = __glXClients[client->index];
393706f2543Smrg    if (!cl) {
394706f2543Smrg	cl = calloc(1, sizeof(__GLXclientState));
395706f2543Smrg	 __glXClients[client->index] = cl;
396706f2543Smrg	if (!cl) {
397706f2543Smrg	    return BadAlloc;
398706f2543Smrg	}
399706f2543Smrg
400706f2543Smrg	cl->be_displays = calloc(screenInfo.numScreens, sizeof(Display *));
401706f2543Smrg	if (!cl->be_displays) {
402706f2543Smrg	    free( cl );
403706f2543Smrg	    return BadAlloc;
404706f2543Smrg	}
405706f2543Smrg    }
406706f2543Smrg
407706f2543Smrg    if (!cl->inUse) {
408706f2543Smrg	/*
409706f2543Smrg	** This is first request from this client.  Associate a resource
410706f2543Smrg	** with the client so we will be notified when the client dies.
411706f2543Smrg	*/
412706f2543Smrg	XID xid = FakeClientID(client->index);
413706f2543Smrg	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
414706f2543Smrg	    return BadAlloc;
415706f2543Smrg	}
416706f2543Smrg	ResetClientState(client->index);
417706f2543Smrg	cl->largeCmdRequestsTotal = 0;
418706f2543Smrg	cl->inUse = GL_TRUE;
419706f2543Smrg	cl->client = client;
420706f2543Smrg    }
421706f2543Smrg
422706f2543Smrg    /*
423706f2543Smrg    ** Check for valid opcode.
424706f2543Smrg    */
425706f2543Smrg    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
426706f2543Smrg	return BadRequest;
427706f2543Smrg    }
428706f2543Smrg
429706f2543Smrg    /*
430706f2543Smrg    ** Use the opcode to index into the procedure table.
431706f2543Smrg    */
432706f2543Smrg    proc = __glXSingleTable[opcode];
433706f2543Smrg    return (*proc)(cl, (GLbyte *) stuff);
434706f2543Smrg}
435706f2543Smrg
436706f2543Smrgstatic int __glXSwapDispatch(ClientPtr client)
437706f2543Smrg{
438706f2543Smrg    REQUEST(xGLXSingleReq);
439706f2543Smrg    CARD8 opcode;
440706f2543Smrg    int (*proc)(__GLXclientState *cl, GLbyte *pc);
441706f2543Smrg    __GLXclientState *cl;
442706f2543Smrg
443706f2543Smrg    opcode = stuff->glxCode;
444706f2543Smrg    cl = __glXClients[client->index];
445706f2543Smrg    if (!cl) {
446706f2543Smrg	cl = calloc(1, sizeof(__GLXclientState));
447706f2543Smrg	 __glXClients[client->index] = cl;
448706f2543Smrg	if (!cl) {
449706f2543Smrg	    return BadAlloc;
450706f2543Smrg	}
451706f2543Smrg
452706f2543Smrg	cl->be_displays = calloc(screenInfo.numScreens, sizeof(Display *));
453706f2543Smrg	if (!cl->be_displays) {
454706f2543Smrg	    free( cl );
455706f2543Smrg	    return BadAlloc;
456706f2543Smrg	}
457706f2543Smrg    }
458706f2543Smrg
459706f2543Smrg    if (!cl->inUse) {
460706f2543Smrg	/*
461706f2543Smrg	** This is first request from this client.  Associate a resource
462706f2543Smrg	** with the client so we will be notified when the client dies.
463706f2543Smrg	*/
464706f2543Smrg	XID xid = FakeClientID(client->index);
465706f2543Smrg	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
466706f2543Smrg	    return BadAlloc;
467706f2543Smrg	}
468706f2543Smrg	ResetClientState(client->index);
469706f2543Smrg	cl->inUse = GL_TRUE;
470706f2543Smrg	cl->client = client;
471706f2543Smrg    }
472706f2543Smrg
473706f2543Smrg    /*
474706f2543Smrg    ** Check for valid opcode.
475706f2543Smrg    */
476706f2543Smrg    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
477706f2543Smrg	return BadRequest;
478706f2543Smrg    }
479706f2543Smrg
480706f2543Smrg    /*
481706f2543Smrg    ** Use the opcode to index into the procedure table.
482706f2543Smrg    */
483706f2543Smrg    proc = __glXSwapSingleTable[opcode];
484706f2543Smrg    return (*proc)(cl, (GLbyte *) stuff);
485706f2543Smrg}
486706f2543Smrg
487706f2543Smrgint __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
488706f2543Smrg{
489706f2543Smrg    return BadRequest;
490706f2543Smrg}
491706f2543Smrg
492706f2543Smrgvoid __glXNoSuchRenderOpcode(GLbyte *pc)
493706f2543Smrg{
494706f2543Smrg    return;
495706f2543Smrg}
496706f2543Smrg
497