1706f2543Smrg/*
2706f2543Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3706f2543Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4706f2543Smrg *
5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6706f2543Smrg * copy of this software and associated documentation files (the "Software"),
7706f2543Smrg * to deal in the Software without restriction, including without limitation
8706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
10706f2543Smrg * Software is furnished to do so, subject to the following conditions:
11706f2543Smrg *
12706f2543Smrg * The above copyright notice including the dates of first publication and
13706f2543Smrg * either this permission notice or a reference to
14706f2543Smrg * http://oss.sgi.com/projects/FreeB/
15706f2543Smrg * shall be included in all copies or substantial portions of the Software.
16706f2543Smrg *
17706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18706f2543Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20706f2543Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23706f2543Smrg * SOFTWARE.
24706f2543Smrg *
25706f2543Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26706f2543Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27706f2543Smrg * other dealings in this Software without prior written authorization from
28706f2543Smrg * Silicon Graphics, Inc.
29706f2543Smrg */
30706f2543Smrg
31706f2543Smrg#ifdef HAVE_DMX_CONFIG_H
32706f2543Smrg#include <dmx-config.h>
33706f2543Smrg#endif
34706f2543Smrg
35706f2543Smrg#include "dmx.h"
36706f2543Smrg#include "dmxwindow.h"
37706f2543Smrg#include "dmxpixmap.h"
38706f2543Smrg#include "dmxfont.h"
39706f2543Smrg#include "dmxsync.h"
40706f2543Smrg
41706f2543Smrg#include "glxserver.h"
42706f2543Smrg#include <GL/glxtokens.h>
43706f2543Smrg#include "g_disptab.h"
44706f2543Smrg#include <pixmapstr.h>
45706f2543Smrg#include <windowstr.h>
46706f2543Smrg#include "glxutil.h"
47706f2543Smrg#include "glxext.h"
48706f2543Smrg#include "unpack.h"
49706f2543Smrg
50706f2543Smrg#include "GL/glxproto.h"
51706f2543Smrg#include "glxvendor.h"
52706f2543Smrg#include "glxvisuals.h"
53706f2543Smrg#include "glxswap.h"
54706f2543Smrg
55706f2543Smrg#include "glxcmds.h"
56706f2543Smrg
57706f2543Smrg#ifdef PANORAMIX
58706f2543Smrg#include "panoramiXsrv.h"
59706f2543Smrg#endif
60706f2543Smrg
61706f2543Smrgextern __GLXFBConfig **__glXFBConfigs;
62706f2543Smrgextern int            __glXNumFBConfigs;
63706f2543Smrg
64706f2543Smrgextern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id );
65706f2543Smrgextern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid );
66706f2543Smrgextern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen );
67706f2543Smrgextern int glxIsExtensionSupported( char *ext );
68706f2543Smrgextern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
69706f2543Smrg
70706f2543Smrg#define BE_TO_CLIENT_ERROR(x) \
71706f2543Smrg           ( (x) >= __glXerrorBase ? \
72706f2543Smrg             (x) - dmxScreen->glxErrorBase + __glXerrorBase \
73706f2543Smrg	     : (x) )
74706f2543Smrg
75706f2543SmrgDisplay *GetBackEndDisplay( __GLXclientState *cl, int s )
76706f2543Smrg{
77706f2543Smrg   if (! cl->be_displays[s] ) {
78706f2543Smrg      cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) );
79706f2543Smrg   }
80706f2543Smrg   return cl->be_displays[s];
81706f2543Smrg}
82706f2543Smrg
83706f2543Smrg/*
84706f2543Smrg** Create a GL context with the given properties.
85706f2543Smrg*/
86706f2543Smrgstatic int CreateContext(__GLXclientState *cl,
87706f2543Smrg                         GLXContextID gcId,
88706f2543Smrg			 VisualID vid, GLXFBConfigID fbconfigId,
89706f2543Smrg			 int screen,
90706f2543Smrg			 GLXContextID shareList,
91706f2543Smrg			 int isDirect )
92706f2543Smrg{
93706f2543Smrg    ClientPtr client = cl->client;
94706f2543Smrg    xGLXCreateContextReq *be_req;
95706f2543Smrg    xGLXCreateNewContextReq *be_new_req;
96706f2543Smrg    VisualPtr pVisual;
97706f2543Smrg    ScreenPtr pScreen;
98706f2543Smrg    __GLXcontext *glxc, *shareglxc;
99706f2543Smrg    __GLXvisualConfig *pGlxVisual;
100706f2543Smrg    __GLXscreenInfo *pGlxScreen;
101706f2543Smrg    VisualID visual = vid;
102706f2543Smrg    GLint i;
103706f2543Smrg    int from_screen = screen;
104706f2543Smrg    int to_screen = screen;
105706f2543Smrg    DMXScreenInfo *dmxScreen;
106706f2543Smrg    VisualID be_vid = 0;
107706f2543Smrg    GLXFBConfigID be_fbconfigId = 0;
108706f2543Smrg    int num_be_screens;
109706f2543Smrg    Display *dpy;
110706f2543Smrg
111706f2543Smrg    /*
112706f2543Smrg    ** Check if screen exists.
113706f2543Smrg    */
114706f2543Smrg    if (screen >= screenInfo.numScreens) {
115706f2543Smrg	client->errorValue = screen;
116706f2543Smrg	return BadValue;
117706f2543Smrg    }
118706f2543Smrg
119706f2543Smrg
120706f2543Smrg#ifdef PANORAMIX
121706f2543Smrg    if (!noPanoramiXExtension) {
122706f2543Smrg       from_screen = 0;
123706f2543Smrg       to_screen = screenInfo.numScreens - 1;
124706f2543Smrg    }
125706f2543Smrg#endif
126706f2543Smrg
127706f2543Smrg    /*
128706f2543Smrg     ** Find the display list space that we want to share.
129706f2543Smrg     **
130706f2543Smrg     */
131706f2543Smrg    if (shareList == None) {
132706f2543Smrg       shareglxc = NULL;
133706f2543Smrg    } else {
134706f2543Smrg       dixLookupResourceByType((pointer*) &shareglxc, shareList,
135706f2543Smrg                               __glXContextRes, NullClient, DixUnknownAccess);
136706f2543Smrg       if (!shareglxc) {
137706f2543Smrg	  client->errorValue = shareList;
138706f2543Smrg	  return __glXBadContext;
139706f2543Smrg       }
140706f2543Smrg    }
141706f2543Smrg
142706f2543Smrg    /*
143706f2543Smrg    ** Allocate memory for the new context
144706f2543Smrg    */
145706f2543Smrg    glxc = calloc(1, sizeof(__GLXcontext));
146706f2543Smrg    if (!glxc) {
147706f2543Smrg	return BadAlloc;
148706f2543Smrg    }
149706f2543Smrg
150706f2543Smrg    pScreen = screenInfo.screens[screen];
151706f2543Smrg    pGlxScreen = &__glXActiveScreens[screen];
152706f2543Smrg
153706f2543Smrg    if (fbconfigId != None) {
154706f2543Smrg       glxc->pFBConfig = glxLookupFBConfig( fbconfigId );
155706f2543Smrg       if (!glxc->pFBConfig) {
156706f2543Smrg	  client->errorValue = fbconfigId;
157706f2543Smrg	  free( glxc );
158706f2543Smrg	  return BadValue;
159706f2543Smrg       }
160706f2543Smrg       visual = glxc->pFBConfig->associatedVisualId;
161706f2543Smrg    }
162706f2543Smrg    else {
163706f2543Smrg       glxc->pFBConfig = NULL;
164706f2543Smrg    }
165706f2543Smrg
166706f2543Smrg    if (visual != None) {
167706f2543Smrg       /*
168706f2543Smrg	** Check if the visual ID is valid for this screen.
169706f2543Smrg	*/
170706f2543Smrg       pVisual = pScreen->visuals;
171706f2543Smrg       for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
172706f2543Smrg	  if (pVisual->vid == visual) {
173706f2543Smrg	     break;
174706f2543Smrg	  }
175706f2543Smrg       }
176706f2543Smrg       if (i == pScreen->numVisuals) {
177706f2543Smrg	  client->errorValue = visual;
178706f2543Smrg	  free( glxc );
179706f2543Smrg	  return BadValue;
180706f2543Smrg       }
181706f2543Smrg
182706f2543Smrg       pGlxVisual = pGlxScreen->pGlxVisual;
183706f2543Smrg       for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
184706f2543Smrg	  if (pGlxVisual->vid == visual) {
185706f2543Smrg	     break;
186706f2543Smrg	  }
187706f2543Smrg       }
188706f2543Smrg       if (i == pGlxScreen->numVisuals) {
189706f2543Smrg	  /*
190706f2543Smrg	   ** Visual not support on this screen by this OpenGL implementation.
191706f2543Smrg	   */
192706f2543Smrg	  client->errorValue = visual;
193706f2543Smrg	  free( glxc );
194706f2543Smrg	  return BadValue;
195706f2543Smrg       }
196706f2543Smrg
197706f2543Smrg       if ( glxc->pFBConfig == NULL ) {
198706f2543Smrg	   glxc->pFBConfig = glxLookupFBConfigByVID( visual );
199706f2543Smrg
200706f2543Smrg	   if ( glxc->pFBConfig == NULL ) {
201706f2543Smrg	      /*
202706f2543Smrg               * visual does not have an FBConfig ???
203706f2543Smrg	      client->errorValue = visual;
204706f2543Smrg	      free( glxc );
205706f2543Smrg	      return BadValue;
206706f2543Smrg	       */
207706f2543Smrg	   }
208706f2543Smrg       }
209706f2543Smrg    }
210706f2543Smrg    else {
211706f2543Smrg       pVisual = NULL;
212706f2543Smrg       pGlxVisual = NULL;
213706f2543Smrg    }
214706f2543Smrg
215706f2543Smrg    glxc->pScreen = pScreen;
216706f2543Smrg    glxc->pGlxScreen = pGlxScreen;
217706f2543Smrg    glxc->pVisual = pVisual;
218706f2543Smrg    glxc->pGlxVisual = pGlxVisual;
219706f2543Smrg
220706f2543Smrg    /*
221706f2543Smrg     * allocate memory for back-end servers info
222706f2543Smrg     */
223706f2543Smrg    num_be_screens = to_screen - from_screen + 1;
224706f2543Smrg    glxc->real_ids = (XID *)malloc(sizeof(XID) * num_be_screens);
225706f2543Smrg    if (!glxc->real_ids) {
226706f2543Smrg	return BadAlloc;
227706f2543Smrg    }
228706f2543Smrg    glxc->real_vids = (XID *)malloc(sizeof(XID) * num_be_screens);
229706f2543Smrg    if (!glxc->real_vids) {
230706f2543Smrg	return BadAlloc;
231706f2543Smrg    }
232706f2543Smrg
233706f2543Smrg    for (screen = from_screen; screen <= to_screen; screen++) {
234706f2543Smrg       int sent = 0;
235706f2543Smrg       pScreen = screenInfo.screens[screen];
236706f2543Smrg       pGlxScreen = &__glXActiveScreens[screen];
237706f2543Smrg       dmxScreen = &dmxScreens[screen];
238706f2543Smrg
239706f2543Smrg       if (glxc->pFBConfig) {
240706f2543Smrg	  __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id,
241706f2543Smrg		                                                screen );
242706f2543Smrg	  be_fbconfigId = beFBConfig->id;
243706f2543Smrg       }
244706f2543Smrg
245706f2543Smrg       if (pGlxVisual) {
246706f2543Smrg
247706f2543Smrg	  be_vid = glxMatchGLXVisualInConfigList( pGlxVisual,
248706f2543Smrg	                                    dmxScreen->glxVisuals,
249706f2543Smrg					    dmxScreen->numGlxVisuals  );
250706f2543Smrg
251706f2543Smrg	  if (!be_vid) {
252706f2543Smrg	     /* visual is not supported on the back-end server */
253706f2543Smrg	     free( glxc->real_ids );
254706f2543Smrg	     free( glxc->real_vids );
255706f2543Smrg	     free( glxc );
256706f2543Smrg	     return BadValue;
257706f2543Smrg	  }
258706f2543Smrg       }
259706f2543Smrg
260706f2543Smrg       glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen));
261706f2543Smrg
262706f2543Smrg       /* send the create context request to the back-end server */
263706f2543Smrg       dpy = GetBackEndDisplay(cl,screen);
264706f2543Smrg       if (glxc->pFBConfig) {
265706f2543Smrg	     /*Since for a certain visual both RGB and COLOR INDEX
266706f2543Smrg	      *can be on then the only parmeter to choose the renderType
267706f2543Smrg	      * should be the class of the colormap since all 4 first
268706f2543Smrg	      * classes does not support RGB mode only COLOR INDEX ,
269706f2543Smrg	      * and so TrueColor and DirectColor does not support COLOR INDEX*/
270706f2543Smrg	     int renderType =  glxc->pFBConfig->renderType;
271706f2543Smrg	     if ( pVisual ) {
272706f2543Smrg		 switch ( pVisual->class ){
273706f2543Smrg		     case PseudoColor:
274706f2543Smrg                     case StaticColor:
275706f2543Smrg                     case GrayScale:
276706f2543Smrg                     case StaticGray:
277706f2543Smrg                         renderType = GLX_COLOR_INDEX_TYPE;
278706f2543Smrg                         break;
279706f2543Smrg                     case TrueColor:
280706f2543Smrg                     case DirectColor:
281706f2543Smrg                     default:
282706f2543Smrg                         renderType = GLX_RGBA_TYPE;
283706f2543Smrg                     break;
284706f2543Smrg		 }
285706f2543Smrg	     }
286706f2543Smrg	  if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
287706f2543Smrg	     LockDisplay(dpy);
288706f2543Smrg	     GetReq(GLXCreateNewContext,be_new_req);
289706f2543Smrg	     be_new_req->reqType = dmxScreen->glxMajorOpcode;
290706f2543Smrg	     be_new_req->glxCode = X_GLXCreateNewContext;
291706f2543Smrg	     be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
292706f2543Smrg	     be_new_req->fbconfig = (unsigned int)be_fbconfigId;
293706f2543Smrg	     be_new_req->screen = DefaultScreen(dpy);
294706f2543Smrg	     be_new_req->renderType = renderType;
295706f2543Smrg
296706f2543Smrg	     be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
297706f2543Smrg	     be_new_req->isDirect = 0;
298706f2543Smrg	     UnlockDisplay(dpy);
299706f2543Smrg	     glxc->real_vids[screen-from_screen] = be_fbconfigId;
300706f2543Smrg	     sent = 1;
301706f2543Smrg	  }
302706f2543Smrg	  else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
303706f2543Smrg
304706f2543Smrg	     xGLXCreateContextWithConfigSGIXReq *ext_req;
305706f2543Smrg	     xGLXVendorPrivateReq *vpreq;
306706f2543Smrg	     LockDisplay(dpy);
307706f2543Smrg	     GetReqExtra(GLXVendorPrivate,
308706f2543Smrg		         sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq,
309706f2543Smrg			vpreq);
310706f2543Smrg	     ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
311706f2543Smrg	     ext_req->reqType = dmxScreen->glxMajorOpcode;
312706f2543Smrg	     ext_req->glxCode = X_GLXVendorPrivate;
313706f2543Smrg	     ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
314706f2543Smrg	     ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
315706f2543Smrg	     ext_req->fbconfig = (unsigned int)be_fbconfigId;
316706f2543Smrg	     ext_req->screen = DefaultScreen(dpy);
317706f2543Smrg	     ext_req->renderType = renderType;
318706f2543Smrg	     ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
319706f2543Smrg	     ext_req->isDirect = 0;
320706f2543Smrg	     UnlockDisplay(dpy);
321706f2543Smrg	     glxc->real_vids[screen-from_screen] = be_fbconfigId;
322706f2543Smrg	     sent = 1;
323706f2543Smrg	  }
324706f2543Smrg       }
325706f2543Smrg
326706f2543Smrg       if (!sent) {
327706f2543Smrg	  LockDisplay(dpy);
328706f2543Smrg	  GetReq(GLXCreateContext,be_req);
329706f2543Smrg	  be_req->reqType = dmxScreen->glxMajorOpcode;
330706f2543Smrg	  be_req->glxCode = X_GLXCreateContext;
331706f2543Smrg	  be_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
332706f2543Smrg	  be_req->visual = (unsigned int)be_vid;
333706f2543Smrg	  be_req->screen = DefaultScreen(dpy);
334706f2543Smrg	  be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
335706f2543Smrg	  be_req->isDirect = 0;
336706f2543Smrg	  UnlockDisplay(dpy);
337706f2543Smrg	  glxc->real_vids[screen-from_screen] = be_vid;
338706f2543Smrg       }
339706f2543Smrg       SyncHandle();
340706f2543Smrg
341706f2543Smrg    }
342706f2543Smrg
343706f2543Smrg    /*
344706f2543Smrg    ** Register this context as a resource.
345706f2543Smrg    */
346706f2543Smrg    if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
347706f2543Smrg       free( glxc->real_ids );
348706f2543Smrg       free( glxc->real_vids );
349706f2543Smrg       free( glxc );
350706f2543Smrg	client->errorValue = gcId;
351706f2543Smrg	return BadAlloc;
352706f2543Smrg    }
353706f2543Smrg
354706f2543Smrg    /*
355706f2543Smrg    ** Finally, now that everything is working, setup the rest of the
356706f2543Smrg    ** context.
357706f2543Smrg    */
358706f2543Smrg    glxc->id = gcId;
359706f2543Smrg    glxc->share_id = shareList;
360706f2543Smrg    glxc->idExists = GL_TRUE;
361706f2543Smrg    glxc->isCurrent = GL_FALSE;
362706f2543Smrg
363706f2543Smrg    return Success;
364706f2543Smrg}
365706f2543Smrg
366706f2543Smrgint __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
367706f2543Smrg{
368706f2543Smrg    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
369706f2543Smrg
370706f2543Smrg    return( CreateContext(cl, req->context,req->visual, None,
371706f2543Smrg	                  req->screen, req->shareList, req->isDirect) );
372706f2543Smrg
373706f2543Smrg}
374706f2543Smrg
375706f2543Smrgint __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
376706f2543Smrg{
377706f2543Smrg    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
378706f2543Smrg
379706f2543Smrg    return( CreateContext(cl, req->context,None, req->fbconfig,
380706f2543Smrg	                  req->screen, req->shareList, req->isDirect) );
381706f2543Smrg
382706f2543Smrg}
383706f2543Smrg
384706f2543Smrgint __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
385706f2543Smrg{
386706f2543Smrg    xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
387706f2543Smrg
388706f2543Smrg    return( CreateContext(cl, req->context, None, req->fbconfig,
389706f2543Smrg	                  req->screen, req->shareList, req->isDirect) );
390706f2543Smrg
391706f2543Smrg}
392706f2543Smrg
393706f2543Smrgint __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
394706f2543Smrg{
395706f2543Smrg    ClientPtr client = cl->client;
396706f2543Smrg    xGLXQueryMaxSwapBarriersSGIXReq *req =
397706f2543Smrg	(xGLXQueryMaxSwapBarriersSGIXReq *)pc;
398706f2543Smrg    xGLXQueryMaxSwapBarriersSGIXReply reply;
399706f2543Smrg
400706f2543Smrg    reply.type = X_Reply;
401706f2543Smrg    reply.sequenceNumber = client->sequence;
402706f2543Smrg    reply.length = 0;
403706f2543Smrg    reply.max = QueryMaxSwapBarriersSGIX(req->screen);
404706f2543Smrg
405706f2543Smrg    if (client->swapped) {
406706f2543Smrg	__glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
407706f2543Smrg    } else {
408706f2543Smrg	WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
409706f2543Smrg		      (char *)&reply);
410706f2543Smrg    }
411706f2543Smrg
412706f2543Smrg    return Success;
413706f2543Smrg}
414706f2543Smrg
415706f2543Smrgint __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
416706f2543Smrg{
417706f2543Smrg    ClientPtr client = cl->client;
418706f2543Smrg    xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
419706f2543Smrg    DrawablePtr pDraw;
420706f2543Smrg    __GLXpixmap *pGlxPixmap = NULL;
421706f2543Smrg    __glXWindow *pGlxWindow = NULL;
422706f2543Smrg    int rc;
423706f2543Smrg
424706f2543Smrg    rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess);
425706f2543Smrg    if (rc != Success) {
426706f2543Smrg	dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable,
427706f2543Smrg				__glXPixmapRes, NullClient, DixUnknownAccess);
428706f2543Smrg	if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
429706f2543Smrg    }
430706f2543Smrg
431706f2543Smrg    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
432706f2543Smrg       dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable,
433706f2543Smrg                               __glXWindowRes, NullClient, DixUnknownAccess);
434706f2543Smrg       if (pGlxWindow) pDraw = pGlxWindow->pDraw;
435706f2543Smrg    }
436706f2543Smrg
437706f2543Smrg    if (!pDraw) {
438706f2543Smrg       client->errorValue = req->drawable;
439706f2543Smrg       return __glXBadDrawable;
440706f2543Smrg    }
441706f2543Smrg
442706f2543Smrg    return BindSwapBarrierSGIX(pDraw, req->barrier);
443706f2543Smrg}
444706f2543Smrg
445706f2543Smrgint __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
446706f2543Smrg{
447706f2543Smrg    ClientPtr client = cl->client;
448706f2543Smrg    xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
449706f2543Smrg    DrawablePtr pDraw, pMember = NULL;
450706f2543Smrg    __GLXpixmap *pGlxPixmap = NULL;
451706f2543Smrg    __glXWindow *pGlxWindow = NULL;
452706f2543Smrg    int rc;
453706f2543Smrg
454706f2543Smrg    rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess);
455706f2543Smrg    if (rc != Success) {
456706f2543Smrg	dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable,
457706f2543Smrg				__glXPixmapRes, NullClient, DixUnknownAccess);
458706f2543Smrg	if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
459706f2543Smrg    }
460706f2543Smrg
461706f2543Smrg    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
462706f2543Smrg       dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable,
463706f2543Smrg                               __glXWindowRes, NullClient, DixUnknownAccess);
464706f2543Smrg       if (pGlxWindow) pDraw = pGlxWindow->pDraw;
465706f2543Smrg    }
466706f2543Smrg
467706f2543Smrg    if (!pDraw) {
468706f2543Smrg       client->errorValue = req->drawable;
469706f2543Smrg       return __glXBadDrawable;
470706f2543Smrg    }
471706f2543Smrg
472706f2543Smrg    if (req->member != None) {
473706f2543Smrg	rc = dixLookupDrawable(&pMember, req->member, client, 0,
474706f2543Smrg			       DixGetAttrAccess);
475706f2543Smrg	if (rc != Success) {
476706f2543Smrg	    dixLookupResourceByType((pointer*) &pGlxPixmap, req->member,
477706f2543Smrg                                    __glXPixmapRes, NullClient,
478706f2543Smrg                                    DixUnknownAccess);
479706f2543Smrg	    if (pGlxPixmap) pMember = pGlxPixmap->pDraw;
480706f2543Smrg	}
481706f2543Smrg
482706f2543Smrg	if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
483706f2543Smrg	    dixLookupResourceByType((pointer*) &pGlxWindow, req->member,
484706f2543Smrg                                    __glXWindowRes, NullClient,
485706f2543Smrg                                    DixUnknownAccess);
486706f2543Smrg	    if (pGlxWindow) pMember = pGlxWindow->pDraw;
487706f2543Smrg	}
488706f2543Smrg
489706f2543Smrg	if (!pMember) {
490706f2543Smrg	    client->errorValue = req->member;
491706f2543Smrg	    return __glXBadDrawable;
492706f2543Smrg	}
493706f2543Smrg    }
494706f2543Smrg
495706f2543Smrg    return JoinSwapGroupSGIX(pDraw, pMember);
496706f2543Smrg}
497706f2543Smrg
498706f2543Smrg
499706f2543Smrg/*
500706f2543Smrg** Destroy a GL context as an X resource.
501706f2543Smrg*/
502706f2543Smrgint __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
503706f2543Smrg{
504706f2543Smrg    ClientPtr client = cl->client;
505706f2543Smrg    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
506706f2543Smrg    xGLXDestroyContextReq *be_req;
507706f2543Smrg    GLXContextID gcId = req->context;
508706f2543Smrg    __GLXcontext *glxc;
509706f2543Smrg    int from_screen = 0;
510706f2543Smrg    int to_screen = 0;
511706f2543Smrg    int s;
512706f2543Smrg
513706f2543Smrg    dixLookupResourceByType((pointer*) &glxc, gcId, __glXContextRes,
514706f2543Smrg			    NullClient, DixUnknownAccess);
515706f2543Smrg    if (glxc) {
516706f2543Smrg	/*
517706f2543Smrg	** Just free the resource; don't actually destroy the context,
518706f2543Smrg	** because it might be in use.  The
519706f2543Smrg	** destroy method will be called by the resource destruction routine
520706f2543Smrg	** if necessary.
521706f2543Smrg	*/
522706f2543Smrg	FreeResourceByType(gcId, __glXContextRes, FALSE);
523706f2543Smrg
524706f2543Smrg	from_screen = to_screen = glxc->pScreen->myNum;
525706f2543Smrg
526706f2543Smrg    } else {
527706f2543Smrg	client->errorValue = gcId;
528706f2543Smrg	return __glXBadContext;
529706f2543Smrg    }
530706f2543Smrg
531706f2543Smrg#ifdef PANORAMIX
532706f2543Smrg    if (!noPanoramiXExtension) {
533706f2543Smrg       from_screen = 0;
534706f2543Smrg       to_screen = screenInfo.numScreens - 1;
535706f2543Smrg    }
536706f2543Smrg#endif
537706f2543Smrg
538706f2543Smrg    /*
539706f2543Smrg     * send DestroyContext request to all back-end servers
540706f2543Smrg     */
541706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
542706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
543706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
544706f2543Smrg
545706f2543Smrg       LockDisplay(dpy);
546706f2543Smrg       GetReq(GLXDestroyContext,be_req);
547706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
548706f2543Smrg       be_req->glxCode = X_GLXDestroyContext;
549706f2543Smrg       be_req->context = glxc->real_ids[s-from_screen];
550706f2543Smrg       UnlockDisplay(dpy);
551706f2543Smrg       SyncHandle();
552706f2543Smrg    }
553706f2543Smrg
554706f2543Smrg    return Success;
555706f2543Smrg}
556706f2543Smrg
557706f2543Smrg/*****************************************************************************/
558706f2543Smrg
559706f2543Smrg/*
560706f2543Smrg** For each client, the server keeps a table of all the contexts that are
561706f2543Smrg** current for that client (each thread of a client may have its own current
562706f2543Smrg** context).  These routines add, change, and lookup contexts in the table.
563706f2543Smrg*/
564706f2543Smrg
565706f2543Smrg/*
566706f2543Smrg** Add a current context, and return the tag that will be used to refer to it.
567706f2543Smrg*/
568706f2543Smrgstatic int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw)
569706f2543Smrg{
570706f2543Smrg    int i;
571706f2543Smrg    int num = cl->numCurrentContexts;
572706f2543Smrg    __GLXcontext **table = cl->currentContexts;
573706f2543Smrg
574706f2543Smrg    if (!glxc) return -1;
575706f2543Smrg
576706f2543Smrg    /*
577706f2543Smrg    ** Try to find an empty slot and use it.
578706f2543Smrg    */
579706f2543Smrg    for (i=0; i < num; i++) {
580706f2543Smrg	if (!table[i]) {
581706f2543Smrg	    table[i] = glxc;
582706f2543Smrg	    return i+1;
583706f2543Smrg	}
584706f2543Smrg    }
585706f2543Smrg    /*
586706f2543Smrg    ** Didn't find a free slot, so we'll have to grow the table.
587706f2543Smrg    */
588706f2543Smrg    if (!num) {
589706f2543Smrg	table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
590706f2543Smrg	cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr));
591706f2543Smrg	cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens *sizeof(GLXContextTag));
592706f2543Smrg    } else {
593706f2543Smrg	table = (__GLXcontext **) realloc(table,
594706f2543Smrg					   (num+1)*sizeof(__GLXcontext *));
595706f2543Smrg	cl->currentDrawables = (DrawablePtr *) realloc(
596706f2543Smrg	                                          cl->currentDrawables ,
597706f2543Smrg						  (num+1)*sizeof(DrawablePtr));
598706f2543Smrg	cl->be_currentCTag = (GLXContextTag *) realloc(cl->be_currentCTag,
599706f2543Smrg	            (num+1)*screenInfo.numScreens*sizeof(GLXContextTag));
600706f2543Smrg    }
601706f2543Smrg    table[num] = glxc;
602706f2543Smrg    cl->currentDrawables[num] = pDraw;
603706f2543Smrg    cl->currentContexts = table;
604706f2543Smrg    cl->numCurrentContexts++;
605706f2543Smrg
606706f2543Smrg    memset(cl->be_currentCTag + num*screenInfo.numScreens, 0,
607706f2543Smrg	         screenInfo.numScreens * sizeof(GLXContextTag));
608706f2543Smrg
609706f2543Smrg    return num+1;
610706f2543Smrg}
611706f2543Smrg
612706f2543Smrg/*
613706f2543Smrg** Given a tag, change the current context for the corresponding entry.
614706f2543Smrg*/
615706f2543Smrgstatic void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
616706f2543Smrg				GLXContextTag tag)
617706f2543Smrg{
618706f2543Smrg    __GLXcontext **table = cl->currentContexts;
619706f2543Smrg    table[tag-1] = glxc;
620706f2543Smrg}
621706f2543Smrg
622706f2543Smrg/*
623706f2543Smrg** Given a tag, and back-end screen number, retrives the current back-end
624706f2543Smrg** tag.
625706f2543Smrg*/
626706f2543Smrgint GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s)
627706f2543Smrg{
628706f2543Smrg   if (tag >0) {
629706f2543Smrg      return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] );
630706f2543Smrg   }
631706f2543Smrg   else {
632706f2543Smrg      return 0;
633706f2543Smrg   }
634706f2543Smrg}
635706f2543Smrg
636706f2543Smrg/*
637706f2543Smrg** Given a tag, and back-end screen number, sets the current back-end
638706f2543Smrg** tag.
639706f2543Smrg*/
640706f2543Smrgstatic void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag)
641706f2543Smrg{
642706f2543Smrg   if (tag >0) {
643706f2543Smrg      cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag;
644706f2543Smrg   }
645706f2543Smrg}
646706f2543Smrg
647706f2543Smrg/*
648706f2543Smrg** For this implementation we have chosen to simply use the index of the
649706f2543Smrg** context's entry in the table as the context tag.  A tag must be greater
650706f2543Smrg** than 0.
651706f2543Smrg*/
652706f2543Smrg__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
653706f2543Smrg{
654706f2543Smrg    int num = cl->numCurrentContexts;
655706f2543Smrg
656706f2543Smrg    if (tag < 1 || tag > num) {
657706f2543Smrg	return 0;
658706f2543Smrg    } else {
659706f2543Smrg	return cl->currentContexts[tag-1];
660706f2543Smrg    }
661706f2543Smrg}
662706f2543Smrg
663706f2543SmrgDrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag)
664706f2543Smrg{
665706f2543Smrg    int num = cl->numCurrentContexts;
666706f2543Smrg
667706f2543Smrg    if (tag < 1 || tag > num) {
668706f2543Smrg	return 0;
669706f2543Smrg    } else {
670706f2543Smrg	return cl->currentDrawables[tag-1];
671706f2543Smrg    }
672706f2543Smrg}
673706f2543Smrg
674706f2543Smrg/*****************************************************************************/
675706f2543Smrg
676706f2543Smrgstatic void StopUsingContext(__GLXcontext *glxc)
677706f2543Smrg{
678706f2543Smrg    if (glxc) {
679706f2543Smrg	if (glxc == __glXLastContext) {
680706f2543Smrg	    /* Tell server GL library */
681706f2543Smrg	    __glXLastContext = 0;
682706f2543Smrg	}
683706f2543Smrg	glxc->isCurrent = GL_FALSE;
684706f2543Smrg	if (!glxc->idExists) {
685706f2543Smrg	    __glXFreeContext(glxc);
686706f2543Smrg	}
687706f2543Smrg    }
688706f2543Smrg}
689706f2543Smrg
690706f2543Smrgstatic void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
691706f2543Smrg{
692706f2543Smrg    glxc->isCurrent = GL_TRUE;
693706f2543Smrg}
694706f2543Smrg
695706f2543Smrg/*****************************************************************************/
696706f2543Smrg/*
697706f2543Smrg** Make an OpenGL context and drawable current.
698706f2543Smrg*/
699706f2543Smrgstatic int MakeCurrent(__GLXclientState *cl,
700706f2543Smrg                       GLXDrawable drawable,
701706f2543Smrg                       GLXDrawable readdrawable,
702706f2543Smrg		       GLXContextID context,
703706f2543Smrg		       GLXContextTag oldContextTag)
704706f2543Smrg{
705706f2543Smrg    ClientPtr client = cl->client;
706706f2543Smrg    DrawablePtr pDraw = NULL;
707706f2543Smrg    DrawablePtr pReadDraw = NULL;
708706f2543Smrg    xGLXMakeCurrentReadSGIReply new_reply;
709706f2543Smrg    xGLXMakeCurrentReq *be_req;
710706f2543Smrg    xGLXMakeCurrentReply be_reply;
711706f2543Smrg    xGLXMakeContextCurrentReq *be_new_req;
712706f2543Smrg    xGLXMakeContextCurrentReply be_new_reply;
713706f2543Smrg    GLXDrawable drawId = drawable;
714706f2543Smrg    GLXDrawable readId = readdrawable;
715706f2543Smrg    GLXContextID contextId = context;
716706f2543Smrg    __GLXpixmap *pGlxPixmap = 0;
717706f2543Smrg    __GLXpixmap *pReadGlxPixmap = 0;
718706f2543Smrg    __GLXcontext *glxc, *prevglxc;
719706f2543Smrg    GLXContextTag tag = oldContextTag;
720706f2543Smrg    WindowPtr pWin = NULL;
721706f2543Smrg    WindowPtr pReadWin = NULL;
722706f2543Smrg    __glXWindow *pGlxWindow = NULL;
723706f2543Smrg    __glXWindow *pGlxReadWindow = NULL;
724706f2543Smrg    __glXPbuffer *pGlxPbuffer = NULL;
725706f2543Smrg    __glXPbuffer *pGlxReadPbuffer = NULL;
726706f2543Smrg#ifdef PANORAMIX
727706f2543Smrg    PanoramiXRes *pXinDraw = NULL;
728706f2543Smrg    PanoramiXRes *pXinReadDraw = NULL;
729706f2543Smrg#endif
730706f2543Smrg    int from_screen = 0;
731706f2543Smrg    int to_screen = 0;
732706f2543Smrg    int s, rc;
733706f2543Smrg
734706f2543Smrg    /*
735706f2543Smrg    ** If one is None and the other isn't, it's a bad match.
736706f2543Smrg    */
737706f2543Smrg    if ((drawId == None && contextId != None) ||
738706f2543Smrg	(drawId != None && contextId == None)) {
739706f2543Smrg	return BadMatch;
740706f2543Smrg    }
741706f2543Smrg
742706f2543Smrg    /*
743706f2543Smrg    ** Lookup old context.  If we have one, it must be in a usable state.
744706f2543Smrg    */
745706f2543Smrg    if (tag != 0) {
746706f2543Smrg	prevglxc = __glXLookupContextByTag(cl, tag);
747706f2543Smrg	if (!prevglxc) {
748706f2543Smrg	    /*
749706f2543Smrg	    ** Tag for previous context is invalid.
750706f2543Smrg	    */
751706f2543Smrg	    return __glXBadContextTag;
752706f2543Smrg	}
753706f2543Smrg    } else {
754706f2543Smrg	prevglxc = 0;
755706f2543Smrg    }
756706f2543Smrg
757706f2543Smrg    /*
758706f2543Smrg    ** Lookup new context.  It must not be current for someone else.
759706f2543Smrg    */
760706f2543Smrg    if (contextId != None) {
761706f2543Smrg	dixLookupResourceByType((pointer*) &glxc, contextId, __glXContextRes,
762706f2543Smrg				NullClient, DixUnknownAccess);
763706f2543Smrg	if (!glxc) {
764706f2543Smrg	    client->errorValue = contextId;
765706f2543Smrg	    return __glXBadContext;
766706f2543Smrg	}
767706f2543Smrg	if ((glxc != prevglxc) && glxc->isCurrent) {
768706f2543Smrg	    /* Context is current to somebody else */
769706f2543Smrg	    return BadAccess;
770706f2543Smrg	}
771706f2543Smrg    } else {
772706f2543Smrg	/* Switching to no context.  Ignore new drawable. */
773706f2543Smrg	glxc = 0;
774706f2543Smrg    }
775706f2543Smrg
776706f2543Smrg    if (drawId != None) {
777706f2543Smrg	rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
778706f2543Smrg	if (rc == Success) {
779706f2543Smrg	    if (pDraw->type == DRAWABLE_WINDOW) {
780706f2543Smrg		/*
781706f2543Smrg		** Drawable is an X Window.
782706f2543Smrg		*/
783706f2543Smrg	        VisualID vid;
784706f2543Smrg		pWin = (WindowPtr)pDraw;
785706f2543Smrg		vid = wVisual(pWin);
786706f2543Smrg
787706f2543Smrg		new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
788706f2543Smrg		new_reply.writeType = GLX_WINDOW_TYPE;
789706f2543Smrg
790706f2543Smrg		/*
791706f2543Smrg		** Check if window and context are similar.
792706f2543Smrg		*/
793706f2543Smrg		if ((vid != glxc->pVisual->vid) ||
794706f2543Smrg		    (pWin->drawable.pScreen != glxc->pScreen)) {
795706f2543Smrg		    client->errorValue = drawId;
796706f2543Smrg		    return BadMatch;
797706f2543Smrg		}
798706f2543Smrg
799706f2543Smrg		from_screen = to_screen = pWin->drawable.pScreen->myNum;
800706f2543Smrg
801706f2543Smrg	    } else {
802706f2543Smrg		/*
803706f2543Smrg		** An X Pixmap is not allowed as a parameter (a GLX Pixmap
804706f2543Smrg		** is, but it must first be created with glxCreateGLXPixmap).
805706f2543Smrg		*/
806706f2543Smrg		client->errorValue = drawId;
807706f2543Smrg		return __glXBadDrawable;
808706f2543Smrg	    }
809706f2543Smrg	}
810706f2543Smrg
811706f2543Smrg        if (!pDraw) {
812706f2543Smrg	    dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
813706f2543Smrg				    __glXPixmapRes, NullClient,
814706f2543Smrg				    DixUnknownAccess);
815706f2543Smrg	    if (pGlxPixmap) {
816706f2543Smrg		/*
817706f2543Smrg		** Check if pixmap and context are similar.
818706f2543Smrg		*/
819706f2543Smrg		if (pGlxPixmap->pScreen != glxc->pScreen ||
820706f2543Smrg		    pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
821706f2543Smrg		    client->errorValue = drawId;
822706f2543Smrg		    return BadMatch;
823706f2543Smrg		}
824706f2543Smrg		pDraw = pGlxPixmap->pDraw;
825706f2543Smrg
826706f2543Smrg		new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
827706f2543Smrg		                      pGlxPixmap->pGlxVisual->vid);
828706f2543Smrg
829706f2543Smrg		new_reply.writeType = GLX_PIXMAP_TYPE;
830706f2543Smrg
831706f2543Smrg		from_screen = to_screen = pGlxPixmap->pScreen->myNum;
832706f2543Smrg
833706f2543Smrg	    }
834706f2543Smrg	}
835706f2543Smrg
836706f2543Smrg	if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
837706f2543Smrg	   dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
838706f2543Smrg                                   __glXWindowRes, NullClient,
839706f2543Smrg                                   DixUnknownAccess);
840706f2543Smrg            if (pGlxWindow) {
841706f2543Smrg                /*
842706f2543Smrg                ** Drawable is a GLXWindow.
843706f2543Smrg                **
844706f2543Smrg                ** Check if GLX window and context are similar.
845706f2543Smrg                */
846706f2543Smrg                if (pGlxWindow->pScreen != glxc->pScreen ||
847706f2543Smrg                    pGlxWindow->pGlxFBConfig != glxc->pFBConfig) {
848706f2543Smrg                    client->errorValue = drawId;
849706f2543Smrg                    return BadMatch;
850706f2543Smrg                }
851706f2543Smrg
852706f2543Smrg                pDraw = pGlxWindow->pDraw;
853706f2543Smrg                new_reply.writeVid = pGlxWindow->pGlxFBConfig->id;
854706f2543Smrg                new_reply.writeType = GLX_GLXWINDOW_TYPE;
855706f2543Smrg            }
856706f2543Smrg
857706f2543Smrg	}
858706f2543Smrg
859706f2543Smrg	if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
860706f2543Smrg	   dixLookupResourceByType((pointer*) &pGlxPbuffer, drawId,
861706f2543Smrg                                   __glXPbufferRes, NullClient,
862706f2543Smrg                                   DixUnknownAccess);
863706f2543Smrg	   if (pGlxPbuffer) {
864706f2543Smrg                if (pGlxPbuffer->pScreen != glxc->pScreen ||
865706f2543Smrg                    pGlxPbuffer->pFBConfig != glxc->pFBConfig) {
866706f2543Smrg                    client->errorValue = drawId;
867706f2543Smrg                    return BadMatch;
868706f2543Smrg                }
869706f2543Smrg
870706f2543Smrg		pDraw = (DrawablePtr)pGlxPbuffer;
871706f2543Smrg                new_reply.writeVid = pGlxPbuffer->pFBConfig->id;
872706f2543Smrg                new_reply.writeType = GLX_PBUFFER_TYPE;
873706f2543Smrg	   }
874706f2543Smrg	}
875706f2543Smrg
876706f2543Smrg	if (!pDraw) {
877706f2543Smrg	   /*
878706f2543Smrg    	    ** Drawable is not a Window , GLXWindow or a GLXPixmap.
879706f2543Smrg	    */
880706f2543Smrg	   client->errorValue = drawId;
881706f2543Smrg	   return __glXBadDrawable;
882706f2543Smrg	}
883706f2543Smrg
884706f2543Smrg    } else {
885706f2543Smrg	pDraw = 0;
886706f2543Smrg    }
887706f2543Smrg
888706f2543Smrg    if (readId != None && readId != drawId ) {
889706f2543Smrg	rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess);
890706f2543Smrg	if (rc == Success) {
891706f2543Smrg	    if (pReadDraw->type == DRAWABLE_WINDOW) {
892706f2543Smrg		/*
893706f2543Smrg		** Drawable is an X Window.
894706f2543Smrg		*/
895706f2543Smrg	        VisualID vid;
896706f2543Smrg		pReadWin = (WindowPtr)pDraw;
897706f2543Smrg		vid = wVisual(pReadWin);
898706f2543Smrg
899706f2543Smrg		new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
900706f2543Smrg		new_reply.readType = GLX_WINDOW_TYPE;
901706f2543Smrg
902706f2543Smrg		/*
903706f2543Smrg		** Check if window and context are similar.
904706f2543Smrg		*/
905706f2543Smrg		if ((vid != glxc->pVisual->vid) ||
906706f2543Smrg		    (pReadWin->drawable.pScreen != glxc->pScreen)) {
907706f2543Smrg		    client->errorValue = readId;
908706f2543Smrg		    return BadMatch;
909706f2543Smrg		}
910706f2543Smrg
911706f2543Smrg	    } else {
912706f2543Smrg
913706f2543Smrg		/*
914706f2543Smrg		** An X Pixmap is not allowed as a parameter (a GLX Pixmap
915706f2543Smrg		** is, but it must first be created with glxCreateGLXPixmap).
916706f2543Smrg		*/
917706f2543Smrg		client->errorValue = readId;
918706f2543Smrg		return __glXBadDrawable;
919706f2543Smrg	    }
920706f2543Smrg	}
921706f2543Smrg
922706f2543Smrg	if (!pReadDraw) {
923706f2543Smrg	    dixLookupResourceByType((pointer*) &pReadGlxPixmap, readId,
924706f2543Smrg				    __glXPixmapRes, NullClient,
925706f2543Smrg				    DixUnknownAccess);
926706f2543Smrg	    if (pReadGlxPixmap) {
927706f2543Smrg		/*
928706f2543Smrg		** Check if pixmap and context are similar.
929706f2543Smrg		*/
930706f2543Smrg		if (pReadGlxPixmap->pScreen != glxc->pScreen ||
931706f2543Smrg		    pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
932706f2543Smrg		    client->errorValue = readId;
933706f2543Smrg		    return BadMatch;
934706f2543Smrg		}
935706f2543Smrg		pReadDraw = pReadGlxPixmap->pDraw;
936706f2543Smrg
937706f2543Smrg		new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
938706f2543Smrg		                     pReadGlxPixmap->pGlxVisual->vid );
939706f2543Smrg		new_reply.readType = GLX_PIXMAP_TYPE;
940706f2543Smrg
941706f2543Smrg	    }
942706f2543Smrg	}
943706f2543Smrg
944706f2543Smrg	if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
945706f2543Smrg	   dixLookupResourceByType((pointer*) &pGlxReadWindow, readId,
946706f2543Smrg                                   __glXWindowRes, NullClient,
947706f2543Smrg                                   DixUnknownAccess);
948706f2543Smrg            if (pGlxReadWindow) {
949706f2543Smrg                /*
950706f2543Smrg                ** Drawable is a GLXWindow.
951706f2543Smrg                **
952706f2543Smrg                ** Check if GLX window and context are similar.
953706f2543Smrg                */
954706f2543Smrg                if (pGlxReadWindow->pScreen != glxc->pScreen ||
955706f2543Smrg                    pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) {
956706f2543Smrg                    client->errorValue = readId;
957706f2543Smrg                    return BadMatch;
958706f2543Smrg                }
959706f2543Smrg
960706f2543Smrg                pReadDraw = pGlxReadWindow->pDraw;
961706f2543Smrg                new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id;
962706f2543Smrg                new_reply.readType = GLX_GLXWINDOW_TYPE;
963706f2543Smrg            }
964706f2543Smrg	}
965706f2543Smrg
966706f2543Smrg	if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
967706f2543Smrg	   dixLookupResourceByType((pointer*) &pGlxReadPbuffer, readId,
968706f2543Smrg                                   __glXPbufferRes, NullClient,
969706f2543Smrg                                   DixUnknownAccess);
970706f2543Smrg	   if (pGlxReadPbuffer) {
971706f2543Smrg                if (pGlxReadPbuffer->pScreen != glxc->pScreen ||
972706f2543Smrg                    pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) {
973706f2543Smrg                    client->errorValue = drawId;
974706f2543Smrg                    return BadMatch;
975706f2543Smrg                }
976706f2543Smrg
977706f2543Smrg		pReadDraw = (DrawablePtr)pGlxReadPbuffer;
978706f2543Smrg                new_reply.readVid = pGlxReadPbuffer->pFBConfig->id;
979706f2543Smrg                new_reply.readType = GLX_PBUFFER_TYPE;
980706f2543Smrg	   }
981706f2543Smrg	}
982706f2543Smrg
983706f2543Smrg	if (!pReadDraw) {
984706f2543Smrg	   /*
985706f2543Smrg    	    ** Drawable is neither a Window nor a GLXPixmap.
986706f2543Smrg	    */
987706f2543Smrg	   client->errorValue = readId;
988706f2543Smrg	   return __glXBadDrawable;
989706f2543Smrg	}
990706f2543Smrg
991706f2543Smrg    } else {
992706f2543Smrg	pReadDraw = pDraw;
993706f2543Smrg	pReadGlxPixmap = pGlxPixmap;
994706f2543Smrg	pReadWin = pWin;
995706f2543Smrg	new_reply.readVid = new_reply.writeVid;
996706f2543Smrg	new_reply.readType = new_reply.writeType;
997706f2543Smrg    }
998706f2543Smrg
999706f2543Smrg    if (prevglxc) {
1000706f2543Smrg
1001706f2543Smrg	if (prevglxc->pGlxPixmap) {
1002706f2543Smrg	    /*
1003706f2543Smrg	    ** The previous drawable was a glx pixmap, release it.
1004706f2543Smrg	    */
1005706f2543Smrg	    prevglxc->pGlxPixmap->refcnt--;
1006706f2543Smrg	    __glXFreeGLXPixmap( prevglxc->pGlxPixmap );
1007706f2543Smrg	    prevglxc->pGlxPixmap = 0;
1008706f2543Smrg	}
1009706f2543Smrg
1010706f2543Smrg	if (prevglxc->pGlxReadPixmap) {
1011706f2543Smrg	    /*
1012706f2543Smrg	    ** The previous drawable was a glx pixmap, release it.
1013706f2543Smrg	    */
1014706f2543Smrg	    prevglxc->pGlxReadPixmap->refcnt--;
1015706f2543Smrg	    __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap );
1016706f2543Smrg	    prevglxc->pGlxReadPixmap = 0;
1017706f2543Smrg	}
1018706f2543Smrg
1019706f2543Smrg	if (prevglxc->pGlxWindow) {
1020706f2543Smrg	    /*
1021706f2543Smrg	    ** The previous drawable was a glx window, release it.
1022706f2543Smrg	    */
1023706f2543Smrg	    prevglxc->pGlxWindow->refcnt--;
1024706f2543Smrg	    __glXFreeGLXWindow( prevglxc->pGlxWindow );
1025706f2543Smrg	    prevglxc->pGlxWindow = 0;
1026706f2543Smrg	}
1027706f2543Smrg
1028706f2543Smrg	if (prevglxc->pGlxReadWindow) {
1029706f2543Smrg	    /*
1030706f2543Smrg	    ** The previous drawable was a glx window, release it.
1031706f2543Smrg	    */
1032706f2543Smrg	    prevglxc->pGlxReadWindow->refcnt--;
1033706f2543Smrg	    __glXFreeGLXWindow( prevglxc->pGlxReadWindow );
1034706f2543Smrg	    prevglxc->pGlxReadWindow = 0;
1035706f2543Smrg	}
1036706f2543Smrg
1037706f2543Smrg	if (prevglxc->pGlxPbuffer) {
1038706f2543Smrg	    /*
1039706f2543Smrg	    ** The previous drawable was a glx Pbuffer, release it.
1040706f2543Smrg	    */
1041706f2543Smrg	    prevglxc->pGlxPbuffer->refcnt--;
1042706f2543Smrg	    __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer );
1043706f2543Smrg	    prevglxc->pGlxPbuffer = 0;
1044706f2543Smrg	}
1045706f2543Smrg
1046706f2543Smrg	if (prevglxc->pGlxReadPbuffer) {
1047706f2543Smrg	    /*
1048706f2543Smrg	    ** The previous drawable was a glx Pbuffer, release it.
1049706f2543Smrg	    */
1050706f2543Smrg	    prevglxc->pGlxReadPbuffer->refcnt--;
1051706f2543Smrg	    __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer );
1052706f2543Smrg	    prevglxc->pGlxReadPbuffer = 0;
1053706f2543Smrg	}
1054706f2543Smrg
1055706f2543Smrg	ChangeCurrentContext(cl, glxc, tag);
1056706f2543Smrg	ChangeCurrentContext(cl, glxc, tag);
1057706f2543Smrg	StopUsingContext(prevglxc);
1058706f2543Smrg    } else {
1059706f2543Smrg	tag = AddCurrentContext(cl, glxc, pDraw);
1060706f2543Smrg    }
1061706f2543Smrg    if (glxc) {
1062706f2543Smrg
1063706f2543Smrg       glxc->pGlxPixmap = pGlxPixmap;
1064706f2543Smrg       glxc->pGlxReadPixmap = pReadGlxPixmap;
1065706f2543Smrg       glxc->pGlxWindow = pGlxWindow;
1066706f2543Smrg       glxc->pGlxReadWindow = pGlxReadWindow;
1067706f2543Smrg       glxc->pGlxPbuffer = pGlxPbuffer;
1068706f2543Smrg       glxc->pGlxReadPbuffer = pGlxReadPbuffer;
1069706f2543Smrg
1070706f2543Smrg	if (pGlxPixmap) {
1071706f2543Smrg	    pGlxPixmap->refcnt++;
1072706f2543Smrg	}
1073706f2543Smrg
1074706f2543Smrg	if (pReadGlxPixmap) {
1075706f2543Smrg	    pReadGlxPixmap->refcnt++;
1076706f2543Smrg	}
1077706f2543Smrg
1078706f2543Smrg	if (pGlxWindow) {
1079706f2543Smrg	   pGlxWindow->refcnt++;
1080706f2543Smrg	}
1081706f2543Smrg
1082706f2543Smrg	if (pGlxReadWindow) {
1083706f2543Smrg	   pGlxReadWindow->refcnt++;
1084706f2543Smrg	}
1085706f2543Smrg
1086706f2543Smrg	if (pGlxPbuffer) {
1087706f2543Smrg	   pGlxPbuffer->refcnt++;
1088706f2543Smrg	}
1089706f2543Smrg
1090706f2543Smrg	if (pGlxReadPbuffer) {
1091706f2543Smrg	   pGlxReadPbuffer->refcnt++;
1092706f2543Smrg	}
1093706f2543Smrg
1094706f2543Smrg	StartUsingContext(cl, glxc);
1095706f2543Smrg	new_reply.contextTag = tag;
1096706f2543Smrg    } else {
1097706f2543Smrg	new_reply.contextTag = 0;
1098706f2543Smrg    }
1099706f2543Smrg    new_reply.length = 0;
1100706f2543Smrg    new_reply.type = X_Reply;
1101706f2543Smrg    new_reply.sequenceNumber = client->sequence;
1102706f2543Smrg
1103706f2543Smrg#ifdef PANORAMIX
1104706f2543Smrg    if (!noPanoramiXExtension) {
1105706f2543Smrg       from_screen = 0;
1106706f2543Smrg       to_screen = screenInfo.numScreens - 1;
1107706f2543Smrg
1108706f2543Smrg       if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
1109706f2543Smrg	  dixLookupResourceByClass((pointer*) &pXinDraw,
1110706f2543Smrg				   pDraw->id, XRC_DRAWABLE,
1111706f2543Smrg				   client, DixReadAccess);
1112706f2543Smrg       }
1113706f2543Smrg
1114706f2543Smrg       if (pReadDraw && pReadDraw != pDraw &&
1115706f2543Smrg	     new_reply.readType != GLX_PBUFFER_TYPE) {
1116706f2543Smrg	  dixLookupResourceByClass((pointer*) &pXinReadDraw,
1117706f2543Smrg				   pReadDraw->id, XRC_DRAWABLE,
1118706f2543Smrg				   client, DixReadAccess);
1119706f2543Smrg       }
1120706f2543Smrg       else {
1121706f2543Smrg	  pXinReadDraw = pXinDraw;
1122706f2543Smrg       }
1123706f2543Smrg    }
1124706f2543Smrg#endif
1125706f2543Smrg
1126706f2543Smrg
1127706f2543Smrg    /* send the MakeCurrent request to all required
1128706f2543Smrg     * back-end servers.
1129706f2543Smrg     */
1130706f2543Smrg    for (s = from_screen; s<=to_screen; s++) {
1131706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1132706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
1133706f2543Smrg       unsigned int be_draw = None;
1134706f2543Smrg       unsigned int be_read_draw = None;
1135706f2543Smrg
1136706f2543Smrg       if (pGlxPixmap) {
1137706f2543Smrg	   be_draw = pGlxPixmap->be_xids[s];
1138706f2543Smrg       }
1139706f2543Smrg       else if (pGlxPbuffer) {
1140706f2543Smrg	  be_draw = pGlxPbuffer->be_xids[s];
1141706f2543Smrg       }
1142706f2543Smrg#ifdef PANORAMIX
1143706f2543Smrg       else if (pXinDraw) {
1144706f2543Smrg	  dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
1145706f2543Smrg       }
1146706f2543Smrg#endif
1147706f2543Smrg       else if (pGlxWindow) {
1148706f2543Smrg	  pWin = (WindowPtr)pGlxWindow->pDraw;
1149706f2543Smrg       }
1150706f2543Smrg
1151706f2543Smrg       if (pWin && be_draw == None) {
1152706f2543Smrg	   be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
1153706f2543Smrg	   if (!be_draw) {
1154706f2543Smrg	      /* it might be that the window did not created yet on the */
1155706f2543Smrg	      /* back-end server (lazy window creation option), force   */
1156706f2543Smrg	      /* creation of the window */
1157706f2543Smrg	      dmxCreateAndRealizeWindow( pWin, TRUE );
1158706f2543Smrg	      be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
1159706f2543Smrg	   }
1160706f2543Smrg       }
1161706f2543Smrg
1162706f2543Smrg       /*
1163706f2543Smrg	* Before sending the MakeCurrent request - sync the
1164706f2543Smrg	* X11 connection to the back-end servers to make sure
1165706f2543Smrg	* that drawable is already created
1166706f2543Smrg	*/
1167706f2543Smrg       dmxSync( dmxScreen, 1 );
1168706f2543Smrg
1169706f2543Smrg       if (drawId == readId) {
1170706f2543Smrg	  LockDisplay(dpy);
1171706f2543Smrg	  GetReq(GLXMakeCurrent, be_req);
1172706f2543Smrg	  be_req->reqType = dmxScreen->glxMajorOpcode;
1173706f2543Smrg	  be_req->glxCode = X_GLXMakeCurrent;
1174706f2543Smrg	  be_req->drawable = be_draw;
1175706f2543Smrg	  be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1176706f2543Smrg	  be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1177706f2543Smrg	  if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
1178706f2543Smrg
1179706f2543Smrg	     /* The make current failed */
1180706f2543Smrg	     UnlockDisplay(dpy);
1181706f2543Smrg	     SyncHandle();
1182706f2543Smrg	     return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1183706f2543Smrg	  }
1184706f2543Smrg
1185706f2543Smrg	  UnlockDisplay(dpy);
1186706f2543Smrg       	  SyncHandle();
1187706f2543Smrg
1188706f2543Smrg	  SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag );
1189706f2543Smrg       }
1190706f2543Smrg       else {
1191706f2543Smrg
1192706f2543Smrg	  if (pReadGlxPixmap) {
1193706f2543Smrg	     be_read_draw = pReadGlxPixmap->be_xids[s];
1194706f2543Smrg	  }
1195706f2543Smrg	  else if (pGlxReadPbuffer) {
1196706f2543Smrg	     be_read_draw = pGlxReadPbuffer->be_xids[s];
1197706f2543Smrg	  }
1198706f2543Smrg#ifdef PANORAMIX
1199706f2543Smrg	  else if (pXinReadDraw) {
1200706f2543Smrg	     dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client,
1201706f2543Smrg			     DixReadAccess);
1202706f2543Smrg   	  }
1203706f2543Smrg#endif
1204706f2543Smrg	  else if (pGlxReadWindow) {
1205706f2543Smrg	     pReadWin = (WindowPtr)pGlxReadWindow->pDraw;
1206706f2543Smrg	  }
1207706f2543Smrg
1208706f2543Smrg      	  if (pReadWin && be_read_draw == None) {
1209706f2543Smrg  	     be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
1210706f2543Smrg	   if (!be_read_draw) {
1211706f2543Smrg	      /* it might be that the window did not created yet on the */
1212706f2543Smrg	      /* back-end server (lazy window creation option), force   */
1213706f2543Smrg	      /* creation of the window */
1214706f2543Smrg	      dmxCreateAndRealizeWindow( pReadWin, TRUE );
1215706f2543Smrg	      be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
1216706f2543Smrg              dmxSync( dmxScreen, 1 );
1217706f2543Smrg	   }
1218706f2543Smrg     	  }
1219706f2543Smrg
1220706f2543Smrg	  if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1221706f2543Smrg	     LockDisplay(dpy);
1222706f2543Smrg	     GetReq(GLXMakeContextCurrent, be_new_req);
1223706f2543Smrg	     be_new_req->reqType = dmxScreen->glxMajorOpcode;
1224706f2543Smrg	     be_new_req->glxCode = X_GLXMakeContextCurrent;
1225706f2543Smrg	     be_new_req->drawable = be_draw;
1226706f2543Smrg	     be_new_req->readdrawable = be_read_draw;
1227706f2543Smrg	     be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1228706f2543Smrg	     be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1229706f2543Smrg	     if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
1230706f2543Smrg
1231706f2543Smrg		/* The make current failed */
1232706f2543Smrg		UnlockDisplay(dpy);
1233706f2543Smrg   		SyncHandle();
1234706f2543Smrg   		return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1235706f2543Smrg   	     }
1236706f2543Smrg
1237706f2543Smrg   	     UnlockDisplay(dpy);
1238706f2543Smrg      	     SyncHandle();
1239706f2543Smrg
1240706f2543Smrg   	     SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag );
1241706f2543Smrg	  }
1242706f2543Smrg	  else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) {
1243706f2543Smrg	     xGLXMakeCurrentReadSGIReq *ext_req;
1244706f2543Smrg	     xGLXVendorPrivateWithReplyReq *vpreq;
1245706f2543Smrg             xGLXMakeCurrentReadSGIReply ext_reply;
1246706f2543Smrg
1247706f2543Smrg	     LockDisplay(dpy);
1248706f2543Smrg	     GetReqExtra(GLXVendorPrivateWithReply,
1249706f2543Smrg		         sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq,
1250706f2543Smrg		         vpreq);
1251706f2543Smrg	     ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq;
1252706f2543Smrg	     ext_req->reqType = dmxScreen->glxMajorOpcode;
1253706f2543Smrg	     ext_req->glxCode = X_GLXVendorPrivateWithReply;
1254706f2543Smrg	     ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
1255706f2543Smrg	     ext_req->drawable = be_draw;
1256706f2543Smrg	     ext_req->readable = be_read_draw;
1257706f2543Smrg	     ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1258706f2543Smrg	     ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1259706f2543Smrg	     if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
1260706f2543Smrg
1261706f2543Smrg		/* The make current failed */
1262706f2543Smrg		UnlockDisplay(dpy);
1263706f2543Smrg   		SyncHandle();
1264706f2543Smrg   		return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1265706f2543Smrg   	     }
1266706f2543Smrg
1267706f2543Smrg   	     UnlockDisplay(dpy);
1268706f2543Smrg      	     SyncHandle();
1269706f2543Smrg
1270706f2543Smrg   	     SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag );
1271706f2543Smrg
1272706f2543Smrg	  }
1273706f2543Smrg	  else {
1274706f2543Smrg	     return BadMatch;
1275706f2543Smrg	  }
1276706f2543Smrg       }
1277706f2543Smrg
1278706f2543Smrg       XFlush( dpy );
1279706f2543Smrg    }
1280706f2543Smrg
1281706f2543Smrg    if (client->swapped) {
1282706f2543Smrg	__glXSwapMakeCurrentReply(client, &new_reply);
1283706f2543Smrg    } else {
1284706f2543Smrg	WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply);
1285706f2543Smrg    }
1286706f2543Smrg
1287706f2543Smrg    return Success;
1288706f2543Smrg}
1289706f2543Smrg
1290706f2543Smrgint __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
1291706f2543Smrg{
1292706f2543Smrg    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
1293706f2543Smrg
1294706f2543Smrg    return( MakeCurrent(cl, req->drawable, req->drawable,
1295706f2543Smrg	                req->context, req->oldContextTag ) );
1296706f2543Smrg}
1297706f2543Smrg
1298706f2543Smrgint __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
1299706f2543Smrg{
1300706f2543Smrg    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
1301706f2543Smrg
1302706f2543Smrg    return( MakeCurrent(cl, req->drawable, req->readdrawable,
1303706f2543Smrg	                req->context, req->oldContextTag ) );
1304706f2543Smrg}
1305706f2543Smrg
1306706f2543Smrgint __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
1307706f2543Smrg{
1308706f2543Smrg    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
1309706f2543Smrg
1310706f2543Smrg    return( MakeCurrent(cl, req->drawable, req->readable,
1311706f2543Smrg	                req->context, req->oldContextTag ) );
1312706f2543Smrg}
1313706f2543Smrg
1314706f2543Smrgint __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
1315706f2543Smrg{
1316706f2543Smrg    ClientPtr client = cl->client;
1317706f2543Smrg    xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
1318706f2543Smrg    xGLXIsDirectReply reply;
1319706f2543Smrg    __GLXcontext *glxc;
1320706f2543Smrg
1321706f2543Smrg    /*
1322706f2543Smrg    ** Find the GL context.
1323706f2543Smrg    */
1324706f2543Smrg    dixLookupResourceByType((pointer*) &glxc, req->context, __glXContextRes,
1325706f2543Smrg                            NullClient, DixUnknownAccess);
1326706f2543Smrg    if (!glxc) {
1327706f2543Smrg	client->errorValue = req->context;
1328706f2543Smrg	return __glXBadContext;
1329706f2543Smrg    }
1330706f2543Smrg
1331706f2543Smrg    reply.isDirect = 0;
1332706f2543Smrg    reply.length = 0;
1333706f2543Smrg    reply.type = X_Reply;
1334706f2543Smrg    reply.sequenceNumber = client->sequence;
1335706f2543Smrg
1336706f2543Smrg    if (client->swapped) {
1337706f2543Smrg	__glXSwapIsDirectReply(client, &reply);
1338706f2543Smrg    } else {
1339706f2543Smrg	WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
1340706f2543Smrg    }
1341706f2543Smrg
1342706f2543Smrg    return Success;
1343706f2543Smrg}
1344706f2543Smrg
1345706f2543Smrgint __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
1346706f2543Smrg{
1347706f2543Smrg    ClientPtr client = cl->client;
1348706f2543Smrg/*    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
1349706f2543Smrg    xGLXQueryVersionReply reply;
1350706f2543Smrg
1351706f2543Smrg    /*
1352706f2543Smrg    ** Server should take into consideration the version numbers sent by the
1353706f2543Smrg    ** client if it wants to work with older clients; however, in this
1354706f2543Smrg    ** implementation the server just returns its version number.
1355706f2543Smrg    */
1356706f2543Smrg    reply.majorVersion = __glXVersionMajor;
1357706f2543Smrg    reply.minorVersion = __glXVersionMinor;
1358706f2543Smrg    reply.length = 0;
1359706f2543Smrg    reply.type = X_Reply;
1360706f2543Smrg    reply.sequenceNumber = client->sequence;
1361706f2543Smrg
1362706f2543Smrg    if (client->swapped) {
1363706f2543Smrg	__glXSwapQueryVersionReply(client, &reply);
1364706f2543Smrg    } else {
1365706f2543Smrg	WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
1366706f2543Smrg    }
1367706f2543Smrg    return Success;
1368706f2543Smrg}
1369706f2543Smrg
1370706f2543Smrgint __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
1371706f2543Smrg{
1372706f2543Smrg    xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
1373706f2543Smrg    xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc;
1374706f2543Smrg    int from_screen = 0;
1375706f2543Smrg    int to_screen = 0;
1376706f2543Smrg    int s;
1377706f2543Smrg    __GLXcontext *glxc = NULL;
1378706f2543Smrg
1379706f2543Smrg    if (req->contextTag != 0) {
1380706f2543Smrg	glxc = __glXLookupContextByTag(cl, req->contextTag);
1381706f2543Smrg	if (glxc) {
1382706f2543Smrg	   from_screen = to_screen = glxc->pScreen->myNum;
1383706f2543Smrg	}
1384706f2543Smrg    }
1385706f2543Smrg
1386706f2543Smrg#ifdef PANORAMIX
1387706f2543Smrg    if (!noPanoramiXExtension) {
1388706f2543Smrg       from_screen = 0;
1389706f2543Smrg       to_screen = screenInfo.numScreens - 1;
1390706f2543Smrg    }
1391706f2543Smrg#endif
1392706f2543Smrg
1393706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
1394706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1395706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
1396706f2543Smrg
1397706f2543Smrg       LockDisplay(dpy);
1398706f2543Smrg       GetReq(GLXWaitGL,be_req);
1399706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
1400706f2543Smrg       be_req->glxCode = X_GLXWaitGL;
1401706f2543Smrg       be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1402706f2543Smrg       UnlockDisplay(dpy);
1403706f2543Smrg       SyncHandle();
1404706f2543Smrg
1405706f2543Smrg       XSync(dpy, False);
1406706f2543Smrg    }
1407706f2543Smrg
1408706f2543Smrg    return Success;
1409706f2543Smrg}
1410706f2543Smrg
1411706f2543Smrgint __glXWaitX(__GLXclientState *cl, GLbyte *pc)
1412706f2543Smrg{
1413706f2543Smrg    xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
1414706f2543Smrg    xGLXWaitXReq *be_req;
1415706f2543Smrg    int from_screen = 0;
1416706f2543Smrg    int to_screen = 0;
1417706f2543Smrg    int s;
1418706f2543Smrg    __GLXcontext *glxc = NULL;
1419706f2543Smrg
1420706f2543Smrg    if (req->contextTag != 0) {
1421706f2543Smrg	glxc = __glXLookupContextByTag(cl, req->contextTag);
1422706f2543Smrg	if (glxc) {
1423706f2543Smrg	   from_screen = to_screen = glxc->pScreen->myNum;
1424706f2543Smrg	}
1425706f2543Smrg    }
1426706f2543Smrg
1427706f2543Smrg#ifdef PANORAMIX
1428706f2543Smrg    if (!noPanoramiXExtension) {
1429706f2543Smrg       from_screen = 0;
1430706f2543Smrg       to_screen = screenInfo.numScreens - 1;
1431706f2543Smrg    }
1432706f2543Smrg#endif
1433706f2543Smrg
1434706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
1435706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1436706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
1437706f2543Smrg
1438706f2543Smrg       dmxSync( dmxScreen, 1 );
1439706f2543Smrg
1440706f2543Smrg       LockDisplay(dpy);
1441706f2543Smrg       GetReq(GLXWaitX,be_req);
1442706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
1443706f2543Smrg       be_req->glxCode = X_GLXWaitX;
1444706f2543Smrg       be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1445706f2543Smrg       UnlockDisplay(dpy);
1446706f2543Smrg       SyncHandle();
1447706f2543Smrg
1448706f2543Smrg       XFlush( dpy );
1449706f2543Smrg    }
1450706f2543Smrg
1451706f2543Smrg    return Success;
1452706f2543Smrg}
1453706f2543Smrg
1454706f2543Smrgint __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
1455706f2543Smrg{
1456706f2543Smrg    ClientPtr client = cl->client;
1457706f2543Smrg    xGLXCopyContextReq *be_req;
1458706f2543Smrg    xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
1459706f2543Smrg    GLXContextID source = req->source;
1460706f2543Smrg    GLXContextID dest = req->dest;
1461706f2543Smrg    GLXContextTag tag = req->contextTag;
1462706f2543Smrg    unsigned long mask = req->mask;
1463706f2543Smrg    __GLXcontext *src, *dst;
1464706f2543Smrg    int s;
1465706f2543Smrg    int from_screen = 0;
1466706f2543Smrg    int to_screen = 0;
1467706f2543Smrg
1468706f2543Smrg    /*
1469706f2543Smrg    ** Check that each context exists.
1470706f2543Smrg    */
1471706f2543Smrg    dixLookupResourceByType((pointer*) &src, source, __glXContextRes,
1472706f2543Smrg                            NullClient, DixUnknownAccess);
1473706f2543Smrg    if (!src) {
1474706f2543Smrg	client->errorValue = source;
1475706f2543Smrg	return __glXBadContext;
1476706f2543Smrg    }
1477706f2543Smrg    dixLookupResourceByType((pointer*) &dst, dest, __glXContextRes,
1478706f2543Smrg                            NullClient, DixUnknownAccess);
1479706f2543Smrg    if (!dst) {
1480706f2543Smrg	client->errorValue = dest;
1481706f2543Smrg	return __glXBadContext;
1482706f2543Smrg    }
1483706f2543Smrg
1484706f2543Smrg    /*
1485706f2543Smrg    ** They must be in the same address space, and same screen.
1486706f2543Smrg    */
1487706f2543Smrg    if (src->pGlxScreen != dst->pGlxScreen) {
1488706f2543Smrg	client->errorValue = source;
1489706f2543Smrg	return BadMatch;
1490706f2543Smrg    }
1491706f2543Smrg
1492706f2543Smrg    /*
1493706f2543Smrg    ** The destination context must not be current for any client.
1494706f2543Smrg    */
1495706f2543Smrg    if (dst->isCurrent) {
1496706f2543Smrg	client->errorValue = dest;
1497706f2543Smrg	return BadAccess;
1498706f2543Smrg    }
1499706f2543Smrg
1500706f2543Smrg    if (tag) {
1501706f2543Smrg	__GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
1502706f2543Smrg
1503706f2543Smrg	if (!tagcx) {
1504706f2543Smrg	    return __glXBadContextTag;
1505706f2543Smrg	}
1506706f2543Smrg	if (tagcx != src) {
1507706f2543Smrg	    /*
1508706f2543Smrg	    ** This would be caused by a faulty implementation of the client
1509706f2543Smrg	    ** library.
1510706f2543Smrg	    */
1511706f2543Smrg	    return BadMatch;
1512706f2543Smrg	}
1513706f2543Smrg    }
1514706f2543Smrg
1515706f2543Smrg    from_screen = to_screen = src->pScreen->myNum;
1516706f2543Smrg
1517706f2543Smrg#ifdef PANORAMIX
1518706f2543Smrg    if (!noPanoramiXExtension) {
1519706f2543Smrg       from_screen = 0;
1520706f2543Smrg       to_screen = screenInfo.numScreens - 1;
1521706f2543Smrg    }
1522706f2543Smrg#endif
1523706f2543Smrg
1524706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
1525706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1526706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
1527706f2543Smrg
1528706f2543Smrg       LockDisplay(dpy);
1529706f2543Smrg       GetReq(GLXCopyContext,be_req);
1530706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
1531706f2543Smrg       be_req->glxCode = X_GLXCopyContext;
1532706f2543Smrg       be_req->source = (unsigned int)src->real_ids[s-from_screen];
1533706f2543Smrg       be_req->dest = (unsigned int)dst->real_ids[s-from_screen];
1534706f2543Smrg       be_req->mask = mask;
1535706f2543Smrg       be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1536706f2543Smrg       UnlockDisplay(dpy);
1537706f2543Smrg       SyncHandle();
1538706f2543Smrg    }
1539706f2543Smrg
1540706f2543Smrg    return Success;
1541706f2543Smrg}
1542706f2543Smrg
1543706f2543Smrgint __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
1544706f2543Smrg{
1545706f2543Smrg    ClientPtr client = cl->client;
1546706f2543Smrg    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
1547706f2543Smrg    xGLXGetVisualConfigsReply reply;
1548706f2543Smrg    __GLXscreenInfo *pGlxScreen;
1549706f2543Smrg    __GLXvisualConfig *pGlxVisual;
1550706f2543Smrg    CARD32 buf[__GLX_TOTAL_CONFIG];
1551706f2543Smrg    unsigned int screen;
1552706f2543Smrg    int i, p;
1553706f2543Smrg
1554706f2543Smrg    screen = req->screen;
1555706f2543Smrg    if (screen >= screenInfo.numScreens) {
1556706f2543Smrg	/* The client library must send a valid screen number. */
1557706f2543Smrg	client->errorValue = screen;
1558706f2543Smrg	return BadValue;
1559706f2543Smrg    }
1560706f2543Smrg    pGlxScreen = &__glXActiveScreens[screen];
1561706f2543Smrg
1562706f2543Smrg    reply.numVisuals = pGlxScreen->numGLXVisuals;
1563706f2543Smrg    reply.numProps = __GLX_TOTAL_CONFIG;
1564706f2543Smrg    reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
1565706f2543Smrg		    __GLX_TOTAL_CONFIG) >> 2;
1566706f2543Smrg    reply.type = X_Reply;
1567706f2543Smrg    reply.sequenceNumber = client->sequence;
1568706f2543Smrg
1569706f2543Smrg    WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
1570706f2543Smrg
1571706f2543Smrg    for (i=0; i < pGlxScreen->numVisuals; i++) {
1572706f2543Smrg	pGlxVisual = &pGlxScreen->pGlxVisual[i];
1573706f2543Smrg	if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
1574706f2543Smrg	    /* not a usable visual */
1575706f2543Smrg	    continue;
1576706f2543Smrg	}
1577706f2543Smrg	p = 0;
1578706f2543Smrg	buf[p++] = pGlxVisual->vid;
1579706f2543Smrg	buf[p++] = pGlxVisual->class;
1580706f2543Smrg	buf[p++] = pGlxVisual->rgba;
1581706f2543Smrg
1582706f2543Smrg	buf[p++] = pGlxVisual->redSize;
1583706f2543Smrg	buf[p++] = pGlxVisual->greenSize;
1584706f2543Smrg	buf[p++] = pGlxVisual->blueSize;
1585706f2543Smrg	buf[p++] = pGlxVisual->alphaSize;
1586706f2543Smrg	buf[p++] = pGlxVisual->accumRedSize;
1587706f2543Smrg	buf[p++] = pGlxVisual->accumGreenSize;
1588706f2543Smrg	buf[p++] = pGlxVisual->accumBlueSize;
1589706f2543Smrg	buf[p++] = pGlxVisual->accumAlphaSize;
1590706f2543Smrg
1591706f2543Smrg	buf[p++] = pGlxVisual->doubleBuffer;
1592706f2543Smrg	buf[p++] = pGlxVisual->stereo;
1593706f2543Smrg
1594706f2543Smrg	buf[p++] = pGlxVisual->bufferSize;
1595706f2543Smrg	buf[p++] = pGlxVisual->depthSize;
1596706f2543Smrg	buf[p++] = pGlxVisual->stencilSize;
1597706f2543Smrg	buf[p++] = pGlxVisual->auxBuffers;
1598706f2543Smrg	buf[p++] = pGlxVisual->level;
1599706f2543Smrg	/*
1600706f2543Smrg	** Add token/value pairs for extensions.
1601706f2543Smrg	*/
1602706f2543Smrg	buf[p++] = GLX_VISUAL_CAVEAT_EXT;
1603706f2543Smrg	buf[p++] = pGlxVisual->visualRating;
1604706f2543Smrg	buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
1605706f2543Smrg	buf[p++] = pGlxVisual->transparentPixel;
1606706f2543Smrg	buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
1607706f2543Smrg	buf[p++] = pGlxVisual->transparentRed;
1608706f2543Smrg	buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
1609706f2543Smrg	buf[p++] = pGlxVisual->transparentGreen;
1610706f2543Smrg	buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
1611706f2543Smrg	buf[p++] = pGlxVisual->transparentBlue;
1612706f2543Smrg	buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
1613706f2543Smrg	buf[p++] = pGlxVisual->transparentAlpha;
1614706f2543Smrg	buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
1615706f2543Smrg	buf[p++] = pGlxVisual->transparentIndex;
1616706f2543Smrg	buf[p++] = GLX_SAMPLES_SGIS;
1617706f2543Smrg	buf[p++] = pGlxVisual->multiSampleSize;
1618706f2543Smrg	buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
1619706f2543Smrg	buf[p++] = pGlxVisual->nMultiSampleBuffers;
1620706f2543Smrg	buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
1621706f2543Smrg	buf[p++] = pGlxVisual->visualSelectGroup;
1622706f2543Smrg
1623706f2543Smrg	WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
1624706f2543Smrg		(char *)buf);
1625706f2543Smrg    }
1626706f2543Smrg    return Success;
1627706f2543Smrg}
1628706f2543Smrg
1629706f2543Smrg/*
1630706f2543Smrg** Create a GLX Pixmap from an X Pixmap.
1631706f2543Smrg*/
1632706f2543Smrgstatic int CreateGLXPixmap(__GLXclientState *cl,
1633706f2543Smrg                    VisualID visual, GLXFBConfigID fbconfigId,
1634706f2543Smrg		    int screenNum, XID pixmapId, XID glxpixmapId )
1635706f2543Smrg{
1636706f2543Smrg    ClientPtr client = cl->client;
1637706f2543Smrg    xGLXCreateGLXPixmapReq *be_req;
1638706f2543Smrg    xGLXCreatePixmapReq *be_new_req;
1639706f2543Smrg    DrawablePtr pDraw;
1640706f2543Smrg    ScreenPtr pScreen;
1641706f2543Smrg    VisualPtr pVisual;
1642706f2543Smrg    __GLXpixmap *pGlxPixmap;
1643706f2543Smrg    __GLXscreenInfo *pGlxScreen;
1644706f2543Smrg    __GLXvisualConfig *pGlxVisual;
1645706f2543Smrg    __GLXFBConfig *pFBConfig;
1646706f2543Smrg    int i, s, rc;
1647706f2543Smrg    int from_screen, to_screen;
1648706f2543Smrg#ifdef PANORAMIX
1649706f2543Smrg    PanoramiXRes *pXinDraw = NULL;
1650706f2543Smrg#endif
1651706f2543Smrg
1652706f2543Smrg    rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP,
1653706f2543Smrg			   DixAddAccess);
1654706f2543Smrg    if (rc != Success)
1655706f2543Smrg	return rc;
1656706f2543Smrg
1657706f2543Smrg    /*
1658706f2543Smrg    ** Check if screen of visual matches screen of pixmap.
1659706f2543Smrg    */
1660706f2543Smrg    pScreen = pDraw->pScreen;
1661706f2543Smrg    if (screenNum != pScreen->myNum) {
1662706f2543Smrg	return BadMatch;
1663706f2543Smrg    }
1664706f2543Smrg
1665706f2543Smrg    if (fbconfigId == 0 && visual == 0) {
1666706f2543Smrg	  return BadValue;
1667706f2543Smrg    }
1668706f2543Smrg
1669706f2543Smrg    if (fbconfigId != None) {
1670706f2543Smrg       pFBConfig = glxLookupFBConfig( fbconfigId );
1671706f2543Smrg       if (!pFBConfig) {
1672706f2543Smrg	  client->errorValue = fbconfigId;
1673706f2543Smrg	  return BadValue;
1674706f2543Smrg       }
1675706f2543Smrg       visual = pFBConfig->associatedVisualId;
1676706f2543Smrg    }
1677706f2543Smrg    else {
1678706f2543Smrg       pFBConfig = NULL;
1679706f2543Smrg    }
1680706f2543Smrg
1681706f2543Smrg    if (visual != None) {
1682706f2543Smrg       /*
1683706f2543Smrg	** Find the VisualRec for this visual.
1684706f2543Smrg	*/
1685706f2543Smrg       pVisual = pScreen->visuals;
1686706f2543Smrg       for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
1687706f2543Smrg	  if (pVisual->vid == visual) {
1688706f2543Smrg	     break;
1689706f2543Smrg	  }
1690706f2543Smrg       }
1691706f2543Smrg       if (i == pScreen->numVisuals) {
1692706f2543Smrg	  client->errorValue = visual;
1693706f2543Smrg	  return BadValue;
1694706f2543Smrg       }
1695706f2543Smrg       /*
1696706f2543Smrg	** Check if depth of visual matches depth of pixmap.
1697706f2543Smrg	*/
1698706f2543Smrg       if (pVisual->nplanes != pDraw->depth) {
1699706f2543Smrg	  client->errorValue = visual;
1700706f2543Smrg	  return BadMatch;
1701706f2543Smrg       }
1702706f2543Smrg
1703706f2543Smrg       /*
1704706f2543Smrg	** Get configuration of the visual.
1705706f2543Smrg	*/
1706706f2543Smrg       pGlxScreen = &__glXActiveScreens[screenNum];
1707706f2543Smrg       pGlxVisual = pGlxScreen->pGlxVisual;
1708706f2543Smrg       for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
1709706f2543Smrg	  if (pGlxVisual->vid == visual) {
1710706f2543Smrg	     break;
1711706f2543Smrg	  }
1712706f2543Smrg       }
1713706f2543Smrg       if (i == pGlxScreen->numVisuals) {
1714706f2543Smrg	  /*
1715706f2543Smrg	   ** Visual not support on this screen by this OpenGL implementation.
1716706f2543Smrg	   */
1717706f2543Smrg	  client->errorValue = visual;
1718706f2543Smrg	  return BadValue;
1719706f2543Smrg       }
1720706f2543Smrg
1721706f2543Smrg
1722706f2543Smrg       /* find the FBConfig for that visual (if any) */
1723706f2543Smrg       if ( pFBConfig == NULL ) {
1724706f2543Smrg	   pFBConfig = glxLookupFBConfigByVID( visual );
1725706f2543Smrg
1726706f2543Smrg	   if ( pFBConfig == NULL ) {
1727706f2543Smrg	      /*
1728706f2543Smrg               * visual does not have an FBConfig ???
1729706f2543Smrg	      client->errorValue = visual;
1730706f2543Smrg	      return BadValue;
1731706f2543Smrg	       */
1732706f2543Smrg	   }
1733706f2543Smrg       }
1734706f2543Smrg    }
1735706f2543Smrg    else {
1736706f2543Smrg       pVisual = NULL;
1737706f2543Smrg       pGlxVisual = NULL;
1738706f2543Smrg       pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum];
1739706f2543Smrg    }
1740706f2543Smrg
1741706f2543Smrg    pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap));
1742706f2543Smrg    if (!pGlxPixmap) {
1743706f2543Smrg	return BadAlloc;
1744706f2543Smrg    }
1745706f2543Smrg    pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens);
1746706f2543Smrg    if (!pGlxPixmap->be_xids) {
1747706f2543Smrg        free( pGlxPixmap );
1748706f2543Smrg	return BadAlloc;
1749706f2543Smrg    }
1750706f2543Smrg
1751706f2543Smrg    pGlxPixmap->pDraw = pDraw;
1752706f2543Smrg    pGlxPixmap->pGlxScreen = pGlxScreen;
1753706f2543Smrg    pGlxPixmap->pGlxVisual = pGlxVisual;
1754706f2543Smrg    pGlxPixmap->pFBConfig = pFBConfig;
1755706f2543Smrg    pGlxPixmap->pScreen = pScreen;
1756706f2543Smrg    pGlxPixmap->idExists = True;
1757706f2543Smrg    pGlxPixmap->refcnt = 0;
1758706f2543Smrg
1759706f2543Smrg    /*
1760706f2543Smrg    ** Bump the ref count on the X pixmap so it won't disappear.
1761706f2543Smrg    */
1762706f2543Smrg    ((PixmapPtr) pDraw)->refcnt++;
1763706f2543Smrg
1764706f2543Smrg    /*
1765706f2543Smrg     * send the request to the back-end server(s)
1766706f2543Smrg     */
1767706f2543Smrg    from_screen = to_screen = screenNum;
1768706f2543Smrg#ifdef PANORAMIX
1769706f2543Smrg    if (!noPanoramiXExtension) {
1770706f2543Smrg       from_screen = 0;
1771706f2543Smrg       to_screen = screenInfo.numScreens - 1;
1772706f2543Smrg
1773706f2543Smrg       dixLookupResourceByClass((pointer*) &pXinDraw,
1774706f2543Smrg				pDraw->id, XRC_DRAWABLE,
1775706f2543Smrg				client, DixReadAccess);
1776706f2543Smrg    }
1777706f2543Smrg#endif
1778706f2543Smrg
1779706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
1780706f2543Smrg
1781706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1782706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
1783706f2543Smrg       Pixmap  be_pixmap;
1784706f2543Smrg       DrawablePtr pRealDraw = pDraw;
1785706f2543Smrg
1786706f2543Smrg#ifdef PANORAMIX
1787706f2543Smrg       if (pXinDraw) {
1788706f2543Smrg	   dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0,
1789706f2543Smrg			     DixAddAccess);
1790706f2543Smrg       }
1791706f2543Smrg#endif
1792706f2543Smrg
1793706f2543Smrg       be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap;
1794706f2543Smrg
1795706f2543Smrg       /* make sure pixmap already created on back-end */
1796706f2543Smrg       dmxSync( dmxScreen, 1 );
1797706f2543Smrg
1798706f2543Smrg       if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1799706f2543Smrg       	  __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
1800706f2543Smrg
1801706f2543Smrg	  LockDisplay(dpy);
1802706f2543Smrg	  pGlxPixmap->be_xids[s] = XAllocID(dpy);
1803706f2543Smrg	  GetReq(GLXCreatePixmap,be_new_req);
1804706f2543Smrg	  be_new_req->reqType = dmxScreen->glxMajorOpcode;
1805706f2543Smrg	  be_new_req->glxCode = X_GLXCreatePixmap;
1806706f2543Smrg	  be_new_req->screen = DefaultScreen(dpy);
1807706f2543Smrg	  be_new_req->fbconfig = be_FBConfig->id;
1808706f2543Smrg	  be_new_req->pixmap = (unsigned int)be_pixmap;
1809706f2543Smrg	  be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1810706f2543Smrg	  be_new_req->numAttribs = 0;
1811706f2543Smrg	  UnlockDisplay(dpy);
1812706f2543Smrg	  SyncHandle();
1813706f2543Smrg       }
1814706f2543Smrg       else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
1815706f2543Smrg	  __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
1816706f2543Smrg	  xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req;
1817706f2543Smrg	  xGLXVendorPrivateReq *vpreq;
1818706f2543Smrg
1819706f2543Smrg	  LockDisplay(dpy);
1820706f2543Smrg	  pGlxPixmap->be_xids[s] = XAllocID(dpy);
1821706f2543Smrg	  GetReqExtra(GLXVendorPrivate,
1822706f2543Smrg		      sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,
1823706f2543Smrg		      vpreq);
1824706f2543Smrg	  ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
1825706f2543Smrg	  ext_req->reqType = dmxScreen->glxMajorOpcode;
1826706f2543Smrg	  ext_req->glxCode = X_GLXVendorPrivate;
1827706f2543Smrg	  ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
1828706f2543Smrg	  ext_req->screen = DefaultScreen(dpy);
1829706f2543Smrg	  ext_req->fbconfig = be_FBConfig->id;
1830706f2543Smrg	  ext_req->pixmap = (unsigned int)be_pixmap;
1831706f2543Smrg	  ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1832706f2543Smrg	  UnlockDisplay(dpy);
1833706f2543Smrg	  SyncHandle();
1834706f2543Smrg       }
1835706f2543Smrg       else if (pGlxVisual) {
1836706f2543Smrg	  LockDisplay(dpy);
1837706f2543Smrg	  pGlxPixmap->be_xids[s] = XAllocID(dpy);
1838706f2543Smrg	  GetReq(GLXCreateGLXPixmap,be_req);
1839706f2543Smrg	  be_req->reqType = dmxScreen->glxMajorOpcode;
1840706f2543Smrg	  be_req->glxCode = X_GLXCreateGLXPixmap;
1841706f2543Smrg	  be_req->screen = DefaultScreen(dpy);
1842706f2543Smrg	  be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList(
1843706f2543Smrg	 	pGlxVisual,
1844706f2543Smrg		dmxScreen->glxVisuals,
1845706f2543Smrg		dmxScreen->numGlxVisuals );
1846706f2543Smrg   	  be_req->pixmap = (unsigned int)be_pixmap;
1847706f2543Smrg      	  be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1848706f2543Smrg	  UnlockDisplay(dpy);
1849706f2543Smrg	  SyncHandle();
1850706f2543Smrg       }
1851706f2543Smrg       else {
1852706f2543Smrg	  client->errorValue = ( visual ? visual : fbconfigId );
1853706f2543Smrg          free( pGlxPixmap );
1854706f2543Smrg	  return BadValue;
1855706f2543Smrg       }
1856706f2543Smrg
1857706f2543Smrg       XFlush( dpy );
1858706f2543Smrg    }
1859706f2543Smrg
1860706f2543Smrg    if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
1861706f2543Smrg        free( pGlxPixmap );
1862706f2543Smrg	return BadAlloc;
1863706f2543Smrg    }
1864706f2543Smrg
1865706f2543Smrg    return Success;
1866706f2543Smrg}
1867706f2543Smrg
1868706f2543Smrgint __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1869706f2543Smrg{
1870706f2543Smrg    xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
1871706f2543Smrg
1872706f2543Smrg    return( CreateGLXPixmap(cl, req->visual, None,
1873706f2543Smrg	                    req->screen, req->pixmap, req->glxpixmap) );
1874706f2543Smrg}
1875706f2543Smrg
1876706f2543Smrgint __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
1877706f2543Smrg{
1878706f2543Smrg    xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
1879706f2543Smrg
1880706f2543Smrg    return( CreateGLXPixmap(cl, None, req->fbconfig,
1881706f2543Smrg	                    req->screen, req->pixmap, req->glxpixmap) );
1882706f2543Smrg}
1883706f2543Smrg
1884706f2543Smrgint __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1885706f2543Smrg{
1886706f2543Smrg    ClientPtr client = cl->client;
1887706f2543Smrg    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
1888706f2543Smrg    XID glxpixmap = req->glxpixmap;
1889706f2543Smrg    __GLXpixmap *pGlxPixmap;
1890706f2543Smrg    int s;
1891706f2543Smrg    int from_screen, to_screen;
1892706f2543Smrg
1893706f2543Smrg    /*
1894706f2543Smrg    ** Check if it's a valid GLX pixmap.
1895706f2543Smrg    */
1896706f2543Smrg    dixLookupResourceByType((pointer*) &pGlxPixmap, glxpixmap,
1897706f2543Smrg                            __glXPixmapRes, NullClient, DixUnknownAccess);
1898706f2543Smrg    if (!pGlxPixmap) {
1899706f2543Smrg	client->errorValue = glxpixmap;
1900706f2543Smrg	return __glXBadPixmap;
1901706f2543Smrg    }
1902706f2543Smrg    FreeResource(glxpixmap, FALSE);
1903706f2543Smrg
1904706f2543Smrg    /*
1905706f2543Smrg     * destroy the pixmap on the back-end server(s).
1906706f2543Smrg     */
1907706f2543Smrg    from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum;
1908706f2543Smrg#ifdef PANORAMIX
1909706f2543Smrg    if (!noPanoramiXExtension) {
1910706f2543Smrg       from_screen = 0;
1911706f2543Smrg       to_screen = screenInfo.numScreens - 1;
1912706f2543Smrg    }
1913706f2543Smrg#endif
1914706f2543Smrg
1915706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
1916706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1917706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
1918706f2543Smrg
1919706f2543Smrg       /* make sure pixmap exist in back-end */
1920706f2543Smrg       dmxSync( dmxScreen, 1 );
1921706f2543Smrg
1922706f2543Smrg       LockDisplay(dpy);
1923706f2543Smrg       GetReq(GLXDestroyGLXPixmap,req);
1924706f2543Smrg       req->reqType = dmxScreen->glxMajorOpcode;
1925706f2543Smrg       req->glxCode = X_GLXDestroyGLXPixmap;
1926706f2543Smrg       req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1927706f2543Smrg       UnlockDisplay(dpy);
1928706f2543Smrg       SyncHandle();
1929706f2543Smrg    }
1930706f2543Smrg
1931706f2543Smrg
1932706f2543Smrg    return Success;
1933706f2543Smrg}
1934706f2543Smrg
1935706f2543Smrg/*****************************************************************************/
1936706f2543Smrg
1937706f2543Smrg/*
1938706f2543Smrg** NOTE: There is no portable implementation for swap buffers as of
1939706f2543Smrg** this time that is of value.  Consequently, this code must be
1940706f2543Smrg** implemented by somebody other than SGI.
1941706f2543Smrg*/
1942706f2543Smrgint __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag)
1943706f2543Smrg{
1944706f2543Smrg    ClientPtr client = cl->client;
1945706f2543Smrg    DrawablePtr pDraw;
1946706f2543Smrg    xGLXSwapBuffersReq *be_req;
1947706f2543Smrg    WindowPtr pWin = NULL;
1948706f2543Smrg    __GLXpixmap *pGlxPixmap = NULL;
1949706f2543Smrg    __GLXcontext *glxc = NULL;
1950706f2543Smrg#ifdef PANORAMIX
1951706f2543Smrg    PanoramiXRes *pXinDraw = NULL;
1952706f2543Smrg#endif
1953706f2543Smrg    __glXWindow *pGlxWindow = NULL;
1954706f2543Smrg    int from_screen = 0;
1955706f2543Smrg    int to_screen = 0;
1956706f2543Smrg    int s, rc;
1957706f2543Smrg
1958706f2543Smrg    /*
1959706f2543Smrg    ** Check that the GLX drawable is valid.
1960706f2543Smrg    */
1961706f2543Smrg    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
1962706f2543Smrg    if (rc == Success) {
1963706f2543Smrg        from_screen = to_screen = pDraw->pScreen->myNum;
1964706f2543Smrg
1965706f2543Smrg	if (pDraw->type == DRAWABLE_WINDOW) {
1966706f2543Smrg	    /*
1967706f2543Smrg	    ** Drawable is an X window.
1968706f2543Smrg	    */
1969706f2543Smrg	   pWin = (WindowPtr)pDraw;
1970706f2543Smrg	} else {
1971706f2543Smrg	    /*
1972706f2543Smrg	    ** Drawable is an X pixmap, which is not allowed.
1973706f2543Smrg	    */
1974706f2543Smrg	    client->errorValue = drawId;
1975706f2543Smrg	    return __glXBadDrawable;
1976706f2543Smrg	}
1977706f2543Smrg    }
1978706f2543Smrg
1979706f2543Smrg    if (!pDraw) {
1980706f2543Smrg	dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
1981706f2543Smrg				__glXPixmapRes, NullClient, DixUnknownAccess);
1982706f2543Smrg	if (pGlxPixmap) {
1983706f2543Smrg	    /*
1984706f2543Smrg	    ** Drawable is a GLX pixmap.
1985706f2543Smrg	    */
1986706f2543Smrg	   pDraw = pGlxPixmap->pDraw;
1987706f2543Smrg	   from_screen = to_screen = pGlxPixmap->pScreen->myNum;
1988706f2543Smrg	}
1989706f2543Smrg    }
1990706f2543Smrg
1991706f2543Smrg    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1992706f2543Smrg       dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
1993706f2543Smrg                               __glXWindowRes, NullClient, DixUnknownAccess);
1994706f2543Smrg       if (pGlxWindow) {
1995706f2543Smrg	  /*
1996706f2543Smrg	   ** Drawable is a GLXWindow.
1997706f2543Smrg	   */
1998706f2543Smrg	  pDraw = pGlxWindow->pDraw;
1999706f2543Smrg	  from_screen = to_screen = pGlxWindow->pScreen->myNum;
2000706f2543Smrg       }
2001706f2543Smrg    }
2002706f2543Smrg
2003706f2543Smrg    if (!pDraw) {
2004706f2543Smrg       /*
2005706f2543Smrg	** Drawable is neither a X window nor a GLX pixmap.
2006706f2543Smrg	*/
2007706f2543Smrg       client->errorValue = drawId;
2008706f2543Smrg       return __glXBadDrawable;
2009706f2543Smrg    }
2010706f2543Smrg
2011706f2543Smrg    if (tag) {
2012706f2543Smrg	glxc = __glXLookupContextByTag(cl, tag);
2013706f2543Smrg	if (!glxc) {
2014706f2543Smrg	    return __glXBadContextTag;
2015706f2543Smrg	}
2016706f2543Smrg    }
2017706f2543Smrg
2018706f2543Smrg#ifdef PANORAMIX
2019706f2543Smrg    if (!noPanoramiXExtension) {
2020706f2543Smrg       from_screen = 0;
2021706f2543Smrg       to_screen = screenInfo.numScreens - 1;
2022706f2543Smrg       dixLookupResourceByClass((pointer*) &pXinDraw,
2023706f2543Smrg				pDraw->id, XRC_DRAWABLE,
2024706f2543Smrg				client, DixReadAccess);
2025706f2543Smrg    }
2026706f2543Smrg#endif
2027706f2543Smrg
2028706f2543Smrg    /* If requested, send a glFinish to all back-end servers before swapping. */
2029706f2543Smrg    if (dmxGLXFinishSwap) {
2030706f2543Smrg	for (s=from_screen; s<=to_screen; s++) {
2031706f2543Smrg	    Display *dpy = GetBackEndDisplay(cl,s);
2032706f2543Smrg	    DMXScreenInfo *dmxScreen = &dmxScreens[s];
2033706f2543Smrg	    xGLXSingleReq *finishReq;
2034706f2543Smrg	    xGLXSingleReply reply;
2035706f2543Smrg
2036706f2543Smrg#define X_GLXSingle 0    /* needed by GetReq below */
2037706f2543Smrg
2038706f2543Smrg	    LockDisplay(dpy);
2039706f2543Smrg	    GetReq(GLXSingle,finishReq);
2040706f2543Smrg	    finishReq->reqType = dmxScreen->glxMajorOpcode;
2041706f2543Smrg	    finishReq->glxCode = X_GLsop_Finish;
2042706f2543Smrg	    finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0);
2043706f2543Smrg	    (void) _XReply(dpy, (xReply*) &reply, 0, False);
2044706f2543Smrg	    UnlockDisplay(dpy);
2045706f2543Smrg	    SyncHandle();
2046706f2543Smrg	}
2047706f2543Smrg    }
2048706f2543Smrg
2049706f2543Smrg    /* If requested, send an XSync to all back-end servers before swapping. */
2050706f2543Smrg    if (dmxGLXSyncSwap) {
2051706f2543Smrg	for (s=from_screen; s<=to_screen; s++)
2052706f2543Smrg	    XSync(GetBackEndDisplay(cl,s), False);
2053706f2543Smrg    }
2054706f2543Smrg
2055706f2543Smrg
2056706f2543Smrg    /* send the SwapBuffers request to all back-end servers */
2057706f2543Smrg
2058706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
2059706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2060706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
2061706f2543Smrg       unsigned int be_draw = 0;
2062706f2543Smrg
2063706f2543Smrg       if (pGlxPixmap) {
2064706f2543Smrg	  be_draw = (unsigned int)pGlxPixmap->be_xids[s];
2065706f2543Smrg       }
2066706f2543Smrg#ifdef PANORAMIX
2067706f2543Smrg       else if (pXinDraw) {
2068706f2543Smrg	  dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
2069706f2543Smrg       }
2070706f2543Smrg#endif
2071706f2543Smrg       else if (pGlxWindow) {
2072706f2543Smrg	  pWin = (WindowPtr)pGlxWindow->pDraw;
2073706f2543Smrg       }
2074706f2543Smrg
2075706f2543Smrg       if (pWin && !be_draw) {
2076706f2543Smrg	   be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
2077706f2543Smrg	   if (!be_draw) {
2078706f2543Smrg	      /* it might be that the window did not created yet on the */
2079706f2543Smrg	      /* back-end server (lazy window creation option), force   */
2080706f2543Smrg	      /* creation of the window */
2081706f2543Smrg	      dmxCreateAndRealizeWindow( pWin, TRUE );
2082706f2543Smrg	      be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
2083706f2543Smrg	   }
2084706f2543Smrg       }
2085706f2543Smrg
2086706f2543Smrg       dmxSync( dmxScreen, 1 );
2087706f2543Smrg
2088706f2543Smrg       LockDisplay(dpy);
2089706f2543Smrg       GetReq(GLXSwapBuffers,be_req);
2090706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
2091706f2543Smrg       be_req->glxCode = X_GLXSwapBuffers;
2092706f2543Smrg       be_req->drawable = be_draw;
2093706f2543Smrg       be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 );
2094706f2543Smrg       UnlockDisplay(dpy);
2095706f2543Smrg       SyncHandle();
2096706f2543Smrg       XFlush(dpy);
2097706f2543Smrg    }
2098706f2543Smrg
2099706f2543Smrg    return Success;
2100706f2543Smrg}
2101706f2543Smrg
2102706f2543Smrgint __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
2103706f2543Smrg{
2104706f2543Smrg    ClientPtr client = cl->client;
2105706f2543Smrg    DrawablePtr pDraw;
2106706f2543Smrg    xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
2107706f2543Smrg    GLXContextTag tag = req->contextTag;
2108706f2543Smrg    XID drawId = req->drawable;
2109706f2543Smrg    __GLXpixmap *pGlxPixmap = NULL;
2110706f2543Smrg    __GLXcontext *glxc = NULL;
2111706f2543Smrg    __glXWindow *pGlxWindow = NULL;
2112706f2543Smrg    int rc;
2113706f2543Smrg
2114706f2543Smrg    /*
2115706f2543Smrg    ** Check that the GLX drawable is valid.
2116706f2543Smrg    */
2117706f2543Smrg    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
2118706f2543Smrg    if (rc == Success) {
2119706f2543Smrg	if (pDraw->type != DRAWABLE_WINDOW) {
2120706f2543Smrg	    /*
2121706f2543Smrg	    ** Drawable is an X pixmap, which is not allowed.
2122706f2543Smrg	    */
2123706f2543Smrg	    client->errorValue = drawId;
2124706f2543Smrg	    return __glXBadDrawable;
2125706f2543Smrg	}
2126706f2543Smrg    }
2127706f2543Smrg
2128706f2543Smrg    if (!pDraw) {
2129706f2543Smrg	dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
2130706f2543Smrg				__glXPixmapRes, NullClient, DixUnknownAccess);
2131706f2543Smrg	if (pGlxPixmap) {
2132706f2543Smrg	    /*
2133706f2543Smrg	    ** Drawable is a GLX pixmap.
2134706f2543Smrg	    */
2135706f2543Smrg	   pDraw = pGlxPixmap->pDraw;
2136706f2543Smrg	}
2137706f2543Smrg    }
2138706f2543Smrg
2139706f2543Smrg    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
2140706f2543Smrg       dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
2141706f2543Smrg                               __glXWindowRes, NullClient, DixUnknownAccess);
2142706f2543Smrg       if (pGlxWindow) {
2143706f2543Smrg	  /*
2144706f2543Smrg	   ** Drawable is a GLXWindow.
2145706f2543Smrg	   */
2146706f2543Smrg	  pDraw = pGlxWindow->pDraw;
2147706f2543Smrg       }
2148706f2543Smrg    }
2149706f2543Smrg
2150706f2543Smrg    if (!pDraw) {
2151706f2543Smrg       /*
2152706f2543Smrg	** Drawable is neither a X window nor a GLX pixmap.
2153706f2543Smrg	*/
2154706f2543Smrg       client->errorValue = drawId;
2155706f2543Smrg       return __glXBadDrawable;
2156706f2543Smrg    }
2157706f2543Smrg
2158706f2543Smrg    if (tag) {
2159706f2543Smrg	glxc = __glXLookupContextByTag(cl, tag);
2160706f2543Smrg	if (!glxc) {
2161706f2543Smrg	    return __glXBadContextTag;
2162706f2543Smrg	}
2163706f2543Smrg    }
2164706f2543Smrg
2165706f2543Smrg    if (pDraw &&
2166706f2543Smrg	pDraw->type == DRAWABLE_WINDOW &&
2167706f2543Smrg	DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) {
2168706f2543Smrg	return SGSwapBuffers(cl, drawId, tag, pDraw);
2169706f2543Smrg    }
2170706f2543Smrg
2171706f2543Smrg    return __glXDoSwapBuffers(cl, drawId, tag);
2172706f2543Smrg}
2173706f2543Smrg
2174706f2543Smrg
2175706f2543Smrg/************************************************************************/
2176706f2543Smrg
2177706f2543Smrg/*
2178706f2543Smrg** Render and Renderlarge are not in the GLX API.  They are used by the GLX
2179706f2543Smrg** client library to send batches of GL rendering commands.
2180706f2543Smrg*/
2181706f2543Smrg
2182706f2543Smrg/*
2183706f2543Smrg** Execute all the drawing commands in a request.
2184706f2543Smrg*/
2185706f2543Smrgint __glXRender(__GLXclientState *cl, GLbyte *pc)
2186706f2543Smrg{
2187706f2543Smrg    xGLXRenderReq *req;
2188706f2543Smrg    xGLXRenderReq *be_req;
2189706f2543Smrg    int size;
2190706f2543Smrg    __GLXcontext *glxc;
2191706f2543Smrg    int from_screen = 0;
2192706f2543Smrg    int to_screen = 0;
2193706f2543Smrg    int s;
2194706f2543Smrg
2195706f2543Smrg    /*
2196706f2543Smrg    ** NOTE: much of this code also appears in the byteswapping version of this
2197706f2543Smrg    ** routine, __glXSwapRender().  Any changes made here should also be
2198706f2543Smrg    ** duplicated there.
2199706f2543Smrg    */
2200706f2543Smrg
2201706f2543Smrg    req = (xGLXRenderReq *) pc;
2202706f2543Smrg
2203706f2543Smrg    glxc = __glXLookupContextByTag(cl, req->contextTag);
2204706f2543Smrg    if (!glxc) {
2205706f2543Smrg	return 0;
2206706f2543Smrg    }
2207706f2543Smrg    from_screen = to_screen = glxc->pScreen->myNum;
2208706f2543Smrg
2209706f2543Smrg#ifdef PANORAMIX
2210706f2543Smrg    if (!noPanoramiXExtension) {
2211706f2543Smrg       from_screen = 0;
2212706f2543Smrg       to_screen = screenInfo.numScreens - 1;
2213706f2543Smrg    }
2214706f2543Smrg#endif
2215706f2543Smrg
2216706f2543Smrg    pc += sz_xGLXRenderReq;
2217706f2543Smrg    size = (req->length << 2) - sz_xGLXRenderReq;
2218706f2543Smrg
2219706f2543Smrg    /*
2220706f2543Smrg     * just forward the request to back-end server(s)
2221706f2543Smrg     */
2222706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
2223706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2224706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
2225706f2543Smrg
2226706f2543Smrg       LockDisplay(dpy);
2227706f2543Smrg       GetReq(GLXRender,be_req);
2228706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
2229706f2543Smrg       be_req->glxCode = X_GLXRender;
2230706f2543Smrg       be_req->length = req->length;
2231706f2543Smrg       be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
2232706f2543Smrg       _XSend(dpy, (const char *)pc, size);
2233706f2543Smrg       UnlockDisplay(dpy);
2234706f2543Smrg       SyncHandle();
2235706f2543Smrg    }
2236706f2543Smrg
2237706f2543Smrg    return Success;
2238706f2543Smrg}
2239706f2543Smrg
2240706f2543Smrg/*
2241706f2543Smrg** Execute a large rendering request (one that spans multiple X requests).
2242706f2543Smrg*/
2243706f2543Smrgint __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
2244706f2543Smrg{
2245706f2543Smrg    xGLXRenderLargeReq *req;
2246706f2543Smrg    xGLXRenderLargeReq *be_req;
2247706f2543Smrg    __GLXcontext *glxc;
2248706f2543Smrg    int from_screen = 0;
2249706f2543Smrg    int to_screen = 0;
2250706f2543Smrg    int s;
2251706f2543Smrg
2252706f2543Smrg    /*
2253706f2543Smrg    ** NOTE: much of this code also appears in the byteswapping version of this
2254706f2543Smrg    ** routine, __glXSwapRenderLarge().  Any changes made here should also be
2255706f2543Smrg    ** duplicated there.
2256706f2543Smrg    */
2257706f2543Smrg
2258706f2543Smrg    req = (xGLXRenderLargeReq *) pc;
2259706f2543Smrg    glxc = __glXLookupContextByTag(cl, req->contextTag);
2260706f2543Smrg    if (!glxc) {
2261706f2543Smrg	return 0;
2262706f2543Smrg    }
2263706f2543Smrg    from_screen = to_screen = glxc->pScreen->myNum;
2264706f2543Smrg
2265706f2543Smrg#ifdef PANORAMIX
2266706f2543Smrg    if (!noPanoramiXExtension) {
2267706f2543Smrg       from_screen = 0;
2268706f2543Smrg       to_screen = screenInfo.numScreens - 1;
2269706f2543Smrg    }
2270706f2543Smrg#endif
2271706f2543Smrg
2272706f2543Smrg    pc += sz_xGLXRenderLargeReq;
2273706f2543Smrg
2274706f2543Smrg    /*
2275706f2543Smrg     * just forward the request to back-end server(s)
2276706f2543Smrg     */
2277706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
2278706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2279706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
2280706f2543Smrg
2281706f2543Smrg       GetReq(GLXRenderLarge,be_req);
2282706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
2283706f2543Smrg       be_req->glxCode = X_GLXRenderLarge;
2284706f2543Smrg       be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
2285706f2543Smrg       be_req->length = req->length;
2286706f2543Smrg       be_req->requestNumber = req->requestNumber;
2287706f2543Smrg       be_req->requestTotal = req->requestTotal;
2288706f2543Smrg       be_req->dataBytes = req->dataBytes;
2289706f2543Smrg       Data(dpy, (const char *)pc, req->dataBytes);
2290706f2543Smrg       UnlockDisplay(dpy);
2291706f2543Smrg       SyncHandle();
2292706f2543Smrg
2293706f2543Smrg    }
2294706f2543Smrg
2295706f2543Smrg    return Success;
2296706f2543Smrg}
2297706f2543Smrg
2298706f2543Smrg
2299706f2543Smrg/************************************************************************/
2300706f2543Smrg
2301706f2543Smrgint __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
2302706f2543Smrg{
2303706f2543Smrg    xGLXVendorPrivateReq *req;
2304706f2543Smrg
2305706f2543Smrg    req = (xGLXVendorPrivateReq *) pc;
2306706f2543Smrg
2307706f2543Smrg    switch( req->vendorCode ) {
2308706f2543Smrg
2309706f2543Smrg       case X_GLvop_DeleteTexturesEXT:
2310706f2543Smrg	  return __glXVForwardSingleReq( cl, pc );
2311706f2543Smrg	  break;
2312706f2543Smrg
2313706f2543Smrg       case X_GLXvop_SwapIntervalSGI:
2314706f2543Smrg	  if (glxIsExtensionSupported("SGI_swap_control")) {
2315706f2543Smrg	     return __glXVForwardSingleReq( cl, pc );
2316706f2543Smrg	  }
2317706f2543Smrg	  else {
2318706f2543Smrg	     return Success;
2319706f2543Smrg	  }
2320706f2543Smrg	  break;
2321706f2543Smrg
2322706f2543Smrg#if 0 /* glx 1.3 */
2323706f2543Smrg       case X_GLXvop_CreateGLXVideoSourceSGIX:
2324706f2543Smrg	  break;
2325706f2543Smrg       case X_GLXvop_DestroyGLXVideoSourceSGIX:
2326706f2543Smrg	  break;
2327706f2543Smrg       case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
2328706f2543Smrg	  break;
2329706f2543Smrg       case X_GLXvop_DestroyGLXPbufferSGIX:
2330706f2543Smrg	  break;
2331706f2543Smrg       case X_GLXvop_ChangeDrawableAttributesSGIX:
2332706f2543Smrg	  break;
2333706f2543Smrg#endif
2334706f2543Smrg
2335706f2543Smrg       case X_GLXvop_BindSwapBarrierSGIX:
2336706f2543Smrg	  return __glXBindSwapBarrierSGIX( cl, pc );
2337706f2543Smrg	  break;
2338706f2543Smrg
2339706f2543Smrg       case X_GLXvop_JoinSwapGroupSGIX:
2340706f2543Smrg	  return __glXJoinSwapGroupSGIX( cl, pc );
2341706f2543Smrg	  break;
2342706f2543Smrg
2343706f2543Smrg       case X_GLXvop_CreateContextWithConfigSGIX:
2344706f2543Smrg	  return __glXCreateContextWithConfigSGIX( cl, pc );
2345706f2543Smrg	  break;
2346706f2543Smrg
2347706f2543Smrg       default:
2348706f2543Smrg	  /*
2349706f2543Smrg	   ** unsupported private request
2350706f2543Smrg	   */
2351706f2543Smrg	  cl->client->errorValue = req->vendorCode;
2352706f2543Smrg	  return __glXUnsupportedPrivateRequest;
2353706f2543Smrg    }
2354706f2543Smrg
2355706f2543Smrg    cl->client->errorValue = req->vendorCode;
2356706f2543Smrg    return __glXUnsupportedPrivateRequest;
2357706f2543Smrg
2358706f2543Smrg}
2359706f2543Smrg
2360706f2543Smrgint __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
2361706f2543Smrg{
2362706f2543Smrg    xGLXVendorPrivateWithReplyReq *req;
2363706f2543Smrg
2364706f2543Smrg    req = (xGLXVendorPrivateWithReplyReq *) pc;
2365706f2543Smrg
2366706f2543Smrg    switch( req->vendorCode ) {
2367706f2543Smrg
2368706f2543Smrg       case X_GLvop_GetConvolutionFilterEXT:
2369706f2543Smrg       case X_GLvop_GetConvolutionParameterfvEXT:
2370706f2543Smrg       case X_GLvop_GetConvolutionParameterivEXT:
2371706f2543Smrg       case X_GLvop_GetSeparableFilterEXT:
2372706f2543Smrg       case X_GLvop_GetHistogramEXT:
2373706f2543Smrg       case X_GLvop_GetHistogramParameterivEXT:
2374706f2543Smrg       case X_GLvop_GetMinmaxEXT:
2375706f2543Smrg       case X_GLvop_GetMinmaxParameterfvEXT:
2376706f2543Smrg       case X_GLvop_GetMinmaxParameterivEXT:
2377706f2543Smrg       case X_GLvop_AreTexturesResidentEXT:
2378706f2543Smrg       case X_GLvop_IsTextureEXT:
2379706f2543Smrg	  return( __glXVForwardPipe0WithReply(cl, pc) );
2380706f2543Smrg	  break;
2381706f2543Smrg
2382706f2543Smrg       case X_GLvop_GenTexturesEXT:
2383706f2543Smrg	  return( __glXVForwardAllWithReply(cl, pc) );
2384706f2543Smrg	  break;
2385706f2543Smrg
2386706f2543Smrg
2387706f2543Smrg#if 0 /* glx1.3 */
2388706f2543Smrg       case X_GLvop_GetDetailTexFuncSGIS:
2389706f2543Smrg       case X_GLvop_GetSharpenTexFuncSGIS:
2390706f2543Smrg       case X_GLvop_GetColorTableSGI:
2391706f2543Smrg       case X_GLvop_GetColorTableParameterfvSGI:
2392706f2543Smrg       case X_GLvop_GetColorTableParameterivSGI:
2393706f2543Smrg       case X_GLvop_GetTexFilterFuncSGIS:
2394706f2543Smrg       case X_GLvop_GetInstrumentsSGIX:
2395706f2543Smrg       case X_GLvop_InstrumentsBufferSGIX:
2396706f2543Smrg       case X_GLvop_PollInstrumentsSGIX:
2397706f2543Smrg       case X_GLvop_FlushRasterSGIX:
2398706f2543Smrg       case X_GLXvop_CreateGLXPbufferSGIX:
2399706f2543Smrg       case X_GLXvop_GetDrawableAttributesSGIX:
2400706f2543Smrg       case X_GLXvop_QueryHyperpipeNetworkSGIX:
2401706f2543Smrg       case X_GLXvop_QueryHyperpipeConfigSGIX:
2402706f2543Smrg       case X_GLXvop_HyperpipeConfigSGIX:
2403706f2543Smrg       case X_GLXvop_DestroyHyperpipeConfigSGIX:
2404706f2543Smrg#endif
2405706f2543Smrg       case X_GLXvop_QueryMaxSwapBarriersSGIX:
2406706f2543Smrg	  return( __glXQueryMaxSwapBarriersSGIX(cl, pc) );
2407706f2543Smrg	  break;
2408706f2543Smrg
2409706f2543Smrg       case X_GLXvop_GetFBConfigsSGIX:
2410706f2543Smrg	  return( __glXGetFBConfigsSGIX(cl, pc) );
2411706f2543Smrg	  break;
2412706f2543Smrg
2413706f2543Smrg       case X_GLXvop_MakeCurrentReadSGI:
2414706f2543Smrg	  return( __glXMakeCurrentReadSGI(cl, pc) );
2415706f2543Smrg	  break;
2416706f2543Smrg
2417706f2543Smrg       case X_GLXvop_QueryContextInfoEXT:
2418706f2543Smrg	  return( __glXQueryContextInfoEXT(cl,pc) );
2419706f2543Smrg	  break;
2420706f2543Smrg
2421706f2543Smrg       default:
2422706f2543Smrg	  /*
2423706f2543Smrg	   ** unsupported private request
2424706f2543Smrg	   */
2425706f2543Smrg	  cl->client->errorValue = req->vendorCode;
2426706f2543Smrg	  return __glXUnsupportedPrivateRequest;
2427706f2543Smrg    }
2428706f2543Smrg
2429706f2543Smrg}
2430706f2543Smrg
2431706f2543Smrgint __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
2432706f2543Smrg{
2433706f2543Smrg    ClientPtr client = cl->client;
2434706f2543Smrg    xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
2435706f2543Smrg    xGLXQueryExtensionsStringReply reply;
2436706f2543Smrg    GLint screen;
2437706f2543Smrg    size_t length;
2438706f2543Smrg    int len, numbytes;
2439706f2543Smrg    char *be_buf;
2440706f2543Smrg
2441706f2543Smrg#ifdef FWD_QUERY_REQ
2442706f2543Smrg    xGLXQueryExtensionsStringReq *be_req;
2443706f2543Smrg    xGLXQueryExtensionsStringReply be_reply;
2444706f2543Smrg    DMXScreenInfo *dmxScreen;
2445706f2543Smrg    Display *dpy;
2446706f2543Smrg    int slop;
2447706f2543Smrg#endif
2448706f2543Smrg
2449706f2543Smrg    screen = req->screen;
2450706f2543Smrg
2451706f2543Smrg    /*
2452706f2543Smrg    ** Check if screen exists.
2453706f2543Smrg    */
2454706f2543Smrg    if ((screen < 0) || (screen >= screenInfo.numScreens)) {
2455706f2543Smrg	client->errorValue = screen;
2456706f2543Smrg	return BadValue;
2457706f2543Smrg    }
2458706f2543Smrg
2459706f2543Smrg#ifdef FWD_QUERY_REQ
2460706f2543Smrg    dmxScreen = &dmxScreens[screen];
2461706f2543Smrg
2462706f2543Smrg    /* Send the glXQueryServerString request */
2463706f2543Smrg    dpy = GetBackEndDisplay(cl,screen);
2464706f2543Smrg    LockDisplay(dpy);
2465706f2543Smrg    GetReq(GLXQueryExtensionsString,be_req);
2466706f2543Smrg    be_req->reqType = dmxScreen->glxMajorOpcode;
2467706f2543Smrg    be_req->glxCode = X_GLXQueryServerString;
2468706f2543Smrg    be_req->screen = DefaultScreen(dpy);
2469706f2543Smrg    _XReply(dpy, (xReply*) &be_reply, 0, False);
2470706f2543Smrg    len = (int)be_reply.length;
2471706f2543Smrg    numbytes = (int)be_reply.n;
2472706f2543Smrg    slop = numbytes * __GLX_SIZE_INT8 & 3;
2473706f2543Smrg    be_buf = (char *)malloc(numbytes);
2474706f2543Smrg    if (!be_buf) {
2475706f2543Smrg        /* Throw data on the floor */
2476706f2543Smrg        _XEatData(dpy, len);
2477706f2543Smrg    } else {
2478706f2543Smrg        _XRead(dpy, (char *)be_buf, numbytes);
2479706f2543Smrg        if (slop) _XEatData(dpy,4-slop);
2480706f2543Smrg    }
2481706f2543Smrg    UnlockDisplay(dpy);
2482706f2543Smrg    SyncHandle();
2483706f2543Smrg
2484706f2543Smrg#else
2485706f2543Smrg
2486706f2543Smrg    be_buf = __glXGetServerString(GLX_EXTENSIONS);
2487706f2543Smrg    numbytes = strlen(be_buf) + 1;
2488706f2543Smrg    len = __GLX_PAD(numbytes) >> 2;
2489706f2543Smrg
2490706f2543Smrg#endif
2491706f2543Smrg
2492706f2543Smrg    length = len;
2493706f2543Smrg    reply.type = X_Reply;
2494706f2543Smrg    reply.sequenceNumber = client->sequence;
2495706f2543Smrg    reply.length = len;
2496706f2543Smrg    reply.n = numbytes;
2497706f2543Smrg
2498706f2543Smrg    if (client->swapped) {
2499706f2543Smrg        glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
2500706f2543Smrg    } else {
2501706f2543Smrg        WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
2502706f2543Smrg        WriteToClient(client, (int)(length << 2), (char *)be_buf);
2503706f2543Smrg    }
2504706f2543Smrg
2505706f2543Smrg    return Success;
2506706f2543Smrg}
2507706f2543Smrg
2508706f2543Smrgint __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
2509706f2543Smrg{
2510706f2543Smrg    ClientPtr client = cl->client;
2511706f2543Smrg    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
2512706f2543Smrg    xGLXQueryServerStringReply reply;
2513706f2543Smrg    int name;
2514706f2543Smrg    GLint screen;
2515706f2543Smrg    size_t length;
2516706f2543Smrg    int len, numbytes;
2517706f2543Smrg    char *be_buf;
2518706f2543Smrg#ifdef FWD_QUERY_REQ
2519706f2543Smrg    xGLXQueryServerStringReq *be_req;
2520706f2543Smrg    xGLXQueryServerStringReply be_reply;
2521706f2543Smrg    DMXScreenInfo *dmxScreen;
2522706f2543Smrg    Display *dpy;
2523706f2543Smrg    int  slop;
2524706f2543Smrg#endif
2525706f2543Smrg
2526706f2543Smrg    name = req->name;
2527706f2543Smrg    screen = req->screen;
2528706f2543Smrg    /*
2529706f2543Smrg    ** Check if screen exists.
2530706f2543Smrg    */
2531706f2543Smrg    if ((screen < 0) || (screen >= screenInfo.numScreens)) {
2532706f2543Smrg	client->errorValue = screen;
2533706f2543Smrg	return BadValue;
2534706f2543Smrg    }
2535706f2543Smrg
2536706f2543Smrg#ifdef FWD_QUERY_REQ
2537706f2543Smrg    dmxScreen = &dmxScreens[screen];
2538706f2543Smrg
2539706f2543Smrg    /* Send the glXQueryServerString request */
2540706f2543Smrg    dpy = GetBackEndDisplay(cl,screen);
2541706f2543Smrg    LockDisplay(dpy);
2542706f2543Smrg    GetReq(GLXQueryServerString,be_req);
2543706f2543Smrg    be_req->reqType = dmxScreen->glxMajorOpcode;
2544706f2543Smrg    be_req->glxCode = X_GLXQueryServerString;
2545706f2543Smrg    be_req->screen = DefaultScreen(dpy);
2546706f2543Smrg    be_req->name = name;
2547706f2543Smrg    _XReply(dpy, (xReply*) &be_reply, 0, False);
2548706f2543Smrg    len = (int)be_reply.length;
2549706f2543Smrg    numbytes = (int)be_reply.n;
2550706f2543Smrg    slop = numbytes * __GLX_SIZE_INT8 & 3;
2551706f2543Smrg    be_buf = (char *)malloc(numbytes);
2552706f2543Smrg    if (!be_buf) {
2553706f2543Smrg        /* Throw data on the floor */
2554706f2543Smrg        _XEatData(dpy, len);
2555706f2543Smrg    } else {
2556706f2543Smrg        _XRead(dpy, (char *)be_buf, numbytes);
2557706f2543Smrg        if (slop) _XEatData(dpy,4-slop);
2558706f2543Smrg    }
2559706f2543Smrg    UnlockDisplay(dpy);
2560706f2543Smrg    SyncHandle();
2561706f2543Smrg
2562706f2543Smrg#else
2563706f2543Smrg    be_buf = __glXGetServerString(name);
2564706f2543Smrg    numbytes = strlen(be_buf) + 1;
2565706f2543Smrg    len = __GLX_PAD(numbytes) >> 2;
2566706f2543Smrg#endif
2567706f2543Smrg
2568706f2543Smrg    length = len;
2569706f2543Smrg    reply.type = X_Reply;
2570706f2543Smrg    reply.sequenceNumber = client->sequence;
2571706f2543Smrg    reply.length = length;
2572706f2543Smrg    reply.n = numbytes;
2573706f2543Smrg
2574706f2543Smrg    if (client->swapped) {
2575706f2543Smrg        glxSwapQueryServerStringReply(client, &reply, be_buf);
2576706f2543Smrg    } else {
2577706f2543Smrg        WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
2578706f2543Smrg        WriteToClient(client, (int)(length << 2), be_buf);
2579706f2543Smrg    }
2580706f2543Smrg
2581706f2543Smrg    return Success;
2582706f2543Smrg}
2583706f2543Smrg
2584706f2543Smrgint __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
2585706f2543Smrg{
2586706f2543Smrg    xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
2587706f2543Smrg    xGLXClientInfoReq *be_req;
2588706f2543Smrg    const char *buf;
2589706f2543Smrg    int from_screen = 0;
2590706f2543Smrg    int to_screen = 0;
2591706f2543Smrg    int s;
2592706f2543Smrg
2593706f2543Smrg    cl->GLClientmajorVersion = req->major;
2594706f2543Smrg    cl->GLClientminorVersion = req->minor;
2595706f2543Smrg    free(cl->GLClientextensions);
2596706f2543Smrg    buf = (const char *)(req+1);
2597706f2543Smrg    cl->GLClientextensions = strdup(buf);
2598706f2543Smrg
2599706f2543Smrg    to_screen = screenInfo.numScreens - 1;
2600706f2543Smrg
2601706f2543Smrg    for (s=from_screen; s<=to_screen; s++)
2602706f2543Smrg    {
2603706f2543Smrg       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2604706f2543Smrg       Display *dpy = GetBackEndDisplay(cl,s);
2605706f2543Smrg
2606706f2543Smrg       LockDisplay(dpy);
2607706f2543Smrg       GetReq(GLXClientInfo,be_req);
2608706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
2609706f2543Smrg       be_req->glxCode = X_GLXClientInfo;
2610706f2543Smrg       be_req->major = req->major;
2611706f2543Smrg       be_req->minor = req->minor;
2612706f2543Smrg       be_req->length = req->length;
2613706f2543Smrg       be_req->numbytes = req->numbytes;
2614706f2543Smrg       Data(dpy, buf, req->numbytes);
2615706f2543Smrg
2616706f2543Smrg       UnlockDisplay(dpy);
2617706f2543Smrg       SyncHandle();
2618706f2543Smrg    }
2619706f2543Smrg
2620706f2543Smrg    return Success;
2621706f2543Smrg}
2622706f2543Smrg
2623706f2543Smrgint __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
2624706f2543Smrg{
2625706f2543Smrg    ClientPtr client = cl->client;
2626706f2543Smrg    xGLXUseXFontReq *req;
2627706f2543Smrg    xGLXUseXFontReq *be_req;
2628706f2543Smrg    FontPtr pFont;
2629706f2543Smrg    __GLXcontext *glxc = NULL;
2630706f2543Smrg    int from_screen = 0;
2631706f2543Smrg    int to_screen = 0;
2632706f2543Smrg    int s;
2633706f2543Smrg    dmxFontPrivPtr  pFontPriv;
2634706f2543Smrg    DMXScreenInfo *dmxScreen;
2635706f2543Smrg    Display *dpy;
2636706f2543Smrg
2637706f2543Smrg    req = (xGLXUseXFontReq *) pc;
2638706f2543Smrg
2639706f2543Smrg    if (req->contextTag != 0) {
2640706f2543Smrg	glxc = __glXLookupContextByTag(cl, req->contextTag);
2641706f2543Smrg	if (glxc) {
2642706f2543Smrg	   from_screen = to_screen = glxc->pScreen->myNum;
2643706f2543Smrg	}
2644706f2543Smrg    }
2645706f2543Smrg
2646706f2543Smrg    /*
2647706f2543Smrg    ** Font can actually be either the ID of a font or the ID of a GC
2648706f2543Smrg    ** containing a font.
2649706f2543Smrg    */
2650706f2543Smrg    dixLookupResourceByType((pointer*) &pFont, req->font, RT_FONT,
2651706f2543Smrg                            NullClient, DixUnknownAccess);
2652706f2543Smrg    if (!pFont) {
2653706f2543Smrg        GC *pGC;
2654706f2543Smrg        dixLookupResourceByType((pointer*) &pGC, req->font,
2655706f2543Smrg				RT_GC, NullClient,
2656706f2543Smrg				DixUnknownAccess);
2657706f2543Smrg        if (!pGC) {
2658706f2543Smrg	    client->errorValue = req->font;
2659706f2543Smrg            return BadFont;
2660706f2543Smrg	}
2661706f2543Smrg	pFont = pGC->font;
2662706f2543Smrg    }
2663706f2543Smrg
2664706f2543Smrg    pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
2665706f2543Smrg
2666706f2543Smrg#ifdef PANORAMIX
2667706f2543Smrg    if (!noPanoramiXExtension) {
2668706f2543Smrg       from_screen = 0;
2669706f2543Smrg       to_screen = screenInfo.numScreens - 1;
2670706f2543Smrg    }
2671706f2543Smrg#endif
2672706f2543Smrg
2673706f2543Smrg
2674706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
2675706f2543Smrg       dmxScreen = &dmxScreens[s];
2676706f2543Smrg       dpy = GetBackEndDisplay(cl,s);
2677706f2543Smrg
2678706f2543Smrg       dmxSync( dmxScreen, 1 );
2679706f2543Smrg
2680706f2543Smrg       LockDisplay(dpy);
2681706f2543Smrg       GetReq(GLXUseXFont,be_req);
2682706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
2683706f2543Smrg       be_req->glxCode = X_GLXUseXFont;
2684706f2543Smrg       be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
2685706f2543Smrg       be_req->font = pFontPriv->font[s]->fid;
2686706f2543Smrg       be_req->first = req->first;
2687706f2543Smrg       be_req->count = req->count;
2688706f2543Smrg       be_req->listBase = req->listBase;
2689706f2543Smrg       UnlockDisplay(dpy);
2690706f2543Smrg       SyncHandle();
2691706f2543Smrg
2692706f2543Smrg       XSync( dpy, False );
2693706f2543Smrg    }
2694706f2543Smrg
2695706f2543Smrg    return Success;
2696706f2543Smrg}
2697706f2543Smrg
2698706f2543Smrg/*
2699706f2543Smrg * start GLX 1.3 here
2700706f2543Smrg */
2701706f2543Smrg
2702706f2543Smrgint __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
2703706f2543Smrg{
2704706f2543Smrg    ClientPtr client = cl->client;
2705706f2543Smrg    xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
2706706f2543Smrg    xGLXGetFBConfigsReply reply;
2707706f2543Smrg    __GLXFBConfig *pFBConfig;
2708706f2543Smrg    CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS];
2709706f2543Smrg    int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS;
2710706f2543Smrg    unsigned int screen = req->screen;
2711706f2543Smrg    int numFBConfigs, i, p;
2712706f2543Smrg    __GLXscreenInfo *pGlxScreen;
2713706f2543Smrg
2714706f2543Smrg    if (screen >= screenInfo.numScreens) {
2715706f2543Smrg	/* The client library must send a valid screen number. */
2716706f2543Smrg	client->errorValue = screen;
2717706f2543Smrg	return BadValue;
2718706f2543Smrg    }
2719706f2543Smrg
2720706f2543Smrg    pGlxScreen = &__glXActiveScreens[screen];
2721706f2543Smrg    numFBConfigs = __glXNumFBConfigs;
2722706f2543Smrg
2723706f2543Smrg    reply.numFBConfigs = numFBConfigs;
2724706f2543Smrg    reply.numAttribs = numAttribs;
2725706f2543Smrg    reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2;
2726706f2543Smrg    reply.type = X_Reply;
2727706f2543Smrg    reply.sequenceNumber = client->sequence;
2728706f2543Smrg
2729706f2543Smrg    if (client->swapped) {
2730706f2543Smrg	__GLX_DECLARE_SWAP_VARIABLES;
2731706f2543Smrg	__GLX_SWAP_SHORT(&reply.sequenceNumber);
2732706f2543Smrg	__GLX_SWAP_INT(&reply.length);
2733706f2543Smrg	__GLX_SWAP_INT(&reply.numFBConfigs);
2734706f2543Smrg	__GLX_SWAP_INT(&reply.numAttribs);
2735706f2543Smrg    }
2736706f2543Smrg    WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
2737706f2543Smrg
2738706f2543Smrg    for (i=0; i < numFBConfigs; i++) {
2739706f2543Smrg       int associatedVisualId = 0;
2740706f2543Smrg       int drawableTypeIndex;
2741706f2543Smrg       pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ];
2742706f2543Smrg
2743706f2543Smrg	p = 0;
2744706f2543Smrg	/* core attributes */
2745706f2543Smrg	buf[p++] = GLX_FBCONFIG_ID;
2746706f2543Smrg	buf[p++] = pFBConfig->id;
2747706f2543Smrg	buf[p++] = GLX_BUFFER_SIZE;
2748706f2543Smrg	buf[p++] = pFBConfig->indexBits;
2749706f2543Smrg	buf[p++] = GLX_LEVEL;
2750706f2543Smrg	buf[p++] = pFBConfig->level;
2751706f2543Smrg	buf[p++] = GLX_DOUBLEBUFFER;
2752706f2543Smrg	buf[p++] = pFBConfig->doubleBufferMode;
2753706f2543Smrg	buf[p++] = GLX_STEREO;
2754706f2543Smrg	buf[p++] = pFBConfig->stereoMode;
2755706f2543Smrg	buf[p++] = GLX_AUX_BUFFERS;
2756706f2543Smrg	buf[p++] = pFBConfig->maxAuxBuffers;
2757706f2543Smrg	buf[p++] = GLX_RED_SIZE;
2758706f2543Smrg	buf[p++] = pFBConfig->redBits;
2759706f2543Smrg	buf[p++] = GLX_GREEN_SIZE;
2760706f2543Smrg	buf[p++] = pFBConfig->greenBits;
2761706f2543Smrg	buf[p++] = GLX_BLUE_SIZE;
2762706f2543Smrg	buf[p++] = pFBConfig->blueBits;
2763706f2543Smrg	buf[p++] = GLX_ALPHA_SIZE;
2764706f2543Smrg	buf[p++] = pFBConfig->alphaBits;
2765706f2543Smrg	buf[p++] = GLX_DEPTH_SIZE;
2766706f2543Smrg	buf[p++] = pFBConfig->depthBits;
2767706f2543Smrg	buf[p++] = GLX_STENCIL_SIZE;
2768706f2543Smrg	buf[p++] = pFBConfig->stencilBits;
2769706f2543Smrg	buf[p++] = GLX_ACCUM_RED_SIZE;
2770706f2543Smrg	buf[p++] = pFBConfig->accumRedBits;
2771706f2543Smrg	buf[p++] = GLX_ACCUM_GREEN_SIZE;
2772706f2543Smrg	buf[p++] = pFBConfig->accumGreenBits;
2773706f2543Smrg	buf[p++] = GLX_ACCUM_BLUE_SIZE;
2774706f2543Smrg	buf[p++] = pFBConfig->accumBlueBits;
2775706f2543Smrg	buf[p++] = GLX_ACCUM_ALPHA_SIZE;
2776706f2543Smrg	buf[p++] = pFBConfig->accumAlphaBits;
2777706f2543Smrg	buf[p++] = GLX_RENDER_TYPE;
2778706f2543Smrg	buf[p++] = pFBConfig->renderType;
2779706f2543Smrg	buf[p++] = GLX_DRAWABLE_TYPE;
2780706f2543Smrg	drawableTypeIndex = p;
2781706f2543Smrg	buf[p++] = pFBConfig->drawableType;
2782706f2543Smrg	buf[p++] = GLX_X_VISUAL_TYPE;
2783706f2543Smrg	buf[p++] = pFBConfig->visualType;
2784706f2543Smrg	buf[p++] = GLX_CONFIG_CAVEAT;
2785706f2543Smrg	buf[p++] = pFBConfig->visualCaveat;
2786706f2543Smrg	buf[p++] = GLX_TRANSPARENT_TYPE;
2787706f2543Smrg	buf[p++] = pFBConfig->transparentType;
2788706f2543Smrg	buf[p++] = GLX_TRANSPARENT_RED_VALUE;
2789706f2543Smrg	buf[p++] = pFBConfig->transparentRed;
2790706f2543Smrg	buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
2791706f2543Smrg	buf[p++] = pFBConfig->transparentGreen;
2792706f2543Smrg	buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
2793706f2543Smrg	buf[p++] = pFBConfig->transparentBlue;
2794706f2543Smrg	buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
2795706f2543Smrg	buf[p++] = pFBConfig->transparentAlpha;
2796706f2543Smrg	buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
2797706f2543Smrg	buf[p++] = pFBConfig->transparentIndex;
2798706f2543Smrg	buf[p++] = GLX_MAX_PBUFFER_WIDTH;
2799706f2543Smrg	buf[p++] = pFBConfig->maxPbufferWidth;
2800706f2543Smrg	buf[p++] = GLX_MAX_PBUFFER_HEIGHT;
2801706f2543Smrg	buf[p++] = pFBConfig->maxPbufferHeight;
2802706f2543Smrg	buf[p++] = GLX_MAX_PBUFFER_PIXELS;
2803706f2543Smrg	buf[p++] = pFBConfig->maxPbufferPixels;
2804706f2543Smrg
2805706f2543Smrg	/*
2806706f2543Smrg         * find the visual of the back-end server and match a visual
2807706f2543Smrg	 * on the proxy.
2808706f2543Smrg	 * do only once - if a visual is not yet associated.
2809706f2543Smrg	 */
2810706f2543Smrg	if (pFBConfig->associatedVisualId == (unsigned int)-1) {
2811706f2543Smrg	   DMXScreenInfo *dmxScreen = &dmxScreens[screen];
2812706f2543Smrg	   __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ];
2813706f2543Smrg	   __GLXvisualConfig *pGlxVisual = NULL;
2814706f2543Smrg	   int v;
2815706f2543Smrg	   int found = 0;
2816706f2543Smrg	   for (v=0; v<dmxScreen->numGlxVisuals; v++) {
2817706f2543Smrg	      if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) {
2818706f2543Smrg		 pGlxVisual = &dmxScreen->glxVisuals[v];
2819706f2543Smrg		 break;
2820706f2543Smrg	      }
2821706f2543Smrg	   }
2822706f2543Smrg
2823706f2543Smrg	   if (pGlxVisual) {
2824706f2543Smrg	      for (v=0; v<pGlxScreen->numVisuals; v++) {
2825706f2543Smrg		 if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) {
2826706f2543Smrg		    associatedVisualId = pGlxScreen->pGlxVisual[v].vid;
2827706f2543Smrg		    found = 1;
2828706f2543Smrg		    break;
2829706f2543Smrg		 }
2830706f2543Smrg	      }
2831706f2543Smrg	   }
2832706f2543Smrg
2833706f2543Smrg	   if (!found) {
2834706f2543Smrg	      associatedVisualId = 0;
2835706f2543Smrg	      pFBConfig->drawableType &= ~(GLX_WINDOW_BIT);
2836706f2543Smrg	      buf[drawableTypeIndex] = pFBConfig->drawableType;
2837706f2543Smrg	   }
2838706f2543Smrg#ifdef PANORAMIX
2839706f2543Smrg	   else if (!noPanoramiXExtension) {
2840706f2543Smrg	      /* convert the associated visualId to the panoramix one */
2841706f2543Smrg	      pFBConfig->associatedVisualId =
2842706f2543Smrg		  PanoramiXTranslateVisualID(screen, v);
2843706f2543Smrg	   }
2844706f2543Smrg#endif
2845706f2543Smrg	}
2846706f2543Smrg	else {
2847706f2543Smrg	   associatedVisualId = pFBConfig->associatedVisualId;
2848706f2543Smrg	}
2849706f2543Smrg
2850706f2543Smrg	buf[p++] = GLX_VISUAL_ID;
2851706f2543Smrg	buf[p++] = associatedVisualId;
2852706f2543Smrg
2853706f2543Smrg	/* SGIS_multisample attributes */
2854706f2543Smrg	buf[p++] = GLX_SAMPLES_SGIS;
2855706f2543Smrg	buf[p++] = pFBConfig->multiSampleSize;
2856706f2543Smrg	buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
2857706f2543Smrg	buf[p++] = pFBConfig->nMultiSampleBuffers;
2858706f2543Smrg
2859706f2543Smrg	/* SGIX_pbuffer specific attributes */
2860706f2543Smrg	buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX;
2861706f2543Smrg	buf[p++] = pFBConfig->optimalPbufferWidth;
2862706f2543Smrg	buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX;
2863706f2543Smrg	buf[p++] = pFBConfig->optimalPbufferHeight;
2864706f2543Smrg
2865706f2543Smrg	buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
2866706f2543Smrg	buf[p++] = pFBConfig->visualSelectGroup;
2867706f2543Smrg
2868706f2543Smrg	if (client->swapped) {
2869706f2543Smrg	    __GLX_DECLARE_SWAP_VARIABLES;
2870706f2543Smrg	    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
2871706f2543Smrg	    __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs);
2872706f2543Smrg	}
2873706f2543Smrg	WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf);
2874706f2543Smrg    }
2875706f2543Smrg    return Success;
2876706f2543Smrg}
2877706f2543Smrg
2878706f2543Smrgint __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
2879706f2543Smrg{
2880706f2543Smrg   xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
2881706f2543Smrg   xGLXGetFBConfigsReq new_req;
2882706f2543Smrg
2883706f2543Smrg   new_req.reqType = req->reqType;
2884706f2543Smrg   new_req.glxCode = req->glxCode;
2885706f2543Smrg   new_req.length = req->length;
2886706f2543Smrg   new_req.screen = req->screen;
2887706f2543Smrg
2888706f2543Smrg   return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) );
2889706f2543Smrg}
2890706f2543Smrg
2891706f2543Smrg
2892706f2543Smrgint __glXCreateWindow(__GLXclientState *cl, GLbyte *pc)
2893706f2543Smrg{
2894706f2543Smrg    ClientPtr client = cl->client;
2895706f2543Smrg    xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
2896706f2543Smrg    int screen = req->screen;
2897706f2543Smrg    GLXFBConfigID fbconfigId = req->fbconfig;
2898706f2543Smrg    XID windowId = req->window;
2899706f2543Smrg    XID glxwindowId = req->glxwindow;
2900706f2543Smrg    DrawablePtr pDraw;
2901706f2543Smrg    ScreenPtr pScreen;
2902706f2543Smrg    __glXWindow *pGlxWindow;
2903706f2543Smrg    __GLXFBConfig *pGlxFBConfig = NULL;
2904706f2543Smrg    VisualPtr pVisual;
2905706f2543Smrg    VisualID visId;
2906706f2543Smrg    int i, rc;
2907706f2543Smrg    pointer val;
2908706f2543Smrg
2909706f2543Smrg    /*
2910706f2543Smrg    ** Check if windowId is valid
2911706f2543Smrg    */
2912706f2543Smrg    rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
2913706f2543Smrg			   DixAddAccess);
2914706f2543Smrg    if (rc != Success)
2915706f2543Smrg	return rc;
2916706f2543Smrg
2917706f2543Smrg    /*
2918706f2543Smrg    ** Check if screen of window matches screen of fbconfig.
2919706f2543Smrg    */
2920706f2543Smrg    pScreen = pDraw->pScreen;
2921706f2543Smrg    if (screen != pScreen->myNum) {
2922706f2543Smrg	return BadMatch;
2923706f2543Smrg    }
2924706f2543Smrg
2925706f2543Smrg    /*
2926706f2543Smrg    ** Find the FBConfigRec for this fbconfigid.
2927706f2543Smrg    */
2928706f2543Smrg    if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
2929706f2543Smrg	client->errorValue = fbconfigId;
2930706f2543Smrg	return __glXBadFBConfig;
2931706f2543Smrg    }
2932706f2543Smrg    visId = pGlxFBConfig->associatedVisualId;
2933706f2543Smrg
2934706f2543Smrg    /*
2935706f2543Smrg    ** Check if the fbconfig supports rendering to windows
2936706f2543Smrg    */
2937706f2543Smrg    if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) {
2938706f2543Smrg	return BadMatch;
2939706f2543Smrg    }
2940706f2543Smrg
2941706f2543Smrg    if (visId != None) {
2942706f2543Smrg       /*
2943706f2543Smrg	** Check if the visual ID is valid for this screen.
2944706f2543Smrg	*/
2945706f2543Smrg       pVisual = pScreen->visuals;
2946706f2543Smrg       for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
2947706f2543Smrg	  if (pVisual->vid == visId) {
2948706f2543Smrg	     break;
2949706f2543Smrg	  }
2950706f2543Smrg       }
2951706f2543Smrg       if (i == pScreen->numVisuals) {
2952706f2543Smrg	  client->errorValue = visId;
2953706f2543Smrg	  return BadValue;
2954706f2543Smrg       }
2955706f2543Smrg
2956706f2543Smrg        /*
2957706f2543Smrg        ** Check if color buffer depth of fbconfig matches depth
2958706f2543Smrg	** of window.
2959706f2543Smrg        */
2960706f2543Smrg        if (pVisual->nplanes != pDraw->depth) {
2961706f2543Smrg	    return BadMatch;
2962706f2543Smrg	}
2963706f2543Smrg    } else
2964706f2543Smrg	/*
2965706f2543Smrg	** The window was created with no visual that corresponds
2966706f2543Smrg	** to fbconfig
2967706f2543Smrg	*/
2968706f2543Smrg	return BadMatch;
2969706f2543Smrg
2970706f2543Smrg    /*
2971706f2543Smrg    ** Check if there is already a fbconfig associated with this window
2972706f2543Smrg    */
2973706f2543Smrg    if (Success == dixLookupResourceByType(&val,
2974706f2543Smrg					   glxwindowId, __glXWindowRes,
2975706f2543Smrg					   NullClient, DixUnknownAccess)) {
2976706f2543Smrg	client->errorValue = glxwindowId;
2977706f2543Smrg	return BadAlloc;
2978706f2543Smrg    }
2979706f2543Smrg
2980706f2543Smrg    pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow));
2981706f2543Smrg    if (!pGlxWindow) {
2982706f2543Smrg	return BadAlloc;
2983706f2543Smrg    }
2984706f2543Smrg
2985706f2543Smrg    /*
2986706f2543Smrg    ** Register this GLX window as a resource
2987706f2543Smrg    */
2988706f2543Smrg    if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) {
2989706f2543Smrg	return BadAlloc;
2990706f2543Smrg    }
2991706f2543Smrg
2992706f2543Smrg    pGlxWindow->pDraw = pDraw;
2993706f2543Smrg    pGlxWindow->type = GLX_GLXWINDOW_TYPE;
2994706f2543Smrg    pGlxWindow->idExists = True;
2995706f2543Smrg    pGlxWindow->refcnt = 0;
2996706f2543Smrg    pGlxWindow->pGlxFBConfig = pGlxFBConfig;
2997706f2543Smrg    pGlxWindow->pScreen = pScreen;
2998706f2543Smrg
2999706f2543Smrg    return Success;
3000706f2543Smrg}
3001706f2543Smrg
3002706f2543Smrgint __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
3003706f2543Smrg{
3004706f2543Smrg    ClientPtr client = cl->client;
3005706f2543Smrg    xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
3006706f2543Smrg    XID glxwindow = req->glxwindow;
3007706f2543Smrg    pointer val;
3008706f2543Smrg
3009706f2543Smrg    /*
3010706f2543Smrg    ** Check if it's a valid GLX window.
3011706f2543Smrg    */
3012706f2543Smrg    if (Success != dixLookupResourceByType(&val,
3013706f2543Smrg					   glxwindow, __glXWindowRes,
3014706f2543Smrg					   NullClient, DixUnknownAccess)) {
3015706f2543Smrg	client->errorValue = glxwindow;
3016706f2543Smrg	return __glXBadDrawable;
3017706f2543Smrg    }
3018706f2543Smrg    /*
3019706f2543Smrg    ** The glx window destructor will check whether it's current before
3020706f2543Smrg    ** freeing anything.
3021706f2543Smrg    */
3022706f2543Smrg    FreeResource(glxwindow, RT_NONE);
3023706f2543Smrg
3024706f2543Smrg    return Success;
3025706f2543Smrg}
3026706f2543Smrg
3027706f2543Smrgint __glXQueryContext(__GLXclientState *cl, GLbyte *pc)
3028706f2543Smrg{
3029706f2543Smrg    ClientPtr client = cl->client;
3030706f2543Smrg    __GLXcontext *ctx;
3031706f2543Smrg    xGLXQueryContextReq *req;
3032706f2543Smrg    xGLXQueryContextReply reply;
3033706f2543Smrg    int nProps;
3034706f2543Smrg    int *sendBuf, *pSendBuf;
3035706f2543Smrg    int nReplyBytes;
3036706f2543Smrg
3037706f2543Smrg    req = (xGLXQueryContextReq *)pc;
3038706f2543Smrg    dixLookupResourceByType((pointer*) &ctx, req->context, __glXContextRes,
3039706f2543Smrg                            NullClient, DixUnknownAccess);
3040706f2543Smrg    if (!ctx) {
3041706f2543Smrg        client->errorValue = req->context;
3042706f2543Smrg        return __glXBadContext;
3043706f2543Smrg    }
3044706f2543Smrg
3045706f2543Smrg    nProps = 3;
3046706f2543Smrg
3047706f2543Smrg    reply.length = nProps << 1;
3048706f2543Smrg    reply.type = X_Reply;
3049706f2543Smrg    reply.sequenceNumber = client->sequence;
3050706f2543Smrg    reply.n = nProps;
3051706f2543Smrg
3052706f2543Smrg    nReplyBytes = reply.length << 2;
3053706f2543Smrg    sendBuf = (int *)malloc(nReplyBytes);
3054706f2543Smrg    pSendBuf = sendBuf;
3055706f2543Smrg    *pSendBuf++ = GLX_FBCONFIG_ID;
3056706f2543Smrg    *pSendBuf++ = (int)(ctx->pFBConfig->id);
3057706f2543Smrg    *pSendBuf++ = GLX_RENDER_TYPE;
3058706f2543Smrg    *pSendBuf++ = (int)(ctx->pFBConfig->renderType);
3059706f2543Smrg    *pSendBuf++ = GLX_SCREEN;
3060706f2543Smrg    *pSendBuf++ = (int)(ctx->pScreen->myNum);
3061706f2543Smrg
3062706f2543Smrg    if (client->swapped) {
3063706f2543Smrg        __glXSwapQueryContextReply(client, &reply, sendBuf);
3064706f2543Smrg    } else {
3065706f2543Smrg        WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply);
3066706f2543Smrg        WriteToClient(client, nReplyBytes, (char *)sendBuf);
3067706f2543Smrg    }
3068706f2543Smrg    free((char *)sendBuf);
3069706f2543Smrg
3070706f2543Smrg    return Success;
3071706f2543Smrg}
3072706f2543Smrg
3073706f2543Smrgint __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
3074706f2543Smrg{
3075706f2543Smrg    ClientPtr client = cl->client;
3076706f2543Smrg    __GLXcontext *ctx;
3077706f2543Smrg    xGLXQueryContextInfoEXTReq *req;
3078706f2543Smrg    xGLXQueryContextInfoEXTReply reply;
3079706f2543Smrg    int nProps;
3080706f2543Smrg    int *sendBuf, *pSendBuf;
3081706f2543Smrg    int nReplyBytes;
3082706f2543Smrg
3083706f2543Smrg    req = (xGLXQueryContextInfoEXTReq *)pc;
3084706f2543Smrg    dixLookupResourceByType((pointer*) &ctx,
3085706f2543Smrg			    req->context, __glXContextRes,
3086706f2543Smrg			    client,  DixReadAccess);
3087706f2543Smrg
3088706f2543Smrg    if (!ctx) {
3089706f2543Smrg        client->errorValue = req->context;
3090706f2543Smrg        return __glXBadContext;
3091706f2543Smrg    }
3092706f2543Smrg
3093706f2543Smrg    nProps = 4;
3094706f2543Smrg
3095706f2543Smrg    reply.length = nProps << 1;
3096706f2543Smrg    reply.type = X_Reply;
3097706f2543Smrg    reply.sequenceNumber = client->sequence;
3098706f2543Smrg    reply.n = nProps;
3099706f2543Smrg
3100706f2543Smrg    nReplyBytes = reply.length << 2;
3101706f2543Smrg    sendBuf = (int *)malloc(nReplyBytes);
3102706f2543Smrg    pSendBuf = sendBuf;
3103706f2543Smrg    *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
3104706f2543Smrg    *pSendBuf++ = (int)(ctx->share_id);
3105706f2543Smrg    *pSendBuf++ = GLX_VISUAL_ID_EXT;
3106706f2543Smrg    *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0);
3107706f2543Smrg    *pSendBuf++ = GLX_SCREEN_EXT;
3108706f2543Smrg    *pSendBuf++ = (int)(ctx->pScreen->myNum);
3109706f2543Smrg    *pSendBuf++ = GLX_FBCONFIG_ID;
3110706f2543Smrg    *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0);
3111706f2543Smrg
3112706f2543Smrg    if (client->swapped) {
3113706f2543Smrg        __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
3114706f2543Smrg    } else {
3115706f2543Smrg        WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
3116706f2543Smrg        WriteToClient(client, nReplyBytes, (char *)sendBuf);
3117706f2543Smrg    }
3118706f2543Smrg    free((char *)sendBuf);
3119706f2543Smrg
3120706f2543Smrg    return Success;
3121706f2543Smrg}
3122706f2543Smrg
3123706f2543Smrgint __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
3124706f2543Smrg{
3125706f2543Smrg    ClientPtr client = cl->client;
3126706f2543Smrg    xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
3127706f2543Smrg    xGLXCreatePbufferReq *be_req;
3128706f2543Smrg    int screen = req->screen;
3129706f2543Smrg    GLXFBConfigID fbconfigId = req->fbconfig;
3130706f2543Smrg    GLXPbuffer pbuffer = req->pbuffer;
3131706f2543Smrg    __glXPbuffer *pGlxPbuffer;
3132706f2543Smrg    int numAttribs = req->numAttribs;
3133706f2543Smrg    int *attr;
3134706f2543Smrg    ScreenPtr pScreen;
3135706f2543Smrg    __GLXFBConfig *pGlxFBConfig;
3136706f2543Smrg    __GLXFBConfig *be_pGlxFBConfig;
3137706f2543Smrg    XID be_xid;
3138706f2543Smrg    Display *dpy;
3139706f2543Smrg    DMXScreenInfo *dmxScreen;
3140706f2543Smrg    int s;
3141706f2543Smrg    int from_screen, to_screen;
3142706f2543Smrg
3143706f2543Smrg   /*
3144706f2543Smrg    ** Look up screen and FBConfig.
3145706f2543Smrg    */
3146706f2543Smrg    if (screen >= screenInfo.numScreens) {
3147706f2543Smrg        /* The client library must send a valid screen number. */
3148706f2543Smrg        client->errorValue = screen;
3149706f2543Smrg        return BadValue;
3150706f2543Smrg    }
3151706f2543Smrg    pScreen = screenInfo.screens[screen];
3152706f2543Smrg
3153706f2543Smrg    /*
3154706f2543Smrg    ** Find the FBConfigRec for this fbconfigid.
3155706f2543Smrg    */
3156706f2543Smrg    if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
3157706f2543Smrg	client->errorValue = fbconfigId;
3158706f2543Smrg	return __glXBadFBConfig;
3159706f2543Smrg    }
3160706f2543Smrg
3161706f2543Smrg    /*
3162706f2543Smrg    ** Create the GLX part of the Pbuffer.
3163706f2543Smrg    */
3164706f2543Smrg    pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer));
3165706f2543Smrg    if (!pGlxPbuffer) {
3166706f2543Smrg        return BadAlloc;
3167706f2543Smrg    }
3168706f2543Smrg
3169706f2543Smrg    pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens );
3170706f2543Smrg    if (!pGlxPbuffer->be_xids) {
3171706f2543Smrg        free(pGlxPbuffer);
3172706f2543Smrg        return BadAlloc;
3173706f2543Smrg    }
3174706f2543Smrg
3175706f2543Smrg    /*
3176706f2543Smrg     * Allocate an XID on the back-end server(s) and send him the request
3177706f2543Smrg     */
3178706f2543Smrg    from_screen = to_screen = screen;
3179706f2543Smrg#ifdef PANORAMIX
3180706f2543Smrg    if (!noPanoramiXExtension) {
3181706f2543Smrg       from_screen = 0;
3182706f2543Smrg       to_screen = screenInfo.numScreens - 1;
3183706f2543Smrg    }
3184706f2543Smrg#endif
3185706f2543Smrg
3186706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
3187706f2543Smrg       dpy = GetBackEndDisplay(cl,s);
3188706f2543Smrg       be_xid = XAllocID(dpy);
3189706f2543Smrg       dmxScreen = &dmxScreens[s];
3190706f2543Smrg       be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s );
3191706f2543Smrg
3192706f2543Smrg       attr = (int *)( req+1 );
3193706f2543Smrg
3194706f2543Smrg       LockDisplay(dpy);
3195706f2543Smrg       GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req);
3196706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
3197706f2543Smrg       be_req->glxCode = X_GLXCreatePbuffer;
3198706f2543Smrg       be_req->screen = be_pGlxFBConfig->screen;
3199706f2543Smrg       be_req->fbconfig = be_pGlxFBConfig->id;
3200706f2543Smrg       be_req->pbuffer = be_xid;
3201706f2543Smrg       be_req->numAttribs = numAttribs;
3202706f2543Smrg
3203706f2543Smrg       /* Send attributes */
3204706f2543Smrg       if ( attr != NULL ) {
3205706f2543Smrg	  CARD32 *pc = (CARD32 *)(be_req + 1);
3206706f2543Smrg
3207706f2543Smrg	  while (numAttribs-- > 0) {
3208706f2543Smrg	     *pc++ = *attr++;     /* token */
3209706f2543Smrg	     *pc++ = *attr++;     /* value */
3210706f2543Smrg	  }
3211706f2543Smrg       }
3212706f2543Smrg
3213706f2543Smrg       UnlockDisplay(dpy);
3214706f2543Smrg       SyncHandle();
3215706f2543Smrg
3216706f2543Smrg       pGlxPbuffer->be_xids[s] = be_xid;
3217706f2543Smrg    }
3218706f2543Smrg
3219706f2543Smrg
3220706f2543Smrg    pGlxPbuffer->idExists = True;
3221706f2543Smrg    pGlxPbuffer->refcnt = 0;
3222706f2543Smrg    pGlxPbuffer->pFBConfig = pGlxFBConfig;
3223706f2543Smrg    pGlxPbuffer->pScreen = pScreen;
3224706f2543Smrg
3225706f2543Smrg    /*
3226706f2543Smrg    ** Register the resource.
3227706f2543Smrg    */
3228706f2543Smrg    if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) {
3229706f2543Smrg        return BadAlloc;
3230706f2543Smrg    }
3231706f2543Smrg
3232706f2543Smrg    return Success;
3233706f2543Smrg
3234706f2543Smrg}
3235706f2543Smrg
3236706f2543Smrgint __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
3237706f2543Smrg{
3238706f2543Smrg    ClientPtr client = cl->client;
3239706f2543Smrg    xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
3240706f2543Smrg    xGLXDestroyPbufferReq *be_req;
3241706f2543Smrg    GLXPbuffer pbuffer = req->pbuffer;
3242706f2543Smrg    Display *dpy;
3243706f2543Smrg    int screen;
3244706f2543Smrg    DMXScreenInfo *dmxScreen;
3245706f2543Smrg    __glXPbuffer *pGlxPbuffer;
3246706f2543Smrg    int s;
3247706f2543Smrg    int from_screen, to_screen;
3248706f2543Smrg
3249706f2543Smrg    /*
3250706f2543Smrg    ** Check if it's a valid Pbuffer
3251706f2543Smrg    */
3252706f2543Smrg    dixLookupResourceByType((pointer*) &pGlxPbuffer, pbuffer,
3253706f2543Smrg                            __glXPbufferRes, NullClient, DixUnknownAccess);
3254706f2543Smrg    if (!pGlxPbuffer) {
3255706f2543Smrg	client->errorValue = pbuffer;
3256706f2543Smrg	return __glXBadPbuffer;
3257706f2543Smrg    }
3258706f2543Smrg
3259706f2543Smrg    screen = pGlxPbuffer->pScreen->myNum;
3260706f2543Smrg
3261706f2543Smrg    from_screen = to_screen = screen;
3262706f2543Smrg#ifdef PANORAMIX
3263706f2543Smrg    if (!noPanoramiXExtension) {
3264706f2543Smrg       from_screen = 0;
3265706f2543Smrg       to_screen = screenInfo.numScreens - 1;
3266706f2543Smrg    }
3267706f2543Smrg#endif
3268706f2543Smrg
3269706f2543Smrg    for (s=from_screen; s<=to_screen; s++) {
3270706f2543Smrg       dpy = GetBackEndDisplay(cl,s);
3271706f2543Smrg       dmxScreen = &dmxScreens[s];
3272706f2543Smrg
3273706f2543Smrg       /* send the destroy request to the back-end server */
3274706f2543Smrg       LockDisplay(dpy);
3275706f2543Smrg       GetReq(GLXDestroyPbuffer, be_req);
3276706f2543Smrg       be_req->reqType = dmxScreen->glxMajorOpcode;
3277706f2543Smrg       be_req->glxCode = X_GLXDestroyPbuffer;
3278706f2543Smrg       be_req->pbuffer = pGlxPbuffer->be_xids[s];
3279706f2543Smrg       UnlockDisplay(dpy);
3280706f2543Smrg       SyncHandle();
3281706f2543Smrg    }
3282706f2543Smrg
3283706f2543Smrg    FreeResource(pbuffer, RT_NONE);
3284706f2543Smrg
3285706f2543Smrg    return Success;
3286706f2543Smrg}
3287706f2543Smrg
3288706f2543Smrgint __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
3289706f2543Smrg{
3290706f2543Smrg   xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
3291706f2543Smrg   xGLXGetDrawableAttributesReq *be_req;
3292706f2543Smrg   xGLXGetDrawableAttributesReply reply;
3293706f2543Smrg   ClientPtr client = cl->client;
3294706f2543Smrg   GLXDrawable drawId = req->drawable;
3295706f2543Smrg   GLXDrawable be_drawable = 0;
3296706f2543Smrg   DrawablePtr pDraw = NULL;
3297706f2543Smrg   Display *dpy;
3298706f2543Smrg   int screen, rc;
3299706f2543Smrg   DMXScreenInfo *dmxScreen;
3300706f2543Smrg   CARD32 *attribs = NULL;
3301706f2543Smrg   int attribs_size = 0;
3302706f2543Smrg#ifdef PANORAMIX
3303706f2543Smrg    PanoramiXRes *pXinDraw = NULL;
3304706f2543Smrg#endif
3305706f2543Smrg
3306706f2543Smrg   if (drawId != None) {
3307706f2543Smrg      rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
3308706f2543Smrg      if (rc == Success && pDraw->type == DRAWABLE_WINDOW) {
3309706f2543Smrg	 WindowPtr pWin = (WindowPtr)pDraw;
3310706f2543Smrg	 be_drawable = 0;
3311706f2543Smrg	 screen = pWin->drawable.pScreen->myNum;
3312706f2543Smrg      } else {
3313706f2543Smrg	 /*
3314706f2543Smrg	  ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3315706f2543Smrg	  */
3316706f2543Smrg	 client->errorValue = drawId;
3317706f2543Smrg	 return __glXBadDrawable;
3318706f2543Smrg      }
3319706f2543Smrg
3320706f2543Smrg      if (!pDraw) {
3321706f2543Smrg	 __GLXpixmap *pGlxPixmap;
3322706f2543Smrg	 dixLookupResourceByType((pointer*) &pGlxPixmap,
3323706f2543Smrg				 drawId, __glXPixmapRes,
3324706f2543Smrg				 NullClient, DixUnknownAccess);
3325706f2543Smrg	 if (pGlxPixmap) {
3326706f2543Smrg		pDraw = pGlxPixmap->pDraw;
3327706f2543Smrg		screen = pGlxPixmap->pScreen->myNum;
3328706f2543Smrg                be_drawable = pGlxPixmap->be_xids[screen];
3329706f2543Smrg	 }
3330706f2543Smrg      }
3331706f2543Smrg
3332706f2543Smrg      if (!pDraw) {
3333706f2543Smrg	 __glXWindow *pGlxWindow;
3334706f2543Smrg	 dixLookupResourceByType((pointer*) &pGlxWindow,
3335706f2543Smrg				 drawId, __glXWindowRes,
3336706f2543Smrg				 NullClient, DixUnknownAccess);
3337706f2543Smrg	 if (pGlxWindow) {
3338706f2543Smrg	    pDraw = pGlxWindow->pDraw;
3339706f2543Smrg	    screen = pGlxWindow->pScreen->myNum;
3340706f2543Smrg	    be_drawable = 0;
3341706f2543Smrg     	 }
3342706f2543Smrg      }
3343706f2543Smrg
3344706f2543Smrg      if (!pDraw) {
3345706f2543Smrg	 __glXPbuffer *pGlxPbuffer;
3346706f2543Smrg	 dixLookupResourceByType((pointer*) &pGlxPbuffer,
3347706f2543Smrg				 drawId, __glXPbufferRes,
3348706f2543Smrg				 NullClient, DixUnknownAccess);
3349706f2543Smrg	 if (pGlxPbuffer) {
3350706f2543Smrg    	    pDraw = (DrawablePtr)pGlxPbuffer;
3351706f2543Smrg	    screen = pGlxPbuffer->pScreen->myNum;
3352706f2543Smrg	    be_drawable = pGlxPbuffer->be_xids[screen];
3353706f2543Smrg	 }
3354706f2543Smrg      }
3355706f2543Smrg    }
3356706f2543Smrg
3357706f2543Smrg    if (!pDraw) {
3358706f2543Smrg	/*
3359706f2543Smrg	 ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3360706f2543Smrg	 */
3361706f2543Smrg	client->errorValue = drawId;
3362706f2543Smrg	return __glXBadDrawable;
3363706f2543Smrg   }
3364706f2543Smrg
3365706f2543Smrg   /* if the drawable is a window or GLXWindow -
3366706f2543Smrg    * we need to find the base id on the back-end server
3367706f2543Smrg    */
3368706f2543Smrg   if (!be_drawable) {
3369706f2543Smrg       WindowPtr pWin = (WindowPtr)pDraw;
3370706f2543Smrg
3371706f2543Smrg#ifdef PANORAMIX
3372706f2543Smrg       if (!noPanoramiXExtension) {
3373706f2543Smrg	  if (Success != dixLookupResourceByClass((pointer*) &pXinDraw,
3374706f2543Smrg						  pDraw->id, XRC_DRAWABLE,
3375706f2543Smrg						  client, DixReadAccess)) {
3376706f2543Smrg	     client->errorValue = drawId;
3377706f2543Smrg	     return __glXBadDrawable;
3378706f2543Smrg	  }
3379706f2543Smrg
3380706f2543Smrg	  dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
3381706f2543Smrg			  DixReadAccess);
3382706f2543Smrg       }
3383706f2543Smrg#endif
3384706f2543Smrg
3385706f2543Smrg       if (pWin) {
3386706f2543Smrg	   be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3387706f2543Smrg	   if (!be_drawable) {
3388706f2543Smrg	      /* it might be that the window did not created yet on the */
3389706f2543Smrg	      /* back-end server (lazy window creation option), force   */
3390706f2543Smrg	      /* creation of the window */
3391706f2543Smrg	      dmxCreateAndRealizeWindow( pWin, TRUE );
3392706f2543Smrg	      be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3393706f2543Smrg	   }
3394706f2543Smrg       }
3395706f2543Smrg       else {
3396706f2543Smrg	  client->errorValue = drawId;
3397706f2543Smrg	  return __glXBadDrawable;
3398706f2543Smrg       }
3399706f2543Smrg   }
3400706f2543Smrg
3401706f2543Smrg
3402706f2543Smrg   /* send the request to the back-end server */
3403706f2543Smrg   dpy = GetBackEndDisplay(cl,screen);
3404706f2543Smrg   dmxScreen = &dmxScreens[screen];
3405706f2543Smrg
3406706f2543Smrg   /* make sure drawable exists on back-end */
3407706f2543Smrg   dmxSync( dmxScreen, 1 );
3408706f2543Smrg
3409706f2543Smrg   LockDisplay(dpy);
3410706f2543Smrg   GetReq(GLXGetDrawableAttributes, be_req);
3411706f2543Smrg   be_req->reqType = dmxScreen->glxMajorOpcode;
3412706f2543Smrg   be_req->glxCode = X_GLXGetDrawableAttributes;
3413706f2543Smrg   be_req->drawable = be_drawable;
3414706f2543Smrg   be_req->length = req->length;
3415706f2543Smrg   if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
3416706f2543Smrg      UnlockDisplay(dpy);
3417706f2543Smrg      SyncHandle();
3418706f2543Smrg      return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
3419706f2543Smrg   }
3420706f2543Smrg
3421706f2543Smrg   if (reply.numAttribs) {
3422706f2543Smrg      attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
3423706f2543Smrg      attribs = (CARD32 *) malloc(attribs_size);
3424706f2543Smrg      if (attribs == NULL) {
3425706f2543Smrg	 UnlockDisplay(dpy);
3426706f2543Smrg	 SyncHandle();
3427706f2543Smrg	 return BadAlloc;
3428706f2543Smrg      }
3429706f2543Smrg
3430706f2543Smrg      _XRead(dpy, (char *) attribs, attribs_size);
3431706f2543Smrg   }
3432706f2543Smrg
3433706f2543Smrg   UnlockDisplay(dpy);
3434706f2543Smrg   SyncHandle();
3435706f2543Smrg
3436706f2543Smrg
3437706f2543Smrg   /* send the reply back to the client */
3438706f2543Smrg   reply.sequenceNumber = client->sequence;
3439706f2543Smrg   if (client->swapped) {
3440706f2543Smrg      __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs);
3441706f2543Smrg   }
3442706f2543Smrg   else {
3443706f2543Smrg      WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply);
3444706f2543Smrg      WriteToClient(client, attribs_size, (char *)attribs);
3445706f2543Smrg   }
3446706f2543Smrg
3447706f2543Smrg   free(attribs);
3448706f2543Smrg
3449706f2543Smrg   return Success;
3450706f2543Smrg}
3451706f2543Smrg
3452706f2543Smrgint __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
3453706f2543Smrg{
3454706f2543Smrg   xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
3455706f2543Smrg   xGLXChangeDrawableAttributesReq *be_req;
3456706f2543Smrg   ClientPtr client = cl->client;
3457706f2543Smrg   GLXDrawable drawId = req->drawable;
3458706f2543Smrg   GLXDrawable be_drawable = 0;
3459706f2543Smrg   DrawablePtr pDraw = NULL;
3460706f2543Smrg   Display *dpy;
3461706f2543Smrg   int screen, rc;
3462706f2543Smrg   DMXScreenInfo *dmxScreen;
3463706f2543Smrg
3464706f2543Smrg   if (drawId != None) {
3465706f2543Smrg      rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess);
3466706f2543Smrg      if (rc == Success && pDraw->type == DRAWABLE_WINDOW) {
3467706f2543Smrg	  be_drawable = 0;
3468706f2543Smrg	  screen = pDraw->pScreen->myNum;
3469706f2543Smrg      } else {
3470706f2543Smrg	 /*
3471706f2543Smrg	  ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3472706f2543Smrg	  */
3473706f2543Smrg	 client->errorValue = drawId;
3474706f2543Smrg	 return __glXBadDrawable;
3475706f2543Smrg      }
3476706f2543Smrg
3477706f2543Smrg      if (!pDraw) {
3478706f2543Smrg	 __GLXpixmap *pGlxPixmap;
3479706f2543Smrg	 dixLookupResourceByType((pointer*) &pGlxPixmap,
3480706f2543Smrg				 drawId, __glXPixmapRes,
3481706f2543Smrg				 NullClient, DixUnknownAccess);
3482706f2543Smrg	 if (pGlxPixmap) {
3483706f2543Smrg		pDraw = pGlxPixmap->pDraw;
3484706f2543Smrg		screen = pGlxPixmap->pScreen->myNum;
3485706f2543Smrg                be_drawable = pGlxPixmap->be_xids[screen];
3486706f2543Smrg	 }
3487706f2543Smrg      }
3488706f2543Smrg
3489706f2543Smrg      if (!pDraw) {
3490706f2543Smrg	 __glXWindow *pGlxWindow;
3491706f2543Smrg	 dixLookupResourceByType((pointer*) &pGlxWindow,
3492706f2543Smrg				 drawId, __glXWindowRes,
3493706f2543Smrg				 NullClient, DixUnknownAccess);
3494706f2543Smrg	 if (pGlxWindow) {
3495706f2543Smrg	    pDraw = pGlxWindow->pDraw;
3496706f2543Smrg	    screen = pGlxWindow->pScreen->myNum;
3497706f2543Smrg	    be_drawable = 0;
3498706f2543Smrg     	 }
3499706f2543Smrg      }
3500706f2543Smrg
3501706f2543Smrg      if (!pDraw) {
3502706f2543Smrg	 __glXPbuffer *pGlxPbuffer;
3503706f2543Smrg	 dixLookupResourceByType((pointer*) &pGlxPbuffer,
3504706f2543Smrg				 drawId, __glXPbufferRes,
3505706f2543Smrg				 NullClient, DixUnknownAccess);
3506706f2543Smrg	 if (pGlxPbuffer) {
3507706f2543Smrg    	    pDraw = (DrawablePtr)pGlxPbuffer;
3508706f2543Smrg	    screen = pGlxPbuffer->pScreen->myNum;
3509706f2543Smrg	    be_drawable = pGlxPbuffer->be_xids[screen];
3510706f2543Smrg	 }
3511706f2543Smrg      }
3512706f2543Smrg   }
3513706f2543Smrg
3514706f2543Smrg   if (!pDraw) {
3515706f2543Smrg	 /*
3516706f2543Smrg	  ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3517706f2543Smrg	  */
3518706f2543Smrg	 client->errorValue = drawId;
3519706f2543Smrg	 return __glXBadDrawable;
3520706f2543Smrg   }
3521706f2543Smrg
3522706f2543Smrg   /* if the drawable is a window or GLXWindow -
3523706f2543Smrg    * we need to find the base id on the back-end server
3524706f2543Smrg    */
3525706f2543Smrg   if (!be_drawable) {
3526706f2543Smrg       WindowPtr pWin = (WindowPtr)pDraw;
3527706f2543Smrg
3528706f2543Smrg#ifdef PANORAMIX
3529706f2543Smrg       if (!noPanoramiXExtension) {
3530706f2543Smrg	  PanoramiXRes *pXinDraw;
3531706f2543Smrg	  if (Success != dixLookupResourceByClass((pointer*) &pXinDraw,
3532706f2543Smrg						  pDraw->id, XRC_DRAWABLE,
3533706f2543Smrg						  client, DixReadAccess)) {
3534706f2543Smrg	     client->errorValue = drawId;
3535706f2543Smrg	     return __glXBadDrawable;
3536706f2543Smrg	  }
3537706f2543Smrg
3538706f2543Smrg	  dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
3539706f2543Smrg			  DixReadAccess);
3540706f2543Smrg       }
3541706f2543Smrg#endif
3542706f2543Smrg
3543706f2543Smrg       if (pWin) {
3544706f2543Smrg	   be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3545706f2543Smrg	   if (!be_drawable) {
3546706f2543Smrg	      /* it might be that the window did not created yet on the */
3547706f2543Smrg	      /* back-end server (lazy window creation option), force   */
3548706f2543Smrg	      /* creation of the window */
3549706f2543Smrg	      dmxCreateAndRealizeWindow( pWin, TRUE );
3550706f2543Smrg	      be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3551706f2543Smrg	   }
3552706f2543Smrg       }
3553706f2543Smrg       else {
3554706f2543Smrg	  client->errorValue = drawId;
3555706f2543Smrg	  return __glXBadDrawable;
3556706f2543Smrg       }
3557706f2543Smrg   }
3558706f2543Smrg
3559706f2543Smrg
3560706f2543Smrg   /* send the request to the back-end server */
3561706f2543Smrg   dpy = GetBackEndDisplay(cl,screen);
3562706f2543Smrg   dmxScreen = &dmxScreens[screen];
3563706f2543Smrg
3564706f2543Smrg   /* make sure drawable exists on back-end */
3565706f2543Smrg   dmxSync( dmxScreen, 1 );
3566706f2543Smrg
3567706f2543Smrg   LockDisplay(dpy);
3568706f2543Smrg   GetReqExtra(GLXChangeDrawableAttributes,
3569706f2543Smrg                        2 * req->numAttribs * __GLX_SIZE_CARD32, be_req);
3570706f2543Smrg   be_req->reqType = dmxScreen->glxMajorOpcode;
3571706f2543Smrg   be_req->glxCode = X_GLXChangeDrawableAttributes;
3572706f2543Smrg   be_req->drawable = be_drawable;
3573706f2543Smrg   be_req->numAttribs = req->numAttribs;
3574706f2543Smrg   be_req->length = req->length;
3575706f2543Smrg
3576706f2543Smrg   UnlockDisplay(dpy);
3577706f2543Smrg   SyncHandle();
3578706f2543Smrg
3579706f2543Smrg   return Success;
3580706f2543Smrg}
3581706f2543Smrg
3582706f2543Smrgint __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag)
3583706f2543Smrg{
3584706f2543Smrg   ClientPtr client = cl->client;
3585706f2543Smrg    xGLXRenderLargeReq *req;
3586706f2543Smrg    GLint maxSize, amount;
3587706f2543Smrg    GLint totalRequests, requestNumber;
3588706f2543Smrg    GLint dataLen;
3589706f2543Smrg    GLbyte *data;
3590706f2543Smrg    __GLXcontext *glxc;
3591706f2543Smrg    int s;
3592706f2543Smrg    int from_screen, to_screen;
3593706f2543Smrg
3594706f2543Smrg    maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq);
3595706f2543Smrg    dataLen = cl->largeCmdBytesTotal;
3596706f2543Smrg    totalRequests = (dataLen / maxSize);
3597706f2543Smrg    if (dataLen % maxSize) totalRequests++;
3598706f2543Smrg
3599706f2543Smrg    glxc = __glXLookupContextByTag(cl, contextTag);
3600706f2543Smrg    if (!glxc) {
3601706f2543Smrg       client->errorValue = contextTag;
3602706f2543Smrg       return __glXBadContext;
3603706f2543Smrg    }
3604706f2543Smrg    from_screen = to_screen = glxc->pScreen->myNum;
3605706f2543Smrg
3606706f2543Smrg#ifdef PANORAMIX
3607706f2543Smrg    if (!noPanoramiXExtension) {
3608706f2543Smrg       from_screen = 0;
3609706f2543Smrg       to_screen = screenInfo.numScreens - 1;
3610706f2543Smrg    }
3611706f2543Smrg#endif
3612706f2543Smrg
3613706f2543Smrg    /*
3614706f2543Smrg    ** Send enough requests until the whole array is sent.
3615706f2543Smrg    */
3616706f2543Smrg    requestNumber = 1;
3617706f2543Smrg    data = cl->largeCmdBuf;
3618706f2543Smrg    while (dataLen > 0) {
3619706f2543Smrg	amount = dataLen;
3620706f2543Smrg	if (amount > maxSize) {
3621706f2543Smrg	    amount = maxSize;
3622706f2543Smrg	}
3623706f2543Smrg
3624706f2543Smrg	for (s=from_screen; s<=to_screen; s++) {
3625706f2543Smrg
3626706f2543Smrg	   Display *dpy = GetBackEndDisplay(cl,s);
3627706f2543Smrg	   DMXScreenInfo *dmxScreen = &dmxScreens[s];
3628706f2543Smrg
3629706f2543Smrg	   LockDisplay(dpy);
3630706f2543Smrg	   GetReq(GLXRenderLarge,req);
3631706f2543Smrg	   req->reqType = dmxScreen->glxMajorOpcode;
3632706f2543Smrg	   req->glxCode = X_GLXRenderLarge;
3633706f2543Smrg	   req->contextTag = GetCurrentBackEndTag(cl,contextTag,s);
3634706f2543Smrg	   req->length += (amount + 3) >> 2;
3635706f2543Smrg	   req->requestNumber = requestNumber++;
3636706f2543Smrg	   req->requestTotal = totalRequests;
3637706f2543Smrg	   req->dataBytes = amount;
3638706f2543Smrg	   Data(dpy, ((const char*)data), amount);
3639706f2543Smrg	   dataLen -= amount;
3640706f2543Smrg	   data = ((GLbyte *) data) + amount;
3641706f2543Smrg	   UnlockDisplay(dpy);
3642706f2543Smrg	   SyncHandle();
3643706f2543Smrg	}
3644706f2543Smrg    }
3645706f2543Smrg
3646706f2543Smrg    return Success;
3647706f2543Smrg}
3648