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