1/*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31#ifdef HAVE_DMX_CONFIG_H
32#include <dmx-config.h>
33#endif
34
35#include "dmx.h"
36#include "dmxwindow.h"
37#include "dmxpixmap.h"
38#include "dmxfont.h"
39#include "dmxsync.h"
40
41#include "glxserver.h"
42#include <GL/glxtokens.h>
43#include "g_disptab.h"
44#include <pixmapstr.h>
45#include <windowstr.h>
46#include "glxutil.h"
47#include "glxext.h"
48#include "unpack.h"
49
50#include "GL/glxproto.h"
51#include "glxvendor.h"
52#include "glxvisuals.h"
53#include "glxswap.h"
54
55#include "glxcmds.h"
56
57#ifdef PANORAMIX
58#include "panoramiXsrv.h"
59#endif
60
61extern __GLXFBConfig **__glXFBConfigs;
62extern int            __glXNumFBConfigs;
63
64extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id );
65extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid );
66extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen );
67extern int glxIsExtensionSupported( char *ext );
68extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
69
70#define BE_TO_CLIENT_ERROR(x) \
71           ( (x) >= __glXerrorBase ? \
72             (x) - dmxScreen->glxErrorBase + __glXerrorBase \
73	     : (x) )
74
75Display *GetBackEndDisplay( __GLXclientState *cl, int s )
76{
77   if (! cl->be_displays[s] ) {
78      cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) );
79   }
80   return cl->be_displays[s];
81}
82
83/*
84** Create a GL context with the given properties.
85*/
86static int CreateContext(__GLXclientState *cl,
87                         GLXContextID gcId,
88			 VisualID vid, GLXFBConfigID fbconfigId,
89			 int screen,
90			 GLXContextID shareList,
91			 int isDirect )
92{
93    ClientPtr client = cl->client;
94    xGLXCreateContextReq *be_req;
95    xGLXCreateNewContextReq *be_new_req;
96    VisualPtr pVisual;
97    ScreenPtr pScreen;
98    __GLXcontext *glxc, *shareglxc;
99    __GLXvisualConfig *pGlxVisual;
100    __GLXscreenInfo *pGlxScreen;
101    VisualID visual = vid;
102    GLint i;
103    int from_screen = screen;
104    int to_screen = screen;
105    DMXScreenInfo *dmxScreen;
106    VisualID be_vid = 0;
107    GLXFBConfigID be_fbconfigId = 0;
108    int num_be_screens;
109    Display *dpy;
110
111    /*
112    ** Check if screen exists.
113    */
114    if (screen >= screenInfo.numScreens) {
115	client->errorValue = screen;
116	return BadValue;
117    }
118
119
120#ifdef PANORAMIX
121    if (!noPanoramiXExtension) {
122       from_screen = 0;
123       to_screen = screenInfo.numScreens - 1;
124    }
125#endif
126
127    /*
128     ** Find the display list space that we want to share.
129     **
130     */
131    if (shareList == None) {
132       shareglxc = NULL;
133    } else {
134       dixLookupResourceByType((pointer*) &shareglxc, shareList,
135                               __glXContextRes, NullClient, DixUnknownAccess);
136       if (!shareglxc) {
137	  client->errorValue = shareList;
138	  return __glXBadContext;
139       }
140    }
141
142    /*
143    ** Allocate memory for the new context
144    */
145    glxc = calloc(1, sizeof(__GLXcontext));
146    if (!glxc) {
147	return BadAlloc;
148    }
149
150    pScreen = screenInfo.screens[screen];
151    pGlxScreen = &__glXActiveScreens[screen];
152
153    if (fbconfigId != None) {
154       glxc->pFBConfig = glxLookupFBConfig( fbconfigId );
155       if (!glxc->pFBConfig) {
156	  client->errorValue = fbconfigId;
157	  free( glxc );
158	  return BadValue;
159       }
160       visual = glxc->pFBConfig->associatedVisualId;
161    }
162    else {
163       glxc->pFBConfig = NULL;
164    }
165
166    if (visual != None) {
167       /*
168	** Check if the visual ID is valid for this screen.
169	*/
170       pVisual = pScreen->visuals;
171       for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
172	  if (pVisual->vid == visual) {
173	     break;
174	  }
175       }
176       if (i == pScreen->numVisuals) {
177	  client->errorValue = visual;
178	  free( glxc );
179	  return BadValue;
180       }
181
182       pGlxVisual = pGlxScreen->pGlxVisual;
183       for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
184	  if (pGlxVisual->vid == visual) {
185	     break;
186	  }
187       }
188       if (i == pGlxScreen->numVisuals) {
189	  /*
190	   ** Visual not support on this screen by this OpenGL implementation.
191	   */
192	  client->errorValue = visual;
193	  free( glxc );
194	  return BadValue;
195       }
196
197       if ( glxc->pFBConfig == NULL ) {
198	   glxc->pFBConfig = glxLookupFBConfigByVID( visual );
199
200	   if ( glxc->pFBConfig == NULL ) {
201	      /*
202               * visual does not have an FBConfig ???
203	      client->errorValue = visual;
204	      free( glxc );
205	      return BadValue;
206	       */
207	   }
208       }
209    }
210    else {
211       pVisual = NULL;
212       pGlxVisual = NULL;
213    }
214
215    glxc->pScreen = pScreen;
216    glxc->pGlxScreen = pGlxScreen;
217    glxc->pVisual = pVisual;
218    glxc->pGlxVisual = pGlxVisual;
219
220    /*
221     * allocate memory for back-end servers info
222     */
223    num_be_screens = to_screen - from_screen + 1;
224    glxc->real_ids = (XID *)malloc(sizeof(XID) * num_be_screens);
225    if (!glxc->real_ids) {
226	return BadAlloc;
227    }
228    glxc->real_vids = (XID *)malloc(sizeof(XID) * num_be_screens);
229    if (!glxc->real_vids) {
230	return BadAlloc;
231    }
232
233    for (screen = from_screen; screen <= to_screen; screen++) {
234       int sent = 0;
235       pScreen = screenInfo.screens[screen];
236       pGlxScreen = &__glXActiveScreens[screen];
237       dmxScreen = &dmxScreens[screen];
238
239       if (glxc->pFBConfig) {
240	  __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id,
241		                                                screen );
242	  be_fbconfigId = beFBConfig->id;
243       }
244
245       if (pGlxVisual) {
246
247	  be_vid = glxMatchGLXVisualInConfigList( pGlxVisual,
248	                                    dmxScreen->glxVisuals,
249					    dmxScreen->numGlxVisuals  );
250
251	  if (!be_vid) {
252	     /* visual is not supported on the back-end server */
253	     free( glxc->real_ids );
254	     free( glxc->real_vids );
255	     free( glxc );
256	     return BadValue;
257	  }
258       }
259
260       glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen));
261
262       /* send the create context request to the back-end server */
263       dpy = GetBackEndDisplay(cl,screen);
264       if (glxc->pFBConfig) {
265	     /*Since for a certain visual both RGB and COLOR INDEX
266	      *can be on then the only parmeter to choose the renderType
267	      * should be the class of the colormap since all 4 first
268	      * classes does not support RGB mode only COLOR INDEX ,
269	      * and so TrueColor and DirectColor does not support COLOR INDEX*/
270	     int renderType =  glxc->pFBConfig->renderType;
271	     if ( pVisual ) {
272		 switch ( pVisual->class ){
273		     case PseudoColor:
274                     case StaticColor:
275                     case GrayScale:
276                     case StaticGray:
277                         renderType = GLX_COLOR_INDEX_TYPE;
278                         break;
279                     case TrueColor:
280                     case DirectColor:
281                     default:
282                         renderType = GLX_RGBA_TYPE;
283                     break;
284		 }
285	     }
286	  if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
287	     LockDisplay(dpy);
288	     GetReq(GLXCreateNewContext,be_new_req);
289	     be_new_req->reqType = dmxScreen->glxMajorOpcode;
290	     be_new_req->glxCode = X_GLXCreateNewContext;
291	     be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
292	     be_new_req->fbconfig = (unsigned int)be_fbconfigId;
293	     be_new_req->screen = DefaultScreen(dpy);
294	     be_new_req->renderType = renderType;
295
296	     be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
297	     be_new_req->isDirect = 0;
298	     UnlockDisplay(dpy);
299	     glxc->real_vids[screen-from_screen] = be_fbconfigId;
300	     sent = 1;
301	  }
302	  else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
303
304	     xGLXCreateContextWithConfigSGIXReq *ext_req;
305	     xGLXVendorPrivateReq *vpreq;
306	     LockDisplay(dpy);
307	     GetReqExtra(GLXVendorPrivate,
308		         sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq,
309			vpreq);
310	     ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
311	     ext_req->reqType = dmxScreen->glxMajorOpcode;
312	     ext_req->glxCode = X_GLXVendorPrivate;
313	     ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
314	     ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
315	     ext_req->fbconfig = (unsigned int)be_fbconfigId;
316	     ext_req->screen = DefaultScreen(dpy);
317	     ext_req->renderType = renderType;
318	     ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
319	     ext_req->isDirect = 0;
320	     UnlockDisplay(dpy);
321	     glxc->real_vids[screen-from_screen] = be_fbconfigId;
322	     sent = 1;
323	  }
324       }
325
326       if (!sent) {
327	  LockDisplay(dpy);
328	  GetReq(GLXCreateContext,be_req);
329	  be_req->reqType = dmxScreen->glxMajorOpcode;
330	  be_req->glxCode = X_GLXCreateContext;
331	  be_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
332	  be_req->visual = (unsigned int)be_vid;
333	  be_req->screen = DefaultScreen(dpy);
334	  be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
335	  be_req->isDirect = 0;
336	  UnlockDisplay(dpy);
337	  glxc->real_vids[screen-from_screen] = be_vid;
338       }
339       SyncHandle();
340
341    }
342
343    /*
344    ** Register this context as a resource.
345    */
346    if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
347       free( glxc->real_ids );
348       free( glxc->real_vids );
349       free( glxc );
350	client->errorValue = gcId;
351	return BadAlloc;
352    }
353
354    /*
355    ** Finally, now that everything is working, setup the rest of the
356    ** context.
357    */
358    glxc->id = gcId;
359    glxc->share_id = shareList;
360    glxc->idExists = GL_TRUE;
361    glxc->isCurrent = GL_FALSE;
362
363    return Success;
364}
365
366int __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
367{
368    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
369
370    return( CreateContext(cl, req->context,req->visual, None,
371	                  req->screen, req->shareList, req->isDirect) );
372
373}
374
375int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
376{
377    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
378
379    return( CreateContext(cl, req->context,None, req->fbconfig,
380	                  req->screen, req->shareList, req->isDirect) );
381
382}
383
384int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
385{
386    xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
387
388    return( CreateContext(cl, req->context, None, req->fbconfig,
389	                  req->screen, req->shareList, req->isDirect) );
390
391}
392
393int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
394{
395    ClientPtr client = cl->client;
396    xGLXQueryMaxSwapBarriersSGIXReq *req =
397	(xGLXQueryMaxSwapBarriersSGIXReq *)pc;
398    xGLXQueryMaxSwapBarriersSGIXReply reply;
399
400    reply.type = X_Reply;
401    reply.sequenceNumber = client->sequence;
402    reply.length = 0;
403    reply.max = QueryMaxSwapBarriersSGIX(req->screen);
404
405    if (client->swapped) {
406	__glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
407    } else {
408	WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
409		      (char *)&reply);
410    }
411
412    return Success;
413}
414
415int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
416{
417    ClientPtr client = cl->client;
418    xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
419    DrawablePtr pDraw;
420    __GLXpixmap *pGlxPixmap = NULL;
421    __glXWindow *pGlxWindow = NULL;
422    int rc;
423
424    rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess);
425    if (rc != Success) {
426	dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable,
427				__glXPixmapRes, NullClient, DixUnknownAccess);
428	if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
429    }
430
431    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
432       dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable,
433                               __glXWindowRes, NullClient, DixUnknownAccess);
434       if (pGlxWindow) pDraw = pGlxWindow->pDraw;
435    }
436
437    if (!pDraw) {
438       client->errorValue = req->drawable;
439       return __glXBadDrawable;
440    }
441
442    return BindSwapBarrierSGIX(pDraw, req->barrier);
443}
444
445int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
446{
447    ClientPtr client = cl->client;
448    xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
449    DrawablePtr pDraw, pMember = NULL;
450    __GLXpixmap *pGlxPixmap = NULL;
451    __glXWindow *pGlxWindow = NULL;
452    int rc;
453
454    rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess);
455    if (rc != Success) {
456	dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable,
457				__glXPixmapRes, NullClient, DixUnknownAccess);
458	if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
459    }
460
461    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
462       dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable,
463                               __glXWindowRes, NullClient, DixUnknownAccess);
464       if (pGlxWindow) pDraw = pGlxWindow->pDraw;
465    }
466
467    if (!pDraw) {
468       client->errorValue = req->drawable;
469       return __glXBadDrawable;
470    }
471
472    if (req->member != None) {
473	rc = dixLookupDrawable(&pMember, req->member, client, 0,
474			       DixGetAttrAccess);
475	if (rc != Success) {
476	    dixLookupResourceByType((pointer*) &pGlxPixmap, req->member,
477                                    __glXPixmapRes, NullClient,
478                                    DixUnknownAccess);
479	    if (pGlxPixmap) pMember = pGlxPixmap->pDraw;
480	}
481
482	if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
483	    dixLookupResourceByType((pointer*) &pGlxWindow, req->member,
484                                    __glXWindowRes, NullClient,
485                                    DixUnknownAccess);
486	    if (pGlxWindow) pMember = pGlxWindow->pDraw;
487	}
488
489	if (!pMember) {
490	    client->errorValue = req->member;
491	    return __glXBadDrawable;
492	}
493    }
494
495    return JoinSwapGroupSGIX(pDraw, pMember);
496}
497
498
499/*
500** Destroy a GL context as an X resource.
501*/
502int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
503{
504    ClientPtr client = cl->client;
505    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
506    xGLXDestroyContextReq *be_req;
507    GLXContextID gcId = req->context;
508    __GLXcontext *glxc;
509    int from_screen = 0;
510    int to_screen = 0;
511    int s;
512
513    dixLookupResourceByType((pointer*) &glxc, gcId, __glXContextRes,
514			    NullClient, DixUnknownAccess);
515    if (glxc) {
516	/*
517	** Just free the resource; don't actually destroy the context,
518	** because it might be in use.  The
519	** destroy method will be called by the resource destruction routine
520	** if necessary.
521	*/
522	FreeResourceByType(gcId, __glXContextRes, FALSE);
523
524	from_screen = to_screen = glxc->pScreen->myNum;
525
526    } else {
527	client->errorValue = gcId;
528	return __glXBadContext;
529    }
530
531#ifdef PANORAMIX
532    if (!noPanoramiXExtension) {
533       from_screen = 0;
534       to_screen = screenInfo.numScreens - 1;
535    }
536#endif
537
538    /*
539     * send DestroyContext request to all back-end servers
540     */
541    for (s=from_screen; s<=to_screen; s++) {
542       DMXScreenInfo *dmxScreen = &dmxScreens[s];
543       Display *dpy = GetBackEndDisplay(cl,s);
544
545       LockDisplay(dpy);
546       GetReq(GLXDestroyContext,be_req);
547       be_req->reqType = dmxScreen->glxMajorOpcode;
548       be_req->glxCode = X_GLXDestroyContext;
549       be_req->context = glxc->real_ids[s-from_screen];
550       UnlockDisplay(dpy);
551       SyncHandle();
552    }
553
554    return Success;
555}
556
557/*****************************************************************************/
558
559/*
560** For each client, the server keeps a table of all the contexts that are
561** current for that client (each thread of a client may have its own current
562** context).  These routines add, change, and lookup contexts in the table.
563*/
564
565/*
566** Add a current context, and return the tag that will be used to refer to it.
567*/
568static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw)
569{
570    int i;
571    int num = cl->numCurrentContexts;
572    __GLXcontext **table = cl->currentContexts;
573
574    if (!glxc) return -1;
575
576    /*
577    ** Try to find an empty slot and use it.
578    */
579    for (i=0; i < num; i++) {
580	if (!table[i]) {
581	    table[i] = glxc;
582	    return i+1;
583	}
584    }
585    /*
586    ** Didn't find a free slot, so we'll have to grow the table.
587    */
588    if (!num) {
589	table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
590	cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr));
591	cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens *sizeof(GLXContextTag));
592    } else {
593	table = (__GLXcontext **) realloc(table,
594					   (num+1)*sizeof(__GLXcontext *));
595	cl->currentDrawables = (DrawablePtr *) realloc(
596	                                          cl->currentDrawables ,
597						  (num+1)*sizeof(DrawablePtr));
598	cl->be_currentCTag = (GLXContextTag *) realloc(cl->be_currentCTag,
599	            (num+1)*screenInfo.numScreens*sizeof(GLXContextTag));
600    }
601    table[num] = glxc;
602    cl->currentDrawables[num] = pDraw;
603    cl->currentContexts = table;
604    cl->numCurrentContexts++;
605
606    memset(cl->be_currentCTag + num*screenInfo.numScreens, 0,
607	         screenInfo.numScreens * sizeof(GLXContextTag));
608
609    return num+1;
610}
611
612/*
613** Given a tag, change the current context for the corresponding entry.
614*/
615static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
616				GLXContextTag tag)
617{
618    __GLXcontext **table = cl->currentContexts;
619    table[tag-1] = glxc;
620}
621
622/*
623** Given a tag, and back-end screen number, retrives the current back-end
624** tag.
625*/
626int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s)
627{
628   if (tag >0) {
629      return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] );
630   }
631   else {
632      return 0;
633   }
634}
635
636/*
637** Given a tag, and back-end screen number, sets the current back-end
638** tag.
639*/
640static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag)
641{
642   if (tag >0) {
643      cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag;
644   }
645}
646
647/*
648** For this implementation we have chosen to simply use the index of the
649** context's entry in the table as the context tag.  A tag must be greater
650** than 0.
651*/
652__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
653{
654    int num = cl->numCurrentContexts;
655
656    if (tag < 1 || tag > num) {
657	return 0;
658    } else {
659	return cl->currentContexts[tag-1];
660    }
661}
662
663DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag)
664{
665    int num = cl->numCurrentContexts;
666
667    if (tag < 1 || tag > num) {
668	return 0;
669    } else {
670	return cl->currentDrawables[tag-1];
671    }
672}
673
674/*****************************************************************************/
675
676static void StopUsingContext(__GLXcontext *glxc)
677{
678    if (glxc) {
679	if (glxc == __glXLastContext) {
680	    /* Tell server GL library */
681	    __glXLastContext = 0;
682	}
683	glxc->isCurrent = GL_FALSE;
684	if (!glxc->idExists) {
685	    __glXFreeContext(glxc);
686	}
687    }
688}
689
690static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
691{
692    glxc->isCurrent = GL_TRUE;
693}
694
695/*****************************************************************************/
696/*
697** Make an OpenGL context and drawable current.
698*/
699static int MakeCurrent(__GLXclientState *cl,
700                       GLXDrawable drawable,
701                       GLXDrawable readdrawable,
702		       GLXContextID context,
703		       GLXContextTag oldContextTag)
704{
705    ClientPtr client = cl->client;
706    DrawablePtr pDraw = NULL;
707    DrawablePtr pReadDraw = NULL;
708    xGLXMakeCurrentReadSGIReply new_reply;
709    xGLXMakeCurrentReq *be_req;
710    xGLXMakeCurrentReply be_reply;
711    xGLXMakeContextCurrentReq *be_new_req;
712    xGLXMakeContextCurrentReply be_new_reply;
713    GLXDrawable drawId = drawable;
714    GLXDrawable readId = readdrawable;
715    GLXContextID contextId = context;
716    __GLXpixmap *pGlxPixmap = 0;
717    __GLXpixmap *pReadGlxPixmap = 0;
718    __GLXcontext *glxc, *prevglxc;
719    GLXContextTag tag = oldContextTag;
720    WindowPtr pWin = NULL;
721    WindowPtr pReadWin = NULL;
722    __glXWindow *pGlxWindow = NULL;
723    __glXWindow *pGlxReadWindow = NULL;
724    __glXPbuffer *pGlxPbuffer = NULL;
725    __glXPbuffer *pGlxReadPbuffer = NULL;
726#ifdef PANORAMIX
727    PanoramiXRes *pXinDraw = NULL;
728    PanoramiXRes *pXinReadDraw = NULL;
729#endif
730    int from_screen = 0;
731    int to_screen = 0;
732    int s, rc;
733
734    /*
735    ** If one is None and the other isn't, it's a bad match.
736    */
737    if ((drawId == None && contextId != None) ||
738	(drawId != None && contextId == None)) {
739	return BadMatch;
740    }
741
742    /*
743    ** Lookup old context.  If we have one, it must be in a usable state.
744    */
745    if (tag != 0) {
746	prevglxc = __glXLookupContextByTag(cl, tag);
747	if (!prevglxc) {
748	    /*
749	    ** Tag for previous context is invalid.
750	    */
751	    return __glXBadContextTag;
752	}
753    } else {
754	prevglxc = 0;
755    }
756
757    /*
758    ** Lookup new context.  It must not be current for someone else.
759    */
760    if (contextId != None) {
761	dixLookupResourceByType((pointer*) &glxc, contextId, __glXContextRes,
762				NullClient, DixUnknownAccess);
763	if (!glxc) {
764	    client->errorValue = contextId;
765	    return __glXBadContext;
766	}
767	if ((glxc != prevglxc) && glxc->isCurrent) {
768	    /* Context is current to somebody else */
769	    return BadAccess;
770	}
771    } else {
772	/* Switching to no context.  Ignore new drawable. */
773	glxc = 0;
774    }
775
776    if (drawId != None) {
777	rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
778	if (rc == Success) {
779	    if (pDraw->type == DRAWABLE_WINDOW) {
780		/*
781		** Drawable is an X Window.
782		*/
783	        VisualID vid;
784		pWin = (WindowPtr)pDraw;
785		vid = wVisual(pWin);
786
787		new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
788		new_reply.writeType = GLX_WINDOW_TYPE;
789
790		/*
791		** Check if window and context are similar.
792		*/
793		if ((vid != glxc->pVisual->vid) ||
794		    (pWin->drawable.pScreen != glxc->pScreen)) {
795		    client->errorValue = drawId;
796		    return BadMatch;
797		}
798
799		from_screen = to_screen = pWin->drawable.pScreen->myNum;
800
801	    } else {
802		/*
803		** An X Pixmap is not allowed as a parameter (a GLX Pixmap
804		** is, but it must first be created with glxCreateGLXPixmap).
805		*/
806		client->errorValue = drawId;
807		return __glXBadDrawable;
808	    }
809	}
810
811        if (!pDraw) {
812	    dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
813				    __glXPixmapRes, NullClient,
814				    DixUnknownAccess);
815	    if (pGlxPixmap) {
816		/*
817		** Check if pixmap and context are similar.
818		*/
819		if (pGlxPixmap->pScreen != glxc->pScreen ||
820		    pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
821		    client->errorValue = drawId;
822		    return BadMatch;
823		}
824		pDraw = pGlxPixmap->pDraw;
825
826		new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
827		                      pGlxPixmap->pGlxVisual->vid);
828
829		new_reply.writeType = GLX_PIXMAP_TYPE;
830
831		from_screen = to_screen = pGlxPixmap->pScreen->myNum;
832
833	    }
834	}
835
836	if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
837	   dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
838                                   __glXWindowRes, NullClient,
839                                   DixUnknownAccess);
840            if (pGlxWindow) {
841                /*
842                ** Drawable is a GLXWindow.
843                **
844                ** Check if GLX window and context are similar.
845                */
846                if (pGlxWindow->pScreen != glxc->pScreen ||
847                    pGlxWindow->pGlxFBConfig != glxc->pFBConfig) {
848                    client->errorValue = drawId;
849                    return BadMatch;
850                }
851
852                pDraw = pGlxWindow->pDraw;
853                new_reply.writeVid = pGlxWindow->pGlxFBConfig->id;
854                new_reply.writeType = GLX_GLXWINDOW_TYPE;
855            }
856
857	}
858
859	if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
860	   dixLookupResourceByType((pointer*) &pGlxPbuffer, drawId,
861                                   __glXPbufferRes, NullClient,
862                                   DixUnknownAccess);
863	   if (pGlxPbuffer) {
864                if (pGlxPbuffer->pScreen != glxc->pScreen ||
865                    pGlxPbuffer->pFBConfig != glxc->pFBConfig) {
866                    client->errorValue = drawId;
867                    return BadMatch;
868                }
869
870		pDraw = (DrawablePtr)pGlxPbuffer;
871                new_reply.writeVid = pGlxPbuffer->pFBConfig->id;
872                new_reply.writeType = GLX_PBUFFER_TYPE;
873	   }
874	}
875
876	if (!pDraw) {
877	   /*
878    	    ** Drawable is not a Window , GLXWindow or a GLXPixmap.
879	    */
880	   client->errorValue = drawId;
881	   return __glXBadDrawable;
882	}
883
884    } else {
885	pDraw = 0;
886    }
887
888    if (readId != None && readId != drawId ) {
889	rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess);
890	if (rc == Success) {
891	    if (pReadDraw->type == DRAWABLE_WINDOW) {
892		/*
893		** Drawable is an X Window.
894		*/
895	        VisualID vid;
896		pReadWin = (WindowPtr)pDraw;
897		vid = wVisual(pReadWin);
898
899		new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
900		new_reply.readType = GLX_WINDOW_TYPE;
901
902		/*
903		** Check if window and context are similar.
904		*/
905		if ((vid != glxc->pVisual->vid) ||
906		    (pReadWin->drawable.pScreen != glxc->pScreen)) {
907		    client->errorValue = readId;
908		    return BadMatch;
909		}
910
911	    } else {
912
913		/*
914		** An X Pixmap is not allowed as a parameter (a GLX Pixmap
915		** is, but it must first be created with glxCreateGLXPixmap).
916		*/
917		client->errorValue = readId;
918		return __glXBadDrawable;
919	    }
920	}
921
922	if (!pReadDraw) {
923	    dixLookupResourceByType((pointer*) &pReadGlxPixmap, readId,
924				    __glXPixmapRes, NullClient,
925				    DixUnknownAccess);
926	    if (pReadGlxPixmap) {
927		/*
928		** Check if pixmap and context are similar.
929		*/
930		if (pReadGlxPixmap->pScreen != glxc->pScreen ||
931		    pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
932		    client->errorValue = readId;
933		    return BadMatch;
934		}
935		pReadDraw = pReadGlxPixmap->pDraw;
936
937		new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
938		                     pReadGlxPixmap->pGlxVisual->vid );
939		new_reply.readType = GLX_PIXMAP_TYPE;
940
941	    }
942	}
943
944	if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
945	   dixLookupResourceByType((pointer*) &pGlxReadWindow, readId,
946                                   __glXWindowRes, NullClient,
947                                   DixUnknownAccess);
948            if (pGlxReadWindow) {
949                /*
950                ** Drawable is a GLXWindow.
951                **
952                ** Check if GLX window and context are similar.
953                */
954                if (pGlxReadWindow->pScreen != glxc->pScreen ||
955                    pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) {
956                    client->errorValue = readId;
957                    return BadMatch;
958                }
959
960                pReadDraw = pGlxReadWindow->pDraw;
961                new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id;
962                new_reply.readType = GLX_GLXWINDOW_TYPE;
963            }
964	}
965
966	if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
967	   dixLookupResourceByType((pointer*) &pGlxReadPbuffer, readId,
968                                   __glXPbufferRes, NullClient,
969                                   DixUnknownAccess);
970	   if (pGlxReadPbuffer) {
971                if (pGlxReadPbuffer->pScreen != glxc->pScreen ||
972                    pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) {
973                    client->errorValue = drawId;
974                    return BadMatch;
975                }
976
977		pReadDraw = (DrawablePtr)pGlxReadPbuffer;
978                new_reply.readVid = pGlxReadPbuffer->pFBConfig->id;
979                new_reply.readType = GLX_PBUFFER_TYPE;
980	   }
981	}
982
983	if (!pReadDraw) {
984	   /*
985    	    ** Drawable is neither a Window nor a GLXPixmap.
986	    */
987	   client->errorValue = readId;
988	   return __glXBadDrawable;
989	}
990
991    } else {
992	pReadDraw = pDraw;
993	pReadGlxPixmap = pGlxPixmap;
994	pReadWin = pWin;
995	new_reply.readVid = new_reply.writeVid;
996	new_reply.readType = new_reply.writeType;
997    }
998
999    if (prevglxc) {
1000
1001	if (prevglxc->pGlxPixmap) {
1002	    /*
1003	    ** The previous drawable was a glx pixmap, release it.
1004	    */
1005	    prevglxc->pGlxPixmap->refcnt--;
1006	    __glXFreeGLXPixmap( prevglxc->pGlxPixmap );
1007	    prevglxc->pGlxPixmap = 0;
1008	}
1009
1010	if (prevglxc->pGlxReadPixmap) {
1011	    /*
1012	    ** The previous drawable was a glx pixmap, release it.
1013	    */
1014	    prevglxc->pGlxReadPixmap->refcnt--;
1015	    __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap );
1016	    prevglxc->pGlxReadPixmap = 0;
1017	}
1018
1019	if (prevglxc->pGlxWindow) {
1020	    /*
1021	    ** The previous drawable was a glx window, release it.
1022	    */
1023	    prevglxc->pGlxWindow->refcnt--;
1024	    __glXFreeGLXWindow( prevglxc->pGlxWindow );
1025	    prevglxc->pGlxWindow = 0;
1026	}
1027
1028	if (prevglxc->pGlxReadWindow) {
1029	    /*
1030	    ** The previous drawable was a glx window, release it.
1031	    */
1032	    prevglxc->pGlxReadWindow->refcnt--;
1033	    __glXFreeGLXWindow( prevglxc->pGlxReadWindow );
1034	    prevglxc->pGlxReadWindow = 0;
1035	}
1036
1037	if (prevglxc->pGlxPbuffer) {
1038	    /*
1039	    ** The previous drawable was a glx Pbuffer, release it.
1040	    */
1041	    prevglxc->pGlxPbuffer->refcnt--;
1042	    __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer );
1043	    prevglxc->pGlxPbuffer = 0;
1044	}
1045
1046	if (prevglxc->pGlxReadPbuffer) {
1047	    /*
1048	    ** The previous drawable was a glx Pbuffer, release it.
1049	    */
1050	    prevglxc->pGlxReadPbuffer->refcnt--;
1051	    __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer );
1052	    prevglxc->pGlxReadPbuffer = 0;
1053	}
1054
1055	ChangeCurrentContext(cl, glxc, tag);
1056	ChangeCurrentContext(cl, glxc, tag);
1057	StopUsingContext(prevglxc);
1058    } else {
1059	tag = AddCurrentContext(cl, glxc, pDraw);
1060    }
1061    if (glxc) {
1062
1063       glxc->pGlxPixmap = pGlxPixmap;
1064       glxc->pGlxReadPixmap = pReadGlxPixmap;
1065       glxc->pGlxWindow = pGlxWindow;
1066       glxc->pGlxReadWindow = pGlxReadWindow;
1067       glxc->pGlxPbuffer = pGlxPbuffer;
1068       glxc->pGlxReadPbuffer = pGlxReadPbuffer;
1069
1070	if (pGlxPixmap) {
1071	    pGlxPixmap->refcnt++;
1072	}
1073
1074	if (pReadGlxPixmap) {
1075	    pReadGlxPixmap->refcnt++;
1076	}
1077
1078	if (pGlxWindow) {
1079	   pGlxWindow->refcnt++;
1080	}
1081
1082	if (pGlxReadWindow) {
1083	   pGlxReadWindow->refcnt++;
1084	}
1085
1086	if (pGlxPbuffer) {
1087	   pGlxPbuffer->refcnt++;
1088	}
1089
1090	if (pGlxReadPbuffer) {
1091	   pGlxReadPbuffer->refcnt++;
1092	}
1093
1094	StartUsingContext(cl, glxc);
1095	new_reply.contextTag = tag;
1096    } else {
1097	new_reply.contextTag = 0;
1098    }
1099    new_reply.length = 0;
1100    new_reply.type = X_Reply;
1101    new_reply.sequenceNumber = client->sequence;
1102
1103#ifdef PANORAMIX
1104    if (!noPanoramiXExtension) {
1105       from_screen = 0;
1106       to_screen = screenInfo.numScreens - 1;
1107
1108       if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
1109	  dixLookupResourceByClass((pointer*) &pXinDraw,
1110				   pDraw->id, XRC_DRAWABLE,
1111				   client, DixReadAccess);
1112       }
1113
1114       if (pReadDraw && pReadDraw != pDraw &&
1115	     new_reply.readType != GLX_PBUFFER_TYPE) {
1116	  dixLookupResourceByClass((pointer*) &pXinReadDraw,
1117				   pReadDraw->id, XRC_DRAWABLE,
1118				   client, DixReadAccess);
1119       }
1120       else {
1121	  pXinReadDraw = pXinDraw;
1122       }
1123    }
1124#endif
1125
1126
1127    /* send the MakeCurrent request to all required
1128     * back-end servers.
1129     */
1130    for (s = from_screen; s<=to_screen; s++) {
1131       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1132       Display *dpy = GetBackEndDisplay(cl,s);
1133       unsigned int be_draw = None;
1134       unsigned int be_read_draw = None;
1135
1136       if (pGlxPixmap) {
1137	   be_draw = pGlxPixmap->be_xids[s];
1138       }
1139       else if (pGlxPbuffer) {
1140	  be_draw = pGlxPbuffer->be_xids[s];
1141       }
1142#ifdef PANORAMIX
1143       else if (pXinDraw) {
1144	  dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
1145       }
1146#endif
1147       else if (pGlxWindow) {
1148	  pWin = (WindowPtr)pGlxWindow->pDraw;
1149       }
1150
1151       if (pWin && be_draw == None) {
1152	   be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
1153	   if (!be_draw) {
1154	      /* it might be that the window did not created yet on the */
1155	      /* back-end server (lazy window creation option), force   */
1156	      /* creation of the window */
1157	      dmxCreateAndRealizeWindow( pWin, TRUE );
1158	      be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
1159	   }
1160       }
1161
1162       /*
1163	* Before sending the MakeCurrent request - sync the
1164	* X11 connection to the back-end servers to make sure
1165	* that drawable is already created
1166	*/
1167       dmxSync( dmxScreen, 1 );
1168
1169       if (drawId == readId) {
1170	  LockDisplay(dpy);
1171	  GetReq(GLXMakeCurrent, be_req);
1172	  be_req->reqType = dmxScreen->glxMajorOpcode;
1173	  be_req->glxCode = X_GLXMakeCurrent;
1174	  be_req->drawable = be_draw;
1175	  be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1176	  be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1177	  if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
1178
1179	     /* The make current failed */
1180	     UnlockDisplay(dpy);
1181	     SyncHandle();
1182	     return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1183	  }
1184
1185	  UnlockDisplay(dpy);
1186       	  SyncHandle();
1187
1188	  SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag );
1189       }
1190       else {
1191
1192	  if (pReadGlxPixmap) {
1193	     be_read_draw = pReadGlxPixmap->be_xids[s];
1194	  }
1195	  else if (pGlxReadPbuffer) {
1196	     be_read_draw = pGlxReadPbuffer->be_xids[s];
1197	  }
1198#ifdef PANORAMIX
1199	  else if (pXinReadDraw) {
1200	     dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client,
1201			     DixReadAccess);
1202   	  }
1203#endif
1204	  else if (pGlxReadWindow) {
1205	     pReadWin = (WindowPtr)pGlxReadWindow->pDraw;
1206	  }
1207
1208      	  if (pReadWin && be_read_draw == None) {
1209  	     be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
1210	   if (!be_read_draw) {
1211	      /* it might be that the window did not created yet on the */
1212	      /* back-end server (lazy window creation option), force   */
1213	      /* creation of the window */
1214	      dmxCreateAndRealizeWindow( pReadWin, TRUE );
1215	      be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
1216              dmxSync( dmxScreen, 1 );
1217	   }
1218     	  }
1219
1220	  if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1221	     LockDisplay(dpy);
1222	     GetReq(GLXMakeContextCurrent, be_new_req);
1223	     be_new_req->reqType = dmxScreen->glxMajorOpcode;
1224	     be_new_req->glxCode = X_GLXMakeContextCurrent;
1225	     be_new_req->drawable = be_draw;
1226	     be_new_req->readdrawable = be_read_draw;
1227	     be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1228	     be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1229	     if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
1230
1231		/* The make current failed */
1232		UnlockDisplay(dpy);
1233   		SyncHandle();
1234   		return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1235   	     }
1236
1237   	     UnlockDisplay(dpy);
1238      	     SyncHandle();
1239
1240   	     SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag );
1241	  }
1242	  else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) {
1243	     xGLXMakeCurrentReadSGIReq *ext_req;
1244	     xGLXVendorPrivateWithReplyReq *vpreq;
1245             xGLXMakeCurrentReadSGIReply ext_reply;
1246
1247	     LockDisplay(dpy);
1248	     GetReqExtra(GLXVendorPrivateWithReply,
1249		         sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq,
1250		         vpreq);
1251	     ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq;
1252	     ext_req->reqType = dmxScreen->glxMajorOpcode;
1253	     ext_req->glxCode = X_GLXVendorPrivateWithReply;
1254	     ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
1255	     ext_req->drawable = be_draw;
1256	     ext_req->readable = be_read_draw;
1257	     ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1258	     ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1259	     if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
1260
1261		/* The make current failed */
1262		UnlockDisplay(dpy);
1263   		SyncHandle();
1264   		return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1265   	     }
1266
1267   	     UnlockDisplay(dpy);
1268      	     SyncHandle();
1269
1270   	     SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag );
1271
1272	  }
1273	  else {
1274	     return BadMatch;
1275	  }
1276       }
1277
1278       XFlush( dpy );
1279    }
1280
1281    if (client->swapped) {
1282	__glXSwapMakeCurrentReply(client, &new_reply);
1283    } else {
1284	WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply);
1285    }
1286
1287    return Success;
1288}
1289
1290int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
1291{
1292    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
1293
1294    return( MakeCurrent(cl, req->drawable, req->drawable,
1295	                req->context, req->oldContextTag ) );
1296}
1297
1298int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
1299{
1300    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
1301
1302    return( MakeCurrent(cl, req->drawable, req->readdrawable,
1303	                req->context, req->oldContextTag ) );
1304}
1305
1306int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
1307{
1308    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
1309
1310    return( MakeCurrent(cl, req->drawable, req->readable,
1311	                req->context, req->oldContextTag ) );
1312}
1313
1314int __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
1315{
1316    ClientPtr client = cl->client;
1317    xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
1318    xGLXIsDirectReply reply;
1319    __GLXcontext *glxc;
1320
1321    /*
1322    ** Find the GL context.
1323    */
1324    dixLookupResourceByType((pointer*) &glxc, req->context, __glXContextRes,
1325                            NullClient, DixUnknownAccess);
1326    if (!glxc) {
1327	client->errorValue = req->context;
1328	return __glXBadContext;
1329    }
1330
1331    reply.isDirect = 0;
1332    reply.length = 0;
1333    reply.type = X_Reply;
1334    reply.sequenceNumber = client->sequence;
1335
1336    if (client->swapped) {
1337	__glXSwapIsDirectReply(client, &reply);
1338    } else {
1339	WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
1340    }
1341
1342    return Success;
1343}
1344
1345int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
1346{
1347    ClientPtr client = cl->client;
1348/*    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
1349    xGLXQueryVersionReply reply;
1350
1351    /*
1352    ** Server should take into consideration the version numbers sent by the
1353    ** client if it wants to work with older clients; however, in this
1354    ** implementation the server just returns its version number.
1355    */
1356    reply.majorVersion = __glXVersionMajor;
1357    reply.minorVersion = __glXVersionMinor;
1358    reply.length = 0;
1359    reply.type = X_Reply;
1360    reply.sequenceNumber = client->sequence;
1361
1362    if (client->swapped) {
1363	__glXSwapQueryVersionReply(client, &reply);
1364    } else {
1365	WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
1366    }
1367    return Success;
1368}
1369
1370int __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
1371{
1372    xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
1373    xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc;
1374    int from_screen = 0;
1375    int to_screen = 0;
1376    int s;
1377    __GLXcontext *glxc = NULL;
1378
1379    if (req->contextTag != 0) {
1380	glxc = __glXLookupContextByTag(cl, req->contextTag);
1381	if (glxc) {
1382	   from_screen = to_screen = glxc->pScreen->myNum;
1383	}
1384    }
1385
1386#ifdef PANORAMIX
1387    if (!noPanoramiXExtension) {
1388       from_screen = 0;
1389       to_screen = screenInfo.numScreens - 1;
1390    }
1391#endif
1392
1393    for (s=from_screen; s<=to_screen; s++) {
1394       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1395       Display *dpy = GetBackEndDisplay(cl,s);
1396
1397       LockDisplay(dpy);
1398       GetReq(GLXWaitGL,be_req);
1399       be_req->reqType = dmxScreen->glxMajorOpcode;
1400       be_req->glxCode = X_GLXWaitGL;
1401       be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1402       UnlockDisplay(dpy);
1403       SyncHandle();
1404
1405       XSync(dpy, False);
1406    }
1407
1408    return Success;
1409}
1410
1411int __glXWaitX(__GLXclientState *cl, GLbyte *pc)
1412{
1413    xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
1414    xGLXWaitXReq *be_req;
1415    int from_screen = 0;
1416    int to_screen = 0;
1417    int s;
1418    __GLXcontext *glxc = NULL;
1419
1420    if (req->contextTag != 0) {
1421	glxc = __glXLookupContextByTag(cl, req->contextTag);
1422	if (glxc) {
1423	   from_screen = to_screen = glxc->pScreen->myNum;
1424	}
1425    }
1426
1427#ifdef PANORAMIX
1428    if (!noPanoramiXExtension) {
1429       from_screen = 0;
1430       to_screen = screenInfo.numScreens - 1;
1431    }
1432#endif
1433
1434    for (s=from_screen; s<=to_screen; s++) {
1435       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1436       Display *dpy = GetBackEndDisplay(cl,s);
1437
1438       dmxSync( dmxScreen, 1 );
1439
1440       LockDisplay(dpy);
1441       GetReq(GLXWaitX,be_req);
1442       be_req->reqType = dmxScreen->glxMajorOpcode;
1443       be_req->glxCode = X_GLXWaitX;
1444       be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1445       UnlockDisplay(dpy);
1446       SyncHandle();
1447
1448       XFlush( dpy );
1449    }
1450
1451    return Success;
1452}
1453
1454int __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
1455{
1456    ClientPtr client = cl->client;
1457    xGLXCopyContextReq *be_req;
1458    xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
1459    GLXContextID source = req->source;
1460    GLXContextID dest = req->dest;
1461    GLXContextTag tag = req->contextTag;
1462    unsigned long mask = req->mask;
1463    __GLXcontext *src, *dst;
1464    int s;
1465    int from_screen = 0;
1466    int to_screen = 0;
1467
1468    /*
1469    ** Check that each context exists.
1470    */
1471    dixLookupResourceByType((pointer*) &src, source, __glXContextRes,
1472                            NullClient, DixUnknownAccess);
1473    if (!src) {
1474	client->errorValue = source;
1475	return __glXBadContext;
1476    }
1477    dixLookupResourceByType((pointer*) &dst, dest, __glXContextRes,
1478                            NullClient, DixUnknownAccess);
1479    if (!dst) {
1480	client->errorValue = dest;
1481	return __glXBadContext;
1482    }
1483
1484    /*
1485    ** They must be in the same address space, and same screen.
1486    */
1487    if (src->pGlxScreen != dst->pGlxScreen) {
1488	client->errorValue = source;
1489	return BadMatch;
1490    }
1491
1492    /*
1493    ** The destination context must not be current for any client.
1494    */
1495    if (dst->isCurrent) {
1496	client->errorValue = dest;
1497	return BadAccess;
1498    }
1499
1500    if (tag) {
1501	__GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
1502
1503	if (!tagcx) {
1504	    return __glXBadContextTag;
1505	}
1506	if (tagcx != src) {
1507	    /*
1508	    ** This would be caused by a faulty implementation of the client
1509	    ** library.
1510	    */
1511	    return BadMatch;
1512	}
1513    }
1514
1515    from_screen = to_screen = src->pScreen->myNum;
1516
1517#ifdef PANORAMIX
1518    if (!noPanoramiXExtension) {
1519       from_screen = 0;
1520       to_screen = screenInfo.numScreens - 1;
1521    }
1522#endif
1523
1524    for (s=from_screen; s<=to_screen; s++) {
1525       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1526       Display *dpy = GetBackEndDisplay(cl,s);
1527
1528       LockDisplay(dpy);
1529       GetReq(GLXCopyContext,be_req);
1530       be_req->reqType = dmxScreen->glxMajorOpcode;
1531       be_req->glxCode = X_GLXCopyContext;
1532       be_req->source = (unsigned int)src->real_ids[s-from_screen];
1533       be_req->dest = (unsigned int)dst->real_ids[s-from_screen];
1534       be_req->mask = mask;
1535       be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1536       UnlockDisplay(dpy);
1537       SyncHandle();
1538    }
1539
1540    return Success;
1541}
1542
1543int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
1544{
1545    ClientPtr client = cl->client;
1546    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
1547    xGLXGetVisualConfigsReply reply;
1548    __GLXscreenInfo *pGlxScreen;
1549    __GLXvisualConfig *pGlxVisual;
1550    CARD32 buf[__GLX_TOTAL_CONFIG];
1551    unsigned int screen;
1552    int i, p;
1553
1554    screen = req->screen;
1555    if (screen >= screenInfo.numScreens) {
1556	/* The client library must send a valid screen number. */
1557	client->errorValue = screen;
1558	return BadValue;
1559    }
1560    pGlxScreen = &__glXActiveScreens[screen];
1561
1562    reply.numVisuals = pGlxScreen->numGLXVisuals;
1563    reply.numProps = __GLX_TOTAL_CONFIG;
1564    reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
1565		    __GLX_TOTAL_CONFIG) >> 2;
1566    reply.type = X_Reply;
1567    reply.sequenceNumber = client->sequence;
1568
1569    WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
1570
1571    for (i=0; i < pGlxScreen->numVisuals; i++) {
1572	pGlxVisual = &pGlxScreen->pGlxVisual[i];
1573	if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
1574	    /* not a usable visual */
1575	    continue;
1576	}
1577	p = 0;
1578	buf[p++] = pGlxVisual->vid;
1579	buf[p++] = pGlxVisual->class;
1580	buf[p++] = pGlxVisual->rgba;
1581
1582	buf[p++] = pGlxVisual->redSize;
1583	buf[p++] = pGlxVisual->greenSize;
1584	buf[p++] = pGlxVisual->blueSize;
1585	buf[p++] = pGlxVisual->alphaSize;
1586	buf[p++] = pGlxVisual->accumRedSize;
1587	buf[p++] = pGlxVisual->accumGreenSize;
1588	buf[p++] = pGlxVisual->accumBlueSize;
1589	buf[p++] = pGlxVisual->accumAlphaSize;
1590
1591	buf[p++] = pGlxVisual->doubleBuffer;
1592	buf[p++] = pGlxVisual->stereo;
1593
1594	buf[p++] = pGlxVisual->bufferSize;
1595	buf[p++] = pGlxVisual->depthSize;
1596	buf[p++] = pGlxVisual->stencilSize;
1597	buf[p++] = pGlxVisual->auxBuffers;
1598	buf[p++] = pGlxVisual->level;
1599	/*
1600	** Add token/value pairs for extensions.
1601	*/
1602	buf[p++] = GLX_VISUAL_CAVEAT_EXT;
1603	buf[p++] = pGlxVisual->visualRating;
1604	buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
1605	buf[p++] = pGlxVisual->transparentPixel;
1606	buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
1607	buf[p++] = pGlxVisual->transparentRed;
1608	buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
1609	buf[p++] = pGlxVisual->transparentGreen;
1610	buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
1611	buf[p++] = pGlxVisual->transparentBlue;
1612	buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
1613	buf[p++] = pGlxVisual->transparentAlpha;
1614	buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
1615	buf[p++] = pGlxVisual->transparentIndex;
1616	buf[p++] = GLX_SAMPLES_SGIS;
1617	buf[p++] = pGlxVisual->multiSampleSize;
1618	buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
1619	buf[p++] = pGlxVisual->nMultiSampleBuffers;
1620	buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
1621	buf[p++] = pGlxVisual->visualSelectGroup;
1622
1623	WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
1624		(char *)buf);
1625    }
1626    return Success;
1627}
1628
1629/*
1630** Create a GLX Pixmap from an X Pixmap.
1631*/
1632static int CreateGLXPixmap(__GLXclientState *cl,
1633                    VisualID visual, GLXFBConfigID fbconfigId,
1634		    int screenNum, XID pixmapId, XID glxpixmapId )
1635{
1636    ClientPtr client = cl->client;
1637    xGLXCreateGLXPixmapReq *be_req;
1638    xGLXCreatePixmapReq *be_new_req;
1639    DrawablePtr pDraw;
1640    ScreenPtr pScreen;
1641    VisualPtr pVisual;
1642    __GLXpixmap *pGlxPixmap;
1643    __GLXscreenInfo *pGlxScreen;
1644    __GLXvisualConfig *pGlxVisual;
1645    __GLXFBConfig *pFBConfig;
1646    int i, s, rc;
1647    int from_screen, to_screen;
1648#ifdef PANORAMIX
1649    PanoramiXRes *pXinDraw = NULL;
1650#endif
1651
1652    rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP,
1653			   DixAddAccess);
1654    if (rc != Success)
1655	return rc;
1656
1657    /*
1658    ** Check if screen of visual matches screen of pixmap.
1659    */
1660    pScreen = pDraw->pScreen;
1661    if (screenNum != pScreen->myNum) {
1662	return BadMatch;
1663    }
1664
1665    if (fbconfigId == 0 && visual == 0) {
1666	  return BadValue;
1667    }
1668
1669    if (fbconfigId != None) {
1670       pFBConfig = glxLookupFBConfig( fbconfigId );
1671       if (!pFBConfig) {
1672	  client->errorValue = fbconfigId;
1673	  return BadValue;
1674       }
1675       visual = pFBConfig->associatedVisualId;
1676    }
1677    else {
1678       pFBConfig = NULL;
1679    }
1680
1681    if (visual != None) {
1682       /*
1683	** Find the VisualRec for this visual.
1684	*/
1685       pVisual = pScreen->visuals;
1686       for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
1687	  if (pVisual->vid == visual) {
1688	     break;
1689	  }
1690       }
1691       if (i == pScreen->numVisuals) {
1692	  client->errorValue = visual;
1693	  return BadValue;
1694       }
1695       /*
1696	** Check if depth of visual matches depth of pixmap.
1697	*/
1698       if (pVisual->nplanes != pDraw->depth) {
1699	  client->errorValue = visual;
1700	  return BadMatch;
1701       }
1702
1703       /*
1704	** Get configuration of the visual.
1705	*/
1706       pGlxScreen = &__glXActiveScreens[screenNum];
1707       pGlxVisual = pGlxScreen->pGlxVisual;
1708       for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
1709	  if (pGlxVisual->vid == visual) {
1710	     break;
1711	  }
1712       }
1713       if (i == pGlxScreen->numVisuals) {
1714	  /*
1715	   ** Visual not support on this screen by this OpenGL implementation.
1716	   */
1717	  client->errorValue = visual;
1718	  return BadValue;
1719       }
1720
1721
1722       /* find the FBConfig for that visual (if any) */
1723       if ( pFBConfig == NULL ) {
1724	   pFBConfig = glxLookupFBConfigByVID( visual );
1725
1726	   if ( pFBConfig == NULL ) {
1727	      /*
1728               * visual does not have an FBConfig ???
1729	      client->errorValue = visual;
1730	      return BadValue;
1731	       */
1732	   }
1733       }
1734    }
1735    else {
1736       pVisual = NULL;
1737       pGlxVisual = NULL;
1738       pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum];
1739    }
1740
1741    pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap));
1742    if (!pGlxPixmap) {
1743	return BadAlloc;
1744    }
1745    pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens);
1746    if (!pGlxPixmap->be_xids) {
1747        free( pGlxPixmap );
1748	return BadAlloc;
1749    }
1750
1751    pGlxPixmap->pDraw = pDraw;
1752    pGlxPixmap->pGlxScreen = pGlxScreen;
1753    pGlxPixmap->pGlxVisual = pGlxVisual;
1754    pGlxPixmap->pFBConfig = pFBConfig;
1755    pGlxPixmap->pScreen = pScreen;
1756    pGlxPixmap->idExists = True;
1757    pGlxPixmap->refcnt = 0;
1758
1759    /*
1760    ** Bump the ref count on the X pixmap so it won't disappear.
1761    */
1762    ((PixmapPtr) pDraw)->refcnt++;
1763
1764    /*
1765     * send the request to the back-end server(s)
1766     */
1767    from_screen = to_screen = screenNum;
1768#ifdef PANORAMIX
1769    if (!noPanoramiXExtension) {
1770       from_screen = 0;
1771       to_screen = screenInfo.numScreens - 1;
1772
1773       dixLookupResourceByClass((pointer*) &pXinDraw,
1774				pDraw->id, XRC_DRAWABLE,
1775				client, DixReadAccess);
1776    }
1777#endif
1778
1779    for (s=from_screen; s<=to_screen; s++) {
1780
1781       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1782       Display *dpy = GetBackEndDisplay(cl,s);
1783       Pixmap  be_pixmap;
1784       DrawablePtr pRealDraw = pDraw;
1785
1786#ifdef PANORAMIX
1787       if (pXinDraw) {
1788	   dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0,
1789			     DixAddAccess);
1790       }
1791#endif
1792
1793       be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap;
1794
1795       /* make sure pixmap already created on back-end */
1796       dmxSync( dmxScreen, 1 );
1797
1798       if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1799       	  __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
1800
1801	  LockDisplay(dpy);
1802	  pGlxPixmap->be_xids[s] = XAllocID(dpy);
1803	  GetReq(GLXCreatePixmap,be_new_req);
1804	  be_new_req->reqType = dmxScreen->glxMajorOpcode;
1805	  be_new_req->glxCode = X_GLXCreatePixmap;
1806	  be_new_req->screen = DefaultScreen(dpy);
1807	  be_new_req->fbconfig = be_FBConfig->id;
1808	  be_new_req->pixmap = (unsigned int)be_pixmap;
1809	  be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1810	  be_new_req->numAttribs = 0;
1811	  UnlockDisplay(dpy);
1812	  SyncHandle();
1813       }
1814       else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
1815	  __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
1816	  xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req;
1817	  xGLXVendorPrivateReq *vpreq;
1818
1819	  LockDisplay(dpy);
1820	  pGlxPixmap->be_xids[s] = XAllocID(dpy);
1821	  GetReqExtra(GLXVendorPrivate,
1822		      sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,
1823		      vpreq);
1824	  ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
1825	  ext_req->reqType = dmxScreen->glxMajorOpcode;
1826	  ext_req->glxCode = X_GLXVendorPrivate;
1827	  ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
1828	  ext_req->screen = DefaultScreen(dpy);
1829	  ext_req->fbconfig = be_FBConfig->id;
1830	  ext_req->pixmap = (unsigned int)be_pixmap;
1831	  ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1832	  UnlockDisplay(dpy);
1833	  SyncHandle();
1834       }
1835       else if (pGlxVisual) {
1836	  LockDisplay(dpy);
1837	  pGlxPixmap->be_xids[s] = XAllocID(dpy);
1838	  GetReq(GLXCreateGLXPixmap,be_req);
1839	  be_req->reqType = dmxScreen->glxMajorOpcode;
1840	  be_req->glxCode = X_GLXCreateGLXPixmap;
1841	  be_req->screen = DefaultScreen(dpy);
1842	  be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList(
1843	 	pGlxVisual,
1844		dmxScreen->glxVisuals,
1845		dmxScreen->numGlxVisuals );
1846   	  be_req->pixmap = (unsigned int)be_pixmap;
1847      	  be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1848	  UnlockDisplay(dpy);
1849	  SyncHandle();
1850       }
1851       else {
1852	  client->errorValue = ( visual ? visual : fbconfigId );
1853          free( pGlxPixmap );
1854	  return BadValue;
1855       }
1856
1857       XFlush( dpy );
1858    }
1859
1860    if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
1861        free( pGlxPixmap );
1862	return BadAlloc;
1863    }
1864
1865    return Success;
1866}
1867
1868int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1869{
1870    xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
1871
1872    return( CreateGLXPixmap(cl, req->visual, None,
1873	                    req->screen, req->pixmap, req->glxpixmap) );
1874}
1875
1876int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
1877{
1878    xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
1879
1880    return( CreateGLXPixmap(cl, None, req->fbconfig,
1881	                    req->screen, req->pixmap, req->glxpixmap) );
1882}
1883
1884int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1885{
1886    ClientPtr client = cl->client;
1887    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
1888    XID glxpixmap = req->glxpixmap;
1889    __GLXpixmap *pGlxPixmap;
1890    int s;
1891    int from_screen, to_screen;
1892
1893    /*
1894    ** Check if it's a valid GLX pixmap.
1895    */
1896    dixLookupResourceByType((pointer*) &pGlxPixmap, glxpixmap,
1897                            __glXPixmapRes, NullClient, DixUnknownAccess);
1898    if (!pGlxPixmap) {
1899	client->errorValue = glxpixmap;
1900	return __glXBadPixmap;
1901    }
1902    FreeResource(glxpixmap, FALSE);
1903
1904    /*
1905     * destroy the pixmap on the back-end server(s).
1906     */
1907    from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum;
1908#ifdef PANORAMIX
1909    if (!noPanoramiXExtension) {
1910       from_screen = 0;
1911       to_screen = screenInfo.numScreens - 1;
1912    }
1913#endif
1914
1915    for (s=from_screen; s<=to_screen; s++) {
1916       DMXScreenInfo *dmxScreen = &dmxScreens[s];
1917       Display *dpy = GetBackEndDisplay(cl,s);
1918
1919       /* make sure pixmap exist in back-end */
1920       dmxSync( dmxScreen, 1 );
1921
1922       LockDisplay(dpy);
1923       GetReq(GLXDestroyGLXPixmap,req);
1924       req->reqType = dmxScreen->glxMajorOpcode;
1925       req->glxCode = X_GLXDestroyGLXPixmap;
1926       req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1927       UnlockDisplay(dpy);
1928       SyncHandle();
1929    }
1930
1931
1932    return Success;
1933}
1934
1935/*****************************************************************************/
1936
1937/*
1938** NOTE: There is no portable implementation for swap buffers as of
1939** this time that is of value.  Consequently, this code must be
1940** implemented by somebody other than SGI.
1941*/
1942int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag)
1943{
1944    ClientPtr client = cl->client;
1945    DrawablePtr pDraw;
1946    xGLXSwapBuffersReq *be_req;
1947    WindowPtr pWin = NULL;
1948    __GLXpixmap *pGlxPixmap = NULL;
1949    __GLXcontext *glxc = NULL;
1950#ifdef PANORAMIX
1951    PanoramiXRes *pXinDraw = NULL;
1952#endif
1953    __glXWindow *pGlxWindow = NULL;
1954    int from_screen = 0;
1955    int to_screen = 0;
1956    int s, rc;
1957
1958    /*
1959    ** Check that the GLX drawable is valid.
1960    */
1961    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
1962    if (rc == Success) {
1963        from_screen = to_screen = pDraw->pScreen->myNum;
1964
1965	if (pDraw->type == DRAWABLE_WINDOW) {
1966	    /*
1967	    ** Drawable is an X window.
1968	    */
1969	   pWin = (WindowPtr)pDraw;
1970	} else {
1971	    /*
1972	    ** Drawable is an X pixmap, which is not allowed.
1973	    */
1974	    client->errorValue = drawId;
1975	    return __glXBadDrawable;
1976	}
1977    }
1978
1979    if (!pDraw) {
1980	dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
1981				__glXPixmapRes, NullClient, DixUnknownAccess);
1982	if (pGlxPixmap) {
1983	    /*
1984	    ** Drawable is a GLX pixmap.
1985	    */
1986	   pDraw = pGlxPixmap->pDraw;
1987	   from_screen = to_screen = pGlxPixmap->pScreen->myNum;
1988	}
1989    }
1990
1991    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1992       dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
1993                               __glXWindowRes, NullClient, DixUnknownAccess);
1994       if (pGlxWindow) {
1995	  /*
1996	   ** Drawable is a GLXWindow.
1997	   */
1998	  pDraw = pGlxWindow->pDraw;
1999	  from_screen = to_screen = pGlxWindow->pScreen->myNum;
2000       }
2001    }
2002
2003    if (!pDraw) {
2004       /*
2005	** Drawable is neither a X window nor a GLX pixmap.
2006	*/
2007       client->errorValue = drawId;
2008       return __glXBadDrawable;
2009    }
2010
2011    if (tag) {
2012	glxc = __glXLookupContextByTag(cl, tag);
2013	if (!glxc) {
2014	    return __glXBadContextTag;
2015	}
2016    }
2017
2018#ifdef PANORAMIX
2019    if (!noPanoramiXExtension) {
2020       from_screen = 0;
2021       to_screen = screenInfo.numScreens - 1;
2022       dixLookupResourceByClass((pointer*) &pXinDraw,
2023				pDraw->id, XRC_DRAWABLE,
2024				client, DixReadAccess);
2025    }
2026#endif
2027
2028    /* If requested, send a glFinish to all back-end servers before swapping. */
2029    if (dmxGLXFinishSwap) {
2030	for (s=from_screen; s<=to_screen; s++) {
2031	    Display *dpy = GetBackEndDisplay(cl,s);
2032	    DMXScreenInfo *dmxScreen = &dmxScreens[s];
2033	    xGLXSingleReq *finishReq;
2034	    xGLXSingleReply reply;
2035
2036#define X_GLXSingle 0    /* needed by GetReq below */
2037
2038	    LockDisplay(dpy);
2039	    GetReq(GLXSingle,finishReq);
2040	    finishReq->reqType = dmxScreen->glxMajorOpcode;
2041	    finishReq->glxCode = X_GLsop_Finish;
2042	    finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0);
2043	    (void) _XReply(dpy, (xReply*) &reply, 0, False);
2044	    UnlockDisplay(dpy);
2045	    SyncHandle();
2046	}
2047    }
2048
2049    /* If requested, send an XSync to all back-end servers before swapping. */
2050    if (dmxGLXSyncSwap) {
2051	for (s=from_screen; s<=to_screen; s++)
2052	    XSync(GetBackEndDisplay(cl,s), False);
2053    }
2054
2055
2056    /* send the SwapBuffers request to all back-end servers */
2057
2058    for (s=from_screen; s<=to_screen; s++) {
2059       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2060       Display *dpy = GetBackEndDisplay(cl,s);
2061       unsigned int be_draw = 0;
2062
2063       if (pGlxPixmap) {
2064	  be_draw = (unsigned int)pGlxPixmap->be_xids[s];
2065       }
2066#ifdef PANORAMIX
2067       else if (pXinDraw) {
2068	  dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
2069       }
2070#endif
2071       else if (pGlxWindow) {
2072	  pWin = (WindowPtr)pGlxWindow->pDraw;
2073       }
2074
2075       if (pWin && !be_draw) {
2076	   be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
2077	   if (!be_draw) {
2078	      /* it might be that the window did not created yet on the */
2079	      /* back-end server (lazy window creation option), force   */
2080	      /* creation of the window */
2081	      dmxCreateAndRealizeWindow( pWin, TRUE );
2082	      be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
2083	   }
2084       }
2085
2086       dmxSync( dmxScreen, 1 );
2087
2088       LockDisplay(dpy);
2089       GetReq(GLXSwapBuffers,be_req);
2090       be_req->reqType = dmxScreen->glxMajorOpcode;
2091       be_req->glxCode = X_GLXSwapBuffers;
2092       be_req->drawable = be_draw;
2093       be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 );
2094       UnlockDisplay(dpy);
2095       SyncHandle();
2096       XFlush(dpy);
2097    }
2098
2099    return Success;
2100}
2101
2102int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
2103{
2104    ClientPtr client = cl->client;
2105    DrawablePtr pDraw;
2106    xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
2107    GLXContextTag tag = req->contextTag;
2108    XID drawId = req->drawable;
2109    __GLXpixmap *pGlxPixmap = NULL;
2110    __GLXcontext *glxc = NULL;
2111    __glXWindow *pGlxWindow = NULL;
2112    int rc;
2113
2114    /*
2115    ** Check that the GLX drawable is valid.
2116    */
2117    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
2118    if (rc == Success) {
2119	if (pDraw->type != DRAWABLE_WINDOW) {
2120	    /*
2121	    ** Drawable is an X pixmap, which is not allowed.
2122	    */
2123	    client->errorValue = drawId;
2124	    return __glXBadDrawable;
2125	}
2126    }
2127
2128    if (!pDraw) {
2129	dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
2130				__glXPixmapRes, NullClient, DixUnknownAccess);
2131	if (pGlxPixmap) {
2132	    /*
2133	    ** Drawable is a GLX pixmap.
2134	    */
2135	   pDraw = pGlxPixmap->pDraw;
2136	}
2137    }
2138
2139    if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
2140       dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
2141                               __glXWindowRes, NullClient, DixUnknownAccess);
2142       if (pGlxWindow) {
2143	  /*
2144	   ** Drawable is a GLXWindow.
2145	   */
2146	  pDraw = pGlxWindow->pDraw;
2147       }
2148    }
2149
2150    if (!pDraw) {
2151       /*
2152	** Drawable is neither a X window nor a GLX pixmap.
2153	*/
2154       client->errorValue = drawId;
2155       return __glXBadDrawable;
2156    }
2157
2158    if (tag) {
2159	glxc = __glXLookupContextByTag(cl, tag);
2160	if (!glxc) {
2161	    return __glXBadContextTag;
2162	}
2163    }
2164
2165    if (pDraw &&
2166	pDraw->type == DRAWABLE_WINDOW &&
2167	DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) {
2168	return SGSwapBuffers(cl, drawId, tag, pDraw);
2169    }
2170
2171    return __glXDoSwapBuffers(cl, drawId, tag);
2172}
2173
2174
2175/************************************************************************/
2176
2177/*
2178** Render and Renderlarge are not in the GLX API.  They are used by the GLX
2179** client library to send batches of GL rendering commands.
2180*/
2181
2182/*
2183** Execute all the drawing commands in a request.
2184*/
2185int __glXRender(__GLXclientState *cl, GLbyte *pc)
2186{
2187    xGLXRenderReq *req;
2188    xGLXRenderReq *be_req;
2189    int size;
2190    __GLXcontext *glxc;
2191    int from_screen = 0;
2192    int to_screen = 0;
2193    int s;
2194
2195    /*
2196    ** NOTE: much of this code also appears in the byteswapping version of this
2197    ** routine, __glXSwapRender().  Any changes made here should also be
2198    ** duplicated there.
2199    */
2200
2201    req = (xGLXRenderReq *) pc;
2202
2203    glxc = __glXLookupContextByTag(cl, req->contextTag);
2204    if (!glxc) {
2205	return 0;
2206    }
2207    from_screen = to_screen = glxc->pScreen->myNum;
2208
2209#ifdef PANORAMIX
2210    if (!noPanoramiXExtension) {
2211       from_screen = 0;
2212       to_screen = screenInfo.numScreens - 1;
2213    }
2214#endif
2215
2216    pc += sz_xGLXRenderReq;
2217    size = (req->length << 2) - sz_xGLXRenderReq;
2218
2219    /*
2220     * just forward the request to back-end server(s)
2221     */
2222    for (s=from_screen; s<=to_screen; s++) {
2223       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2224       Display *dpy = GetBackEndDisplay(cl,s);
2225
2226       LockDisplay(dpy);
2227       GetReq(GLXRender,be_req);
2228       be_req->reqType = dmxScreen->glxMajorOpcode;
2229       be_req->glxCode = X_GLXRender;
2230       be_req->length = req->length;
2231       be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
2232       _XSend(dpy, (const char *)pc, size);
2233       UnlockDisplay(dpy);
2234       SyncHandle();
2235    }
2236
2237    return Success;
2238}
2239
2240/*
2241** Execute a large rendering request (one that spans multiple X requests).
2242*/
2243int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
2244{
2245    xGLXRenderLargeReq *req;
2246    xGLXRenderLargeReq *be_req;
2247    __GLXcontext *glxc;
2248    int from_screen = 0;
2249    int to_screen = 0;
2250    int s;
2251
2252    /*
2253    ** NOTE: much of this code also appears in the byteswapping version of this
2254    ** routine, __glXSwapRenderLarge().  Any changes made here should also be
2255    ** duplicated there.
2256    */
2257
2258    req = (xGLXRenderLargeReq *) pc;
2259    glxc = __glXLookupContextByTag(cl, req->contextTag);
2260    if (!glxc) {
2261	return 0;
2262    }
2263    from_screen = to_screen = glxc->pScreen->myNum;
2264
2265#ifdef PANORAMIX
2266    if (!noPanoramiXExtension) {
2267       from_screen = 0;
2268       to_screen = screenInfo.numScreens - 1;
2269    }
2270#endif
2271
2272    pc += sz_xGLXRenderLargeReq;
2273
2274    /*
2275     * just forward the request to back-end server(s)
2276     */
2277    for (s=from_screen; s<=to_screen; s++) {
2278       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2279       Display *dpy = GetBackEndDisplay(cl,s);
2280
2281       GetReq(GLXRenderLarge,be_req);
2282       be_req->reqType = dmxScreen->glxMajorOpcode;
2283       be_req->glxCode = X_GLXRenderLarge;
2284       be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
2285       be_req->length = req->length;
2286       be_req->requestNumber = req->requestNumber;
2287       be_req->requestTotal = req->requestTotal;
2288       be_req->dataBytes = req->dataBytes;
2289       Data(dpy, (const char *)pc, req->dataBytes);
2290       UnlockDisplay(dpy);
2291       SyncHandle();
2292
2293    }
2294
2295    return Success;
2296}
2297
2298
2299/************************************************************************/
2300
2301int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
2302{
2303    xGLXVendorPrivateReq *req;
2304
2305    req = (xGLXVendorPrivateReq *) pc;
2306
2307    switch( req->vendorCode ) {
2308
2309       case X_GLvop_DeleteTexturesEXT:
2310	  return __glXVForwardSingleReq( cl, pc );
2311	  break;
2312
2313       case X_GLXvop_SwapIntervalSGI:
2314	  if (glxIsExtensionSupported("SGI_swap_control")) {
2315	     return __glXVForwardSingleReq( cl, pc );
2316	  }
2317	  else {
2318	     return Success;
2319	  }
2320	  break;
2321
2322#if 0 /* glx 1.3 */
2323       case X_GLXvop_CreateGLXVideoSourceSGIX:
2324	  break;
2325       case X_GLXvop_DestroyGLXVideoSourceSGIX:
2326	  break;
2327       case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
2328	  break;
2329       case X_GLXvop_DestroyGLXPbufferSGIX:
2330	  break;
2331       case X_GLXvop_ChangeDrawableAttributesSGIX:
2332	  break;
2333#endif
2334
2335       case X_GLXvop_BindSwapBarrierSGIX:
2336	  return __glXBindSwapBarrierSGIX( cl, pc );
2337	  break;
2338
2339       case X_GLXvop_JoinSwapGroupSGIX:
2340	  return __glXJoinSwapGroupSGIX( cl, pc );
2341	  break;
2342
2343       case X_GLXvop_CreateContextWithConfigSGIX:
2344	  return __glXCreateContextWithConfigSGIX( cl, pc );
2345	  break;
2346
2347       default:
2348	  /*
2349	   ** unsupported private request
2350	   */
2351	  cl->client->errorValue = req->vendorCode;
2352	  return __glXUnsupportedPrivateRequest;
2353    }
2354
2355    cl->client->errorValue = req->vendorCode;
2356    return __glXUnsupportedPrivateRequest;
2357
2358}
2359
2360int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
2361{
2362    xGLXVendorPrivateWithReplyReq *req;
2363
2364    req = (xGLXVendorPrivateWithReplyReq *) pc;
2365
2366    switch( req->vendorCode ) {
2367
2368       case X_GLvop_GetConvolutionFilterEXT:
2369       case X_GLvop_GetConvolutionParameterfvEXT:
2370       case X_GLvop_GetConvolutionParameterivEXT:
2371       case X_GLvop_GetSeparableFilterEXT:
2372       case X_GLvop_GetHistogramEXT:
2373       case X_GLvop_GetHistogramParameterivEXT:
2374       case X_GLvop_GetMinmaxEXT:
2375       case X_GLvop_GetMinmaxParameterfvEXT:
2376       case X_GLvop_GetMinmaxParameterivEXT:
2377       case X_GLvop_AreTexturesResidentEXT:
2378       case X_GLvop_IsTextureEXT:
2379	  return( __glXVForwardPipe0WithReply(cl, pc) );
2380	  break;
2381
2382       case X_GLvop_GenTexturesEXT:
2383	  return( __glXVForwardAllWithReply(cl, pc) );
2384	  break;
2385
2386
2387#if 0 /* glx1.3 */
2388       case X_GLvop_GetDetailTexFuncSGIS:
2389       case X_GLvop_GetSharpenTexFuncSGIS:
2390       case X_GLvop_GetColorTableSGI:
2391       case X_GLvop_GetColorTableParameterfvSGI:
2392       case X_GLvop_GetColorTableParameterivSGI:
2393       case X_GLvop_GetTexFilterFuncSGIS:
2394       case X_GLvop_GetInstrumentsSGIX:
2395       case X_GLvop_InstrumentsBufferSGIX:
2396       case X_GLvop_PollInstrumentsSGIX:
2397       case X_GLvop_FlushRasterSGIX:
2398       case X_GLXvop_CreateGLXPbufferSGIX:
2399       case X_GLXvop_GetDrawableAttributesSGIX:
2400       case X_GLXvop_QueryHyperpipeNetworkSGIX:
2401       case X_GLXvop_QueryHyperpipeConfigSGIX:
2402       case X_GLXvop_HyperpipeConfigSGIX:
2403       case X_GLXvop_DestroyHyperpipeConfigSGIX:
2404#endif
2405       case X_GLXvop_QueryMaxSwapBarriersSGIX:
2406	  return( __glXQueryMaxSwapBarriersSGIX(cl, pc) );
2407	  break;
2408
2409       case X_GLXvop_GetFBConfigsSGIX:
2410	  return( __glXGetFBConfigsSGIX(cl, pc) );
2411	  break;
2412
2413       case X_GLXvop_MakeCurrentReadSGI:
2414	  return( __glXMakeCurrentReadSGI(cl, pc) );
2415	  break;
2416
2417       case X_GLXvop_QueryContextInfoEXT:
2418	  return( __glXQueryContextInfoEXT(cl,pc) );
2419	  break;
2420
2421       default:
2422	  /*
2423	   ** unsupported private request
2424	   */
2425	  cl->client->errorValue = req->vendorCode;
2426	  return __glXUnsupportedPrivateRequest;
2427    }
2428
2429}
2430
2431int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
2432{
2433    ClientPtr client = cl->client;
2434    xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
2435    xGLXQueryExtensionsStringReply reply;
2436    GLint screen;
2437    size_t length;
2438    int len, numbytes;
2439    char *be_buf;
2440
2441#ifdef FWD_QUERY_REQ
2442    xGLXQueryExtensionsStringReq *be_req;
2443    xGLXQueryExtensionsStringReply be_reply;
2444    DMXScreenInfo *dmxScreen;
2445    Display *dpy;
2446    int slop;
2447#endif
2448
2449    screen = req->screen;
2450
2451    /*
2452    ** Check if screen exists.
2453    */
2454    if ((screen < 0) || (screen >= screenInfo.numScreens)) {
2455	client->errorValue = screen;
2456	return BadValue;
2457    }
2458
2459#ifdef FWD_QUERY_REQ
2460    dmxScreen = &dmxScreens[screen];
2461
2462    /* Send the glXQueryServerString request */
2463    dpy = GetBackEndDisplay(cl,screen);
2464    LockDisplay(dpy);
2465    GetReq(GLXQueryExtensionsString,be_req);
2466    be_req->reqType = dmxScreen->glxMajorOpcode;
2467    be_req->glxCode = X_GLXQueryServerString;
2468    be_req->screen = DefaultScreen(dpy);
2469    _XReply(dpy, (xReply*) &be_reply, 0, False);
2470    len = (int)be_reply.length;
2471    numbytes = (int)be_reply.n;
2472    slop = numbytes * __GLX_SIZE_INT8 & 3;
2473    be_buf = (char *)malloc(numbytes);
2474    if (!be_buf) {
2475        /* Throw data on the floor */
2476        _XEatData(dpy, len);
2477    } else {
2478        _XRead(dpy, (char *)be_buf, numbytes);
2479        if (slop) _XEatData(dpy,4-slop);
2480    }
2481    UnlockDisplay(dpy);
2482    SyncHandle();
2483
2484#else
2485
2486    be_buf = __glXGetServerString(GLX_EXTENSIONS);
2487    numbytes = strlen(be_buf) + 1;
2488    len = __GLX_PAD(numbytes) >> 2;
2489
2490#endif
2491
2492    length = len;
2493    reply.type = X_Reply;
2494    reply.sequenceNumber = client->sequence;
2495    reply.length = len;
2496    reply.n = numbytes;
2497
2498    if (client->swapped) {
2499        glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
2500    } else {
2501        WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
2502        WriteToClient(client, (int)(length << 2), (char *)be_buf);
2503    }
2504
2505    return Success;
2506}
2507
2508int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
2509{
2510    ClientPtr client = cl->client;
2511    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
2512    xGLXQueryServerStringReply reply;
2513    int name;
2514    GLint screen;
2515    size_t length;
2516    int len, numbytes;
2517    char *be_buf;
2518#ifdef FWD_QUERY_REQ
2519    xGLXQueryServerStringReq *be_req;
2520    xGLXQueryServerStringReply be_reply;
2521    DMXScreenInfo *dmxScreen;
2522    Display *dpy;
2523    int  slop;
2524#endif
2525
2526    name = req->name;
2527    screen = req->screen;
2528    /*
2529    ** Check if screen exists.
2530    */
2531    if ((screen < 0) || (screen >= screenInfo.numScreens)) {
2532	client->errorValue = screen;
2533	return BadValue;
2534    }
2535
2536#ifdef FWD_QUERY_REQ
2537    dmxScreen = &dmxScreens[screen];
2538
2539    /* Send the glXQueryServerString request */
2540    dpy = GetBackEndDisplay(cl,screen);
2541    LockDisplay(dpy);
2542    GetReq(GLXQueryServerString,be_req);
2543    be_req->reqType = dmxScreen->glxMajorOpcode;
2544    be_req->glxCode = X_GLXQueryServerString;
2545    be_req->screen = DefaultScreen(dpy);
2546    be_req->name = name;
2547    _XReply(dpy, (xReply*) &be_reply, 0, False);
2548    len = (int)be_reply.length;
2549    numbytes = (int)be_reply.n;
2550    slop = numbytes * __GLX_SIZE_INT8 & 3;
2551    be_buf = (char *)malloc(numbytes);
2552    if (!be_buf) {
2553        /* Throw data on the floor */
2554        _XEatData(dpy, len);
2555    } else {
2556        _XRead(dpy, (char *)be_buf, numbytes);
2557        if (slop) _XEatData(dpy,4-slop);
2558    }
2559    UnlockDisplay(dpy);
2560    SyncHandle();
2561
2562#else
2563    be_buf = __glXGetServerString(name);
2564    numbytes = strlen(be_buf) + 1;
2565    len = __GLX_PAD(numbytes) >> 2;
2566#endif
2567
2568    length = len;
2569    reply.type = X_Reply;
2570    reply.sequenceNumber = client->sequence;
2571    reply.length = length;
2572    reply.n = numbytes;
2573
2574    if (client->swapped) {
2575        glxSwapQueryServerStringReply(client, &reply, be_buf);
2576    } else {
2577        WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
2578        WriteToClient(client, (int)(length << 2), be_buf);
2579    }
2580
2581    return Success;
2582}
2583
2584int __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
2585{
2586    xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
2587    xGLXClientInfoReq *be_req;
2588    const char *buf;
2589    int from_screen = 0;
2590    int to_screen = 0;
2591    int s;
2592
2593    cl->GLClientmajorVersion = req->major;
2594    cl->GLClientminorVersion = req->minor;
2595    free(cl->GLClientextensions);
2596    buf = (const char *)(req+1);
2597    cl->GLClientextensions = strdup(buf);
2598
2599    to_screen = screenInfo.numScreens - 1;
2600
2601    for (s=from_screen; s<=to_screen; s++)
2602    {
2603       DMXScreenInfo *dmxScreen = &dmxScreens[s];
2604       Display *dpy = GetBackEndDisplay(cl,s);
2605
2606       LockDisplay(dpy);
2607       GetReq(GLXClientInfo,be_req);
2608       be_req->reqType = dmxScreen->glxMajorOpcode;
2609       be_req->glxCode = X_GLXClientInfo;
2610       be_req->major = req->major;
2611       be_req->minor = req->minor;
2612       be_req->length = req->length;
2613       be_req->numbytes = req->numbytes;
2614       Data(dpy, buf, req->numbytes);
2615
2616       UnlockDisplay(dpy);
2617       SyncHandle();
2618    }
2619
2620    return Success;
2621}
2622
2623int __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
2624{
2625    ClientPtr client = cl->client;
2626    xGLXUseXFontReq *req;
2627    xGLXUseXFontReq *be_req;
2628    FontPtr pFont;
2629    __GLXcontext *glxc = NULL;
2630    int from_screen = 0;
2631    int to_screen = 0;
2632    int s;
2633    dmxFontPrivPtr  pFontPriv;
2634    DMXScreenInfo *dmxScreen;
2635    Display *dpy;
2636
2637    req = (xGLXUseXFontReq *) pc;
2638
2639    if (req->contextTag != 0) {
2640	glxc = __glXLookupContextByTag(cl, req->contextTag);
2641	if (glxc) {
2642	   from_screen = to_screen = glxc->pScreen->myNum;
2643	}
2644    }
2645
2646    /*
2647    ** Font can actually be either the ID of a font or the ID of a GC
2648    ** containing a font.
2649    */
2650    dixLookupResourceByType((pointer*) &pFont, req->font, RT_FONT,
2651                            NullClient, DixUnknownAccess);
2652    if (!pFont) {
2653        GC *pGC;
2654        dixLookupResourceByType((pointer*) &pGC, req->font,
2655				RT_GC, NullClient,
2656				DixUnknownAccess);
2657        if (!pGC) {
2658	    client->errorValue = req->font;
2659            return BadFont;
2660	}
2661	pFont = pGC->font;
2662    }
2663
2664    pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
2665
2666#ifdef PANORAMIX
2667    if (!noPanoramiXExtension) {
2668       from_screen = 0;
2669       to_screen = screenInfo.numScreens - 1;
2670    }
2671#endif
2672
2673
2674    for (s=from_screen; s<=to_screen; s++) {
2675       dmxScreen = &dmxScreens[s];
2676       dpy = GetBackEndDisplay(cl,s);
2677
2678       dmxSync( dmxScreen, 1 );
2679
2680       LockDisplay(dpy);
2681       GetReq(GLXUseXFont,be_req);
2682       be_req->reqType = dmxScreen->glxMajorOpcode;
2683       be_req->glxCode = X_GLXUseXFont;
2684       be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
2685       be_req->font = pFontPriv->font[s]->fid;
2686       be_req->first = req->first;
2687       be_req->count = req->count;
2688       be_req->listBase = req->listBase;
2689       UnlockDisplay(dpy);
2690       SyncHandle();
2691
2692       XSync( dpy, False );
2693    }
2694
2695    return Success;
2696}
2697
2698/*
2699 * start GLX 1.3 here
2700 */
2701
2702int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
2703{
2704    ClientPtr client = cl->client;
2705    xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
2706    xGLXGetFBConfigsReply reply;
2707    __GLXFBConfig *pFBConfig;
2708    CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS];
2709    int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS;
2710    unsigned int screen = req->screen;
2711    int numFBConfigs, i, p;
2712    __GLXscreenInfo *pGlxScreen;
2713
2714    if (screen >= screenInfo.numScreens) {
2715	/* The client library must send a valid screen number. */
2716	client->errorValue = screen;
2717	return BadValue;
2718    }
2719
2720    pGlxScreen = &__glXActiveScreens[screen];
2721    numFBConfigs = __glXNumFBConfigs;
2722
2723    reply.numFBConfigs = numFBConfigs;
2724    reply.numAttribs = numAttribs;
2725    reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2;
2726    reply.type = X_Reply;
2727    reply.sequenceNumber = client->sequence;
2728
2729    if (client->swapped) {
2730	__GLX_DECLARE_SWAP_VARIABLES;
2731	__GLX_SWAP_SHORT(&reply.sequenceNumber);
2732	__GLX_SWAP_INT(&reply.length);
2733	__GLX_SWAP_INT(&reply.numFBConfigs);
2734	__GLX_SWAP_INT(&reply.numAttribs);
2735    }
2736    WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
2737
2738    for (i=0; i < numFBConfigs; i++) {
2739       int associatedVisualId = 0;
2740       int drawableTypeIndex;
2741       pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ];
2742
2743	p = 0;
2744	/* core attributes */
2745	buf[p++] = GLX_FBCONFIG_ID;
2746	buf[p++] = pFBConfig->id;
2747	buf[p++] = GLX_BUFFER_SIZE;
2748	buf[p++] = pFBConfig->indexBits;
2749	buf[p++] = GLX_LEVEL;
2750	buf[p++] = pFBConfig->level;
2751	buf[p++] = GLX_DOUBLEBUFFER;
2752	buf[p++] = pFBConfig->doubleBufferMode;
2753	buf[p++] = GLX_STEREO;
2754	buf[p++] = pFBConfig->stereoMode;
2755	buf[p++] = GLX_AUX_BUFFERS;
2756	buf[p++] = pFBConfig->maxAuxBuffers;
2757	buf[p++] = GLX_RED_SIZE;
2758	buf[p++] = pFBConfig->redBits;
2759	buf[p++] = GLX_GREEN_SIZE;
2760	buf[p++] = pFBConfig->greenBits;
2761	buf[p++] = GLX_BLUE_SIZE;
2762	buf[p++] = pFBConfig->blueBits;
2763	buf[p++] = GLX_ALPHA_SIZE;
2764	buf[p++] = pFBConfig->alphaBits;
2765	buf[p++] = GLX_DEPTH_SIZE;
2766	buf[p++] = pFBConfig->depthBits;
2767	buf[p++] = GLX_STENCIL_SIZE;
2768	buf[p++] = pFBConfig->stencilBits;
2769	buf[p++] = GLX_ACCUM_RED_SIZE;
2770	buf[p++] = pFBConfig->accumRedBits;
2771	buf[p++] = GLX_ACCUM_GREEN_SIZE;
2772	buf[p++] = pFBConfig->accumGreenBits;
2773	buf[p++] = GLX_ACCUM_BLUE_SIZE;
2774	buf[p++] = pFBConfig->accumBlueBits;
2775	buf[p++] = GLX_ACCUM_ALPHA_SIZE;
2776	buf[p++] = pFBConfig->accumAlphaBits;
2777	buf[p++] = GLX_RENDER_TYPE;
2778	buf[p++] = pFBConfig->renderType;
2779	buf[p++] = GLX_DRAWABLE_TYPE;
2780	drawableTypeIndex = p;
2781	buf[p++] = pFBConfig->drawableType;
2782	buf[p++] = GLX_X_VISUAL_TYPE;
2783	buf[p++] = pFBConfig->visualType;
2784	buf[p++] = GLX_CONFIG_CAVEAT;
2785	buf[p++] = pFBConfig->visualCaveat;
2786	buf[p++] = GLX_TRANSPARENT_TYPE;
2787	buf[p++] = pFBConfig->transparentType;
2788	buf[p++] = GLX_TRANSPARENT_RED_VALUE;
2789	buf[p++] = pFBConfig->transparentRed;
2790	buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
2791	buf[p++] = pFBConfig->transparentGreen;
2792	buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
2793	buf[p++] = pFBConfig->transparentBlue;
2794	buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
2795	buf[p++] = pFBConfig->transparentAlpha;
2796	buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
2797	buf[p++] = pFBConfig->transparentIndex;
2798	buf[p++] = GLX_MAX_PBUFFER_WIDTH;
2799	buf[p++] = pFBConfig->maxPbufferWidth;
2800	buf[p++] = GLX_MAX_PBUFFER_HEIGHT;
2801	buf[p++] = pFBConfig->maxPbufferHeight;
2802	buf[p++] = GLX_MAX_PBUFFER_PIXELS;
2803	buf[p++] = pFBConfig->maxPbufferPixels;
2804
2805	/*
2806         * find the visual of the back-end server and match a visual
2807	 * on the proxy.
2808	 * do only once - if a visual is not yet associated.
2809	 */
2810	if (pFBConfig->associatedVisualId == (unsigned int)-1) {
2811	   DMXScreenInfo *dmxScreen = &dmxScreens[screen];
2812	   __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ];
2813	   __GLXvisualConfig *pGlxVisual = NULL;
2814	   int v;
2815	   int found = 0;
2816	   for (v=0; v<dmxScreen->numGlxVisuals; v++) {
2817	      if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) {
2818		 pGlxVisual = &dmxScreen->glxVisuals[v];
2819		 break;
2820	      }
2821	   }
2822
2823	   if (pGlxVisual) {
2824	      for (v=0; v<pGlxScreen->numVisuals; v++) {
2825		 if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) {
2826		    associatedVisualId = pGlxScreen->pGlxVisual[v].vid;
2827		    found = 1;
2828		    break;
2829		 }
2830	      }
2831	   }
2832
2833	   if (!found) {
2834	      associatedVisualId = 0;
2835	      pFBConfig->drawableType &= ~(GLX_WINDOW_BIT);
2836	      buf[drawableTypeIndex] = pFBConfig->drawableType;
2837	   }
2838#ifdef PANORAMIX
2839	   else if (!noPanoramiXExtension) {
2840	      /* convert the associated visualId to the panoramix one */
2841	      pFBConfig->associatedVisualId =
2842		  PanoramiXTranslateVisualID(screen, v);
2843	   }
2844#endif
2845	}
2846	else {
2847	   associatedVisualId = pFBConfig->associatedVisualId;
2848	}
2849
2850	buf[p++] = GLX_VISUAL_ID;
2851	buf[p++] = associatedVisualId;
2852
2853	/* SGIS_multisample attributes */
2854	buf[p++] = GLX_SAMPLES_SGIS;
2855	buf[p++] = pFBConfig->multiSampleSize;
2856	buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
2857	buf[p++] = pFBConfig->nMultiSampleBuffers;
2858
2859	/* SGIX_pbuffer specific attributes */
2860	buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX;
2861	buf[p++] = pFBConfig->optimalPbufferWidth;
2862	buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX;
2863	buf[p++] = pFBConfig->optimalPbufferHeight;
2864
2865	buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
2866	buf[p++] = pFBConfig->visualSelectGroup;
2867
2868	if (client->swapped) {
2869	    __GLX_DECLARE_SWAP_VARIABLES;
2870	    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
2871	    __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs);
2872	}
2873	WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf);
2874    }
2875    return Success;
2876}
2877
2878int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
2879{
2880   xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
2881   xGLXGetFBConfigsReq new_req;
2882
2883   new_req.reqType = req->reqType;
2884   new_req.glxCode = req->glxCode;
2885   new_req.length = req->length;
2886   new_req.screen = req->screen;
2887
2888   return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) );
2889}
2890
2891
2892int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc)
2893{
2894    ClientPtr client = cl->client;
2895    xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
2896    int screen = req->screen;
2897    GLXFBConfigID fbconfigId = req->fbconfig;
2898    XID windowId = req->window;
2899    XID glxwindowId = req->glxwindow;
2900    DrawablePtr pDraw;
2901    ScreenPtr pScreen;
2902    __glXWindow *pGlxWindow;
2903    __GLXFBConfig *pGlxFBConfig = NULL;
2904    VisualPtr pVisual;
2905    VisualID visId;
2906    int i, rc;
2907    pointer val;
2908
2909    /*
2910    ** Check if windowId is valid
2911    */
2912    rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
2913			   DixAddAccess);
2914    if (rc != Success)
2915	return rc;
2916
2917    /*
2918    ** Check if screen of window matches screen of fbconfig.
2919    */
2920    pScreen = pDraw->pScreen;
2921    if (screen != pScreen->myNum) {
2922	return BadMatch;
2923    }
2924
2925    /*
2926    ** Find the FBConfigRec for this fbconfigid.
2927    */
2928    if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
2929	client->errorValue = fbconfigId;
2930	return __glXBadFBConfig;
2931    }
2932    visId = pGlxFBConfig->associatedVisualId;
2933
2934    /*
2935    ** Check if the fbconfig supports rendering to windows
2936    */
2937    if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) {
2938	return BadMatch;
2939    }
2940
2941    if (visId != None) {
2942       /*
2943	** Check if the visual ID is valid for this screen.
2944	*/
2945       pVisual = pScreen->visuals;
2946       for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
2947	  if (pVisual->vid == visId) {
2948	     break;
2949	  }
2950       }
2951       if (i == pScreen->numVisuals) {
2952	  client->errorValue = visId;
2953	  return BadValue;
2954       }
2955
2956        /*
2957        ** Check if color buffer depth of fbconfig matches depth
2958	** of window.
2959        */
2960        if (pVisual->nplanes != pDraw->depth) {
2961	    return BadMatch;
2962	}
2963    } else
2964	/*
2965	** The window was created with no visual that corresponds
2966	** to fbconfig
2967	*/
2968	return BadMatch;
2969
2970    /*
2971    ** Check if there is already a fbconfig associated with this window
2972    */
2973    if (Success == dixLookupResourceByType(&val,
2974					   glxwindowId, __glXWindowRes,
2975					   NullClient, DixUnknownAccess)) {
2976	client->errorValue = glxwindowId;
2977	return BadAlloc;
2978    }
2979
2980    pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow));
2981    if (!pGlxWindow) {
2982	return BadAlloc;
2983    }
2984
2985    /*
2986    ** Register this GLX window as a resource
2987    */
2988    if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) {
2989	return BadAlloc;
2990    }
2991
2992    pGlxWindow->pDraw = pDraw;
2993    pGlxWindow->type = GLX_GLXWINDOW_TYPE;
2994    pGlxWindow->idExists = True;
2995    pGlxWindow->refcnt = 0;
2996    pGlxWindow->pGlxFBConfig = pGlxFBConfig;
2997    pGlxWindow->pScreen = pScreen;
2998
2999    return Success;
3000}
3001
3002int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
3003{
3004    ClientPtr client = cl->client;
3005    xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
3006    XID glxwindow = req->glxwindow;
3007    pointer val;
3008
3009    /*
3010    ** Check if it's a valid GLX window.
3011    */
3012    if (Success != dixLookupResourceByType(&val,
3013					   glxwindow, __glXWindowRes,
3014					   NullClient, DixUnknownAccess)) {
3015	client->errorValue = glxwindow;
3016	return __glXBadDrawable;
3017    }
3018    /*
3019    ** The glx window destructor will check whether it's current before
3020    ** freeing anything.
3021    */
3022    FreeResource(glxwindow, RT_NONE);
3023
3024    return Success;
3025}
3026
3027int __glXQueryContext(__GLXclientState *cl, GLbyte *pc)
3028{
3029    ClientPtr client = cl->client;
3030    __GLXcontext *ctx;
3031    xGLXQueryContextReq *req;
3032    xGLXQueryContextReply reply;
3033    int nProps;
3034    int *sendBuf, *pSendBuf;
3035    int nReplyBytes;
3036
3037    req = (xGLXQueryContextReq *)pc;
3038    dixLookupResourceByType((pointer*) &ctx, req->context, __glXContextRes,
3039                            NullClient, DixUnknownAccess);
3040    if (!ctx) {
3041        client->errorValue = req->context;
3042        return __glXBadContext;
3043    }
3044
3045    nProps = 3;
3046
3047    reply.length = nProps << 1;
3048    reply.type = X_Reply;
3049    reply.sequenceNumber = client->sequence;
3050    reply.n = nProps;
3051
3052    nReplyBytes = reply.length << 2;
3053    sendBuf = (int *)malloc(nReplyBytes);
3054    pSendBuf = sendBuf;
3055    *pSendBuf++ = GLX_FBCONFIG_ID;
3056    *pSendBuf++ = (int)(ctx->pFBConfig->id);
3057    *pSendBuf++ = GLX_RENDER_TYPE;
3058    *pSendBuf++ = (int)(ctx->pFBConfig->renderType);
3059    *pSendBuf++ = GLX_SCREEN;
3060    *pSendBuf++ = (int)(ctx->pScreen->myNum);
3061
3062    if (client->swapped) {
3063        __glXSwapQueryContextReply(client, &reply, sendBuf);
3064    } else {
3065        WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply);
3066        WriteToClient(client, nReplyBytes, (char *)sendBuf);
3067    }
3068    free((char *)sendBuf);
3069
3070    return Success;
3071}
3072
3073int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
3074{
3075    ClientPtr client = cl->client;
3076    __GLXcontext *ctx;
3077    xGLXQueryContextInfoEXTReq *req;
3078    xGLXQueryContextInfoEXTReply reply;
3079    int nProps;
3080    int *sendBuf, *pSendBuf;
3081    int nReplyBytes;
3082
3083    req = (xGLXQueryContextInfoEXTReq *)pc;
3084    dixLookupResourceByType((pointer*) &ctx,
3085			    req->context, __glXContextRes,
3086			    client,  DixReadAccess);
3087
3088    if (!ctx) {
3089        client->errorValue = req->context;
3090        return __glXBadContext;
3091    }
3092
3093    nProps = 4;
3094
3095    reply.length = nProps << 1;
3096    reply.type = X_Reply;
3097    reply.sequenceNumber = client->sequence;
3098    reply.n = nProps;
3099
3100    nReplyBytes = reply.length << 2;
3101    sendBuf = (int *)malloc(nReplyBytes);
3102    pSendBuf = sendBuf;
3103    *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
3104    *pSendBuf++ = (int)(ctx->share_id);
3105    *pSendBuf++ = GLX_VISUAL_ID_EXT;
3106    *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0);
3107    *pSendBuf++ = GLX_SCREEN_EXT;
3108    *pSendBuf++ = (int)(ctx->pScreen->myNum);
3109    *pSendBuf++ = GLX_FBCONFIG_ID;
3110    *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0);
3111
3112    if (client->swapped) {
3113        __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
3114    } else {
3115        WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
3116        WriteToClient(client, nReplyBytes, (char *)sendBuf);
3117    }
3118    free((char *)sendBuf);
3119
3120    return Success;
3121}
3122
3123int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
3124{
3125    ClientPtr client = cl->client;
3126    xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
3127    xGLXCreatePbufferReq *be_req;
3128    int screen = req->screen;
3129    GLXFBConfigID fbconfigId = req->fbconfig;
3130    GLXPbuffer pbuffer = req->pbuffer;
3131    __glXPbuffer *pGlxPbuffer;
3132    int numAttribs = req->numAttribs;
3133    int *attr;
3134    ScreenPtr pScreen;
3135    __GLXFBConfig *pGlxFBConfig;
3136    __GLXFBConfig *be_pGlxFBConfig;
3137    XID be_xid;
3138    Display *dpy;
3139    DMXScreenInfo *dmxScreen;
3140    int s;
3141    int from_screen, to_screen;
3142
3143   /*
3144    ** Look up screen and FBConfig.
3145    */
3146    if (screen >= screenInfo.numScreens) {
3147        /* The client library must send a valid screen number. */
3148        client->errorValue = screen;
3149        return BadValue;
3150    }
3151    pScreen = screenInfo.screens[screen];
3152
3153    /*
3154    ** Find the FBConfigRec for this fbconfigid.
3155    */
3156    if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
3157	client->errorValue = fbconfigId;
3158	return __glXBadFBConfig;
3159    }
3160
3161    /*
3162    ** Create the GLX part of the Pbuffer.
3163    */
3164    pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer));
3165    if (!pGlxPbuffer) {
3166        return BadAlloc;
3167    }
3168
3169    pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens );
3170    if (!pGlxPbuffer->be_xids) {
3171        free(pGlxPbuffer);
3172        return BadAlloc;
3173    }
3174
3175    /*
3176     * Allocate an XID on the back-end server(s) and send him the request
3177     */
3178    from_screen = to_screen = screen;
3179#ifdef PANORAMIX
3180    if (!noPanoramiXExtension) {
3181       from_screen = 0;
3182       to_screen = screenInfo.numScreens - 1;
3183    }
3184#endif
3185
3186    for (s=from_screen; s<=to_screen; s++) {
3187       dpy = GetBackEndDisplay(cl,s);
3188       be_xid = XAllocID(dpy);
3189       dmxScreen = &dmxScreens[s];
3190       be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s );
3191
3192       attr = (int *)( req+1 );
3193
3194       LockDisplay(dpy);
3195       GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req);
3196       be_req->reqType = dmxScreen->glxMajorOpcode;
3197       be_req->glxCode = X_GLXCreatePbuffer;
3198       be_req->screen = be_pGlxFBConfig->screen;
3199       be_req->fbconfig = be_pGlxFBConfig->id;
3200       be_req->pbuffer = be_xid;
3201       be_req->numAttribs = numAttribs;
3202
3203       /* Send attributes */
3204       if ( attr != NULL ) {
3205	  CARD32 *pc = (CARD32 *)(be_req + 1);
3206
3207	  while (numAttribs-- > 0) {
3208	     *pc++ = *attr++;     /* token */
3209	     *pc++ = *attr++;     /* value */
3210	  }
3211       }
3212
3213       UnlockDisplay(dpy);
3214       SyncHandle();
3215
3216       pGlxPbuffer->be_xids[s] = be_xid;
3217    }
3218
3219
3220    pGlxPbuffer->idExists = True;
3221    pGlxPbuffer->refcnt = 0;
3222    pGlxPbuffer->pFBConfig = pGlxFBConfig;
3223    pGlxPbuffer->pScreen = pScreen;
3224
3225    /*
3226    ** Register the resource.
3227    */
3228    if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) {
3229        return BadAlloc;
3230    }
3231
3232    return Success;
3233
3234}
3235
3236int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
3237{
3238    ClientPtr client = cl->client;
3239    xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
3240    xGLXDestroyPbufferReq *be_req;
3241    GLXPbuffer pbuffer = req->pbuffer;
3242    Display *dpy;
3243    int screen;
3244    DMXScreenInfo *dmxScreen;
3245    __glXPbuffer *pGlxPbuffer;
3246    int s;
3247    int from_screen, to_screen;
3248
3249    /*
3250    ** Check if it's a valid Pbuffer
3251    */
3252    dixLookupResourceByType((pointer*) &pGlxPbuffer, pbuffer,
3253                            __glXPbufferRes, NullClient, DixUnknownAccess);
3254    if (!pGlxPbuffer) {
3255	client->errorValue = pbuffer;
3256	return __glXBadPbuffer;
3257    }
3258
3259    screen = pGlxPbuffer->pScreen->myNum;
3260
3261    from_screen = to_screen = screen;
3262#ifdef PANORAMIX
3263    if (!noPanoramiXExtension) {
3264       from_screen = 0;
3265       to_screen = screenInfo.numScreens - 1;
3266    }
3267#endif
3268
3269    for (s=from_screen; s<=to_screen; s++) {
3270       dpy = GetBackEndDisplay(cl,s);
3271       dmxScreen = &dmxScreens[s];
3272
3273       /* send the destroy request to the back-end server */
3274       LockDisplay(dpy);
3275       GetReq(GLXDestroyPbuffer, be_req);
3276       be_req->reqType = dmxScreen->glxMajorOpcode;
3277       be_req->glxCode = X_GLXDestroyPbuffer;
3278       be_req->pbuffer = pGlxPbuffer->be_xids[s];
3279       UnlockDisplay(dpy);
3280       SyncHandle();
3281    }
3282
3283    FreeResource(pbuffer, RT_NONE);
3284
3285    return Success;
3286}
3287
3288int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
3289{
3290   xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
3291   xGLXGetDrawableAttributesReq *be_req;
3292   xGLXGetDrawableAttributesReply reply;
3293   ClientPtr client = cl->client;
3294   GLXDrawable drawId = req->drawable;
3295   GLXDrawable be_drawable = 0;
3296   DrawablePtr pDraw = NULL;
3297   Display *dpy;
3298   int screen, rc;
3299   DMXScreenInfo *dmxScreen;
3300   CARD32 *attribs = NULL;
3301   int attribs_size = 0;
3302#ifdef PANORAMIX
3303    PanoramiXRes *pXinDraw = NULL;
3304#endif
3305
3306   if (drawId != None) {
3307      rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
3308      if (rc == Success && pDraw->type == DRAWABLE_WINDOW) {
3309	 WindowPtr pWin = (WindowPtr)pDraw;
3310	 be_drawable = 0;
3311	 screen = pWin->drawable.pScreen->myNum;
3312      } else {
3313	 /*
3314	  ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3315	  */
3316	 client->errorValue = drawId;
3317	 return __glXBadDrawable;
3318      }
3319
3320      if (!pDraw) {
3321	 __GLXpixmap *pGlxPixmap;
3322	 dixLookupResourceByType((pointer*) &pGlxPixmap,
3323				 drawId, __glXPixmapRes,
3324				 NullClient, DixUnknownAccess);
3325	 if (pGlxPixmap) {
3326		pDraw = pGlxPixmap->pDraw;
3327		screen = pGlxPixmap->pScreen->myNum;
3328                be_drawable = pGlxPixmap->be_xids[screen];
3329	 }
3330      }
3331
3332      if (!pDraw) {
3333	 __glXWindow *pGlxWindow;
3334	 dixLookupResourceByType((pointer*) &pGlxWindow,
3335				 drawId, __glXWindowRes,
3336				 NullClient, DixUnknownAccess);
3337	 if (pGlxWindow) {
3338	    pDraw = pGlxWindow->pDraw;
3339	    screen = pGlxWindow->pScreen->myNum;
3340	    be_drawable = 0;
3341     	 }
3342      }
3343
3344      if (!pDraw) {
3345	 __glXPbuffer *pGlxPbuffer;
3346	 dixLookupResourceByType((pointer*) &pGlxPbuffer,
3347				 drawId, __glXPbufferRes,
3348				 NullClient, DixUnknownAccess);
3349	 if (pGlxPbuffer) {
3350    	    pDraw = (DrawablePtr)pGlxPbuffer;
3351	    screen = pGlxPbuffer->pScreen->myNum;
3352	    be_drawable = pGlxPbuffer->be_xids[screen];
3353	 }
3354      }
3355    }
3356
3357    if (!pDraw) {
3358	/*
3359	 ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3360	 */
3361	client->errorValue = drawId;
3362	return __glXBadDrawable;
3363   }
3364
3365   /* if the drawable is a window or GLXWindow -
3366    * we need to find the base id on the back-end server
3367    */
3368   if (!be_drawable) {
3369       WindowPtr pWin = (WindowPtr)pDraw;
3370
3371#ifdef PANORAMIX
3372       if (!noPanoramiXExtension) {
3373	  if (Success != dixLookupResourceByClass((pointer*) &pXinDraw,
3374						  pDraw->id, XRC_DRAWABLE,
3375						  client, DixReadAccess)) {
3376	     client->errorValue = drawId;
3377	     return __glXBadDrawable;
3378	  }
3379
3380	  dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
3381			  DixReadAccess);
3382       }
3383#endif
3384
3385       if (pWin) {
3386	   be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3387	   if (!be_drawable) {
3388	      /* it might be that the window did not created yet on the */
3389	      /* back-end server (lazy window creation option), force   */
3390	      /* creation of the window */
3391	      dmxCreateAndRealizeWindow( pWin, TRUE );
3392	      be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3393	   }
3394       }
3395       else {
3396	  client->errorValue = drawId;
3397	  return __glXBadDrawable;
3398       }
3399   }
3400
3401
3402   /* send the request to the back-end server */
3403   dpy = GetBackEndDisplay(cl,screen);
3404   dmxScreen = &dmxScreens[screen];
3405
3406   /* make sure drawable exists on back-end */
3407   dmxSync( dmxScreen, 1 );
3408
3409   LockDisplay(dpy);
3410   GetReq(GLXGetDrawableAttributes, be_req);
3411   be_req->reqType = dmxScreen->glxMajorOpcode;
3412   be_req->glxCode = X_GLXGetDrawableAttributes;
3413   be_req->drawable = be_drawable;
3414   be_req->length = req->length;
3415   if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
3416      UnlockDisplay(dpy);
3417      SyncHandle();
3418      return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
3419   }
3420
3421   if (reply.numAttribs) {
3422      attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
3423      attribs = (CARD32 *) malloc(attribs_size);
3424      if (attribs == NULL) {
3425	 UnlockDisplay(dpy);
3426	 SyncHandle();
3427	 return BadAlloc;
3428      }
3429
3430      _XRead(dpy, (char *) attribs, attribs_size);
3431   }
3432
3433   UnlockDisplay(dpy);
3434   SyncHandle();
3435
3436
3437   /* send the reply back to the client */
3438   reply.sequenceNumber = client->sequence;
3439   if (client->swapped) {
3440      __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs);
3441   }
3442   else {
3443      WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply);
3444      WriteToClient(client, attribs_size, (char *)attribs);
3445   }
3446
3447   free(attribs);
3448
3449   return Success;
3450}
3451
3452int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
3453{
3454   xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
3455   xGLXChangeDrawableAttributesReq *be_req;
3456   ClientPtr client = cl->client;
3457   GLXDrawable drawId = req->drawable;
3458   GLXDrawable be_drawable = 0;
3459   DrawablePtr pDraw = NULL;
3460   Display *dpy;
3461   int screen, rc;
3462   DMXScreenInfo *dmxScreen;
3463
3464   if (drawId != None) {
3465      rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess);
3466      if (rc == Success && pDraw->type == DRAWABLE_WINDOW) {
3467	  be_drawable = 0;
3468	  screen = pDraw->pScreen->myNum;
3469      } else {
3470	 /*
3471	  ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3472	  */
3473	 client->errorValue = drawId;
3474	 return __glXBadDrawable;
3475      }
3476
3477      if (!pDraw) {
3478	 __GLXpixmap *pGlxPixmap;
3479	 dixLookupResourceByType((pointer*) &pGlxPixmap,
3480				 drawId, __glXPixmapRes,
3481				 NullClient, DixUnknownAccess);
3482	 if (pGlxPixmap) {
3483		pDraw = pGlxPixmap->pDraw;
3484		screen = pGlxPixmap->pScreen->myNum;
3485                be_drawable = pGlxPixmap->be_xids[screen];
3486	 }
3487      }
3488
3489      if (!pDraw) {
3490	 __glXWindow *pGlxWindow;
3491	 dixLookupResourceByType((pointer*) &pGlxWindow,
3492				 drawId, __glXWindowRes,
3493				 NullClient, DixUnknownAccess);
3494	 if (pGlxWindow) {
3495	    pDraw = pGlxWindow->pDraw;
3496	    screen = pGlxWindow->pScreen->myNum;
3497	    be_drawable = 0;
3498     	 }
3499      }
3500
3501      if (!pDraw) {
3502	 __glXPbuffer *pGlxPbuffer;
3503	 dixLookupResourceByType((pointer*) &pGlxPbuffer,
3504				 drawId, __glXPbufferRes,
3505				 NullClient, DixUnknownAccess);
3506	 if (pGlxPbuffer) {
3507    	    pDraw = (DrawablePtr)pGlxPbuffer;
3508	    screen = pGlxPbuffer->pScreen->myNum;
3509	    be_drawable = pGlxPbuffer->be_xids[screen];
3510	 }
3511      }
3512   }
3513
3514   if (!pDraw) {
3515	 /*
3516	  ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3517	  */
3518	 client->errorValue = drawId;
3519	 return __glXBadDrawable;
3520   }
3521
3522   /* if the drawable is a window or GLXWindow -
3523    * we need to find the base id on the back-end server
3524    */
3525   if (!be_drawable) {
3526       WindowPtr pWin = (WindowPtr)pDraw;
3527
3528#ifdef PANORAMIX
3529       if (!noPanoramiXExtension) {
3530	  PanoramiXRes *pXinDraw;
3531	  if (Success != dixLookupResourceByClass((pointer*) &pXinDraw,
3532						  pDraw->id, XRC_DRAWABLE,
3533						  client, DixReadAccess)) {
3534	     client->errorValue = drawId;
3535	     return __glXBadDrawable;
3536	  }
3537
3538	  dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
3539			  DixReadAccess);
3540       }
3541#endif
3542
3543       if (pWin) {
3544	   be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3545	   if (!be_drawable) {
3546	      /* it might be that the window did not created yet on the */
3547	      /* back-end server (lazy window creation option), force   */
3548	      /* creation of the window */
3549	      dmxCreateAndRealizeWindow( pWin, TRUE );
3550	      be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3551	   }
3552       }
3553       else {
3554	  client->errorValue = drawId;
3555	  return __glXBadDrawable;
3556       }
3557   }
3558
3559
3560   /* send the request to the back-end server */
3561   dpy = GetBackEndDisplay(cl,screen);
3562   dmxScreen = &dmxScreens[screen];
3563
3564   /* make sure drawable exists on back-end */
3565   dmxSync( dmxScreen, 1 );
3566
3567   LockDisplay(dpy);
3568   GetReqExtra(GLXChangeDrawableAttributes,
3569                        2 * req->numAttribs * __GLX_SIZE_CARD32, be_req);
3570   be_req->reqType = dmxScreen->glxMajorOpcode;
3571   be_req->glxCode = X_GLXChangeDrawableAttributes;
3572   be_req->drawable = be_drawable;
3573   be_req->numAttribs = req->numAttribs;
3574   be_req->length = req->length;
3575
3576   UnlockDisplay(dpy);
3577   SyncHandle();
3578
3579   return Success;
3580}
3581
3582int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag)
3583{
3584   ClientPtr client = cl->client;
3585    xGLXRenderLargeReq *req;
3586    GLint maxSize, amount;
3587    GLint totalRequests, requestNumber;
3588    GLint dataLen;
3589    GLbyte *data;
3590    __GLXcontext *glxc;
3591    int s;
3592    int from_screen, to_screen;
3593
3594    maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq);
3595    dataLen = cl->largeCmdBytesTotal;
3596    totalRequests = (dataLen / maxSize);
3597    if (dataLen % maxSize) totalRequests++;
3598
3599    glxc = __glXLookupContextByTag(cl, contextTag);
3600    if (!glxc) {
3601       client->errorValue = contextTag;
3602       return __glXBadContext;
3603    }
3604    from_screen = to_screen = glxc->pScreen->myNum;
3605
3606#ifdef PANORAMIX
3607    if (!noPanoramiXExtension) {
3608       from_screen = 0;
3609       to_screen = screenInfo.numScreens - 1;
3610    }
3611#endif
3612
3613    /*
3614    ** Send enough requests until the whole array is sent.
3615    */
3616    requestNumber = 1;
3617    data = cl->largeCmdBuf;
3618    while (dataLen > 0) {
3619	amount = dataLen;
3620	if (amount > maxSize) {
3621	    amount = maxSize;
3622	}
3623
3624	for (s=from_screen; s<=to_screen; s++) {
3625
3626	   Display *dpy = GetBackEndDisplay(cl,s);
3627	   DMXScreenInfo *dmxScreen = &dmxScreens[s];
3628
3629	   LockDisplay(dpy);
3630	   GetReq(GLXRenderLarge,req);
3631	   req->reqType = dmxScreen->glxMajorOpcode;
3632	   req->glxCode = X_GLXRenderLarge;
3633	   req->contextTag = GetCurrentBackEndTag(cl,contextTag,s);
3634	   req->length += (amount + 3) >> 2;
3635	   req->requestNumber = requestNumber++;
3636	   req->requestTotal = totalRequests;
3637	   req->dataBytes = amount;
3638	   Data(dpy, ((const char*)data), amount);
3639	   dataLen -= amount;
3640	   data = ((GLbyte *) data) + amount;
3641	   UnlockDisplay(dpy);
3642	   SyncHandle();
3643	}
3644    }
3645
3646    return Success;
3647}
3648