2 * (C) Copyright IBM Corporation 2004
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
27 * Implementation of pbuffer related functions.
29 * \author Ian Romanick <idr@us.ibm.com>
33 #include "glxclient.h"
34 #include <X11/extensions/extutil.h>
35 #include <X11/extensions/Xext.h>
38 #include "glxextensions.h"
40 #ifdef GLX_USE_APPLEGL
42 #include "apple/apple_glx_drawable.h"
45 #include "glx_error.h"
47 #define WARN_ONCE_GLX_1_3(a, b) { \
48 static int warned=1; \
50 warn_GLX_1_3((a), b ); \
56 * Emit a warning when clients use GLX 1.3 functions on pre-1.3 systems.
59 warn_GLX_1_3(Display
* dpy
, const char *function_name
)
61 struct glx_display
*priv
= __glXInitialize(dpy
);
63 if (priv
&& priv
->minorVersion
< 3) {
65 "WARNING: Application calling GLX 1.3 function \"%s\" "
66 "when GLX 1.3 is not supported! This is an application bug!\n",
71 #ifndef GLX_USE_APPLEGL
73 * Change a drawable's attribute.
75 * This function is used to implement \c glXSelectEvent and
76 * \c glXSelectEventSGIX.
79 * This function dynamically determines whether to use the SGIX_pbuffer
80 * version of the protocol or the GLX 1.3 version of the protocol.
83 ChangeDrawableAttribute(Display
* dpy
, GLXDrawable drawable
,
84 const CARD32
* attribs
, size_t num_attribs
)
86 struct glx_display
*priv
= __glXInitialize(dpy
);
87 #ifdef GLX_DIRECT_RENDERING
88 __GLXDRIdrawable
*pdraw
;
94 if ((priv
== NULL
) || (dpy
== NULL
) || (drawable
== 0)) {
98 opcode
= __glXSetupForCommand(dpy
);
104 if ((priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3)) {
105 xGLXChangeDrawableAttributesReq
*req
;
107 GetReqExtra(GLXChangeDrawableAttributes
, 8 * num_attribs
, req
);
108 output
= (CARD32
*) (req
+ 1);
110 req
->reqType
= opcode
;
111 req
->glxCode
= X_GLXChangeDrawableAttributes
;
112 req
->drawable
= drawable
;
113 req
->numAttribs
= (CARD32
) num_attribs
;
116 xGLXVendorPrivateWithReplyReq
*vpreq
;
118 GetReqExtra(GLXVendorPrivateWithReply
, 8 + (8 * num_attribs
), vpreq
);
119 output
= (CARD32
*) (vpreq
+ 1);
121 vpreq
->reqType
= opcode
;
122 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
123 vpreq
->vendorCode
= X_GLXvop_ChangeDrawableAttributesSGIX
;
125 output
[0] = (CARD32
) drawable
;
126 output
[1] = num_attribs
;
130 (void) memcpy(output
, attribs
, sizeof(CARD32
) * 2 * num_attribs
);
135 #ifdef GLX_DIRECT_RENDERING
136 pdraw
= GetGLXDRIDrawable(dpy
, drawable
);
141 for (i
= 0; i
< num_attribs
; i
++) {
142 switch(attribs
[i
* 2]) {
144 /* Keep a local copy for masking out DRI2 proto events as needed */
145 pdraw
->eventMask
= attribs
[i
* 2 + 1];
155 #ifdef GLX_DIRECT_RENDERING
157 determineTextureTarget(const int *attribs
, int numAttribs
)
162 for (i
= 0; i
< numAttribs
; i
++) {
163 if (attribs
[2 * i
] == GLX_TEXTURE_TARGET_EXT
) {
164 switch (attribs
[2 * i
+ 1]) {
165 case GLX_TEXTURE_2D_EXT
:
166 target
= GL_TEXTURE_2D
;
168 case GLX_TEXTURE_RECTANGLE_EXT
:
169 target
= GL_TEXTURE_RECTANGLE_ARB
;
179 determineTextureFormat(const int *attribs
, int numAttribs
)
183 for (i
= 0; i
< numAttribs
; i
++) {
184 if (attribs
[2 * i
] == GLX_TEXTURE_FORMAT_EXT
)
185 return attribs
[2 * i
+ 1];
192 CreateDRIDrawable(Display
*dpy
, struct glx_config
*config
,
193 XID drawable
, XID glxdrawable
,
194 const int *attrib_list
, size_t num_attribs
)
196 struct glx_display
*const priv
= __glXInitialize(dpy
);
197 __GLXDRIdrawable
*pdraw
;
198 struct glx_screen
*psc
;
201 fprintf(stderr
, "failed to create drawable\n");
205 psc
= priv
->screens
[config
->screen
];
206 if (psc
->driScreen
== NULL
)
209 pdraw
= psc
->driScreen
->createDrawable(psc
, drawable
,
210 glxdrawable
, config
);
212 fprintf(stderr
, "failed to create drawable\n");
216 if (__glxHashInsert(priv
->drawHash
, glxdrawable
, pdraw
)) {
217 (*pdraw
->destroyDrawable
) (pdraw
);
221 pdraw
->textureTarget
= determineTextureTarget(attrib_list
, num_attribs
);
222 pdraw
->textureFormat
= determineTextureFormat(attrib_list
, num_attribs
);
228 DestroyDRIDrawable(Display
*dpy
, GLXDrawable drawable
, int destroy_xdrawable
)
230 struct glx_display
*const priv
= __glXInitialize(dpy
);
231 __GLXDRIdrawable
*pdraw
= GetGLXDRIDrawable(dpy
, drawable
);
234 if (priv
!= NULL
&& pdraw
!= NULL
) {
235 xid
= pdraw
->xDrawable
;
236 (*pdraw
->destroyDrawable
) (pdraw
);
237 __glxHashDelete(priv
->drawHash
, drawable
);
238 if (destroy_xdrawable
)
239 XFreePixmap(priv
->dpy
, xid
);
246 CreateDRIDrawable(Display
*dpy
, const struct glx_config
* fbconfig
,
247 XID drawable
, XID glxdrawable
,
248 const int *attrib_list
, size_t num_attribs
)
254 DestroyDRIDrawable(Display
*dpy
, GLXDrawable drawable
, int destroy_xdrawable
)
261 * Get a drawable's attribute.
263 * This function is used to implement \c glXGetSelectedEvent and
264 * \c glXGetSelectedEventSGIX.
267 * This function dynamically determines whether to use the SGIX_pbuffer
268 * version of the protocol or the GLX 1.3 version of the protocol.
271 * The number of attributes returned is likely to be small, probably less than
272 * 10. Given that, this routine should try to use an array on the stack to
273 * capture the reply rather than always calling Xmalloc.
276 __glXGetDrawableAttribute(Display
* dpy
, GLXDrawable drawable
,
277 int attribute
, unsigned int *value
)
279 struct glx_display
*priv
;
280 xGLXGetDrawableAttributesReply reply
;
285 unsigned int num_attributes
;
286 GLboolean use_glx_1_3
;
288 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
289 __GLXDRIdrawable
*pdraw
;
295 /* Page 38 (page 52 of the PDF) of glxencode1.3.pdf says:
297 * "If drawable is not a valid GLX drawable, a GLXBadDrawable error is
301 __glXSendError(dpy
, GLXBadDrawable
, 0, X_GLXGetDrawableAttributes
, false);
305 priv
= __glXInitialize(dpy
);
309 use_glx_1_3
= ((priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3));
314 opcode
= __glXSetupForCommand(dpy
);
318 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
319 pdraw
= GetGLXDRIDrawable(dpy
, drawable
);
321 if (attribute
== GLX_BACK_BUFFER_AGE_EXT
) {
322 struct glx_context
*gc
= __glXGetCurrentContext();
323 struct glx_screen
*psc
;
325 /* The GLX_EXT_buffer_age spec says:
327 * "If querying GLX_BACK_BUFFER_AGE_EXT and <draw> is not bound to
328 * the calling thread's current context a GLXBadDrawable error is
331 if (pdraw
== NULL
|| gc
== &dummyContext
|| gc
->currentDpy
!= dpy
||
332 (gc
->currentDrawable
!= drawable
&&
333 gc
->currentReadable
!= drawable
)) {
334 __glXSendError(dpy
, GLXBadDrawable
, drawable
,
335 X_GLXGetDrawableAttributes
, false);
341 if (psc
->driScreen
->getBufferAge
!= NULL
)
342 *value
= psc
->driScreen
->getBufferAge(pdraw
);
351 xGLXGetDrawableAttributesReq
*req
;
353 GetReq(GLXGetDrawableAttributes
, req
);
354 req
->reqType
= opcode
;
355 req
->glxCode
= X_GLXGetDrawableAttributes
;
356 req
->drawable
= drawable
;
359 xGLXVendorPrivateWithReplyReq
*vpreq
;
361 GetReqExtra(GLXVendorPrivateWithReply
, 4, vpreq
);
362 data
= (CARD32
*) (vpreq
+ 1);
363 data
[0] = (CARD32
) drawable
;
365 vpreq
->reqType
= opcode
;
366 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
367 vpreq
->vendorCode
= X_GLXvop_GetDrawableAttributesSGIX
;
370 _XReply(dpy
, (xReply
*) & reply
, 0, False
);
372 if (reply
.type
== X_Error
) {
378 length
= reply
.length
;
380 num_attributes
= (use_glx_1_3
) ? reply
.numAttribs
: length
/ 2;
381 data
= malloc(length
* sizeof(CARD32
));
383 /* Throw data on the floor */
384 _XEatData(dpy
, length
);
387 _XRead(dpy
, (char *) data
, length
* sizeof(CARD32
));
389 /* Search the set of returned attributes for the attribute requested by
392 for (i
= 0; i
< num_attributes
; i
++) {
393 if (data
[i
* 2] == attribute
) {
394 *value
= data
[(i
* 2) + 1];
399 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
401 if (!pdraw
->textureTarget
)
402 pdraw
->textureTarget
=
403 determineTextureTarget((const int *) data
, num_attributes
);
404 if (!pdraw
->textureFormat
)
405 pdraw
->textureFormat
=
406 determineTextureFormat((const int *) data
, num_attributes
);
421 protocolDestroyDrawable(Display
*dpy
, GLXDrawable drawable
, CARD32 glxCode
)
423 xGLXDestroyPbufferReq
*req
;
426 opcode
= __glXSetupForCommand(dpy
);
432 GetReq(GLXDestroyPbuffer
, req
);
433 req
->reqType
= opcode
;
434 req
->glxCode
= glxCode
;
435 req
->pbuffer
= (GLXPbuffer
) drawable
;
442 * Create a non-pbuffer GLX drawable.
445 CreateDrawable(Display
*dpy
, struct glx_config
*config
,
446 Drawable drawable
, const int *attrib_list
, CARD8 glxCode
)
448 xGLXCreateWindowReq
*req
;
449 struct glx_drawable
*glxDraw
;
457 while (attrib_list
[i
* 2] != None
)
461 opcode
= __glXSetupForCommand(dpy
);
465 glxDraw
= malloc(sizeof(*glxDraw
));
470 GetReqExtra(GLXCreateWindow
, 8 * i
, req
);
471 data
= (CARD32
*) (req
+ 1);
473 req
->reqType
= opcode
;
474 req
->glxCode
= glxCode
;
475 req
->screen
= config
->screen
;
476 req
->fbconfig
= config
->fbconfigID
;
477 req
->window
= drawable
;
478 req
->glxwindow
= xid
= XAllocID(dpy
);
482 memcpy(data
, attrib_list
, 8 * i
);
487 if (InitGLXDrawable(dpy
, glxDraw
, drawable
, xid
)) {
492 if (!CreateDRIDrawable(dpy
, config
, drawable
, xid
, attrib_list
, i
)) {
493 if (glxCode
== X_GLXCreatePixmap
)
494 glxCode
= X_GLXDestroyPixmap
;
496 glxCode
= X_GLXDestroyWindow
;
497 protocolDestroyDrawable(dpy
, xid
, glxCode
);
506 * Destroy a non-pbuffer GLX drawable.
509 DestroyDrawable(Display
* dpy
, GLXDrawable drawable
, CARD32 glxCode
)
511 if ((dpy
== NULL
) || (drawable
== 0)) {
515 protocolDestroyDrawable(dpy
, drawable
, glxCode
);
517 DestroyGLXDrawable(dpy
, drawable
);
518 DestroyDRIDrawable(dpy
, drawable
, GL_FALSE
);
527 * This function is used to implement \c glXCreatePbuffer and
528 * \c glXCreateGLXPbufferSGIX.
531 * This function dynamically determines whether to use the SGIX_pbuffer
532 * version of the protocol or the GLX 1.3 version of the protocol.
535 CreatePbuffer(Display
* dpy
, struct glx_config
*config
,
536 unsigned int width
, unsigned int height
,
537 const int *attrib_list
, GLboolean size_in_attribs
)
539 struct glx_display
*priv
= __glXInitialize(dpy
);
545 GLboolean glx_1_3
= GL_FALSE
;
552 while (attrib_list
[i
* 2])
556 opcode
= __glXSetupForCommand(dpy
);
563 if ((priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3)) {
564 xGLXCreatePbufferReq
*req
;
565 unsigned int extra
= (size_in_attribs
) ? 0 : 2;
569 GetReqExtra(GLXCreatePbuffer
, (8 * (i
+ extra
)), req
);
570 data
= (CARD32
*) (req
+ 1);
572 req
->reqType
= opcode
;
573 req
->glxCode
= X_GLXCreatePbuffer
;
574 req
->screen
= config
->screen
;
575 req
->fbconfig
= config
->fbconfigID
;
577 req
->numAttribs
= i
+ extra
;
579 if (!size_in_attribs
) {
580 data
[(2 * i
) + 0] = GLX_PBUFFER_WIDTH
;
581 data
[(2 * i
) + 1] = width
;
582 data
[(2 * i
) + 2] = GLX_PBUFFER_HEIGHT
;
583 data
[(2 * i
) + 3] = height
;
588 xGLXVendorPrivateReq
*vpreq
;
590 GetReqExtra(GLXVendorPrivate
, 20 + (8 * i
), vpreq
);
591 data
= (CARD32
*) (vpreq
+ 1);
593 vpreq
->reqType
= opcode
;
594 vpreq
->glxCode
= X_GLXVendorPrivate
;
595 vpreq
->vendorCode
= X_GLXvop_CreateGLXPbufferSGIX
;
597 data
[0] = config
->screen
;
598 data
[1] = config
->fbconfigID
;
605 (void) memcpy(data
, attrib_list
, sizeof(CARD32
) * 2 * i
);
610 pixmap
= XCreatePixmap(dpy
, RootWindow(dpy
, config
->screen
),
611 width
, height
, config
->rgbBits
);
613 if (!CreateDRIDrawable(dpy
, config
, pixmap
, id
, attrib_list
, i
)) {
614 CARD32 o
= glx_1_3
? X_GLXDestroyPbuffer
: X_GLXvop_DestroyGLXPbufferSGIX
;
615 XFreePixmap(dpy
, pixmap
);
616 protocolDestroyDrawable(dpy
, id
, o
);
626 * This function is used to implement \c glXDestroyPbuffer and
627 * \c glXDestroyGLXPbufferSGIX.
630 * This function dynamically determines whether to use the SGIX_pbuffer
631 * version of the protocol or the GLX 1.3 version of the protocol.
634 DestroyPbuffer(Display
* dpy
, GLXDrawable drawable
)
636 struct glx_display
*priv
= __glXInitialize(dpy
);
639 if ((priv
== NULL
) || (dpy
== NULL
) || (drawable
== 0)) {
643 opcode
= __glXSetupForCommand(dpy
);
649 if ((priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3)) {
650 xGLXDestroyPbufferReq
*req
;
652 GetReq(GLXDestroyPbuffer
, req
);
653 req
->reqType
= opcode
;
654 req
->glxCode
= X_GLXDestroyPbuffer
;
655 req
->pbuffer
= (GLXPbuffer
) drawable
;
658 xGLXVendorPrivateWithReplyReq
*vpreq
;
661 GetReqExtra(GLXVendorPrivateWithReply
, 4, vpreq
);
662 data
= (CARD32
*) (vpreq
+ 1);
664 data
[0] = (CARD32
) drawable
;
666 vpreq
->reqType
= opcode
;
667 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
668 vpreq
->vendorCode
= X_GLXvop_DestroyGLXPbufferSGIX
;
674 DestroyDRIDrawable(dpy
, drawable
, GL_TRUE
);
680 * Create a new pbuffer.
682 _GLX_PUBLIC GLXPbufferSGIX
683 glXCreateGLXPbufferSGIX(Display
* dpy
, GLXFBConfigSGIX config
,
684 unsigned int width
, unsigned int height
,
687 return (GLXPbufferSGIX
) CreatePbuffer(dpy
, (struct glx_config
*) config
,
689 attrib_list
, GL_FALSE
);
692 #endif /* GLX_USE_APPLEGL */
695 * Create a new pbuffer.
697 _GLX_PUBLIC GLXPbuffer
698 glXCreatePbuffer(Display
* dpy
, GLXFBConfig config
, const int *attrib_list
)
700 int i
, width
, height
;
701 #ifdef GLX_USE_APPLEGL
709 WARN_ONCE_GLX_1_3(dpy
, __func__
);
711 #ifdef GLX_USE_APPLEGL
712 for (i
= 0; attrib_list
[i
]; ++i
) {
713 switch (attrib_list
[i
]) {
714 case GLX_PBUFFER_WIDTH
:
715 width
= attrib_list
[i
+ 1];
719 case GLX_PBUFFER_HEIGHT
:
720 height
= attrib_list
[i
+ 1];
724 case GLX_LARGEST_PBUFFER
:
725 /* This is a hint we should probably handle, but how? */
729 case GLX_PRESERVED_CONTENTS
:
730 /* The contents are always preserved with AppleSGLX with CGL. */
739 if (apple_glx_pbuffer_create(dpy
, config
, width
, height
, &errorcode
,
742 * apple_glx_pbuffer_create only sets the errorcode to core X11
745 __glXSendError(dpy
, errorcode
, 0, X_GLXCreatePbuffer
, true);
752 for (i
= 0; attrib_list
[i
* 2]; i
++) {
753 switch (attrib_list
[i
* 2]) {
754 case GLX_PBUFFER_WIDTH
:
755 width
= attrib_list
[i
* 2 + 1];
757 case GLX_PBUFFER_HEIGHT
:
758 height
= attrib_list
[i
* 2 + 1];
763 return (GLXPbuffer
) CreatePbuffer(dpy
, (struct glx_config
*) config
,
764 width
, height
, attrib_list
, GL_TRUE
);
770 * Destroy an existing pbuffer.
773 glXDestroyPbuffer(Display
* dpy
, GLXPbuffer pbuf
)
775 #ifdef GLX_USE_APPLEGL
776 if (apple_glx_pbuffer_destroy(dpy
, pbuf
)) {
777 __glXSendError(dpy
, GLXBadPbuffer
, pbuf
, X_GLXDestroyPbuffer
, false);
780 DestroyPbuffer(dpy
, pbuf
);
786 * Query an attribute of a drawable.
789 glXQueryDrawable(Display
* dpy
, GLXDrawable drawable
,
790 int attribute
, unsigned int *value
)
792 WARN_ONCE_GLX_1_3(dpy
, __func__
);
793 #ifdef GLX_USE_APPLEGL
796 unsigned int width
, height
, bd
, depth
;
798 if (apple_glx_pixmap_query(drawable
, attribute
, value
))
801 if (apple_glx_pbuffer_query(drawable
, attribute
, value
))
805 * The OpenGL spec states that we should report GLXBadDrawable if
806 * the drawable is invalid, however doing so would require that we
807 * use XSetErrorHandler(), which is known to not be thread safe.
808 * If we use a round-trip call to validate the drawable, there could
809 * be a race, so instead we just opt in favor of letting the
810 * XGetGeometry request fail with a GetGeometry request X error
811 * rather than GLXBadDrawable, in what is hoped to be a rare
812 * case of an invalid drawable. In practice most and possibly all
813 * X11 apps using GLX shouldn't notice a difference.
816 (dpy
, drawable
, &root
, &x
, &y
, &width
, &height
, &bd
, &depth
)) {
828 __glXGetDrawableAttribute(dpy
, drawable
, attribute
, value
);
833 #ifndef GLX_USE_APPLEGL
835 * Query an attribute of a pbuffer.
838 glXQueryGLXPbufferSGIX(Display
* dpy
, GLXPbufferSGIX drawable
,
839 int attribute
, unsigned int *value
)
841 __glXGetDrawableAttribute(dpy
, drawable
, attribute
, value
);
846 * Select the event mask for a drawable.
849 glXSelectEvent(Display
* dpy
, GLXDrawable drawable
, unsigned long mask
)
851 #ifdef GLX_USE_APPLEGL
852 XWindowAttributes xwattr
;
854 if (apple_glx_pbuffer_set_event_mask(drawable
, mask
))
858 * The spec allows a window, but currently there are no valid
859 * events for a window, so do nothing.
861 if (XGetWindowAttributes(dpy
, drawable
, &xwattr
))
863 /* The drawable seems to be invalid. Report an error. */
865 __glXSendError(dpy
, GLXBadDrawable
, drawable
,
866 X_GLXChangeDrawableAttributes
, false);
870 attribs
[0] = (CARD32
) GLX_EVENT_MASK
;
871 attribs
[1] = (CARD32
) mask
;
873 ChangeDrawableAttribute(dpy
, drawable
, attribs
, 1);
879 * Get the selected event mask for a drawable.
882 glXGetSelectedEvent(Display
* dpy
, GLXDrawable drawable
, unsigned long *mask
)
884 #ifdef GLX_USE_APPLEGL
885 XWindowAttributes xwattr
;
887 if (apple_glx_pbuffer_get_event_mask(drawable
, mask
))
891 * The spec allows a window, but currently there are no valid
892 * events for a window, so do nothing, but set the mask to 0.
894 if (XGetWindowAttributes(dpy
, drawable
, &xwattr
)) {
895 /* The window is valid, so set the mask to 0. */
899 /* The drawable seems to be invalid. Report an error. */
901 __glXSendError(dpy
, GLXBadDrawable
, drawable
, X_GLXGetDrawableAttributes
,
904 unsigned int value
= 0;
907 /* The non-sense with value is required because on LP64 platforms
908 * sizeof(unsigned int) != sizeof(unsigned long). On little-endian
909 * we could just type-cast the pointer, but why?
912 __glXGetDrawableAttribute(dpy
, drawable
, GLX_EVENT_MASK_SGIX
, &value
);
918 _GLX_PUBLIC GLXPixmap
919 glXCreatePixmap(Display
* dpy
, GLXFBConfig config
, Pixmap pixmap
,
920 const int *attrib_list
)
922 WARN_ONCE_GLX_1_3(dpy
, __func__
);
924 #ifdef GLX_USE_APPLEGL
925 const struct glx_config
*modes
= (const struct glx_config
*) config
;
927 if (apple_glx_pixmap_create(dpy
, modes
->screen
, pixmap
, modes
))
932 return CreateDrawable(dpy
, (struct glx_config
*) config
,
933 (Drawable
) pixmap
, attrib_list
, X_GLXCreatePixmap
);
938 _GLX_PUBLIC GLXWindow
939 glXCreateWindow(Display
* dpy
, GLXFBConfig config
, Window win
,
940 const int *attrib_list
)
942 WARN_ONCE_GLX_1_3(dpy
, __func__
);
943 #ifdef GLX_USE_APPLEGL
944 XWindowAttributes xwattr
;
945 XVisualInfo
*visinfo
;
947 (void) attrib_list
; /*unused according to GLX 1.4 */
949 XGetWindowAttributes(dpy
, win
, &xwattr
);
951 visinfo
= glXGetVisualFromFBConfig(dpy
, config
);
953 if (NULL
== visinfo
) {
954 __glXSendError(dpy
, GLXBadFBConfig
, 0, X_GLXCreateWindow
, false);
958 if (visinfo
->visualid
!= XVisualIDFromVisual(xwattr
.visual
)) {
959 __glXSendError(dpy
, BadMatch
, 0, X_GLXCreateWindow
, true);
967 return CreateDrawable(dpy
, (struct glx_config
*) config
,
968 (Drawable
) win
, attrib_list
, X_GLXCreateWindow
);
974 glXDestroyPixmap(Display
* dpy
, GLXPixmap pixmap
)
976 WARN_ONCE_GLX_1_3(dpy
, __func__
);
977 #ifdef GLX_USE_APPLEGL
978 if (apple_glx_pixmap_destroy(dpy
, pixmap
))
979 __glXSendError(dpy
, GLXBadPixmap
, pixmap
, X_GLXDestroyPixmap
, false);
981 DestroyDrawable(dpy
, (GLXDrawable
) pixmap
, X_GLXDestroyPixmap
);
987 glXDestroyWindow(Display
* dpy
, GLXWindow win
)
989 WARN_ONCE_GLX_1_3(dpy
, __func__
);
990 #ifndef GLX_USE_APPLEGL
991 DestroyDrawable(dpy
, (GLXDrawable
) win
, X_GLXDestroyWindow
);
996 GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX
,
997 (Display
* dpy
, GLXPbufferSGIX pbuf
),
998 (dpy
, pbuf
), glXDestroyPbuffer
)
1001 GLX_ALIAS_VOID(glXSelectEventSGIX
,
1002 (Display
* dpy
, GLXDrawable drawable
,
1003 unsigned long mask
), (dpy
, drawable
, mask
), glXSelectEvent
)
1006 GLX_ALIAS_VOID(glXGetSelectedEventSGIX
,
1007 (Display
* dpy
, GLXDrawable drawable
,
1008 unsigned long *mask
), (dpy
, drawable
, mask
),
1009 glXGetSelectedEvent
)