xref: /OK3568_Linux_fs/external/xserver/glx/glxcmds.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3*4882a593Smuzhiyun  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
6*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
7*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
8*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
10*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * The above copyright notice including the dates of first publication and
13*4882a593Smuzhiyun  * either this permission notice or a reference to
14*4882a593Smuzhiyun  * http://oss.sgi.com/projects/FreeB/
15*4882a593Smuzhiyun  * shall be included in all copies or substantial portions of the Software.
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*4882a593Smuzhiyun  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*4882a593Smuzhiyun  * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21*4882a593Smuzhiyun  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22*4882a593Smuzhiyun  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23*4882a593Smuzhiyun  * SOFTWARE.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * Except as contained in this notice, the name of Silicon Graphics, Inc.
26*4882a593Smuzhiyun  * shall not be used in advertising or otherwise to promote the sale, use or
27*4882a593Smuzhiyun  * other dealings in this Software without prior written authorization from
28*4882a593Smuzhiyun  * Silicon Graphics, Inc.
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
32*4882a593Smuzhiyun #include <dix-config.h>
33*4882a593Smuzhiyun #endif
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #include <string.h>
36*4882a593Smuzhiyun #include <assert.h>
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #include "glxserver.h"
39*4882a593Smuzhiyun #include <GL/glxtokens.h>
40*4882a593Smuzhiyun #include <X11/extensions/presenttokens.h>
41*4882a593Smuzhiyun #include <unpack.h>
42*4882a593Smuzhiyun #include <pixmapstr.h>
43*4882a593Smuzhiyun #include <windowstr.h>
44*4882a593Smuzhiyun #include "glxutil.h"
45*4882a593Smuzhiyun #include "glxext.h"
46*4882a593Smuzhiyun #include "indirect_dispatch.h"
47*4882a593Smuzhiyun #include "indirect_table.h"
48*4882a593Smuzhiyun #include "indirect_util.h"
49*4882a593Smuzhiyun #include "protocol-versions.h"
50*4882a593Smuzhiyun #include "glxvndabi.h"
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun static char GLXServerVendorName[] = "SGI";
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun _X_HIDDEN int
validGlxScreen(ClientPtr client,int screen,__GLXscreen ** pGlxScreen,int * err)55*4882a593Smuzhiyun validGlxScreen(ClientPtr client, int screen, __GLXscreen ** pGlxScreen,
56*4882a593Smuzhiyun                int *err)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun     /*
59*4882a593Smuzhiyun      ** Check if screen exists.
60*4882a593Smuzhiyun      */
61*4882a593Smuzhiyun     if (screen < 0 || screen >= screenInfo.numScreens) {
62*4882a593Smuzhiyun         client->errorValue = screen;
63*4882a593Smuzhiyun         *err = BadValue;
64*4882a593Smuzhiyun         return FALSE;
65*4882a593Smuzhiyun     }
66*4882a593Smuzhiyun     *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun     return TRUE;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun _X_HIDDEN int
validGlxFBConfig(ClientPtr client,__GLXscreen * pGlxScreen,XID id,__GLXconfig ** config,int * err)72*4882a593Smuzhiyun validGlxFBConfig(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
73*4882a593Smuzhiyun                  __GLXconfig ** config, int *err)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun     __GLXconfig *m;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun     for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
78*4882a593Smuzhiyun         if (m->fbconfigID == id) {
79*4882a593Smuzhiyun             *config = m;
80*4882a593Smuzhiyun             return TRUE;
81*4882a593Smuzhiyun         }
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun     client->errorValue = id;
84*4882a593Smuzhiyun     *err = __glXError(GLXBadFBConfig);
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun     return FALSE;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun static int
validGlxVisual(ClientPtr client,__GLXscreen * pGlxScreen,XID id,__GLXconfig ** config,int * err)90*4882a593Smuzhiyun validGlxVisual(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
91*4882a593Smuzhiyun                __GLXconfig ** config, int *err)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun     int i;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun     for (i = 0; i < pGlxScreen->numVisuals; i++)
96*4882a593Smuzhiyun         if (pGlxScreen->visuals[i]->visualID == id) {
97*4882a593Smuzhiyun             *config = pGlxScreen->visuals[i];
98*4882a593Smuzhiyun             return TRUE;
99*4882a593Smuzhiyun         }
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun     client->errorValue = id;
102*4882a593Smuzhiyun     *err = BadValue;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun     return FALSE;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun static int
validGlxFBConfigForWindow(ClientPtr client,__GLXconfig * config,DrawablePtr pDraw,int * err)108*4882a593Smuzhiyun validGlxFBConfigForWindow(ClientPtr client, __GLXconfig * config,
109*4882a593Smuzhiyun                           DrawablePtr pDraw, int *err)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun     ScreenPtr pScreen = pDraw->pScreen;
112*4882a593Smuzhiyun     VisualPtr pVisual = NULL;
113*4882a593Smuzhiyun     XID vid;
114*4882a593Smuzhiyun     int i;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun     vid = wVisual((WindowPtr) pDraw);
117*4882a593Smuzhiyun     for (i = 0; i < pScreen->numVisuals; i++) {
118*4882a593Smuzhiyun         if (pScreen->visuals[i].vid == vid) {
119*4882a593Smuzhiyun             pVisual = &pScreen->visuals[i];
120*4882a593Smuzhiyun             break;
121*4882a593Smuzhiyun         }
122*4882a593Smuzhiyun     }
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun     /* FIXME: What exactly should we check here... */
125*4882a593Smuzhiyun     if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
126*4882a593Smuzhiyun         !(config->drawableType & GLX_WINDOW_BIT)) {
127*4882a593Smuzhiyun         client->errorValue = pDraw->id;
128*4882a593Smuzhiyun         *err = BadMatch;
129*4882a593Smuzhiyun         return FALSE;
130*4882a593Smuzhiyun     }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun     return TRUE;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun _X_HIDDEN int
validGlxContext(ClientPtr client,XID id,int access_mode,__GLXcontext ** context,int * err)136*4882a593Smuzhiyun validGlxContext(ClientPtr client, XID id, int access_mode,
137*4882a593Smuzhiyun                 __GLXcontext ** context, int *err)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun     /* no ghost contexts */
140*4882a593Smuzhiyun     if (id & SERVER_BIT) {
141*4882a593Smuzhiyun         *err = __glXError(GLXBadContext);
142*4882a593Smuzhiyun         return FALSE;
143*4882a593Smuzhiyun     }
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun     *err = dixLookupResourceByType((void **) context, id,
146*4882a593Smuzhiyun                                    __glXContextRes, client, access_mode);
147*4882a593Smuzhiyun     if (*err != Success || (*context)->idExists == GL_FALSE) {
148*4882a593Smuzhiyun         client->errorValue = id;
149*4882a593Smuzhiyun         if (*err == BadValue || *err == Success)
150*4882a593Smuzhiyun             *err = __glXError(GLXBadContext);
151*4882a593Smuzhiyun         return FALSE;
152*4882a593Smuzhiyun     }
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun     return TRUE;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun int
validGlxDrawable(ClientPtr client,XID id,int type,int access_mode,__GLXdrawable ** drawable,int * err)158*4882a593Smuzhiyun validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
159*4882a593Smuzhiyun                  __GLXdrawable ** drawable, int *err)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun     int rc;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun     rc = dixLookupResourceByType((void **) drawable, id,
164*4882a593Smuzhiyun                                  __glXDrawableRes, client, access_mode);
165*4882a593Smuzhiyun     if (rc != Success && rc != BadValue) {
166*4882a593Smuzhiyun         *err = rc;
167*4882a593Smuzhiyun         client->errorValue = id;
168*4882a593Smuzhiyun         return FALSE;
169*4882a593Smuzhiyun     }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun     /* If the ID of the glx drawable we looked up doesn't match the id
172*4882a593Smuzhiyun      * we looked for, it's because we looked it up under the X
173*4882a593Smuzhiyun      * drawable ID (see DoCreateGLXDrawable). */
174*4882a593Smuzhiyun     if (rc == BadValue ||
175*4882a593Smuzhiyun         (*drawable)->drawId != id ||
176*4882a593Smuzhiyun         (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
177*4882a593Smuzhiyun         client->errorValue = id;
178*4882a593Smuzhiyun         switch (type) {
179*4882a593Smuzhiyun         case GLX_DRAWABLE_WINDOW:
180*4882a593Smuzhiyun             *err = __glXError(GLXBadWindow);
181*4882a593Smuzhiyun             return FALSE;
182*4882a593Smuzhiyun         case GLX_DRAWABLE_PIXMAP:
183*4882a593Smuzhiyun             *err = __glXError(GLXBadPixmap);
184*4882a593Smuzhiyun             return FALSE;
185*4882a593Smuzhiyun         case GLX_DRAWABLE_PBUFFER:
186*4882a593Smuzhiyun             *err = __glXError(GLXBadPbuffer);
187*4882a593Smuzhiyun             return FALSE;
188*4882a593Smuzhiyun         case GLX_DRAWABLE_ANY:
189*4882a593Smuzhiyun             *err = __glXError(GLXBadDrawable);
190*4882a593Smuzhiyun             return FALSE;
191*4882a593Smuzhiyun         }
192*4882a593Smuzhiyun     }
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun     return TRUE;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun void
__glXContextDestroy(__GLXcontext * context)198*4882a593Smuzhiyun __glXContextDestroy(__GLXcontext * context)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun     lastGLContext = NULL;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun static void
__glXdirectContextDestroy(__GLXcontext * context)204*4882a593Smuzhiyun __glXdirectContextDestroy(__GLXcontext * context)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun     __glXContextDestroy(context);
207*4882a593Smuzhiyun     free(context);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun static int
__glXdirectContextLoseCurrent(__GLXcontext * context)211*4882a593Smuzhiyun __glXdirectContextLoseCurrent(__GLXcontext * context)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun     return GL_TRUE;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun _X_HIDDEN __GLXcontext *
__glXdirectContextCreate(__GLXscreen * screen,__GLXconfig * modes,__GLXcontext * shareContext)217*4882a593Smuzhiyun __glXdirectContextCreate(__GLXscreen * screen,
218*4882a593Smuzhiyun                          __GLXconfig * modes, __GLXcontext * shareContext)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun     __GLXcontext *context;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun     context = calloc(1, sizeof(__GLXcontext));
223*4882a593Smuzhiyun     if (context == NULL)
224*4882a593Smuzhiyun         return NULL;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun     context->config = modes;
227*4882a593Smuzhiyun     context->destroy = __glXdirectContextDestroy;
228*4882a593Smuzhiyun     context->loseCurrent = __glXdirectContextLoseCurrent;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun     return context;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun /**
234*4882a593Smuzhiyun  * Create a GL context with the given properties.  This routine is used
235*4882a593Smuzhiyun  * to implement \c glXCreateContext, \c glXCreateNewContext, and
236*4882a593Smuzhiyun  * \c glXCreateContextWithConfigSGIX.  This works because of the hack way
237*4882a593Smuzhiyun  * that GLXFBConfigs are implemented.  Basically, the FBConfigID is the
238*4882a593Smuzhiyun  * same as the VisualID.
239*4882a593Smuzhiyun  */
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun static int
DoCreateContext(__GLXclientState * cl,GLXContextID gcId,GLXContextID shareList,__GLXconfig * config,__GLXscreen * pGlxScreen,GLboolean isDirect)242*4882a593Smuzhiyun DoCreateContext(__GLXclientState * cl, GLXContextID gcId,
243*4882a593Smuzhiyun                 GLXContextID shareList, __GLXconfig * config,
244*4882a593Smuzhiyun                 __GLXscreen * pGlxScreen, GLboolean isDirect)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun     ClientPtr client = cl->client;
247*4882a593Smuzhiyun     __GLXcontext *glxc, *shareglxc;
248*4882a593Smuzhiyun     int err;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun     /*
251*4882a593Smuzhiyun      ** Find the display list space that we want to share.
252*4882a593Smuzhiyun      **
253*4882a593Smuzhiyun      ** NOTE: In a multithreaded X server, we would need to keep a reference
254*4882a593Smuzhiyun      ** count for each display list so that if one client detroyed a list that
255*4882a593Smuzhiyun      ** another client was using, the list would not really be freed until it
256*4882a593Smuzhiyun      ** was no longer in use.  Since this sample implementation has no support
257*4882a593Smuzhiyun      ** for multithreaded servers, we don't do this.
258*4882a593Smuzhiyun      */
259*4882a593Smuzhiyun     if (shareList == None) {
260*4882a593Smuzhiyun         shareglxc = 0;
261*4882a593Smuzhiyun     }
262*4882a593Smuzhiyun     else {
263*4882a593Smuzhiyun         if (!validGlxContext(client, shareList, DixReadAccess,
264*4882a593Smuzhiyun                              &shareglxc, &err))
265*4882a593Smuzhiyun             return err;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun         /* Page 26 (page 32 of the PDF) of the GLX 1.4 spec says:
268*4882a593Smuzhiyun          *
269*4882a593Smuzhiyun          *     "The server context state for all sharing contexts must exist
270*4882a593Smuzhiyun          *     in a single address space or a BadMatch error is generated."
271*4882a593Smuzhiyun          *
272*4882a593Smuzhiyun          * If the share context is indirect, force the new context to also be
273*4882a593Smuzhiyun          * indirect.  If the shard context is direct but the new context
274*4882a593Smuzhiyun          * cannot be direct, generate BadMatch.
275*4882a593Smuzhiyun          */
276*4882a593Smuzhiyun         if (shareglxc->isDirect && !isDirect) {
277*4882a593Smuzhiyun             client->errorValue = shareList;
278*4882a593Smuzhiyun             return BadMatch;
279*4882a593Smuzhiyun         }
280*4882a593Smuzhiyun         else if (!shareglxc->isDirect) {
281*4882a593Smuzhiyun             /*
282*4882a593Smuzhiyun              ** Create an indirect context regardless of what the client asked
283*4882a593Smuzhiyun              ** for; this way we can share display list space with shareList.
284*4882a593Smuzhiyun              */
285*4882a593Smuzhiyun             isDirect = GL_FALSE;
286*4882a593Smuzhiyun         }
287*4882a593Smuzhiyun     }
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun     /*
290*4882a593Smuzhiyun      ** Allocate memory for the new context
291*4882a593Smuzhiyun      */
292*4882a593Smuzhiyun     if (!isDirect) {
293*4882a593Smuzhiyun         /* Only allow creating indirect GLX contexts if allowed by
294*4882a593Smuzhiyun          * server command line.  Indirect GLX is of limited use (since
295*4882a593Smuzhiyun          * it's only GL 1.4), it's slower than direct contexts, and
296*4882a593Smuzhiyun          * it's a massive attack surface for buffer overflow type
297*4882a593Smuzhiyun          * errors.
298*4882a593Smuzhiyun          */
299*4882a593Smuzhiyun         if (!enableIndirectGLX) {
300*4882a593Smuzhiyun             client->errorValue = isDirect;
301*4882a593Smuzhiyun             return BadValue;
302*4882a593Smuzhiyun         }
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun         /* Without any attributes, the only error that the driver should be
305*4882a593Smuzhiyun          * able to generate is BadAlloc.  As result, just drop the error
306*4882a593Smuzhiyun          * returned from the driver on the floor.
307*4882a593Smuzhiyun          */
308*4882a593Smuzhiyun         glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc,
309*4882a593Smuzhiyun                                          0, NULL, &err);
310*4882a593Smuzhiyun     }
311*4882a593Smuzhiyun     else
312*4882a593Smuzhiyun         glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
313*4882a593Smuzhiyun     if (!glxc) {
314*4882a593Smuzhiyun         return BadAlloc;
315*4882a593Smuzhiyun     }
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun     /* Initialize the GLXcontext structure.
318*4882a593Smuzhiyun      */
319*4882a593Smuzhiyun     glxc->pGlxScreen = pGlxScreen;
320*4882a593Smuzhiyun     glxc->config = config;
321*4882a593Smuzhiyun     glxc->id = gcId;
322*4882a593Smuzhiyun     glxc->share_id = shareList;
323*4882a593Smuzhiyun     glxc->idExists = GL_TRUE;
324*4882a593Smuzhiyun     glxc->isDirect = isDirect;
325*4882a593Smuzhiyun     glxc->renderMode = GL_RENDER;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun     /* The GLX_ARB_create_context_robustness spec says:
328*4882a593Smuzhiyun      *
329*4882a593Smuzhiyun      *     "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
330*4882a593Smuzhiyun      *     is GLX_NO_RESET_NOTIFICATION_ARB."
331*4882a593Smuzhiyun      *
332*4882a593Smuzhiyun      * Without using glXCreateContextAttribsARB, there is no way to specify a
333*4882a593Smuzhiyun      * non-default reset notification strategy.
334*4882a593Smuzhiyun      */
335*4882a593Smuzhiyun     glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB;
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
338*4882a593Smuzhiyun     /* The GLX_ARB_context_flush_control spec says:
339*4882a593Smuzhiyun      *
340*4882a593Smuzhiyun      *     "The default value [for GLX_CONTEXT_RELEASE_BEHAVIOR] is
341*4882a593Smuzhiyun      *     CONTEXT_RELEASE_BEHAVIOR_FLUSH, and may in some cases be changed
342*4882a593Smuzhiyun      *     using platform-specific context creation extensions."
343*4882a593Smuzhiyun      *
344*4882a593Smuzhiyun      * Without using glXCreateContextAttribsARB, there is no way to specify a
345*4882a593Smuzhiyun      * non-default release behavior.
346*4882a593Smuzhiyun      */
347*4882a593Smuzhiyun     glxc->releaseBehavior = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
348*4882a593Smuzhiyun #endif
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun     /* Add the new context to the various global tables of GLX contexts.
351*4882a593Smuzhiyun      */
352*4882a593Smuzhiyun     if (!__glXAddContext(glxc)) {
353*4882a593Smuzhiyun         (*glxc->destroy) (glxc);
354*4882a593Smuzhiyun         client->errorValue = gcId;
355*4882a593Smuzhiyun         return BadAlloc;
356*4882a593Smuzhiyun     }
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun     return Success;
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun int
__glXDisp_CreateContext(__GLXclientState * cl,GLbyte * pc)362*4882a593Smuzhiyun __glXDisp_CreateContext(__GLXclientState * cl, GLbyte * pc)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun     xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
365*4882a593Smuzhiyun     __GLXconfig *config;
366*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
367*4882a593Smuzhiyun     int err;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
370*4882a593Smuzhiyun         return err;
371*4882a593Smuzhiyun     if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
372*4882a593Smuzhiyun         return err;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun     return DoCreateContext(cl, req->context, req->shareList,
375*4882a593Smuzhiyun                            config, pGlxScreen, req->isDirect);
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun int
__glXDisp_CreateNewContext(__GLXclientState * cl,GLbyte * pc)379*4882a593Smuzhiyun __glXDisp_CreateNewContext(__GLXclientState * cl, GLbyte * pc)
380*4882a593Smuzhiyun {
381*4882a593Smuzhiyun     xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
382*4882a593Smuzhiyun     __GLXconfig *config;
383*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
384*4882a593Smuzhiyun     int err;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
387*4882a593Smuzhiyun         return err;
388*4882a593Smuzhiyun     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
389*4882a593Smuzhiyun         return err;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun     return DoCreateContext(cl, req->context, req->shareList,
392*4882a593Smuzhiyun                            config, pGlxScreen, req->isDirect);
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun int
__glXDisp_CreateContextWithConfigSGIX(__GLXclientState * cl,GLbyte * pc)396*4882a593Smuzhiyun __glXDisp_CreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun     ClientPtr client = cl->client;
399*4882a593Smuzhiyun     xGLXCreateContextWithConfigSGIXReq *req =
400*4882a593Smuzhiyun         (xGLXCreateContextWithConfigSGIXReq *) pc;
401*4882a593Smuzhiyun     __GLXconfig *config;
402*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
403*4882a593Smuzhiyun     int err;
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq);
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
408*4882a593Smuzhiyun         return err;
409*4882a593Smuzhiyun     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
410*4882a593Smuzhiyun         return err;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun     return DoCreateContext(cl, req->context, req->shareList,
413*4882a593Smuzhiyun                            config, pGlxScreen, req->isDirect);
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun int
__glXDisp_DestroyContext(__GLXclientState * cl,GLbyte * pc)417*4882a593Smuzhiyun __glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun     xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
420*4882a593Smuzhiyun     __GLXcontext *glxc;
421*4882a593Smuzhiyun     int err;
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun     if (!validGlxContext(cl->client, req->context, DixDestroyAccess,
424*4882a593Smuzhiyun                          &glxc, &err))
425*4882a593Smuzhiyun         return err;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun     glxc->idExists = GL_FALSE;
428*4882a593Smuzhiyun     if (glxc->currentClient) {
429*4882a593Smuzhiyun         XID ghost = FakeClientID(glxc->currentClient->index);
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun         if (!AddResource(ghost, __glXContextRes, glxc))
432*4882a593Smuzhiyun             return BadAlloc;
433*4882a593Smuzhiyun         ChangeResourceValue(glxc->id, __glXContextRes, NULL);
434*4882a593Smuzhiyun         glxc->id = ghost;
435*4882a593Smuzhiyun     }
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun     FreeResourceByType(req->context, __glXContextRes, FALSE);
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun     return Success;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun __GLXcontext *
__glXLookupContextByTag(__GLXclientState * cl,GLXContextTag tag)443*4882a593Smuzhiyun __glXLookupContextByTag(__GLXclientState * cl, GLXContextTag tag)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun     return glxServer.getContextTagPrivate(cl->client, tag);
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun static __GLXconfig *
inferConfigForWindow(__GLXscreen * pGlxScreen,WindowPtr pWin)449*4882a593Smuzhiyun inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin)
450*4882a593Smuzhiyun {
451*4882a593Smuzhiyun     int i, vid = wVisual(pWin);
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun     for (i = 0; i < pGlxScreen->numVisuals; i++)
454*4882a593Smuzhiyun         if (pGlxScreen->visuals[i]->visualID == vid)
455*4882a593Smuzhiyun             return pGlxScreen->visuals[i];
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun     return NULL;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun /**
461*4882a593Smuzhiyun  * This is a helper function to handle the legacy (pre GLX 1.3) cases
462*4882a593Smuzhiyun  * where passing an X window to glXMakeCurrent is valid.  Given a
463*4882a593Smuzhiyun  * resource ID, look up the GLX drawable if available, otherwise, make
464*4882a593Smuzhiyun  * sure it's an X window and create a GLX drawable one the fly.
465*4882a593Smuzhiyun  */
466*4882a593Smuzhiyun static __GLXdrawable *
__glXGetDrawable(__GLXcontext * glxc,GLXDrawable drawId,ClientPtr client,int * error)467*4882a593Smuzhiyun __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
468*4882a593Smuzhiyun                  int *error)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun     DrawablePtr pDraw;
471*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
472*4882a593Smuzhiyun     __GLXconfig *config;
473*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
474*4882a593Smuzhiyun     int rc;
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun     if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
477*4882a593Smuzhiyun                          DixWriteAccess, &pGlxDraw, &rc)) {
478*4882a593Smuzhiyun         if (glxc != NULL &&
479*4882a593Smuzhiyun             glxc->config != NULL &&
480*4882a593Smuzhiyun             glxc->config != pGlxDraw->config) {
481*4882a593Smuzhiyun             client->errorValue = drawId;
482*4882a593Smuzhiyun             *error = BadMatch;
483*4882a593Smuzhiyun             return NULL;
484*4882a593Smuzhiyun         }
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun         return pGlxDraw;
487*4882a593Smuzhiyun     }
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun     /* No active context and an unknown drawable, bail. */
490*4882a593Smuzhiyun     if (glxc == NULL) {
491*4882a593Smuzhiyun         client->errorValue = drawId;
492*4882a593Smuzhiyun         *error = BadMatch;
493*4882a593Smuzhiyun         return NULL;
494*4882a593Smuzhiyun     }
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun     /* The drawId wasn't a GLX drawable.  Make sure it's a window and
497*4882a593Smuzhiyun      * create a GLXWindow for it.  Check that the drawable screen
498*4882a593Smuzhiyun      * matches the context screen and that the context fbconfig is
499*4882a593Smuzhiyun      * compatible with the window visual. */
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun     rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
502*4882a593Smuzhiyun     if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
503*4882a593Smuzhiyun         client->errorValue = drawId;
504*4882a593Smuzhiyun         *error = __glXError(GLXBadDrawable);
505*4882a593Smuzhiyun         return NULL;
506*4882a593Smuzhiyun     }
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun     pGlxScreen = glxc->pGlxScreen;
509*4882a593Smuzhiyun     if (pDraw->pScreen != pGlxScreen->pScreen) {
510*4882a593Smuzhiyun         client->errorValue = pDraw->pScreen->myNum;
511*4882a593Smuzhiyun         *error = BadMatch;
512*4882a593Smuzhiyun         return NULL;
513*4882a593Smuzhiyun     }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun     config = glxc->config;
516*4882a593Smuzhiyun     if (!config)
517*4882a593Smuzhiyun         config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw);
518*4882a593Smuzhiyun     if (!config) {
519*4882a593Smuzhiyun         /*
520*4882a593Smuzhiyun          * If we get here, we've tried to bind a no-config context to a
521*4882a593Smuzhiyun          * window without a corresponding fbconfig, presumably because
522*4882a593Smuzhiyun          * we don't support GL on it (PseudoColor perhaps). From GLX Section
523*4882a593Smuzhiyun          * 3.3.7 "Rendering Contexts":
524*4882a593Smuzhiyun          *
525*4882a593Smuzhiyun          * "If draw or read are not compatible with ctx a BadMatch error
526*4882a593Smuzhiyun          * is generated."
527*4882a593Smuzhiyun          */
528*4882a593Smuzhiyun         *error = BadMatch;
529*4882a593Smuzhiyun         return NULL;
530*4882a593Smuzhiyun     }
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun     if (!validGlxFBConfigForWindow(client, config, pDraw, error))
533*4882a593Smuzhiyun         return NULL;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun     pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId,
536*4882a593Smuzhiyun                                           GLX_DRAWABLE_WINDOW, drawId, config);
537*4882a593Smuzhiyun     if (!pGlxDraw) {
538*4882a593Smuzhiyun 	*error = BadAlloc;
539*4882a593Smuzhiyun 	return NULL;
540*4882a593Smuzhiyun     }
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun     /* since we are creating the drawablePrivate, drawId should be new */
543*4882a593Smuzhiyun     if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
544*4882a593Smuzhiyun         *error = BadAlloc;
545*4882a593Smuzhiyun         return NULL;
546*4882a593Smuzhiyun     }
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun     return pGlxDraw;
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun /*****************************************************************************/
552*4882a593Smuzhiyun /*
553*4882a593Smuzhiyun ** Make an OpenGL context and drawable current.
554*4882a593Smuzhiyun */
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun int
xorgGlxMakeCurrent(ClientPtr client,GLXContextTag tag,XID drawId,XID readId,XID contextId,GLXContextTag newContextTag)557*4882a593Smuzhiyun xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
558*4882a593Smuzhiyun                    XID contextId, GLXContextTag newContextTag)
559*4882a593Smuzhiyun {
560*4882a593Smuzhiyun     __GLXclientState *cl = glxGetClient(client);
561*4882a593Smuzhiyun     __GLXcontext *glxc = NULL, *prevglxc = NULL;
562*4882a593Smuzhiyun     __GLXdrawable *drawPriv = NULL;
563*4882a593Smuzhiyun     __GLXdrawable *readPriv = NULL;
564*4882a593Smuzhiyun     int error;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun     /* Drawables but no context makes no sense */
567*4882a593Smuzhiyun     if (!contextId && (drawId || readId))
568*4882a593Smuzhiyun         return BadMatch;
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun     /* If either drawable is null, the other must be too */
571*4882a593Smuzhiyun     if ((drawId == None) != (readId == None))
572*4882a593Smuzhiyun         return BadMatch;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun     /* Look up old context. If we have one, it must be in a usable state. */
575*4882a593Smuzhiyun     if (tag != 0) {
576*4882a593Smuzhiyun         prevglxc = glxServer.getContextTagPrivate(client, tag);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun         if (prevglxc && prevglxc->renderMode != GL_RENDER) {
579*4882a593Smuzhiyun             /* Oops.  Not in render mode render. */
580*4882a593Smuzhiyun             client->errorValue = prevglxc->id;
581*4882a593Smuzhiyun             return __glXError(GLXBadContextState);
582*4882a593Smuzhiyun         }
583*4882a593Smuzhiyun     }
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun     /* Look up new context. It must not be current for someone else. */
586*4882a593Smuzhiyun     if (contextId != None) {
587*4882a593Smuzhiyun         int status;
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun         if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error))
590*4882a593Smuzhiyun             return error;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun         if ((glxc != prevglxc) && glxc->currentClient)
593*4882a593Smuzhiyun             return BadAccess;
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun         if (drawId) {
596*4882a593Smuzhiyun             drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
597*4882a593Smuzhiyun             if (drawPriv == NULL)
598*4882a593Smuzhiyun                 return status;
599*4882a593Smuzhiyun         }
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun         if (readId) {
602*4882a593Smuzhiyun             readPriv = __glXGetDrawable(glxc, readId, client, &status);
603*4882a593Smuzhiyun             if (readPriv == NULL)
604*4882a593Smuzhiyun                 return status;
605*4882a593Smuzhiyun         }
606*4882a593Smuzhiyun     }
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun     if (prevglxc) {
609*4882a593Smuzhiyun         /* Flush the previous context if needed. */
610*4882a593Smuzhiyun         Bool need_flush = !prevglxc->isDirect;
611*4882a593Smuzhiyun #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
612*4882a593Smuzhiyun         if (prevglxc->releaseBehavior == GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB)
613*4882a593Smuzhiyun             need_flush = GL_FALSE;
614*4882a593Smuzhiyun #endif
615*4882a593Smuzhiyun         if (need_flush) {
616*4882a593Smuzhiyun             if (!__glXForceCurrent(cl, tag, (int *) &error))
617*4882a593Smuzhiyun                 return error;
618*4882a593Smuzhiyun             glFlush();
619*4882a593Smuzhiyun         }
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun         /* Make the previous context not current. */
622*4882a593Smuzhiyun         if (!(*prevglxc->loseCurrent) (prevglxc))
623*4882a593Smuzhiyun             return __glXError(GLXBadContext);
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun         lastGLContext = NULL;
626*4882a593Smuzhiyun         if (!prevglxc->isDirect) {
627*4882a593Smuzhiyun             prevglxc->drawPriv = NULL;
628*4882a593Smuzhiyun             prevglxc->readPriv = NULL;
629*4882a593Smuzhiyun         }
630*4882a593Smuzhiyun     }
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun     if (glxc && !glxc->isDirect) {
633*4882a593Smuzhiyun         glxc->drawPriv = drawPriv;
634*4882a593Smuzhiyun         glxc->readPriv = readPriv;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun         /* make the context current */
637*4882a593Smuzhiyun         lastGLContext = glxc;
638*4882a593Smuzhiyun         if (!(*glxc->makeCurrent) (glxc)) {
639*4882a593Smuzhiyun             lastGLContext = NULL;
640*4882a593Smuzhiyun             glxc->drawPriv = NULL;
641*4882a593Smuzhiyun             glxc->readPriv = NULL;
642*4882a593Smuzhiyun             return __glXError(GLXBadContext);
643*4882a593Smuzhiyun         }
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun         glxc->currentClient = client;
646*4882a593Smuzhiyun         glxServer.setContextTagPrivate(client, newContextTag, glxc);
647*4882a593Smuzhiyun     }
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun     if (prevglxc) {
650*4882a593Smuzhiyun         prevglxc->currentClient = NULL;
651*4882a593Smuzhiyun         if (!prevglxc->idExists) {
652*4882a593Smuzhiyun             FreeResourceByType(prevglxc->id, __glXContextRes, FALSE);
653*4882a593Smuzhiyun         }
654*4882a593Smuzhiyun     }
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun     return Success;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun int
__glXDisp_MakeCurrent(__GLXclientState * cl,GLbyte * pc)660*4882a593Smuzhiyun __glXDisp_MakeCurrent(__GLXclientState * cl, GLbyte * pc)
661*4882a593Smuzhiyun {
662*4882a593Smuzhiyun     return BadImplementation;
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun int
__glXDisp_MakeContextCurrent(__GLXclientState * cl,GLbyte * pc)666*4882a593Smuzhiyun __glXDisp_MakeContextCurrent(__GLXclientState * cl, GLbyte * pc)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun     return BadImplementation;
669*4882a593Smuzhiyun }
670*4882a593Smuzhiyun 
671*4882a593Smuzhiyun int
__glXDisp_MakeCurrentReadSGI(__GLXclientState * cl,GLbyte * pc)672*4882a593Smuzhiyun __glXDisp_MakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc)
673*4882a593Smuzhiyun {
674*4882a593Smuzhiyun     return BadImplementation;
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun int
__glXDisp_IsDirect(__GLXclientState * cl,GLbyte * pc)678*4882a593Smuzhiyun __glXDisp_IsDirect(__GLXclientState * cl, GLbyte * pc)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun     ClientPtr client = cl->client;
681*4882a593Smuzhiyun     xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
682*4882a593Smuzhiyun     xGLXIsDirectReply reply;
683*4882a593Smuzhiyun     __GLXcontext *glxc;
684*4882a593Smuzhiyun     int err;
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun     if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err))
687*4882a593Smuzhiyun         return err;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun     reply = (xGLXIsDirectReply) {
690*4882a593Smuzhiyun         .type = X_Reply,
691*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
692*4882a593Smuzhiyun         .length = 0,
693*4882a593Smuzhiyun         .isDirect = glxc->isDirect
694*4882a593Smuzhiyun     };
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun     if (client->swapped) {
697*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_VARIABLES;
698*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
699*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
700*4882a593Smuzhiyun     }
701*4882a593Smuzhiyun     WriteToClient(client, sz_xGLXIsDirectReply, &reply);
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun     return Success;
704*4882a593Smuzhiyun }
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun int
__glXDisp_QueryVersion(__GLXclientState * cl,GLbyte * pc)707*4882a593Smuzhiyun __glXDisp_QueryVersion(__GLXclientState * cl, GLbyte * pc)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun     ClientPtr client = cl->client;
710*4882a593Smuzhiyun     xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
711*4882a593Smuzhiyun     xGLXQueryVersionReply reply;
712*4882a593Smuzhiyun     GLuint major, minor;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xGLXQueryVersionReq);
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun     major = req->majorVersion;
717*4882a593Smuzhiyun     minor = req->minorVersion;
718*4882a593Smuzhiyun     (void) major;
719*4882a593Smuzhiyun     (void) minor;
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun     /*
722*4882a593Smuzhiyun      ** Server should take into consideration the version numbers sent by the
723*4882a593Smuzhiyun      ** client if it wants to work with older clients; however, in this
724*4882a593Smuzhiyun      ** implementation the server just returns its version number.
725*4882a593Smuzhiyun      */
726*4882a593Smuzhiyun     reply = (xGLXQueryVersionReply) {
727*4882a593Smuzhiyun         .type = X_Reply,
728*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
729*4882a593Smuzhiyun         .length = 0,
730*4882a593Smuzhiyun         .majorVersion = SERVER_GLX_MAJOR_VERSION,
731*4882a593Smuzhiyun         .minorVersion = SERVER_GLX_MINOR_VERSION
732*4882a593Smuzhiyun     };
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun     if (client->swapped) {
735*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_VARIABLES;
736*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
737*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
738*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.majorVersion);
739*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.minorVersion);
740*4882a593Smuzhiyun     }
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun     WriteToClient(client, sz_xGLXQueryVersionReply, &reply);
743*4882a593Smuzhiyun     return Success;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun int
__glXDisp_WaitGL(__GLXclientState * cl,GLbyte * pc)747*4882a593Smuzhiyun __glXDisp_WaitGL(__GLXclientState * cl, GLbyte * pc)
748*4882a593Smuzhiyun {
749*4882a593Smuzhiyun     xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
750*4882a593Smuzhiyun     GLXContextTag tag;
751*4882a593Smuzhiyun     __GLXcontext *glxc = NULL;
752*4882a593Smuzhiyun     int error;
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun     tag = req->contextTag;
755*4882a593Smuzhiyun     if (tag) {
756*4882a593Smuzhiyun         glxc = __glXLookupContextByTag(cl, tag);
757*4882a593Smuzhiyun         if (!glxc)
758*4882a593Smuzhiyun             return __glXError(GLXBadContextTag);
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun         if (!__glXForceCurrent(cl, req->contextTag, &error))
761*4882a593Smuzhiyun             return error;
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun         glFinish();
764*4882a593Smuzhiyun     }
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun     if (glxc && glxc->drawPriv->waitGL)
767*4882a593Smuzhiyun         (*glxc->drawPriv->waitGL) (glxc->drawPriv);
768*4882a593Smuzhiyun 
769*4882a593Smuzhiyun     return Success;
770*4882a593Smuzhiyun }
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun int
__glXDisp_WaitX(__GLXclientState * cl,GLbyte * pc)773*4882a593Smuzhiyun __glXDisp_WaitX(__GLXclientState * cl, GLbyte * pc)
774*4882a593Smuzhiyun {
775*4882a593Smuzhiyun     xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
776*4882a593Smuzhiyun     GLXContextTag tag;
777*4882a593Smuzhiyun     __GLXcontext *glxc = NULL;
778*4882a593Smuzhiyun     int error;
779*4882a593Smuzhiyun 
780*4882a593Smuzhiyun     tag = req->contextTag;
781*4882a593Smuzhiyun     if (tag) {
782*4882a593Smuzhiyun         glxc = __glXLookupContextByTag(cl, tag);
783*4882a593Smuzhiyun         if (!glxc)
784*4882a593Smuzhiyun             return __glXError(GLXBadContextTag);
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun         if (!__glXForceCurrent(cl, req->contextTag, &error))
787*4882a593Smuzhiyun             return error;
788*4882a593Smuzhiyun     }
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun     if (glxc && glxc->drawPriv->waitX)
791*4882a593Smuzhiyun         (*glxc->drawPriv->waitX) (glxc->drawPriv);
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun     return Success;
794*4882a593Smuzhiyun }
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun int
__glXDisp_CopyContext(__GLXclientState * cl,GLbyte * pc)797*4882a593Smuzhiyun __glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun     ClientPtr client = cl->client;
800*4882a593Smuzhiyun     xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
801*4882a593Smuzhiyun     GLXContextID source;
802*4882a593Smuzhiyun     GLXContextID dest;
803*4882a593Smuzhiyun     GLXContextTag tag;
804*4882a593Smuzhiyun     unsigned long mask;
805*4882a593Smuzhiyun     __GLXcontext *src, *dst;
806*4882a593Smuzhiyun     int error;
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun     source = req->source;
809*4882a593Smuzhiyun     dest = req->dest;
810*4882a593Smuzhiyun     tag = req->contextTag;
811*4882a593Smuzhiyun     mask = req->mask;
812*4882a593Smuzhiyun     if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error))
813*4882a593Smuzhiyun         return error;
814*4882a593Smuzhiyun     if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error))
815*4882a593Smuzhiyun         return error;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun     /*
818*4882a593Smuzhiyun      ** They must be in the same address space, and same screen.
819*4882a593Smuzhiyun      ** NOTE: no support for direct rendering contexts here.
820*4882a593Smuzhiyun      */
821*4882a593Smuzhiyun     if (src->isDirect || dst->isDirect || (src->pGlxScreen != dst->pGlxScreen)) {
822*4882a593Smuzhiyun         client->errorValue = source;
823*4882a593Smuzhiyun         return BadMatch;
824*4882a593Smuzhiyun     }
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun     /*
827*4882a593Smuzhiyun      ** The destination context must not be current for any client.
828*4882a593Smuzhiyun      */
829*4882a593Smuzhiyun     if (dst->currentClient) {
830*4882a593Smuzhiyun         client->errorValue = dest;
831*4882a593Smuzhiyun         return BadAccess;
832*4882a593Smuzhiyun     }
833*4882a593Smuzhiyun 
834*4882a593Smuzhiyun     if (tag) {
835*4882a593Smuzhiyun         __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun         if (!tagcx) {
838*4882a593Smuzhiyun             return __glXError(GLXBadContextTag);
839*4882a593Smuzhiyun         }
840*4882a593Smuzhiyun         if (tagcx != src) {
841*4882a593Smuzhiyun             /*
842*4882a593Smuzhiyun              ** This would be caused by a faulty implementation of the client
843*4882a593Smuzhiyun              ** library.
844*4882a593Smuzhiyun              */
845*4882a593Smuzhiyun             return BadMatch;
846*4882a593Smuzhiyun         }
847*4882a593Smuzhiyun         /*
848*4882a593Smuzhiyun          ** In this case, glXCopyContext is in both GL and X streams, in terms
849*4882a593Smuzhiyun          ** of sequentiality.
850*4882a593Smuzhiyun          */
851*4882a593Smuzhiyun         if (__glXForceCurrent(cl, tag, &error)) {
852*4882a593Smuzhiyun             /*
853*4882a593Smuzhiyun              ** Do whatever is needed to make sure that all preceding requests
854*4882a593Smuzhiyun              ** in both streams are completed before the copy is executed.
855*4882a593Smuzhiyun              */
856*4882a593Smuzhiyun             glFinish();
857*4882a593Smuzhiyun         }
858*4882a593Smuzhiyun         else {
859*4882a593Smuzhiyun             return error;
860*4882a593Smuzhiyun         }
861*4882a593Smuzhiyun     }
862*4882a593Smuzhiyun     /*
863*4882a593Smuzhiyun      ** Issue copy.  The only reason for failure is a bad mask.
864*4882a593Smuzhiyun      */
865*4882a593Smuzhiyun     if (!(*dst->copy) (dst, src, mask)) {
866*4882a593Smuzhiyun         client->errorValue = mask;
867*4882a593Smuzhiyun         return BadValue;
868*4882a593Smuzhiyun     }
869*4882a593Smuzhiyun     return Success;
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun enum {
873*4882a593Smuzhiyun     GLX_VIS_CONFIG_UNPAIRED = 18,
874*4882a593Smuzhiyun     GLX_VIS_CONFIG_PAIRED = 22
875*4882a593Smuzhiyun };
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun enum {
878*4882a593Smuzhiyun     GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
879*4882a593Smuzhiyun };
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun int
__glXDisp_GetVisualConfigs(__GLXclientState * cl,GLbyte * pc)882*4882a593Smuzhiyun __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun     xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
885*4882a593Smuzhiyun     ClientPtr client = cl->client;
886*4882a593Smuzhiyun     xGLXGetVisualConfigsReply reply;
887*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
888*4882a593Smuzhiyun     __GLXconfig *modes;
889*4882a593Smuzhiyun     CARD32 buf[GLX_VIS_CONFIG_TOTAL];
890*4882a593Smuzhiyun     int p, i, err;
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun     __GLX_DECLARE_SWAP_VARIABLES;
893*4882a593Smuzhiyun     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
896*4882a593Smuzhiyun         return err;
897*4882a593Smuzhiyun 
898*4882a593Smuzhiyun     reply = (xGLXGetVisualConfigsReply) {
899*4882a593Smuzhiyun         .type = X_Reply,
900*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
901*4882a593Smuzhiyun         .length = (pGlxScreen->numVisuals *
902*4882a593Smuzhiyun                    __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2,
903*4882a593Smuzhiyun         .numVisuals = pGlxScreen->numVisuals,
904*4882a593Smuzhiyun         .numProps = GLX_VIS_CONFIG_TOTAL
905*4882a593Smuzhiyun     };
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun     if (client->swapped) {
908*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
909*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
910*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.numVisuals);
911*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.numProps);
912*4882a593Smuzhiyun     }
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun     WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun     for (i = 0; i < pGlxScreen->numVisuals; i++) {
917*4882a593Smuzhiyun         modes = pGlxScreen->visuals[i];
918*4882a593Smuzhiyun 
919*4882a593Smuzhiyun         p = 0;
920*4882a593Smuzhiyun         buf[p++] = modes->visualID;
921*4882a593Smuzhiyun         buf[p++] = glxConvertToXVisualType(modes->visualType);
922*4882a593Smuzhiyun         buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE;
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun         buf[p++] = modes->redBits;
925*4882a593Smuzhiyun         buf[p++] = modes->greenBits;
926*4882a593Smuzhiyun         buf[p++] = modes->blueBits;
927*4882a593Smuzhiyun         buf[p++] = modes->alphaBits;
928*4882a593Smuzhiyun         buf[p++] = modes->accumRedBits;
929*4882a593Smuzhiyun         buf[p++] = modes->accumGreenBits;
930*4882a593Smuzhiyun         buf[p++] = modes->accumBlueBits;
931*4882a593Smuzhiyun         buf[p++] = modes->accumAlphaBits;
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun         buf[p++] = modes->doubleBufferMode;
934*4882a593Smuzhiyun         buf[p++] = modes->stereoMode;
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun         buf[p++] = modes->rgbBits;
937*4882a593Smuzhiyun         buf[p++] = modes->depthBits;
938*4882a593Smuzhiyun         buf[p++] = modes->stencilBits;
939*4882a593Smuzhiyun         buf[p++] = modes->numAuxBuffers;
940*4882a593Smuzhiyun         buf[p++] = modes->level;
941*4882a593Smuzhiyun 
942*4882a593Smuzhiyun         assert(p == GLX_VIS_CONFIG_UNPAIRED);
943*4882a593Smuzhiyun         /*
944*4882a593Smuzhiyun          ** Add token/value pairs for extensions.
945*4882a593Smuzhiyun          */
946*4882a593Smuzhiyun         buf[p++] = GLX_VISUAL_CAVEAT_EXT;
947*4882a593Smuzhiyun         buf[p++] = modes->visualRating;
948*4882a593Smuzhiyun         buf[p++] = GLX_TRANSPARENT_TYPE;
949*4882a593Smuzhiyun         buf[p++] = modes->transparentPixel;
950*4882a593Smuzhiyun         buf[p++] = GLX_TRANSPARENT_RED_VALUE;
951*4882a593Smuzhiyun         buf[p++] = modes->transparentRed;
952*4882a593Smuzhiyun         buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
953*4882a593Smuzhiyun         buf[p++] = modes->transparentGreen;
954*4882a593Smuzhiyun         buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
955*4882a593Smuzhiyun         buf[p++] = modes->transparentBlue;
956*4882a593Smuzhiyun         buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
957*4882a593Smuzhiyun         buf[p++] = modes->transparentAlpha;
958*4882a593Smuzhiyun         buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
959*4882a593Smuzhiyun         buf[p++] = modes->transparentIndex;
960*4882a593Smuzhiyun         buf[p++] = GLX_SAMPLES_SGIS;
961*4882a593Smuzhiyun         buf[p++] = modes->samples;
962*4882a593Smuzhiyun         buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
963*4882a593Smuzhiyun         buf[p++] = modes->sampleBuffers;
964*4882a593Smuzhiyun         buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
965*4882a593Smuzhiyun         buf[p++] = modes->visualSelectGroup;
966*4882a593Smuzhiyun         /* Add attribute only if its value is not default. */
967*4882a593Smuzhiyun         if (modes->sRGBCapable != GL_FALSE) {
968*4882a593Smuzhiyun             buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT;
969*4882a593Smuzhiyun             buf[p++] = modes->sRGBCapable;
970*4882a593Smuzhiyun         }
971*4882a593Smuzhiyun         /* Pad with zeroes, so that attributes count is constant. */
972*4882a593Smuzhiyun         while (p < GLX_VIS_CONFIG_TOTAL) {
973*4882a593Smuzhiyun             buf[p++] = 0;
974*4882a593Smuzhiyun             buf[p++] = 0;
975*4882a593Smuzhiyun         }
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun         assert(p == GLX_VIS_CONFIG_TOTAL);
978*4882a593Smuzhiyun         if (client->swapped) {
979*4882a593Smuzhiyun             __GLX_SWAP_INT_ARRAY(buf, p);
980*4882a593Smuzhiyun         }
981*4882a593Smuzhiyun         WriteToClient(client, __GLX_SIZE_CARD32 * p, buf);
982*4882a593Smuzhiyun     }
983*4882a593Smuzhiyun     return Success;
984*4882a593Smuzhiyun }
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun #define __GLX_TOTAL_FBCONFIG_ATTRIBS (44)
987*4882a593Smuzhiyun #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
988*4882a593Smuzhiyun /**
989*4882a593Smuzhiyun  * Send the set of GLXFBConfigs to the client.  There is not currently
990*4882a593Smuzhiyun  * and interface into the driver on the server-side to get GLXFBConfigs,
991*4882a593Smuzhiyun  * so we "invent" some based on the \c __GLXvisualConfig structures that
992*4882a593Smuzhiyun  * the driver does supply.
993*4882a593Smuzhiyun  *
994*4882a593Smuzhiyun  * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
995*4882a593Smuzhiyun  * is the same, so this routine pulls double duty.
996*4882a593Smuzhiyun  */
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun static int
DoGetFBConfigs(__GLXclientState * cl,unsigned screen)999*4882a593Smuzhiyun DoGetFBConfigs(__GLXclientState * cl, unsigned screen)
1000*4882a593Smuzhiyun {
1001*4882a593Smuzhiyun     ClientPtr client = cl->client;
1002*4882a593Smuzhiyun     xGLXGetFBConfigsReply reply;
1003*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
1004*4882a593Smuzhiyun     CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
1005*4882a593Smuzhiyun     int p, err;
1006*4882a593Smuzhiyun     __GLXconfig *modes;
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun     __GLX_DECLARE_SWAP_VARIABLES;
1009*4882a593Smuzhiyun     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
1012*4882a593Smuzhiyun         return err;
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun     reply = (xGLXGetFBConfigsReply) {
1015*4882a593Smuzhiyun         .type = X_Reply,
1016*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
1017*4882a593Smuzhiyun         .length = __GLX_FBCONFIG_ATTRIBS_LENGTH * pGlxScreen->numFBConfigs,
1018*4882a593Smuzhiyun         .numFBConfigs = pGlxScreen->numFBConfigs,
1019*4882a593Smuzhiyun         .numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS
1020*4882a593Smuzhiyun     };
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun     if (client->swapped) {
1023*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
1024*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
1025*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.numFBConfigs);
1026*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.numAttribs);
1027*4882a593Smuzhiyun     }
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun     WriteToClient(client, sz_xGLXGetFBConfigsReply, &reply);
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun     for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
1032*4882a593Smuzhiyun         p = 0;
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun #define WRITE_PAIR(tag,value) \
1035*4882a593Smuzhiyun     do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun         WRITE_PAIR(GLX_VISUAL_ID, modes->visualID);
1038*4882a593Smuzhiyun         WRITE_PAIR(GLX_FBCONFIG_ID, modes->fbconfigID);
1039*4882a593Smuzhiyun         WRITE_PAIR(GLX_X_RENDERABLE,
1040*4882a593Smuzhiyun                    (modes->drawableType & (GLX_WINDOW_BIT | GLX_PIXMAP_BIT)
1041*4882a593Smuzhiyun                     ? GL_TRUE
1042*4882a593Smuzhiyun                     : GL_FALSE));
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun         WRITE_PAIR(GLX_RGBA,
1045*4882a593Smuzhiyun                    (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE);
1046*4882a593Smuzhiyun         WRITE_PAIR(GLX_RENDER_TYPE, modes->renderType);
1047*4882a593Smuzhiyun         WRITE_PAIR(GLX_DOUBLEBUFFER, modes->doubleBufferMode);
1048*4882a593Smuzhiyun         WRITE_PAIR(GLX_STEREO, modes->stereoMode);
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun         WRITE_PAIR(GLX_BUFFER_SIZE, modes->rgbBits);
1051*4882a593Smuzhiyun         WRITE_PAIR(GLX_LEVEL, modes->level);
1052*4882a593Smuzhiyun         WRITE_PAIR(GLX_AUX_BUFFERS, modes->numAuxBuffers);
1053*4882a593Smuzhiyun         WRITE_PAIR(GLX_RED_SIZE, modes->redBits);
1054*4882a593Smuzhiyun         WRITE_PAIR(GLX_GREEN_SIZE, modes->greenBits);
1055*4882a593Smuzhiyun         WRITE_PAIR(GLX_BLUE_SIZE, modes->blueBits);
1056*4882a593Smuzhiyun         WRITE_PAIR(GLX_ALPHA_SIZE, modes->alphaBits);
1057*4882a593Smuzhiyun         WRITE_PAIR(GLX_ACCUM_RED_SIZE, modes->accumRedBits);
1058*4882a593Smuzhiyun         WRITE_PAIR(GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits);
1059*4882a593Smuzhiyun         WRITE_PAIR(GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits);
1060*4882a593Smuzhiyun         WRITE_PAIR(GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits);
1061*4882a593Smuzhiyun         WRITE_PAIR(GLX_DEPTH_SIZE, modes->depthBits);
1062*4882a593Smuzhiyun         WRITE_PAIR(GLX_STENCIL_SIZE, modes->stencilBits);
1063*4882a593Smuzhiyun         WRITE_PAIR(GLX_X_VISUAL_TYPE, modes->visualType);
1064*4882a593Smuzhiyun         WRITE_PAIR(GLX_CONFIG_CAVEAT, modes->visualRating);
1065*4882a593Smuzhiyun         WRITE_PAIR(GLX_TRANSPARENT_TYPE, modes->transparentPixel);
1066*4882a593Smuzhiyun         WRITE_PAIR(GLX_TRANSPARENT_RED_VALUE, modes->transparentRed);
1067*4882a593Smuzhiyun         WRITE_PAIR(GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen);
1068*4882a593Smuzhiyun         WRITE_PAIR(GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue);
1069*4882a593Smuzhiyun         WRITE_PAIR(GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha);
1070*4882a593Smuzhiyun         WRITE_PAIR(GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex);
1071*4882a593Smuzhiyun         WRITE_PAIR(GLX_SWAP_METHOD_OML, modes->swapMethod);
1072*4882a593Smuzhiyun         WRITE_PAIR(GLX_SAMPLES_SGIS, modes->samples);
1073*4882a593Smuzhiyun         WRITE_PAIR(GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers);
1074*4882a593Smuzhiyun         WRITE_PAIR(GLX_VISUAL_SELECT_GROUP_SGIX, modes->visualSelectGroup);
1075*4882a593Smuzhiyun         WRITE_PAIR(GLX_DRAWABLE_TYPE, modes->drawableType);
1076*4882a593Smuzhiyun         WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb);
1077*4882a593Smuzhiyun         WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba);
1078*4882a593Smuzhiyun         WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture);
1079*4882a593Smuzhiyun         WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1080*4882a593Smuzhiyun                    modes->bindToTextureTargets);
1081*4882a593Smuzhiyun 	/* can't report honestly until mesa is fixed */
1082*4882a593Smuzhiyun 	WRITE_PAIR(GLX_Y_INVERTED_EXT, GLX_DONT_CARE);
1083*4882a593Smuzhiyun 	if (modes->drawableType & GLX_PBUFFER_BIT) {
1084*4882a593Smuzhiyun 	    WRITE_PAIR(GLX_MAX_PBUFFER_WIDTH, modes->maxPbufferWidth);
1085*4882a593Smuzhiyun 	    WRITE_PAIR(GLX_MAX_PBUFFER_HEIGHT, modes->maxPbufferHeight);
1086*4882a593Smuzhiyun 	    WRITE_PAIR(GLX_MAX_PBUFFER_PIXELS, modes->maxPbufferPixels);
1087*4882a593Smuzhiyun 	    WRITE_PAIR(GLX_OPTIMAL_PBUFFER_WIDTH_SGIX,
1088*4882a593Smuzhiyun 		       modes->optimalPbufferWidth);
1089*4882a593Smuzhiyun 	    WRITE_PAIR(GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX,
1090*4882a593Smuzhiyun 		       modes->optimalPbufferHeight);
1091*4882a593Smuzhiyun 	}
1092*4882a593Smuzhiyun         /* Add attribute only if its value is not default. */
1093*4882a593Smuzhiyun         if (modes->sRGBCapable != GL_FALSE) {
1094*4882a593Smuzhiyun             WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable);
1095*4882a593Smuzhiyun         }
1096*4882a593Smuzhiyun         /* Pad the remaining place with zeroes, so that attributes count is constant. */
1097*4882a593Smuzhiyun         while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH) {
1098*4882a593Smuzhiyun             WRITE_PAIR(0, 0);
1099*4882a593Smuzhiyun         }
1100*4882a593Smuzhiyun         assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH);
1101*4882a593Smuzhiyun 
1102*4882a593Smuzhiyun         if (client->swapped) {
1103*4882a593Smuzhiyun             __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
1104*4882a593Smuzhiyun         }
1105*4882a593Smuzhiyun         WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
1106*4882a593Smuzhiyun                       (char *) buf);
1107*4882a593Smuzhiyun     }
1108*4882a593Smuzhiyun     return Success;
1109*4882a593Smuzhiyun }
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun int
__glXDisp_GetFBConfigs(__GLXclientState * cl,GLbyte * pc)1112*4882a593Smuzhiyun __glXDisp_GetFBConfigs(__GLXclientState * cl, GLbyte * pc)
1113*4882a593Smuzhiyun {
1114*4882a593Smuzhiyun     xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
1115*4882a593Smuzhiyun 
1116*4882a593Smuzhiyun     return DoGetFBConfigs(cl, req->screen);
1117*4882a593Smuzhiyun }
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun int
__glXDisp_GetFBConfigsSGIX(__GLXclientState * cl,GLbyte * pc)1120*4882a593Smuzhiyun __glXDisp_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
1121*4882a593Smuzhiyun {
1122*4882a593Smuzhiyun     ClientPtr client = cl->client;
1123*4882a593Smuzhiyun     xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun     /* work around mesa bug, don't use REQUEST_SIZE_MATCH */
1126*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq);
1127*4882a593Smuzhiyun     return DoGetFBConfigs(cl, req->screen);
1128*4882a593Smuzhiyun }
1129*4882a593Smuzhiyun 
1130*4882a593Smuzhiyun GLboolean
__glXDrawableInit(__GLXdrawable * drawable,__GLXscreen * screen,DrawablePtr pDraw,int type,XID drawId,__GLXconfig * config)1131*4882a593Smuzhiyun __glXDrawableInit(__GLXdrawable * drawable,
1132*4882a593Smuzhiyun                   __GLXscreen * screen, DrawablePtr pDraw, int type,
1133*4882a593Smuzhiyun                   XID drawId, __GLXconfig * config)
1134*4882a593Smuzhiyun {
1135*4882a593Smuzhiyun     drawable->pDraw = pDraw;
1136*4882a593Smuzhiyun     drawable->type = type;
1137*4882a593Smuzhiyun     drawable->drawId = drawId;
1138*4882a593Smuzhiyun     drawable->config = config;
1139*4882a593Smuzhiyun     drawable->eventMask = 0;
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun     return GL_TRUE;
1142*4882a593Smuzhiyun }
1143*4882a593Smuzhiyun 
1144*4882a593Smuzhiyun void
__glXDrawableRelease(__GLXdrawable * drawable)1145*4882a593Smuzhiyun __glXDrawableRelease(__GLXdrawable * drawable)
1146*4882a593Smuzhiyun {
1147*4882a593Smuzhiyun }
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun static int
DoCreateGLXDrawable(ClientPtr client,__GLXscreen * pGlxScreen,__GLXconfig * config,DrawablePtr pDraw,XID drawableId,XID glxDrawableId,int type)1150*4882a593Smuzhiyun DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen,
1151*4882a593Smuzhiyun                     __GLXconfig * config, DrawablePtr pDraw, XID drawableId,
1152*4882a593Smuzhiyun                     XID glxDrawableId, int type)
1153*4882a593Smuzhiyun {
1154*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun     if (pGlxScreen->pScreen != pDraw->pScreen)
1157*4882a593Smuzhiyun         return BadMatch;
1158*4882a593Smuzhiyun 
1159*4882a593Smuzhiyun     pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
1160*4882a593Smuzhiyun                                           drawableId, type,
1161*4882a593Smuzhiyun                                           glxDrawableId, config);
1162*4882a593Smuzhiyun     if (pGlxDraw == NULL)
1163*4882a593Smuzhiyun         return BadAlloc;
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun     if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw))
1166*4882a593Smuzhiyun         return BadAlloc;
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun     /*
1169*4882a593Smuzhiyun      * Windows aren't refcounted, so track both the X and the GLX window
1170*4882a593Smuzhiyun      * so we get called regardless of destruction order.
1171*4882a593Smuzhiyun      */
1172*4882a593Smuzhiyun     if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW &&
1173*4882a593Smuzhiyun         !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw))
1174*4882a593Smuzhiyun         return BadAlloc;
1175*4882a593Smuzhiyun 
1176*4882a593Smuzhiyun     return Success;
1177*4882a593Smuzhiyun }
1178*4882a593Smuzhiyun 
1179*4882a593Smuzhiyun static int
DoCreateGLXPixmap(ClientPtr client,__GLXscreen * pGlxScreen,__GLXconfig * config,XID drawableId,XID glxDrawableId)1180*4882a593Smuzhiyun DoCreateGLXPixmap(ClientPtr client, __GLXscreen * pGlxScreen,
1181*4882a593Smuzhiyun                   __GLXconfig * config, XID drawableId, XID glxDrawableId)
1182*4882a593Smuzhiyun {
1183*4882a593Smuzhiyun     DrawablePtr pDraw;
1184*4882a593Smuzhiyun     int err;
1185*4882a593Smuzhiyun 
1186*4882a593Smuzhiyun     err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
1187*4882a593Smuzhiyun     if (err != Success) {
1188*4882a593Smuzhiyun         client->errorValue = drawableId;
1189*4882a593Smuzhiyun         return err;
1190*4882a593Smuzhiyun     }
1191*4882a593Smuzhiyun     if (pDraw->type != DRAWABLE_PIXMAP) {
1192*4882a593Smuzhiyun         client->errorValue = drawableId;
1193*4882a593Smuzhiyun         return BadPixmap;
1194*4882a593Smuzhiyun     }
1195*4882a593Smuzhiyun 
1196*4882a593Smuzhiyun     err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
1197*4882a593Smuzhiyun                               glxDrawableId, GLX_DRAWABLE_PIXMAP);
1198*4882a593Smuzhiyun 
1199*4882a593Smuzhiyun     if (err == Success)
1200*4882a593Smuzhiyun         ((PixmapPtr) pDraw)->refcnt++;
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun     return err;
1203*4882a593Smuzhiyun }
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun static void
determineTextureTarget(ClientPtr client,XID glxDrawableID,CARD32 * attribs,CARD32 numAttribs)1206*4882a593Smuzhiyun determineTextureTarget(ClientPtr client, XID glxDrawableID,
1207*4882a593Smuzhiyun                        CARD32 *attribs, CARD32 numAttribs)
1208*4882a593Smuzhiyun {
1209*4882a593Smuzhiyun     GLenum target = 0;
1210*4882a593Smuzhiyun     GLenum format = 0;
1211*4882a593Smuzhiyun     int i, err;
1212*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1213*4882a593Smuzhiyun 
1214*4882a593Smuzhiyun     if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
1215*4882a593Smuzhiyun                           DixWriteAccess, &pGlxDraw, &err))
1216*4882a593Smuzhiyun         /* We just added it in CreatePixmap, so we should never get here. */
1217*4882a593Smuzhiyun         return;
1218*4882a593Smuzhiyun 
1219*4882a593Smuzhiyun     for (i = 0; i < numAttribs; i++) {
1220*4882a593Smuzhiyun         if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
1221*4882a593Smuzhiyun             switch (attribs[2 * i + 1]) {
1222*4882a593Smuzhiyun             case GLX_TEXTURE_2D_EXT:
1223*4882a593Smuzhiyun                 target = GL_TEXTURE_2D;
1224*4882a593Smuzhiyun                 break;
1225*4882a593Smuzhiyun             case GLX_TEXTURE_RECTANGLE_EXT:
1226*4882a593Smuzhiyun                 target = GL_TEXTURE_RECTANGLE_ARB;
1227*4882a593Smuzhiyun                 break;
1228*4882a593Smuzhiyun             }
1229*4882a593Smuzhiyun         }
1230*4882a593Smuzhiyun 
1231*4882a593Smuzhiyun         if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
1232*4882a593Smuzhiyun             format = attribs[2 * i + 1];
1233*4882a593Smuzhiyun     }
1234*4882a593Smuzhiyun 
1235*4882a593Smuzhiyun     if (!target) {
1236*4882a593Smuzhiyun         int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun         if (h & (h - 1) || w & (w - 1))
1239*4882a593Smuzhiyun             target = GL_TEXTURE_RECTANGLE_ARB;
1240*4882a593Smuzhiyun         else
1241*4882a593Smuzhiyun             target = GL_TEXTURE_2D;
1242*4882a593Smuzhiyun     }
1243*4882a593Smuzhiyun 
1244*4882a593Smuzhiyun     pGlxDraw->target = target;
1245*4882a593Smuzhiyun     pGlxDraw->format = format;
1246*4882a593Smuzhiyun }
1247*4882a593Smuzhiyun 
1248*4882a593Smuzhiyun int
__glXDisp_CreateGLXPixmap(__GLXclientState * cl,GLbyte * pc)1249*4882a593Smuzhiyun __glXDisp_CreateGLXPixmap(__GLXclientState * cl, GLbyte * pc)
1250*4882a593Smuzhiyun {
1251*4882a593Smuzhiyun     xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
1252*4882a593Smuzhiyun     __GLXconfig *config;
1253*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
1254*4882a593Smuzhiyun     int err;
1255*4882a593Smuzhiyun 
1256*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1257*4882a593Smuzhiyun         return err;
1258*4882a593Smuzhiyun     if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
1259*4882a593Smuzhiyun         return err;
1260*4882a593Smuzhiyun 
1261*4882a593Smuzhiyun     return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
1262*4882a593Smuzhiyun                              req->pixmap, req->glxpixmap);
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun int
__glXDisp_CreatePixmap(__GLXclientState * cl,GLbyte * pc)1266*4882a593Smuzhiyun __glXDisp_CreatePixmap(__GLXclientState * cl, GLbyte * pc)
1267*4882a593Smuzhiyun {
1268*4882a593Smuzhiyun     ClientPtr client = cl->client;
1269*4882a593Smuzhiyun     xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
1270*4882a593Smuzhiyun     __GLXconfig *config;
1271*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
1272*4882a593Smuzhiyun     int err;
1273*4882a593Smuzhiyun 
1274*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq);
1275*4882a593Smuzhiyun     if (req->numAttribs > (UINT32_MAX >> 3)) {
1276*4882a593Smuzhiyun         client->errorValue = req->numAttribs;
1277*4882a593Smuzhiyun         return BadValue;
1278*4882a593Smuzhiyun     }
1279*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3);
1280*4882a593Smuzhiyun 
1281*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1282*4882a593Smuzhiyun         return err;
1283*4882a593Smuzhiyun     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
1284*4882a593Smuzhiyun         return err;
1285*4882a593Smuzhiyun 
1286*4882a593Smuzhiyun     err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
1287*4882a593Smuzhiyun                             req->pixmap, req->glxpixmap);
1288*4882a593Smuzhiyun     if (err != Success)
1289*4882a593Smuzhiyun         return err;
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun     determineTextureTarget(cl->client, req->glxpixmap,
1292*4882a593Smuzhiyun                            (CARD32 *) (req + 1), req->numAttribs);
1293*4882a593Smuzhiyun 
1294*4882a593Smuzhiyun     return Success;
1295*4882a593Smuzhiyun }
1296*4882a593Smuzhiyun 
1297*4882a593Smuzhiyun int
__glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl,GLbyte * pc)1298*4882a593Smuzhiyun __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
1299*4882a593Smuzhiyun {
1300*4882a593Smuzhiyun     ClientPtr client = cl->client;
1301*4882a593Smuzhiyun     xGLXCreateGLXPixmapWithConfigSGIXReq *req =
1302*4882a593Smuzhiyun         (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
1303*4882a593Smuzhiyun     __GLXconfig *config;
1304*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
1305*4882a593Smuzhiyun     int err;
1306*4882a593Smuzhiyun 
1307*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq);
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun     if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1310*4882a593Smuzhiyun         return err;
1311*4882a593Smuzhiyun     if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
1312*4882a593Smuzhiyun         return err;
1313*4882a593Smuzhiyun 
1314*4882a593Smuzhiyun     return DoCreateGLXPixmap(cl->client, pGlxScreen,
1315*4882a593Smuzhiyun                              config, req->pixmap, req->glxpixmap);
1316*4882a593Smuzhiyun }
1317*4882a593Smuzhiyun 
1318*4882a593Smuzhiyun static int
DoDestroyDrawable(__GLXclientState * cl,XID glxdrawable,int type)1319*4882a593Smuzhiyun DoDestroyDrawable(__GLXclientState * cl, XID glxdrawable, int type)
1320*4882a593Smuzhiyun {
1321*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1322*4882a593Smuzhiyun     int err;
1323*4882a593Smuzhiyun 
1324*4882a593Smuzhiyun     if (!validGlxDrawable(cl->client, glxdrawable, type,
1325*4882a593Smuzhiyun                           DixDestroyAccess, &pGlxDraw, &err))
1326*4882a593Smuzhiyun         return err;
1327*4882a593Smuzhiyun 
1328*4882a593Smuzhiyun     FreeResource(glxdrawable, FALSE);
1329*4882a593Smuzhiyun 
1330*4882a593Smuzhiyun     return Success;
1331*4882a593Smuzhiyun }
1332*4882a593Smuzhiyun 
1333*4882a593Smuzhiyun int
__glXDisp_DestroyGLXPixmap(__GLXclientState * cl,GLbyte * pc)1334*4882a593Smuzhiyun __glXDisp_DestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc)
1335*4882a593Smuzhiyun {
1336*4882a593Smuzhiyun     xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
1337*4882a593Smuzhiyun 
1338*4882a593Smuzhiyun     return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
1339*4882a593Smuzhiyun }
1340*4882a593Smuzhiyun 
1341*4882a593Smuzhiyun int
__glXDisp_DestroyPixmap(__GLXclientState * cl,GLbyte * pc)1342*4882a593Smuzhiyun __glXDisp_DestroyPixmap(__GLXclientState * cl, GLbyte * pc)
1343*4882a593Smuzhiyun {
1344*4882a593Smuzhiyun     ClientPtr client = cl->client;
1345*4882a593Smuzhiyun     xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
1346*4882a593Smuzhiyun 
1347*4882a593Smuzhiyun     /* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set
1348*4882a593Smuzhiyun      * length to 3 instead of 2 */
1349*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq);
1350*4882a593Smuzhiyun 
1351*4882a593Smuzhiyun     return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun 
1354*4882a593Smuzhiyun static int
DoCreatePbuffer(ClientPtr client,int screenNum,XID fbconfigId,int width,int height,XID glxDrawableId)1355*4882a593Smuzhiyun DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
1356*4882a593Smuzhiyun                 int width, int height, XID glxDrawableId)
1357*4882a593Smuzhiyun {
1358*4882a593Smuzhiyun     __GLXconfig *config;
1359*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
1360*4882a593Smuzhiyun     PixmapPtr pPixmap;
1361*4882a593Smuzhiyun     int err;
1362*4882a593Smuzhiyun 
1363*4882a593Smuzhiyun     if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
1364*4882a593Smuzhiyun         return err;
1365*4882a593Smuzhiyun     if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
1366*4882a593Smuzhiyun         return err;
1367*4882a593Smuzhiyun 
1368*4882a593Smuzhiyun     pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
1369*4882a593Smuzhiyun                                                     width, height,
1370*4882a593Smuzhiyun                                                     config->rgbBits, 0);
1371*4882a593Smuzhiyun     if (!pPixmap)
1372*4882a593Smuzhiyun         return BadAlloc;
1373*4882a593Smuzhiyun 
1374*4882a593Smuzhiyun     /* Assign the pixmap the same id as the pbuffer and add it as a
1375*4882a593Smuzhiyun      * resource so it and the DRI2 drawable will be reclaimed when the
1376*4882a593Smuzhiyun      * pbuffer is destroyed. */
1377*4882a593Smuzhiyun     pPixmap->drawable.id = glxDrawableId;
1378*4882a593Smuzhiyun     if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
1379*4882a593Smuzhiyun         return BadAlloc;
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun     return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
1382*4882a593Smuzhiyun                                glxDrawableId, glxDrawableId,
1383*4882a593Smuzhiyun                                GLX_DRAWABLE_PBUFFER);
1384*4882a593Smuzhiyun }
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun int
__glXDisp_CreatePbuffer(__GLXclientState * cl,GLbyte * pc)1387*4882a593Smuzhiyun __glXDisp_CreatePbuffer(__GLXclientState * cl, GLbyte * pc)
1388*4882a593Smuzhiyun {
1389*4882a593Smuzhiyun     ClientPtr client = cl->client;
1390*4882a593Smuzhiyun     xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
1391*4882a593Smuzhiyun     CARD32 *attrs;
1392*4882a593Smuzhiyun     int width, height, i;
1393*4882a593Smuzhiyun 
1394*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq);
1395*4882a593Smuzhiyun     if (req->numAttribs > (UINT32_MAX >> 3)) {
1396*4882a593Smuzhiyun         client->errorValue = req->numAttribs;
1397*4882a593Smuzhiyun         return BadValue;
1398*4882a593Smuzhiyun     }
1399*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3);
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun     attrs = (CARD32 *) (req + 1);
1402*4882a593Smuzhiyun     width = 0;
1403*4882a593Smuzhiyun     height = 0;
1404*4882a593Smuzhiyun 
1405*4882a593Smuzhiyun     for (i = 0; i < req->numAttribs; i++) {
1406*4882a593Smuzhiyun         switch (attrs[i * 2]) {
1407*4882a593Smuzhiyun         case GLX_PBUFFER_WIDTH:
1408*4882a593Smuzhiyun             width = attrs[i * 2 + 1];
1409*4882a593Smuzhiyun             break;
1410*4882a593Smuzhiyun         case GLX_PBUFFER_HEIGHT:
1411*4882a593Smuzhiyun             height = attrs[i * 2 + 1];
1412*4882a593Smuzhiyun             break;
1413*4882a593Smuzhiyun         case GLX_LARGEST_PBUFFER:
1414*4882a593Smuzhiyun             /* FIXME: huh... */
1415*4882a593Smuzhiyun             break;
1416*4882a593Smuzhiyun         }
1417*4882a593Smuzhiyun     }
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun     return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
1420*4882a593Smuzhiyun                            width, height, req->pbuffer);
1421*4882a593Smuzhiyun }
1422*4882a593Smuzhiyun 
1423*4882a593Smuzhiyun int
__glXDisp_CreateGLXPbufferSGIX(__GLXclientState * cl,GLbyte * pc)1424*4882a593Smuzhiyun __glXDisp_CreateGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
1425*4882a593Smuzhiyun {
1426*4882a593Smuzhiyun     ClientPtr client = cl->client;
1427*4882a593Smuzhiyun     xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
1428*4882a593Smuzhiyun 
1429*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq);
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun     /*
1432*4882a593Smuzhiyun      * We should really handle attributes correctly, but this extension
1433*4882a593Smuzhiyun      * is so rare I have difficulty caring.
1434*4882a593Smuzhiyun      */
1435*4882a593Smuzhiyun     return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
1436*4882a593Smuzhiyun                            req->width, req->height, req->pbuffer);
1437*4882a593Smuzhiyun }
1438*4882a593Smuzhiyun 
1439*4882a593Smuzhiyun int
__glXDisp_DestroyPbuffer(__GLXclientState * cl,GLbyte * pc)1440*4882a593Smuzhiyun __glXDisp_DestroyPbuffer(__GLXclientState * cl, GLbyte * pc)
1441*4882a593Smuzhiyun {
1442*4882a593Smuzhiyun     ClientPtr client = cl->client;
1443*4882a593Smuzhiyun     xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
1444*4882a593Smuzhiyun 
1445*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq);
1446*4882a593Smuzhiyun 
1447*4882a593Smuzhiyun     return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
1448*4882a593Smuzhiyun }
1449*4882a593Smuzhiyun 
1450*4882a593Smuzhiyun int
__glXDisp_DestroyGLXPbufferSGIX(__GLXclientState * cl,GLbyte * pc)1451*4882a593Smuzhiyun __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
1452*4882a593Smuzhiyun {
1453*4882a593Smuzhiyun     ClientPtr client = cl->client;
1454*4882a593Smuzhiyun     xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
1455*4882a593Smuzhiyun 
1456*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq);
1457*4882a593Smuzhiyun 
1458*4882a593Smuzhiyun     return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
1459*4882a593Smuzhiyun }
1460*4882a593Smuzhiyun 
1461*4882a593Smuzhiyun static int
DoChangeDrawableAttributes(ClientPtr client,XID glxdrawable,int numAttribs,CARD32 * attribs)1462*4882a593Smuzhiyun DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
1463*4882a593Smuzhiyun                            int numAttribs, CARD32 *attribs)
1464*4882a593Smuzhiyun {
1465*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1466*4882a593Smuzhiyun     int i, err;
1467*4882a593Smuzhiyun 
1468*4882a593Smuzhiyun     if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
1469*4882a593Smuzhiyun                           DixSetAttrAccess, &pGlxDraw, &err))
1470*4882a593Smuzhiyun         return err;
1471*4882a593Smuzhiyun 
1472*4882a593Smuzhiyun     for (i = 0; i < numAttribs; i++) {
1473*4882a593Smuzhiyun         switch (attribs[i * 2]) {
1474*4882a593Smuzhiyun         case GLX_EVENT_MASK:
1475*4882a593Smuzhiyun             /* All we do is to record the event mask so we can send it
1476*4882a593Smuzhiyun              * back when queried.  We never actually clobber the
1477*4882a593Smuzhiyun              * pbuffers, so we never need to send out the event. */
1478*4882a593Smuzhiyun             pGlxDraw->eventMask = attribs[i * 2 + 1];
1479*4882a593Smuzhiyun             break;
1480*4882a593Smuzhiyun         }
1481*4882a593Smuzhiyun     }
1482*4882a593Smuzhiyun 
1483*4882a593Smuzhiyun     return Success;
1484*4882a593Smuzhiyun }
1485*4882a593Smuzhiyun 
1486*4882a593Smuzhiyun int
__glXDisp_ChangeDrawableAttributes(__GLXclientState * cl,GLbyte * pc)1487*4882a593Smuzhiyun __glXDisp_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
1488*4882a593Smuzhiyun {
1489*4882a593Smuzhiyun     ClientPtr client = cl->client;
1490*4882a593Smuzhiyun     xGLXChangeDrawableAttributesReq *req =
1491*4882a593Smuzhiyun         (xGLXChangeDrawableAttributesReq *) pc;
1492*4882a593Smuzhiyun 
1493*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq);
1494*4882a593Smuzhiyun     if (req->numAttribs > (UINT32_MAX >> 3)) {
1495*4882a593Smuzhiyun         client->errorValue = req->numAttribs;
1496*4882a593Smuzhiyun         return BadValue;
1497*4882a593Smuzhiyun     }
1498*4882a593Smuzhiyun #if 0
1499*4882a593Smuzhiyun     /* mesa sends an additional 8 bytes */
1500*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3);
1501*4882a593Smuzhiyun #else
1502*4882a593Smuzhiyun     if (((sizeof(xGLXChangeDrawableAttributesReq) +
1503*4882a593Smuzhiyun           (req->numAttribs << 3)) >> 2) < client->req_len)
1504*4882a593Smuzhiyun         return BadLength;
1505*4882a593Smuzhiyun #endif
1506*4882a593Smuzhiyun 
1507*4882a593Smuzhiyun     return DoChangeDrawableAttributes(cl->client, req->drawable,
1508*4882a593Smuzhiyun                                       req->numAttribs, (CARD32 *) (req + 1));
1509*4882a593Smuzhiyun }
1510*4882a593Smuzhiyun 
1511*4882a593Smuzhiyun int
__glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState * cl,GLbyte * pc)1512*4882a593Smuzhiyun __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
1513*4882a593Smuzhiyun {
1514*4882a593Smuzhiyun     ClientPtr client = cl->client;
1515*4882a593Smuzhiyun     xGLXChangeDrawableAttributesSGIXReq *req =
1516*4882a593Smuzhiyun         (xGLXChangeDrawableAttributesSGIXReq *) pc;
1517*4882a593Smuzhiyun 
1518*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq);
1519*4882a593Smuzhiyun     if (req->numAttribs > (UINT32_MAX >> 3)) {
1520*4882a593Smuzhiyun         client->errorValue = req->numAttribs;
1521*4882a593Smuzhiyun         return BadValue;
1522*4882a593Smuzhiyun     }
1523*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq,
1524*4882a593Smuzhiyun                        req->numAttribs << 3);
1525*4882a593Smuzhiyun 
1526*4882a593Smuzhiyun     return DoChangeDrawableAttributes(cl->client, req->drawable,
1527*4882a593Smuzhiyun                                       req->numAttribs, (CARD32 *) (req + 1));
1528*4882a593Smuzhiyun }
1529*4882a593Smuzhiyun 
1530*4882a593Smuzhiyun int
__glXDisp_CreateWindow(__GLXclientState * cl,GLbyte * pc)1531*4882a593Smuzhiyun __glXDisp_CreateWindow(__GLXclientState * cl, GLbyte * pc)
1532*4882a593Smuzhiyun {
1533*4882a593Smuzhiyun     xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
1534*4882a593Smuzhiyun     __GLXconfig *config;
1535*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
1536*4882a593Smuzhiyun     ClientPtr client = cl->client;
1537*4882a593Smuzhiyun     DrawablePtr pDraw;
1538*4882a593Smuzhiyun     int err;
1539*4882a593Smuzhiyun 
1540*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq);
1541*4882a593Smuzhiyun     if (req->numAttribs > (UINT32_MAX >> 3)) {
1542*4882a593Smuzhiyun         client->errorValue = req->numAttribs;
1543*4882a593Smuzhiyun         return BadValue;
1544*4882a593Smuzhiyun     }
1545*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3);
1546*4882a593Smuzhiyun 
1547*4882a593Smuzhiyun     if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
1548*4882a593Smuzhiyun         return err;
1549*4882a593Smuzhiyun     if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
1550*4882a593Smuzhiyun         return err;
1551*4882a593Smuzhiyun 
1552*4882a593Smuzhiyun     err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess);
1553*4882a593Smuzhiyun     if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
1554*4882a593Smuzhiyun         client->errorValue = req->window;
1555*4882a593Smuzhiyun         return BadWindow;
1556*4882a593Smuzhiyun     }
1557*4882a593Smuzhiyun 
1558*4882a593Smuzhiyun     if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
1559*4882a593Smuzhiyun         return err;
1560*4882a593Smuzhiyun 
1561*4882a593Smuzhiyun     return DoCreateGLXDrawable(client, pGlxScreen, config,
1562*4882a593Smuzhiyun                                pDraw, req->window,
1563*4882a593Smuzhiyun                                req->glxwindow, GLX_DRAWABLE_WINDOW);
1564*4882a593Smuzhiyun }
1565*4882a593Smuzhiyun 
1566*4882a593Smuzhiyun int
__glXDisp_DestroyWindow(__GLXclientState * cl,GLbyte * pc)1567*4882a593Smuzhiyun __glXDisp_DestroyWindow(__GLXclientState * cl, GLbyte * pc)
1568*4882a593Smuzhiyun {
1569*4882a593Smuzhiyun     ClientPtr client = cl->client;
1570*4882a593Smuzhiyun     xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
1571*4882a593Smuzhiyun 
1572*4882a593Smuzhiyun     /* mesa's glXDestroyWindow used to set length to 3 instead of 2 */
1573*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq);
1574*4882a593Smuzhiyun 
1575*4882a593Smuzhiyun     return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
1576*4882a593Smuzhiyun }
1577*4882a593Smuzhiyun 
1578*4882a593Smuzhiyun /*****************************************************************************/
1579*4882a593Smuzhiyun 
1580*4882a593Smuzhiyun /*
1581*4882a593Smuzhiyun ** NOTE: There is no portable implementation for swap buffers as of
1582*4882a593Smuzhiyun ** this time that is of value.  Consequently, this code must be
1583*4882a593Smuzhiyun ** implemented by somebody other than SGI.
1584*4882a593Smuzhiyun */
1585*4882a593Smuzhiyun int
__glXDisp_SwapBuffers(__GLXclientState * cl,GLbyte * pc)1586*4882a593Smuzhiyun __glXDisp_SwapBuffers(__GLXclientState * cl, GLbyte * pc)
1587*4882a593Smuzhiyun {
1588*4882a593Smuzhiyun     ClientPtr client = cl->client;
1589*4882a593Smuzhiyun     xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
1590*4882a593Smuzhiyun     GLXContextTag tag;
1591*4882a593Smuzhiyun     XID drawId;
1592*4882a593Smuzhiyun     __GLXcontext *glxc = NULL;
1593*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1594*4882a593Smuzhiyun     int error;
1595*4882a593Smuzhiyun 
1596*4882a593Smuzhiyun     tag = req->contextTag;
1597*4882a593Smuzhiyun     drawId = req->drawable;
1598*4882a593Smuzhiyun     if (tag) {
1599*4882a593Smuzhiyun         glxc = __glXLookupContextByTag(cl, tag);
1600*4882a593Smuzhiyun         if (!glxc) {
1601*4882a593Smuzhiyun             return __glXError(GLXBadContextTag);
1602*4882a593Smuzhiyun         }
1603*4882a593Smuzhiyun         /*
1604*4882a593Smuzhiyun          ** The calling thread is swapping its current drawable.  In this case,
1605*4882a593Smuzhiyun          ** glxSwapBuffers is in both GL and X streams, in terms of
1606*4882a593Smuzhiyun          ** sequentiality.
1607*4882a593Smuzhiyun          */
1608*4882a593Smuzhiyun         if (__glXForceCurrent(cl, tag, &error)) {
1609*4882a593Smuzhiyun             /*
1610*4882a593Smuzhiyun              ** Do whatever is needed to make sure that all preceding requests
1611*4882a593Smuzhiyun              ** in both streams are completed before the swap is executed.
1612*4882a593Smuzhiyun              */
1613*4882a593Smuzhiyun             glFinish();
1614*4882a593Smuzhiyun         }
1615*4882a593Smuzhiyun         else {
1616*4882a593Smuzhiyun             return error;
1617*4882a593Smuzhiyun         }
1618*4882a593Smuzhiyun     }
1619*4882a593Smuzhiyun 
1620*4882a593Smuzhiyun     pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
1621*4882a593Smuzhiyun     if (pGlxDraw == NULL)
1622*4882a593Smuzhiyun         return error;
1623*4882a593Smuzhiyun 
1624*4882a593Smuzhiyun     if (pGlxDraw->type == DRAWABLE_WINDOW &&
1625*4882a593Smuzhiyun         (*pGlxDraw->swapBuffers) (cl->client, pGlxDraw) == GL_FALSE)
1626*4882a593Smuzhiyun         return __glXError(GLXBadDrawable);
1627*4882a593Smuzhiyun 
1628*4882a593Smuzhiyun     return Success;
1629*4882a593Smuzhiyun }
1630*4882a593Smuzhiyun 
1631*4882a593Smuzhiyun static int
DoQueryContext(__GLXclientState * cl,GLXContextID gcId)1632*4882a593Smuzhiyun DoQueryContext(__GLXclientState * cl, GLXContextID gcId)
1633*4882a593Smuzhiyun {
1634*4882a593Smuzhiyun     ClientPtr client = cl->client;
1635*4882a593Smuzhiyun     __GLXcontext *ctx;
1636*4882a593Smuzhiyun     xGLXQueryContextInfoEXTReply reply;
1637*4882a593Smuzhiyun     int nProps = 5;
1638*4882a593Smuzhiyun     int sendBuf[nProps * 2];
1639*4882a593Smuzhiyun     int nReplyBytes;
1640*4882a593Smuzhiyun     int err;
1641*4882a593Smuzhiyun 
1642*4882a593Smuzhiyun     if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err))
1643*4882a593Smuzhiyun         return err;
1644*4882a593Smuzhiyun 
1645*4882a593Smuzhiyun     reply = (xGLXQueryContextInfoEXTReply) {
1646*4882a593Smuzhiyun         .type = X_Reply,
1647*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
1648*4882a593Smuzhiyun         .length = nProps << 1,
1649*4882a593Smuzhiyun         .n = nProps
1650*4882a593Smuzhiyun     };
1651*4882a593Smuzhiyun 
1652*4882a593Smuzhiyun     nReplyBytes = reply.length << 2;
1653*4882a593Smuzhiyun     sendBuf[0] = GLX_SHARE_CONTEXT_EXT;
1654*4882a593Smuzhiyun     sendBuf[1] = (int) (ctx->share_id);
1655*4882a593Smuzhiyun     sendBuf[2] = GLX_VISUAL_ID_EXT;
1656*4882a593Smuzhiyun     sendBuf[3] = (int) (ctx->config ? ctx->config->visualID : 0);
1657*4882a593Smuzhiyun     sendBuf[4] = GLX_SCREEN_EXT;
1658*4882a593Smuzhiyun     sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum);
1659*4882a593Smuzhiyun     sendBuf[6] = GLX_FBCONFIG_ID;
1660*4882a593Smuzhiyun     sendBuf[7] = (int) (ctx->config ? ctx->config->fbconfigID : 0);
1661*4882a593Smuzhiyun     sendBuf[8] = GLX_RENDER_TYPE;
1662*4882a593Smuzhiyun     sendBuf[9] = (int) (ctx->config ? ctx->config->renderType : GLX_DONT_CARE);
1663*4882a593Smuzhiyun 
1664*4882a593Smuzhiyun     if (client->swapped) {
1665*4882a593Smuzhiyun         int length = reply.length;
1666*4882a593Smuzhiyun 
1667*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_VARIABLES;
1668*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
1669*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
1670*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
1671*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.n);
1672*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply);
1673*4882a593Smuzhiyun         __GLX_SWAP_INT_ARRAY((int *) sendBuf, length);
1674*4882a593Smuzhiyun         WriteToClient(client, length << 2, sendBuf);
1675*4882a593Smuzhiyun     }
1676*4882a593Smuzhiyun     else {
1677*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply);
1678*4882a593Smuzhiyun         WriteToClient(client, nReplyBytes, sendBuf);
1679*4882a593Smuzhiyun     }
1680*4882a593Smuzhiyun 
1681*4882a593Smuzhiyun     return Success;
1682*4882a593Smuzhiyun }
1683*4882a593Smuzhiyun 
1684*4882a593Smuzhiyun int
__glXDisp_QueryContextInfoEXT(__GLXclientState * cl,GLbyte * pc)1685*4882a593Smuzhiyun __glXDisp_QueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc)
1686*4882a593Smuzhiyun {
1687*4882a593Smuzhiyun     ClientPtr client = cl->client;
1688*4882a593Smuzhiyun     xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
1689*4882a593Smuzhiyun 
1690*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq);
1691*4882a593Smuzhiyun 
1692*4882a593Smuzhiyun     return DoQueryContext(cl, req->context);
1693*4882a593Smuzhiyun }
1694*4882a593Smuzhiyun 
1695*4882a593Smuzhiyun int
__glXDisp_QueryContext(__GLXclientState * cl,GLbyte * pc)1696*4882a593Smuzhiyun __glXDisp_QueryContext(__GLXclientState * cl, GLbyte * pc)
1697*4882a593Smuzhiyun {
1698*4882a593Smuzhiyun     xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
1699*4882a593Smuzhiyun 
1700*4882a593Smuzhiyun     return DoQueryContext(cl, req->context);
1701*4882a593Smuzhiyun }
1702*4882a593Smuzhiyun 
1703*4882a593Smuzhiyun int
__glXDisp_BindTexImageEXT(__GLXclientState * cl,GLbyte * pc)1704*4882a593Smuzhiyun __glXDisp_BindTexImageEXT(__GLXclientState * cl, GLbyte * pc)
1705*4882a593Smuzhiyun {
1706*4882a593Smuzhiyun     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1707*4882a593Smuzhiyun     ClientPtr client = cl->client;
1708*4882a593Smuzhiyun     __GLXcontext *context;
1709*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1710*4882a593Smuzhiyun     GLXDrawable drawId;
1711*4882a593Smuzhiyun     int buffer;
1712*4882a593Smuzhiyun     int error;
1713*4882a593Smuzhiyun     CARD32 num_attribs;
1714*4882a593Smuzhiyun 
1715*4882a593Smuzhiyun     if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len)
1716*4882a593Smuzhiyun         return BadLength;
1717*4882a593Smuzhiyun 
1718*4882a593Smuzhiyun     pc += __GLX_VENDPRIV_HDR_SIZE;
1719*4882a593Smuzhiyun 
1720*4882a593Smuzhiyun     drawId = *((CARD32 *) (pc));
1721*4882a593Smuzhiyun     buffer = *((INT32 *) (pc + 4));
1722*4882a593Smuzhiyun     num_attribs = *((CARD32 *) (pc + 8));
1723*4882a593Smuzhiyun     if (num_attribs > (UINT32_MAX >> 3)) {
1724*4882a593Smuzhiyun         client->errorValue = num_attribs;
1725*4882a593Smuzhiyun         return BadValue;
1726*4882a593Smuzhiyun     }
1727*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 12 + (num_attribs << 3));
1728*4882a593Smuzhiyun 
1729*4882a593Smuzhiyun     if (buffer != GLX_FRONT_LEFT_EXT)
1730*4882a593Smuzhiyun         return __glXError(GLXBadPixmap);
1731*4882a593Smuzhiyun 
1732*4882a593Smuzhiyun     context = __glXForceCurrent(cl, req->contextTag, &error);
1733*4882a593Smuzhiyun     if (!context)
1734*4882a593Smuzhiyun         return error;
1735*4882a593Smuzhiyun 
1736*4882a593Smuzhiyun     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
1737*4882a593Smuzhiyun                           DixReadAccess, &pGlxDraw, &error))
1738*4882a593Smuzhiyun         return error;
1739*4882a593Smuzhiyun 
1740*4882a593Smuzhiyun     if (!context->bindTexImage)
1741*4882a593Smuzhiyun         return __glXError(GLXUnsupportedPrivateRequest);
1742*4882a593Smuzhiyun 
1743*4882a593Smuzhiyun     return context->bindTexImage(context, buffer, pGlxDraw);
1744*4882a593Smuzhiyun }
1745*4882a593Smuzhiyun 
1746*4882a593Smuzhiyun int
__glXDisp_ReleaseTexImageEXT(__GLXclientState * cl,GLbyte * pc)1747*4882a593Smuzhiyun __glXDisp_ReleaseTexImageEXT(__GLXclientState * cl, GLbyte * pc)
1748*4882a593Smuzhiyun {
1749*4882a593Smuzhiyun     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1750*4882a593Smuzhiyun     ClientPtr client = cl->client;
1751*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1752*4882a593Smuzhiyun     __GLXcontext *context;
1753*4882a593Smuzhiyun     GLXDrawable drawId;
1754*4882a593Smuzhiyun     int buffer;
1755*4882a593Smuzhiyun     int error;
1756*4882a593Smuzhiyun 
1757*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8);
1758*4882a593Smuzhiyun 
1759*4882a593Smuzhiyun     pc += __GLX_VENDPRIV_HDR_SIZE;
1760*4882a593Smuzhiyun 
1761*4882a593Smuzhiyun     drawId = *((CARD32 *) (pc));
1762*4882a593Smuzhiyun     buffer = *((INT32 *) (pc + 4));
1763*4882a593Smuzhiyun 
1764*4882a593Smuzhiyun     context = __glXForceCurrent(cl, req->contextTag, &error);
1765*4882a593Smuzhiyun     if (!context)
1766*4882a593Smuzhiyun         return error;
1767*4882a593Smuzhiyun 
1768*4882a593Smuzhiyun     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
1769*4882a593Smuzhiyun                           DixReadAccess, &pGlxDraw, &error))
1770*4882a593Smuzhiyun         return error;
1771*4882a593Smuzhiyun 
1772*4882a593Smuzhiyun     if (!context->releaseTexImage)
1773*4882a593Smuzhiyun         return __glXError(GLXUnsupportedPrivateRequest);
1774*4882a593Smuzhiyun 
1775*4882a593Smuzhiyun     return context->releaseTexImage(context, buffer, pGlxDraw);
1776*4882a593Smuzhiyun }
1777*4882a593Smuzhiyun 
1778*4882a593Smuzhiyun int
__glXDisp_CopySubBufferMESA(__GLXclientState * cl,GLbyte * pc)1779*4882a593Smuzhiyun __glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc)
1780*4882a593Smuzhiyun {
1781*4882a593Smuzhiyun     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1782*4882a593Smuzhiyun     GLXContextTag tag = req->contextTag;
1783*4882a593Smuzhiyun     __GLXcontext *glxc = NULL;
1784*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw;
1785*4882a593Smuzhiyun     ClientPtr client = cl->client;
1786*4882a593Smuzhiyun     GLXDrawable drawId;
1787*4882a593Smuzhiyun     int error;
1788*4882a593Smuzhiyun     int x, y, width, height;
1789*4882a593Smuzhiyun 
1790*4882a593Smuzhiyun     (void) client;
1791*4882a593Smuzhiyun     (void) req;
1792*4882a593Smuzhiyun 
1793*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20);
1794*4882a593Smuzhiyun 
1795*4882a593Smuzhiyun     pc += __GLX_VENDPRIV_HDR_SIZE;
1796*4882a593Smuzhiyun 
1797*4882a593Smuzhiyun     drawId = *((CARD32 *) (pc));
1798*4882a593Smuzhiyun     x = *((INT32 *) (pc + 4));
1799*4882a593Smuzhiyun     y = *((INT32 *) (pc + 8));
1800*4882a593Smuzhiyun     width = *((INT32 *) (pc + 12));
1801*4882a593Smuzhiyun     height = *((INT32 *) (pc + 16));
1802*4882a593Smuzhiyun 
1803*4882a593Smuzhiyun     if (tag) {
1804*4882a593Smuzhiyun         glxc = __glXLookupContextByTag(cl, tag);
1805*4882a593Smuzhiyun         if (!glxc) {
1806*4882a593Smuzhiyun             return __glXError(GLXBadContextTag);
1807*4882a593Smuzhiyun         }
1808*4882a593Smuzhiyun         /*
1809*4882a593Smuzhiyun          ** The calling thread is swapping its current drawable.  In this case,
1810*4882a593Smuzhiyun          ** glxSwapBuffers is in both GL and X streams, in terms of
1811*4882a593Smuzhiyun          ** sequentiality.
1812*4882a593Smuzhiyun          */
1813*4882a593Smuzhiyun         if (__glXForceCurrent(cl, tag, &error)) {
1814*4882a593Smuzhiyun             /*
1815*4882a593Smuzhiyun              ** Do whatever is needed to make sure that all preceding requests
1816*4882a593Smuzhiyun              ** in both streams are completed before the swap is executed.
1817*4882a593Smuzhiyun              */
1818*4882a593Smuzhiyun             glFinish();
1819*4882a593Smuzhiyun         }
1820*4882a593Smuzhiyun         else {
1821*4882a593Smuzhiyun             return error;
1822*4882a593Smuzhiyun         }
1823*4882a593Smuzhiyun     }
1824*4882a593Smuzhiyun 
1825*4882a593Smuzhiyun     pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
1826*4882a593Smuzhiyun     if (!pGlxDraw)
1827*4882a593Smuzhiyun         return error;
1828*4882a593Smuzhiyun 
1829*4882a593Smuzhiyun     if (pGlxDraw == NULL ||
1830*4882a593Smuzhiyun         pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
1831*4882a593Smuzhiyun         pGlxDraw->copySubBuffer == NULL)
1832*4882a593Smuzhiyun         return __glXError(GLXBadDrawable);
1833*4882a593Smuzhiyun 
1834*4882a593Smuzhiyun     (*pGlxDraw->copySubBuffer) (pGlxDraw, x, y, width, height);
1835*4882a593Smuzhiyun 
1836*4882a593Smuzhiyun     return Success;
1837*4882a593Smuzhiyun }
1838*4882a593Smuzhiyun 
1839*4882a593Smuzhiyun /* hack for old glxext.h */
1840*4882a593Smuzhiyun #ifndef GLX_STEREO_TREE_EXT
1841*4882a593Smuzhiyun #define GLX_STEREO_TREE_EXT                 0x20F5
1842*4882a593Smuzhiyun #endif
1843*4882a593Smuzhiyun 
1844*4882a593Smuzhiyun /*
1845*4882a593Smuzhiyun ** Get drawable attributes
1846*4882a593Smuzhiyun */
1847*4882a593Smuzhiyun static int
DoGetDrawableAttributes(__GLXclientState * cl,XID drawId)1848*4882a593Smuzhiyun DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
1849*4882a593Smuzhiyun {
1850*4882a593Smuzhiyun     ClientPtr client = cl->client;
1851*4882a593Smuzhiyun     xGLXGetDrawableAttributesReply reply;
1852*4882a593Smuzhiyun     __GLXdrawable *pGlxDraw = NULL;
1853*4882a593Smuzhiyun     DrawablePtr pDraw;
1854*4882a593Smuzhiyun     CARD32 attributes[18];
1855*4882a593Smuzhiyun     int num = 0, error;
1856*4882a593Smuzhiyun 
1857*4882a593Smuzhiyun     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
1858*4882a593Smuzhiyun                           DixGetAttrAccess, &pGlxDraw, &error)) {
1859*4882a593Smuzhiyun         /* hack for GLX 1.2 naked windows */
1860*4882a593Smuzhiyun         int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client,
1861*4882a593Smuzhiyun                                   DixGetAttrAccess);
1862*4882a593Smuzhiyun         if (err != Success)
1863*4882a593Smuzhiyun             return error;
1864*4882a593Smuzhiyun     }
1865*4882a593Smuzhiyun     if (pGlxDraw)
1866*4882a593Smuzhiyun         pDraw = pGlxDraw->pDraw;
1867*4882a593Smuzhiyun 
1868*4882a593Smuzhiyun #define ATTRIB(a, v) do { \
1869*4882a593Smuzhiyun     attributes[2*num] = (a); \
1870*4882a593Smuzhiyun     attributes[2*num+1] = (v); \
1871*4882a593Smuzhiyun     num++; \
1872*4882a593Smuzhiyun     } while (0)
1873*4882a593Smuzhiyun 
1874*4882a593Smuzhiyun     ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE);
1875*4882a593Smuzhiyun     ATTRIB(GLX_WIDTH, pDraw->width);
1876*4882a593Smuzhiyun     ATTRIB(GLX_HEIGHT, pDraw->height);
1877*4882a593Smuzhiyun     ATTRIB(GLX_SCREEN, pDraw->pScreen->myNum);
1878*4882a593Smuzhiyun     if (pGlxDraw) {
1879*4882a593Smuzhiyun         ATTRIB(GLX_TEXTURE_TARGET_EXT,
1880*4882a593Smuzhiyun                pGlxDraw->target == GL_TEXTURE_2D ?
1881*4882a593Smuzhiyun                 GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT);
1882*4882a593Smuzhiyun         ATTRIB(GLX_EVENT_MASK, pGlxDraw->eventMask);
1883*4882a593Smuzhiyun         ATTRIB(GLX_FBCONFIG_ID, pGlxDraw->config->fbconfigID);
1884*4882a593Smuzhiyun         if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
1885*4882a593Smuzhiyun             ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE);
1886*4882a593Smuzhiyun         }
1887*4882a593Smuzhiyun         if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) {
1888*4882a593Smuzhiyun             ATTRIB(GLX_STEREO_TREE_EXT, 0);
1889*4882a593Smuzhiyun         }
1890*4882a593Smuzhiyun     }
1891*4882a593Smuzhiyun #undef ATTRIB
1892*4882a593Smuzhiyun 
1893*4882a593Smuzhiyun     reply = (xGLXGetDrawableAttributesReply) {
1894*4882a593Smuzhiyun         .type = X_Reply,
1895*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
1896*4882a593Smuzhiyun         .length = num << 1,
1897*4882a593Smuzhiyun         .numAttribs = num
1898*4882a593Smuzhiyun     };
1899*4882a593Smuzhiyun 
1900*4882a593Smuzhiyun     if (client->swapped) {
1901*4882a593Smuzhiyun         int length = reply.length;
1902*4882a593Smuzhiyun 
1903*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_VARIABLES;
1904*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
1905*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
1906*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
1907*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.numAttribs);
1908*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply);
1909*4882a593Smuzhiyun         __GLX_SWAP_INT_ARRAY((int *) attributes, length);
1910*4882a593Smuzhiyun         WriteToClient(client, length << 2, attributes);
1911*4882a593Smuzhiyun     }
1912*4882a593Smuzhiyun     else {
1913*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply);
1914*4882a593Smuzhiyun         WriteToClient(client, reply.length * sizeof(CARD32), attributes);
1915*4882a593Smuzhiyun     }
1916*4882a593Smuzhiyun 
1917*4882a593Smuzhiyun     return Success;
1918*4882a593Smuzhiyun }
1919*4882a593Smuzhiyun 
1920*4882a593Smuzhiyun int
__glXDisp_GetDrawableAttributes(__GLXclientState * cl,GLbyte * pc)1921*4882a593Smuzhiyun __glXDisp_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
1922*4882a593Smuzhiyun {
1923*4882a593Smuzhiyun     ClientPtr client = cl->client;
1924*4882a593Smuzhiyun     xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc;
1925*4882a593Smuzhiyun 
1926*4882a593Smuzhiyun     /* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */
1927*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq);
1928*4882a593Smuzhiyun 
1929*4882a593Smuzhiyun     return DoGetDrawableAttributes(cl, req->drawable);
1930*4882a593Smuzhiyun }
1931*4882a593Smuzhiyun 
1932*4882a593Smuzhiyun int
__glXDisp_GetDrawableAttributesSGIX(__GLXclientState * cl,GLbyte * pc)1933*4882a593Smuzhiyun __glXDisp_GetDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
1934*4882a593Smuzhiyun {
1935*4882a593Smuzhiyun     ClientPtr client = cl->client;
1936*4882a593Smuzhiyun     xGLXGetDrawableAttributesSGIXReq *req =
1937*4882a593Smuzhiyun         (xGLXGetDrawableAttributesSGIXReq *) pc;
1938*4882a593Smuzhiyun 
1939*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq);
1940*4882a593Smuzhiyun 
1941*4882a593Smuzhiyun     return DoGetDrawableAttributes(cl, req->drawable);
1942*4882a593Smuzhiyun }
1943*4882a593Smuzhiyun 
1944*4882a593Smuzhiyun /************************************************************************/
1945*4882a593Smuzhiyun 
1946*4882a593Smuzhiyun /*
1947*4882a593Smuzhiyun ** Render and Renderlarge are not in the GLX API.  They are used by the GLX
1948*4882a593Smuzhiyun ** client library to send batches of GL rendering commands.
1949*4882a593Smuzhiyun */
1950*4882a593Smuzhiyun 
1951*4882a593Smuzhiyun /*
1952*4882a593Smuzhiyun ** Reset state used to keep track of large (multi-request) commands.
1953*4882a593Smuzhiyun */
1954*4882a593Smuzhiyun static void
ResetLargeCommandStatus(__GLXcontext * cx)1955*4882a593Smuzhiyun ResetLargeCommandStatus(__GLXcontext *cx)
1956*4882a593Smuzhiyun {
1957*4882a593Smuzhiyun     cx->largeCmdBytesSoFar = 0;
1958*4882a593Smuzhiyun     cx->largeCmdBytesTotal = 0;
1959*4882a593Smuzhiyun     cx->largeCmdRequestsSoFar = 0;
1960*4882a593Smuzhiyun     cx->largeCmdRequestsTotal = 0;
1961*4882a593Smuzhiyun }
1962*4882a593Smuzhiyun 
1963*4882a593Smuzhiyun /*
1964*4882a593Smuzhiyun ** Execute all the drawing commands in a request.
1965*4882a593Smuzhiyun */
1966*4882a593Smuzhiyun int
__glXDisp_Render(__GLXclientState * cl,GLbyte * pc)1967*4882a593Smuzhiyun __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
1968*4882a593Smuzhiyun {
1969*4882a593Smuzhiyun     xGLXRenderReq *req;
1970*4882a593Smuzhiyun     ClientPtr client = cl->client;
1971*4882a593Smuzhiyun     int left, cmdlen, error;
1972*4882a593Smuzhiyun     int commandsDone;
1973*4882a593Smuzhiyun     CARD16 opcode;
1974*4882a593Smuzhiyun     __GLXrenderHeader *hdr;
1975*4882a593Smuzhiyun     __GLXcontext *glxc;
1976*4882a593Smuzhiyun 
1977*4882a593Smuzhiyun     __GLX_DECLARE_SWAP_VARIABLES;
1978*4882a593Smuzhiyun 
1979*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXRenderReq);
1980*4882a593Smuzhiyun 
1981*4882a593Smuzhiyun     req = (xGLXRenderReq *) pc;
1982*4882a593Smuzhiyun     if (client->swapped) {
1983*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&req->length);
1984*4882a593Smuzhiyun         __GLX_SWAP_INT(&req->contextTag);
1985*4882a593Smuzhiyun     }
1986*4882a593Smuzhiyun 
1987*4882a593Smuzhiyun     glxc = __glXForceCurrent(cl, req->contextTag, &error);
1988*4882a593Smuzhiyun     if (!glxc) {
1989*4882a593Smuzhiyun         return error;
1990*4882a593Smuzhiyun     }
1991*4882a593Smuzhiyun 
1992*4882a593Smuzhiyun     commandsDone = 0;
1993*4882a593Smuzhiyun     pc += sz_xGLXRenderReq;
1994*4882a593Smuzhiyun     left = (req->length << 2) - sz_xGLXRenderReq;
1995*4882a593Smuzhiyun     while (left > 0) {
1996*4882a593Smuzhiyun         __GLXrenderSizeData entry;
1997*4882a593Smuzhiyun         int extra = 0;
1998*4882a593Smuzhiyun         __GLXdispatchRenderProcPtr proc;
1999*4882a593Smuzhiyun         int err;
2000*4882a593Smuzhiyun 
2001*4882a593Smuzhiyun         if (left < sizeof(__GLXrenderHeader))
2002*4882a593Smuzhiyun             return BadLength;
2003*4882a593Smuzhiyun 
2004*4882a593Smuzhiyun         /*
2005*4882a593Smuzhiyun          ** Verify that the header length and the overall length agree.
2006*4882a593Smuzhiyun          ** Also, each command must be word aligned.
2007*4882a593Smuzhiyun          */
2008*4882a593Smuzhiyun         hdr = (__GLXrenderHeader *) pc;
2009*4882a593Smuzhiyun         if (client->swapped) {
2010*4882a593Smuzhiyun             __GLX_SWAP_SHORT(&hdr->length);
2011*4882a593Smuzhiyun             __GLX_SWAP_SHORT(&hdr->opcode);
2012*4882a593Smuzhiyun         }
2013*4882a593Smuzhiyun         cmdlen = hdr->length;
2014*4882a593Smuzhiyun         opcode = hdr->opcode;
2015*4882a593Smuzhiyun 
2016*4882a593Smuzhiyun         if (left < cmdlen)
2017*4882a593Smuzhiyun             return BadLength;
2018*4882a593Smuzhiyun 
2019*4882a593Smuzhiyun         /*
2020*4882a593Smuzhiyun          ** Check for core opcodes and grab entry data.
2021*4882a593Smuzhiyun          */
2022*4882a593Smuzhiyun         err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
2023*4882a593Smuzhiyun         proc = (__GLXdispatchRenderProcPtr)
2024*4882a593Smuzhiyun             __glXGetProtocolDecodeFunction(&Render_dispatch_info,
2025*4882a593Smuzhiyun                                            opcode, client->swapped);
2026*4882a593Smuzhiyun 
2027*4882a593Smuzhiyun         if ((err < 0) || (proc == NULL)) {
2028*4882a593Smuzhiyun             client->errorValue = commandsDone;
2029*4882a593Smuzhiyun             return __glXError(GLXBadRenderRequest);
2030*4882a593Smuzhiyun         }
2031*4882a593Smuzhiyun 
2032*4882a593Smuzhiyun         if (cmdlen < entry.bytes) {
2033*4882a593Smuzhiyun             return BadLength;
2034*4882a593Smuzhiyun         }
2035*4882a593Smuzhiyun 
2036*4882a593Smuzhiyun         if (entry.varsize) {
2037*4882a593Smuzhiyun             /* variable size command */
2038*4882a593Smuzhiyun             extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE,
2039*4882a593Smuzhiyun                                       client->swapped,
2040*4882a593Smuzhiyun                                       left - __GLX_RENDER_HDR_SIZE);
2041*4882a593Smuzhiyun             if (extra < 0) {
2042*4882a593Smuzhiyun                 return BadLength;
2043*4882a593Smuzhiyun             }
2044*4882a593Smuzhiyun         }
2045*4882a593Smuzhiyun 
2046*4882a593Smuzhiyun         if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) {
2047*4882a593Smuzhiyun             return BadLength;
2048*4882a593Smuzhiyun         }
2049*4882a593Smuzhiyun 
2050*4882a593Smuzhiyun         /*
2051*4882a593Smuzhiyun          ** Skip over the header and execute the command.  We allow the
2052*4882a593Smuzhiyun          ** caller to trash the command memory.  This is useful especially
2053*4882a593Smuzhiyun          ** for things that require double alignment - they can just shift
2054*4882a593Smuzhiyun          ** the data towards lower memory (trashing the header) by 4 bytes
2055*4882a593Smuzhiyun          ** and achieve the required alignment.
2056*4882a593Smuzhiyun          */
2057*4882a593Smuzhiyun         (*proc) (pc + __GLX_RENDER_HDR_SIZE);
2058*4882a593Smuzhiyun         pc += cmdlen;
2059*4882a593Smuzhiyun         left -= cmdlen;
2060*4882a593Smuzhiyun         commandsDone++;
2061*4882a593Smuzhiyun     }
2062*4882a593Smuzhiyun     return Success;
2063*4882a593Smuzhiyun }
2064*4882a593Smuzhiyun 
2065*4882a593Smuzhiyun /*
2066*4882a593Smuzhiyun ** Execute a large rendering request (one that spans multiple X requests).
2067*4882a593Smuzhiyun */
2068*4882a593Smuzhiyun int
__glXDisp_RenderLarge(__GLXclientState * cl,GLbyte * pc)2069*4882a593Smuzhiyun __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
2070*4882a593Smuzhiyun {
2071*4882a593Smuzhiyun     xGLXRenderLargeReq *req;
2072*4882a593Smuzhiyun     ClientPtr client = cl->client;
2073*4882a593Smuzhiyun     size_t dataBytes;
2074*4882a593Smuzhiyun     __GLXrenderLargeHeader *hdr;
2075*4882a593Smuzhiyun     __GLXcontext *glxc;
2076*4882a593Smuzhiyun     int error;
2077*4882a593Smuzhiyun     CARD16 opcode;
2078*4882a593Smuzhiyun 
2079*4882a593Smuzhiyun     __GLX_DECLARE_SWAP_VARIABLES;
2080*4882a593Smuzhiyun 
2081*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq);
2082*4882a593Smuzhiyun 
2083*4882a593Smuzhiyun     req = (xGLXRenderLargeReq *) pc;
2084*4882a593Smuzhiyun     if (client->swapped) {
2085*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&req->length);
2086*4882a593Smuzhiyun         __GLX_SWAP_INT(&req->contextTag);
2087*4882a593Smuzhiyun         __GLX_SWAP_INT(&req->dataBytes);
2088*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&req->requestNumber);
2089*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&req->requestTotal);
2090*4882a593Smuzhiyun     }
2091*4882a593Smuzhiyun 
2092*4882a593Smuzhiyun     glxc = __glXForceCurrent(cl, req->contextTag, &error);
2093*4882a593Smuzhiyun     if (!glxc) {
2094*4882a593Smuzhiyun         return error;
2095*4882a593Smuzhiyun     }
2096*4882a593Smuzhiyun     if (safe_pad(req->dataBytes) < 0)
2097*4882a593Smuzhiyun         return BadLength;
2098*4882a593Smuzhiyun     dataBytes = req->dataBytes;
2099*4882a593Smuzhiyun 
2100*4882a593Smuzhiyun     /*
2101*4882a593Smuzhiyun      ** Check the request length.
2102*4882a593Smuzhiyun      */
2103*4882a593Smuzhiyun     if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) {
2104*4882a593Smuzhiyun         client->errorValue = req->length;
2105*4882a593Smuzhiyun         /* Reset in case this isn't 1st request. */
2106*4882a593Smuzhiyun         ResetLargeCommandStatus(glxc);
2107*4882a593Smuzhiyun         return BadLength;
2108*4882a593Smuzhiyun     }
2109*4882a593Smuzhiyun     pc += sz_xGLXRenderLargeReq;
2110*4882a593Smuzhiyun 
2111*4882a593Smuzhiyun     if (glxc->largeCmdRequestsSoFar == 0) {
2112*4882a593Smuzhiyun         __GLXrenderSizeData entry;
2113*4882a593Smuzhiyun         int extra = 0;
2114*4882a593Smuzhiyun         int left = (req->length << 2) - sz_xGLXRenderLargeReq;
2115*4882a593Smuzhiyun         int cmdlen;
2116*4882a593Smuzhiyun         int err;
2117*4882a593Smuzhiyun 
2118*4882a593Smuzhiyun         /*
2119*4882a593Smuzhiyun          ** This is the first request of a multi request command.
2120*4882a593Smuzhiyun          ** Make enough space in the buffer, then copy the entire request.
2121*4882a593Smuzhiyun          */
2122*4882a593Smuzhiyun         if (req->requestNumber != 1) {
2123*4882a593Smuzhiyun             client->errorValue = req->requestNumber;
2124*4882a593Smuzhiyun             return __glXError(GLXBadLargeRequest);
2125*4882a593Smuzhiyun         }
2126*4882a593Smuzhiyun 
2127*4882a593Smuzhiyun         if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE)
2128*4882a593Smuzhiyun             return BadLength;
2129*4882a593Smuzhiyun 
2130*4882a593Smuzhiyun         hdr = (__GLXrenderLargeHeader *) pc;
2131*4882a593Smuzhiyun         if (client->swapped) {
2132*4882a593Smuzhiyun             __GLX_SWAP_INT(&hdr->length);
2133*4882a593Smuzhiyun             __GLX_SWAP_INT(&hdr->opcode);
2134*4882a593Smuzhiyun         }
2135*4882a593Smuzhiyun         opcode = hdr->opcode;
2136*4882a593Smuzhiyun         if ((cmdlen = safe_pad(hdr->length)) < 0)
2137*4882a593Smuzhiyun             return BadLength;
2138*4882a593Smuzhiyun 
2139*4882a593Smuzhiyun         /*
2140*4882a593Smuzhiyun          ** Check for core opcodes and grab entry data.
2141*4882a593Smuzhiyun          */
2142*4882a593Smuzhiyun         err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
2143*4882a593Smuzhiyun         if (err < 0) {
2144*4882a593Smuzhiyun             client->errorValue = opcode;
2145*4882a593Smuzhiyun             return __glXError(GLXBadLargeRequest);
2146*4882a593Smuzhiyun         }
2147*4882a593Smuzhiyun 
2148*4882a593Smuzhiyun         if (entry.varsize) {
2149*4882a593Smuzhiyun             /*
2150*4882a593Smuzhiyun              ** If it's a variable-size command (a command whose length must
2151*4882a593Smuzhiyun              ** be computed from its parameters), all the parameters needed
2152*4882a593Smuzhiyun              ** will be in the 1st request, so it's okay to do this.
2153*4882a593Smuzhiyun              */
2154*4882a593Smuzhiyun             extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE,
2155*4882a593Smuzhiyun                                       client->swapped,
2156*4882a593Smuzhiyun                                       left - __GLX_RENDER_LARGE_HDR_SIZE);
2157*4882a593Smuzhiyun             if (extra < 0) {
2158*4882a593Smuzhiyun                 return BadLength;
2159*4882a593Smuzhiyun             }
2160*4882a593Smuzhiyun         }
2161*4882a593Smuzhiyun 
2162*4882a593Smuzhiyun         /* the +4 is safe because we know entry.bytes is small */
2163*4882a593Smuzhiyun         if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) {
2164*4882a593Smuzhiyun             return BadLength;
2165*4882a593Smuzhiyun         }
2166*4882a593Smuzhiyun 
2167*4882a593Smuzhiyun         /*
2168*4882a593Smuzhiyun          ** Make enough space in the buffer, then copy the entire request.
2169*4882a593Smuzhiyun          */
2170*4882a593Smuzhiyun         if (glxc->largeCmdBufSize < cmdlen) {
2171*4882a593Smuzhiyun 	    GLbyte *newbuf = glxc->largeCmdBuf;
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun 	    if (!(newbuf = realloc(newbuf, cmdlen)))
2174*4882a593Smuzhiyun 		return BadAlloc;
2175*4882a593Smuzhiyun 
2176*4882a593Smuzhiyun 	    glxc->largeCmdBuf = newbuf;
2177*4882a593Smuzhiyun             glxc->largeCmdBufSize = cmdlen;
2178*4882a593Smuzhiyun         }
2179*4882a593Smuzhiyun         memcpy(glxc->largeCmdBuf, pc, dataBytes);
2180*4882a593Smuzhiyun 
2181*4882a593Smuzhiyun         glxc->largeCmdBytesSoFar = dataBytes;
2182*4882a593Smuzhiyun         glxc->largeCmdBytesTotal = cmdlen;
2183*4882a593Smuzhiyun         glxc->largeCmdRequestsSoFar = 1;
2184*4882a593Smuzhiyun         glxc->largeCmdRequestsTotal = req->requestTotal;
2185*4882a593Smuzhiyun         return Success;
2186*4882a593Smuzhiyun 
2187*4882a593Smuzhiyun     }
2188*4882a593Smuzhiyun     else {
2189*4882a593Smuzhiyun         /*
2190*4882a593Smuzhiyun          ** We are receiving subsequent (i.e. not the first) requests of a
2191*4882a593Smuzhiyun          ** multi request command.
2192*4882a593Smuzhiyun          */
2193*4882a593Smuzhiyun         int bytesSoFar; /* including this packet */
2194*4882a593Smuzhiyun 
2195*4882a593Smuzhiyun         /*
2196*4882a593Smuzhiyun          ** Check the request number and the total request count.
2197*4882a593Smuzhiyun          */
2198*4882a593Smuzhiyun         if (req->requestNumber != glxc->largeCmdRequestsSoFar + 1) {
2199*4882a593Smuzhiyun             client->errorValue = req->requestNumber;
2200*4882a593Smuzhiyun             ResetLargeCommandStatus(glxc);
2201*4882a593Smuzhiyun             return __glXError(GLXBadLargeRequest);
2202*4882a593Smuzhiyun         }
2203*4882a593Smuzhiyun         if (req->requestTotal != glxc->largeCmdRequestsTotal) {
2204*4882a593Smuzhiyun             client->errorValue = req->requestTotal;
2205*4882a593Smuzhiyun             ResetLargeCommandStatus(glxc);
2206*4882a593Smuzhiyun             return __glXError(GLXBadLargeRequest);
2207*4882a593Smuzhiyun         }
2208*4882a593Smuzhiyun 
2209*4882a593Smuzhiyun         /*
2210*4882a593Smuzhiyun          ** Check that we didn't get too much data.
2211*4882a593Smuzhiyun          */
2212*4882a593Smuzhiyun         if ((bytesSoFar = safe_add(glxc->largeCmdBytesSoFar, dataBytes)) < 0) {
2213*4882a593Smuzhiyun             client->errorValue = dataBytes;
2214*4882a593Smuzhiyun             ResetLargeCommandStatus(glxc);
2215*4882a593Smuzhiyun             return __glXError(GLXBadLargeRequest);
2216*4882a593Smuzhiyun         }
2217*4882a593Smuzhiyun 
2218*4882a593Smuzhiyun         if (bytesSoFar > glxc->largeCmdBytesTotal) {
2219*4882a593Smuzhiyun             client->errorValue = dataBytes;
2220*4882a593Smuzhiyun             ResetLargeCommandStatus(glxc);
2221*4882a593Smuzhiyun             return __glXError(GLXBadLargeRequest);
2222*4882a593Smuzhiyun         }
2223*4882a593Smuzhiyun 
2224*4882a593Smuzhiyun         memcpy(glxc->largeCmdBuf + glxc->largeCmdBytesSoFar, pc, dataBytes);
2225*4882a593Smuzhiyun         glxc->largeCmdBytesSoFar += dataBytes;
2226*4882a593Smuzhiyun         glxc->largeCmdRequestsSoFar++;
2227*4882a593Smuzhiyun 
2228*4882a593Smuzhiyun         if (req->requestNumber == glxc->largeCmdRequestsTotal) {
2229*4882a593Smuzhiyun             __GLXdispatchRenderProcPtr proc;
2230*4882a593Smuzhiyun 
2231*4882a593Smuzhiyun             /*
2232*4882a593Smuzhiyun              ** This is the last request; it must have enough bytes to complete
2233*4882a593Smuzhiyun              ** the command.
2234*4882a593Smuzhiyun              */
2235*4882a593Smuzhiyun             /* NOTE: the pad macro below is needed because the client library
2236*4882a593Smuzhiyun              ** pads the total byte count, but not the per-request byte counts.
2237*4882a593Smuzhiyun              ** The Protocol Encoding says the total byte count should not be
2238*4882a593Smuzhiyun              ** padded, so a proposal will be made to the ARB to relax the
2239*4882a593Smuzhiyun              ** padding constraint on the total byte count, thus preserving
2240*4882a593Smuzhiyun              ** backward compatibility.  Meanwhile, the padding done below
2241*4882a593Smuzhiyun              ** fixes a bug that did not allow large commands of odd sizes to
2242*4882a593Smuzhiyun              ** be accepted by the server.
2243*4882a593Smuzhiyun              */
2244*4882a593Smuzhiyun             if (safe_pad(glxc->largeCmdBytesSoFar) != glxc->largeCmdBytesTotal) {
2245*4882a593Smuzhiyun                 client->errorValue = dataBytes;
2246*4882a593Smuzhiyun                 ResetLargeCommandStatus(glxc);
2247*4882a593Smuzhiyun                 return __glXError(GLXBadLargeRequest);
2248*4882a593Smuzhiyun             }
2249*4882a593Smuzhiyun             hdr = (__GLXrenderLargeHeader *) glxc->largeCmdBuf;
2250*4882a593Smuzhiyun             /*
2251*4882a593Smuzhiyun              ** The opcode and length field in the header had already been
2252*4882a593Smuzhiyun              ** swapped when the first request was received.
2253*4882a593Smuzhiyun              **
2254*4882a593Smuzhiyun              ** Use the opcode to index into the procedure table.
2255*4882a593Smuzhiyun              */
2256*4882a593Smuzhiyun             opcode = hdr->opcode;
2257*4882a593Smuzhiyun 
2258*4882a593Smuzhiyun             proc = (__GLXdispatchRenderProcPtr)
2259*4882a593Smuzhiyun                 __glXGetProtocolDecodeFunction(&Render_dispatch_info, opcode,
2260*4882a593Smuzhiyun                                                client->swapped);
2261*4882a593Smuzhiyun             if (proc == NULL) {
2262*4882a593Smuzhiyun                 client->errorValue = opcode;
2263*4882a593Smuzhiyun                 return __glXError(GLXBadLargeRequest);
2264*4882a593Smuzhiyun             }
2265*4882a593Smuzhiyun 
2266*4882a593Smuzhiyun             /*
2267*4882a593Smuzhiyun              ** Skip over the header and execute the command.
2268*4882a593Smuzhiyun              */
2269*4882a593Smuzhiyun             (*proc) (glxc->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
2270*4882a593Smuzhiyun 
2271*4882a593Smuzhiyun             /*
2272*4882a593Smuzhiyun              ** Reset for the next RenderLarge series.
2273*4882a593Smuzhiyun              */
2274*4882a593Smuzhiyun             ResetLargeCommandStatus(glxc);
2275*4882a593Smuzhiyun         }
2276*4882a593Smuzhiyun         else {
2277*4882a593Smuzhiyun             /*
2278*4882a593Smuzhiyun              ** This is neither the first nor the last request.
2279*4882a593Smuzhiyun              */
2280*4882a593Smuzhiyun         }
2281*4882a593Smuzhiyun         return Success;
2282*4882a593Smuzhiyun     }
2283*4882a593Smuzhiyun }
2284*4882a593Smuzhiyun 
2285*4882a593Smuzhiyun /************************************************************************/
2286*4882a593Smuzhiyun 
2287*4882a593Smuzhiyun /*
2288*4882a593Smuzhiyun ** No support is provided for the vendor-private requests other than
2289*4882a593Smuzhiyun ** allocating the entry points in the dispatch table.
2290*4882a593Smuzhiyun */
2291*4882a593Smuzhiyun 
2292*4882a593Smuzhiyun int
__glXDisp_VendorPrivate(__GLXclientState * cl,GLbyte * pc)2293*4882a593Smuzhiyun __glXDisp_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
2294*4882a593Smuzhiyun {
2295*4882a593Smuzhiyun     ClientPtr client = cl->client;
2296*4882a593Smuzhiyun     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
2297*4882a593Smuzhiyun     GLint vendorcode = req->vendorCode;
2298*4882a593Smuzhiyun     __GLXdispatchVendorPrivProcPtr proc;
2299*4882a593Smuzhiyun 
2300*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
2301*4882a593Smuzhiyun 
2302*4882a593Smuzhiyun     proc = (__GLXdispatchVendorPrivProcPtr)
2303*4882a593Smuzhiyun         __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
2304*4882a593Smuzhiyun                                        vendorcode, 0);
2305*4882a593Smuzhiyun     if (proc != NULL) {
2306*4882a593Smuzhiyun         return (*proc) (cl, (GLbyte *) req);
2307*4882a593Smuzhiyun     }
2308*4882a593Smuzhiyun 
2309*4882a593Smuzhiyun     cl->client->errorValue = req->vendorCode;
2310*4882a593Smuzhiyun     return __glXError(GLXUnsupportedPrivateRequest);
2311*4882a593Smuzhiyun }
2312*4882a593Smuzhiyun 
2313*4882a593Smuzhiyun int
__glXDisp_VendorPrivateWithReply(__GLXclientState * cl,GLbyte * pc)2314*4882a593Smuzhiyun __glXDisp_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc)
2315*4882a593Smuzhiyun {
2316*4882a593Smuzhiyun     ClientPtr client = cl->client;
2317*4882a593Smuzhiyun     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
2318*4882a593Smuzhiyun     GLint vendorcode = req->vendorCode;
2319*4882a593Smuzhiyun     __GLXdispatchVendorPrivProcPtr proc;
2320*4882a593Smuzhiyun 
2321*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
2322*4882a593Smuzhiyun 
2323*4882a593Smuzhiyun     proc = (__GLXdispatchVendorPrivProcPtr)
2324*4882a593Smuzhiyun         __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
2325*4882a593Smuzhiyun                                        vendorcode, 0);
2326*4882a593Smuzhiyun     if (proc != NULL) {
2327*4882a593Smuzhiyun         return (*proc) (cl, (GLbyte *) req);
2328*4882a593Smuzhiyun     }
2329*4882a593Smuzhiyun 
2330*4882a593Smuzhiyun     cl->client->errorValue = vendorcode;
2331*4882a593Smuzhiyun     return __glXError(GLXUnsupportedPrivateRequest);
2332*4882a593Smuzhiyun }
2333*4882a593Smuzhiyun 
2334*4882a593Smuzhiyun int
__glXDisp_QueryExtensionsString(__GLXclientState * cl,GLbyte * pc)2335*4882a593Smuzhiyun __glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
2336*4882a593Smuzhiyun {
2337*4882a593Smuzhiyun     ClientPtr client = cl->client;
2338*4882a593Smuzhiyun     xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
2339*4882a593Smuzhiyun     xGLXQueryExtensionsStringReply reply;
2340*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
2341*4882a593Smuzhiyun     size_t n, length;
2342*4882a593Smuzhiyun     char *buf;
2343*4882a593Smuzhiyun     int err;
2344*4882a593Smuzhiyun 
2345*4882a593Smuzhiyun     if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
2346*4882a593Smuzhiyun         return err;
2347*4882a593Smuzhiyun 
2348*4882a593Smuzhiyun     n = strlen(pGlxScreen->GLXextensions) + 1;
2349*4882a593Smuzhiyun     length = __GLX_PAD(n) >> 2;
2350*4882a593Smuzhiyun     reply = (xGLXQueryExtensionsStringReply) {
2351*4882a593Smuzhiyun         .type = X_Reply,
2352*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
2353*4882a593Smuzhiyun         .length = length,
2354*4882a593Smuzhiyun         .n = n
2355*4882a593Smuzhiyun     };
2356*4882a593Smuzhiyun 
2357*4882a593Smuzhiyun     /* Allocate buffer to make sure it's a multiple of 4 bytes big. */
2358*4882a593Smuzhiyun     buf = calloc(length, 4);
2359*4882a593Smuzhiyun     if (buf == NULL)
2360*4882a593Smuzhiyun         return BadAlloc;
2361*4882a593Smuzhiyun     memcpy(buf, pGlxScreen->GLXextensions, n);
2362*4882a593Smuzhiyun 
2363*4882a593Smuzhiyun     if (client->swapped) {
2364*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_VARIABLES;
2365*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
2366*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
2367*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
2368*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.n);
2369*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply);
2370*4882a593Smuzhiyun         __GLX_SWAP_INT_ARRAY((int *) buf, length);
2371*4882a593Smuzhiyun         WriteToClient(client, length << 2, buf);
2372*4882a593Smuzhiyun     }
2373*4882a593Smuzhiyun     else {
2374*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply);
2375*4882a593Smuzhiyun         WriteToClient(client, (int) (length << 2), buf);
2376*4882a593Smuzhiyun     }
2377*4882a593Smuzhiyun 
2378*4882a593Smuzhiyun     free(buf);
2379*4882a593Smuzhiyun     return Success;
2380*4882a593Smuzhiyun }
2381*4882a593Smuzhiyun 
2382*4882a593Smuzhiyun #ifndef GLX_VENDOR_NAMES_EXT
2383*4882a593Smuzhiyun #define GLX_VENDOR_NAMES_EXT 0x20F6
2384*4882a593Smuzhiyun #endif
2385*4882a593Smuzhiyun 
2386*4882a593Smuzhiyun int
__glXDisp_QueryServerString(__GLXclientState * cl,GLbyte * pc)2387*4882a593Smuzhiyun __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
2388*4882a593Smuzhiyun {
2389*4882a593Smuzhiyun     ClientPtr client = cl->client;
2390*4882a593Smuzhiyun     xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
2391*4882a593Smuzhiyun     xGLXQueryServerStringReply reply;
2392*4882a593Smuzhiyun     size_t n, length;
2393*4882a593Smuzhiyun     const char *ptr;
2394*4882a593Smuzhiyun     char *buf;
2395*4882a593Smuzhiyun     __GLXscreen *pGlxScreen;
2396*4882a593Smuzhiyun     int err;
2397*4882a593Smuzhiyun 
2398*4882a593Smuzhiyun     if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
2399*4882a593Smuzhiyun         return err;
2400*4882a593Smuzhiyun 
2401*4882a593Smuzhiyun     switch (req->name) {
2402*4882a593Smuzhiyun     case GLX_VENDOR:
2403*4882a593Smuzhiyun         ptr = GLXServerVendorName;
2404*4882a593Smuzhiyun         break;
2405*4882a593Smuzhiyun     case GLX_VERSION:
2406*4882a593Smuzhiyun         ptr = "1.4";
2407*4882a593Smuzhiyun         break;
2408*4882a593Smuzhiyun     case GLX_EXTENSIONS:
2409*4882a593Smuzhiyun         ptr = pGlxScreen->GLXextensions;
2410*4882a593Smuzhiyun         break;
2411*4882a593Smuzhiyun     case GLX_VENDOR_NAMES_EXT:
2412*4882a593Smuzhiyun         if (pGlxScreen->glvnd) {
2413*4882a593Smuzhiyun             ptr = pGlxScreen->glvnd;
2414*4882a593Smuzhiyun             break;
2415*4882a593Smuzhiyun         }
2416*4882a593Smuzhiyun         /* else fall through */
2417*4882a593Smuzhiyun     default:
2418*4882a593Smuzhiyun         return BadValue;
2419*4882a593Smuzhiyun     }
2420*4882a593Smuzhiyun 
2421*4882a593Smuzhiyun     n = strlen(ptr) + 1;
2422*4882a593Smuzhiyun     length = __GLX_PAD(n) >> 2;
2423*4882a593Smuzhiyun     reply = (xGLXQueryServerStringReply) {
2424*4882a593Smuzhiyun         .type = X_Reply,
2425*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
2426*4882a593Smuzhiyun         .length = length,
2427*4882a593Smuzhiyun         .n = n
2428*4882a593Smuzhiyun     };
2429*4882a593Smuzhiyun 
2430*4882a593Smuzhiyun     buf = calloc(length, 4);
2431*4882a593Smuzhiyun     if (buf == NULL) {
2432*4882a593Smuzhiyun         return BadAlloc;
2433*4882a593Smuzhiyun     }
2434*4882a593Smuzhiyun     memcpy(buf, ptr, n);
2435*4882a593Smuzhiyun 
2436*4882a593Smuzhiyun     if (client->swapped) {
2437*4882a593Smuzhiyun         __GLX_DECLARE_SWAP_VARIABLES;
2438*4882a593Smuzhiyun         __GLX_SWAP_SHORT(&reply.sequenceNumber);
2439*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.length);
2440*4882a593Smuzhiyun         __GLX_SWAP_INT(&reply.n);
2441*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
2442*4882a593Smuzhiyun         /** no swap is needed for an array of chars **/
2443*4882a593Smuzhiyun         /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */
2444*4882a593Smuzhiyun         WriteToClient(client, length << 2, buf);
2445*4882a593Smuzhiyun     }
2446*4882a593Smuzhiyun     else {
2447*4882a593Smuzhiyun         WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
2448*4882a593Smuzhiyun         WriteToClient(client, (int) (length << 2), buf);
2449*4882a593Smuzhiyun     }
2450*4882a593Smuzhiyun 
2451*4882a593Smuzhiyun     free(buf);
2452*4882a593Smuzhiyun     return Success;
2453*4882a593Smuzhiyun }
2454*4882a593Smuzhiyun 
2455*4882a593Smuzhiyun int
__glXDisp_ClientInfo(__GLXclientState * cl,GLbyte * pc)2456*4882a593Smuzhiyun __glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc)
2457*4882a593Smuzhiyun {
2458*4882a593Smuzhiyun     ClientPtr client = cl->client;
2459*4882a593Smuzhiyun     xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
2460*4882a593Smuzhiyun     const char *buf;
2461*4882a593Smuzhiyun 
2462*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq);
2463*4882a593Smuzhiyun 
2464*4882a593Smuzhiyun     buf = (const char *) (req + 1);
2465*4882a593Smuzhiyun     if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq)))
2466*4882a593Smuzhiyun         return BadLength;
2467*4882a593Smuzhiyun 
2468*4882a593Smuzhiyun     free(cl->GLClientextensions);
2469*4882a593Smuzhiyun     cl->GLClientextensions = strdup(buf);
2470*4882a593Smuzhiyun 
2471*4882a593Smuzhiyun     return Success;
2472*4882a593Smuzhiyun }
2473*4882a593Smuzhiyun 
2474*4882a593Smuzhiyun #include <GL/glxtokens.h>
2475*4882a593Smuzhiyun 
2476*4882a593Smuzhiyun void
__glXsendSwapEvent(__GLXdrawable * drawable,int type,CARD64 ust,CARD64 msc,CARD32 sbc)2477*4882a593Smuzhiyun __glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust,
2478*4882a593Smuzhiyun                    CARD64 msc, CARD32 sbc)
2479*4882a593Smuzhiyun {
2480*4882a593Smuzhiyun     ClientPtr client = clients[CLIENT_ID(drawable->drawId)];
2481*4882a593Smuzhiyun 
2482*4882a593Smuzhiyun     xGLXBufferSwapComplete2 wire =  {
2483*4882a593Smuzhiyun         .type = __glXEventBase + GLX_BufferSwapComplete
2484*4882a593Smuzhiyun     };
2485*4882a593Smuzhiyun 
2486*4882a593Smuzhiyun     if (!client)
2487*4882a593Smuzhiyun         return;
2488*4882a593Smuzhiyun 
2489*4882a593Smuzhiyun     if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
2490*4882a593Smuzhiyun         return;
2491*4882a593Smuzhiyun 
2492*4882a593Smuzhiyun     wire.event_type = type;
2493*4882a593Smuzhiyun     wire.drawable = drawable->drawId;
2494*4882a593Smuzhiyun     wire.ust_hi = ust >> 32;
2495*4882a593Smuzhiyun     wire.ust_lo = ust & 0xffffffff;
2496*4882a593Smuzhiyun     wire.msc_hi = msc >> 32;
2497*4882a593Smuzhiyun     wire.msc_lo = msc & 0xffffffff;
2498*4882a593Smuzhiyun     wire.sbc = sbc;
2499*4882a593Smuzhiyun 
2500*4882a593Smuzhiyun     WriteEventsToClient(client, 1, (xEvent *) &wire);
2501*4882a593Smuzhiyun }
2502*4882a593Smuzhiyun 
2503*4882a593Smuzhiyun #if PRESENT
2504*4882a593Smuzhiyun static void
__glXpresentCompleteNotify(WindowPtr window,CARD8 present_kind,CARD8 present_mode,CARD32 serial,uint64_t ust,uint64_t msc)2505*4882a593Smuzhiyun __glXpresentCompleteNotify(WindowPtr window, CARD8 present_kind, CARD8 present_mode,
2506*4882a593Smuzhiyun                            CARD32 serial, uint64_t ust, uint64_t msc)
2507*4882a593Smuzhiyun {
2508*4882a593Smuzhiyun     __GLXdrawable *drawable;
2509*4882a593Smuzhiyun     int glx_type;
2510*4882a593Smuzhiyun     int rc;
2511*4882a593Smuzhiyun 
2512*4882a593Smuzhiyun     if (present_kind != PresentCompleteKindPixmap)
2513*4882a593Smuzhiyun         return;
2514*4882a593Smuzhiyun 
2515*4882a593Smuzhiyun     rc = dixLookupResourceByType((void **) &drawable, window->drawable.id,
2516*4882a593Smuzhiyun                                  __glXDrawableRes, serverClient, DixGetAttrAccess);
2517*4882a593Smuzhiyun 
2518*4882a593Smuzhiyun     if (rc != Success)
2519*4882a593Smuzhiyun         return;
2520*4882a593Smuzhiyun 
2521*4882a593Smuzhiyun     if (present_mode == PresentCompleteModeFlip)
2522*4882a593Smuzhiyun         glx_type = GLX_FLIP_COMPLETE_INTEL;
2523*4882a593Smuzhiyun     else
2524*4882a593Smuzhiyun         glx_type = GLX_BLIT_COMPLETE_INTEL;
2525*4882a593Smuzhiyun 
2526*4882a593Smuzhiyun     __glXsendSwapEvent(drawable, glx_type, ust, msc, serial);
2527*4882a593Smuzhiyun }
2528*4882a593Smuzhiyun 
2529*4882a593Smuzhiyun #include <present.h>
2530*4882a593Smuzhiyun 
2531*4882a593Smuzhiyun void
__glXregisterPresentCompleteNotify(void)2532*4882a593Smuzhiyun __glXregisterPresentCompleteNotify(void)
2533*4882a593Smuzhiyun {
2534*4882a593Smuzhiyun     present_register_complete_notify(__glXpresentCompleteNotify);
2535*4882a593Smuzhiyun }
2536*4882a593Smuzhiyun #endif
2537