Refactor the code that converts a transpose-matrix enum to a
[mesa.git] / src / glx / x11 / glxcmds.c
1 /* $XFree86: xc/lib/GL/glx/glxcmds.c,v 1.30 2004/01/30 20:33:06 alanh Exp $ */
2 /*
3 ** License Applicability. Except to the extent portions of this file are
4 ** made subject to an alternative license as permitted in the SGI Free
5 ** Software License B, Version 1.1 (the "License"), the contents of this
6 ** file are subject only to the provisions of the License. You may not use
7 ** this file except in compliance with the License. You may obtain a copy
8 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 **
11 ** http://oss.sgi.com/projects/FreeB
12 **
13 ** Note that, as provided in the License, the Software is distributed on an
14 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 **
19 ** Original Code. The Original Code is: OpenGL Sample Implementation,
20 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22 ** Copyright in any portions created by third parties is as indicated
23 ** elsewhere herein. All Rights Reserved.
24 **
25 ** Additional Notice Provisions: The application programming interfaces
26 ** established by SGI in conjunction with the Original Code are The
27 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30 ** Window System(R) (Version 1.3), released October 19, 1998. This software
31 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32 ** published by SGI, but has not been independently verified as being
33 ** compliant with the OpenGL(R) version 1.2.1 Specification.
34 **
35 */
36
37 /**
38 * \file glxcmds.c
39 * Client-side GLX interface.
40 */
41
42 #include <inttypes.h>
43 #include "glxclient.h"
44 #include <extutil.h>
45 #include <Xext.h>
46 #include <assert.h>
47 #include <string.h>
48 #include "glapi.h"
49 #ifdef GLX_DIRECT_RENDERING
50 #include "indirect_init.h"
51 #include "xf86vmode.h"
52 #endif
53 #include "glxextensions.h"
54 #include "glcontextmodes.h"
55 #include "glheader.h"
56 #include <sys/time.h>
57
58 #ifdef IN_DOXYGEN
59 #define GLX_PREFIX(x) x
60 #endif /* IN_DOXYGEN */
61
62 static const char __glXGLXClientVendorName[] = "SGI";
63 static const char __glXGLXClientVersion[] = "1.4";
64
65
66 #if defined(GLX_DIRECT_RENDERING)
67 #include "xf86dri.h"
68
69 static Bool __glXWindowExists(Display *dpy, GLXDrawable draw);
70
71 static void * DriverCreateContextWrapper( const __GLXscreenConfigs *psc,
72 Display *dpy, XVisualInfo *vis, void *shared, __DRIcontext *ctx,
73 const __GLcontextModes *fbconfig, int render_type );
74
75 static Bool dummyBindContext2( Display *dpy, int scrn,
76 GLXDrawable draw, GLXDrawable read, GLXContext gc );
77
78 static Bool dummyUnbindContext2( Display *dpy, int scrn,
79 GLXDrawable draw, GLXDrawable read, GLXContext gc );
80
81 /****************************************************************************/
82
83 /**
84 * Used as glue when a driver does not support
85 * \c __DRIcontextRec::bindContext2.
86 *
87 * XXX .bindContext is only defined as a function pointer if
88 * !DRI_NEW_INTERFACE_ONLY.
89 *
90 * \sa DriverCreateContextWrapper, __DRIcontextRec::bindContext2
91 */
92 static Bool dummyBindContext2( Display *dpy, int scrn,
93 GLXDrawable draw, GLXDrawable read,
94 GLXContext gc )
95 {
96 assert( draw == read );
97 return (*gc->driContext.bindContext)( dpy, scrn, draw, gc );
98 }
99
100 /**
101 * Used as glue when a driver does not support
102 * \c __DRIcontextRec::unbindContext2.
103 *
104 * XXX .unbindContext is only defined as a function pointer if
105 * !DRI_NEW_INTERFACE_ONLY.
106 *
107 * \sa DriverCreateContextWrapper, __DRIcontextRec::unbindContext2
108 */
109 static Bool dummyUnbindContext2( Display *dpy, int scrn,
110 GLXDrawable draw, GLXDrawable read,
111 GLXContext gc )
112 {
113 assert( draw == read );
114 return (*gc->driContext.unbindContext)( dpy, scrn, draw, gc, GL_FALSE );
115 }
116
117
118 /****************************************************************************/
119 /**
120 * Wrap the call to the driver's \c createContext function.
121 *
122 * The \c createContext function is wrapped because not all drivers support
123 * the "new" \c unbindContext2 and \c bindContext2 interfaces. libGL should
124 * not have to check to see which functions the driver supports. Instead,
125 * if either function is not supported it is wrapped. The wrappers test to
126 * make sure that both drawables are the same and pass control to the old
127 * interface.
128 *
129 * \sa dummyBindContext2, dummyUnbindContext2,
130 * __DRIcontextRec::bindContext2, __DRIcontextRec::unbindContext2
131 */
132
133 static void * DriverCreateContextWrapper( const __GLXscreenConfigs *psc,
134 Display *dpy, XVisualInfo *vis,
135 void *shared,
136 __DRIcontext *ctx,
137 const __GLcontextModes *modes,
138 int render_type )
139 {
140 void * ctx_priv = NULL;
141
142 if ( psc->driScreen.createNewContext != NULL ) {
143 assert( modes != NULL );
144 ctx_priv = (*psc->driScreen.createNewContext)(dpy, modes, render_type,
145 shared, ctx);
146
147 /* If the driver supports the createNewContext interface, then
148 * it MUST also support either the bindContext2 / unbindContext2
149 * interface or the bindContext3 / unbindContext3 interface.
150 */
151
152 assert( (ctx_priv == NULL) || (ctx->unbindContext2 != NULL)
153 || (ctx->unbindContext3 != NULL) );
154 assert( (ctx_priv == NULL) || (ctx->bindContext2 != NULL)
155 || (ctx->bindContext3 != NULL) );
156 }
157 else {
158 if ( vis != NULL ) {
159 ctx_priv = (*psc->driScreen.createContext)(dpy, vis, shared, ctx);
160
161 if ( ctx_priv != NULL ) {
162 if ( ctx->unbindContext2 == NULL ) {
163 ctx->unbindContext2 = dummyUnbindContext2;
164 }
165
166 if ( ctx->bindContext2 == NULL ) {
167 ctx->bindContext2 = dummyBindContext2;
168 }
169 }
170 }
171 }
172
173 return ctx_priv;
174 }
175 #endif
176
177
178 /****************************************************************************/
179 /**
180 * Get the __DRIdrawable for the drawable associated with a GLXContext
181 *
182 * \param dpy The display associated with \c drawable.
183 * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved.
184 * \returns A pointer to the context's __DRIdrawable on success, or NULL if
185 * the drawable is not associated with a direct-rendering context.
186 */
187
188 #ifdef GLX_DIRECT_RENDERING
189 static __DRIdrawable *
190 GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num )
191 {
192 __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
193
194 if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) {
195 const unsigned screen_count = ScreenCount(dpy);
196 unsigned i;
197
198 for ( i = 0 ; i < screen_count ; i++ ) {
199 __DRIscreen * const psc = &priv->screenConfigs[i].driScreen;
200 __DRIdrawable * const pdraw = (psc->private != NULL)
201 ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL;
202
203 if ( pdraw != NULL ) {
204 if ( scrn_num != NULL ) {
205 *scrn_num = i;
206 }
207 return pdraw;
208 }
209 }
210 }
211
212 return NULL;
213 }
214 #endif
215
216
217 /**
218 * Get the GLX per-screen data structure associated with a GLX context.
219 *
220 * \param dpy Display for which the GLX per-screen information is to be
221 * retrieved.
222 * \param scrn Screen on \c dpy for which the GLX per-screen information is
223 * to be retrieved.
224 * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
225 * specify a valid GLX screen, or NULL otherwise.
226 *
227 * \todo Should this function validate that \c scrn is within the screen
228 * number range for \c dpy?
229 */
230
231 static __GLXscreenConfigs *
232 GetGLXScreenConfigs(Display *dpy, int scrn)
233 {
234 __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
235
236 return (priv->screenConfigs != NULL) ? &priv->screenConfigs[scrn] : NULL;
237 }
238
239
240 static int
241 GetGLXPrivScreenConfig( Display *dpy, int scrn, __GLXdisplayPrivate ** ppriv,
242 __GLXscreenConfigs ** ppsc )
243 {
244 /* Initialize the extension, if needed . This has the added value
245 * of initializing/allocating the display private
246 */
247
248 if ( dpy == NULL ) {
249 return GLX_NO_EXTENSION;
250 }
251
252 *ppriv = __glXInitialize(dpy);
253 if ( *ppriv == NULL ) {
254 return GLX_NO_EXTENSION;
255 }
256
257 /* Check screen number to see if its valid */
258 if ((scrn < 0) || (scrn >= ScreenCount(dpy))) {
259 return GLX_BAD_SCREEN;
260 }
261
262 /* Check to see if the GL is supported on this screen */
263 *ppsc = &((*ppriv)->screenConfigs[scrn]);
264 if ( (*ppsc)->configs == NULL ) {
265 /* No support for GL on this screen regardless of visual */
266 return GLX_BAD_VISUAL;
267 }
268
269 return Success;
270 }
271
272
273 /**
274 * Determine if a \c GLXFBConfig supplied by the application is valid.
275 *
276 * \param dpy Application supplied \c Display pointer.
277 * \param config Application supplied \c GLXFBConfig.
278 *
279 * \returns If the \c GLXFBConfig is valid, the a pointer to the matching
280 * \c __GLcontextModes structure is returned. Otherwise, \c NULL
281 * is returned.
282 */
283 static __GLcontextModes *
284 ValidateGLXFBConfig( Display * dpy, GLXFBConfig config )
285 {
286 __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
287 const unsigned num_screens = ScreenCount(dpy);
288 unsigned i;
289 const __GLcontextModes * modes;
290
291
292 if ( priv != NULL ) {
293 for ( i = 0 ; i < num_screens ; i++ ) {
294 for ( modes = priv->screenConfigs[i].configs
295 ; modes != NULL
296 ; modes = modes->next ) {
297 if ( modes == (__GLcontextModes *) config ) {
298 return (__GLcontextModes *) config;
299 }
300 }
301 }
302 }
303
304 return NULL;
305 }
306
307
308 /**
309 * \todo It should be possible to move the allocate of \c client_state_private
310 * later in the function for direct-rendering contexts. Direct-rendering
311 * contexts don't need to track client state, so they don't need that memory
312 * at all.
313 *
314 * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new
315 * function called \c __glXAllocateClientState that allocates the memory and
316 * does all the initialization (including the pixel pack / unpack).
317 */
318 static
319 GLXContext AllocateGLXContext( Display *dpy )
320 {
321 GLXContext gc;
322 int bufSize;
323 CARD8 opcode;
324 __GLXattribute *state;
325
326 if (!dpy)
327 return NULL;
328
329 opcode = __glXSetupForCommand(dpy);
330 if (!opcode) {
331 return NULL;
332 }
333
334 /* Allocate our context record */
335 gc = (GLXContext) Xmalloc(sizeof(struct __GLXcontextRec));
336 if (!gc) {
337 /* Out of memory */
338 return NULL;
339 }
340 memset(gc, 0, sizeof(struct __GLXcontextRec));
341
342 state = Xmalloc(sizeof(struct __GLXattributeRec));
343 if (state == NULL) {
344 /* Out of memory */
345 Xfree(gc);
346 return NULL;
347 }
348 gc->client_state_private = state;
349 memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
350 state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
351
352 /*
353 ** Create a temporary buffer to hold GLX rendering commands. The size
354 ** of the buffer is selected so that the maximum number of GLX rendering
355 ** commands can fit in a single X packet and still have room in the X
356 ** packet for the GLXRenderReq header.
357 */
358
359 bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq;
360 gc->buf = (GLubyte *) Xmalloc(bufSize);
361 if (!gc->buf) {
362 Xfree(gc->client_state_private);
363 Xfree(gc);
364 return NULL;
365 }
366 gc->bufSize = bufSize;
367
368 /* Fill in the new context */
369 gc->renderMode = GL_RENDER;
370
371 state->storePack.alignment = 4;
372 state->storeUnpack.alignment = 4;
373
374 __glXInitVertexArrayState(gc);
375
376 gc->attributes.stackPointer = &gc->attributes.stack[0];
377
378 /*
379 ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
380 ** Other code uses the fastImageUnpack bit, but it is never set
381 ** to GL_TRUE.
382 */
383 gc->fastImageUnpack = GL_FALSE;
384 gc->fillImage = __glFillImage;
385 gc->isDirect = GL_FALSE;
386 gc->pc = gc->buf;
387 gc->bufEnd = gc->buf + bufSize;
388 if (__glXDebug) {
389 /*
390 ** Set limit register so that there will be one command per packet
391 */
392 gc->limit = gc->buf;
393 } else {
394 gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
395 }
396 gc->createDpy = dpy;
397 gc->majorOpcode = opcode;
398
399 /*
400 ** Constrain the maximum drawing command size allowed to be
401 ** transfered using the X_GLXRender protocol request. First
402 ** constrain by a software limit, then constrain by the protocl
403 ** limit.
404 */
405 if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
406 bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
407 }
408 if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
409 bufSize = __GLX_MAX_RENDER_CMD_SIZE;
410 }
411 gc->maxSmallRenderCommandSize = bufSize;
412 return gc;
413 }
414
415
416 /**
417 * Create a new context. Exactly one of \c vis and \c fbconfig should be
418 * non-NULL.
419 *
420 * \param use_glx_1_3 For FBConfigs, should GLX 1.3 protocol or
421 * SGIX_fbconfig protocol be used?
422 * \param renderType For FBConfigs, what is the rendering type?
423 */
424
425 static GLXContext
426 CreateContext(Display *dpy, XVisualInfo *vis,
427 const __GLcontextModes * const fbconfig,
428 GLXContext shareList,
429 Bool allowDirect, GLXContextID contextID,
430 Bool use_glx_1_3, int renderType)
431 {
432 GLXContext gc;
433
434 if ( dpy == NULL )
435 return NULL;
436
437 gc = AllocateGLXContext(dpy);
438 if (!gc)
439 return NULL;
440
441 if (None == contextID) {
442 if ( (vis == NULL) && (fbconfig == NULL) )
443 return NULL;
444
445 #ifdef GLX_DIRECT_RENDERING
446 if (allowDirect) {
447 int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
448 __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
449 const __GLcontextModes * mode;
450
451 /* The value of fbconfig cannot change because it is tested
452 * later in the function.
453 */
454 if ( fbconfig == NULL ) {
455 /* FIXME: Is it possible for the __GLcontextModes structure
456 * FIXME: to not be found?
457 */
458 mode = _gl_context_modes_find_visual( psc->configs,
459 vis->visualid );
460 assert( mode != NULL );
461 assert( mode->screen == screen );
462 }
463 else {
464 mode = fbconfig;
465 }
466
467 if (psc && psc->driScreen.private) {
468 void * const shared = (shareList != NULL)
469 ? shareList->driContext.private : NULL;
470 gc->driContext.private =
471 DriverCreateContextWrapper( psc, dpy, vis, shared,
472 &gc->driContext, mode,
473 renderType );
474 if (gc->driContext.private) {
475 gc->isDirect = GL_TRUE;
476 gc->screen = mode->screen;
477 gc->vid = mode->visualID;
478 gc->fbconfigID = mode->fbconfigID;
479 gc->driContext.mode = mode;
480 }
481 }
482 }
483 #endif
484
485 LockDisplay(dpy);
486 if ( fbconfig == NULL ) {
487 xGLXCreateContextReq *req;
488
489 /* Send the glXCreateContext request */
490 GetReq(GLXCreateContext,req);
491 req->reqType = gc->majorOpcode;
492 req->glxCode = X_GLXCreateContext;
493 req->context = gc->xid = XAllocID(dpy);
494 req->visual = vis->visualid;
495 req->screen = vis->screen;
496 req->shareList = shareList ? shareList->xid : None;
497 req->isDirect = gc->isDirect;
498 }
499 else if ( use_glx_1_3 ) {
500 xGLXCreateNewContextReq *req;
501
502 /* Send the glXCreateNewContext request */
503 GetReq(GLXCreateNewContext,req);
504 req->reqType = gc->majorOpcode;
505 req->glxCode = X_GLXCreateNewContext;
506 req->context = gc->xid = XAllocID(dpy);
507 req->fbconfig = fbconfig->fbconfigID;
508 req->screen = fbconfig->screen;
509 req->renderType = renderType;
510 req->shareList = shareList ? shareList->xid : None;
511 req->isDirect = gc->isDirect;
512 }
513 else {
514 xGLXVendorPrivateWithReplyReq *vpreq;
515 xGLXCreateContextWithConfigSGIXReq *req;
516
517 /* Send the glXCreateNewContext request */
518 GetReqExtra(GLXVendorPrivateWithReply,
519 sz_xGLXCreateContextWithConfigSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
520 req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
521 req->reqType = gc->majorOpcode;
522 req->glxCode = X_GLXVendorPrivateWithReply;
523 req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
524 req->context = gc->xid = XAllocID(dpy);
525 req->fbconfig = fbconfig->fbconfigID;
526 req->screen = fbconfig->screen;
527 req->renderType = renderType;
528 req->shareList = shareList ? shareList->xid : None;
529 req->isDirect = gc->isDirect;
530 }
531
532 UnlockDisplay(dpy);
533 SyncHandle();
534 gc->imported = GL_FALSE;
535 }
536 else {
537 gc->xid = contextID;
538 gc->imported = GL_TRUE;
539 }
540
541 return gc;
542 }
543
544 PUBLIC GLXContext GLX_PREFIX(glXCreateContext)(Display *dpy, XVisualInfo *vis,
545 GLXContext shareList,
546 Bool allowDirect)
547 {
548 return CreateContext(dpy, vis, NULL, shareList, allowDirect, None,
549 False, 0);
550 }
551
552 void __glXFreeContext(__GLXcontext *gc)
553 {
554 if (gc->vendor) XFree((char *) gc->vendor);
555 if (gc->renderer) XFree((char *) gc->renderer);
556 if (gc->version) XFree((char *) gc->version);
557 if (gc->extensions) XFree((char *) gc->extensions);
558 __glFreeAttributeState(gc);
559 XFree((char *) gc->buf);
560 Xfree((char *) gc->client_state_private);
561 XFree((char *) gc);
562
563 }
564
565 /*
566 ** Destroy the named context
567 */
568 static void
569 DestroyContext(Display *dpy, GLXContext gc)
570 {
571 xGLXDestroyContextReq *req;
572 GLXContextID xid;
573 CARD8 opcode;
574 GLboolean imported;
575
576 opcode = __glXSetupForCommand(dpy);
577 if (!opcode || !gc) {
578 return;
579 }
580
581 __glXLock();
582 xid = gc->xid;
583 imported = gc->imported;
584 gc->xid = None;
585
586 #ifdef GLX_DIRECT_RENDERING
587 /* Destroy the direct rendering context */
588 if (gc->isDirect) {
589 if (gc->driContext.private) {
590 (*gc->driContext.destroyContext)(dpy, gc->screen,
591 gc->driContext.private);
592 gc->driContext.private = NULL;
593 }
594 }
595 #endif
596
597 if (gc->currentDpy) {
598 /* Have to free later cuz it's in use now */
599 __glXUnlock();
600 } else {
601 /* Destroy the handle if not current to anybody */
602 __glXUnlock();
603 __glXFreeContext(gc);
604 }
605
606 if (!imported) {
607 /*
608 ** This dpy also created the server side part of the context.
609 ** Send the glXDestroyContext request.
610 */
611 LockDisplay(dpy);
612 GetReq(GLXDestroyContext,req);
613 req->reqType = opcode;
614 req->glxCode = X_GLXDestroyContext;
615 req->context = xid;
616 UnlockDisplay(dpy);
617 SyncHandle();
618 }
619 }
620
621 PUBLIC void GLX_PREFIX(glXDestroyContext)(Display *dpy, GLXContext gc)
622 {
623 DestroyContext(dpy, gc);
624 }
625
626 /*
627 ** Return the major and minor version #s for the GLX extension
628 */
629 PUBLIC Bool GLX_PREFIX(glXQueryVersion)(Display *dpy, int *major, int *minor)
630 {
631 __GLXdisplayPrivate *priv;
632
633 /* Init the extension. This fetches the major and minor version. */
634 priv = __glXInitialize(dpy);
635 if (!priv) return GL_FALSE;
636
637 if (major) *major = priv->majorVersion;
638 if (minor) *minor = priv->minorVersion;
639 return GL_TRUE;
640 }
641
642 /*
643 ** Query the existance of the GLX extension
644 */
645 PUBLIC Bool GLX_PREFIX(glXQueryExtension)(Display *dpy, int *errorBase,
646 int *eventBase)
647 {
648 int major_op, erb, evb;
649 Bool rv;
650
651 rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb);
652 if (rv) {
653 if (errorBase) *errorBase = erb;
654 if (eventBase) *eventBase = evb;
655 }
656 return rv;
657 }
658
659 /*
660 ** Put a barrier in the token stream that forces the GL to finish its
661 ** work before X can proceed.
662 */
663 PUBLIC void GLX_PREFIX(glXWaitGL)(void)
664 {
665 xGLXWaitGLReq *req;
666 GLXContext gc = __glXGetCurrentContext();
667 Display *dpy = gc->currentDpy;
668
669 if (!dpy) return;
670
671 /* Flush any pending commands out */
672 __glXFlushRenderBuffer(gc, gc->pc);
673
674 #ifdef GLX_DIRECT_RENDERING
675 if (gc->isDirect) {
676 /* This bit of ugliness unwraps the glFinish function */
677 #ifdef glFinish
678 #undef glFinish
679 #endif
680 glFinish();
681 return;
682 }
683 #endif
684
685 /* Send the glXWaitGL request */
686 LockDisplay(dpy);
687 GetReq(GLXWaitGL,req);
688 req->reqType = gc->majorOpcode;
689 req->glxCode = X_GLXWaitGL;
690 req->contextTag = gc->currentContextTag;
691 UnlockDisplay(dpy);
692 SyncHandle();
693 }
694
695 /*
696 ** Put a barrier in the token stream that forces X to finish its
697 ** work before GL can proceed.
698 */
699 PUBLIC void GLX_PREFIX(glXWaitX)(void)
700 {
701 xGLXWaitXReq *req;
702 GLXContext gc = __glXGetCurrentContext();
703 Display *dpy = gc->currentDpy;
704
705 if (!dpy) return;
706
707 /* Flush any pending commands out */
708 __glXFlushRenderBuffer(gc, gc->pc);
709
710 #ifdef GLX_DIRECT_RENDERING
711 if (gc->isDirect) {
712 XSync(dpy, False);
713 return;
714 }
715 #endif
716
717 /*
718 ** Send the glXWaitX request.
719 */
720 LockDisplay(dpy);
721 GetReq(GLXWaitX,req);
722 req->reqType = gc->majorOpcode;
723 req->glxCode = X_GLXWaitX;
724 req->contextTag = gc->currentContextTag;
725 UnlockDisplay(dpy);
726 SyncHandle();
727 }
728
729 PUBLIC void GLX_PREFIX(glXUseXFont)(Font font, int first, int count,
730 int listBase)
731 {
732 xGLXUseXFontReq *req;
733 GLXContext gc = __glXGetCurrentContext();
734 Display *dpy = gc->currentDpy;
735
736 if (!dpy) return;
737
738 /* Flush any pending commands out */
739 (void) __glXFlushRenderBuffer(gc, gc->pc);
740
741 #ifdef GLX_DIRECT_RENDERING
742 if (gc->isDirect) {
743 DRI_glXUseXFont(font, first, count, listBase);
744 return;
745 }
746 #endif
747
748 /* Send the glXUseFont request */
749 LockDisplay(dpy);
750 GetReq(GLXUseXFont,req);
751 req->reqType = gc->majorOpcode;
752 req->glxCode = X_GLXUseXFont;
753 req->contextTag = gc->currentContextTag;
754 req->font = font;
755 req->first = first;
756 req->count = count;
757 req->listBase = listBase;
758 UnlockDisplay(dpy);
759 SyncHandle();
760 }
761
762 /************************************************************************/
763
764 /*
765 ** Copy the source context to the destination context using the
766 ** attribute "mask".
767 */
768 PUBLIC void GLX_PREFIX(glXCopyContext)(Display *dpy, GLXContext source,
769 GLXContext dest, unsigned long mask)
770 {
771 xGLXCopyContextReq *req;
772 GLXContext gc = __glXGetCurrentContext();
773 GLXContextTag tag;
774 CARD8 opcode;
775
776 opcode = __glXSetupForCommand(dpy);
777 if (!opcode) {
778 return;
779 }
780
781 #ifdef GLX_DIRECT_RENDERING
782 if (gc->isDirect) {
783 /* NOT_DONE: This does not work yet */
784 }
785 #endif
786
787 /*
788 ** If the source is the current context, send its tag so that the context
789 ** can be flushed before the copy.
790 */
791 if (source == gc && dpy == gc->currentDpy) {
792 tag = gc->currentContextTag;
793 } else {
794 tag = 0;
795 }
796
797 /* Send the glXCopyContext request */
798 LockDisplay(dpy);
799 GetReq(GLXCopyContext,req);
800 req->reqType = opcode;
801 req->glxCode = X_GLXCopyContext;
802 req->source = source ? source->xid : None;
803 req->dest = dest ? dest->xid : None;
804 req->mask = mask;
805 req->contextTag = tag;
806 UnlockDisplay(dpy);
807 SyncHandle();
808 }
809
810
811 /**
812 * Determine if a context uses direct rendering.
813 *
814 * \param dpy Display where the context was created.
815 * \param contextID ID of the context to be tested.
816 *
817 * \returns \c GL_TRUE if the context is direct rendering or not.
818 */
819 static Bool __glXIsDirect(Display *dpy, GLXContextID contextID)
820 {
821 xGLXIsDirectReq *req;
822 xGLXIsDirectReply reply;
823 CARD8 opcode;
824
825 opcode = __glXSetupForCommand(dpy);
826 if (!opcode) {
827 return GL_FALSE;
828 }
829
830 /* Send the glXIsDirect request */
831 LockDisplay(dpy);
832 GetReq(GLXIsDirect,req);
833 req->reqType = opcode;
834 req->glxCode = X_GLXIsDirect;
835 req->context = contextID;
836 _XReply(dpy, (xReply*) &reply, 0, False);
837 UnlockDisplay(dpy);
838 SyncHandle();
839
840 return reply.isDirect;
841 }
842
843 PUBLIC Bool GLX_PREFIX(glXIsDirect)(Display *dpy, GLXContext gc)
844 {
845 if (!gc) {
846 return GL_FALSE;
847 #ifdef GLX_DIRECT_RENDERING
848 } else if (gc->isDirect) {
849 return GL_TRUE;
850 #endif
851 }
852 return __glXIsDirect(dpy, gc->xid);
853 }
854
855 PUBLIC GLXPixmap GLX_PREFIX(glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis,
856 Pixmap pixmap)
857 {
858 xGLXCreateGLXPixmapReq *req;
859 GLXPixmap xid;
860 CARD8 opcode;
861
862 opcode = __glXSetupForCommand(dpy);
863 if (!opcode) {
864 return None;
865 }
866
867 /* Send the glXCreateGLXPixmap request */
868 LockDisplay(dpy);
869 GetReq(GLXCreateGLXPixmap,req);
870 req->reqType = opcode;
871 req->glxCode = X_GLXCreateGLXPixmap;
872 req->screen = vis->screen;
873 req->visual = vis->visualid;
874 req->pixmap = pixmap;
875 req->glxpixmap = xid = XAllocID(dpy);
876 UnlockDisplay(dpy);
877 SyncHandle();
878 return xid;
879 }
880
881 /*
882 ** Destroy the named pixmap
883 */
884 PUBLIC void GLX_PREFIX(glXDestroyGLXPixmap)(Display *dpy, GLXPixmap glxpixmap)
885 {
886 xGLXDestroyGLXPixmapReq *req;
887 CARD8 opcode;
888
889 opcode = __glXSetupForCommand(dpy);
890 if (!opcode) {
891 return;
892 }
893
894 /* Send the glXDestroyGLXPixmap request */
895 LockDisplay(dpy);
896 GetReq(GLXDestroyGLXPixmap,req);
897 req->reqType = opcode;
898 req->glxCode = X_GLXDestroyGLXPixmap;
899 req->glxpixmap = glxpixmap;
900 UnlockDisplay(dpy);
901 SyncHandle();
902 }
903
904 PUBLIC void GLX_PREFIX(glXSwapBuffers)(Display *dpy, GLXDrawable drawable)
905 {
906 xGLXSwapBuffersReq *req;
907 GLXContext gc;
908 GLXContextTag tag;
909 CARD8 opcode;
910 #ifdef GLX_DIRECT_RENDERING
911 __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL );
912
913 if ( pdraw != NULL ) {
914 (*pdraw->swapBuffers)(dpy, pdraw->private);
915 return;
916 }
917 #endif
918
919 opcode = __glXSetupForCommand(dpy);
920 if (!opcode) {
921 return;
922 }
923
924 /*
925 ** The calling thread may or may not have a current context. If it
926 ** does, send the context tag so the server can do a flush.
927 */
928 gc = __glXGetCurrentContext();
929 if ((gc != NULL) && (dpy == gc->currentDpy) &&
930 ((drawable == gc->currentDrawable) || (drawable == gc->currentReadable)) ) {
931 tag = gc->currentContextTag;
932 } else {
933 tag = 0;
934 }
935
936 /* Send the glXSwapBuffers request */
937 LockDisplay(dpy);
938 GetReq(GLXSwapBuffers,req);
939 req->reqType = opcode;
940 req->glxCode = X_GLXSwapBuffers;
941 req->drawable = drawable;
942 req->contextTag = tag;
943 UnlockDisplay(dpy);
944 SyncHandle();
945 XFlush(dpy);
946 }
947
948
949 /*
950 ** Return configuration information for the given display, screen and
951 ** visual combination.
952 */
953 PUBLIC int GLX_PREFIX(glXGetConfig)(Display *dpy, XVisualInfo *vis,
954 int attribute, int *value_return)
955 {
956 __GLXdisplayPrivate *priv;
957 __GLXscreenConfigs *psc;
958 int status;
959
960 status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc );
961 if ( status == Success ) {
962 const __GLcontextModes * const modes = _gl_context_modes_find_visual(
963 psc->configs, vis->visualid );
964
965 /* Lookup attribute after first finding a match on the visual */
966 if ( modes != NULL ) {
967 return _gl_get_context_mode_data( modes, attribute, value_return );
968 }
969
970 status = GLX_BAD_VISUAL;
971 }
972
973 /*
974 ** If we can't find the config for this visual, this visual is not
975 ** supported by the OpenGL implementation on the server.
976 */
977 if ( (status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL) ) {
978 *value_return = GL_FALSE;
979 status = Success;
980 }
981
982 return status;
983 }
984
985 /************************************************************************/
986
987 static void
988 init_fbconfig_for_chooser( __GLcontextModes * config,
989 GLboolean fbconfig_style_tags )
990 {
991 memset( config, 0, sizeof( __GLcontextModes ) );
992 config->visualID = (XID) GLX_DONT_CARE;
993 config->visualType = GLX_DONT_CARE;
994
995 /* glXChooseFBConfig specifies different defaults for these two than
996 * glXChooseVisual.
997 */
998 if ( fbconfig_style_tags ) {
999 config->rgbMode = GL_TRUE;
1000 config->doubleBufferMode = GLX_DONT_CARE;
1001 }
1002
1003 config->visualRating = GLX_DONT_CARE;
1004 config->transparentPixel = GLX_NONE;
1005 config->transparentRed = GLX_DONT_CARE;
1006 config->transparentGreen = GLX_DONT_CARE;
1007 config->transparentBlue = GLX_DONT_CARE;
1008 config->transparentAlpha = GLX_DONT_CARE;
1009 config->transparentIndex = GLX_DONT_CARE;
1010
1011 config->drawableType = GLX_WINDOW_BIT;
1012 config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
1013 config->xRenderable = GLX_DONT_CARE;
1014 config->fbconfigID = (GLXFBConfigID)(GLX_DONT_CARE);
1015
1016 config->swapMethod = GLX_DONT_CARE;
1017 }
1018
1019 #define MATCH_DONT_CARE( param ) \
1020 do { \
1021 if ( (a-> param != GLX_DONT_CARE) \
1022 && (a-> param != b-> param) ) { \
1023 return False; \
1024 } \
1025 } while ( 0 )
1026
1027 #define MATCH_MINIMUM( param ) \
1028 do { \
1029 if ( (a-> param != GLX_DONT_CARE) \
1030 && (a-> param > b-> param) ) { \
1031 return False; \
1032 } \
1033 } while ( 0 )
1034
1035 #define MATCH_EXACT( param ) \
1036 do { \
1037 if ( a-> param != b-> param) { \
1038 return False; \
1039 } \
1040 } while ( 0 )
1041
1042 /**
1043 * Determine if two GLXFBConfigs are compatible.
1044 *
1045 * \param a Application specified config to test.
1046 * \param b Server specified config to test against \c a.
1047 */
1048 static Bool
1049 fbconfigs_compatible( const __GLcontextModes * const a,
1050 const __GLcontextModes * const b )
1051 {
1052 MATCH_DONT_CARE( doubleBufferMode );
1053 MATCH_DONT_CARE( visualType );
1054 MATCH_DONT_CARE( visualRating );
1055 MATCH_DONT_CARE( xRenderable );
1056 MATCH_DONT_CARE( fbconfigID );
1057 MATCH_DONT_CARE( swapMethod );
1058
1059 MATCH_MINIMUM( rgbBits );
1060 MATCH_MINIMUM( numAuxBuffers );
1061 MATCH_MINIMUM( redBits );
1062 MATCH_MINIMUM( greenBits );
1063 MATCH_MINIMUM( blueBits );
1064 MATCH_MINIMUM( alphaBits );
1065 MATCH_MINIMUM( depthBits );
1066 MATCH_MINIMUM( stencilBits );
1067 MATCH_MINIMUM( accumRedBits );
1068 MATCH_MINIMUM( accumGreenBits );
1069 MATCH_MINIMUM( accumBlueBits );
1070 MATCH_MINIMUM( accumAlphaBits );
1071 MATCH_MINIMUM( sampleBuffers );
1072 MATCH_MINIMUM( maxPbufferWidth );
1073 MATCH_MINIMUM( maxPbufferHeight );
1074 MATCH_MINIMUM( maxPbufferPixels );
1075 MATCH_MINIMUM( samples );
1076
1077 MATCH_DONT_CARE( stereoMode );
1078 MATCH_EXACT( level );
1079
1080 if ( ((a->drawableType & b->drawableType) == 0)
1081 || ((a->renderType & b->renderType) == 0) ) {
1082 return False;
1083 }
1084
1085
1086 /* There is a bug in a few of the XFree86 DDX drivers. They contain
1087 * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
1088 * Technically speaking, it is a bug in the DDX driver, but there is
1089 * enough of an installed base to work around the problem here. In any
1090 * case, 0 is not a valid value of the transparent type, so we'll treat 0
1091 * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
1092 * 0 from the server to be a match to maintain backward compatibility with
1093 * the (broken) drivers.
1094 */
1095
1096 if ( a->transparentPixel != GLX_DONT_CARE
1097 && a->transparentPixel != 0 ) {
1098 if ( a->transparentPixel == GLX_NONE ) {
1099 if ( b->transparentPixel != GLX_NONE && b->transparentPixel != 0 )
1100 return False;
1101 } else {
1102 MATCH_EXACT( transparentPixel );
1103 }
1104
1105 switch ( a->transparentPixel ) {
1106 case GLX_TRANSPARENT_RGB:
1107 MATCH_DONT_CARE( transparentRed );
1108 MATCH_DONT_CARE( transparentGreen );
1109 MATCH_DONT_CARE( transparentBlue );
1110 MATCH_DONT_CARE( transparentAlpha );
1111 break;
1112
1113 case GLX_TRANSPARENT_INDEX:
1114 MATCH_DONT_CARE( transparentIndex );
1115 break;
1116
1117 default:
1118 break;
1119 }
1120 }
1121
1122 return True;
1123 }
1124
1125
1126 /* There's some trickly language in the GLX spec about how this is supposed
1127 * to work. Basically, if a given component size is either not specified
1128 * or the requested size is zero, it is supposed to act like PERFER_SMALLER.
1129 * Well, that's really hard to do with the code as-is. This behavior is
1130 * closer to correct, but still not technically right.
1131 */
1132 #define PREFER_LARGER_OR_ZERO(comp) \
1133 do { \
1134 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1135 if ( ((*a)-> comp) == 0 ) { \
1136 return -1; \
1137 } \
1138 else if ( ((*b)-> comp) == 0 ) { \
1139 return 1; \
1140 } \
1141 else { \
1142 return ((*b)-> comp) - ((*a)-> comp) ; \
1143 } \
1144 } \
1145 } while( 0 )
1146
1147 #define PREFER_LARGER(comp) \
1148 do { \
1149 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1150 return ((*b)-> comp) - ((*a)-> comp) ; \
1151 } \
1152 } while( 0 )
1153
1154 #define PREFER_SMALLER(comp) \
1155 do { \
1156 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1157 return ((*a)-> comp) - ((*b)-> comp) ; \
1158 } \
1159 } while( 0 )
1160
1161 /**
1162 * Compare two GLXFBConfigs. This function is intended to be used as the
1163 * compare function passed in to qsort.
1164 *
1165 * \returns If \c a is a "better" config, according to the specification of
1166 * SGIX_fbconfig, a number less than zero is returned. If \c b is
1167 * better, then a number greater than zero is return. If both are
1168 * equal, zero is returned.
1169 * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1170 */
1171 static int
1172 fbconfig_compare( const __GLcontextModes * const * const a,
1173 const __GLcontextModes * const * const b )
1174 {
1175 /* The order of these comparisons must NOT change. It is defined by
1176 * the GLX 1.3 spec and ARB_multisample.
1177 */
1178
1179 PREFER_SMALLER( visualSelectGroup );
1180
1181 /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
1182 * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the
1183 * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
1184 */
1185 PREFER_SMALLER( visualRating );
1186
1187 /* This isn't quite right. It is supposed to compare the sum of the
1188 * components the user specifically set minimums for.
1189 */
1190 PREFER_LARGER_OR_ZERO( redBits );
1191 PREFER_LARGER_OR_ZERO( greenBits );
1192 PREFER_LARGER_OR_ZERO( blueBits );
1193 PREFER_LARGER_OR_ZERO( alphaBits );
1194
1195 PREFER_SMALLER( rgbBits );
1196
1197 if ( ((*a)->doubleBufferMode != (*b)->doubleBufferMode) ) {
1198 /* Prefer single-buffer.
1199 */
1200 return ( !(*a)->doubleBufferMode ) ? -1 : 1;
1201 }
1202
1203 PREFER_SMALLER( numAuxBuffers );
1204
1205 PREFER_LARGER_OR_ZERO( depthBits );
1206 PREFER_SMALLER( stencilBits );
1207
1208 /* This isn't quite right. It is supposed to compare the sum of the
1209 * components the user specifically set minimums for.
1210 */
1211 PREFER_LARGER_OR_ZERO( accumRedBits );
1212 PREFER_LARGER_OR_ZERO( accumGreenBits );
1213 PREFER_LARGER_OR_ZERO( accumBlueBits );
1214 PREFER_LARGER_OR_ZERO( accumAlphaBits );
1215
1216 PREFER_SMALLER( visualType );
1217
1218 /* None of the multisample specs say where this comparison should happen,
1219 * so I put it near the end.
1220 */
1221 PREFER_SMALLER( sampleBuffers );
1222 PREFER_SMALLER( samples );
1223
1224 /* None of the pbuffer or fbconfig specs say that this comparison needs
1225 * to happen at all, but it seems like it should.
1226 */
1227 PREFER_LARGER( maxPbufferWidth );
1228 PREFER_LARGER( maxPbufferHeight );
1229 PREFER_LARGER( maxPbufferPixels );
1230
1231 return 0;
1232 }
1233
1234
1235 /**
1236 * Selects and sorts a subset of the supplied configs based on the attributes.
1237 * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
1238 * and \c glXChooseFBConfigSGIX.
1239 *
1240 * \param configs Array of pointers to possible configs. The elements of
1241 * this array that do not meet the criteria will be set to
1242 * NULL. The remaining elements will be sorted according to
1243 * the various visual / FBConfig selection rules.
1244 * \param num_configs Number of elements in the \c configs array.
1245 * \param attribList Attributes used select from \c configs. This array is
1246 * terminated by a \c None tag. The array can either take
1247 * the form expected by \c glXChooseVisual (where boolean
1248 * tags do not have a value) or by \c glXChooseFBConfig
1249 * (where every tag has a value).
1250 * \param fbconfig_style_tags Selects whether \c attribList is in
1251 * \c glXChooseVisual style or
1252 * \c glXChooseFBConfig style.
1253 * \returns The number of valid elements left in \c configs.
1254 *
1255 * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1256 */
1257 static int
1258 choose_visual( __GLcontextModes ** configs, int num_configs,
1259 const int *attribList, GLboolean fbconfig_style_tags )
1260 {
1261 __GLcontextModes test_config;
1262 int base;
1263 int i;
1264
1265 /* This is a fairly direct implementation of the selection method
1266 * described by GLX_SGIX_fbconfig. Start by culling out all the
1267 * configs that are not compatible with the selected parameter
1268 * list.
1269 */
1270
1271 init_fbconfig_for_chooser( & test_config, fbconfig_style_tags );
1272 __glXInitializeVisualConfigFromTags( & test_config, 512,
1273 (const INT32 *) attribList,
1274 GL_TRUE, fbconfig_style_tags );
1275
1276 base = 0;
1277 for ( i = 0 ; i < num_configs ; i++ ) {
1278 if ( fbconfigs_compatible( & test_config, configs[i] ) ) {
1279 configs[ base ] = configs[ i ];
1280 base++;
1281 }
1282 }
1283
1284 if ( base == 0 ) {
1285 return 0;
1286 }
1287
1288 if ( base < num_configs ) {
1289 (void) memset( & configs[ base ], 0,
1290 sizeof( void * ) * (num_configs - base) );
1291 }
1292
1293 /* After the incompatible configs are removed, the resulting
1294 * list is sorted according to the rules set out in the various
1295 * specifications.
1296 */
1297
1298 qsort( configs, base, sizeof( __GLcontextModes * ),
1299 (int (*)(const void*, const void*)) fbconfig_compare );
1300 return base;
1301 }
1302
1303
1304
1305
1306 /*
1307 ** Return the visual that best matches the template. Return None if no
1308 ** visual matches the template.
1309 */
1310 PUBLIC XVisualInfo *GLX_PREFIX(glXChooseVisual)(Display *dpy, int screen,
1311 int *attribList)
1312 {
1313 XVisualInfo *visualList = NULL;
1314 __GLXdisplayPrivate *priv;
1315 __GLXscreenConfigs *psc;
1316 __GLcontextModes test_config;
1317 __GLcontextModes *modes;
1318 const __GLcontextModes *best_config = NULL;
1319
1320 /*
1321 ** Get a list of all visuals, return if list is empty
1322 */
1323 if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) {
1324 return None;
1325 }
1326
1327
1328 /*
1329 ** Build a template from the defaults and the attribute list
1330 ** Free visual list and return if an unexpected token is encountered
1331 */
1332 init_fbconfig_for_chooser( & test_config, GL_FALSE );
1333 __glXInitializeVisualConfigFromTags( & test_config, 512,
1334 (const INT32 *) attribList,
1335 GL_TRUE, GL_FALSE );
1336
1337 /*
1338 ** Eliminate visuals that don't meet minimum requirements
1339 ** Compute a score for those that do
1340 ** Remember which visual, if any, got the highest score
1341 */
1342 for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) {
1343 if ( fbconfigs_compatible( & test_config, modes )
1344 && ((best_config == NULL)
1345 || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) {
1346 best_config = modes;
1347 }
1348 }
1349
1350 /*
1351 ** If no visual is acceptable, return None
1352 ** Otherwise, create an XVisualInfo list with just the selected X visual
1353 ** and return this.
1354 */
1355 if (best_config != NULL) {
1356 XVisualInfo visualTemplate;
1357 int i;
1358
1359 visualTemplate.screen = screen;
1360 visualTemplate.visualid = best_config->visualID;
1361 visualList = XGetVisualInfo( dpy, VisualScreenMask|VisualIDMask,
1362 &visualTemplate, &i );
1363 }
1364
1365 return visualList;
1366 }
1367
1368
1369 PUBLIC const char *GLX_PREFIX(glXQueryExtensionsString)( Display *dpy,
1370 int screen )
1371 {
1372 __GLXscreenConfigs *psc;
1373 __GLXdisplayPrivate *priv;
1374
1375 if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) {
1376 return NULL;
1377 }
1378
1379 if (!psc->effectiveGLXexts) {
1380 if (!psc->serverGLXexts) {
1381 psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
1382 X_GLXQueryServerString,
1383 screen, GLX_EXTENSIONS);
1384 }
1385
1386 __glXCalculateUsableExtensions(psc,
1387 #ifdef GLX_DIRECT_RENDERING
1388 (priv->driDisplay.private != NULL),
1389 #else
1390 GL_FALSE,
1391 #endif
1392 priv->minorVersion);
1393 }
1394
1395 return psc->effectiveGLXexts;
1396 }
1397
1398 PUBLIC const char *GLX_PREFIX(glXGetClientString)( Display *dpy, int name )
1399 {
1400 switch(name) {
1401 case GLX_VENDOR:
1402 return (__glXGLXClientVendorName);
1403 case GLX_VERSION:
1404 return (__glXGLXClientVersion);
1405 case GLX_EXTENSIONS:
1406 return (__glXGetClientExtensions());
1407 default:
1408 return NULL;
1409 }
1410 }
1411
1412 PUBLIC const char *GLX_PREFIX(glXQueryServerString)( Display *dpy, int screen,
1413 int name )
1414 {
1415 __GLXscreenConfigs *psc;
1416 __GLXdisplayPrivate *priv;
1417 const char ** str;
1418
1419
1420 if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) {
1421 return NULL;
1422 }
1423
1424 switch(name) {
1425 case GLX_VENDOR:
1426 str = & priv->serverGLXvendor;
1427 break;
1428 case GLX_VERSION:
1429 str = & priv->serverGLXversion;
1430 break;
1431 case GLX_EXTENSIONS:
1432 str = & psc->serverGLXexts;
1433 break;
1434 default:
1435 return NULL;
1436 }
1437
1438 if ( *str == NULL ) {
1439 *str = __glXGetStringFromServer(dpy, priv->majorOpcode,
1440 X_GLXQueryServerString, screen, name);
1441 }
1442
1443 return *str;
1444 }
1445
1446 void __glXClientInfo ( Display *dpy, int opcode )
1447 {
1448 xGLXClientInfoReq *req;
1449 int size;
1450 char * ext_str = __glXGetClientGLExtensionString();
1451
1452 /* Send the glXClientInfo request */
1453 LockDisplay(dpy);
1454 GetReq(GLXClientInfo,req);
1455 req->reqType = opcode;
1456 req->glxCode = X_GLXClientInfo;
1457 req->major = GLX_MAJOR_VERSION;
1458 req->minor = GLX_MINOR_VERSION;
1459
1460 size = strlen( ext_str ) + 1;
1461 req->length += (size + 3) >> 2;
1462 req->numbytes = size;
1463 Data(dpy, ext_str, size);
1464
1465 UnlockDisplay(dpy);
1466 SyncHandle();
1467
1468 Xfree( ext_str );
1469 }
1470
1471
1472 /*
1473 ** EXT_import_context
1474 */
1475
1476 PUBLIC Display *glXGetCurrentDisplay(void)
1477 {
1478 GLXContext gc = __glXGetCurrentContext();
1479 if (NULL == gc) return NULL;
1480 return gc->currentDpy;
1481 }
1482
1483 PUBLIC GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
1484 glXGetCurrentDisplay)
1485
1486 /**
1487 * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests
1488 * to the X-server.
1489 *
1490 * \param dpy Display where \c ctx was created.
1491 * \param ctx Context to query.
1492 * \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid,
1493 * or zero if the request failed due to internal problems (i.e.,
1494 * unable to allocate temporary memory, etc.)
1495 *
1496 * \note
1497 * This function dynamically determines whether to use the EXT_import_context
1498 * version of the protocol or the GLX 1.3 version of the protocol.
1499 */
1500 static int __glXQueryContextInfo(Display *dpy, GLXContext ctx)
1501 {
1502 __GLXdisplayPrivate *priv = __glXInitialize(dpy);
1503 xGLXQueryContextReply reply;
1504 CARD8 opcode;
1505 GLuint numValues;
1506 int retval;
1507
1508 if (ctx == NULL) {
1509 return GLX_BAD_CONTEXT;
1510 }
1511 opcode = __glXSetupForCommand(dpy);
1512 if (!opcode) {
1513 return 0;
1514 }
1515
1516 /* Send the glXQueryContextInfoEXT request */
1517 LockDisplay(dpy);
1518
1519 if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) {
1520 xGLXQueryContextReq *req;
1521
1522 GetReq(GLXQueryContext, req);
1523
1524 req->reqType = opcode;
1525 req->glxCode = X_GLXQueryContext;
1526 req->context = (unsigned int)(ctx->xid);
1527 }
1528 else {
1529 xGLXVendorPrivateReq *vpreq;
1530 xGLXQueryContextInfoEXTReq *req;
1531
1532 GetReqExtra( GLXVendorPrivate,
1533 sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
1534 vpreq );
1535 req = (xGLXQueryContextInfoEXTReq *)vpreq;
1536 req->reqType = opcode;
1537 req->glxCode = X_GLXVendorPrivateWithReply;
1538 req->vendorCode = X_GLXvop_QueryContextInfoEXT;
1539 req->context = (unsigned int)(ctx->xid);
1540 }
1541
1542 _XReply(dpy, (xReply*) &reply, 0, False);
1543
1544 numValues = reply.n;
1545 if (numValues == 0)
1546 retval = Success;
1547 else if (numValues > __GLX_MAX_CONTEXT_PROPS)
1548 retval = 0;
1549 else
1550 {
1551 int *propList, *pProp;
1552 int nPropListBytes;
1553 int i;
1554
1555 nPropListBytes = numValues << 3;
1556 propList = (int *) Xmalloc(nPropListBytes);
1557 if (NULL == propList) {
1558 retval = 0;
1559 } else {
1560 _XRead(dpy, (char *)propList, nPropListBytes);
1561 pProp = propList;
1562 for (i=0; i < numValues; i++) {
1563 switch (*pProp++) {
1564 case GLX_SHARE_CONTEXT_EXT:
1565 ctx->share_xid = *pProp++;
1566 break;
1567 case GLX_VISUAL_ID_EXT:
1568 ctx->vid = *pProp++;
1569 break;
1570 case GLX_SCREEN:
1571 ctx->screen = *pProp++;
1572 break;
1573 case GLX_FBCONFIG_ID:
1574 ctx->fbconfigID = *pProp++;
1575 break;
1576 case GLX_RENDER_TYPE:
1577 ctx->renderType = *pProp++;
1578 break;
1579 default:
1580 pProp++;
1581 continue;
1582 }
1583 }
1584 Xfree((char *)propList);
1585 retval = Success;
1586 }
1587 }
1588 UnlockDisplay(dpy);
1589 SyncHandle();
1590 return retval;
1591 }
1592
1593 PUBLIC int
1594 GLX_PREFIX(glXQueryContext)(Display *dpy, GLXContext ctx,
1595 int attribute, int *value)
1596 {
1597 int retVal;
1598
1599 /* get the information from the server if we don't have it already */
1600 if (!ctx->isDirect && (ctx->vid == None)) {
1601 retVal = __glXQueryContextInfo(dpy, ctx);
1602 if (Success != retVal) return retVal;
1603 }
1604 switch (attribute) {
1605 case GLX_SHARE_CONTEXT_EXT:
1606 *value = (int)(ctx->share_xid);
1607 break;
1608 case GLX_VISUAL_ID_EXT:
1609 *value = (int)(ctx->vid);
1610 break;
1611 case GLX_SCREEN:
1612 *value = (int)(ctx->screen);
1613 break;
1614 case GLX_FBCONFIG_ID:
1615 *value = (int)(ctx->fbconfigID);
1616 break;
1617 case GLX_RENDER_TYPE:
1618 *value = (int)(ctx->renderType);
1619 break;
1620 default:
1621 return GLX_BAD_ATTRIBUTE;
1622 }
1623 return Success;
1624 }
1625
1626 PUBLIC GLX_ALIAS( int, glXQueryContextInfoEXT,
1627 (Display *dpy, GLXContext ctx, int attribute, int *value),
1628 (dpy, ctx, attribute, value),
1629 glXQueryContext )
1630
1631 PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx)
1632 {
1633 return ctx->xid;
1634 }
1635
1636 PUBLIC GLXContext GLX_PREFIX(glXImportContextEXT)(Display *dpy,
1637 GLXContextID contextID)
1638 {
1639 GLXContext ctx;
1640
1641 if (contextID == None) {
1642 return NULL;
1643 }
1644 if (__glXIsDirect(dpy, contextID)) {
1645 return NULL;
1646 }
1647
1648 ctx = CreateContext(dpy, NULL, NULL, NULL, False, contextID, False, 0);
1649 if (NULL != ctx) {
1650 if (Success != __glXQueryContextInfo(dpy, ctx)) {
1651 return NULL;
1652 }
1653 }
1654 return ctx;
1655 }
1656
1657 PUBLIC void GLX_PREFIX(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
1658 {
1659 DestroyContext(dpy, ctx);
1660 }
1661
1662
1663
1664 /*
1665 * GLX 1.3 functions - these are just stubs for now!
1666 */
1667
1668 PUBLIC GLXFBConfig *GLX_PREFIX(glXChooseFBConfig)(Display *dpy, int screen,
1669 const int *attribList,
1670 int *nitems)
1671 {
1672 __GLcontextModes ** config_list;
1673 int list_size;
1674
1675
1676 config_list = (__GLcontextModes **)
1677 GLX_PREFIX(glXGetFBConfigs)( dpy, screen, & list_size );
1678
1679 if ( (config_list != NULL) && (list_size > 0) ) {
1680 list_size = choose_visual( config_list, list_size, attribList,
1681 GL_TRUE );
1682 if ( list_size == 0 ) {
1683 XFree( config_list );
1684 config_list = NULL;
1685 }
1686 }
1687
1688 *nitems = list_size;
1689 return (GLXFBConfig *) config_list;
1690 }
1691
1692
1693 PUBLIC GLXContext GLX_PREFIX(glXCreateNewContext)(Display *dpy,
1694 GLXFBConfig config,
1695 int renderType,
1696 GLXContext shareList,
1697 Bool allowDirect)
1698 {
1699 return CreateContext( dpy, NULL, (__GLcontextModes *) config, shareList,
1700 allowDirect, None, True, renderType );
1701 }
1702
1703
1704 PUBLIC GLXDrawable GLX_PREFIX(glXGetCurrentReadDrawable)(void)
1705 {
1706 GLXContext gc = __glXGetCurrentContext();
1707 return gc->currentReadable;
1708 }
1709
1710
1711 PUBLIC GLXFBConfig *GLX_PREFIX(glXGetFBConfigs)(Display *dpy, int screen,
1712 int *nelements)
1713 {
1714 __GLXdisplayPrivate *priv = __glXInitialize(dpy);
1715 __GLcontextModes ** config = NULL;
1716 int i;
1717
1718 if ( (priv->screenConfigs != NULL)
1719 && (screen >= 0) && (screen <= ScreenCount(dpy))
1720 && (priv->screenConfigs[screen].configs != NULL)
1721 && (priv->screenConfigs[screen].configs->fbconfigID != GLX_DONT_CARE) ) {
1722 unsigned num_configs = 0;
1723 __GLcontextModes * modes;
1724
1725
1726 for ( modes = priv->screenConfigs[screen].configs
1727 ; modes != NULL
1728 ; modes = modes->next ) {
1729 if ( modes->fbconfigID != GLX_DONT_CARE ) {
1730 num_configs++;
1731 }
1732 }
1733
1734 config = (__GLcontextModes **) Xmalloc( sizeof(__GLcontextModes *)
1735 * num_configs );
1736 if ( config != NULL ) {
1737 *nelements = num_configs;
1738 i = 0;
1739 for ( modes = priv->screenConfigs[screen].configs
1740 ; modes != NULL
1741 ; modes = modes->next ) {
1742 config[i] = modes;
1743 i++;
1744 }
1745 }
1746 }
1747 return (GLXFBConfig *) config;
1748 }
1749
1750
1751 PUBLIC int GLX_PREFIX(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config,
1752 int attribute, int *value)
1753 {
1754 __GLcontextModes * const modes = ValidateGLXFBConfig( dpy, config );
1755
1756 return (modes != NULL)
1757 ? _gl_get_context_mode_data( modes, attribute, value )
1758 : GLXBadFBConfig;
1759 }
1760
1761
1762 PUBLIC XVisualInfo *GLX_PREFIX(glXGetVisualFromFBConfig)(Display *dpy,
1763 GLXFBConfig config)
1764 {
1765 XVisualInfo visualTemplate;
1766 __GLcontextModes * fbconfig = (__GLcontextModes *) config;
1767 int count;
1768
1769 /*
1770 ** Get a list of all visuals, return if list is empty
1771 */
1772 visualTemplate.visualid = fbconfig->visualID;
1773 return XGetVisualInfo(dpy,VisualIDMask,&visualTemplate,&count);
1774 }
1775
1776
1777 /*
1778 ** GLX_SGI_make_current_read
1779 */
1780
1781 PUBLIC GLX_ALIAS(GLXDrawable, glXGetCurrentReadDrawableSGI, (void), (),
1782 glXGetCurrentReadDrawable)
1783
1784
1785 /*
1786 ** GLX_SGI_swap_control
1787 */
1788 PUBLIC int GLX_PREFIX(glXSwapIntervalSGI)(int interval)
1789 {
1790 xGLXVendorPrivateReq *req;
1791 GLXContext gc = __glXGetCurrentContext();
1792 Display * dpy;
1793 CARD32 * interval_ptr;
1794 CARD8 opcode;
1795
1796 if ( gc == NULL ) {
1797 return GLX_BAD_CONTEXT;
1798 }
1799
1800 if ( interval <= 0 ) {
1801 return GLX_BAD_VALUE;
1802 }
1803
1804 #ifdef GLX_DIRECT_RENDERING
1805 if ( gc->isDirect ) {
1806 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
1807 gc->screen );
1808 __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy,
1809 gc->currentDrawable,
1810 NULL );
1811 if ( __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit )
1812 && (pdraw != NULL) ) {
1813 pdraw->swap_interval = interval;
1814 return 0;
1815 }
1816 else {
1817 return GLX_BAD_CONTEXT;
1818 }
1819 }
1820 #endif
1821 dpy = gc->currentDpy;
1822 opcode = __glXSetupForCommand(dpy);
1823 if (!opcode) {
1824 return 0;
1825 }
1826
1827 /* Send the glXSwapIntervalSGI request */
1828 LockDisplay(dpy);
1829 GetReqExtra(GLXVendorPrivate,sizeof(CARD32),req);
1830 req->reqType = opcode;
1831 req->glxCode = X_GLXVendorPrivate;
1832 req->vendorCode = X_GLXvop_SwapIntervalSGI;
1833 req->contextTag = gc->currentContextTag;
1834
1835 interval_ptr = (CARD32 *) req + 1;
1836 *interval_ptr = interval;
1837
1838 UnlockDisplay(dpy);
1839 SyncHandle();
1840 XFlush(dpy);
1841
1842 return 0;
1843 }
1844
1845
1846 /*
1847 ** GLX_MESA_swap_control
1848 */
1849 PUBLIC GLint GLX_PREFIX(glXSwapIntervalMESA)(unsigned interval)
1850 {
1851 #ifdef GLX_DIRECT_RENDERING
1852 GLXContext gc = __glXGetCurrentContext();
1853
1854 if ( interval < 0 ) {
1855 return GLX_BAD_VALUE;
1856 }
1857
1858 if ( (gc != NULL) && gc->isDirect ) {
1859 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
1860 gc->screen );
1861
1862 if ( (psc != NULL) && (psc->driScreen.private != NULL)
1863 && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
1864 __DRIdrawable * const pdraw =
1865 (*psc->driScreen.getDrawable)(gc->currentDpy,
1866 gc->currentDrawable,
1867 psc->driScreen.private);
1868 if ( pdraw != NULL ) {
1869 pdraw->swap_interval = interval;
1870 return 0;
1871 }
1872 }
1873 }
1874 #else
1875 (void) interval;
1876 #endif
1877
1878 return GLX_BAD_CONTEXT;
1879 }
1880
1881 PUBLIC GLint GLX_PREFIX(glXGetSwapIntervalMESA)( void )
1882 {
1883 #ifdef GLX_DIRECT_RENDERING
1884 GLXContext gc = __glXGetCurrentContext();
1885
1886 if ( (gc != NULL) && gc->isDirect ) {
1887 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
1888 gc->screen );
1889
1890 if ( (psc != NULL) && (psc->driScreen.private != NULL)
1891 && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
1892 __DRIdrawable * const pdraw =
1893 (*psc->driScreen.getDrawable)(gc->currentDpy,
1894 gc->currentDrawable,
1895 psc->driScreen.private);
1896 if ( pdraw != NULL ) {
1897 return pdraw->swap_interval;
1898 }
1899 }
1900 }
1901 #endif
1902
1903 return 0;
1904 }
1905
1906
1907 /*
1908 ** GLX_MESA_swap_frame_usage
1909 */
1910
1911 PUBLIC GLint GLX_PREFIX(glXBeginFrameTrackingMESA)(Display *dpy,
1912 GLXDrawable drawable)
1913 {
1914 int status = GLX_BAD_CONTEXT;
1915 #ifdef GLX_DIRECT_RENDERING
1916 int screen;
1917 __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
1918 __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
1919
1920 if ( (pdraw != NULL) && (pdraw->frameTracking != NULL)
1921 && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
1922 status = pdraw->frameTracking( dpy, pdraw->private, GL_TRUE );
1923 }
1924 #else
1925 (void) dpy;
1926 (void) drawable;
1927 #endif
1928 return status;
1929 }
1930
1931
1932 PUBLIC GLint GLX_PREFIX(glXEndFrameTrackingMESA)(Display *dpy,
1933 GLXDrawable drawable)
1934 {
1935 int status = GLX_BAD_CONTEXT;
1936 #ifdef GLX_DIRECT_RENDERING
1937 int screen;
1938 __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
1939 __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
1940
1941 if ( (pdraw != NULL) && (pdraw->frameTracking != NULL)
1942 && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
1943 status = pdraw->frameTracking( dpy, pdraw->private, GL_FALSE );
1944 }
1945 #else
1946 (void) dpy;
1947 (void) drawable;
1948 #endif
1949 return status;
1950 }
1951
1952
1953 PUBLIC GLint GLX_PREFIX(glXGetFrameUsageMESA)(Display *dpy,
1954 GLXDrawable drawable,
1955 GLfloat *usage)
1956 {
1957 int status = GLX_BAD_CONTEXT;
1958 #ifdef GLX_DIRECT_RENDERING
1959 int screen;
1960 __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
1961 __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
1962
1963 if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL)
1964 && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
1965 int64_t sbc, missedFrames;
1966 float lastMissedUsage;
1967
1968 status = pdraw->queryFrameTracking( dpy, pdraw->private, &sbc,
1969 &missedFrames, &lastMissedUsage,
1970 usage );
1971 }
1972 #else
1973 (void) dpy;
1974 (void) drawable;
1975 (void) usage;
1976 #endif
1977 return status;
1978 }
1979
1980
1981 PUBLIC GLint GLX_PREFIX(glXQueryFrameTrackingMESA)(Display *dpy,
1982 GLXDrawable drawable,
1983 int64_t *sbc,
1984 int64_t *missedFrames,
1985 GLfloat *lastMissedUsage)
1986 {
1987 int status = GLX_BAD_CONTEXT;
1988 #ifdef GLX_DIRECT_RENDERING
1989 int screen;
1990 __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
1991 __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
1992
1993 if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL)
1994 && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
1995 float usage;
1996
1997 status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc,
1998 missedFrames, lastMissedUsage,
1999 & usage );
2000 }
2001 #else
2002 (void) dpy;
2003 (void) drawable;
2004 (void) sbc;
2005 (void) missedFrames;
2006 (void) lastMissedUsage;
2007 #endif
2008 return status;
2009 }
2010
2011
2012 /*
2013 ** GLX_SGI_video_sync
2014 */
2015 PUBLIC int GLX_PREFIX(glXGetVideoSyncSGI)(unsigned int *count)
2016 {
2017 /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
2018 * FIXME: there should be a GLX encoding for this call. I can find no
2019 * FIXME: documentation for the GLX encoding.
2020 */
2021 #ifdef GLX_DIRECT_RENDERING
2022 GLXContext gc = __glXGetCurrentContext();
2023
2024
2025 if ( (gc != NULL) && gc->isDirect ) {
2026 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
2027 gc->screen );
2028 if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
2029 && psc->driScreen.private && psc->driScreen.getMSC) {
2030 int ret;
2031 int64_t temp;
2032
2033 ret = psc->driScreen.getMSC( psc->driScreen.private, & temp );
2034 *count = (unsigned) temp;
2035 return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
2036 }
2037 }
2038 #else
2039 (void) count;
2040 #endif
2041 return GLX_BAD_CONTEXT;
2042 }
2043
2044 PUBLIC int GLX_PREFIX(glXWaitVideoSyncSGI)(int divisor, int remainder,
2045 unsigned int *count)
2046 {
2047 #ifdef GLX_DIRECT_RENDERING
2048 GLXContext gc = __glXGetCurrentContext();
2049
2050 if ( divisor <= 0 || remainder < 0 )
2051 return GLX_BAD_VALUE;
2052
2053 if ( (gc != NULL) && gc->isDirect ) {
2054 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
2055 gc->screen );
2056 if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
2057 && psc->driScreen.private ) {
2058 __DRIdrawable * const pdraw =
2059 (*psc->driScreen.getDrawable)(gc->currentDpy,
2060 gc->currentDrawable,
2061 psc->driScreen.private);
2062 if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) {
2063 int ret;
2064 int64_t msc;
2065 int64_t sbc;
2066
2067 ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private,
2068 0, divisor, remainder,
2069 & msc, & sbc );
2070 *count = (unsigned) msc;
2071 return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
2072 }
2073 }
2074 }
2075 #else
2076 (void) count;
2077 #endif
2078 return GLX_BAD_CONTEXT;
2079 }
2080
2081
2082 /*
2083 ** GLX_SGIS_video_source
2084 */
2085 #if defined(_VL_H)
2086
2087 PUBLIC GLXVideoSourceSGIX GLX_PREFIX(glXCreateGLXVideoSourceSGIX)(Display *dpy,
2088 int screen, VLServer server, VLPath path,
2089 int nodeClass, VLNode drainNode)
2090 {
2091 (void) dpy;
2092 (void) screen;
2093 (void) server;
2094 (void) path;
2095 (void) nodeClass;
2096 (void) drainNode;
2097 return 0;
2098 }
2099
2100 PUBLIC void GLX_PREFIX(glXDestroyGLXVideoSourceSGIX)(Display *dpy,
2101 GLXVideoSourceSGIX src)
2102 {
2103 (void) dpy;
2104 (void) src;
2105 }
2106
2107 #endif
2108
2109
2110 /*
2111 ** GLX_SGIX_fbconfig
2112 ** Many of these functions are aliased to GLX 1.3 entry points in the
2113 ** GLX_functions table.
2114 */
2115
2116 PUBLIC GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
2117 (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value),
2118 (dpy, config, attribute, value),
2119 glXGetFBConfigAttrib)
2120
2121 PUBLIC GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
2122 (Display *dpy, int screen, int *attrib_list, int *nelements),
2123 (dpy, screen, attrib_list, nelements),
2124 glXChooseFBConfig)
2125
2126 PUBLIC GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
2127 (Display * dpy, GLXFBConfigSGIX config),
2128 (dpy, config),
2129 glXGetVisualFromFBConfig)
2130
2131 PUBLIC GLXPixmap GLX_PREFIX(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy,
2132 GLXFBConfigSGIX config, Pixmap pixmap)
2133 {
2134 xGLXVendorPrivateWithReplyReq *vpreq;
2135 xGLXCreateGLXPixmapWithConfigSGIXReq *req;
2136 GLXPixmap xid = None;
2137 CARD8 opcode;
2138 const __GLcontextModes * const fbconfig = (__GLcontextModes *) config;
2139 __GLXscreenConfigs * psc;
2140
2141
2142 if ( (dpy == NULL) || (config == NULL) ) {
2143 return None;
2144 }
2145
2146 psc = GetGLXScreenConfigs( dpy, fbconfig->screen );
2147 if ( (psc != NULL)
2148 && __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) {
2149 opcode = __glXSetupForCommand(dpy);
2150 if (!opcode) {
2151 return None;
2152 }
2153
2154 /* Send the glXCreateGLXPixmapWithConfigSGIX request */
2155 LockDisplay(dpy);
2156 GetReqExtra(GLXVendorPrivateWithReply,
2157 sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
2158 req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
2159 req->reqType = opcode;
2160 req->glxCode = X_GLXVendorPrivateWithReply;
2161 req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
2162 req->screen = fbconfig->screen;
2163 req->fbconfig = fbconfig->fbconfigID;
2164 req->pixmap = pixmap;
2165 req->glxpixmap = xid = XAllocID(dpy);
2166 UnlockDisplay(dpy);
2167 SyncHandle();
2168 }
2169
2170 return xid;
2171 }
2172
2173 PUBLIC GLXContext GLX_PREFIX(glXCreateContextWithConfigSGIX)(Display *dpy,
2174 GLXFBConfigSGIX config, int renderType,
2175 GLXContext shareList, Bool allowDirect)
2176 {
2177 GLXContext gc = NULL;
2178 const __GLcontextModes * const fbconfig = (__GLcontextModes *) config;
2179 __GLXscreenConfigs * psc;
2180
2181
2182 if ( (dpy == NULL) || (config == NULL) ) {
2183 return None;
2184 }
2185
2186 psc = GetGLXScreenConfigs( dpy, fbconfig->screen );
2187 if ( (psc != NULL)
2188 && __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) {
2189 gc = CreateContext( dpy, NULL, (__GLcontextModes *) config, shareList,
2190 allowDirect, None, False, renderType );
2191 }
2192
2193 return gc;
2194 }
2195
2196
2197 PUBLIC GLXFBConfigSGIX GLX_PREFIX(glXGetFBConfigFromVisualSGIX)(Display *dpy,
2198 XVisualInfo *vis)
2199 {
2200 __GLXdisplayPrivate *priv;
2201 __GLXscreenConfigs *psc;
2202
2203 if ( (GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc ) != Success)
2204 && __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit )
2205 && (psc->configs->fbconfigID != GLX_DONT_CARE) ) {
2206 return (GLXFBConfigSGIX) _gl_context_modes_find_visual( psc->configs,
2207 vis->visualid );
2208 }
2209
2210 return NULL;
2211 }
2212
2213
2214 /*
2215 ** GLX_SGI_cushion
2216 */
2217 PUBLIC void GLX_PREFIX(glXCushionSGI)(Display *dpy, Window win, float cushion)
2218 {
2219 (void) dpy;
2220 (void) win;
2221 (void) cushion;
2222 }
2223
2224
2225 /*
2226 ** GLX_SGIX_video_resize
2227 */
2228 PUBLIC int GLX_PREFIX(glXBindChannelToWindowSGIX)(Display *dpy, int screen,
2229 int channel , Window window)
2230 {
2231 (void) dpy;
2232 (void) screen;
2233 (void) channel;
2234 (void) window;
2235 return 0;
2236 }
2237
2238 PUBLIC int GLX_PREFIX(glXChannelRectSGIX)(Display *dpy, int screen, int channel,
2239 int x, int y, int w, int h)
2240 {
2241 (void) dpy;
2242 (void) screen;
2243 (void) channel;
2244 (void) x;
2245 (void) y;
2246 (void) w;
2247 (void) h;
2248 return 0;
2249 }
2250
2251 PUBLIC int GLX_PREFIX(glXQueryChannelRectSGIX)(Display *dpy, int screen,
2252 int channel, int *x, int *y,
2253 int *w, int *h)
2254 {
2255 (void) dpy;
2256 (void) screen;
2257 (void) channel;
2258 (void) x;
2259 (void) y;
2260 (void) w;
2261 (void) h;
2262 return 0;
2263 }
2264
2265 int GLX_PREFIX(glXQueryChannelDeltasSGIX)(Display *dpy, int screen, int channel,
2266 int *dx, int *dy, int *dw, int *dh)
2267 {
2268 (void) dpy;
2269 (void) screen;
2270 (void) channel;
2271 (void) dx;
2272 (void) dy;
2273 (void) dw;
2274 (void) dh;
2275 return 0;
2276 }
2277
2278 PUBLIC int GLX_PREFIX(glXChannelRectSyncSGIX)(Display *dpy, int screen,
2279 int channel, GLenum synctype)
2280 {
2281 (void) dpy;
2282 (void) screen;
2283 (void) channel;
2284 (void) synctype;
2285 return 0;
2286 }
2287
2288
2289 #if defined(_DM_BUFFER_H_)
2290
2291 PUBLIC Bool GLX_PREFIX(glXAssociateDMPbufferSGIX)(Display *dpy,
2292 GLXPbufferSGIX pbuffer,
2293 DMparams *params,
2294 DMbuffer dmbuffer)
2295 {
2296 (void) dpy;
2297 (void) pbuffer;
2298 (void) params;
2299 (void) dmbuffer;
2300 return False;
2301 }
2302
2303 #endif
2304
2305
2306 /*
2307 ** GLX_SGIX_swap_group
2308 */
2309 PUBLIC void GLX_PREFIX(glXJoinSwapGroupSGIX)(Display *dpy, GLXDrawable drawable,
2310 GLXDrawable member)
2311 {
2312 (void) dpy;
2313 (void) drawable;
2314 (void) member;
2315 }
2316
2317
2318 /*
2319 ** GLX_SGIX_swap_barrier
2320 */
2321 PUBLIC void GLX_PREFIX(glXBindSwapBarrierSGIX)(Display *dpy,
2322 GLXDrawable drawable,
2323 int barrier)
2324 {
2325 (void) dpy;
2326 (void) drawable;
2327 (void) barrier;
2328 }
2329
2330 PUBLIC Bool GLX_PREFIX(glXQueryMaxSwapBarriersSGIX)(Display *dpy, int screen,
2331 int *max)
2332 {
2333 (void) dpy;
2334 (void) screen;
2335 (void) max;
2336 return False;
2337 }
2338
2339
2340 /*
2341 ** GLX_SUN_get_transparent_index
2342 */
2343 PUBLIC Status GLX_PREFIX(glXGetTransparentIndexSUN)(Display *dpy,
2344 Window overlay,
2345 Window underlay,
2346 long *pTransparent)
2347 {
2348 (void) dpy;
2349 (void) overlay;
2350 (void) underlay;
2351 (void) pTransparent;
2352 return 0;
2353 }
2354
2355
2356 /*
2357 ** GLX_OML_sync_control
2358 */
2359 PUBLIC Bool GLX_PREFIX(glXGetSyncValuesOML)(Display *dpy, GLXDrawable drawable,
2360 int64_t *ust, int64_t *msc, int64_t *sbc)
2361 {
2362 #ifdef GLX_DIRECT_RENDERING
2363 __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
2364
2365 if ( priv != NULL ) {
2366 int i;
2367 __DRIdrawable * const pdraw = GetDRIDrawable( dpy, drawable, & i );
2368 __GLXscreenConfigs * const psc = &priv->screenConfigs[i];
2369
2370 assert( (pdraw == NULL) || (i != -1) );
2371 return ( (pdraw && pdraw->getSBC && psc->driScreen.getMSC)
2372 && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )
2373 && ((*psc->driScreen.getMSC)( psc->driScreen.private, msc ) == 0)
2374 && ((*pdraw->getSBC)( dpy, psc->driScreen.private, sbc ) == 0)
2375 && (__glXGetUST( ust ) == 0) );
2376 }
2377 #else
2378 (void) dpy;
2379 (void) drawable;
2380 (void) ust;
2381 (void) msc;
2382 (void) sbc;
2383 #endif
2384 return False;
2385 }
2386
2387
2388 /**
2389 * Determine the refresh rate of the specified drawable and display.
2390 *
2391 * \param dpy Display whose refresh rate is to be determined.
2392 * \param drawable Drawable whose refresh rate is to be determined.
2393 * \param numerator Numerator of the refresh rate.
2394 * \param demoninator Denominator of the refresh rate.
2395 * \return If the refresh rate for the specified display and drawable could
2396 * be calculated, True is returned. Otherwise False is returned.
2397 *
2398 * \note This function is implemented entirely client-side. A lot of other
2399 * functionality is required to export GLX_OML_sync_control, so on
2400 * XFree86 this function can be called for direct-rendering contexts
2401 * when GLX_OML_sync_control appears in the client extension string.
2402 */
2403
2404 PUBLIC Bool GLX_PREFIX(glXGetMscRateOML)(Display * dpy, GLXDrawable drawable,
2405 int32_t * numerator, int32_t * denominator)
2406 {
2407 #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
2408 __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
2409
2410
2411 if ( priv != NULL ) {
2412 XF86VidModeModeLine mode_line;
2413 int dot_clock;
2414 int screen_num;
2415 int i;
2416
2417
2418 GetDRIDrawable( dpy, drawable, & screen_num );
2419 if ( (screen_num != -1)
2420 && XF86VidModeQueryVersion( dpy, & i, & i )
2421 && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock,
2422 & mode_line ) ) {
2423 unsigned n = dot_clock * 1000;
2424 unsigned d = mode_line.vtotal * mode_line.htotal;
2425
2426 # define V_INTERLACE 0x010
2427 # define V_DBLSCAN 0x020
2428
2429 if ( (mode_line.flags & V_INTERLACE) ) {
2430 n *= 2;
2431 }
2432 else if ( (mode_line.flags & V_DBLSCAN) ) {
2433 d *= 2;
2434 }
2435
2436 /* The OML_sync_control spec requires that if the refresh rate is a
2437 * whole number, that the returned numerator be equal to the refresh
2438 * rate and the denominator be 1.
2439 */
2440
2441 if ( (n % d) == 0 ) {
2442 n /= d;
2443 d = 1;
2444 }
2445 else {
2446 static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
2447
2448
2449 /* This is a poor man's way to reduce a fraction. It's far from
2450 * perfect, but it will work well enough for this situation.
2451 */
2452
2453 for ( i = 0 ; f[i] != 0 ; i++ ) {
2454 while ( ((n % f[i]) == 0) && ((d % f[i]) == 0) ) {
2455 d /= f[i];
2456 n /= f[i];
2457 }
2458 }
2459 }
2460
2461 *numerator = n;
2462 *denominator = d;
2463
2464 (void) drawable;
2465 return True;
2466 }
2467 }
2468 #else
2469 (void) dpy;
2470 (void) drawable;
2471 (void) numerator;
2472 (void) denominator;
2473 #endif
2474 return False;
2475 }
2476
2477
2478 PUBLIC int64_t GLX_PREFIX(glXSwapBuffersMscOML)(Display *dpy,
2479 GLXDrawable drawable,
2480 int64_t target_msc,
2481 int64_t divisor,
2482 int64_t remainder)
2483 {
2484 #ifdef GLX_DIRECT_RENDERING
2485 int screen;
2486 __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
2487 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
2488
2489 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2490 * error", but it also says "It [glXSwapBuffersMscOML] will return a value
2491 * of -1 if the function failed because of errors detected in the input
2492 * parameters"
2493 */
2494 if ( divisor < 0 || remainder < 0 || target_msc < 0 )
2495 return -1;
2496 if ( divisor > 0 && remainder >= divisor )
2497 return -1;
2498
2499 if ( (pdraw != NULL) && (pdraw->swapBuffersMSC != NULL)
2500 && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) {
2501 return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc,
2502 divisor, remainder);
2503 }
2504 #else
2505 (void) dpy;
2506 (void) drawable;
2507 (void) target_msc;
2508 (void) divisor;
2509 (void) remainder;
2510 #endif
2511 return 0;
2512 }
2513
2514
2515 PUBLIC Bool GLX_PREFIX(glXWaitForMscOML)(Display * dpy, GLXDrawable drawable,
2516 int64_t target_msc, int64_t divisor,
2517 int64_t remainder, int64_t *ust,
2518 int64_t *msc, int64_t *sbc)
2519 {
2520 #ifdef GLX_DIRECT_RENDERING
2521 int screen;
2522 __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
2523 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
2524 int ret;
2525
2526 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2527 * error", but the return type in the spec is Bool.
2528 */
2529 if ( divisor < 0 || remainder < 0 || target_msc < 0 )
2530 return False;
2531 if ( divisor > 0 && remainder >= divisor )
2532 return False;
2533
2534 if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL)
2535 && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) {
2536 ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc,
2537 divisor, remainder, msc, sbc );
2538
2539 /* __glXGetUST returns zero on success and non-zero on failure.
2540 * This function returns True on success and False on failure.
2541 */
2542 return ( (ret == 0) && (__glXGetUST( ust ) == 0) );
2543 }
2544 #else
2545 (void) dpy;
2546 (void) drawable;
2547 (void) target_msc;
2548 (void) divisor;
2549 (void) remainder;
2550 (void) ust;
2551 (void) msc;
2552 (void) sbc;
2553 #endif
2554 return False;
2555 }
2556
2557
2558 PUBLIC Bool GLX_PREFIX(glXWaitForSbcOML)(Display * dpy, GLXDrawable drawable,
2559 int64_t target_sbc, int64_t *ust,
2560 int64_t *msc, int64_t *sbc )
2561 {
2562 #ifdef GLX_DIRECT_RENDERING
2563 int screen;
2564 __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
2565 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
2566 int ret;
2567
2568 /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
2569 * error", but the return type in the spec is Bool.
2570 */
2571 if ( target_sbc < 0 )
2572 return False;
2573
2574 if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL)
2575 && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) {
2576 ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc );
2577
2578 /* __glXGetUST returns zero on success and non-zero on failure.
2579 * This function returns True on success and False on failure.
2580 */
2581 return( (ret == 0) && (__glXGetUST( ust ) == 0) );
2582 }
2583 #else
2584 (void) dpy;
2585 (void) drawable;
2586 (void) target_sbc;
2587 (void) ust;
2588 (void) msc;
2589 (void) sbc;
2590 #endif
2591 return False;
2592 }
2593
2594
2595 /**
2596 * GLX_MESA_allocate_memory
2597 */
2598 /*@{*/
2599
2600 PUBLIC void *GLX_PREFIX(glXAllocateMemoryMESA)(Display *dpy, int scrn,
2601 size_t size, float readFreq,
2602 float writeFreq, float priority)
2603 {
2604 #ifdef GLX_DIRECT_RENDERING
2605 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
2606
2607 if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
2608 if (psc && psc->driScreen.private && psc->driScreen.allocateMemory) {
2609 return (*psc->driScreen.allocateMemory)( dpy, scrn, size,
2610 readFreq, writeFreq,
2611 priority );
2612 }
2613 }
2614 #else
2615 (void) dpy;
2616 (void) scrn;
2617 (void) size;
2618 (void) readFreq;
2619 (void) writeFreq;
2620 (void) priority;
2621 #endif /* GLX_DIRECT_RENDERING */
2622
2623 return NULL;
2624 }
2625
2626
2627 PUBLIC void GLX_PREFIX(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
2628 {
2629 #ifdef GLX_DIRECT_RENDERING
2630 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
2631
2632 if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
2633 if (psc && psc->driScreen.private && psc->driScreen.freeMemory) {
2634 (*psc->driScreen.freeMemory)( dpy, scrn, pointer );
2635 }
2636 }
2637 #else
2638 (void) dpy;
2639 (void) scrn;
2640 (void) pointer;
2641 #endif /* GLX_DIRECT_RENDERING */
2642 }
2643
2644
2645 PUBLIC GLuint GLX_PREFIX(glXGetMemoryOffsetMESA)( Display *dpy, int scrn,
2646 const void *pointer )
2647 {
2648 #ifdef GLX_DIRECT_RENDERING
2649 __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
2650
2651 if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
2652 if (psc && psc->driScreen.private && psc->driScreen.memoryOffset) {
2653 return (*psc->driScreen.memoryOffset)( dpy, scrn, pointer );
2654 }
2655 }
2656 #else
2657 (void) dpy;
2658 (void) scrn;
2659 (void) pointer;
2660 #endif /* GLX_DIRECT_RENDERING */
2661
2662 return ~0L;
2663 }
2664 /*@}*/
2665
2666
2667 /**
2668 * Mesa extension stubs. These will help reduce portability problems.
2669 */
2670 /*@{*/
2671
2672 /**
2673 * Release all buffers associated with the specified GLX drawable.
2674 *
2675 * \todo
2676 * This function was intended for stand-alone Mesa. The issue there is that
2677 * the library doesn't get any notification when a window is closed. In
2678 * DRI there is a similar but slightly different issue. When GLX 1.3 is
2679 * supported, there are 3 different functions to destroy a drawable. It
2680 * should be possible to create GLX protocol (or have it determine which
2681 * protocol to use based on the type of the drawable) to have one function
2682 * do the work of 3. For the direct-rendering case, this function could
2683 * just call the driver's \c __DRIdrawableRec::destroyDrawable function.
2684 * This would reduce the frequency with which \c __driGarbageCollectDrawables
2685 * would need to be used. This really should be done as part of the new DRI
2686 * interface work.
2687 *
2688 * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt
2689 * __driGarbageCollectDrawables
2690 * glXDestroyGLXPixmap
2691 * glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
2692 * glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
2693 */
2694 PUBLIC Bool GLX_PREFIX(glXReleaseBuffersMESA)( Display *dpy, GLXDrawable d )
2695 {
2696 (void) dpy;
2697 (void) d;
2698 return False;
2699 }
2700
2701
2702 PUBLIC GLXPixmap GLX_PREFIX(glXCreateGLXPixmapMESA)( Display *dpy,
2703 XVisualInfo *visual,
2704 Pixmap pixmap,
2705 Colormap cmap )
2706 {
2707 (void) dpy;
2708 (void) visual;
2709 (void) pixmap;
2710 (void) cmap;
2711 return 0;
2712 }
2713
2714
2715 PUBLIC void GLX_PREFIX(glXCopySubBufferMESA)(Display *dpy, GLXDrawable drawable,
2716 int x, int y,
2717 int width, int height)
2718 {
2719 (void) dpy;
2720 (void) drawable;
2721 (void) x;
2722 (void) y;
2723 (void) width;
2724 (void) height;
2725 }
2726
2727
2728 PUBLIC Bool GLX_PREFIX(glXSet3DfxModeMESA)( int mode )
2729 {
2730 (void) mode;
2731 return GL_FALSE;
2732 }
2733 /*@}*/
2734
2735
2736
2737 /**
2738 * \c strdup is actually not a standard ANSI C or POSIX routine.
2739 * Irix will not define it if ANSI mode is in effect.
2740 *
2741 * \sa strdup
2742 */
2743 char *
2744 __glXstrdup(const char *str)
2745 {
2746 char *copy;
2747 copy = (char *) Xmalloc(strlen(str) + 1);
2748 if (!copy)
2749 return NULL;
2750 strcpy(copy, str);
2751 return copy;
2752 }
2753
2754 /*
2755 ** glXGetProcAddress support
2756 */
2757
2758 struct name_address_pair {
2759 const char *Name;
2760 GLvoid *Address;
2761 };
2762
2763 #define GLX_FUNCTION(f) { # f, (GLvoid *) f }
2764 #define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f }
2765
2766 static const struct name_address_pair GLX_functions[] = {
2767 /*** GLX_VERSION_1_0 ***/
2768 GLX_FUNCTION( glXChooseVisual ),
2769 GLX_FUNCTION( glXCopyContext ),
2770 GLX_FUNCTION( glXCreateContext ),
2771 GLX_FUNCTION( glXCreateGLXPixmap ),
2772 GLX_FUNCTION( glXDestroyContext ),
2773 GLX_FUNCTION( glXDestroyGLXPixmap ),
2774 GLX_FUNCTION( glXGetConfig ),
2775 GLX_FUNCTION( glXGetCurrentContext ),
2776 GLX_FUNCTION( glXGetCurrentDrawable ),
2777 GLX_FUNCTION( glXIsDirect ),
2778 GLX_FUNCTION( glXMakeCurrent ),
2779 GLX_FUNCTION( glXQueryExtension ),
2780 GLX_FUNCTION( glXQueryVersion ),
2781 GLX_FUNCTION( glXSwapBuffers ),
2782 GLX_FUNCTION( glXUseXFont ),
2783 GLX_FUNCTION( glXWaitGL ),
2784 GLX_FUNCTION( glXWaitX ),
2785
2786 /*** GLX_VERSION_1_1 ***/
2787 GLX_FUNCTION( glXGetClientString ),
2788 GLX_FUNCTION( glXQueryExtensionsString ),
2789 GLX_FUNCTION( glXQueryServerString ),
2790
2791 /*** GLX_VERSION_1_2 ***/
2792 GLX_FUNCTION( glXGetCurrentDisplay ),
2793
2794 /*** GLX_VERSION_1_3 ***/
2795 GLX_FUNCTION( glXChooseFBConfig ),
2796 GLX_FUNCTION( glXCreateNewContext ),
2797 GLX_FUNCTION( glXCreatePbuffer ),
2798 GLX_FUNCTION( glXCreatePixmap ),
2799 GLX_FUNCTION( glXCreateWindow ),
2800 GLX_FUNCTION( glXDestroyPbuffer ),
2801 GLX_FUNCTION( glXDestroyPixmap ),
2802 GLX_FUNCTION( glXDestroyWindow ),
2803 GLX_FUNCTION( glXGetCurrentReadDrawable ),
2804 GLX_FUNCTION( glXGetFBConfigAttrib ),
2805 GLX_FUNCTION( glXGetFBConfigs ),
2806 GLX_FUNCTION( glXGetSelectedEvent ),
2807 GLX_FUNCTION( glXGetVisualFromFBConfig ),
2808 GLX_FUNCTION( glXMakeContextCurrent ),
2809 GLX_FUNCTION( glXQueryContext ),
2810 GLX_FUNCTION( glXQueryDrawable ),
2811 GLX_FUNCTION( glXSelectEvent ),
2812
2813 /*** GLX_SGI_swap_control ***/
2814 GLX_FUNCTION( glXSwapIntervalSGI ),
2815
2816 /*** GLX_SGI_video_sync ***/
2817 GLX_FUNCTION( glXGetVideoSyncSGI ),
2818 GLX_FUNCTION( glXWaitVideoSyncSGI ),
2819
2820 /*** GLX_SGI_make_current_read ***/
2821 GLX_FUNCTION2( glXMakeCurrentReadSGI, glXMakeContextCurrent ),
2822 GLX_FUNCTION2( glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable ),
2823
2824 /*** GLX_SGIX_video_source ***/
2825 #if defined(_VL_H)
2826 GLX_FUNCTION( glXCreateGLXVideoSourceSGIX ),
2827 GLX_FUNCTION( glXDestroyGLXVideoSourceSGIX ),
2828 #endif
2829
2830 /*** GLX_EXT_import_context ***/
2831 GLX_FUNCTION( glXFreeContextEXT ),
2832 GLX_FUNCTION( glXGetContextIDEXT ),
2833 GLX_FUNCTION2( glXGetCurrentDisplayEXT, glXGetCurrentDisplay ),
2834 GLX_FUNCTION( glXImportContextEXT ),
2835 GLX_FUNCTION2( glXQueryContextInfoEXT, glXQueryContext ),
2836
2837 /*** GLX_SGIX_fbconfig ***/
2838 GLX_FUNCTION2( glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib ),
2839 GLX_FUNCTION2( glXChooseFBConfigSGIX, glXChooseFBConfig ),
2840 GLX_FUNCTION( glXCreateGLXPixmapWithConfigSGIX ),
2841 GLX_FUNCTION( glXCreateContextWithConfigSGIX ),
2842 GLX_FUNCTION2( glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig ),
2843 GLX_FUNCTION( glXGetFBConfigFromVisualSGIX ),
2844
2845 /*** GLX_SGIX_pbuffer ***/
2846 GLX_FUNCTION( glXCreateGLXPbufferSGIX ),
2847 GLX_FUNCTION( glXDestroyGLXPbufferSGIX ),
2848 GLX_FUNCTION( glXQueryGLXPbufferSGIX ),
2849 GLX_FUNCTION( glXSelectEventSGIX ),
2850 GLX_FUNCTION( glXGetSelectedEventSGIX ),
2851
2852 /*** GLX_SGI_cushion ***/
2853 GLX_FUNCTION( glXCushionSGI ),
2854
2855 /*** GLX_SGIX_video_resize ***/
2856 GLX_FUNCTION( glXBindChannelToWindowSGIX ),
2857 GLX_FUNCTION( glXChannelRectSGIX ),
2858 GLX_FUNCTION( glXQueryChannelRectSGIX ),
2859 GLX_FUNCTION( glXQueryChannelDeltasSGIX ),
2860 GLX_FUNCTION( glXChannelRectSyncSGIX ),
2861
2862 /*** GLX_SGIX_dmbuffer **/
2863 #if defined(_DM_BUFFER_H_)
2864 GLX_FUNCTION( glXAssociateDMPbufferSGIX ),
2865 #endif
2866
2867 /*** GLX_SGIX_swap_group ***/
2868 GLX_FUNCTION( glXJoinSwapGroupSGIX ),
2869
2870 /*** GLX_SGIX_swap_barrier ***/
2871 GLX_FUNCTION( glXBindSwapBarrierSGIX ),
2872 GLX_FUNCTION( glXQueryMaxSwapBarriersSGIX ),
2873
2874 /*** GLX_SUN_get_transparent_index ***/
2875 GLX_FUNCTION( glXGetTransparentIndexSUN ),
2876
2877 /*** GLX_MESA_allocate_memory ***/
2878 GLX_FUNCTION( glXAllocateMemoryMESA ),
2879 GLX_FUNCTION( glXFreeMemoryMESA ),
2880 GLX_FUNCTION( glXGetMemoryOffsetMESA ),
2881
2882 /*** GLX_MESA_copy_sub_buffer ***/
2883 GLX_FUNCTION( glXCopySubBufferMESA ),
2884
2885 /*** GLX_MESA_pixmap_colormap ***/
2886 GLX_FUNCTION( glXCreateGLXPixmapMESA ),
2887
2888 /*** GLX_MESA_release_buffers ***/
2889 GLX_FUNCTION( glXReleaseBuffersMESA ),
2890
2891 /*** GLX_MESA_set_3dfx_mode ***/
2892 GLX_FUNCTION( glXSet3DfxModeMESA ),
2893
2894 /*** GLX_MESA_swap_control ***/
2895 GLX_FUNCTION( glXSwapIntervalMESA ),
2896 GLX_FUNCTION( glXGetSwapIntervalMESA ),
2897
2898 /*** GLX_MESA_swap_frame_usage ***/
2899 GLX_FUNCTION( glXBeginFrameTrackingMESA ),
2900 GLX_FUNCTION( glXEndFrameTrackingMESA ),
2901 GLX_FUNCTION( glXGetFrameUsageMESA ),
2902 GLX_FUNCTION( glXQueryFrameTrackingMESA ),
2903
2904 /*** GLX_ARB_get_proc_address ***/
2905 GLX_FUNCTION( glXGetProcAddressARB ),
2906
2907 /*** GLX 1.4 ***/
2908 GLX_FUNCTION2( glXGetProcAddress, glXGetProcAddressARB ),
2909
2910 /*** GLX_OML_sync_control ***/
2911 GLX_FUNCTION( glXWaitForSbcOML ),
2912 GLX_FUNCTION( glXWaitForMscOML ),
2913 GLX_FUNCTION( glXSwapBuffersMscOML ),
2914 GLX_FUNCTION( glXGetMscRateOML ),
2915 GLX_FUNCTION( glXGetSyncValuesOML ),
2916
2917 #ifdef GLX_DIRECT_RENDERING
2918 /***
2919 *** Internal functions useful to DRI drivers
2920 *** With this, the DRI drivers shouldn't need dlopen()/dlsym() to
2921 *** access internal libGL functions which may or may not exist.
2922 ***/
2923 GLX_FUNCTION( __glXInitialize ),
2924 GLX_FUNCTION( __glXFindDRIScreen ),
2925 GLX_FUNCTION( __glXGetInternalVersion ),
2926 GLX_FUNCTION( __glXWindowExists ),
2927 GLX_FUNCTION2( __glXCreateContextWithConfig, XF86DRICreateContextWithConfig ),
2928 GLX_FUNCTION2( __glXGetDrawableInfo, XF86DRIGetDrawableInfo ),
2929
2930 /*** DRI configuration ***/
2931 GLX_FUNCTION( glXGetScreenDriver ),
2932 GLX_FUNCTION( glXGetDriverConfig ),
2933
2934 GLX_FUNCTION( __glXScrEnableExtension ),
2935
2936 GLX_FUNCTION( __glXGetUST ),
2937
2938 GLX_FUNCTION2( __glXCreateContextModes, _gl_context_modes_create ),
2939 GLX_FUNCTION2( __glXDestroyContextModes, _gl_context_modes_destroy ),
2940 #endif
2941
2942 { NULL, NULL } /* end of list */
2943 };
2944
2945
2946 static const GLvoid *
2947 get_glx_proc_address(const char *funcName)
2948 {
2949 GLuint i;
2950
2951 /* try static functions */
2952 for (i = 0; GLX_functions[i].Name; i++) {
2953 if (strcmp(GLX_functions[i].Name, funcName) == 0)
2954 return GLX_functions[i].Address;
2955 }
2956
2957 return NULL;
2958 }
2959
2960
2961 #ifndef GLX_BUILT_IN_XMESA
2962 /**
2963 * Get the address of a named GL function. This is the pre-GLX 1.4 name for
2964 * \c glXGetProcAddress.
2965 *
2966 * \param procName Name of a GL or GLX function.
2967 * \returns A pointer to the named function
2968 *
2969 * \sa glXGetProcAddress
2970 */
2971 PUBLIC void (*glXGetProcAddressARB(const GLubyte *procName))( void )
2972 {
2973 typedef void (*gl_function)( void );
2974 gl_function f;
2975
2976
2977 /* Search the table of GLX and internal functions first. If that
2978 * fails and the supplied name could be a valid core GL name, try
2979 * searching the core GL function table. This check is done to prevent
2980 * DRI based drivers from searching the core GL function table for
2981 * internal API functions.
2982 */
2983
2984 f = (gl_function) get_glx_proc_address((const char *) procName);
2985 if ( (f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
2986 && (procName[2] != 'X') ) {
2987 f = (gl_function) _glapi_get_proc_address((const char *) procName);
2988 }
2989
2990 return f;
2991 }
2992
2993 /**
2994 * Get the address of a named GL function. This is the GLX 1.4 name for
2995 * \c glXGetProcAddressARB.
2996 *
2997 * \param procName Name of a GL or GLX function.
2998 * \returns A pointer to the named function
2999 *
3000 * \sa glXGetProcAddressARB
3001 */
3002 PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void )
3003 #if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
3004 __attribute__ ((alias ("glXGetProcAddressARB")));
3005 #else
3006 {
3007 return glXGetProcAddressARB(procName);
3008 }
3009 #endif /* __GNUC__ */
3010 #endif /* GLX_BUILT_IN_XMESA */
3011
3012
3013 #ifdef GLX_DIRECT_RENDERING
3014 /**
3015 * Retrieves the verion of the internal libGL API in YYYYMMDD format. This
3016 * might be used by the DRI drivers to determine how new libGL is at runtime.
3017 * Drivers should not call this function directly. They should instead use
3018 * \c glXGetProcAddress to obtain a pointer to the function.
3019 *
3020 * \returns An 8-digit decimal number representing the internal libGL API in
3021 * YYYYMMDD format.
3022 *
3023 * \sa glXGetProcAddress, PFNGLXGETINTERNALVERSIONPROC
3024 *
3025 * \since Internal API version 20021121.
3026 */
3027 int __glXGetInternalVersion(void)
3028 {
3029 /* History:
3030 * 20021121 - Initial version
3031 * 20021128 - Added __glXWindowExists() function
3032 * 20021207 - Added support for dynamic GLX extensions,
3033 * GLX_SGI_swap_control, GLX_SGI_video_sync,
3034 * GLX_OML_sync_control, and GLX_MESA_swap_control.
3035 * Never officially released. Do NOT test against
3036 * this version. Use 20030317 instead.
3037 * 20030317 - Added support GLX_SGIX_fbconfig,
3038 * GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
3039 * GLX_{ARB,SGIS}_multisample, and
3040 * GLX_SGIX_visual_select_group.
3041 * 20030606 - Added support for GLX_SGI_make_current_read.
3042 * 20030813 - Made support for dynamic extensions multi-head aware.
3043 * 20030818 - Added support for GLX_MESA_allocate_memory in place of the
3044 * deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset
3045 * interfaces.
3046 * 20031201 - Added support for the first round of DRI interface changes.
3047 * Do NOT test against this version! It has binary
3048 * compatibility bugs, use 20040317 instead.
3049 * 20040317 - Added the 'mode' field to __DRIcontextRec.
3050 * 20040415 - Added support for bindContext3 and unbindContext3.
3051 * 20040602 - Add __glXGetDrawableInfo. I though that was there
3052 * months ago. :(
3053 */
3054 return 20040602;
3055 }
3056
3057
3058
3059 static Bool windowExistsFlag;
3060
3061 static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
3062 {
3063 if (xerr->error_code == BadWindow) {
3064 windowExistsFlag = GL_FALSE;
3065 }
3066 return 0;
3067 }
3068
3069 /**
3070 * Determine if a window associated with a \c GLXDrawable exists on the
3071 * X-server. This function is not used internally by libGL. It is provided
3072 * as a utility function for DRI drivers.
3073 * Drivers should not call this function directly. They should instead use
3074 * \c glXGetProcAddress to obtain a pointer to the function.
3075 *
3076 * \param dpy Display associated with the drawable to be queried.
3077 * \param draw \c GLXDrawable to test.
3078 *
3079 * \returns \c GL_TRUE if a window exists that is associated with \c draw,
3080 * otherwise \c GL_FALSE is returned.
3081 *
3082 * \warning This function is not currently thread-safe.
3083 *
3084 * \sa glXGetProcAddress
3085 *
3086 * \since Internal API version 20021128.
3087 */
3088 static Bool __glXWindowExists(Display *dpy, GLXDrawable draw)
3089 {
3090 XWindowAttributes xwa;
3091 int (*oldXErrorHandler)(Display *, XErrorEvent *);
3092
3093 XSync(dpy, GL_FALSE);
3094 windowExistsFlag = GL_TRUE;
3095 oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
3096 XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
3097 XSetErrorHandler(oldXErrorHandler);
3098 return windowExistsFlag;
3099 }
3100
3101
3102 /**
3103 * Get the unadjusted system time (UST). Currently, the UST is measured in
3104 * microseconds since Epoc. The actual resolution of the UST may vary from
3105 * system to system, and the units may vary from release to release.
3106 * Drivers should not call this function directly. They should instead use
3107 * \c glXGetProcAddress to obtain a pointer to the function.
3108 *
3109 * \param ust Location to store the 64-bit UST
3110 * \returns Zero on success or a negative errno value on failure.
3111 *
3112 * \sa glXGetProcAddress, PFNGLXGETUSTPROC
3113 *
3114 * \since Internal API version 20030317.
3115 */
3116 int __glXGetUST( int64_t * ust )
3117 {
3118 struct timeval tv;
3119
3120 if ( ust == NULL ) {
3121 return -EFAULT;
3122 }
3123
3124 if ( gettimeofday( & tv, NULL ) == 0 ) {
3125 ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
3126 return 0;
3127 } else {
3128 return -errno;
3129 }
3130 }
3131 #endif /* GLX_DIRECT_RENDERING */