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