Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / dmx / glxProxy / glxcmds.c
blob6771cf1de9ede694ca8fb18545e8616109de4bde
1 /*
2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9 **
10 ** http://oss.sgi.com/projects/FreeB
11 **
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17 **
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
23 **
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
36 #ifdef HAVE_DMX_CONFIG_H
37 #include <dmx-config.h>
38 #endif
40 #include "dmx.h"
41 #include "dmxwindow.h"
42 #include "dmxpixmap.h"
43 #include "dmxfont.h"
44 #include "dmxsync.h"
46 #undef Xmalloc
47 #undef Xcalloc
48 #undef Xrealloc
49 #undef Xfree
51 #define NEED_REPLIES
52 #define FONT_PCF
53 #include "glxserver.h"
54 #include <GL/glxtokens.h>
55 #include "g_disptab.h"
56 #include <pixmapstr.h>
57 #include <windowstr.h>
58 #include "glxutil.h"
59 #include "glxext.h"
60 #include "unpack.h"
62 #include "GL/glxproto.h"
63 #include "glxvendor.h"
64 #include "glxvisuals.h"
65 #include "glxswap.h"
67 #ifdef PANORAMIX
68 #include "panoramiXsrv.h"
69 extern XID *PanoramiXVisualTable;
70 #endif
72 extern __GLXFBConfig **__glXFBConfigs;
73 extern int __glXNumFBConfigs;
75 extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id );
76 extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid );
77 extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen );
78 extern int glxIsExtensionSupported( char *ext );
79 extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
81 #define BE_TO_CLIENT_ERROR(x) \
82 ( (x) >= __glXerrorBase ? \
83 (x) - dmxScreen->glxErrorBase + __glXerrorBase \
84 : (x) )
86 Display *GetBackEndDisplay( __GLXclientState *cl, int s )
88 if (! cl->be_displays[s] ) {
89 cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) );
91 return( cl->be_displays[s] );
95 ** Create a GL context with the given properties.
97 static int CreateContext(__GLXclientState *cl,
98 GLXContextID gcId,
99 VisualID vid, GLXFBConfigID fbconfigId,
100 int screen,
101 GLXContextID shareList,
102 int isDirect )
104 ClientPtr client = cl->client;
105 xGLXCreateContextReq *be_req;
106 xGLXCreateNewContextReq *be_new_req;
107 VisualPtr pVisual;
108 ScreenPtr pScreen;
109 __GLXcontext *glxc, *shareglxc;
110 __GLXvisualConfig *pGlxVisual;
111 __GLXscreenInfo *pGlxScreen;
112 VisualID visual = vid;
113 GLint i;
114 int from_screen = screen;
115 int to_screen = screen;
116 DMXScreenInfo *dmxScreen;
117 VisualID be_vid;
118 GLXFBConfigID be_fbconfigId;
119 int num_be_screens;
120 Display *dpy;
123 ** Check if screen exists.
125 if (screen >= screenInfo.numScreens) {
126 client->errorValue = screen;
127 return BadValue;
131 #ifdef PANORAMIX
132 if (!noPanoramiXExtension) {
133 from_screen = 0;
134 to_screen = screenInfo.numScreens - 1;
136 #endif
139 ** Find the display list space that we want to share.
142 if (shareList == None) {
143 shareglxc = NULL;
144 } else {
145 shareglxc = (__GLXcontext *) LookupIDByType(shareList, __glXContextRes);
146 if (!shareglxc) {
147 client->errorValue = shareList;
148 return __glXBadContext;
153 ** Allocate memory for the new context
155 glxc = (__GLXcontext *) __glXMalloc(sizeof(__GLXcontext));
156 if (!glxc) {
157 return BadAlloc;
159 memset(glxc, 0, sizeof(__GLXcontext));
161 pScreen = screenInfo.screens[screen];
162 pGlxScreen = &__glXActiveScreens[screen];
164 if (fbconfigId != None) {
165 glxc->pFBConfig = glxLookupFBConfig( fbconfigId );
166 if (!glxc->pFBConfig) {
167 client->errorValue = fbconfigId;
168 __glXFree( glxc );
169 return BadValue;
171 visual = glxc->pFBConfig->associatedVisualId;
173 else {
174 glxc->pFBConfig = NULL;
177 if (visual != None) {
179 ** Check if the visual ID is valid for this screen.
181 pVisual = pScreen->visuals;
182 for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
183 if (pVisual->vid == visual) {
184 break;
187 if (i == pScreen->numVisuals) {
188 client->errorValue = visual;
189 __glXFree( glxc );
190 return BadValue;
193 pGlxVisual = pGlxScreen->pGlxVisual;
194 for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
195 if (pGlxVisual->vid == visual) {
196 break;
199 if (i == pGlxScreen->numVisuals) {
201 ** Visual not support on this screen by this OpenGL implementation.
203 client->errorValue = visual;
204 __glXFree( glxc );
205 return BadValue;
208 if ( glxc->pFBConfig == NULL ) {
209 glxc->pFBConfig = glxLookupFBConfigByVID( visual );
211 if ( glxc->pFBConfig == NULL ) {
213 * visual does not have an FBConfig ???
214 client->errorValue = visual;
215 __glXFree( glxc );
216 return BadValue;
221 else {
222 pVisual = NULL;
223 pGlxVisual = NULL;
226 glxc->pScreen = pScreen;
227 glxc->pGlxScreen = pGlxScreen;
228 glxc->pVisual = pVisual;
229 glxc->pGlxVisual = pGlxVisual;
232 * allocate memory for back-end servers info
234 num_be_screens = to_screen - from_screen + 1;
235 glxc->real_ids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
236 if (!glxc->real_ids) {
237 return BadAlloc;
239 glxc->real_vids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
240 if (!glxc->real_vids) {
241 return BadAlloc;
244 for (screen = from_screen; screen <= to_screen; screen++) {
245 int sent = 0;
246 pScreen = screenInfo.screens[screen];
247 pGlxScreen = &__glXActiveScreens[screen];
248 dmxScreen = &dmxScreens[screen];
250 if (glxc->pFBConfig) {
251 __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id,
252 screen );
253 be_fbconfigId = beFBConfig->id;
256 if (pGlxVisual) {
258 be_vid = glxMatchGLXVisualInConfigList( pGlxVisual,
259 dmxScreen->glxVisuals,
260 dmxScreen->numGlxVisuals );
262 if (!be_vid) {
263 /* visual is not supported on the back-end server */
264 __glXFree( glxc->real_ids );
265 __glXFree( glxc->real_vids );
266 __glXFree( glxc );
267 return BadValue;
271 glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen));
273 /* send the create context request to the back-end server */
274 dpy = GetBackEndDisplay(cl,screen);
275 if (glxc->pFBConfig) {
276 /*Since for a certain visual both RGB and COLOR INDEX
277 *can be on then the only parmeter to choose the renderType
278 * should be the class of the colormap since all 4 first
279 * classes does not support RGB mode only COLOR INDEX ,
280 * and so TrueColor and DirectColor does not support COLOR INDEX*/
281 int renderType = glxc->pFBConfig->renderType;
282 if ( pVisual ) {
283 switch ( pVisual->class ){
284 case PseudoColor:
285 case StaticColor:
286 case GrayScale:
287 case StaticGray:
288 renderType = GLX_COLOR_INDEX_TYPE;
289 break;
290 case TrueColor:
291 case DirectColor:
292 default:
293 renderType = GLX_RGBA_TYPE;
294 break;
297 if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
298 LockDisplay(dpy);
299 GetReq(GLXCreateNewContext,be_new_req);
300 be_new_req->reqType = dmxScreen->glxMajorOpcode;
301 be_new_req->glxCode = X_GLXCreateNewContext;
302 be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
303 be_new_req->fbconfig = (unsigned int)be_fbconfigId;
304 be_new_req->screen = DefaultScreen(dpy);
305 be_new_req->renderType = renderType;
307 be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
308 be_new_req->isDirect = 0;
309 UnlockDisplay(dpy);
310 glxc->real_vids[screen-from_screen] = be_fbconfigId;
311 sent = 1;
313 else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
315 xGLXCreateContextWithConfigSGIXReq *ext_req;
316 xGLXVendorPrivateReq *vpreq;
317 LockDisplay(dpy);
318 GetReqExtra(GLXVendorPrivate,
319 sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq,
320 vpreq);
321 ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
322 ext_req->reqType = dmxScreen->glxMajorOpcode;
323 ext_req->glxCode = X_GLXVendorPrivate;
324 ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
325 ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
326 ext_req->fbconfig = (unsigned int)be_fbconfigId;
327 ext_req->screen = DefaultScreen(dpy);
328 ext_req->renderType = renderType;
329 ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
330 ext_req->isDirect = 0;
331 UnlockDisplay(dpy);
332 glxc->real_vids[screen-from_screen] = be_fbconfigId;
333 sent = 1;
337 if (!sent) {
338 LockDisplay(dpy);
339 GetReq(GLXCreateContext,be_req);
340 be_req->reqType = dmxScreen->glxMajorOpcode;
341 be_req->glxCode = X_GLXCreateContext;
342 be_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
343 be_req->visual = (unsigned int)be_vid;
344 be_req->screen = DefaultScreen(dpy);
345 be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
346 be_req->isDirect = 0;
347 UnlockDisplay(dpy);
348 glxc->real_vids[screen-from_screen] = be_vid;
350 SyncHandle();
355 ** Register this context as a resource.
357 if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
358 __glXFree( glxc->real_ids );
359 __glXFree( glxc->real_vids );
360 __glXFree( glxc );
361 client->errorValue = gcId;
362 return BadAlloc;
366 ** Finally, now that everything is working, setup the rest of the
367 ** context.
369 glxc->id = gcId;
370 glxc->share_id = shareList;
371 glxc->idExists = GL_TRUE;
372 glxc->isCurrent = GL_FALSE;
374 return Success;
377 int __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
379 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
381 return( CreateContext(cl, req->context,req->visual, None,
382 req->screen, req->shareList, req->isDirect) );
386 int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
388 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
390 return( CreateContext(cl, req->context,None, req->fbconfig,
391 req->screen, req->shareList, req->isDirect) );
395 int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
397 xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
399 return( CreateContext(cl, req->context, None, req->fbconfig,
400 req->screen, req->shareList, req->isDirect) );
404 int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
406 ClientPtr client = cl->client;
407 xGLXQueryMaxSwapBarriersSGIXReq *req =
408 (xGLXQueryMaxSwapBarriersSGIXReq *)pc;
409 xGLXQueryMaxSwapBarriersSGIXReply reply;
411 reply.type = X_Reply;
412 reply.sequenceNumber = client->sequence;
413 reply.length = 0;
414 reply.max = QueryMaxSwapBarriersSGIX(req->screen);
416 if (client->swapped) {
417 __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
418 } else {
419 WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
420 (char *)&reply);
423 return Success;
426 int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
428 ClientPtr client = cl->client;
429 xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
430 DrawablePtr pDraw;
431 __GLXpixmap *pGlxPixmap = NULL;
432 __glXWindow *pGlxWindow = NULL;
433 int rc;
435 rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixUnknownAccess);
436 if (rc != Success) {
437 pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
438 __glXPixmapRes);
439 if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
442 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
443 pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
444 __glXWindowRes);
445 if (pGlxWindow) pDraw = pGlxWindow->pDraw;
448 if (!pDraw) {
449 client->errorValue = req->drawable;
450 return __glXBadDrawable;
453 return BindSwapBarrierSGIX(pDraw, req->barrier);
456 int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
458 ClientPtr client = cl->client;
459 xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
460 DrawablePtr pDraw, pMember = NULL;
461 __GLXpixmap *pGlxPixmap = NULL;
462 __glXWindow *pGlxWindow = NULL;
463 int rc;
465 rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixUnknownAccess);
466 if (rc != Success) {
467 pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
468 __glXPixmapRes);
469 if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
472 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
473 pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
474 __glXWindowRes);
475 if (pGlxWindow) pDraw = pGlxWindow->pDraw;
478 if (!pDraw) {
479 client->errorValue = req->drawable;
480 return __glXBadDrawable;
483 if (req->member != None) {
484 rc = dixLookupDrawable(&pMember, req->member, client, 0,
485 DixUnknownAccess);
486 if (rc != Success) {
487 pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->member,
488 __glXPixmapRes);
489 if (pGlxPixmap) pMember = pGlxPixmap->pDraw;
492 if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
493 pGlxWindow = (__glXWindow *) LookupIDByType(req->member,
494 __glXWindowRes);
495 if (pGlxWindow) pMember = pGlxWindow->pDraw;
498 if (!pMember) {
499 client->errorValue = req->member;
500 return __glXBadDrawable;
504 return JoinSwapGroupSGIX(pDraw, pMember);
509 ** Destroy a GL context as an X resource.
511 int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
513 ClientPtr client = cl->client;
514 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
515 xGLXDestroyContextReq *be_req;
516 GLXContextID gcId = req->context;
517 __GLXcontext *glxc;
518 int from_screen = 0;
519 int to_screen = 0;
520 int s;
522 glxc = (__GLXcontext *) LookupIDByType(gcId, __glXContextRes);
523 if (glxc) {
525 ** Just free the resource; don't actually destroy the context,
526 ** because it might be in use. The
527 ** destroy method will be called by the resource destruction routine
528 ** if necessary.
530 FreeResourceByType(gcId, __glXContextRes, FALSE);
532 from_screen = to_screen = glxc->pScreen->myNum;
534 } else {
535 client->errorValue = gcId;
536 return __glXBadContext;
539 #ifdef PANORAMIX
540 if (!noPanoramiXExtension) {
541 from_screen = 0;
542 to_screen = screenInfo.numScreens - 1;
544 #endif
547 * send DestroyContext request to all back-end servers
549 for (s=from_screen; s<=to_screen; s++) {
550 DMXScreenInfo *dmxScreen = &dmxScreens[s];
551 Display *dpy = GetBackEndDisplay(cl,s);
553 LockDisplay(dpy);
554 GetReq(GLXDestroyContext,be_req);
555 be_req->reqType = dmxScreen->glxMajorOpcode;
556 be_req->glxCode = X_GLXDestroyContext;
557 be_req->context = glxc->real_ids[s-from_screen];
558 UnlockDisplay(dpy);
559 SyncHandle();
562 return Success;
565 /*****************************************************************************/
568 ** For each client, the server keeps a table of all the contexts that are
569 ** current for that client (each thread of a client may have its own current
570 ** context). These routines add, change, and lookup contexts in the table.
574 ** Add a current context, and return the tag that will be used to refer to it.
576 static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw)
578 int i;
579 int num = cl->numCurrentContexts;
580 __GLXcontext **table = cl->currentContexts;
582 if (!glxc) return -1;
585 ** Try to find an empty slot and use it.
587 for (i=0; i < num; i++) {
588 if (!table[i]) {
589 table[i] = glxc;
590 return i+1;
594 ** Didn't find a free slot, so we'll have to grow the table.
596 if (!num) {
597 table = (__GLXcontext **) __glXMalloc(sizeof(__GLXcontext *));
598 cl->currentDrawables = (DrawablePtr *) __glXMalloc(sizeof(DrawablePtr));
599 cl->be_currentCTag = (GLXContextTag *) __glXMalloc(screenInfo.numScreens *sizeof(GLXContextTag));
600 } else {
601 table = (__GLXcontext **) __glXRealloc(table,
602 (num+1)*sizeof(__GLXcontext *));
603 cl->currentDrawables = (DrawablePtr *) __glXRealloc(
604 cl->currentDrawables ,
605 (num+1)*sizeof(DrawablePtr));
606 cl->be_currentCTag = (GLXContextTag *) __glXRealloc(cl->be_currentCTag,
607 (num+1)*screenInfo.numScreens*sizeof(GLXContextTag));
609 table[num] = glxc;
610 cl->currentDrawables[num] = pDraw;
611 cl->currentContexts = table;
612 cl->numCurrentContexts++;
614 memset(cl->be_currentCTag + num*screenInfo.numScreens, 0,
615 screenInfo.numScreens * sizeof(GLXContextTag));
617 return num+1;
621 ** Given a tag, change the current context for the corresponding entry.
623 static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
624 GLXContextTag tag)
626 __GLXcontext **table = cl->currentContexts;
627 table[tag-1] = glxc;
631 ** Given a tag, and back-end screen number, retrives the current back-end
632 ** tag.
634 int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s)
636 if (tag >0) {
637 return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] );
639 else {
640 return( 0 );
645 ** Given a tag, and back-end screen number, sets the current back-end
646 ** tag.
648 static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag)
650 if (tag >0) {
651 cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag;
656 ** For this implementation we have chosen to simply use the index of the
657 ** context's entry in the table as the context tag. A tag must be greater
658 ** than 0.
660 __GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
662 int num = cl->numCurrentContexts;
664 if (tag < 1 || tag > num) {
665 return 0;
666 } else {
667 return cl->currentContexts[tag-1];
671 DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag)
673 int num = cl->numCurrentContexts;
675 if (tag < 1 || tag > num) {
676 return 0;
677 } else {
678 return cl->currentDrawables[tag-1];
682 /*****************************************************************************/
684 static void StopUsingContext(__GLXcontext *glxc)
686 if (glxc) {
687 if (glxc == __glXLastContext) {
688 /* Tell server GL library */
689 __glXLastContext = 0;
691 glxc->isCurrent = GL_FALSE;
692 if (!glxc->idExists) {
693 __glXFreeContext(glxc);
698 static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
700 glxc->isCurrent = GL_TRUE;
703 /*****************************************************************************/
705 ** Make an OpenGL context and drawable current.
707 static int MakeCurrent(__GLXclientState *cl,
708 GLXDrawable drawable,
709 GLXDrawable readdrawable,
710 GLXContextID context,
711 GLXContextTag oldContextTag)
713 ClientPtr client = cl->client;
714 DrawablePtr pDraw = NULL;
715 DrawablePtr pReadDraw = NULL;
716 xGLXMakeCurrentReadSGIReply new_reply;
717 xGLXMakeCurrentReq *be_req;
718 xGLXMakeCurrentReply be_reply;
719 xGLXMakeContextCurrentReq *be_new_req;
720 xGLXMakeContextCurrentReply be_new_reply;
721 GLXDrawable drawId = drawable;
722 GLXDrawable readId = readdrawable;
723 GLXContextID contextId = context;
724 __GLXpixmap *pGlxPixmap = 0;
725 __GLXpixmap *pReadGlxPixmap = 0;
726 __GLXcontext *glxc, *prevglxc;
727 GLXContextTag tag = oldContextTag;
728 WindowPtr pWin = NULL;
729 WindowPtr pReadWin = NULL;
730 __glXWindow *pGlxWindow = NULL;
731 __glXWindow *pGlxReadWindow = NULL;
732 __glXPbuffer *pGlxPbuffer = NULL;
733 __glXPbuffer *pGlxReadPbuffer = NULL;
734 #ifdef PANORAMIX
735 PanoramiXRes *pXinDraw = NULL;
736 PanoramiXRes *pXinReadDraw = NULL;
737 #endif
738 int from_screen = 0;
739 int to_screen = 0;
740 int s, rc;
743 ** If one is None and the other isn't, it's a bad match.
745 if ((drawId == None && contextId != None) ||
746 (drawId != None && contextId == None)) {
747 return BadMatch;
751 ** Lookup old context. If we have one, it must be in a usable state.
753 if (tag != 0) {
754 prevglxc = __glXLookupContextByTag(cl, tag);
755 if (!prevglxc) {
757 ** Tag for previous context is invalid.
759 return __glXBadContextTag;
761 } else {
762 prevglxc = 0;
766 ** Lookup new context. It must not be current for someone else.
768 if (contextId != None) {
769 glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes);
770 if (!glxc) {
771 client->errorValue = contextId;
772 return __glXBadContext;
774 if ((glxc != prevglxc) && glxc->isCurrent) {
775 /* Context is current to somebody else */
776 return BadAccess;
778 } else {
779 /* Switching to no context. Ignore new drawable. */
780 glxc = 0;
783 if (drawId != None) {
784 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
785 if (rc == Success) {
786 if (pDraw->type == DRAWABLE_WINDOW) {
788 ** Drawable is an X Window.
790 VisualID vid;
791 pWin = (WindowPtr)pDraw;
792 vid = wVisual(pWin);
794 new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
795 new_reply.writeType = GLX_WINDOW_TYPE;
798 ** Check if window and context are similar.
800 if ((vid != glxc->pVisual->vid) ||
801 (pWin->drawable.pScreen != glxc->pScreen)) {
802 client->errorValue = drawId;
803 return BadMatch;
806 from_screen = to_screen = pWin->drawable.pScreen->myNum;
808 } else {
810 ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
811 ** is, but it must first be created with glxCreateGLXPixmap).
813 client->errorValue = drawId;
814 return __glXBadDrawable;
818 if (!pDraw) {
819 pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
820 __glXPixmapRes);
821 if (pGlxPixmap) {
823 ** Check if pixmap and context are similar.
825 if (pGlxPixmap->pScreen != glxc->pScreen ||
826 pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
827 client->errorValue = drawId;
828 return BadMatch;
830 pDraw = pGlxPixmap->pDraw;
832 new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
833 pGlxPixmap->pGlxVisual->vid);
835 new_reply.writeType = GLX_PIXMAP_TYPE;
837 from_screen = to_screen = pGlxPixmap->pScreen->myNum;
842 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
843 pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
844 if (pGlxWindow) {
846 ** Drawable is a GLXWindow.
848 ** Check if GLX window and context are similar.
850 if (pGlxWindow->pScreen != glxc->pScreen ||
851 pGlxWindow->pGlxFBConfig != glxc->pFBConfig) {
852 client->errorValue = drawId;
853 return BadMatch;
856 pDraw = pGlxWindow->pDraw;
857 new_reply.writeVid = pGlxWindow->pGlxFBConfig->id;
858 new_reply.writeType = GLX_GLXWINDOW_TYPE;
863 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
864 pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
865 if (pGlxPbuffer) {
866 if (pGlxPbuffer->pScreen != glxc->pScreen ||
867 pGlxPbuffer->pFBConfig != glxc->pFBConfig) {
868 client->errorValue = drawId;
869 return BadMatch;
872 pDraw = (DrawablePtr)pGlxPbuffer;
873 new_reply.writeVid = pGlxPbuffer->pFBConfig->id;
874 new_reply.writeType = GLX_PBUFFER_TYPE;
878 if (!pDraw) {
880 ** Drawable is not a Window , GLXWindow or a GLXPixmap.
882 client->errorValue = drawId;
883 return __glXBadDrawable;
886 } else {
887 pDraw = 0;
890 if (readId != None && readId != drawId ) {
891 rc = dixLookupDrawable(&pReadDraw, readId, client, 0,DixUnknownAccess);
892 if (rc == Success) {
893 if (pReadDraw->type == DRAWABLE_WINDOW) {
895 ** Drawable is an X Window.
897 VisualID vid;
898 pReadWin = (WindowPtr)pDraw;
899 vid = wVisual(pReadWin);
901 new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
902 new_reply.readType = GLX_WINDOW_TYPE;
905 ** Check if window and context are similar.
907 if ((vid != glxc->pVisual->vid) ||
908 (pReadWin->drawable.pScreen != glxc->pScreen)) {
909 client->errorValue = readId;
910 return BadMatch;
913 } else {
916 ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
917 ** is, but it must first be created with glxCreateGLXPixmap).
919 client->errorValue = readId;
920 return __glXBadDrawable;
924 if (!pReadDraw) {
925 pReadGlxPixmap = (__GLXpixmap *) LookupIDByType(readId,
926 __glXPixmapRes);
927 if (pReadGlxPixmap) {
929 ** Check if pixmap and context are similar.
931 if (pReadGlxPixmap->pScreen != glxc->pScreen ||
932 pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
933 client->errorValue = readId;
934 return BadMatch;
936 pReadDraw = pReadGlxPixmap->pDraw;
938 new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
939 pReadGlxPixmap->pGlxVisual->vid );
940 new_reply.readType = GLX_PIXMAP_TYPE;
945 if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
946 pGlxReadWindow = (__glXWindow *)
947 LookupIDByType(readId, __glXWindowRes);
948 if (pGlxReadWindow) {
950 ** Drawable is a GLXWindow.
952 ** Check if GLX window and context are similar.
954 if (pGlxReadWindow->pScreen != glxc->pScreen ||
955 pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) {
956 client->errorValue = readId;
957 return BadMatch;
960 pReadDraw = pGlxReadWindow->pDraw;
961 new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id;
962 new_reply.readType = GLX_GLXWINDOW_TYPE;
966 if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
967 pGlxReadPbuffer = (__glXPbuffer *)LookupIDByType(readId, __glXPbufferRes);
968 if (pGlxReadPbuffer) {
969 if (pGlxReadPbuffer->pScreen != glxc->pScreen ||
970 pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) {
971 client->errorValue = drawId;
972 return BadMatch;
975 pReadDraw = (DrawablePtr)pGlxReadPbuffer;
976 new_reply.readVid = pGlxReadPbuffer->pFBConfig->id;
977 new_reply.readType = GLX_PBUFFER_TYPE;
981 if (!pReadDraw) {
983 ** Drawable is neither a Window nor a GLXPixmap.
985 client->errorValue = readId;
986 return __glXBadDrawable;
989 } else {
990 pReadDraw = pDraw;
991 pReadGlxPixmap = pGlxPixmap;
992 pReadWin = pWin;
993 new_reply.readVid = new_reply.writeVid;
994 new_reply.readType = new_reply.writeType;
997 if (prevglxc) {
999 if (prevglxc->pGlxPixmap) {
1001 ** The previous drawable was a glx pixmap, release it.
1003 prevglxc->pGlxPixmap->refcnt--;
1004 __glXFreeGLXPixmap( prevglxc->pGlxPixmap );
1005 prevglxc->pGlxPixmap = 0;
1008 if (prevglxc->pGlxReadPixmap &&
1009 prevglxc->pGlxReadPixmap != prevglxc->pGlxPixmap ) {
1011 ** The previous drawable was a glx pixmap, release it.
1013 prevglxc->pGlxReadPixmap->refcnt--;
1014 __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap );
1015 prevglxc->pGlxReadPixmap = 0;
1018 if (prevglxc->pGlxWindow) {
1020 ** The previous drawable was a glx window, release it.
1022 prevglxc->pGlxWindow->refcnt--;
1023 __glXFreeGLXWindow( prevglxc->pGlxWindow );
1024 prevglxc->pGlxWindow = 0;
1027 if (prevglxc->pGlxReadWindow &&
1028 prevglxc->pGlxReadWindow != prevglxc->pGlxWindow) {
1030 ** The previous drawable was a glx window, release it.
1032 prevglxc->pGlxReadWindow->refcnt--;
1033 __glXFreeGLXWindow( prevglxc->pGlxReadWindow );
1034 prevglxc->pGlxReadWindow = 0;
1037 if (prevglxc->pGlxPbuffer) {
1039 ** The previous drawable was a glx Pbuffer, release it.
1041 prevglxc->pGlxPbuffer->refcnt--;
1042 __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer );
1043 prevglxc->pGlxPbuffer = 0;
1046 if (prevglxc->pGlxReadPbuffer &&
1047 prevglxc->pGlxReadPbuffer != prevglxc->pGlxPbuffer ) {
1049 ** The previous drawable was a glx Pbuffer, release it.
1051 prevglxc->pGlxReadPbuffer->refcnt--;
1052 __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer );
1053 prevglxc->pGlxReadPbuffer = 0;
1056 ChangeCurrentContext(cl, glxc, tag);
1057 ChangeCurrentContext(cl, glxc, tag);
1058 StopUsingContext(prevglxc);
1059 } else {
1060 tag = AddCurrentContext(cl, glxc, pDraw);
1062 if (glxc) {
1064 glxc->pGlxPixmap = pGlxPixmap;
1065 glxc->pGlxReadPixmap = pReadGlxPixmap;
1066 glxc->pGlxWindow = pGlxWindow;
1067 glxc->pGlxReadWindow = pGlxReadWindow;
1068 glxc->pGlxPbuffer = pGlxPbuffer;
1069 glxc->pGlxReadPbuffer = pGlxReadPbuffer;
1071 if (pGlxPixmap) {
1072 pGlxPixmap->refcnt++;
1075 if (pReadGlxPixmap && pReadGlxPixmap != pGlxPixmap) {
1076 pReadGlxPixmap->refcnt++;
1079 if (pGlxWindow) {
1080 pGlxWindow->refcnt++;
1083 if (pGlxReadWindow && pGlxReadWindow != pGlxWindow) {
1084 pGlxReadWindow->refcnt++;
1087 if (pGlxPbuffer) {
1088 pGlxPbuffer->refcnt++;
1091 if (pGlxReadPbuffer && pGlxReadPbuffer != pGlxPbuffer) {
1092 pGlxReadPbuffer->refcnt++;
1095 StartUsingContext(cl, glxc);
1096 new_reply.contextTag = tag;
1097 } else {
1098 new_reply.contextTag = 0;
1100 new_reply.length = 0;
1101 new_reply.type = X_Reply;
1102 new_reply.sequenceNumber = client->sequence;
1104 #ifdef PANORAMIX
1105 if (!noPanoramiXExtension) {
1106 from_screen = 0;
1107 to_screen = screenInfo.numScreens - 1;
1109 if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
1110 pXinDraw = (PanoramiXRes *)
1111 SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
1114 if (pReadDraw && pReadDraw != pDraw &&
1115 new_reply.readType != GLX_PBUFFER_TYPE) {
1116 pXinReadDraw = (PanoramiXRes *)
1117 SecurityLookupIDByClass(client, pReadDraw->id, XRC_DRAWABLE, DixReadAccess);
1119 else {
1120 pXinReadDraw = pXinDraw;
1123 #endif
1126 /* send the MakeCurrent request to all required
1127 * back-end servers.
1129 for (s = from_screen; s<=to_screen; s++) {
1130 DMXScreenInfo *dmxScreen = &dmxScreens[s];
1131 Display *dpy = GetBackEndDisplay(cl,s);
1132 unsigned int be_draw = None;
1133 unsigned int be_read_draw = None;
1135 if (pGlxPixmap) {
1136 be_draw = pGlxPixmap->be_xids[s];
1138 else if (pGlxPbuffer) {
1139 be_draw = pGlxPbuffer->be_xids[s];
1141 #ifdef PANORAMIX
1142 else if (pXinDraw) {
1143 dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
1145 #endif
1146 else if (pGlxWindow) {
1147 pWin = (WindowPtr)pGlxWindow->pDraw;
1150 if (pWin && be_draw == None) {
1151 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
1152 if (!be_draw) {
1153 /* it might be that the window did not created yet on the */
1154 /* back-end server (lazy window creation option), force */
1155 /* creation of the window */
1156 dmxCreateAndRealizeWindow( pWin, TRUE );
1157 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
1162 * Before sending the MakeCurrent request - sync the
1163 * X11 connection to the back-end servers to make sure
1164 * that drawable is already created
1166 dmxSync( dmxScreen, 1 );
1168 if (drawId == readId) {
1169 LockDisplay(dpy);
1170 GetReq(GLXMakeCurrent, be_req);
1171 be_req->reqType = dmxScreen->glxMajorOpcode;
1172 be_req->glxCode = X_GLXMakeCurrent;
1173 be_req->drawable = be_draw;
1174 be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1175 be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1176 if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
1178 /* The make current failed */
1179 UnlockDisplay(dpy);
1180 SyncHandle();
1181 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1184 UnlockDisplay(dpy);
1185 SyncHandle();
1187 SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag );
1189 else {
1191 if (pReadGlxPixmap) {
1192 be_read_draw = pReadGlxPixmap->be_xids[s];
1194 else if (pGlxReadPbuffer) {
1195 be_read_draw = pGlxReadPbuffer->be_xids[s];
1197 #ifdef PANORAMIX
1198 else if (pXinReadDraw) {
1199 dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client,
1200 DixReadAccess);
1202 #endif
1203 else if (pGlxReadWindow) {
1204 pReadWin = (WindowPtr)pGlxReadWindow->pDraw;
1207 if (pReadWin && be_read_draw == None) {
1208 be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
1209 if (!be_read_draw) {
1210 /* it might be that the window did not created yet on the */
1211 /* back-end server (lazy window creation option), force */
1212 /* creation of the window */
1213 dmxCreateAndRealizeWindow( pReadWin, TRUE );
1214 be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
1215 dmxSync( dmxScreen, 1 );
1219 if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1220 LockDisplay(dpy);
1221 GetReq(GLXMakeContextCurrent, be_new_req);
1222 be_new_req->reqType = dmxScreen->glxMajorOpcode;
1223 be_new_req->glxCode = X_GLXMakeContextCurrent;
1224 be_new_req->drawable = be_draw;
1225 be_new_req->readdrawable = be_read_draw;
1226 be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1227 be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1228 if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
1230 /* The make current failed */
1231 UnlockDisplay(dpy);
1232 SyncHandle();
1233 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1236 UnlockDisplay(dpy);
1237 SyncHandle();
1239 SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag );
1241 else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) {
1242 xGLXMakeCurrentReadSGIReq *ext_req;
1243 xGLXVendorPrivateWithReplyReq *vpreq;
1244 xGLXMakeCurrentReadSGIReply ext_reply;
1246 LockDisplay(dpy);
1247 GetReqExtra(GLXVendorPrivateWithReply,
1248 sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq,
1249 vpreq);
1250 ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq;
1251 ext_req->reqType = dmxScreen->glxMajorOpcode;
1252 ext_req->glxCode = X_GLXVendorPrivateWithReply;
1253 ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
1254 ext_req->drawable = be_draw;
1255 ext_req->readable = be_read_draw;
1256 ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
1257 ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
1258 if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
1260 /* The make current failed */
1261 UnlockDisplay(dpy);
1262 SyncHandle();
1263 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
1266 UnlockDisplay(dpy);
1267 SyncHandle();
1269 SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag );
1272 else {
1273 return BadMatch;
1277 XFlush( dpy );
1280 if (client->swapped) {
1281 __glXSwapMakeCurrentReply(client, &new_reply);
1282 } else {
1283 WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply);
1286 return Success;
1289 int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
1291 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
1293 return( MakeCurrent(cl, req->drawable, req->drawable,
1294 req->context, req->oldContextTag ) );
1297 int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
1299 xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
1301 return( MakeCurrent(cl, req->drawable, req->readdrawable,
1302 req->context, req->oldContextTag ) );
1305 int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
1307 xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
1309 return( MakeCurrent(cl, req->drawable, req->readable,
1310 req->context, req->oldContextTag ) );
1313 int __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
1315 ClientPtr client = cl->client;
1316 xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
1317 xGLXIsDirectReply reply;
1318 __GLXcontext *glxc;
1321 ** Find the GL context.
1323 glxc = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
1324 if (!glxc) {
1325 client->errorValue = req->context;
1326 return __glXBadContext;
1329 reply.isDirect = 0;
1330 reply.length = 0;
1331 reply.type = X_Reply;
1332 reply.sequenceNumber = client->sequence;
1334 if (client->swapped) {
1335 __glXSwapIsDirectReply(client, &reply);
1336 } else {
1337 WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
1340 return Success;
1343 int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
1345 ClientPtr client = cl->client;
1346 /* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
1347 xGLXQueryVersionReply reply;
1350 ** Server should take into consideration the version numbers sent by the
1351 ** client if it wants to work with older clients; however, in this
1352 ** implementation the server just returns its version number.
1354 reply.majorVersion = __glXVersionMajor;
1355 reply.minorVersion = __glXVersionMinor;
1356 reply.length = 0;
1357 reply.type = X_Reply;
1358 reply.sequenceNumber = client->sequence;
1360 if (client->swapped) {
1361 __glXSwapQueryVersionReply(client, &reply);
1362 } else {
1363 WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
1365 return Success;
1368 int __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
1370 xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
1371 xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc;
1372 int from_screen = 0;
1373 int to_screen = 0;
1374 int s;
1375 __GLXcontext *glxc = NULL;
1377 if (req->contextTag != 0) {
1378 glxc = __glXLookupContextByTag(cl, req->contextTag);
1379 if (glxc) {
1380 from_screen = to_screen = glxc->pScreen->myNum;
1384 #ifdef PANORAMIX
1385 if (!noPanoramiXExtension) {
1386 from_screen = 0;
1387 to_screen = screenInfo.numScreens - 1;
1389 #endif
1391 for (s=from_screen; s<=to_screen; s++) {
1392 DMXScreenInfo *dmxScreen = &dmxScreens[s];
1393 Display *dpy = GetBackEndDisplay(cl,s);
1395 LockDisplay(dpy);
1396 GetReq(GLXWaitGL,be_req);
1397 be_req->reqType = dmxScreen->glxMajorOpcode;
1398 be_req->glxCode = X_GLXWaitGL;
1399 be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1400 UnlockDisplay(dpy);
1401 SyncHandle();
1403 XSync(dpy, False);
1406 return Success;
1409 int __glXWaitX(__GLXclientState *cl, GLbyte *pc)
1411 xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
1412 xGLXWaitXReq *be_req;
1413 int from_screen = 0;
1414 int to_screen = 0;
1415 int s;
1416 __GLXcontext *glxc = NULL;
1418 if (req->contextTag != 0) {
1419 glxc = __glXLookupContextByTag(cl, req->contextTag);
1420 if (glxc) {
1421 from_screen = to_screen = glxc->pScreen->myNum;
1425 #ifdef PANORAMIX
1426 if (!noPanoramiXExtension) {
1427 from_screen = 0;
1428 to_screen = screenInfo.numScreens - 1;
1430 #endif
1432 for (s=from_screen; s<=to_screen; s++) {
1433 DMXScreenInfo *dmxScreen = &dmxScreens[s];
1434 Display *dpy = GetBackEndDisplay(cl,s);
1436 dmxSync( dmxScreen, 1 );
1438 LockDisplay(dpy);
1439 GetReq(GLXWaitX,be_req);
1440 be_req->reqType = dmxScreen->glxMajorOpcode;
1441 be_req->glxCode = X_GLXWaitX;
1442 be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1443 UnlockDisplay(dpy);
1444 SyncHandle();
1446 XFlush( dpy );
1449 return Success;
1452 int __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
1454 ClientPtr client = cl->client;
1455 xGLXCopyContextReq *be_req;
1456 xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
1457 GLXContextID source = req->source;
1458 GLXContextID dest = req->dest;
1459 GLXContextTag tag = req->contextTag;
1460 unsigned long mask = req->mask;
1461 __GLXcontext *src, *dst;
1462 int s;
1463 int from_screen = 0;
1464 int to_screen = 0;
1467 ** Check that each context exists.
1469 src = (__GLXcontext *) LookupIDByType(source, __glXContextRes);
1470 if (!src) {
1471 client->errorValue = source;
1472 return __glXBadContext;
1474 dst = (__GLXcontext *) LookupIDByType(dest, __glXContextRes);
1475 if (!dst) {
1476 client->errorValue = dest;
1477 return __glXBadContext;
1481 ** They must be in the same address space, and same screen.
1483 if (src->pGlxScreen != dst->pGlxScreen) {
1484 client->errorValue = source;
1485 return BadMatch;
1489 ** The destination context must not be current for any client.
1491 if (dst->isCurrent) {
1492 client->errorValue = dest;
1493 return BadAccess;
1496 if (tag) {
1497 __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
1499 if (!tagcx) {
1500 return __glXBadContextTag;
1502 if (tagcx != src) {
1504 ** This would be caused by a faulty implementation of the client
1505 ** library.
1507 return BadMatch;
1511 from_screen = to_screen = src->pScreen->myNum;
1513 #ifdef PANORAMIX
1514 if (!noPanoramiXExtension) {
1515 from_screen = 0;
1516 to_screen = screenInfo.numScreens - 1;
1518 #endif
1520 for (s=from_screen; s<=to_screen; s++) {
1521 DMXScreenInfo *dmxScreen = &dmxScreens[s];
1522 Display *dpy = GetBackEndDisplay(cl,s);
1524 LockDisplay(dpy);
1525 GetReq(GLXCopyContext,be_req);
1526 be_req->reqType = dmxScreen->glxMajorOpcode;
1527 be_req->glxCode = X_GLXCopyContext;
1528 be_req->source = (unsigned int)src->real_ids[s-from_screen];
1529 be_req->dest = (unsigned int)dst->real_ids[s-from_screen];
1530 be_req->mask = mask;
1531 be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
1532 UnlockDisplay(dpy);
1533 SyncHandle();
1536 return Success;
1539 int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
1541 ClientPtr client = cl->client;
1542 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
1543 xGLXGetVisualConfigsReply reply;
1544 __GLXscreenInfo *pGlxScreen;
1545 __GLXvisualConfig *pGlxVisual;
1546 CARD32 buf[__GLX_TOTAL_CONFIG];
1547 unsigned int screen;
1548 int i, p;
1550 screen = req->screen;
1551 if (screen > screenInfo.numScreens) {
1552 /* The client library must send a valid screen number. */
1553 client->errorValue = screen;
1554 return BadValue;
1556 pGlxScreen = &__glXActiveScreens[screen];
1558 reply.numVisuals = pGlxScreen->numGLXVisuals;
1559 reply.numProps = __GLX_TOTAL_CONFIG;
1560 reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
1561 __GLX_TOTAL_CONFIG) >> 2;
1562 reply.type = X_Reply;
1563 reply.sequenceNumber = client->sequence;
1565 WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
1567 for (i=0; i < pGlxScreen->numVisuals; i++) {
1568 pGlxVisual = &pGlxScreen->pGlxVisual[i];
1569 if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
1570 /* not a usable visual */
1571 continue;
1573 p = 0;
1574 buf[p++] = pGlxVisual->vid;
1575 buf[p++] = pGlxVisual->class;
1576 buf[p++] = pGlxVisual->rgba;
1578 buf[p++] = pGlxVisual->redSize;
1579 buf[p++] = pGlxVisual->greenSize;
1580 buf[p++] = pGlxVisual->blueSize;
1581 buf[p++] = pGlxVisual->alphaSize;
1582 buf[p++] = pGlxVisual->accumRedSize;
1583 buf[p++] = pGlxVisual->accumGreenSize;
1584 buf[p++] = pGlxVisual->accumBlueSize;
1585 buf[p++] = pGlxVisual->accumAlphaSize;
1587 buf[p++] = pGlxVisual->doubleBuffer;
1588 buf[p++] = pGlxVisual->stereo;
1590 buf[p++] = pGlxVisual->bufferSize;
1591 buf[p++] = pGlxVisual->depthSize;
1592 buf[p++] = pGlxVisual->stencilSize;
1593 buf[p++] = pGlxVisual->auxBuffers;
1594 buf[p++] = pGlxVisual->level;
1596 ** Add token/value pairs for extensions.
1598 buf[p++] = GLX_VISUAL_CAVEAT_EXT;
1599 buf[p++] = pGlxVisual->visualRating;
1600 buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
1601 buf[p++] = pGlxVisual->transparentPixel;
1602 buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
1603 buf[p++] = pGlxVisual->transparentRed;
1604 buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
1605 buf[p++] = pGlxVisual->transparentGreen;
1606 buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
1607 buf[p++] = pGlxVisual->transparentBlue;
1608 buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
1609 buf[p++] = pGlxVisual->transparentAlpha;
1610 buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
1611 buf[p++] = pGlxVisual->transparentIndex;
1612 buf[p++] = GLX_SAMPLES_SGIS;
1613 buf[p++] = pGlxVisual->multiSampleSize;
1614 buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
1615 buf[p++] = pGlxVisual->nMultiSampleBuffers;
1616 buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
1617 buf[p++] = pGlxVisual->visualSelectGroup;
1619 WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
1620 (char *)buf);
1622 return Success;
1626 ** Create a GLX Pixmap from an X Pixmap.
1628 static int CreateGLXPixmap(__GLXclientState *cl,
1629 VisualID visual, GLXFBConfigID fbconfigId,
1630 int screenNum, XID pixmapId, XID glxpixmapId )
1632 ClientPtr client = cl->client;
1633 xGLXCreateGLXPixmapReq *be_req;
1634 xGLXCreatePixmapReq *be_new_req;
1635 DrawablePtr pDraw;
1636 ScreenPtr pScreen;
1637 VisualPtr pVisual;
1638 __GLXpixmap *pGlxPixmap;
1639 __GLXscreenInfo *pGlxScreen;
1640 __GLXvisualConfig *pGlxVisual;
1641 __GLXFBConfig *pFBConfig;
1642 int i, s, rc;
1643 int from_screen, to_screen;
1644 #ifdef PANORAMIX
1645 PanoramiXRes *pXinDraw = NULL;
1646 #endif
1648 rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP,
1649 DixUnknownAccess);
1650 if (rc != Success)
1651 return rc;
1654 ** Check if screen of visual matches screen of pixmap.
1656 pScreen = pDraw->pScreen;
1657 if (screenNum != pScreen->myNum) {
1658 return BadMatch;
1661 if (fbconfigId == NULL && visual == NULL) {
1662 return BadValue;
1665 if (fbconfigId != None) {
1666 pFBConfig = glxLookupFBConfig( fbconfigId );
1667 if (!pFBConfig) {
1668 client->errorValue = fbconfigId;
1669 return BadValue;
1671 visual = pFBConfig->associatedVisualId;
1673 else {
1674 pFBConfig = NULL;
1677 if (visual != None) {
1679 ** Find the VisualRec for this visual.
1681 pVisual = pScreen->visuals;
1682 for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
1683 if (pVisual->vid == visual) {
1684 break;
1687 if (i == pScreen->numVisuals) {
1688 client->errorValue = visual;
1689 return BadValue;
1692 ** Check if depth of visual matches depth of pixmap.
1694 if (pVisual->nplanes != pDraw->depth) {
1695 client->errorValue = visual;
1696 return BadMatch;
1700 ** Get configuration of the visual.
1702 pGlxScreen = &__glXActiveScreens[screenNum];
1703 pGlxVisual = pGlxScreen->pGlxVisual;
1704 for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
1705 if (pGlxVisual->vid == visual) {
1706 break;
1709 if (i == pGlxScreen->numVisuals) {
1711 ** Visual not support on this screen by this OpenGL implementation.
1713 client->errorValue = visual;
1714 return BadValue;
1718 /* find the FBConfig for that visual (if any) */
1719 if ( pFBConfig == NULL ) {
1720 pFBConfig = glxLookupFBConfigByVID( visual );
1722 if ( pFBConfig == NULL ) {
1724 * visual does not have an FBConfig ???
1725 client->errorValue = visual;
1726 return BadValue;
1731 else {
1732 pVisual = NULL;
1733 pGlxVisual = NULL;
1736 pGlxPixmap = (__GLXpixmap *) __glXMalloc(sizeof(__GLXpixmap));
1737 if (!pGlxPixmap) {
1738 return BadAlloc;
1740 pGlxPixmap->be_xids = (XID *) __glXMalloc(sizeof(XID) * screenInfo.numScreens);
1741 if (!pGlxPixmap->be_xids) {
1742 __glXFree( pGlxPixmap );
1743 return BadAlloc;
1746 pGlxPixmap->pDraw = pDraw;
1747 pGlxPixmap->pGlxScreen = pGlxScreen;
1748 pGlxPixmap->pGlxVisual = pGlxVisual;
1749 pGlxPixmap->pFBConfig = pFBConfig;
1750 pGlxPixmap->pScreen = pScreen;
1751 pGlxPixmap->idExists = True;
1752 pGlxPixmap->refcnt = 0;
1755 ** Bump the ref count on the X pixmap so it won't disappear.
1757 ((PixmapPtr) pDraw)->refcnt++;
1760 * send the request to the back-end server(s)
1762 from_screen = to_screen = screenNum;
1763 #ifdef PANORAMIX
1764 if (!noPanoramiXExtension) {
1765 from_screen = 0;
1766 to_screen = screenInfo.numScreens - 1;
1768 pXinDraw = (PanoramiXRes *)
1769 SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
1771 #endif
1773 for (s=from_screen; s<=to_screen; s++) {
1775 DMXScreenInfo *dmxScreen = &dmxScreens[s];
1776 Display *dpy = GetBackEndDisplay(cl,s);
1777 Pixmap be_pixmap;
1778 DrawablePtr pRealDraw = pDraw;
1780 #ifdef PANORAMIX
1781 if (pXinDraw) {
1782 dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0,
1783 DixUnknownAccess);
1785 #endif
1787 be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap;
1789 /* make sure pixmap already created on back-end */
1790 dmxSync( dmxScreen, 1 );
1792 if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1793 __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
1795 LockDisplay(dpy);
1796 pGlxPixmap->be_xids[s] = XAllocID(dpy);
1797 GetReq(GLXCreatePixmap,be_new_req);
1798 be_new_req->reqType = dmxScreen->glxMajorOpcode;
1799 be_new_req->glxCode = X_GLXCreatePixmap;
1800 be_new_req->screen = DefaultScreen(dpy);
1801 be_new_req->fbconfig = be_FBConfig->id;
1802 be_new_req->pixmap = (unsigned int)be_pixmap;
1803 be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1804 be_new_req->numAttribs = 0;
1805 UnlockDisplay(dpy);
1806 SyncHandle();
1808 else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
1809 __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
1810 xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req;
1811 xGLXVendorPrivateReq *vpreq;
1813 LockDisplay(dpy);
1814 pGlxPixmap->be_xids[s] = XAllocID(dpy);
1815 GetReqExtra(GLXVendorPrivate,
1816 sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,
1817 vpreq);
1818 ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
1819 ext_req->reqType = dmxScreen->glxMajorOpcode;
1820 ext_req->glxCode = X_GLXVendorPrivate;
1821 ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
1822 ext_req->screen = DefaultScreen(dpy);
1823 ext_req->fbconfig = be_FBConfig->id;
1824 ext_req->pixmap = (unsigned int)be_pixmap;
1825 ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1826 UnlockDisplay(dpy);
1827 SyncHandle();
1829 else if (pGlxVisual) {
1830 LockDisplay(dpy);
1831 pGlxPixmap->be_xids[s] = XAllocID(dpy);
1832 GetReq(GLXCreateGLXPixmap,be_req);
1833 be_req->reqType = dmxScreen->glxMajorOpcode;
1834 be_req->glxCode = X_GLXCreateGLXPixmap;
1835 be_req->screen = DefaultScreen(dpy);
1836 be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList(
1837 pGlxVisual,
1838 dmxScreen->glxVisuals,
1839 dmxScreen->numGlxVisuals );
1840 be_req->pixmap = (unsigned int)be_pixmap;
1841 be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1842 UnlockDisplay(dpy);
1843 SyncHandle();
1845 else {
1846 client->errorValue = ( visual ? visual : fbconfigId );
1847 __glXFree( pGlxPixmap );
1848 return BadValue;
1851 XFlush( dpy );
1854 if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
1855 __glXFree( pGlxPixmap );
1856 return BadAlloc;
1859 return Success;
1862 int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1864 xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
1866 return( CreateGLXPixmap(cl, req->visual, None,
1867 req->screen, req->pixmap, req->glxpixmap) );
1870 int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
1872 xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
1874 return( CreateGLXPixmap(cl, None, req->fbconfig,
1875 req->screen, req->pixmap, req->glxpixmap) );
1878 int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
1880 ClientPtr client = cl->client;
1881 xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
1882 XID glxpixmap = req->glxpixmap;
1883 __GLXpixmap *pGlxPixmap;
1884 int s;
1885 int from_screen, to_screen;
1888 ** Check if it's a valid GLX pixmap.
1890 pGlxPixmap = (__GLXpixmap *)LookupIDByType(glxpixmap, __glXPixmapRes);
1891 if (!pGlxPixmap) {
1892 client->errorValue = glxpixmap;
1893 return __glXBadPixmap;
1895 FreeResource(glxpixmap, FALSE);
1898 * destroy the pixmap on the back-end server(s).
1900 from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum;
1901 #ifdef PANORAMIX
1902 if (!noPanoramiXExtension) {
1903 from_screen = 0;
1904 to_screen = screenInfo.numScreens - 1;
1906 #endif
1908 for (s=from_screen; s<=to_screen; s++) {
1909 DMXScreenInfo *dmxScreen = &dmxScreens[s];
1910 Display *dpy = GetBackEndDisplay(cl,s);
1912 /* make sure pixmap exist in back-end */
1913 dmxSync( dmxScreen, 1 );
1915 LockDisplay(dpy);
1916 GetReq(GLXDestroyGLXPixmap,req);
1917 req->reqType = dmxScreen->glxMajorOpcode;
1918 req->glxCode = X_GLXDestroyGLXPixmap;
1919 req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
1920 UnlockDisplay(dpy);
1921 SyncHandle();
1925 return Success;
1928 /*****************************************************************************/
1931 ** NOTE: There is no portable implementation for swap buffers as of
1932 ** this time that is of value. Consequently, this code must be
1933 ** implemented by somebody other than SGI.
1935 int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag)
1937 ClientPtr client = cl->client;
1938 DrawablePtr pDraw;
1939 xGLXSwapBuffersReq *be_req;
1940 WindowPtr pWin = NULL;
1941 __GLXpixmap *pGlxPixmap = NULL;
1942 __GLXcontext *glxc = NULL;
1943 #ifdef PANORAMIX
1944 PanoramiXRes *pXinDraw = NULL;
1945 #endif
1946 __glXWindow *pGlxWindow = NULL;
1947 int from_screen = 0;
1948 int to_screen = 0;
1949 int s, rc;
1952 ** Check that the GLX drawable is valid.
1954 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
1955 if (rc == Success) {
1956 from_screen = to_screen = pDraw->pScreen->myNum;
1958 if (pDraw->type == DRAWABLE_WINDOW) {
1960 ** Drawable is an X window.
1962 pWin = (WindowPtr)pDraw;
1963 } else {
1965 ** Drawable is an X pixmap, which is not allowed.
1967 client->errorValue = drawId;
1968 return __glXBadDrawable;
1972 if (!pDraw) {
1973 pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
1974 __glXPixmapRes);
1975 if (pGlxPixmap) {
1977 ** Drawable is a GLX pixmap.
1979 pDraw = pGlxPixmap->pDraw;
1980 from_screen = to_screen = pGlxPixmap->pScreen->myNum;
1984 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
1985 pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
1986 if (pGlxWindow) {
1988 ** Drawable is a GLXWindow.
1990 pDraw = pGlxWindow->pDraw;
1991 from_screen = to_screen = pGlxWindow->pScreen->myNum;
1995 if (!pDraw) {
1997 ** Drawable is neither a X window nor a GLX pixmap.
1999 client->errorValue = drawId;
2000 return __glXBadDrawable;
2003 if (tag) {
2004 glxc = __glXLookupContextByTag(cl, tag);
2005 if (!glxc) {
2006 return __glXBadContextTag;
2010 #ifdef PANORAMIX
2011 if (!noPanoramiXExtension) {
2012 from_screen = 0;
2013 to_screen = screenInfo.numScreens - 1;
2014 pXinDraw = (PanoramiXRes *)
2015 SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
2017 #endif
2019 /* If requested, send a glFinish to all back-end servers before swapping. */
2020 if (dmxGLXFinishSwap) {
2021 for (s=from_screen; s<=to_screen; s++) {
2022 Display *dpy = GetBackEndDisplay(cl,s);
2023 DMXScreenInfo *dmxScreen = &dmxScreens[s];
2024 xGLXSingleReq *finishReq;
2025 xGLXSingleReply reply;
2027 #define X_GLXSingle 0 /* needed by GetReq below */
2029 LockDisplay(dpy);
2030 GetReq(GLXSingle,finishReq);
2031 finishReq->reqType = dmxScreen->glxMajorOpcode;
2032 finishReq->glxCode = X_GLsop_Finish;
2033 finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0);
2034 (void) _XReply(dpy, (xReply*) &reply, 0, False);
2035 UnlockDisplay(dpy);
2036 SyncHandle();
2040 /* If requested, send an XSync to all back-end servers before swapping. */
2041 if (dmxGLXSyncSwap) {
2042 for (s=from_screen; s<=to_screen; s++)
2043 XSync(GetBackEndDisplay(cl,s), False);
2047 /* send the SwapBuffers request to all back-end servers */
2049 for (s=from_screen; s<=to_screen; s++) {
2050 DMXScreenInfo *dmxScreen = &dmxScreens[s];
2051 Display *dpy = GetBackEndDisplay(cl,s);
2052 unsigned int be_draw = 0;
2054 if (pGlxPixmap) {
2055 be_draw = (unsigned int)pGlxPixmap->be_xids[s];
2057 #ifdef PANORAMIX
2058 else if (pXinDraw) {
2059 dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
2061 #endif
2062 else if (pGlxWindow) {
2063 pWin = (WindowPtr)pGlxWindow->pDraw;
2066 if (pWin && !be_draw) {
2067 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
2068 if (!be_draw) {
2069 /* it might be that the window did not created yet on the */
2070 /* back-end server (lazy window creation option), force */
2071 /* creation of the window */
2072 dmxCreateAndRealizeWindow( pWin, TRUE );
2073 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
2077 dmxSync( dmxScreen, 1 );
2079 LockDisplay(dpy);
2080 GetReq(GLXSwapBuffers,be_req);
2081 be_req->reqType = dmxScreen->glxMajorOpcode;
2082 be_req->glxCode = X_GLXSwapBuffers;
2083 be_req->drawable = be_draw;
2084 be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 );
2085 UnlockDisplay(dpy);
2086 SyncHandle();
2087 XFlush(dpy);
2090 return Success;
2093 int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
2095 ClientPtr client = cl->client;
2096 DrawablePtr pDraw;
2097 xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
2098 GLXContextTag tag = req->contextTag;
2099 XID drawId = req->drawable;
2100 __GLXpixmap *pGlxPixmap = NULL;
2101 __GLXcontext *glxc = NULL;
2102 __glXWindow *pGlxWindow = NULL;
2103 int rc;
2106 ** Check that the GLX drawable is valid.
2108 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
2109 if (rc == Success) {
2110 if (pDraw->type != DRAWABLE_WINDOW) {
2112 ** Drawable is an X pixmap, which is not allowed.
2114 client->errorValue = drawId;
2115 return __glXBadDrawable;
2119 if (!pDraw) {
2120 pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
2121 __glXPixmapRes);
2122 if (pGlxPixmap) {
2124 ** Drawable is a GLX pixmap.
2126 pDraw = pGlxPixmap->pDraw;
2130 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
2131 pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
2132 if (pGlxWindow) {
2134 ** Drawable is a GLXWindow.
2136 pDraw = pGlxWindow->pDraw;
2140 if (!pDraw) {
2142 ** Drawable is neither a X window nor a GLX pixmap.
2144 client->errorValue = drawId;
2145 return __glXBadDrawable;
2148 if (tag) {
2149 glxc = __glXLookupContextByTag(cl, tag);
2150 if (!glxc) {
2151 return __glXBadContextTag;
2155 if (pDraw &&
2156 pDraw->type == DRAWABLE_WINDOW &&
2157 DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) {
2158 return SGSwapBuffers(cl, drawId, tag, pDraw);
2161 return __glXDoSwapBuffers(cl, drawId, tag);
2165 /************************************************************************/
2168 ** Render and Renderlarge are not in the GLX API. They are used by the GLX
2169 ** client library to send batches of GL rendering commands.
2173 ** Execute all the drawing commands in a request.
2175 int __glXRender(__GLXclientState *cl, GLbyte *pc)
2177 xGLXRenderReq *req;
2178 xGLXRenderReq *be_req;
2179 int size;
2180 __GLXcontext *glxc;
2181 int from_screen = 0;
2182 int to_screen = 0;
2183 int s;
2186 ** NOTE: much of this code also appears in the byteswapping version of this
2187 ** routine, __glXSwapRender(). Any changes made here should also be
2188 ** duplicated there.
2191 req = (xGLXRenderReq *) pc;
2193 glxc = __glXLookupContextByTag(cl, req->contextTag);
2194 if (!glxc) {
2195 return 0;
2197 from_screen = to_screen = glxc->pScreen->myNum;
2199 #ifdef PANORAMIX
2200 if (!noPanoramiXExtension) {
2201 from_screen = 0;
2202 to_screen = screenInfo.numScreens - 1;
2204 #endif
2206 pc += sz_xGLXRenderReq;
2207 size = (req->length << 2) - sz_xGLXRenderReq;
2210 * just forward the request to back-end server(s)
2212 for (s=from_screen; s<=to_screen; s++) {
2213 DMXScreenInfo *dmxScreen = &dmxScreens[s];
2214 Display *dpy = GetBackEndDisplay(cl,s);
2216 LockDisplay(dpy);
2217 GetReq(GLXRender,be_req);
2218 be_req->reqType = dmxScreen->glxMajorOpcode;
2219 be_req->glxCode = X_GLXRender;
2220 be_req->length = req->length;
2221 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
2222 _XSend(dpy, (const char *)pc, size);
2223 UnlockDisplay(dpy);
2224 SyncHandle();
2227 return Success;
2231 ** Execute a large rendering request (one that spans multiple X requests).
2233 int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
2235 xGLXRenderLargeReq *req;
2236 xGLXRenderLargeReq *be_req;
2237 __GLXcontext *glxc;
2238 int from_screen = 0;
2239 int to_screen = 0;
2240 int s;
2243 ** NOTE: much of this code also appears in the byteswapping version of this
2244 ** routine, __glXSwapRenderLarge(). Any changes made here should also be
2245 ** duplicated there.
2248 req = (xGLXRenderLargeReq *) pc;
2249 glxc = __glXLookupContextByTag(cl, req->contextTag);
2250 if (!glxc) {
2251 return 0;
2253 from_screen = to_screen = glxc->pScreen->myNum;
2255 #ifdef PANORAMIX
2256 if (!noPanoramiXExtension) {
2257 from_screen = 0;
2258 to_screen = screenInfo.numScreens - 1;
2260 #endif
2262 pc += sz_xGLXRenderLargeReq;
2265 * just forward the request to back-end server(s)
2267 for (s=from_screen; s<=to_screen; s++) {
2268 DMXScreenInfo *dmxScreen = &dmxScreens[s];
2269 Display *dpy = GetBackEndDisplay(cl,s);
2271 GetReq(GLXRenderLarge,be_req);
2272 be_req->reqType = dmxScreen->glxMajorOpcode;
2273 be_req->glxCode = X_GLXRenderLarge;
2274 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
2275 be_req->length = req->length;
2276 be_req->requestNumber = req->requestNumber;
2277 be_req->requestTotal = req->requestTotal;
2278 be_req->dataBytes = req->dataBytes;
2279 Data(dpy, (const char *)pc, req->dataBytes);
2280 UnlockDisplay(dpy);
2281 SyncHandle();
2285 return Success;
2289 /************************************************************************/
2291 int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
2293 xGLXVendorPrivateReq *req;
2295 req = (xGLXVendorPrivateReq *) pc;
2297 switch( req->vendorCode ) {
2299 case X_GLvop_DeleteTexturesEXT:
2300 return __glXVForwardSingleReq( cl, pc );
2301 break;
2303 case X_GLXvop_SwapIntervalSGI:
2304 if (glxIsExtensionSupported("SGI_swap_control")) {
2305 return __glXVForwardSingleReq( cl, pc );
2307 else {
2308 return Success;
2310 break;
2312 #if 0 /* glx 1.3 */
2313 case X_GLXvop_CreateGLXVideoSourceSGIX:
2314 break;
2315 case X_GLXvop_DestroyGLXVideoSourceSGIX:
2316 break;
2317 case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
2318 break;
2319 case X_GLXvop_DestroyGLXPbufferSGIX:
2320 break;
2321 case X_GLXvop_ChangeDrawableAttributesSGIX:
2322 break;
2323 #endif
2325 case X_GLXvop_BindSwapBarrierSGIX:
2326 return __glXBindSwapBarrierSGIX( cl, pc );
2327 break;
2329 case X_GLXvop_JoinSwapGroupSGIX:
2330 return __glXJoinSwapGroupSGIX( cl, pc );
2331 break;
2333 case X_GLXvop_CreateContextWithConfigSGIX:
2334 return __glXCreateContextWithConfigSGIX( cl, pc );
2335 break;
2337 default:
2339 ** unsupported private request
2341 cl->client->errorValue = req->vendorCode;
2342 return __glXUnsupportedPrivateRequest;
2345 cl->client->errorValue = req->vendorCode;
2346 return __glXUnsupportedPrivateRequest;
2350 int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
2352 xGLXVendorPrivateWithReplyReq *req;
2354 req = (xGLXVendorPrivateWithReplyReq *) pc;
2356 switch( req->vendorCode ) {
2358 case X_GLvop_GetConvolutionFilterEXT:
2359 case X_GLvop_GetConvolutionParameterfvEXT:
2360 case X_GLvop_GetConvolutionParameterivEXT:
2361 case X_GLvop_GetSeparableFilterEXT:
2362 case X_GLvop_GetHistogramEXT:
2363 case X_GLvop_GetHistogramParameterivEXT:
2364 case X_GLvop_GetMinmaxEXT:
2365 case X_GLvop_GetMinmaxParameterfvEXT:
2366 case X_GLvop_GetMinmaxParameterivEXT:
2367 case X_GLvop_AreTexturesResidentEXT:
2368 case X_GLvop_IsTextureEXT:
2369 return( __glXVForwardPipe0WithReply(cl, pc) );
2370 break;
2372 case X_GLvop_GenTexturesEXT:
2373 return( __glXVForwardAllWithReply(cl, pc) );
2374 break;
2377 #if 0 /* glx1.3 */
2378 case X_GLvop_GetDetailTexFuncSGIS:
2379 case X_GLvop_GetSharpenTexFuncSGIS:
2380 case X_GLvop_GetColorTableSGI:
2381 case X_GLvop_GetColorTableParameterfvSGI:
2382 case X_GLvop_GetColorTableParameterivSGI:
2383 case X_GLvop_GetTexFilterFuncSGIS:
2384 case X_GLvop_GetInstrumentsSGIX:
2385 case X_GLvop_InstrumentsBufferSGIX:
2386 case X_GLvop_PollInstrumentsSGIX:
2387 case X_GLvop_FlushRasterSGIX:
2388 case X_GLXvop_CreateGLXPbufferSGIX:
2389 case X_GLXvop_GetDrawableAttributesSGIX:
2390 case X_GLXvop_QueryHyperpipeNetworkSGIX:
2391 case X_GLXvop_QueryHyperpipeConfigSGIX:
2392 case X_GLXvop_HyperpipeConfigSGIX:
2393 case X_GLXvop_DestroyHyperpipeConfigSGIX:
2394 #endif
2395 case X_GLXvop_QueryMaxSwapBarriersSGIX:
2396 return( __glXQueryMaxSwapBarriersSGIX(cl, pc) );
2397 break;
2399 case X_GLXvop_GetFBConfigsSGIX:
2400 return( __glXGetFBConfigsSGIX(cl, pc) );
2401 break;
2403 case X_GLXvop_MakeCurrentReadSGI:
2404 return( __glXMakeCurrentReadSGI(cl, pc) );
2405 break;
2407 case X_GLXvop_QueryContextInfoEXT:
2408 return( __glXQueryContextInfoEXT(cl,pc) );
2409 break;
2411 default:
2413 ** unsupported private request
2415 cl->client->errorValue = req->vendorCode;
2416 return __glXUnsupportedPrivateRequest;
2421 int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
2423 ClientPtr client = cl->client;
2424 xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
2425 xGLXQueryExtensionsStringReply reply;
2426 GLint screen;
2427 size_t length;
2428 int len, numbytes;
2429 char *be_buf;
2431 #ifdef FWD_QUERY_REQ
2432 xGLXQueryExtensionsStringReq *be_req;
2433 xGLXQueryExtensionsStringReply be_reply;
2434 DMXScreenInfo *dmxScreen;
2435 Display *dpy;
2436 int slop;
2437 #endif
2439 screen = req->screen;
2442 ** Check if screen exists.
2444 if ((screen < 0) || (screen >= screenInfo.numScreens)) {
2445 client->errorValue = screen;
2446 return BadValue;
2449 #ifdef FWD_QUERY_REQ
2450 dmxScreen = &dmxScreens[screen];
2452 /* Send the glXQueryServerString request */
2453 dpy = GetBackEndDisplay(cl,screen);
2454 LockDisplay(dpy);
2455 GetReq(GLXQueryExtensionsString,be_req);
2456 be_req->reqType = dmxScreen->glxMajorOpcode;
2457 be_req->glxCode = X_GLXQueryServerString;
2458 be_req->screen = DefaultScreen(dpy);
2459 _XReply(dpy, (xReply*) &be_reply, 0, False);
2460 len = (int)be_reply.length;
2461 numbytes = (int)be_reply.n;
2462 slop = numbytes * __GLX_SIZE_INT8 & 3;
2463 be_buf = (char *)Xalloc(numbytes);
2464 if (!be_buf) {
2465 /* Throw data on the floor */
2466 _XEatData(dpy, len);
2467 } else {
2468 _XRead(dpy, (char *)be_buf, numbytes);
2469 if (slop) _XEatData(dpy,4-slop);
2471 UnlockDisplay(dpy);
2472 SyncHandle();
2474 #else
2476 be_buf = __glXGetServerString(GLX_EXTENSIONS);
2477 numbytes = strlen(be_buf) + 1;
2478 len = __GLX_PAD(numbytes) >> 2;
2480 #endif
2482 length = len;
2483 reply.type = X_Reply;
2484 reply.sequenceNumber = client->sequence;
2485 reply.length = len;
2486 reply.n = numbytes;
2488 if (client->swapped) {
2489 glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
2490 } else {
2491 WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
2492 WriteToClient(client, (int)(length << 2), (char *)be_buf);
2495 return Success;
2498 int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
2500 ClientPtr client = cl->client;
2501 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
2502 xGLXQueryServerStringReply reply;
2503 int name;
2504 GLint screen;
2505 size_t length;
2506 int len, numbytes;
2507 char *be_buf;
2508 #ifdef FWD_QUERY_REQ
2509 xGLXQueryServerStringReq *be_req;
2510 xGLXQueryServerStringReply be_reply;
2511 DMXScreenInfo *dmxScreen;
2512 Display *dpy;
2513 int slop;
2514 #endif
2516 name = req->name;
2517 screen = req->screen;
2519 ** Check if screen exists.
2521 if ((screen < 0) || (screen >= screenInfo.numScreens)) {
2522 client->errorValue = screen;
2523 return BadValue;
2526 #ifdef FWD_QUERY_REQ
2527 dmxScreen = &dmxScreens[screen];
2529 /* Send the glXQueryServerString request */
2530 dpy = GetBackEndDisplay(cl,screen);
2531 LockDisplay(dpy);
2532 GetReq(GLXQueryServerString,be_req);
2533 be_req->reqType = dmxScreen->glxMajorOpcode;
2534 be_req->glxCode = X_GLXQueryServerString;
2535 be_req->screen = DefaultScreen(dpy);
2536 be_req->name = name;
2537 _XReply(dpy, (xReply*) &be_reply, 0, False);
2538 len = (int)be_reply.length;
2539 numbytes = (int)be_reply.n;
2540 slop = numbytes * __GLX_SIZE_INT8 & 3;
2541 be_buf = (char *)Xalloc(numbytes);
2542 if (!be_buf) {
2543 /* Throw data on the floor */
2544 _XEatData(dpy, len);
2545 } else {
2546 _XRead(dpy, (char *)be_buf, numbytes);
2547 if (slop) _XEatData(dpy,4-slop);
2549 UnlockDisplay(dpy);
2550 SyncHandle();
2552 #else
2553 be_buf = __glXGetServerString(name);
2554 numbytes = strlen(be_buf) + 1;
2555 len = __GLX_PAD(numbytes) >> 2;
2556 #endif
2558 length = len;
2559 reply.type = X_Reply;
2560 reply.sequenceNumber = client->sequence;
2561 reply.length = length;
2562 reply.n = numbytes;
2564 if (client->swapped) {
2565 glxSwapQueryServerStringReply(client, &reply, be_buf);
2566 } else {
2567 WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
2568 WriteToClient(client, (int)(length << 2), be_buf);
2571 return Success;
2574 int __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
2576 xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
2577 xGLXClientInfoReq *be_req;
2578 const char *buf;
2579 int from_screen = 0;
2580 int to_screen = 0;
2581 int s;
2583 cl->GLClientmajorVersion = req->major;
2584 cl->GLClientminorVersion = req->minor;
2585 if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
2586 buf = (const char *)(req+1);
2587 cl->GLClientextensions = strdup(buf);
2589 to_screen = screenInfo.numScreens - 1;
2591 for (s=from_screen; s<=to_screen; s++)
2593 DMXScreenInfo *dmxScreen = &dmxScreens[s];
2594 Display *dpy = GetBackEndDisplay(cl,s);
2596 LockDisplay(dpy);
2597 GetReq(GLXClientInfo,be_req);
2598 be_req->reqType = dmxScreen->glxMajorOpcode;
2599 be_req->glxCode = X_GLXClientInfo;
2600 be_req->major = req->major;
2601 be_req->minor = req->minor;
2602 be_req->length = req->length;
2603 be_req->numbytes = req->numbytes;
2604 Data(dpy, buf, req->numbytes);
2606 UnlockDisplay(dpy);
2607 SyncHandle();
2610 return Success;
2613 int __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
2615 ClientPtr client = cl->client;
2616 xGLXUseXFontReq *req;
2617 xGLXUseXFontReq *be_req;
2618 FontPtr pFont;
2619 __GLXcontext *glxc = NULL;
2620 int from_screen = 0;
2621 int to_screen = 0;
2622 int s;
2623 dmxFontPrivPtr pFontPriv;
2624 DMXScreenInfo *dmxScreen;
2625 Display *dpy;
2627 req = (xGLXUseXFontReq *) pc;
2629 if (req->contextTag != 0) {
2630 glxc = __glXLookupContextByTag(cl, req->contextTag);
2631 if (glxc) {
2632 from_screen = to_screen = glxc->pScreen->myNum;
2637 ** Font can actually be either the ID of a font or the ID of a GC
2638 ** containing a font.
2640 pFont = (FontPtr)LookupIDByType(req->font, RT_FONT);
2641 if (!pFont) {
2642 GC *pGC = (GC *)LookupIDByType(req->font, RT_GC);
2643 if (!pGC) {
2644 client->errorValue = req->font;
2645 return BadFont;
2647 pFont = pGC->font;
2650 pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
2652 #ifdef PANORAMIX
2653 if (!noPanoramiXExtension) {
2654 from_screen = 0;
2655 to_screen = screenInfo.numScreens - 1;
2657 #endif
2660 for (s=from_screen; s<=to_screen; s++) {
2661 dmxScreen = &dmxScreens[s];
2662 dpy = GetBackEndDisplay(cl,s);
2664 dmxSync( dmxScreen, 1 );
2666 LockDisplay(dpy);
2667 GetReq(GLXUseXFont,be_req);
2668 be_req->reqType = dmxScreen->glxMajorOpcode;
2669 be_req->glxCode = X_GLXUseXFont;
2670 be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
2671 be_req->font = pFontPriv->font[s]->fid;
2672 be_req->first = req->first;
2673 be_req->count = req->count;
2674 be_req->listBase = req->listBase;
2675 UnlockDisplay(dpy);
2676 SyncHandle();
2678 XSync( dpy, False );
2681 return Success;
2685 * start GLX 1.3 here
2688 int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
2690 ClientPtr client = cl->client;
2691 xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
2692 xGLXGetFBConfigsReply reply;
2693 __GLXFBConfig *pFBConfig;
2694 CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS];
2695 int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS;
2696 unsigned int screen = req->screen;
2697 int numFBConfigs, i, p;
2698 __GLXscreenInfo *pGlxScreen;
2700 if (screen > screenInfo.numScreens) {
2701 /* The client library must send a valid screen number. */
2702 client->errorValue = screen;
2703 return BadValue;
2706 pGlxScreen = &__glXActiveScreens[screen];
2707 numFBConfigs = __glXNumFBConfigs;
2709 reply.numFBConfigs = numFBConfigs;
2710 reply.numAttribs = numAttribs;
2711 reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2;
2712 reply.type = X_Reply;
2713 reply.sequenceNumber = client->sequence;
2715 if (client->swapped) {
2716 __GLX_DECLARE_SWAP_VARIABLES;
2717 __GLX_SWAP_SHORT(&reply.sequenceNumber);
2718 __GLX_SWAP_INT(&reply.length);
2719 __GLX_SWAP_INT(&reply.numFBConfigs);
2720 __GLX_SWAP_INT(&reply.numAttribs);
2722 WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
2724 for (i=0; i < numFBConfigs; i++) {
2725 int associatedVisualId = 0;
2726 int drawableTypeIndex;
2727 pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ];
2729 p = 0;
2730 /* core attributes */
2731 buf[p++] = GLX_FBCONFIG_ID;
2732 buf[p++] = pFBConfig->id;
2733 buf[p++] = GLX_BUFFER_SIZE;
2734 buf[p++] = pFBConfig->indexBits;
2735 buf[p++] = GLX_LEVEL;
2736 buf[p++] = pFBConfig->level;
2737 buf[p++] = GLX_DOUBLEBUFFER;
2738 buf[p++] = pFBConfig->doubleBufferMode;
2739 buf[p++] = GLX_STEREO;
2740 buf[p++] = pFBConfig->stereoMode;
2741 buf[p++] = GLX_AUX_BUFFERS;
2742 buf[p++] = pFBConfig->maxAuxBuffers;
2743 buf[p++] = GLX_RED_SIZE;
2744 buf[p++] = pFBConfig->redBits;
2745 buf[p++] = GLX_GREEN_SIZE;
2746 buf[p++] = pFBConfig->greenBits;
2747 buf[p++] = GLX_BLUE_SIZE;
2748 buf[p++] = pFBConfig->blueBits;
2749 buf[p++] = GLX_ALPHA_SIZE;
2750 buf[p++] = pFBConfig->alphaBits;
2751 buf[p++] = GLX_DEPTH_SIZE;
2752 buf[p++] = pFBConfig->depthBits;
2753 buf[p++] = GLX_STENCIL_SIZE;
2754 buf[p++] = pFBConfig->stencilBits;
2755 buf[p++] = GLX_ACCUM_RED_SIZE;
2756 buf[p++] = pFBConfig->accumRedBits;
2757 buf[p++] = GLX_ACCUM_GREEN_SIZE;
2758 buf[p++] = pFBConfig->accumGreenBits;
2759 buf[p++] = GLX_ACCUM_BLUE_SIZE;
2760 buf[p++] = pFBConfig->accumBlueBits;
2761 buf[p++] = GLX_ACCUM_ALPHA_SIZE;
2762 buf[p++] = pFBConfig->accumAlphaBits;
2763 buf[p++] = GLX_RENDER_TYPE;
2764 buf[p++] = pFBConfig->renderType;
2765 buf[p++] = GLX_DRAWABLE_TYPE;
2766 drawableTypeIndex = p;
2767 buf[p++] = pFBConfig->drawableType;
2768 buf[p++] = GLX_X_VISUAL_TYPE;
2769 buf[p++] = pFBConfig->visualType;
2770 buf[p++] = GLX_CONFIG_CAVEAT;
2771 buf[p++] = pFBConfig->visualCaveat;
2772 buf[p++] = GLX_TRANSPARENT_TYPE;
2773 buf[p++] = pFBConfig->transparentType;
2774 buf[p++] = GLX_TRANSPARENT_RED_VALUE;
2775 buf[p++] = pFBConfig->transparentRed;
2776 buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
2777 buf[p++] = pFBConfig->transparentGreen;
2778 buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
2779 buf[p++] = pFBConfig->transparentBlue;
2780 buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
2781 buf[p++] = pFBConfig->transparentAlpha;
2782 buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
2783 buf[p++] = pFBConfig->transparentIndex;
2784 buf[p++] = GLX_MAX_PBUFFER_WIDTH;
2785 buf[p++] = pFBConfig->maxPbufferWidth;
2786 buf[p++] = GLX_MAX_PBUFFER_HEIGHT;
2787 buf[p++] = pFBConfig->maxPbufferHeight;
2788 buf[p++] = GLX_MAX_PBUFFER_PIXELS;
2789 buf[p++] = pFBConfig->maxPbufferPixels;
2792 * find the visual of the back-end server and match a visual
2793 * on the proxy.
2794 * do only once - if a visual is not yet associated.
2796 if (pFBConfig->associatedVisualId == (unsigned int)-1) {
2797 DMXScreenInfo *dmxScreen = &dmxScreens[screen];
2798 __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ];
2799 __GLXvisualConfig *pGlxVisual = NULL;
2800 int v;
2801 int found = 0;
2802 for (v=0; v<dmxScreen->numGlxVisuals; v++) {
2803 if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) {
2804 pGlxVisual = &dmxScreen->glxVisuals[v];
2805 break;
2809 if (pGlxVisual) {
2810 for (v=0; v<pGlxScreen->numVisuals; v++) {
2811 if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) {
2812 associatedVisualId = pGlxScreen->pGlxVisual[v].vid;
2813 found = 1;
2814 break;
2819 if (!found) {
2820 associatedVisualId = 0;
2821 pFBConfig->drawableType &= ~(GLX_WINDOW_BIT);
2822 buf[drawableTypeIndex] = pFBConfig->drawableType;
2824 #ifdef PANORAMIX
2825 else if (!noPanoramiXExtension) {
2826 /* convert the associated visualId to the panoramix one */
2827 for (v=0; v<255; v++) {
2828 if ( PanoramiXVisualTable[ v * MAXSCREENS + screen ] ==
2829 associatedVisualId ) {
2830 associatedVisualId = v;
2831 break;
2834 pFBConfig->associatedVisualId = associatedVisualId;
2836 #endif
2838 else {
2839 associatedVisualId = pFBConfig->associatedVisualId;
2842 buf[p++] = GLX_VISUAL_ID;
2843 buf[p++] = associatedVisualId;
2845 /* SGIS_multisample attributes */
2846 buf[p++] = GLX_SAMPLES_SGIS;
2847 buf[p++] = pFBConfig->multiSampleSize;
2848 buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
2849 buf[p++] = pFBConfig->nMultiSampleBuffers;
2851 /* SGIX_pbuffer specific attributes */
2852 buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX;
2853 buf[p++] = pFBConfig->optimalPbufferWidth;
2854 buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX;
2855 buf[p++] = pFBConfig->optimalPbufferHeight;
2857 buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
2858 buf[p++] = pFBConfig->visualSelectGroup;
2860 if (client->swapped) {
2861 __GLX_DECLARE_SWAP_VARIABLES;
2862 __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs);
2864 WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf);
2866 return Success;
2869 int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
2871 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
2872 xGLXGetFBConfigsReq new_req;
2874 new_req.reqType = req->reqType;
2875 new_req.glxCode = req->glxCode;
2876 new_req.length = req->length;
2877 new_req.screen = req->screen;
2879 return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) );
2883 int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc)
2885 ClientPtr client = cl->client;
2886 xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
2887 int screen = req->screen;
2888 GLXFBConfigID fbconfigId = req->fbconfig;
2889 XID windowId = req->window;
2890 XID glxwindowId = req->glxwindow;
2891 DrawablePtr pDraw;
2892 ScreenPtr pScreen;
2893 __glXWindow *pGlxWindow;
2894 __GLXFBConfig *pGlxFBConfig = NULL;
2895 VisualPtr pVisual;
2896 VisualID visId;
2897 int i, rc;
2900 ** Check if windowId is valid
2902 rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
2903 DixUnknownAccess);
2904 if (rc != Success)
2905 return rc;
2908 ** Check if screen of window matches screen of fbconfig.
2910 pScreen = pDraw->pScreen;
2911 if (screen != pScreen->myNum) {
2912 return BadMatch;
2916 ** Find the FBConfigRec for this fbconfigid.
2918 if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
2919 client->errorValue = fbconfigId;
2920 return __glXBadFBConfig;
2922 visId = pGlxFBConfig->associatedVisualId;
2925 ** Check if the fbconfig supports rendering to windows
2927 if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) {
2928 return BadMatch;
2931 if (visId != None) {
2933 ** Check if the visual ID is valid for this screen.
2935 pVisual = pScreen->visuals;
2936 for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
2937 if (pVisual->vid == visId) {
2938 break;
2941 if (i == pScreen->numVisuals) {
2942 client->errorValue = visId;
2943 return BadValue;
2947 ** Check if color buffer depth of fbconfig matches depth
2948 ** of window.
2950 if (pVisual->nplanes != pDraw->depth) {
2951 return BadMatch;
2953 } else
2955 ** The window was created with no visual that corresponds
2956 ** to fbconfig
2958 return BadMatch;
2961 ** Check if there is already a fbconfig associated with this window
2963 if ( LookupIDByType(glxwindowId, __glXWindowRes) ) {
2964 client->errorValue = glxwindowId;
2965 return BadAlloc;
2968 pGlxWindow = (__glXWindow *) xalloc(sizeof(__glXWindow));
2969 if (!pGlxWindow) {
2970 return BadAlloc;
2974 ** Register this GLX window as a resource
2976 if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) {
2977 return BadAlloc;
2980 pGlxWindow->pDraw = pDraw;
2981 pGlxWindow->type = GLX_GLXWINDOW_TYPE;
2982 pGlxWindow->idExists = True;
2983 pGlxWindow->refcnt = 0;
2984 pGlxWindow->pGlxFBConfig = pGlxFBConfig;
2985 pGlxWindow->pScreen = pScreen;
2987 return Success;
2990 int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
2992 ClientPtr client = cl->client;
2993 xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
2994 XID glxwindow = req->glxwindow;
2997 ** Check if it's a valid GLX window.
2999 if (!LookupIDByType(glxwindow, __glXWindowRes)) {
3000 client->errorValue = glxwindow;
3001 return __glXBadDrawable;
3004 ** The glx window destructor will check whether it's current before
3005 ** freeing anything.
3007 FreeResource(glxwindow, RT_NONE);
3009 return Success;
3012 int __glXQueryContext(__GLXclientState *cl, GLbyte *pc)
3014 ClientPtr client = cl->client;
3015 __GLXcontext *ctx;
3016 xGLXQueryContextReq *req;
3017 xGLXQueryContextReply reply;
3018 int nProps;
3019 int *sendBuf, *pSendBuf;
3020 int nReplyBytes;
3022 req = (xGLXQueryContextReq *)pc;
3023 ctx = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
3024 if (!ctx) {
3025 client->errorValue = req->context;
3026 return __glXBadContext;
3029 nProps = 3;
3031 reply.length = nProps << 1;
3032 reply.type = X_Reply;
3033 reply.sequenceNumber = client->sequence;
3034 reply.n = nProps;
3036 nReplyBytes = reply.length << 2;
3037 sendBuf = (int *)xalloc(nReplyBytes);
3038 pSendBuf = sendBuf;
3039 *pSendBuf++ = GLX_FBCONFIG_ID;
3040 *pSendBuf++ = (int)(ctx->pFBConfig->id);
3041 *pSendBuf++ = GLX_RENDER_TYPE;
3042 *pSendBuf++ = (int)(ctx->pFBConfig->renderType);
3043 *pSendBuf++ = GLX_SCREEN;
3044 *pSendBuf++ = (int)(ctx->pScreen->myNum);
3046 if (client->swapped) {
3047 __glXSwapQueryContextReply(client, &reply, sendBuf);
3048 } else {
3049 WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply);
3050 WriteToClient(client, nReplyBytes, (char *)sendBuf);
3052 xfree((char *)sendBuf);
3054 return Success;
3057 int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
3059 ClientPtr client = cl->client;
3060 __GLXcontext *ctx;
3061 xGLXQueryContextInfoEXTReq *req;
3062 xGLXQueryContextInfoEXTReply reply;
3063 int nProps;
3064 int *sendBuf, *pSendBuf;
3065 int nReplyBytes;
3067 req = (xGLXQueryContextInfoEXTReq *)pc;
3068 ctx = (__GLXcontext *) SecurityLookupIDByType(client, req->context, __glXContextRes, DixReadAccess);
3069 if (!ctx) {
3070 client->errorValue = req->context;
3071 return __glXBadContext;
3074 nProps = 4;
3076 reply.length = nProps << 1;
3077 reply.type = X_Reply;
3078 reply.sequenceNumber = client->sequence;
3079 reply.n = nProps;
3081 nReplyBytes = reply.length << 2;
3082 sendBuf = (int *)xalloc(nReplyBytes);
3083 pSendBuf = sendBuf;
3084 *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
3085 *pSendBuf++ = (int)(ctx->share_id);
3086 *pSendBuf++ = GLX_VISUAL_ID_EXT;
3087 *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0);
3088 *pSendBuf++ = GLX_SCREEN_EXT;
3089 *pSendBuf++ = (int)(ctx->pScreen->myNum);
3090 *pSendBuf++ = GLX_FBCONFIG_ID;
3091 *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0);
3093 if (client->swapped) {
3094 __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
3095 } else {
3096 WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
3097 WriteToClient(client, nReplyBytes, (char *)sendBuf);
3099 xfree((char *)sendBuf);
3101 return Success;
3104 int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
3106 ClientPtr client = cl->client;
3107 xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
3108 xGLXCreatePbufferReq *be_req;
3109 int screen = req->screen;
3110 GLXFBConfigID fbconfigId = req->fbconfig;
3111 GLXPbuffer pbuffer = req->pbuffer;
3112 __glXPbuffer *pGlxPbuffer;
3113 int numAttribs = req->numAttribs;
3114 int *attr;
3115 ScreenPtr pScreen;
3116 __GLXFBConfig *pGlxFBConfig;
3117 __GLXFBConfig *be_pGlxFBConfig;
3118 XID be_xid;
3119 Display *dpy;
3120 DMXScreenInfo *dmxScreen;
3121 int s;
3122 int from_screen, to_screen;
3125 ** Look up screen and FBConfig.
3127 if (screen > screenInfo.numScreens) {
3128 /* The client library must send a valid screen number. */
3129 client->errorValue = screen;
3130 return BadValue;
3132 pScreen = screenInfo.screens[screen];
3135 ** Find the FBConfigRec for this fbconfigid.
3137 if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
3138 client->errorValue = fbconfigId;
3139 return __glXBadFBConfig;
3143 ** Create the GLX part of the Pbuffer.
3145 pGlxPbuffer = (__glXPbuffer *) xalloc(sizeof(__glXPbuffer));
3146 if (!pGlxPbuffer) {
3147 return BadAlloc;
3150 pGlxPbuffer->be_xids = (XID *) xalloc( sizeof(XID) * screenInfo.numScreens );
3151 if (!pGlxPbuffer->be_xids) {
3152 xfree(pGlxPbuffer);
3153 return BadAlloc;
3157 * Allocate an XID on the back-end server(s) and send him the request
3159 from_screen = to_screen = screen;
3160 #ifdef PANORAMIX
3161 if (!noPanoramiXExtension) {
3162 from_screen = 0;
3163 to_screen = screenInfo.numScreens - 1;
3165 #endif
3167 for (s=from_screen; s<=to_screen; s++) {
3168 dpy = GetBackEndDisplay(cl,s);
3169 be_xid = XAllocID(dpy);
3170 dmxScreen = &dmxScreens[s];
3171 be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s );
3173 attr = (int *)( req+1 );
3175 LockDisplay(dpy);
3176 GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req);
3177 be_req->reqType = dmxScreen->glxMajorOpcode;
3178 be_req->glxCode = X_GLXCreatePbuffer;
3179 be_req->screen = be_pGlxFBConfig->screen;
3180 be_req->fbconfig = be_pGlxFBConfig->id;
3181 be_req->pbuffer = be_xid;
3182 be_req->numAttribs = numAttribs;
3184 /* Send attributes */
3185 if ( attr != NULL ) {
3186 CARD32 *pc = (CARD32 *)(be_req + 1);
3188 while (numAttribs-- > 0) {
3189 *pc++ = *attr++; /* token */
3190 *pc++ = *attr++; /* value */
3194 UnlockDisplay(dpy);
3195 SyncHandle();
3197 pGlxPbuffer->be_xids[s] = be_xid;
3201 pGlxPbuffer->idExists = True;
3202 pGlxPbuffer->refcnt = 0;
3203 pGlxPbuffer->pFBConfig = pGlxFBConfig;
3204 pGlxPbuffer->pScreen = pScreen;
3207 ** Register the resource.
3209 if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) {
3210 return BadAlloc;
3213 return Success;
3217 int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
3219 ClientPtr client = cl->client;
3220 xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
3221 xGLXDestroyPbufferReq *be_req;
3222 GLXPbuffer pbuffer = req->pbuffer;
3223 Display *dpy;
3224 int screen;
3225 DMXScreenInfo *dmxScreen;
3226 __glXPbuffer *pGlxPbuffer;
3227 int s;
3228 int from_screen, to_screen;
3231 ** Check if it's a valid Pbuffer
3233 pGlxPbuffer = (__glXPbuffer *)LookupIDByType(pbuffer, __glXPbufferRes);
3234 if (!pGlxPbuffer) {
3235 client->errorValue = pbuffer;
3236 return __glXBadPbuffer;
3239 screen = pGlxPbuffer->pScreen->myNum;
3241 from_screen = to_screen = screen;
3242 #ifdef PANORAMIX
3243 if (!noPanoramiXExtension) {
3244 from_screen = 0;
3245 to_screen = screenInfo.numScreens - 1;
3247 #endif
3249 for (s=from_screen; s<=to_screen; s++) {
3250 dpy = GetBackEndDisplay(cl,s);
3251 dmxScreen = &dmxScreens[s];
3253 /* send the destroy request to the back-end server */
3254 LockDisplay(dpy);
3255 GetReq(GLXDestroyPbuffer, be_req);
3256 be_req->reqType = dmxScreen->glxMajorOpcode;
3257 be_req->glxCode = X_GLXDestroyPbuffer;
3258 be_req->pbuffer = pGlxPbuffer->be_xids[s];
3259 UnlockDisplay(dpy);
3260 SyncHandle();
3263 FreeResource(pbuffer, RT_NONE);
3265 return Success;
3268 int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
3270 xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
3271 xGLXGetDrawableAttributesReq *be_req;
3272 xGLXGetDrawableAttributesReply reply;
3273 ClientPtr client = cl->client;
3274 GLXDrawable drawId = req->drawable;
3275 GLXDrawable be_drawable = 0;
3276 DrawablePtr pDraw = NULL;
3277 Display *dpy;
3278 int screen, rc;
3279 DMXScreenInfo *dmxScreen;
3280 CARD32 *attribs = NULL;
3281 int attribs_size;
3282 #ifdef PANORAMIX
3283 PanoramiXRes *pXinDraw = NULL;
3284 #endif
3286 if (drawId != None) {
3287 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
3288 if (rc == Success) {
3289 if (pDraw->type == DRAWABLE_WINDOW) {
3290 WindowPtr pWin = (WindowPtr)pDraw;
3291 be_drawable = 0;
3292 screen = pWin->drawable.pScreen->myNum;
3295 else {
3297 ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3299 client->errorValue = drawId;
3300 return __glXBadDrawable;
3304 if (!pDraw) {
3305 __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
3306 __glXPixmapRes);
3307 if (pGlxPixmap) {
3308 pDraw = pGlxPixmap->pDraw;
3309 screen = pGlxPixmap->pScreen->myNum;
3310 be_drawable = pGlxPixmap->be_xids[screen];
3314 if (!pDraw) {
3315 __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
3316 if (pGlxWindow) {
3317 pDraw = pGlxWindow->pDraw;
3318 screen = pGlxWindow->pScreen->myNum;
3319 be_drawable = 0;
3323 if (!pDraw) {
3324 __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
3325 if (pGlxPbuffer) {
3326 pDraw = (DrawablePtr)pGlxPbuffer;
3327 screen = pGlxPbuffer->pScreen->myNum;
3328 be_drawable = pGlxPbuffer->be_xids[screen];
3333 if (!pDraw) {
3335 ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3337 client->errorValue = drawId;
3338 return __glXBadDrawable;
3343 /* if the drawable is a window or GLXWindow -
3344 * we need to find the base id on the back-end server
3346 if (!be_drawable) {
3347 WindowPtr pWin = (WindowPtr)pDraw;
3349 #ifdef PANORAMIX
3350 if (!noPanoramiXExtension) {
3351 pXinDraw = (PanoramiXRes *)
3352 SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
3353 if (!pXinDraw) {
3354 client->errorValue = drawId;
3355 return __glXBadDrawable;
3358 dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
3359 DixReadAccess);
3361 #endif
3363 if (pWin) {
3364 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3365 if (!be_drawable) {
3366 /* it might be that the window did not created yet on the */
3367 /* back-end server (lazy window creation option), force */
3368 /* creation of the window */
3369 dmxCreateAndRealizeWindow( pWin, TRUE );
3370 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3373 else {
3374 client->errorValue = drawId;
3375 return __glXBadDrawable;
3380 /* send the request to the back-end server */
3381 dpy = GetBackEndDisplay(cl,screen);
3382 dmxScreen = &dmxScreens[screen];
3384 /* make sure drawable exists on back-end */
3385 dmxSync( dmxScreen, 1 );
3387 LockDisplay(dpy);
3388 GetReq(GLXGetDrawableAttributes, be_req);
3389 be_req->reqType = dmxScreen->glxMajorOpcode;
3390 be_req->glxCode = X_GLXGetDrawableAttributes;
3391 be_req->drawable = be_drawable;
3392 be_req->length = req->length;
3393 if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
3394 UnlockDisplay(dpy);
3395 SyncHandle();
3396 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
3399 if (reply.numAttribs) {
3400 attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
3401 attribs = (CARD32 *) Xalloc(attribs_size);
3402 if (attribs == NULL) {
3403 UnlockDisplay(dpy);
3404 SyncHandle();
3405 return BadAlloc;
3408 _XRead(dpy, (char *) attribs, attribs_size);
3411 UnlockDisplay(dpy);
3412 SyncHandle();
3415 /* send the reply back to the client */
3416 reply.sequenceNumber = client->sequence;
3417 if (client->swapped) {
3418 __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs);
3420 else {
3421 WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply);
3422 WriteToClient(client, attribs_size, (char *)attribs);
3425 Xfree(attribs);
3427 return Success;
3430 int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
3432 xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
3433 xGLXChangeDrawableAttributesReq *be_req;
3434 ClientPtr client = cl->client;
3435 GLXDrawable drawId = req->drawable;
3436 GLXDrawable be_drawable = 0;
3437 DrawablePtr pDraw = NULL;
3438 Display *dpy;
3439 int screen, rc;
3440 DMXScreenInfo *dmxScreen;
3441 char *attrbuf;
3442 #ifdef PANORAMIX
3443 PanoramiXRes *pXinDraw = NULL;
3444 PanoramiXRes *pXinReadDraw = NULL;
3445 #endif
3447 if (drawId != None) {
3448 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
3449 if (rc == Success) {
3450 if (pDraw->type == DRAWABLE_WINDOW) {
3451 WindowPtr pWin = (WindowPtr)pDraw;
3452 be_drawable = 0;
3453 screen = pWin->drawable.pScreen->myNum;
3456 else {
3458 ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3460 client->errorValue = drawId;
3461 return __glXBadDrawable;
3465 if (!pDraw) {
3466 __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
3467 __glXPixmapRes);
3468 if (pGlxPixmap) {
3469 pDraw = pGlxPixmap->pDraw;
3470 screen = pGlxPixmap->pScreen->myNum;
3471 be_drawable = pGlxPixmap->be_xids[screen];
3475 if (!pDraw) {
3476 __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
3477 if (pGlxWindow) {
3478 pDraw = pGlxWindow->pDraw;
3479 screen = pGlxWindow->pScreen->myNum;
3480 be_drawable = 0;
3484 if (!pDraw) {
3485 __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
3486 if (pGlxPbuffer) {
3487 pDraw = (DrawablePtr)pGlxPbuffer;
3488 screen = pGlxPbuffer->pScreen->myNum;
3489 be_drawable = pGlxPbuffer->be_xids[screen];
3494 if (!pDraw) {
3496 ** Drawable is not a Window , GLXWindow or a GLXPixmap.
3498 client->errorValue = drawId;
3499 return __glXBadDrawable;
3504 /* if the drawable is a window or GLXWindow -
3505 * we need to find the base id on the back-end server
3507 if (!be_drawable) {
3508 WindowPtr pWin = (WindowPtr)pDraw;
3510 #ifdef PANORAMIX
3511 if (!noPanoramiXExtension) {
3512 pXinDraw = (PanoramiXRes *)
3513 SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
3514 if (!pXinDraw) {
3515 client->errorValue = drawId;
3516 return __glXBadDrawable;
3519 dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
3520 DixReadAccess);
3522 #endif
3524 if (pWin) {
3525 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3526 if (!be_drawable) {
3527 /* it might be that the window did not created yet on the */
3528 /* back-end server (lazy window creation option), force */
3529 /* creation of the window */
3530 dmxCreateAndRealizeWindow( pWin, TRUE );
3531 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
3534 else {
3535 client->errorValue = drawId;
3536 return __glXBadDrawable;
3541 /* send the request to the back-end server */
3542 dpy = GetBackEndDisplay(cl,screen);
3543 dmxScreen = &dmxScreens[screen];
3545 /* make sure drawable exists on back-end */
3546 dmxSync( dmxScreen, 1 );
3548 LockDisplay(dpy);
3549 GetReqExtra(GLXChangeDrawableAttributes,
3550 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req);
3551 be_req->reqType = dmxScreen->glxMajorOpcode;
3552 be_req->glxCode = X_GLXChangeDrawableAttributes;
3553 be_req->drawable = be_drawable;
3554 be_req->numAttribs = req->numAttribs;
3555 be_req->length = req->length;
3557 UnlockDisplay(dpy);
3558 SyncHandle();
3560 return Success;
3563 int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag)
3565 ClientPtr client = cl->client;
3566 xGLXRenderLargeReq *req;
3567 GLint maxSize, amount;
3568 GLint totalRequests, requestNumber;
3569 GLint dataLen;
3570 GLbyte *data;
3571 __GLXcontext *glxc;
3572 int s;
3573 int from_screen, to_screen;
3575 maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq);
3576 dataLen = cl->largeCmdBytesTotal;
3577 totalRequests = (dataLen / maxSize);
3578 if (dataLen % maxSize) totalRequests++;
3580 glxc = __glXLookupContextByTag(cl, contextTag);
3581 if (!glxc) {
3582 client->errorValue = contextTag;
3583 return __glXBadContext;
3585 from_screen = to_screen = glxc->pScreen->myNum;
3587 #ifdef PANORAMIX
3588 if (!noPanoramiXExtension) {
3589 from_screen = 0;
3590 to_screen = screenInfo.numScreens - 1;
3592 #endif
3595 ** Send enough requests until the whole array is sent.
3597 requestNumber = 1;
3598 data = cl->largeCmdBuf;
3599 while (dataLen > 0) {
3600 amount = dataLen;
3601 if (amount > maxSize) {
3602 amount = maxSize;
3605 for (s=from_screen; s<=to_screen; s++) {
3607 Display *dpy = GetBackEndDisplay(cl,s);
3608 DMXScreenInfo *dmxScreen = &dmxScreens[s];
3610 LockDisplay(dpy);
3611 GetReq(GLXRenderLarge,req);
3612 req->reqType = dmxScreen->glxMajorOpcode;
3613 req->glxCode = X_GLXRenderLarge;
3614 req->contextTag = GetCurrentBackEndTag(cl,contextTag,s);
3615 req->length += (amount + 3) >> 2;
3616 req->requestNumber = requestNumber++;
3617 req->requestTotal = totalRequests;
3618 req->dataBytes = amount;
3619 Data(dpy, ((const char*)data), amount);
3620 dataLen -= amount;
3621 data = ((GLbyte *) data) + amount;
3622 UnlockDisplay(dpy);
3623 SyncHandle();
3627 return Success;