Bug Summary

File:glx/glxcmds.c
Location:line 123, column 9
Description:Access to field 'class' results in a dereference of a null pointer (loaded from variable 'pVisual')

Annotated Source Code

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_DIX_CONFIG_H1
32#include <dix-config.h>
33#endif
34
35#include <string.h>
36#include <assert.h>
37
38#include "glxserver.h"
39#include <GL/glxtokens.h>
40#include <unpack.h>
41#include <pixmapstr.h>
42#include <windowstr.h>
43#include "glxutil.h"
44#include "glxext.h"
45#include "indirect_dispatch.h"
46#include "indirect_table.h"
47#include "indirect_util.h"
48#include "protocol-versions.h"
49
50static char GLXServerVendorName[] = "SGI";
51
52_X_HIDDEN__attribute__((visibility("hidden"))) int
53validGlxScreen(ClientPtr client, int screen, __GLXscreen ** pGlxScreen,
54 int *err)
55{
56 /*
57 ** Check if screen exists.
58 */
59 if (screen < 0 || screen >= screenInfo.numScreens) {
60 client->errorValue = screen;
61 *err = BadValue2;
62 return FALSE0;
63 }
64 *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
65
66 return TRUE1;
67}
68
69_X_HIDDEN__attribute__((visibility("hidden"))) int
70validGlxFBConfig(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
71 __GLXconfig ** config, int *err)
72{
73 __GLXconfig *m;
74
75 for (m = pGlxScreen->fbconfigs; m != NULL((void*)0); m = m->next)
76 if (m->fbconfigID == id) {
77 *config = m;
78 return TRUE1;
79 }
80
81 client->errorValue = id;
82 *err = __glXError(GLXBadFBConfig9);
83
84 return FALSE0;
85}
86
87static int
88validGlxVisual(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
89 __GLXconfig ** config, int *err)
90{
91 int i;
92
93 for (i = 0; i < pGlxScreen->numVisuals; i++)
94 if (pGlxScreen->visuals[i]->visualID == id) {
95 *config = pGlxScreen->visuals[i];
96 return TRUE1;
97 }
98
99 client->errorValue = id;
100 *err = BadValue2;
101
102 return FALSE0;
103}
104
105static int
106validGlxFBConfigForWindow(ClientPtr client, __GLXconfig * config,
107 DrawablePtr pDraw, int *err)
108{
109 ScreenPtr pScreen = pDraw->pScreen;
110 VisualPtr pVisual = NULL((void*)0);
7
'pVisual' initialized to a null pointer value
111 XID vid;
112 int i;
113
114 vid = wVisual((WindowPtr) pDraw)(((WindowPtr) pDraw)->optional ? ((WindowPtr) pDraw)->optional
->visual : FindWindowWithOptional((WindowPtr) pDraw)->optional
->visual)
;
115 for (i = 0; i < pScreen->numVisuals; i++) {
8
Loop condition is false. Execution continues on line 123
116 if (pScreen->visuals[i].vid == vid) {
117 pVisual = &pScreen->visuals[i];
118 break;
119 }
120 }
121
122 /* FIXME: What exactly should we check here... */
123 if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
9
Access to field 'class' results in a dereference of a null pointer (loaded from variable 'pVisual')
124 !(config->drawableType & GLX_WINDOW_BIT0x00000001)) {
125 client->errorValue = pDraw->id;
126 *err = BadMatch8;
127 return FALSE0;
128 }
129
130 return TRUE1;
131}
132
133_X_HIDDEN__attribute__((visibility("hidden"))) int
134validGlxContext(ClientPtr client, XID id, int access_mode,
135 __GLXcontext ** context, int *err)
136{
137 *err = dixLookupResourceByType((void **) context, id,
138 __glXContextRes, client, access_mode);
139 if (*err != Success0 || (*context)->idExists == GL_FALSE0x0) {
140 client->errorValue = id;
141 if (*err == BadValue2 || *err == Success0)
142 *err = __glXError(GLXBadContext0);
143 return FALSE0;
144 }
145
146 return TRUE1;
147}
148
149static int
150validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
151 __GLXdrawable ** drawable, int *err)
152{
153 int rc;
154
155 rc = dixLookupResourceByType((void **) drawable, id,
156 __glXDrawableRes, client, access_mode);
157 if (rc != Success0 && rc != BadValue2) {
158 *err = rc;
159 client->errorValue = id;
160 return FALSE0;
161 }
162
163 /* If the ID of the glx drawable we looked up doesn't match the id
164 * we looked for, it's because we looked it up under the X
165 * drawable ID (see DoCreateGLXDrawable). */
166 if (rc == BadValue2 ||
167 (*drawable)->drawId != id ||
168 (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
169 client->errorValue = id;
170 switch (type) {
171 case GLX_DRAWABLE_WINDOW:
172 *err = __glXError(GLXBadWindow12);
173 return FALSE0;
174 case GLX_DRAWABLE_PIXMAP:
175 *err = __glXError(GLXBadPixmap3);
176 return FALSE0;
177 case GLX_DRAWABLE_PBUFFER:
178 *err = __glXError(GLXBadPbuffer10);
179 return FALSE0;
180 case GLX_DRAWABLE_ANY:
181 *err = __glXError(GLXBadDrawable2);
182 return FALSE0;
183 }
184 }
185
186 return TRUE1;
187}
188
189void
190__glXContextDestroy(__GLXcontext * context)
191{
192 lastGLContext = NULL((void*)0);
193}
194
195static void
196__glXdirectContextDestroy(__GLXcontext * context)
197{
198 __glXContextDestroy(context);
199 free(context);
200}
201
202static int
203__glXdirectContextLoseCurrent(__GLXcontext * context)
204{
205 return GL_TRUE0x1;
206}
207
208_X_HIDDEN__attribute__((visibility("hidden"))) __GLXcontext *
209__glXdirectContextCreate(__GLXscreen * screen,
210 __GLXconfig * modes, __GLXcontext * shareContext)
211{
212 __GLXcontext *context;
213
214 context = calloc(1, sizeof(__GLXcontext));
215 if (context == NULL((void*)0))
216 return NULL((void*)0);
217
218 context->destroy = __glXdirectContextDestroy;
219 context->loseCurrent = __glXdirectContextLoseCurrent;
220
221 return context;
222}
223
224/**
225 * Create a GL context with the given properties. This routine is used
226 * to implement \c glXCreateContext, \c glXCreateNewContext, and
227 * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way
228 * that GLXFBConfigs are implemented. Basically, the FBConfigID is the
229 * same as the VisualID.
230 */
231
232static int
233DoCreateContext(__GLXclientState * cl, GLXContextID gcId,
234 GLXContextID shareList, __GLXconfig * config,
235 __GLXscreen * pGlxScreen, GLboolean isDirect)
236{
237 ClientPtr client = cl->client;
238 __GLXcontext *glxc, *shareglxc;
239 int err;
240
241 LEGAL_NEW_RESOURCE(gcId, client)if (!LegalNewID(gcId,client)) { client->errorValue = gcId;
return 14; }
;
242
243 /*
244 ** Find the display list space that we want to share.
245 **
246 ** NOTE: In a multithreaded X server, we would need to keep a reference
247 ** count for each display list so that if one client detroyed a list that
248 ** another client was using, the list would not really be freed until it
249 ** was no longer in use. Since this sample implementation has no support
250 ** for multithreaded servers, we don't do this.
251 */
252 if (shareList == None0L) {
253 shareglxc = 0;
254 }
255 else {
256 if (!validGlxContext(client, shareList, DixReadAccess(1<<0),
257 &shareglxc, &err))
258 return err;
259
260 /* Page 26 (page 32 of the PDF) of the GLX 1.4 spec says:
261 *
262 * "The server context state for all sharing contexts must exist
263 * in a single address space or a BadMatch error is generated."
264 *
265 * If the share context is indirect, force the new context to also be
266 * indirect. If the shard context is direct but the new context
267 * cannot be direct, generate BadMatch.
268 */
269 if (shareglxc->isDirect && !isDirect) {
270 client->errorValue = shareList;
271 return BadMatch8;
272 }
273 else if (!shareglxc->isDirect) {
274 /*
275 ** Create an indirect context regardless of what the client asked
276 ** for; this way we can share display list space with shareList.
277 */
278 isDirect = GL_FALSE0x0;
279 }
280 }
281
282 /*
283 ** Allocate memory for the new context
284 */
285 if (!isDirect) {
286 /* Only allow creating indirect GLX contexts if allowed by
287 * server command line. Indirect GLX is of limited use (since
288 * it's only GL 1.4), it's slower than direct contexts, and
289 * it's a massive attack surface for buffer overflow type
290 * errors.
291 */
292 if (!enableIndirectGLX) {
293 client->errorValue = isDirect;
294 return BadValue2;
295 }
296
297 /* Without any attributes, the only error that the driver should be
298 * able to generate is BadAlloc. As result, just drop the error
299 * returned from the driver on the floor.
300 */
301 glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc,
302 0, NULL((void*)0), &err);
303 }
304 else
305 glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
306 if (!glxc) {
307 return BadAlloc11;
308 }
309
310 /* Initialize the GLXcontext structure.
311 */
312 glxc->pGlxScreen = pGlxScreen;
313 glxc->config = config;
314 glxc->id = gcId;
315 glxc->share_id = shareList;
316 glxc->idExists = GL_TRUE0x1;
317 glxc->isDirect = isDirect;
318 glxc->renderMode = GL_RENDER0x1C00;
319
320 /* The GLX_ARB_create_context_robustness spec says:
321 *
322 * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
323 * is GLX_NO_RESET_NOTIFICATION_ARB."
324 *
325 * Without using glXCreateContextAttribsARB, there is no way to specify a
326 * non-default reset notification strategy.
327 */
328 glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB0x8261;
329
330#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
331 /* The GLX_ARB_context_flush_control spec says:
332 *
333 * "The default value [for GLX_CONTEXT_RELEASE_BEHAVIOR] is
334 * CONTEXT_RELEASE_BEHAVIOR_FLUSH, and may in some cases be changed
335 * using platform-specific context creation extensions."
336 *
337 * Without using glXCreateContextAttribsARB, there is no way to specify a
338 * non-default release behavior.
339 */
340 glxc->releaseBehavior = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
341#endif
342
343 /* Add the new context to the various global tables of GLX contexts.
344 */
345 if (!__glXAddContext(glxc)) {
346 (*glxc->destroy) (glxc);
347 client->errorValue = gcId;
348 return BadAlloc11;
349 }
350
351 return Success0;
352}
353
354int
355__glXDisp_CreateContext(__GLXclientState * cl, GLbyte * pc)
356{
357 ClientPtr client = cl->client;
358 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
359 __GLXconfig *config;
360 __GLXscreen *pGlxScreen;
361 int err;
362
363 REQUEST_SIZE_MATCH(xGLXCreateContextReq)if ((sizeof(xGLXCreateContextReq) >> 2) != client->req_len
) return(16)
;
364
365 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
366 return err;
367 if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
368 return err;
369
370 return DoCreateContext(cl, req->context, req->shareList,
371 config, pGlxScreen, req->isDirect);
372}
373
374int
375__glXDisp_CreateNewContext(__GLXclientState * cl, GLbyte * pc)
376{
377 ClientPtr client = cl->client;
378 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
379 __GLXconfig *config;
380 __GLXscreen *pGlxScreen;
381 int err;
382
383 REQUEST_SIZE_MATCH(xGLXCreateNewContextReq)if ((sizeof(xGLXCreateNewContextReq) >> 2) != client->
req_len) return(16)
;
384
385 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
386 return err;
387 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
388 return err;
389
390 return DoCreateContext(cl, req->context, req->shareList,
391 config, pGlxScreen, req->isDirect);
392}
393
394int
395__glXDisp_CreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
396{
397 ClientPtr client = cl->client;
398 xGLXCreateContextWithConfigSGIXReq *req =
399 (xGLXCreateContextWithConfigSGIXReq *) pc;
400 __GLXconfig *config;
401 __GLXscreen *pGlxScreen;
402 int err;
403
404 REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq)if ((sizeof(xGLXCreateContextWithConfigSGIXReq) >> 2) !=
client->req_len) return(16)
;
405
406 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
407 return err;
408 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
409 return err;
410
411 return DoCreateContext(cl, req->context, req->shareList,
412 config, pGlxScreen, req->isDirect);
413}
414
415int
416__glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc)
417{
418 ClientPtr client = cl->client;
419 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
420 __GLXcontext *glxc;
421 int err;
422
423 REQUEST_SIZE_MATCH(xGLXDestroyContextReq)if ((sizeof(xGLXDestroyContextReq) >> 2) != client->
req_len) return(16)
;
424
425 if (!validGlxContext(cl->client, req->context, DixDestroyAccess(1<<2),
426 &glxc, &err))
427 return err;
428
429 glxc->idExists = GL_FALSE0x0;
430 if (!glxc->currentClient)
431 FreeResourceByType(req->context, __glXContextRes, FALSE0);
432
433 return Success0;
434}
435
436/*
437 * This will return "deleted" contexts, ie, where idExists is GL_FALSE.
438 * Contrast validGlxContext, which will not. We're cheating here and
439 * using the XID as the context tag, which is fine as long as we defer
440 * actually destroying the context until it's no longer referenced, and
441 * block clients from trying to MakeCurrent on contexts that are on the
442 * way to destruction. Notice that DoMakeCurrent calls validGlxContext
443 * for new contexts but __glXLookupContextByTag for previous contexts.
444 */
445__GLXcontext *
446__glXLookupContextByTag(__GLXclientState * cl, GLXContextTag tag)
447{
448 __GLXcontext *ret;
449
450 if (dixLookupResourceByType((void **) &ret, tag, __glXContextRes,
451 cl->client, DixUseAccess(1<<24)) == Success0)
452 return ret;
453
454 return NULL((void*)0);
455}
456
457/*****************************************************************************/
458
459static void
460StopUsingContext(__GLXcontext * glxc)
461{
462 if (glxc) {
463 glxc->currentClient = NULL((void*)0);
464 if (!glxc->idExists) {
465 FreeResourceByType(glxc->id, __glXContextRes, FALSE0);
466 }
467 }
468}
469
470static void
471StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc)
472{
473 glxc->currentClient = cl->client;
474}
475
476/**
477 * This is a helper function to handle the legacy (pre GLX 1.3) cases
478 * where passing an X window to glXMakeCurrent is valid. Given a
479 * resource ID, look up the GLX drawable if available, otherwise, make
480 * sure it's an X window and create a GLX drawable one the fly.
481 */
482static __GLXdrawable *
483__glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
484 int *error)
485{
486 DrawablePtr pDraw;
487 __GLXdrawable *pGlxDraw;
488 int rc;
489
490 if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
491 DixWriteAccess(1<<1), &pGlxDraw, &rc)) {
492 if (glxc != NULL((void*)0) && pGlxDraw->config != glxc->config) {
493 client->errorValue = drawId;
494 *error = BadMatch8;
495 return NULL((void*)0);
496 }
497
498 return pGlxDraw;
499 }
500
501 /* No active context and an unknown drawable, bail. */
502 if (glxc == NULL((void*)0)) {
503 client->errorValue = drawId;
504 *error = BadMatch8;
505 return NULL((void*)0);
506 }
507
508 /* The drawId wasn't a GLX drawable. Make sure it's a window and
509 * create a GLXWindow for it. Check that the drawable screen
510 * matches the context screen and that the context fbconfig is
511 * compatible with the window visual. */
512
513 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess(1<<4));
514 if (rc != Success0 || pDraw->type != DRAWABLE_WINDOW0) {
515 client->errorValue = drawId;
516 *error = __glXError(GLXBadDrawable2);
517 return NULL((void*)0);
518 }
519
520 if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
521 client->errorValue = pDraw->pScreen->myNum;
522 *error = BadMatch8;
523 return NULL((void*)0);
524 }
525
526 if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
527 return NULL((void*)0);
528
529 pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
530 pDraw, drawId,
531 GLX_DRAWABLE_WINDOW,
532 drawId, glxc->config);
533 if (!pGlxDraw) {
534 *error = BadAlloc11;
535 return NULL((void*)0);
536 }
537
538 /* since we are creating the drawablePrivate, drawId should be new */
539 if (!AddResourceDarwin_X_AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
540 *error = BadAlloc11;
541 return NULL((void*)0);
542 }
543
544 return pGlxDraw;
545}
546
547/*****************************************************************************/
548/*
549** Make an OpenGL context and drawable current.
550*/
551
552static int
553DoMakeCurrent(__GLXclientState * cl,
554 GLXDrawable drawId, GLXDrawable readId,
555 GLXContextID contextId, GLXContextTag tag)
556{
557 ClientPtr client = cl->client;
558 xGLXMakeCurrentReply reply;
559 __GLXcontext *glxc, *prevglxc;
560 __GLXdrawable *drawPriv = NULL((void*)0);
561 __GLXdrawable *readPriv = NULL((void*)0);
562 int error;
563 GLuint mask;
564
565 /*
566 ** If one is None and the other isn't, it's a bad match.
567 */
568
569 mask = (drawId == None0L) ? (1 << 0) : 0;
570 mask |= (readId == None0L) ? (1 << 1) : 0;
571 mask |= (contextId == None0L) ? (1 << 2) : 0;
572
573 if ((mask != 0x00) && (mask != 0x07)) {
574 return BadMatch8;
575 }
576
577 /*
578 ** Lookup old context. If we have one, it must be in a usable state.
579 */
580 if (tag != 0) {
581 prevglxc = __glXLookupContextByTag(cl, tag);
582 if (!prevglxc) {
583 /*
584 ** Tag for previous context is invalid.
585 */
586 return __glXError(GLXBadContextTag4);
587 }
588 if (prevglxc->renderMode != GL_RENDER0x1C00) {
589 /* Oops. Not in render mode render. */
590 client->errorValue = prevglxc->id;
591 return __glXError(GLXBadContextState1);
592 }
593 }
594 else {
595 prevglxc = 0;
596 }
597
598 /*
599 ** Lookup new context. It must not be current for someone else.
600 */
601 if (contextId != None0L) {
602 int status;
603
604 if (!validGlxContext(client, contextId, DixUseAccess(1<<24), &glxc, &error))
605 return error;
606 if ((glxc != prevglxc) && glxc->currentClient) {
607 /* Context is current to somebody else */
608 return BadAccess10;
609 }
610
611 assert(drawId != None)(__builtin_expect(!(drawId != 0L), 0) ? __assert_rtn(__func__
, "glxcmds.c", 611, "drawId != None") : (void)0)
;
612 assert(readId != None)(__builtin_expect(!(readId != 0L), 0) ? __assert_rtn(__func__
, "glxcmds.c", 612, "readId != None") : (void)0)
;
613
614 drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
615 if (drawPriv == NULL((void*)0))
616 return status;
617
618 readPriv = __glXGetDrawable(glxc, readId, client, &status);
619 if (readPriv == NULL((void*)0))
620 return status;
621
622 }
623 else {
624 /* Switching to no context. Ignore new drawable. */
625 glxc = 0;
626 drawPriv = 0;
627 readPriv = 0;
628 }
629
630 if (prevglxc) {
631 /*
632 ** Flush the previous context if needed.
633 */
634 Bool need_flush = GL_TRUE0x1;
635#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
636 if (prevglxc->releaseBehavior == GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB)
637 need_flush = GL_FALSE0x0;
638#endif
639 if (need_flush) {
640 if (__glXForceCurrent(cl, tag, (int *) &error)) {
641 glFlush();
642 }
643 else {
644 return error;
645 }
646 }
647
648 /*
649 ** Make the previous context not current.
650 */
651 if (!(*prevglxc->loseCurrent) (prevglxc)) {
652 return __glXError(GLXBadContext0);
653 }
654 lastGLContext = NULL((void*)0);
655 if (!prevglxc->isDirect) {
656 prevglxc->drawPriv = NULL((void*)0);
657 prevglxc->readPriv = NULL((void*)0);
658 }
659 }
660
661 if ((glxc != 0) && !glxc->isDirect) {
662
663 glxc->drawPriv = drawPriv;
664 glxc->readPriv = readPriv;
665
666 /* make the context current */
667 lastGLContext = glxc;
668 if (!(*glxc->makeCurrent) (glxc)) {
669 lastGLContext = NULL((void*)0);
670 glxc->drawPriv = NULL((void*)0);
671 glxc->readPriv = NULL((void*)0);
672 return __glXError(GLXBadContext0);
673 }
674
675 glxc->currentClient = client;
676 }
677
678 StopUsingContext(prevglxc);
679
680 reply = (xGLXMakeCurrentReply) {
681 .type = X_Reply1,
682 .sequenceNumber = client->sequence,
683 .length = 0,
684 .contextTag = 0
685 };
686
687 if (glxc) {
688 StartUsingContext(cl, glxc);
689 reply.contextTag = glxc->id;
690 }
691
692 if (client->swapped) {
693 __glXSwapMakeCurrentReply(client, &reply);
694 }
695 else {
696 WriteToClient(client, sz_xGLXMakeCurrentReply32, &reply);
697 }
698 return Success0;
699}
700
701int
702__glXDisp_MakeCurrent(__GLXclientState * cl, GLbyte * pc)
703{
704 ClientPtr client = cl->client;
705 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
706
707 REQUEST_SIZE_MATCH(xGLXMakeCurrentReq)if ((sizeof(xGLXMakeCurrentReq) >> 2) != client->req_len
) return(16)
;
708
709 return DoMakeCurrent(cl, req->drawable, req->drawable,
710 req->context, req->oldContextTag);
711}
712
713int
714__glXDisp_MakeContextCurrent(__GLXclientState * cl, GLbyte * pc)
715{
716 ClientPtr client = cl->client;
717 xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
718
719 REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq)if ((sizeof(xGLXMakeContextCurrentReq) >> 2) != client->
req_len) return(16)
;
720
721 return DoMakeCurrent(cl, req->drawable, req->readdrawable,
722 req->context, req->oldContextTag);
723}
724
725int
726__glXDisp_MakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc)
727{
728 ClientPtr client = cl->client;
729 xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
730
731 REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq)if ((sizeof(xGLXMakeCurrentReadSGIReq) >> 2) != client->
req_len) return(16)
;
732
733 return DoMakeCurrent(cl, req->drawable, req->readable,
734 req->context, req->oldContextTag);
735}
736
737int
738__glXDisp_IsDirect(__GLXclientState * cl, GLbyte * pc)
739{
740 ClientPtr client = cl->client;
741 xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
742 xGLXIsDirectReply reply;
743 __GLXcontext *glxc;
744 int err;
745
746 REQUEST_SIZE_MATCH(xGLXIsDirectReq)if ((sizeof(xGLXIsDirectReq) >> 2) != client->req_len
) return(16)
;
747
748 if (!validGlxContext(cl->client, req->context, DixReadAccess(1<<0), &glxc, &err))
749 return err;
750
751 reply = (xGLXIsDirectReply) {
752 .type = X_Reply1,
753 .sequenceNumber = client->sequence,
754 .length = 0,
755 .isDirect = glxc->isDirect
756 };
757
758 if (client->swapped) {
759 __glXSwapIsDirectReply(client, &reply);
760 }
761 else {
762 WriteToClient(client, sz_xGLXIsDirectReply32, &reply);
763 }
764
765 return Success0;
766}
767
768int
769__glXDisp_QueryVersion(__GLXclientState * cl, GLbyte * pc)
770{
771 ClientPtr client = cl->client;
772 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
773 xGLXQueryVersionReply reply;
774 GLuint major, minor;
775
776 REQUEST_SIZE_MATCH(xGLXQueryVersionReq)if ((sizeof(xGLXQueryVersionReq) >> 2) != client->req_len
) return(16)
;
777
778 major = req->majorVersion;
779 minor = req->minorVersion;
780 (void) major;
781 (void) minor;
782
783 /*
784 ** Server should take into consideration the version numbers sent by the
785 ** client if it wants to work with older clients; however, in this
786 ** implementation the server just returns its version number.
787 */
788 reply = (xGLXQueryVersionReply) {
789 .type = X_Reply1,
790 .sequenceNumber = client->sequence,
791 .length = 0,
792 .majorVersion = SERVER_GLX_MAJOR_VERSION1,
793 .minorVersion = SERVER_GLX_MINOR_VERSION4
794 };
795
796 if (client->swapped) {
797 __glXSwapQueryVersionReply(client, &reply);
798 }
799 else {
800 WriteToClient(client, sz_xGLXQueryVersionReply32, &reply);
801 }
802 return Success0;
803}
804
805int
806__glXDisp_WaitGL(__GLXclientState * cl, GLbyte * pc)
807{
808 ClientPtr client = cl->client;
809 xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
810 GLXContextTag tag;
811 __GLXcontext *glxc = NULL((void*)0);
812 int error;
813
814 REQUEST_SIZE_MATCH(xGLXWaitGLReq)if ((sizeof(xGLXWaitGLReq) >> 2) != client->req_len)
return(16)
;
815
816 tag = req->contextTag;
817 if (tag) {
818 glxc = __glXLookupContextByTag(cl, tag);
819 if (!glxc)
820 return __glXError(GLXBadContextTag4);
821
822 if (!__glXForceCurrent(cl, req->contextTag, &error))
823 return error;
824
825 glFinish();
826 }
827
828 if (glxc && glxc->drawPriv->waitGL)
829 (*glxc->drawPriv->waitGL) (glxc->drawPriv);
830
831 return Success0;
832}
833
834int
835__glXDisp_WaitX(__GLXclientState * cl, GLbyte * pc)
836{
837 ClientPtr client = cl->client;
838 xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
839 GLXContextTag tag;
840 __GLXcontext *glxc = NULL((void*)0);
841 int error;
842
843 REQUEST_SIZE_MATCH(xGLXWaitXReq)if ((sizeof(xGLXWaitXReq) >> 2) != client->req_len) return
(16)
;
844
845 tag = req->contextTag;
846 if (tag) {
847 glxc = __glXLookupContextByTag(cl, tag);
848 if (!glxc)
849 return __glXError(GLXBadContextTag4);
850
851 if (!__glXForceCurrent(cl, req->contextTag, &error))
852 return error;
853 }
854
855 if (glxc && glxc->drawPriv->waitX)
856 (*glxc->drawPriv->waitX) (glxc->drawPriv);
857
858 return Success0;
859}
860
861int
862__glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc)
863{
864 ClientPtr client = cl->client;
865 xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
866 GLXContextID source;
867 GLXContextID dest;
868 GLXContextTag tag;
869 unsigned long mask;
870 __GLXcontext *src, *dst;
871 int error;
872
873 REQUEST_SIZE_MATCH(xGLXCopyContextReq)if ((sizeof(xGLXCopyContextReq) >> 2) != client->req_len
) return(16)
;
874
875 source = req->source;
876 dest = req->dest;
877 tag = req->contextTag;
878 mask = req->mask;
879 if (!validGlxContext(cl->client, source, DixReadAccess(1<<0), &src, &error))
880 return error;
881 if (!validGlxContext(cl->client, dest, DixWriteAccess(1<<1), &dst, &error))
882 return error;
883
884 /*
885 ** They must be in the same address space, and same screen.
886 ** NOTE: no support for direct rendering contexts here.
887 */
888 if (src->isDirect || dst->isDirect || (src->pGlxScreen != dst->pGlxScreen)) {
889 client->errorValue = source;
890 return BadMatch8;
891 }
892
893 /*
894 ** The destination context must not be current for any client.
895 */
896 if (dst->currentClient) {
897 client->errorValue = dest;
898 return BadAccess10;
899 }
900
901 if (tag) {
902 __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
903
904 if (!tagcx) {
905 return __glXError(GLXBadContextTag4);
906 }
907 if (tagcx != src) {
908 /*
909 ** This would be caused by a faulty implementation of the client
910 ** library.
911 */
912 return BadMatch8;
913 }
914 /*
915 ** In this case, glXCopyContext is in both GL and X streams, in terms
916 ** of sequentiality.
917 */
918 if (__glXForceCurrent(cl, tag, &error)) {
919 /*
920 ** Do whatever is needed to make sure that all preceding requests
921 ** in both streams are completed before the copy is executed.
922 */
923 glFinish();
924 }
925 else {
926 return error;
927 }
928 }
929 /*
930 ** Issue copy. The only reason for failure is a bad mask.
931 */
932 if (!(*dst->copy) (dst, src, mask)) {
933 client->errorValue = mask;
934 return BadValue2;
935 }
936 return Success0;
937}
938
939enum {
940 GLX_VIS_CONFIG_UNPAIRED = 18,
941 GLX_VIS_CONFIG_PAIRED = 22
942};
943
944enum {
945 GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
946};
947
948int
949__glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc)
950{
951 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
952 ClientPtr client = cl->client;
953 xGLXGetVisualConfigsReply reply;
954 __GLXscreen *pGlxScreen;
955 __GLXconfig *modes;
956 CARD32 buf[GLX_VIS_CONFIG_TOTAL];
957 int p, i, err;
958
959 __GLX_DECLARE_SWAP_VARIABLESGLbyte sw;
960 __GLX_DECLARE_SWAP_ARRAY_VARIABLESGLbyte *swapPC; GLbyte *swapEnd;
961
962 REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq)if ((sizeof(xGLXGetVisualConfigsReq) >> 2) != client->
req_len) return(16)
;
963
964 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
965 return err;
966
967 reply = (xGLXGetVisualConfigsReply) {
968 .type = X_Reply1,
969 .sequenceNumber = client->sequence,
970 .length = (pGlxScreen->numVisuals *
971 __GLX_SIZE_CARD324 * GLX_VIS_CONFIG_TOTAL) >> 2,
972 .numVisuals = pGlxScreen->numVisuals,
973 .numProps = GLX_VIS_CONFIG_TOTAL
974 };
975
976 if (client->swapped) {
977 __GLX_SWAP_SHORT(&reply.sequenceNumber)sw = ((GLbyte *)(&reply.sequenceNumber))[0]; ((GLbyte *)(
&reply.sequenceNumber))[0] = ((GLbyte *)(&reply.sequenceNumber
))[1]; ((GLbyte *)(&reply.sequenceNumber))[1] = sw;
;
978 __GLX_SWAP_INT(&reply.length)sw = ((GLbyte *)(&reply.length))[0]; ((GLbyte *)(&reply
.length))[0] = ((GLbyte *)(&reply.length))[3]; ((GLbyte *
)(&reply.length))[3] = sw; sw = ((GLbyte *)(&reply.length
))[1]; ((GLbyte *)(&reply.length))[1] = ((GLbyte *)(&
reply.length))[2]; ((GLbyte *)(&reply.length))[2] = sw;
;
979 __GLX_SWAP_INT(&reply.numVisuals)sw = ((GLbyte *)(&reply.numVisuals))[0]; ((GLbyte *)(&
reply.numVisuals))[0] = ((GLbyte *)(&reply.numVisuals))[3
]; ((GLbyte *)(&reply.numVisuals))[3] = sw; sw = ((GLbyte
*)(&reply.numVisuals))[1]; ((GLbyte *)(&reply.numVisuals
))[1] = ((GLbyte *)(&reply.numVisuals))[2]; ((GLbyte *)(&
reply.numVisuals))[2] = sw;
;
980 __GLX_SWAP_INT(&reply.numProps)sw = ((GLbyte *)(&reply.numProps))[0]; ((GLbyte *)(&reply
.numProps))[0] = ((GLbyte *)(&reply.numProps))[3]; ((GLbyte
*)(&reply.numProps))[3] = sw; sw = ((GLbyte *)(&reply
.numProps))[1]; ((GLbyte *)(&reply.numProps))[1] = ((GLbyte
*)(&reply.numProps))[2]; ((GLbyte *)(&reply.numProps
))[2] = sw;
;
981 }
982
983 WriteToClient(client, sz_xGLXGetVisualConfigsReply32, &reply);
984
985 for (i = 0; i < pGlxScreen->numVisuals; i++) {
986 modes = pGlxScreen->visuals[i];
987
988 p = 0;
989 buf[p++] = modes->visualID;
990 buf[p++] = glxConvertToXVisualType(modes->visualType);
991 buf[p++] = (modes->renderType & GLX_RGBA_BIT0x00000001) ? GL_TRUE0x1 : GL_FALSE0x0;
992
993 buf[p++] = modes->redBits;
994 buf[p++] = modes->greenBits;
995 buf[p++] = modes->blueBits;
996 buf[p++] = modes->alphaBits;
997 buf[p++] = modes->accumRedBits;
998 buf[p++] = modes->accumGreenBits;
999 buf[p++] = modes->accumBlueBits;
1000 buf[p++] = modes->accumAlphaBits;
1001
1002 buf[p++] = modes->doubleBufferMode;
1003 buf[p++] = modes->stereoMode;
1004
1005 buf[p++] = modes->rgbBits;
1006 buf[p++] = modes->depthBits;
1007 buf[p++] = modes->stencilBits;
1008 buf[p++] = modes->numAuxBuffers;
1009 buf[p++] = modes->level;
1010
1011 assert(p == GLX_VIS_CONFIG_UNPAIRED)(__builtin_expect(!(p == GLX_VIS_CONFIG_UNPAIRED), 0) ? __assert_rtn
(__func__, "glxcmds.c", 1011, "p == GLX_VIS_CONFIG_UNPAIRED")
: (void)0)
;
1012 /*
1013 ** Add token/value pairs for extensions.
1014 */
1015 buf[p++] = GLX_VISUAL_CAVEAT_EXT0x20;
1016 buf[p++] = modes->visualRating;
1017 buf[p++] = GLX_TRANSPARENT_TYPE0x23;
1018 buf[p++] = modes->transparentPixel;
1019 buf[p++] = GLX_TRANSPARENT_RED_VALUE0x25;
1020 buf[p++] = modes->transparentRed;
1021 buf[p++] = GLX_TRANSPARENT_GREEN_VALUE0x26;
1022 buf[p++] = modes->transparentGreen;
1023 buf[p++] = GLX_TRANSPARENT_BLUE_VALUE0x27;
1024 buf[p++] = modes->transparentBlue;
1025 buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE0x28;
1026 buf[p++] = modes->transparentAlpha;
1027 buf[p++] = GLX_TRANSPARENT_INDEX_VALUE0x24;
1028 buf[p++] = modes->transparentIndex;
1029 buf[p++] = GLX_SAMPLES_SGIS100001;
1030 buf[p++] = modes->samples;
1031 buf[p++] = GLX_SAMPLE_BUFFERS_SGIS100000;
1032 buf[p++] = modes->sampleBuffers;
1033 /* Add attribute only if its value is not default. */
1034 if (modes->sRGBCapable != GL_FALSE0x0) {
1035 buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT0x20B2;
1036 buf[p++] = modes->sRGBCapable;
1037 }
1038 /* Don't add visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)?
1039 * Pad the remaining place with zeroes, so that attributes count is constant. */
1040 while (p < GLX_VIS_CONFIG_TOTAL) {
1041 buf[p++] = 0;
1042 buf[p++] = 0;
1043 }
1044
1045 assert(p == GLX_VIS_CONFIG_TOTAL)(__builtin_expect(!(p == GLX_VIS_CONFIG_TOTAL), 0) ? __assert_rtn
(__func__, "glxcmds.c", 1045, "p == GLX_VIS_CONFIG_TOTAL") : (
void)0)
;
1046 if (client->swapped) {
1047 __GLX_SWAP_INT_ARRAY(buf, p)swapPC = ((GLbyte *)(buf)); swapEnd = ((GLbyte *)(buf)) + (p)
*4; while (swapPC < swapEnd) { sw = ((GLbyte *)(swapPC))[0
]; ((GLbyte *)(swapPC))[0] = ((GLbyte *)(swapPC))[3]; ((GLbyte
*)(swapPC))[3] = sw; sw = ((GLbyte *)(swapPC))[1]; ((GLbyte *
)(swapPC))[1] = ((GLbyte *)(swapPC))[2]; ((GLbyte *)(swapPC))
[2] = sw;; swapPC += 4; }
;
1048 }
1049 WriteToClient(client, __GLX_SIZE_CARD324 * p, buf);
1050 }
1051 return Success0;
1052}
1053
1054#define __GLX_TOTAL_FBCONFIG_ATTRIBS(44) (44)
1055#define __GLX_FBCONFIG_ATTRIBS_LENGTH((44) * 2) (__GLX_TOTAL_FBCONFIG_ATTRIBS(44) * 2)
1056/**
1057 * Send the set of GLXFBConfigs to the client. There is not currently
1058 * and interface into the driver on the server-side to get GLXFBConfigs,
1059 * so we "invent" some based on the \c __GLXvisualConfig structures that
1060 * the driver does supply.
1061 *
1062 * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
1063 * is the same, so this routine pulls double duty.
1064 */
1065
1066static int
1067DoGetFBConfigs(__GLXclientState * cl, unsigned screen)
1068{
1069 ClientPtr client = cl->client;
1070 xGLXGetFBConfigsReply reply;
1071 __GLXscreen *pGlxScreen;
1072 CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH((44) * 2)];
1073 int p, err;
1074 __GLXconfig *modes;
1075
1076 __GLX_DECLARE_SWAP_VARIABLESGLbyte sw;
1077 __GLX_DECLARE_SWAP_ARRAY_VARIABLESGLbyte *swapPC; GLbyte *swapEnd;
1078
1079 if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
1080 return err;
1081
1082 reply = (xGLXGetFBConfigsReply) {
1083 .type = X_Reply1,
1084 .sequenceNumber = client->sequence,
1085 .length = __GLX_FBCONFIG_ATTRIBS_LENGTH((44) * 2) * pGlxScreen->numFBConfigs,
1086 .numFBConfigs = pGlxScreen->numFBConfigs,
1087 .numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS(44)
1088 };
1089
1090 if (client->swapped) {
1091 __GLX_SWAP_SHORT(&reply.sequenceNumber)sw = ((GLbyte *)(&reply.sequenceNumber))[0]; ((GLbyte *)(
&reply.sequenceNumber))[0] = ((GLbyte *)(&reply.sequenceNumber
))[1]; ((GLbyte *)(&reply.sequenceNumber))[1] = sw;
;
1092 __GLX_SWAP_INT(&reply.length)sw = ((GLbyte *)(&reply.length))[0]; ((GLbyte *)(&reply
.length))[0] = ((GLbyte *)(&reply.length))[3]; ((GLbyte *
)(&reply.length))[3] = sw; sw = ((GLbyte *)(&reply.length
))[1]; ((GLbyte *)(&reply.length))[1] = ((GLbyte *)(&
reply.length))[2]; ((GLbyte *)(&reply.length))[2] = sw;
;
1093 __GLX_SWAP_INT(&reply.numFBConfigs)sw = ((GLbyte *)(&reply.numFBConfigs))[0]; ((GLbyte *)(&
reply.numFBConfigs))[0] = ((GLbyte *)(&reply.numFBConfigs
))[3]; ((GLbyte *)(&reply.numFBConfigs))[3] = sw; sw = ((
GLbyte *)(&reply.numFBConfigs))[1]; ((GLbyte *)(&reply
.numFBConfigs))[1] = ((GLbyte *)(&reply.numFBConfigs))[2]
; ((GLbyte *)(&reply.numFBConfigs))[2] = sw;
;
1094 __GLX_SWAP_INT(&reply.numAttribs)sw = ((GLbyte *)(&reply.numAttribs))[0]; ((GLbyte *)(&
reply.numAttribs))[0] = ((GLbyte *)(&reply.numAttribs))[3
]; ((GLbyte *)(&reply.numAttribs))[3] = sw; sw = ((GLbyte
*)(&reply.numAttribs))[1]; ((GLbyte *)(&reply.numAttribs
))[1] = ((GLbyte *)(&reply.numAttribs))[2]; ((GLbyte *)(&
reply.numAttribs))[2] = sw;
;
1095 }
1096
1097 WriteToClient(client, sz_xGLXGetFBConfigsReply32, &reply);
1098
1099 for (modes = pGlxScreen->fbconfigs; modes != NULL((void*)0); modes = modes->next) {
1100 p = 0;
1101
1102#define WRITE_PAIR(tag,value)do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) \
1103 do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
1104
1105 WRITE_PAIR(GLX_VISUAL_ID, modes->visualID)do { buf[p++] = 0x800B ; buf[p++] = modes->visualID ; } while
( 0 )
;
1106 WRITE_PAIR(GLX_FBCONFIG_ID, modes->fbconfigID)do { buf[p++] = 0x8013 ; buf[p++] = modes->fbconfigID ; } while
( 0 )
;
1107 WRITE_PAIR(GLX_X_RENDERABLE, GL_TRUE)do { buf[p++] = 0x8012 ; buf[p++] = 0x1 ; } while( 0 );
1108
1109 WRITE_PAIR(GLX_RGBA,do { buf[p++] = 4 ; buf[p++] = (modes->renderType & 0x00000001
) ? 0x1 : 0x0 ; } while( 0 )
1110 (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE)do { buf[p++] = 4 ; buf[p++] = (modes->renderType & 0x00000001
) ? 0x1 : 0x0 ; } while( 0 )
;
1111 WRITE_PAIR(GLX_RENDER_TYPE, modes->renderType)do { buf[p++] = 0x8011 ; buf[p++] = modes->renderType ; } while
( 0 )
;
1112 WRITE_PAIR(GLX_DOUBLEBUFFER, modes->doubleBufferMode)do { buf[p++] = 5 ; buf[p++] = modes->doubleBufferMode ; }
while( 0 )
;
1113 WRITE_PAIR(GLX_STEREO, modes->stereoMode)do { buf[p++] = 6 ; buf[p++] = modes->stereoMode ; } while
( 0 )
;
1114
1115 WRITE_PAIR(GLX_BUFFER_SIZE, modes->rgbBits)do { buf[p++] = 2 ; buf[p++] = modes->rgbBits ; } while( 0
)
;
1116 WRITE_PAIR(GLX_LEVEL, modes->level)do { buf[p++] = 3 ; buf[p++] = modes->level ; } while( 0 );
1117 WRITE_PAIR(GLX_AUX_BUFFERS, modes->numAuxBuffers)do { buf[p++] = 7 ; buf[p++] = modes->numAuxBuffers ; } while
( 0 )
;
1118 WRITE_PAIR(GLX_RED_SIZE, modes->redBits)do { buf[p++] = 8 ; buf[p++] = modes->redBits ; } while( 0
)
;
1119 WRITE_PAIR(GLX_GREEN_SIZE, modes->greenBits)do { buf[p++] = 9 ; buf[p++] = modes->greenBits ; } while(
0 )
;
1120 WRITE_PAIR(GLX_BLUE_SIZE, modes->blueBits)do { buf[p++] = 10 ; buf[p++] = modes->blueBits ; } while(
0 )
;
1121 WRITE_PAIR(GLX_ALPHA_SIZE, modes->alphaBits)do { buf[p++] = 11 ; buf[p++] = modes->alphaBits ; } while
( 0 )
;
1122 WRITE_PAIR(GLX_ACCUM_RED_SIZE, modes->accumRedBits)do { buf[p++] = 14 ; buf[p++] = modes->accumRedBits ; } while
( 0 )
;
1123 WRITE_PAIR(GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits)do { buf[p++] = 15 ; buf[p++] = modes->accumGreenBits ; } while
( 0 )
;
1124 WRITE_PAIR(GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits)do { buf[p++] = 16 ; buf[p++] = modes->accumBlueBits ; } while
( 0 )
;
1125 WRITE_PAIR(GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits)do { buf[p++] = 17 ; buf[p++] = modes->accumAlphaBits ; } while
( 0 )
;
1126 WRITE_PAIR(GLX_DEPTH_SIZE, modes->depthBits)do { buf[p++] = 12 ; buf[p++] = modes->depthBits ; } while
( 0 )
;
1127 WRITE_PAIR(GLX_STENCIL_SIZE, modes->stencilBits)do { buf[p++] = 13 ; buf[p++] = modes->stencilBits ; } while
( 0 )
;
1128 WRITE_PAIR(GLX_X_VISUAL_TYPE, modes->visualType)do { buf[p++] = 0x22 ; buf[p++] = modes->visualType ; } while
( 0 )
;
1129 WRITE_PAIR(GLX_CONFIG_CAVEAT, modes->visualRating)do { buf[p++] = 0x20 ; buf[p++] = modes->visualRating ; } while
( 0 )
;
1130 WRITE_PAIR(GLX_TRANSPARENT_TYPE, modes->transparentPixel)do { buf[p++] = 0x23 ; buf[p++] = modes->transparentPixel ;
} while( 0 )
;
1131 WRITE_PAIR(GLX_TRANSPARENT_RED_VALUE, modes->transparentRed)do { buf[p++] = 0x25 ; buf[p++] = modes->transparentRed ; }
while( 0 )
;
1132 WRITE_PAIR(GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen)do { buf[p++] = 0x26 ; buf[p++] = modes->transparentGreen ;
} while( 0 )
;
1133 WRITE_PAIR(GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue)do { buf[p++] = 0x27 ; buf[p++] = modes->transparentBlue ;
} while( 0 )
;
1134 WRITE_PAIR(GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha)do { buf[p++] = 0x28 ; buf[p++] = modes->transparentAlpha ;
} while( 0 )
;
1135 WRITE_PAIR(GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex)do { buf[p++] = 0x24 ; buf[p++] = modes->transparentIndex ;
} while( 0 )
;
1136 WRITE_PAIR(GLX_SWAP_METHOD_OML, modes->swapMethod)do { buf[p++] = 0x8060 ; buf[p++] = modes->swapMethod ; } while
( 0 )
;
1137 WRITE_PAIR(GLX_SAMPLES_SGIS, modes->samples)do { buf[p++] = 100001 ; buf[p++] = modes->samples ; } while
( 0 )
;
1138 WRITE_PAIR(GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers)do { buf[p++] = 100000 ; buf[p++] = modes->sampleBuffers ;
} while( 0 )
;
1139 WRITE_PAIR(GLX_VISUAL_SELECT_GROUP_SGIX, modes->visualSelectGroup)do { buf[p++] = 0x8028 ; buf[p++] = modes->visualSelectGroup
; } while( 0 )
;
1140 WRITE_PAIR(GLX_DRAWABLE_TYPE, modes->drawableType)do { buf[p++] = 0x8010 ; buf[p++] = modes->drawableType ; }
while( 0 )
;
1141 WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb)do { buf[p++] = 0x20D0 ; buf[p++] = modes->bindToTextureRgb
; } while( 0 )
;
1142 WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba)do { buf[p++] = 0x20D1 ; buf[p++] = modes->bindToTextureRgba
; } while( 0 )
;
1143 WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture)do { buf[p++] = 0x20D2 ; buf[p++] = modes->bindToMipmapTexture
; } while( 0 )
;
1144 WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT,do { buf[p++] = 0x20D3 ; buf[p++] = modes->bindToTextureTargets
; } while( 0 )
1145 modes->bindToTextureTargets)do { buf[p++] = 0x20D3 ; buf[p++] = modes->bindToTextureTargets
; } while( 0 )
;
1146 /* can't report honestly until mesa is fixed */
1147 WRITE_PAIR(GLX_Y_INVERTED_EXT, GLX_DONT_CARE)do { buf[p++] = 0x20D4 ; buf[p++] = 0xFFFFFFFF ; } while( 0 );
1148 if (modes->drawableType & GLX_PBUFFER_BIT0x00000004) {
1149 WRITE_PAIR(GLX_MAX_PBUFFER_WIDTH, modes->maxPbufferWidth)do { buf[p++] = 0x8016 ; buf[p++] = modes->maxPbufferWidth
; } while( 0 )
;
1150 WRITE_PAIR(GLX_MAX_PBUFFER_HEIGHT, modes->maxPbufferHeight)do { buf[p++] = 0x8017 ; buf[p++] = modes->maxPbufferHeight
; } while( 0 )
;
1151 WRITE_PAIR(GLX_MAX_PBUFFER_PIXELS, modes->maxPbufferPixels)do { buf[p++] = 0x8018 ; buf[p++] = modes->maxPbufferPixels
; } while( 0 )
;
1152 WRITE_PAIR(GLX_OPTIMAL_PBUFFER_WIDTH_SGIX,do { buf[p++] = 0x8019 ; buf[p++] = modes->optimalPbufferWidth
; } while( 0 )
1153 modes->optimalPbufferWidth)do { buf[p++] = 0x8019 ; buf[p++] = modes->optimalPbufferWidth
; } while( 0 )
;
1154 WRITE_PAIR(GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX,do { buf[p++] = 0x801A ; buf[p++] = modes->optimalPbufferHeight
; } while( 0 )
1155 modes->optimalPbufferHeight)do { buf[p++] = 0x801A ; buf[p++] = modes->optimalPbufferHeight
; } while( 0 )
;
1156 }
1157 /* Add attribute only if its value is not default. */
1158 if (modes->sRGBCapable != GL_FALSE0x0) {
1159 WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable)do { buf[p++] = 0x20B2 ; buf[p++] = modes->sRGBCapable ; }
while( 0 )
;
1160 }
1161 /* Pad the remaining place with zeroes, so that attributes count is constant. */
1162 while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH((44) * 2)) {
1163 WRITE_PAIR(0, 0)do { buf[p++] = 0 ; buf[p++] = 0 ; } while( 0 );
1164 }
1165 assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH)(__builtin_expect(!(p == ((44) * 2)), 0) ? __assert_rtn(__func__
, "glxcmds.c", 1165, "p == __GLX_FBCONFIG_ATTRIBS_LENGTH") : (
void)0)
;
1166
1167 if (client->swapped) {
1168 __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH)swapPC = ((GLbyte *)(buf)); swapEnd = ((GLbyte *)(buf)) + (((
44) * 2))*4; while (swapPC < swapEnd) { sw = ((GLbyte *)(swapPC
))[0]; ((GLbyte *)(swapPC))[0] = ((GLbyte *)(swapPC))[3]; ((GLbyte
*)(swapPC))[3] = sw; sw = ((GLbyte *)(swapPC))[1]; ((GLbyte *
)(swapPC))[1] = ((GLbyte *)(swapPC))[2]; ((GLbyte *)(swapPC))
[2] = sw;; swapPC += 4; }
;
1169 }
1170 WriteToClient(client, __GLX_SIZE_CARD324 * __GLX_FBCONFIG_ATTRIBS_LENGTH((44) * 2),
1171 (char *) buf);
1172 }
1173 return Success0;
1174}
1175
1176int
1177__glXDisp_GetFBConfigs(__GLXclientState * cl, GLbyte * pc)
1178{
1179 ClientPtr client = cl->client;
1180 xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
1181
1182 REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq)if ((sizeof(xGLXGetFBConfigsReq) >> 2) != client->req_len
) return(16)
;
1183 return DoGetFBConfigs(cl, req->screen);
1184}
1185
1186int
1187__glXDisp_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
1188{
1189 ClientPtr client = cl->client;
1190 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
1191
1192 /* work around mesa bug, don't use REQUEST_SIZE_MATCH */
1193 REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq)if ((sizeof(xGLXGetFBConfigsSGIXReq) >> 2) > client->
req_len ) return(16)
;
1194 return DoGetFBConfigs(cl, req->screen);
1195}
1196
1197GLboolean
1198__glXDrawableInit(__GLXdrawable * drawable,
1199 __GLXscreen * screen, DrawablePtr pDraw, int type,
1200 XID drawId, __GLXconfig * config)
1201{
1202 drawable->pDraw = pDraw;
1203 drawable->type = type;
1204 drawable->drawId = drawId;
1205 drawable->config = config;
1206 drawable->eventMask = 0;
1207
1208 return GL_TRUE0x1;
1209}
1210
1211void
1212__glXDrawableRelease(__GLXdrawable * drawable)
1213{
1214}
1215
1216static int
1217DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen,
1218 __GLXconfig * config, DrawablePtr pDraw, XID drawableId,
1219 XID glxDrawableId, int type)
1220{
1221 __GLXdrawable *pGlxDraw;
1222
1223 if (pGlxScreen->pScreen != pDraw->pScreen)
1224 return BadMatch8;
1225
1226 pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
1227 drawableId, type,
1228 glxDrawableId, config);
1229 if (pGlxDraw == NULL((void*)0))
1230 return BadAlloc11;
1231
1232 if (!AddResourceDarwin_X_AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw))
1233 return BadAlloc11;
1234
1235 /*
1236 * Windows aren't refcounted, so track both the X and the GLX window
1237 * so we get called regardless of destruction order.
1238 */
1239 if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW &&
1240 !AddResourceDarwin_X_AddResource(pDraw->id, __glXDrawableRes, pGlxDraw))
1241 return BadAlloc11;
1242
1243 return Success0;
1244}
1245
1246static int
1247DoCreateGLXPixmap(ClientPtr client, __GLXscreen * pGlxScreen,
1248 __GLXconfig * config, XID drawableId, XID glxDrawableId)
1249{
1250 DrawablePtr pDraw;
1251 int err;
1252
1253 LEGAL_NEW_RESOURCE(glxDrawableId, client)if (!LegalNewID(glxDrawableId,client)) { client->errorValue
= glxDrawableId; return 14; }
;
1254
1255 err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess(1<<12));
1256 if (err != Success0) {
1257 client->errorValue = drawableId;
1258 return err;
1259 }
1260 if (pDraw->type != DRAWABLE_PIXMAP1) {
1261 client->errorValue = drawableId;
1262 return BadPixmap4;
1263 }
1264
1265 err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
1266 glxDrawableId, GLX_DRAWABLE_PIXMAP);
1267
1268 if (err == Success0)
1269 ((PixmapPtr) pDraw)->refcnt++;
1270
1271 return err;
1272}
1273
1274static void
1275determineTextureTarget(ClientPtr client, XID glxDrawableID,
1276 CARD32 *attribs, CARD32 numAttribs)
1277{
1278 GLenum target = 0;
1279 GLenum format = 0;
1280 int i, err;
1281 __GLXdrawable *pGlxDraw;
1282
1283 if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
1284 DixWriteAccess(1<<1), &pGlxDraw, &err))
1285 /* We just added it in CreatePixmap, so we should never get here. */
1286 return;
1287
1288 for (i = 0; i < numAttribs; i++) {
1289 if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT0x20D6) {
1290 switch (attribs[2 * i + 1]) {
1291 case GLX_TEXTURE_2D_EXT0x20DC:
1292 target = GL_TEXTURE_2D0x0DE1;
1293 break;
1294 case GLX_TEXTURE_RECTANGLE_EXT0x20DD:
1295 target = GL_TEXTURE_RECTANGLE_ARB0x84F5;
1296 break;
1297 }
1298 }
1299
1300 if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT0x20D5)
1301 format = attribs[2 * i + 1];
1302 }
1303
1304 if (!target) {
1305 int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
1306
1307 if (h & (h - 1) || w & (w - 1))
1308 target = GL_TEXTURE_RECTANGLE_ARB0x84F5;
1309 else
1310 target = GL_TEXTURE_2D0x0DE1;
1311 }
1312
1313 pGlxDraw->target = target;
1314 pGlxDraw->format = format;
1315}
1316
1317int
1318__glXDisp_CreateGLXPixmap(__GLXclientState * cl, GLbyte * pc)
1319{
1320 ClientPtr client = cl->client;
1321 xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
1322 __GLXconfig *config;
1323 __GLXscreen *pGlxScreen;
1324 int err;
1325
1326 REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq)if ((sizeof(xGLXCreateGLXPixmapReq) >> 2) != client->
req_len) return(16)
;
1327
1328 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1329 return err;
1330 if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
1331 return err;
1332
1333 return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
1334 req->pixmap, req->glxpixmap);
1335}
1336
1337int
1338__glXDisp_CreatePixmap(__GLXclientState * cl, GLbyte * pc)
1339{
1340 ClientPtr client = cl->client;
1341 xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
1342 __GLXconfig *config;
1343 __GLXscreen *pGlxScreen;
1344 int err;
1345
1346 REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq)if ((sizeof(xGLXCreatePixmapReq) >> 2) > client->
req_len ) return(16)
;
1347 if (req->numAttribs > (UINT32_MAX4294967295U >> 3)) {
1348 client->errorValue = req->numAttribs;
1349 return BadValue2;
1350 }
1351 REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3)if (((sizeof(xGLXCreatePixmapReq) >> 2) > client->
req_len) || (((req->numAttribs << 3) >> 2) >=
client->req_len) || ((((uint64_t) sizeof(xGLXCreatePixmapReq
) + (req->numAttribs << 3) + 3) >> 2) != (uint64_t
) client->req_len)) return(16)
;
1352
1353 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1354 return err;
1355 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
1356 return err;
1357
1358 err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
1359 req->pixmap, req->glxpixmap);
1360 if (err != Success0)
1361 return err;
1362
1363 determineTextureTarget(cl->client, req->glxpixmap,
1364 (CARD32 *) (req + 1), req->numAttribs);
1365
1366 return Success0;
1367}
1368
1369int
1370__glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
1371{
1372 ClientPtr client = cl->client;
1373 xGLXCreateGLXPixmapWithConfigSGIXReq *req =
1374 (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
1375 __GLXconfig *config;
1376 __GLXscreen *pGlxScreen;
1377 int err;
1378
1379 REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq)if ((sizeof(xGLXCreateGLXPixmapWithConfigSGIXReq) >> 2)
!= client->req_len) return(16)
;
1380
1381 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
1382 return err;
1383 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
1384 return err;
1385
1386 return DoCreateGLXPixmap(cl->client, pGlxScreen,
1387 config, req->pixmap, req->glxpixmap);
1388}
1389
1390static int
1391DoDestroyDrawable(__GLXclientState * cl, XID glxdrawable, int type)
1392{
1393 __GLXdrawable *pGlxDraw;
1394 int err;
1395
1396 if (!validGlxDrawable(cl->client, glxdrawable, type,
1397 DixDestroyAccess(1<<2), &pGlxDraw, &err))
1398 return err;
1399
1400 FreeResource(glxdrawable, FALSE0);
1401
1402 return Success0;
1403}
1404
1405int
1406__glXDisp_DestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc)
1407{
1408 ClientPtr client = cl->client;
1409 xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
1410
1411 REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq)if ((sizeof(xGLXDestroyGLXPixmapReq) >> 2) != client->
req_len) return(16)
;
1412
1413 return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
1414}
1415
1416int
1417__glXDisp_DestroyPixmap(__GLXclientState * cl, GLbyte * pc)
1418{
1419 ClientPtr client = cl->client;
1420 xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
1421
1422 /* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set
1423 * length to 3 instead of 2 */
1424 REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq)if ((sizeof(xGLXDestroyPixmapReq) >> 2) > client->
req_len ) return(16)
;
1425
1426 return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
1427}
1428
1429static int
1430DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
1431 int width, int height, XID glxDrawableId)
1432{
1433 __GLXconfig *config;
1434 __GLXscreen *pGlxScreen;
1435 PixmapPtr pPixmap;
1436 int err;
1437
1438 LEGAL_NEW_RESOURCE(glxDrawableId, client)if (!LegalNewID(glxDrawableId,client)) { client->errorValue
= glxDrawableId; return 14; }
;
1439
1440 if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
1441 return err;
1442 if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
1443 return err;
1444
1445 __glXenterServer(GL_FALSE0x0);
1446 pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
1447 width, height,
1448 config->rgbBits, 0);
1449 __glXleaveServer(GL_FALSE0x0);
1450 if (!pPixmap)
1451 return BadAlloc11;
1452
1453 /* Assign the pixmap the same id as the pbuffer and add it as a
1454 * resource so it and the DRI2 drawable will be reclaimed when the
1455 * pbuffer is destroyed. */
1456 pPixmap->drawable.id = glxDrawableId;
1457 if (!AddResourceDarwin_X_AddResource(pPixmap->drawable.id, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), pPixmap))
1458 return BadAlloc11;
1459
1460 return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
1461 glxDrawableId, glxDrawableId,
1462 GLX_DRAWABLE_PBUFFER);
1463}
1464
1465int
1466__glXDisp_CreatePbuffer(__GLXclientState * cl, GLbyte * pc)
1467{
1468 ClientPtr client = cl->client;
1469 xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
1470 CARD32 *attrs;
1471 int width, height, i;
1472
1473 REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq)if ((sizeof(xGLXCreatePbufferReq) >> 2) > client->
req_len ) return(16)
;
1474 if (req->numAttribs > (UINT32_MAX4294967295U >> 3)) {
1475 client->errorValue = req->numAttribs;
1476 return BadValue2;
1477 }
1478 REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3)if (((sizeof(xGLXCreatePbufferReq) >> 2) > client->
req_len) || (((req->numAttribs << 3) >> 2) >=
client->req_len) || ((((uint64_t) sizeof(xGLXCreatePbufferReq
) + (req->numAttribs << 3) + 3) >> 2) != (uint64_t
) client->req_len)) return(16)
;
1479
1480 attrs = (CARD32 *) (req + 1);
1481 width = 0;
1482 height = 0;
1483
1484 for (i = 0; i < req->numAttribs; i++) {
1485 switch (attrs[i * 2]) {
1486 case GLX_PBUFFER_WIDTH0x8041:
1487 width = attrs[i * 2 + 1];
1488 break;
1489 case GLX_PBUFFER_HEIGHT0x8040:
1490 height = attrs[i * 2 + 1];
1491 break;
1492 case GLX_LARGEST_PBUFFER0x801C:
1493 /* FIXME: huh... */
1494 break;
1495 }
1496 }
1497
1498 return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
1499 width, height, req->pbuffer);
1500}
1501
1502int
1503__glXDisp_CreateGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
1504{
1505 ClientPtr client = cl->client;
1506 xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
1507
1508 REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq)if ((sizeof(xGLXCreateGLXPbufferSGIXReq) >> 2) > client
->req_len ) return(16)
;
1509
1510 /*
1511 * We should really handle attributes correctly, but this extension
1512 * is so rare I have difficulty caring.
1513 */
1514 return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
1515 req->width, req->height, req->pbuffer);
1516}
1517
1518int
1519__glXDisp_DestroyPbuffer(__GLXclientState * cl, GLbyte * pc)
1520{
1521 ClientPtr client = cl->client;
1522 xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
1523
1524 REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq)if ((sizeof(xGLXDestroyPbufferReq) >> 2) != client->
req_len) return(16)
;
1525
1526 return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
1527}
1528
1529int
1530__glXDisp_DestroyGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
1531{
1532 ClientPtr client = cl->client;
1533 xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
1534
1535 REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq)if ((sizeof(xGLXDestroyGLXPbufferSGIXReq) >> 2) != client
->req_len) return(16)
;
1536
1537 return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
1538}
1539
1540static int
1541DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
1542 int numAttribs, CARD32 *attribs)
1543{
1544 __GLXdrawable *pGlxDraw;
1545 int i, err;
1546
1547 if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
1548 DixSetAttrAccess(1<<5), &pGlxDraw, &err))
1549 return err;
1550
1551 for (i = 0; i < numAttribs; i++) {
1552 switch (attribs[i * 2]) {
1553 case GLX_EVENT_MASK0x801F:
1554 /* All we do is to record the event mask so we can send it
1555 * back when queried. We never actually clobber the
1556 * pbuffers, so we never need to send out the event. */
1557 pGlxDraw->eventMask = attribs[i * 2 + 1];
1558 break;
1559 }
1560 }
1561
1562 return Success0;
1563}
1564
1565int
1566__glXDisp_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
1567{
1568 ClientPtr client = cl->client;
1569 xGLXChangeDrawableAttributesReq *req =
1570 (xGLXChangeDrawableAttributesReq *) pc;
1571
1572 REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq)if ((sizeof(xGLXChangeDrawableAttributesReq) >> 2) >
client->req_len ) return(16)
;
1573 if (req->numAttribs > (UINT32_MAX4294967295U >> 3)) {
1574 client->errorValue = req->numAttribs;
1575 return BadValue2;
1576 }
1577#if 0
1578 /* mesa sends an additional 8 bytes */
1579 REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3)if (((sizeof(xGLXChangeDrawableAttributesReq) >> 2) >
client->req_len) || (((req->numAttribs << 3) >>
2) >= client->req_len) || ((((uint64_t) sizeof(xGLXChangeDrawableAttributesReq
) + (req->numAttribs << 3) + 3) >> 2) != (uint64_t
) client->req_len)) return(16)
;
1580#else
1581 if (((sizeof(xGLXChangeDrawableAttributesReq) +
1582 (req->numAttribs << 3)) >> 2) < client->req_len)
1583 return BadLength16;
1584#endif
1585
1586 return DoChangeDrawableAttributes(cl->client, req->drawable,
1587 req->numAttribs, (CARD32 *) (req + 1));
1588}
1589
1590int
1591__glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
1592{
1593 ClientPtr client = cl->client;
1594 xGLXChangeDrawableAttributesSGIXReq *req =
1595 (xGLXChangeDrawableAttributesSGIXReq *) pc;
1596
1597 REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq)if ((sizeof(xGLXChangeDrawableAttributesSGIXReq) >> 2) >
client->req_len ) return(16)
;
1598 if (req->numAttribs > (UINT32_MAX4294967295U >> 3)) {
1599 client->errorValue = req->numAttribs;
1600 return BadValue2;
1601 }
1602 REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq,if (((sizeof(xGLXChangeDrawableAttributesSGIXReq) >> 2)
> client->req_len) || (((req->numAttribs << 3
) >> 2) >= client->req_len) || ((((uint64_t) sizeof
(xGLXChangeDrawableAttributesSGIXReq) + (req->numAttribs <<
3) + 3) >> 2) != (uint64_t) client->req_len)) return
(16)
1603 req->numAttribs << 3)if (((sizeof(xGLXChangeDrawableAttributesSGIXReq) >> 2)
> client->req_len) || (((req->numAttribs << 3
) >> 2) >= client->req_len) || ((((uint64_t) sizeof
(xGLXChangeDrawableAttributesSGIXReq) + (req->numAttribs <<
3) + 3) >> 2) != (uint64_t) client->req_len)) return
(16)
;
1604
1605 return DoChangeDrawableAttributes(cl->client, req->drawable,
1606 req->numAttribs, (CARD32 *) (req + 1));
1607}
1608
1609int
1610__glXDisp_CreateWindow(__GLXclientState * cl, GLbyte * pc)
1611{
1612 xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
1613 __GLXconfig *config;
1614 __GLXscreen *pGlxScreen;
1615 ClientPtr client = cl->client;
1616 DrawablePtr pDraw;
1617 int err;
1618
1619 REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq)if ((sizeof(xGLXCreateWindowReq) >> 2) > client->
req_len ) return(16)
;
1620 if (req->numAttribs > (UINT32_MAX4294967295U >> 3)) {
1
Taking false branch
1621 client->errorValue = req->numAttribs;
1622 return BadValue2;
1623 }
1624 REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3)if (((sizeof(xGLXCreateWindowReq) >> 2) > client->
req_len) || (((req->numAttribs << 3) >> 2) >=
client->req_len) || ((((uint64_t) sizeof(xGLXCreateWindowReq
) + (req->numAttribs << 3) + 3) >> 2) != (uint64_t
) client->req_len)) return(16)
;
1625
1626 LEGAL_NEW_RESOURCE(req->glxwindow, client)if (!LegalNewID(req->glxwindow,client)) { client->errorValue
= req->glxwindow; return 14; }
;
1627
1628 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
2
Taking false branch
1629 return err;
1630 if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
3
Taking false branch
1631 return err;
1632
1633 err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess(1<<12));
1634 if (err != Success0 || pDraw->type != DRAWABLE_WINDOW0) {
4
Assuming 'err' is equal to 0
5
Taking false branch
1635 client->errorValue = req->window;
1636 return BadWindow3;
1637 }
1638
1639 if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
6
Calling 'validGlxFBConfigForWindow'
1640 return err;
1641
1642 return DoCreateGLXDrawable(client, pGlxScreen, config,
1643 pDraw, req->window,
1644 req->glxwindow, GLX_DRAWABLE_WINDOW);
1645}
1646
1647int
1648__glXDisp_DestroyWindow(__GLXclientState * cl, GLbyte * pc)
1649{
1650 ClientPtr client = cl->client;
1651 xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
1652
1653 /* mesa's glXDestroyWindow used to set length to 3 instead of 2 */
1654 REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq)if ((sizeof(xGLXDestroyWindowReq) >> 2) > client->
req_len ) return(16)
;
1655
1656 return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
1657}
1658
1659/*****************************************************************************/
1660
1661/*
1662** NOTE: There is no portable implementation for swap buffers as of
1663** this time that is of value. Consequently, this code must be
1664** implemented by somebody other than SGI.
1665*/
1666int
1667__glXDisp_SwapBuffers(__GLXclientState * cl, GLbyte * pc)
1668{
1669 ClientPtr client = cl->client;
1670 xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
1671 GLXContextTag tag;
1672 XID drawId;
1673 __GLXcontext *glxc = NULL((void*)0);
1674 __GLXdrawable *pGlxDraw;
1675 int error;
1676
1677 REQUEST_SIZE_MATCH(xGLXSwapBuffersReq)if ((sizeof(xGLXSwapBuffersReq) >> 2) != client->req_len
) return(16)
;
1678
1679 tag = req->contextTag;
1680 drawId = req->drawable;
1681 if (tag) {
1682 glxc = __glXLookupContextByTag(cl, tag);
1683 if (!glxc) {
1684 return __glXError(GLXBadContextTag4);
1685 }
1686 /*
1687 ** The calling thread is swapping its current drawable. In this case,
1688 ** glxSwapBuffers is in both GL and X streams, in terms of
1689 ** sequentiality.
1690 */
1691 if (__glXForceCurrent(cl, tag, &error)) {
1692 /*
1693 ** Do whatever is needed to make sure that all preceding requests
1694 ** in both streams are completed before the swap is executed.
1695 */
1696 glFinish();
1697 }
1698 else {
1699 return error;
1700 }
1701 }
1702
1703 pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
1704 if (pGlxDraw == NULL((void*)0))
1705 return error;
1706
1707 if (pGlxDraw->type == DRAWABLE_WINDOW0 &&
1708 (*pGlxDraw->swapBuffers) (cl->client, pGlxDraw) == GL_FALSE0x0)
1709 return __glXError(GLXBadDrawable2);
1710
1711 return Success0;
1712}
1713
1714static int
1715DoQueryContext(__GLXclientState * cl, GLXContextID gcId)
1716{
1717 ClientPtr client = cl->client;
1718 __GLXcontext *ctx;
1719 xGLXQueryContextInfoEXTReply reply;
1720 int nProps = 3;
1721 int sendBuf[nProps * 2];
1722 int nReplyBytes;
1723 int err;
1724
1725 if (!validGlxContext(cl->client, gcId, DixReadAccess(1<<0), &ctx, &err))
1726 return err;
1727
1728 reply = (xGLXQueryContextInfoEXTReply) {
1729 .type = X_Reply1,
1730 .sequenceNumber = client->sequence,
1731 .length = nProps << 1,
1732 .n = nProps
1733 };
1734
1735 nReplyBytes = reply.length << 2;
1736 sendBuf[0] = GLX_SHARE_CONTEXT_EXT0x800A;
1737 sendBuf[1] = (int) (ctx->share_id);
1738 sendBuf[2] = GLX_VISUAL_ID_EXT0x800B;
1739 sendBuf[3] = (int) (ctx->config->visualID);
1740 sendBuf[4] = GLX_SCREEN_EXT0x800C;
1741 sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum);
1742
1743 if (client->swapped) {
1744 __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
1745 }
1746 else {
1747 WriteToClient(client, sz_xGLXQueryContextInfoEXTReply32, &reply);
1748 WriteToClient(client, nReplyBytes, sendBuf);
1749 }
1750
1751 return Success0;
1752}
1753
1754int
1755__glXDisp_QueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc)
1756{
1757 ClientPtr client = cl->client;
1758 xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
1759
1760 REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq)if ((sizeof(xGLXQueryContextInfoEXTReq) >> 2) != client
->req_len) return(16)
;
1761
1762 return DoQueryContext(cl, req->context);
1763}
1764
1765int
1766__glXDisp_QueryContext(__GLXclientState * cl, GLbyte * pc)
1767{
1768 ClientPtr client = cl->client;
1769 xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
1770
1771 REQUEST_SIZE_MATCH(xGLXQueryContextReq)if ((sizeof(xGLXQueryContextReq) >> 2) != client->req_len
) return(16)
;
1772
1773 return DoQueryContext(cl, req->context);
1774}
1775
1776int
1777__glXDisp_BindTexImageEXT(__GLXclientState * cl, GLbyte * pc)
1778{
1779 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1780 ClientPtr client = cl->client;
1781 __GLXcontext *context;
1782 __GLXdrawable *pGlxDraw;
1783 GLXDrawable drawId;
1784 int buffer;
1785 int error;
1786 CARD32 num_attribs;
1787
1788 if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len)
1789 return BadLength16;
1790
1791 pc += __GLX_VENDPRIV_HDR_SIZE12;
1792
1793 drawId = *((CARD32 *) (pc));
1794 buffer = *((INT32 *) (pc + 4));
1795 num_attribs = *((CARD32 *) (pc + 8));
1796 if (num_attribs > (UINT32_MAX4294967295U >> 3)) {
1797 client->errorValue = num_attribs;
1798 return BadValue2;
1799 }
1800 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 12 + (num_attribs << 3))if (((sizeof(xGLXVendorPrivateReq) >> 2) > client->
req_len) || (((12 + (num_attribs << 3)) >> 2) >=
client->req_len) || ((((uint64_t) sizeof(xGLXVendorPrivateReq
) + (12 + (num_attribs << 3)) + 3) >> 2) != (uint64_t
) client->req_len)) return(16)
;
1801
1802 if (buffer != GLX_FRONT_LEFT_EXT0x20DE)
1803 return __glXError(GLXBadPixmap3);
1804
1805 context = __glXForceCurrent(cl, req->contextTag, &error);
1806 if (!context)
1807 return error;
1808
1809 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
1810 DixReadAccess(1<<0), &pGlxDraw, &error))
1811 return error;
1812
1813 if (!context->textureFromPixmap)
1814 return __glXError(GLXUnsupportedPrivateRequest8);
1815
1816 return context->textureFromPixmap->bindTexImage(context, buffer, pGlxDraw);
1817}
1818
1819int
1820__glXDisp_ReleaseTexImageEXT(__GLXclientState * cl, GLbyte * pc)
1821{
1822 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1823 ClientPtr client = cl->client;
1824 __GLXdrawable *pGlxDraw;
1825 __GLXcontext *context;
1826 GLXDrawable drawId;
1827 int buffer;
1828 int error;
1829
1830 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8)if (((sizeof(xGLXVendorPrivateReq) >> 2) > client->
req_len) || (((8) >> 2) >= client->req_len) || ((
((uint64_t) sizeof(xGLXVendorPrivateReq) + (8) + 3) >> 2
) != (uint64_t) client->req_len)) return(16)
;
1831
1832 pc += __GLX_VENDPRIV_HDR_SIZE12;
1833
1834 drawId = *((CARD32 *) (pc));
1835 buffer = *((INT32 *) (pc + 4));
1836
1837 context = __glXForceCurrent(cl, req->contextTag, &error);
1838 if (!context)
1839 return error;
1840
1841 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
1842 DixReadAccess(1<<0), &pGlxDraw, &error))
1843 return error;
1844
1845 if (!context->textureFromPixmap)
1846 return __glXError(GLXUnsupportedPrivateRequest8);
1847
1848 return context->textureFromPixmap->releaseTexImage(context,
1849 buffer, pGlxDraw);
1850}
1851
1852int
1853__glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc)
1854{
1855 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
1856 GLXContextTag tag = req->contextTag;
1857 __GLXcontext *glxc = NULL((void*)0);
1858 __GLXdrawable *pGlxDraw;
1859 ClientPtr client = cl->client;
1860 GLXDrawable drawId;
1861 int error;
1862 int x, y, width, height;
1863
1864 (void) client;
1865 (void) req;
1866
1867 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20)if (((sizeof(xGLXVendorPrivateReq) >> 2) > client->
req_len) || (((20) >> 2) >= client->req_len) || (
(((uint64_t) sizeof(xGLXVendorPrivateReq) + (20) + 3) >>
2) != (uint64_t) client->req_len)) return(16)
;
1868
1869 pc += __GLX_VENDPRIV_HDR_SIZE12;
1870
1871 drawId = *((CARD32 *) (pc));
1872 x = *((INT32 *) (pc + 4));
1873 y = *((INT32 *) (pc + 8));
1874 width = *((INT32 *) (pc + 12));
1875 height = *((INT32 *) (pc + 16));
1876
1877 if (tag) {
1878 glxc = __glXLookupContextByTag(cl, tag);
1879 if (!glxc) {
1880 return __glXError(GLXBadContextTag4);
1881 }
1882 /*
1883 ** The calling thread is swapping its current drawable. In this case,
1884 ** glxSwapBuffers is in both GL and X streams, in terms of
1885 ** sequentiality.
1886 */
1887 if (__glXForceCurrent(cl, tag, &error)) {
1888 /*
1889 ** Do whatever is needed to make sure that all preceding requests
1890 ** in both streams are completed before the swap is executed.
1891 */
1892 glFinish();
1893 }
1894 else {
1895 return error;
1896 }
1897 }
1898
1899 pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
1900 if (!pGlxDraw)
1901 return error;
1902
1903 if (pGlxDraw == NULL((void*)0) ||
1904 pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
1905 pGlxDraw->copySubBuffer == NULL((void*)0))
1906 return __glXError(GLXBadDrawable2);
1907
1908 (*pGlxDraw->copySubBuffer) (pGlxDraw, x, y, width, height);
1909
1910 return Success0;
1911}
1912
1913/* hack for old glxext.h */
1914#ifndef GLX_STEREO_TREE_EXT0x20F5
1915#define GLX_STEREO_TREE_EXT0x20F5 0x20F5
1916#endif
1917
1918/*
1919** Get drawable attributes
1920*/
1921static int
1922DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
1923{
1924 ClientPtr client = cl->client;
1925 xGLXGetDrawableAttributesReply reply;
1926 __GLXdrawable *pGlxDraw = NULL((void*)0);
1927 DrawablePtr pDraw;
1928 CARD32 attributes[18];
1929 int num = 0, error;
1930
1931 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
1932 DixGetAttrAccess(1<<4), &pGlxDraw, &error)) {
1933 /* hack for GLX 1.2 naked windows */
1934 int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client,
1935 DixGetAttrAccess(1<<4));
1936 if (err != Success0)
1937 return error;
1938 }
1939 if (pGlxDraw)
1940 pDraw = pGlxDraw->pDraw;
1941
1942#define ATTRIB(a, v) do { \
1943 attributes[2*num] = (a); \
1944 attributes[2*num+1] = (v); \
1945 num++; \
1946 } while (0)
1947
1948 ATTRIB(GLX_Y_INVERTED_EXT0x20D4, GL_FALSE0x0);
1949 ATTRIB(GLX_WIDTH0x801D, pDraw->width);
1950 ATTRIB(GLX_HEIGHT0x801E, pDraw->height);
1951 ATTRIB(GLX_SCREEN0x800C, pDraw->pScreen->myNum);
1952 if (pGlxDraw) {
1953 ATTRIB(GLX_TEXTURE_TARGET_EXT0x20D6,
1954 pGlxDraw->target == GL_TEXTURE_2D0x0DE1 ?
1955 GLX_TEXTURE_2D_EXT0x20DC : GLX_TEXTURE_RECTANGLE_EXT0x20DD);
1956 ATTRIB(GLX_EVENT_MASK0x801F, pGlxDraw->eventMask);
1957 ATTRIB(GLX_FBCONFIG_ID0x8013, pGlxDraw->config->fbconfigID);
1958 if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
1959 ATTRIB(GLX_PRESERVED_CONTENTS0x801B, GL_TRUE0x1);
1960 }
1961 if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) {
1962 ATTRIB(GLX_STEREO_TREE_EXT0x20F5, 0);
1963 }
1964 }
1965#undef ATTRIB
1966
1967 reply = (xGLXGetDrawableAttributesReply) {
1968 .type = X_Reply1,
1969 .sequenceNumber = client->sequence,
1970 .length = num << 1,
1971 .numAttribs = num
1972 };
1973
1974 if (client->swapped) {
1975 __glXSwapGetDrawableAttributesReply(client, &reply, attributes);
1976 }
1977 else {
1978 WriteToClient(client, sz_xGLXGetDrawableAttributesReply32, &reply);
1979 WriteToClient(client, reply.length * sizeof(CARD32), attributes);
1980 }
1981
1982 return Success0;
1983}
1984
1985int
1986__glXDisp_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
1987{
1988 ClientPtr client = cl->client;
1989 xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc;
1990
1991 /* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */
1992 REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq)if ((sizeof(xGLXGetDrawableAttributesReq) >> 2) > client
->req_len ) return(16)
;
1993
1994 return DoGetDrawableAttributes(cl, req->drawable);
1995}
1996
1997int
1998__glXDisp_GetDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
1999{
2000 ClientPtr client = cl->client;
2001 xGLXGetDrawableAttributesSGIXReq *req =
2002 (xGLXGetDrawableAttributesSGIXReq *) pc;
2003
2004 REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq)if ((sizeof(xGLXGetDrawableAttributesSGIXReq) >> 2) != client
->req_len) return(16)
;
2005
2006 return DoGetDrawableAttributes(cl, req->drawable);
2007}
2008
2009/************************************************************************/
2010
2011/*
2012** Render and Renderlarge are not in the GLX API. They are used by the GLX
2013** client library to send batches of GL rendering commands.
2014*/
2015
2016/*
2017** Execute all the drawing commands in a request.
2018*/
2019int
2020__glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
2021{
2022 xGLXRenderReq *req;
2023 ClientPtr client = cl->client;
2024 int left, cmdlen, error;
2025 int commandsDone;
2026 CARD16 opcode;
2027 __GLXrenderHeader *hdr;
2028 __GLXcontext *glxc;
2029
2030 __GLX_DECLARE_SWAP_VARIABLESGLbyte sw;
2031
2032 REQUEST_AT_LEAST_SIZE(xGLXRenderReq)if ((sizeof(xGLXRenderReq) >> 2) > client->req_len
) return(16)
;
2033
2034 req = (xGLXRenderReq *) pc;
2035 if (client->swapped) {
2036 __GLX_SWAP_SHORT(&req->length)sw = ((GLbyte *)(&req->length))[0]; ((GLbyte *)(&req
->length))[0] = ((GLbyte *)(&req->length))[1]; ((GLbyte
*)(&req->length))[1] = sw;
;
2037 __GLX_SWAP_INT(&req->contextTag)sw = ((GLbyte *)(&req->contextTag))[0]; ((GLbyte *)(&
req->contextTag))[0] = ((GLbyte *)(&req->contextTag
))[3]; ((GLbyte *)(&req->contextTag))[3] = sw; sw = ((
GLbyte *)(&req->contextTag))[1]; ((GLbyte *)(&req->
contextTag))[1] = ((GLbyte *)(&req->contextTag))[2]; (
(GLbyte *)(&req->contextTag))[2] = sw;
;
2038 }
2039
2040 glxc = __glXForceCurrent(cl, req->contextTag, &error);
2041 if (!glxc) {
2042 return error;
2043 }
2044
2045 commandsDone = 0;
2046 pc += sz_xGLXRenderReq8;
2047 left = (req->length << 2) - sz_xGLXRenderReq8;
2048 while (left > 0) {
2049 __GLXrenderSizeData entry;
2050 int extra = 0;
2051 __GLXdispatchRenderProcPtr proc;
2052 int err;
2053
2054 if (left < sizeof(__GLXrenderHeader))
2055 return BadLength16;
2056
2057 /*
2058 ** Verify that the header length and the overall length agree.
2059 ** Also, each command must be word aligned.
2060 */
2061 hdr = (__GLXrenderHeader *) pc;
2062 if (client->swapped) {
2063 __GLX_SWAP_SHORT(&hdr->length)sw = ((GLbyte *)(&hdr->length))[0]; ((GLbyte *)(&hdr
->length))[0] = ((GLbyte *)(&hdr->length))[1]; ((GLbyte
*)(&hdr->length))[1] = sw;
;
2064 __GLX_SWAP_SHORT(&hdr->opcode)sw = ((GLbyte *)(&hdr->opcode))[0]; ((GLbyte *)(&hdr
->opcode))[0] = ((GLbyte *)(&hdr->opcode))[1]; ((GLbyte
*)(&hdr->opcode))[1] = sw;
;
2065 }
2066 cmdlen = hdr->length;
2067 opcode = hdr->opcode;
2068
2069 if (left < cmdlen)
2070 return BadLength16;
2071
2072 /*
2073 ** Check for core opcodes and grab entry data.
2074 */
2075 err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
2076 proc = (__GLXdispatchRenderProcPtr)
2077 __glXGetProtocolDecodeFunction(&Render_dispatch_info,
2078 opcode, client->swapped);
2079
2080 if ((err < 0) || (proc == NULL((void*)0))) {
2081 client->errorValue = commandsDone;
2082 return __glXError(GLXBadRenderRequest6);
2083 }
2084
2085 if (cmdlen < entry.bytes) {
2086 return BadLength16;
2087 }
2088
2089 if (entry.varsize) {
2090 /* variable size command */
2091 extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE4,
2092 client->swapped,
2093 left - __GLX_RENDER_HDR_SIZE4);
2094 if (extra < 0) {
2095 return BadLength16;
2096 }
2097 }
2098
2099 if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) {
2100 return BadLength16;
2101 }
2102
2103 /*
2104 ** Skip over the header and execute the command. We allow the
2105 ** caller to trash the command memory. This is useful especially
2106 ** for things that require double alignment - they can just shift
2107 ** the data towards lower memory (trashing the header) by 4 bytes
2108 ** and achieve the required alignment.
2109 */
2110 (*proc) (pc + __GLX_RENDER_HDR_SIZE4);
2111 pc += cmdlen;
2112 left -= cmdlen;
2113 commandsDone++;
2114 }
2115 return Success0;
2116}
2117
2118/*
2119** Execute a large rendering request (one that spans multiple X requests).
2120*/
2121int
2122__glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
2123{
2124 xGLXRenderLargeReq *req;
2125 ClientPtr client = cl->client;
2126 size_t dataBytes;
2127 __GLXrenderLargeHeader *hdr;
2128 __GLXcontext *glxc;
2129 int error;
2130 CARD16 opcode;
2131
2132 __GLX_DECLARE_SWAP_VARIABLESGLbyte sw;
2133
2134 REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq)if ((sizeof(xGLXRenderLargeReq) >> 2) > client->req_len
) return(16)
;
2135
2136 req = (xGLXRenderLargeReq *) pc;
2137 if (client->swapped) {
2138 __GLX_SWAP_SHORT(&req->length)sw = ((GLbyte *)(&req->length))[0]; ((GLbyte *)(&req
->length))[0] = ((GLbyte *)(&req->length))[1]; ((GLbyte
*)(&req->length))[1] = sw;
;
2139 __GLX_SWAP_INT(&req->contextTag)sw = ((GLbyte *)(&req->contextTag))[0]; ((GLbyte *)(&
req->contextTag))[0] = ((GLbyte *)(&req->contextTag
))[3]; ((GLbyte *)(&req->contextTag))[3] = sw; sw = ((
GLbyte *)(&req->contextTag))[1]; ((GLbyte *)(&req->
contextTag))[1] = ((GLbyte *)(&req->contextTag))[2]; (
(GLbyte *)(&req->contextTag))[2] = sw;
;
2140 __GLX_SWAP_INT(&req->dataBytes)sw = ((GLbyte *)(&req->dataBytes))[0]; ((GLbyte *)(&
req->dataBytes))[0] = ((GLbyte *)(&req->dataBytes))
[3]; ((GLbyte *)(&req->dataBytes))[3] = sw; sw = ((GLbyte
*)(&req->dataBytes))[1]; ((GLbyte *)(&req->dataBytes
))[1] = ((GLbyte *)(&req->dataBytes))[2]; ((GLbyte *)(
&req->dataBytes))[2] = sw;
;
2141 __GLX_SWAP_SHORT(&req->requestNumber)sw = ((GLbyte *)(&req->requestNumber))[0]; ((GLbyte *)
(&req->requestNumber))[0] = ((GLbyte *)(&req->requestNumber
))[1]; ((GLbyte *)(&req->requestNumber))[1] = sw;
;
2142 __GLX_SWAP_SHORT(&req->requestTotal)sw = ((GLbyte *)(&req->requestTotal))[0]; ((GLbyte *)(
&req->requestTotal))[0] = ((GLbyte *)(&req->requestTotal
))[1]; ((GLbyte *)(&req->requestTotal))[1] = sw;
;
2143 }
2144
2145 glxc = __glXForceCurrent(cl, req->contextTag, &error);
2146 if (!glxc) {
2147 /* Reset in case this isn't 1st request. */
2148 __glXResetLargeCommandStatus(cl);
2149 return error;
2150 }
2151 if (safe_pad(req->dataBytes) < 0)
2152 return BadLength16;
2153 dataBytes = req->dataBytes;
2154
2155 /*
2156 ** Check the request length.
2157 */
2158 if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq16) {
2159 client->errorValue = req->length;
2160 /* Reset in case this isn't 1st request. */
2161 __glXResetLargeCommandStatus(cl);
2162 return BadLength16;
2163 }
2164 pc += sz_xGLXRenderLargeReq16;
2165
2166 if (cl->largeCmdRequestsSoFar == 0) {
2167 __GLXrenderSizeData entry;
2168 int extra = 0;
2169 int left = (req->length << 2) - sz_xGLXRenderLargeReq16;
2170 int cmdlen;
2171 int err;
2172
2173 /*
2174 ** This is the first request of a multi request command.
2175 ** Make enough space in the buffer, then copy the entire request.
2176 */
2177 if (req->requestNumber != 1) {
2178 client->errorValue = req->requestNumber;
2179 return __glXError(GLXBadLargeRequest7);
2180 }
2181
2182 if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE8)
2183 return BadLength16;
2184
2185 hdr = (__GLXrenderLargeHeader *) pc;
2186 if (client->swapped) {
2187 __GLX_SWAP_INT(&hdr->length)sw = ((GLbyte *)(&hdr->length))[0]; ((GLbyte *)(&hdr
->length))[0] = ((GLbyte *)(&hdr->length))[3]; ((GLbyte
*)(&hdr->length))[3] = sw; sw = ((GLbyte *)(&hdr->
length))[1]; ((GLbyte *)(&hdr->length))[1] = ((GLbyte *
)(&hdr->length))[2]; ((GLbyte *)(&hdr->length))
[2] = sw;
;
2188 __GLX_SWAP_INT(&hdr->opcode)sw = ((GLbyte *)(&hdr->opcode))[0]; ((GLbyte *)(&hdr
->opcode))[0] = ((GLbyte *)(&hdr->opcode))[3]; ((GLbyte
*)(&hdr->opcode))[3] = sw; sw = ((GLbyte *)(&hdr->
opcode))[1]; ((GLbyte *)(&hdr->opcode))[1] = ((GLbyte *
)(&hdr->opcode))[2]; ((GLbyte *)(&hdr->opcode))
[2] = sw;
;
2189 }
2190 opcode = hdr->opcode;
2191 if ((cmdlen = safe_pad(hdr->length)) < 0)
2192 return BadLength16;
2193
2194 /*
2195 ** Check for core opcodes and grab entry data.
2196 */
2197 err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
2198 if (err < 0) {
2199 client->errorValue = opcode;
2200 return __glXError(GLXBadLargeRequest7);
2201 }
2202
2203 if (entry.varsize) {
2204 /*
2205 ** If it's a variable-size command (a command whose length must
2206 ** be computed from its parameters), all the parameters needed
2207 ** will be in the 1st request, so it's okay to do this.
2208 */
2209 extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE8,
2210 client->swapped,
2211 left - __GLX_RENDER_LARGE_HDR_SIZE8);
2212 if (extra < 0) {
2213 return BadLength16;
2214 }
2215 }
2216
2217 /* the +4 is safe because we know entry.bytes is small */
2218 if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) {
2219 return BadLength16;
2220 }
2221
2222 /*
2223 ** Make enough space in the buffer, then copy the entire request.
2224 */
2225 if (cl->largeCmdBufSize < cmdlen) {
2226 GLbyte *newbuf = cl->largeCmdBuf;
2227
2228 if (!(newbuf = realloc(newbuf, cmdlen)))
2229 return BadAlloc11;
2230
2231 cl->largeCmdBuf = newbuf;
2232 cl->largeCmdBufSize = cmdlen;
2233 }
2234 memcpy(cl->largeCmdBuf, pc, dataBytes)__builtin___memcpy_chk (cl->largeCmdBuf, pc, dataBytes, __builtin_object_size
(cl->largeCmdBuf, 0))
;
2235
2236 cl->largeCmdBytesSoFar = dataBytes;
2237 cl->largeCmdBytesTotal = cmdlen;
2238 cl->largeCmdRequestsSoFar = 1;
2239 cl->largeCmdRequestsTotal = req->requestTotal;
2240 return Success0;
2241
2242 }
2243 else {
2244 /*
2245 ** We are receiving subsequent (i.e. not the first) requests of a
2246 ** multi request command.
2247 */
2248 int bytesSoFar; /* including this packet */
2249
2250 /*
2251 ** Check the request number and the total request count.
2252 */
2253 if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) {
2254 client->errorValue = req->requestNumber;
2255 __glXResetLargeCommandStatus(cl);
2256 return __glXError(GLXBadLargeRequest7);
2257 }
2258 if (req->requestTotal != cl->largeCmdRequestsTotal) {
2259 client->errorValue = req->requestTotal;
2260 __glXResetLargeCommandStatus(cl);
2261 return __glXError(GLXBadLargeRequest7);
2262 }
2263
2264 /*
2265 ** Check that we didn't get too much data.
2266 */
2267 if ((bytesSoFar = safe_add(cl->largeCmdBytesSoFar, dataBytes)) < 0) {
2268 client->errorValue = dataBytes;
2269 __glXResetLargeCommandStatus(cl);
2270 return __glXError(GLXBadLargeRequest7);
2271 }
2272
2273 if (bytesSoFar > cl->largeCmdBytesTotal) {
2274 client->errorValue = dataBytes;
2275 __glXResetLargeCommandStatus(cl);
2276 return __glXError(GLXBadLargeRequest7);
2277 }
2278
2279 memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes)__builtin___memcpy_chk (cl->largeCmdBuf + cl->largeCmdBytesSoFar
, pc, dataBytes, __builtin_object_size (cl->largeCmdBuf + cl
->largeCmdBytesSoFar, 0))
;
2280 cl->largeCmdBytesSoFar += dataBytes;
2281 cl->largeCmdRequestsSoFar++;
2282
2283 if (req->requestNumber == cl->largeCmdRequestsTotal) {
2284 __GLXdispatchRenderProcPtr proc;
2285
2286 /*
2287 ** This is the last request; it must have enough bytes to complete
2288 ** the command.
2289 */
2290 /* NOTE: the pad macro below is needed because the client library
2291 ** pads the total byte count, but not the per-request byte counts.
2292 ** The Protocol Encoding says the total byte count should not be
2293 ** padded, so a proposal will be made to the ARB to relax the
2294 ** padding constraint on the total byte count, thus preserving
2295 ** backward compatibility. Meanwhile, the padding done below
2296 ** fixes a bug that did not allow large commands of odd sizes to
2297 ** be accepted by the server.
2298 */
2299 if (safe_pad(cl->largeCmdBytesSoFar) != cl->largeCmdBytesTotal) {
2300 client->errorValue = dataBytes;
2301 __glXResetLargeCommandStatus(cl);
2302 return __glXError(GLXBadLargeRequest7);
2303 }
2304 hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf;
2305 /*
2306 ** The opcode and length field in the header had already been
2307 ** swapped when the first request was received.
2308 **
2309 ** Use the opcode to index into the procedure table.
2310 */
2311 opcode = hdr->opcode;
2312
2313 proc = (__GLXdispatchRenderProcPtr)
2314 __glXGetProtocolDecodeFunction(&Render_dispatch_info, opcode,
2315 client->swapped);
2316 if (proc == NULL((void*)0)) {
2317 client->errorValue = opcode;
2318 return __glXError(GLXBadLargeRequest7);
2319 }
2320
2321 /*
2322 ** Skip over the header and execute the command.
2323 */
2324 (*proc) (cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE8);
2325
2326 /*
2327 ** Reset for the next RenderLarge series.
2328 */
2329 __glXResetLargeCommandStatus(cl);
2330 }
2331 else {
2332 /*
2333 ** This is neither the first nor the last request.
2334 */
2335 }
2336 return Success0;
2337 }
2338}
2339
2340/************************************************************************/
2341
2342/*
2343** No support is provided for the vendor-private requests other than
2344** allocating the entry points in the dispatch table.
2345*/
2346
2347int
2348__glXDisp_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
2349{
2350 ClientPtr client = cl->client;
2351 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
2352 GLint vendorcode = req->vendorCode;
2353 __GLXdispatchVendorPrivProcPtr proc;
2354
2355 REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq)if ((sizeof(xGLXVendorPrivateReq) >> 2) > client->
req_len ) return(16)
;
2356
2357 proc = (__GLXdispatchVendorPrivProcPtr)
2358 __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
2359 vendorcode, 0);
2360 if (proc != NULL((void*)0)) {
2361 (*proc) (cl, (GLbyte *) req);
2362 return Success0;
2363 }
2364
2365 cl->client->errorValue = req->vendorCode;
2366 return __glXError(GLXUnsupportedPrivateRequest8);
2367}
2368
2369int
2370__glXDisp_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc)
2371{
2372 ClientPtr client = cl->client;
2373 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
2374 GLint vendorcode = req->vendorCode;
2375 __GLXdispatchVendorPrivProcPtr proc;
2376
2377 REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq)if ((sizeof(xGLXVendorPrivateReq) >> 2) > client->
req_len ) return(16)
;
2378
2379 proc = (__GLXdispatchVendorPrivProcPtr)
2380 __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
2381 vendorcode, 0);
2382 if (proc != NULL((void*)0)) {
2383 return (*proc) (cl, (GLbyte *) req);
2384 }
2385
2386 cl->client->errorValue = vendorcode;
2387 return __glXError(GLXUnsupportedPrivateRequest8);
2388}
2389
2390int
2391__glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
2392{
2393 ClientPtr client = cl->client;
2394 xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
2395 xGLXQueryExtensionsStringReply reply;
2396 __GLXscreen *pGlxScreen;
2397 size_t n, length;
2398 char *buf;
2399 int err;
2400
2401 REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq)if ((sizeof(xGLXQueryExtensionsStringReq) >> 2) != client
->req_len) return(16)
;
2402
2403 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
2404 return err;
2405
2406 n = strlen(pGlxScreen->GLXextensions) + 1;
2407 length = __GLX_PAD(n)(((n)+3) & (GLuint)~3) >> 2;
2408 reply = (xGLXQueryExtensionsStringReply) {
2409 .type = X_Reply1,
2410 .sequenceNumber = client->sequence,
2411 .length = length,
2412 .n = n
2413 };
2414
2415 /* Allocate buffer to make sure it's a multiple of 4 bytes big. */
2416 buf = calloc(length, 4);
2417 if (buf == NULL((void*)0))
2418 return BadAlloc11;
2419 memcpy(buf, pGlxScreen->GLXextensions, n)__builtin___memcpy_chk (buf, pGlxScreen->GLXextensions, n,
__builtin_object_size (buf, 0))
;
2420
2421 if (client->swapped) {
2422 glxSwapQueryExtensionsStringReply(client, &reply, buf);
2423 }
2424 else {
2425 WriteToClient(client, sz_xGLXQueryExtensionsStringReply32, &reply);
2426 WriteToClient(client, (int) (length << 2), buf);
2427 }
2428
2429 free(buf);
2430 return Success0;
2431}
2432
2433#ifndef GLX_VENDOR_NAMES_EXT0x20F6
2434#define GLX_VENDOR_NAMES_EXT0x20F6 0x20F6
2435#endif
2436
2437int
2438__glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
2439{
2440 ClientPtr client = cl->client;
2441 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
2442 xGLXQueryServerStringReply reply;
2443 size_t n, length;
2444 const char *ptr;
2445 char *buf;
2446 __GLXscreen *pGlxScreen;
2447 int err;
2448
2449 REQUEST_SIZE_MATCH(xGLXQueryServerStringReq)if ((sizeof(xGLXQueryServerStringReq) >> 2) != client->
req_len) return(16)
;
2450
2451 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
2452 return err;
2453
2454 switch (req->name) {
2455 case GLX_VENDOR0x1:
2456 ptr = GLXServerVendorName;
2457 break;
2458 case GLX_VERSION0x2:
2459 ptr = "1.4";
2460 break;
2461 case GLX_EXTENSIONS0x3:
2462 ptr = pGlxScreen->GLXextensions;
2463 break;
2464 case GLX_VENDOR_NAMES_EXT0x20F6:
2465 if (pGlxScreen->glvnd) {
2466 ptr = pGlxScreen->glvnd;
2467 break;
2468 }
2469 /* else fall through */
2470 default:
2471 return BadValue2;
2472 }
2473
2474 n = strlen(ptr) + 1;
2475 length = __GLX_PAD(n)(((n)+3) & (GLuint)~3) >> 2;
2476 reply = (xGLXQueryServerStringReply) {
2477 .type = X_Reply1,
2478 .sequenceNumber = client->sequence,
2479 .length = length,
2480 .n = n
2481 };
2482
2483 buf = calloc(length, 4);
2484 if (buf == NULL((void*)0)) {
2485 return BadAlloc11;
2486 }
2487 memcpy(buf, ptr, n)__builtin___memcpy_chk (buf, ptr, n, __builtin_object_size (buf
, 0))
;
2488
2489 if (client->swapped) {
2490 glxSwapQueryServerStringReply(client, &reply, buf);
2491 }
2492 else {
2493 WriteToClient(client, sz_xGLXQueryServerStringReply32, &reply);
2494 WriteToClient(client, (int) (length << 2), buf);
2495 }
2496
2497 free(buf);
2498 return Success0;
2499}
2500
2501int
2502__glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc)
2503{
2504 ClientPtr client = cl->client;
2505 xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
2506 const char *buf;
2507
2508 REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq)if ((sizeof(xGLXClientInfoReq) >> 2) > client->req_len
) return(16)
;
2509
2510 buf = (const char *) (req + 1);
2511 if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq)))
2512 return BadLength16;
2513
2514 free(cl->GLClientextensions);
2515 cl->GLClientextensions = strdup(buf);
2516
2517 return Success0;
2518}
2519
2520#include <GL/glxtokens.h>
2521
2522void
2523__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust,
2524 CARD64 msc, CARD32 sbc)
2525{
2526 ClientPtr client = clients[CLIENT_ID(drawable->drawId)((int)(((drawable->drawId) & (((1 << ResourceClientBits
()) - 1) << (29 - ResourceClientBits()))) >> (29 -
ResourceClientBits())))
];
2527
2528 xGLXBufferSwapComplete2 wire = {
2529 .type = __glXEventBase + GLX_BufferSwapComplete1
2530 };
2531
2532 if (!client)
2533 return;
2534
2535 if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK0x04000000))
2536 return;
2537
2538 wire.event_type = type;
2539 wire.drawable = drawable->drawId;
2540 wire.ust_hi = ust >> 32;
2541 wire.ust_lo = ust & 0xffffffff;
2542 wire.msc_hi = msc >> 32;
2543 wire.msc_lo = msc & 0xffffffff;
2544 wire.sbc = sbc;
2545
2546 WriteEventsToClient(client, 1, (xEvent *) &wire);
2547}
2548
2549#if PRESENT1
2550static void
2551__glXpresentCompleteNotify(WindowPtr window, CARD8 present_kind, CARD8 present_mode,
2552 CARD32 serial, uint64_t ust, uint64_t msc)
2553{
2554 __GLXdrawable *drawable;
2555 int glx_type;
2556 int rc;
2557
2558 if (present_kind != PresentCompleteKindPixmap0)
2559 return;
2560
2561 rc = dixLookupResourceByType((void **) &drawable, window->drawable.id,
2562 __glXDrawableRes, serverClient, DixGetAttrAccess(1<<4));
2563
2564 if (rc != Success0)
2565 return;
2566
2567 if (present_mode == PresentCompleteModeFlip1)
2568 glx_type = GLX_FLIP_COMPLETE_INTEL0x8182;
2569 else
2570 glx_type = GLX_BLIT_COMPLETE_INTEL0x8181;
2571
2572 __glXsendSwapEvent(drawable, glx_type, ust, msc, serial);
2573}
2574
2575#include <present.h>
2576
2577void
2578__glXregisterPresentCompleteNotify(void)
2579{
2580 present_register_complete_notify(__glXpresentCompleteNotify);
2581}
2582#endif