Bug Summary

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