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