g3dvl: Use sobel filter for chroma interpolation
[mesa/nouveau-pmpeg.git] / src / glx / glx_pbuffer.c
blob6738252a31d724a072ca019c8d276ec509670be8
1 /*
2 * (C) Copyright IBM Corporation 2004
3 * All Rights Reserved.
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
14 * Software.
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.
25 /**
26 * \file glx_pbuffer.c
27 * Implementation of pbuffer related functions.
29 * \author Ian Romanick <idr@us.ibm.com>
32 #include <inttypes.h>
33 #include "glxclient.h"
34 #include <X11/extensions/extutil.h>
35 #include <X11/extensions/Xext.h>
36 #include <assert.h>
37 #include <string.h>
38 #include "glxextensions.h"
40 #ifdef GLX_USE_APPLEGL
41 #include <pthread.h>
42 #include "apple_glx_drawable.h"
43 #include "glx_error.h"
44 #endif
46 #define WARN_ONCE_GLX_1_3(a, b) { \
47 static int warned=1; \
48 if(warned) { \
49 warn_GLX_1_3((a), b ); \
50 warned=0; \
51 } \
54 /**
55 * Emit a warning when clients use GLX 1.3 functions on pre-1.3 systems.
57 static void
58 warn_GLX_1_3(Display * dpy, const char *function_name)
60 struct glx_display *priv = __glXInitialize(dpy);
62 if (priv->minorVersion < 3) {
63 fprintf(stderr,
64 "WARNING: Application calling GLX 1.3 function \"%s\" "
65 "when GLX 1.3 is not supported! This is an application bug!\n",
66 function_name);
70 #ifndef GLX_USE_APPLEGL
71 /**
72 * Change a drawable's attribute.
74 * This function is used to implement \c glXSelectEvent and
75 * \c glXSelectEventSGIX.
77 * \note
78 * This function dynamically determines whether to use the SGIX_pbuffer
79 * version of the protocol or the GLX 1.3 version of the protocol.
81 static void
82 ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable,
83 const CARD32 * attribs, size_t num_attribs)
85 struct glx_display *priv = __glXInitialize(dpy);
86 #ifdef GLX_DIRECT_RENDERING
87 __GLXDRIdrawable *pdraw;
88 #endif
89 CARD32 *output;
90 CARD8 opcode;
91 int i;
93 if ((dpy == NULL) || (drawable == 0)) {
94 return;
97 opcode = __glXSetupForCommand(dpy);
98 if (!opcode)
99 return;
101 LockDisplay(dpy);
103 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
104 xGLXChangeDrawableAttributesReq *req;
106 GetReqExtra(GLXChangeDrawableAttributes, 8 * num_attribs, req);
107 output = (CARD32 *) (req + 1);
109 req->reqType = opcode;
110 req->glxCode = X_GLXChangeDrawableAttributes;
111 req->drawable = drawable;
112 req->numAttribs = (CARD32) num_attribs;
114 else {
115 xGLXVendorPrivateWithReplyReq *vpreq;
117 GetReqExtra(GLXVendorPrivateWithReply, 8 + (8 * num_attribs), vpreq);
118 output = (CARD32 *) (vpreq + 1);
120 vpreq->reqType = opcode;
121 vpreq->glxCode = X_GLXVendorPrivateWithReply;
122 vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX;
124 output[0] = (CARD32) drawable;
125 output[1] = num_attribs;
126 output += 2;
129 (void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs);
131 UnlockDisplay(dpy);
132 SyncHandle();
134 #ifdef GLX_DIRECT_RENDERING
135 pdraw = GetGLXDRIDrawable(dpy, drawable);
137 if (!pdraw)
138 return;
140 for (i = 0; i < num_attribs; i++) {
141 switch(attribs[i * 2]) {
142 case GLX_EVENT_MASK:
143 /* Keep a local copy for masking out DRI2 proto events as needed */
144 pdraw->eventMask = attribs[i * 2 + 1];
145 break;
148 #endif
150 return;
154 #ifdef GLX_DIRECT_RENDERING
155 static GLenum
156 determineTextureTarget(const int *attribs, int numAttribs)
158 GLenum target = 0;
159 int i;
161 for (i = 0; i < numAttribs; i++) {
162 if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
163 switch (attribs[2 * i + 1]) {
164 case GLX_TEXTURE_2D_EXT:
165 target = GL_TEXTURE_2D;
166 break;
167 case GLX_TEXTURE_RECTANGLE_EXT:
168 target = GL_TEXTURE_RECTANGLE_ARB;
169 break;
174 return target;
177 static GLenum
178 determineTextureFormat(const int *attribs, int numAttribs)
180 int i;
182 for (i = 0; i < numAttribs; i++) {
183 if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
184 return attribs[2 * i + 1];
187 return 0;
190 static GLboolean
191 CreateDRIDrawable(Display *dpy, struct glx_config *config,
192 XID drawable, XID glxdrawable,
193 const int *attrib_list, size_t num_attribs)
195 struct glx_display *const priv = __glXInitialize(dpy);
196 __GLXDRIdrawable *pdraw;
197 struct glx_screen *psc;
199 psc = priv->screens[config->screen];
200 if (psc->driScreen == NULL)
201 return GL_TRUE;
203 pdraw = psc->driScreen->createDrawable(psc, drawable,
204 glxdrawable, config);
205 if (pdraw == NULL) {
206 fprintf(stderr, "failed to create drawable\n");
207 return GL_FALSE;
210 if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
211 (*pdraw->destroyDrawable) (pdraw);
212 return GL_FALSE;
215 pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
216 pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);
218 return GL_TRUE;
221 static void
222 DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
224 struct glx_display *const priv = __glXInitialize(dpy);
225 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
226 XID xid;
228 if (pdraw != NULL) {
229 xid = pdraw->xDrawable;
230 (*pdraw->destroyDrawable) (pdraw);
231 __glxHashDelete(priv->drawHash, drawable);
232 if (destroy_xdrawable)
233 XFreePixmap(priv->dpy, xid);
237 #else
239 static GLboolean
240 CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig,
241 XID drawable, XID glxdrawable,
242 const int *attrib_list, size_t num_attribs)
244 return GL_FALSE;
247 static void
248 DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
252 #endif
255 * Get a drawable's attribute.
257 * This function is used to implement \c glXGetSelectedEvent and
258 * \c glXGetSelectedEventSGIX.
260 * \note
261 * This function dynamically determines whether to use the SGIX_pbuffer
262 * version of the protocol or the GLX 1.3 version of the protocol.
264 * \todo
265 * The number of attributes returned is likely to be small, probably less than
266 * 10. Given that, this routine should try to use an array on the stack to
267 * capture the reply rather than always calling Xmalloc.
269 static int
270 GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
271 int attribute, unsigned int *value)
273 struct glx_display *priv;
274 xGLXGetDrawableAttributesReply reply;
275 CARD32 *data;
276 CARD8 opcode;
277 unsigned int length;
278 unsigned int i;
279 unsigned int num_attributes;
280 GLboolean use_glx_1_3;
282 if ((dpy == NULL) || (drawable == 0)) {
283 return 0;
286 priv = __glXInitialize(dpy);
287 use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3));
289 *value = 0;
292 opcode = __glXSetupForCommand(dpy);
293 if (!opcode)
294 return 0;
296 LockDisplay(dpy);
298 if (use_glx_1_3) {
299 xGLXGetDrawableAttributesReq *req;
301 GetReq(GLXGetDrawableAttributes, req);
302 req->reqType = opcode;
303 req->glxCode = X_GLXGetDrawableAttributes;
304 req->drawable = drawable;
306 else {
307 xGLXVendorPrivateWithReplyReq *vpreq;
309 GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
310 data = (CARD32 *) (vpreq + 1);
311 data[0] = (CARD32) drawable;
313 vpreq->reqType = opcode;
314 vpreq->glxCode = X_GLXVendorPrivateWithReply;
315 vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX;
318 _XReply(dpy, (xReply *) & reply, 0, False);
320 if (reply.type == X_Error) {
321 UnlockDisplay(dpy);
322 SyncHandle();
323 return 0;
326 length = reply.length;
327 if (length) {
328 num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
329 data = (CARD32 *) Xmalloc(length * sizeof(CARD32));
330 if (data == NULL) {
331 /* Throw data on the floor */
332 _XEatData(dpy, length);
334 else {
335 _XRead(dpy, (char *) data, length * sizeof(CARD32));
337 /* Search the set of returned attributes for the attribute requested by
338 * the caller.
340 for (i = 0; i < num_attributes; i++) {
341 if (data[i * 2] == attribute) {
342 *value = data[(i * 2) + 1];
343 break;
347 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
349 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
351 if (pdraw != NULL && !pdraw->textureTarget)
352 pdraw->textureTarget =
353 determineTextureTarget((const int *) data, num_attributes);
354 if (pdraw != NULL && !pdraw->textureFormat)
355 pdraw->textureFormat =
356 determineTextureFormat((const int *) data, num_attributes);
358 #endif
360 Xfree(data);
364 UnlockDisplay(dpy);
365 SyncHandle();
367 return 0;
370 static void
371 protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode)
373 xGLXDestroyPbufferReq *req;
374 CARD8 opcode;
376 opcode = __glXSetupForCommand(dpy);
377 if (!opcode)
378 return;
380 LockDisplay(dpy);
382 GetReq(GLXDestroyPbuffer, req);
383 req->reqType = opcode;
384 req->glxCode = glxCode;
385 req->pbuffer = (GLXPbuffer) drawable;
387 UnlockDisplay(dpy);
388 SyncHandle();
392 * Create a non-pbuffer GLX drawable.
394 static GLXDrawable
395 CreateDrawable(Display *dpy, struct glx_config *config,
396 Drawable drawable, const int *attrib_list, CARD8 glxCode)
398 xGLXCreateWindowReq *req;
399 struct glx_drawable *glxDraw;
400 CARD32 *data;
401 unsigned int i;
402 CARD8 opcode;
403 GLXDrawable xid;
405 i = 0;
406 if (attrib_list) {
407 while (attrib_list[i * 2] != None)
408 i++;
411 opcode = __glXSetupForCommand(dpy);
412 if (!opcode)
413 return None;
415 glxDraw = Xmalloc(sizeof(*glxDraw));
416 if (!glxDraw)
417 return None;
419 LockDisplay(dpy);
420 GetReqExtra(GLXCreateWindow, 8 * i, req);
421 data = (CARD32 *) (req + 1);
423 req->reqType = opcode;
424 req->glxCode = glxCode;
425 req->screen = config->screen;
426 req->fbconfig = config->fbconfigID;
427 req->window = drawable;
428 req->glxwindow = xid = XAllocID(dpy);
429 req->numAttribs = i;
431 if (attrib_list)
432 memcpy(data, attrib_list, 8 * i);
434 UnlockDisplay(dpy);
435 SyncHandle();
437 if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) {
438 free(glxDraw);
439 return None;
442 if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
443 if (glxCode == X_GLXCreatePixmap)
444 glxCode = X_GLXDestroyPixmap;
445 else
446 glxCode = X_GLXDestroyWindow;
447 protocolDestroyDrawable(dpy, xid, glxCode);
448 xid = None;
451 return xid;
456 * Destroy a non-pbuffer GLX drawable.
458 static void
459 DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
461 if ((dpy == NULL) || (drawable == 0)) {
462 return;
465 protocolDestroyDrawable(dpy, drawable, glxCode);
467 DestroyGLXDrawable(dpy, drawable);
468 DestroyDRIDrawable(dpy, drawable, GL_FALSE);
470 return;
475 * Create a pbuffer.
477 * This function is used to implement \c glXCreatePbuffer and
478 * \c glXCreateGLXPbufferSGIX.
480 * \note
481 * This function dynamically determines whether to use the SGIX_pbuffer
482 * version of the protocol or the GLX 1.3 version of the protocol.
484 static GLXDrawable
485 CreatePbuffer(Display * dpy, struct glx_config *config,
486 unsigned int width, unsigned int height,
487 const int *attrib_list, GLboolean size_in_attribs)
489 struct glx_display *priv = __glXInitialize(dpy);
490 GLXDrawable id = 0;
491 CARD32 *data;
492 CARD8 opcode;
493 unsigned int i;
494 Pixmap pixmap;
495 GLboolean glx_1_3 = GL_FALSE;
497 i = 0;
498 if (attrib_list) {
499 while (attrib_list[i * 2])
500 i++;
503 opcode = __glXSetupForCommand(dpy);
504 if (!opcode)
505 return None;
507 LockDisplay(dpy);
508 id = XAllocID(dpy);
510 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
511 xGLXCreatePbufferReq *req;
512 unsigned int extra = (size_in_attribs) ? 0 : 2;
514 glx_1_3 = GL_TRUE;
516 GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
517 data = (CARD32 *) (req + 1);
519 req->reqType = opcode;
520 req->glxCode = X_GLXCreatePbuffer;
521 req->screen = config->screen;
522 req->fbconfig = config->fbconfigID;
523 req->pbuffer = id;
524 req->numAttribs = i + extra;
526 if (!size_in_attribs) {
527 data[(2 * i) + 0] = GLX_PBUFFER_WIDTH;
528 data[(2 * i) + 1] = width;
529 data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT;
530 data[(2 * i) + 3] = height;
531 data += 4;
534 else {
535 xGLXVendorPrivateReq *vpreq;
537 GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq);
538 data = (CARD32 *) (vpreq + 1);
540 vpreq->reqType = opcode;
541 vpreq->glxCode = X_GLXVendorPrivate;
542 vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX;
544 data[0] = config->screen;
545 data[1] = config->fbconfigID;
546 data[2] = id;
547 data[3] = width;
548 data[4] = height;
549 data += 5;
552 (void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i);
554 UnlockDisplay(dpy);
555 SyncHandle();
557 pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
558 width, height, config->rgbBits);
560 if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) {
561 CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX;
562 XFreePixmap(dpy, pixmap);
563 protocolDestroyDrawable(dpy, id, o);
564 id = None;
567 return id;
571 * Destroy a pbuffer.
573 * This function is used to implement \c glXDestroyPbuffer and
574 * \c glXDestroyGLXPbufferSGIX.
576 * \note
577 * This function dynamically determines whether to use the SGIX_pbuffer
578 * version of the protocol or the GLX 1.3 version of the protocol.
580 static void
581 DestroyPbuffer(Display * dpy, GLXDrawable drawable)
583 struct glx_display *priv = __glXInitialize(dpy);
584 CARD8 opcode;
586 if ((dpy == NULL) || (drawable == 0)) {
587 return;
590 opcode = __glXSetupForCommand(dpy);
591 if (!opcode)
592 return;
594 LockDisplay(dpy);
596 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
597 xGLXDestroyPbufferReq *req;
599 GetReq(GLXDestroyPbuffer, req);
600 req->reqType = opcode;
601 req->glxCode = X_GLXDestroyPbuffer;
602 req->pbuffer = (GLXPbuffer) drawable;
604 else {
605 xGLXVendorPrivateWithReplyReq *vpreq;
606 CARD32 *data;
608 GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
609 data = (CARD32 *) (vpreq + 1);
611 data[0] = (CARD32) drawable;
613 vpreq->reqType = opcode;
614 vpreq->glxCode = X_GLXVendorPrivateWithReply;
615 vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX;
618 UnlockDisplay(dpy);
619 SyncHandle();
621 DestroyDRIDrawable(dpy, drawable, GL_TRUE);
623 return;
627 * Create a new pbuffer.
629 _X_EXPORT GLXPbufferSGIX
630 glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config,
631 unsigned int width, unsigned int height,
632 int *attrib_list)
634 return (GLXPbufferSGIX) CreatePbuffer(dpy, (struct glx_config *) config,
635 width, height,
636 attrib_list, GL_FALSE);
639 #endif /* GLX_USE_APPLEGL */
642 * Create a new pbuffer.
644 _X_EXPORT GLXPbuffer
645 glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list)
647 int i, width, height;
648 #ifdef GLX_USE_APPLEGL
649 GLXPbuffer result;
650 int errorcode;
651 #endif
653 width = 0;
654 height = 0;
656 WARN_ONCE_GLX_1_3(dpy, __func__);
658 #ifdef GLX_USE_APPLEGL
659 for (i = 0; attrib_list[i]; ++i) {
660 switch (attrib_list[i]) {
661 case GLX_PBUFFER_WIDTH:
662 width = attrib_list[i + 1];
663 ++i;
664 break;
666 case GLX_PBUFFER_HEIGHT:
667 height = attrib_list[i + 1];
668 ++i;
669 break;
671 case GLX_LARGEST_PBUFFER:
672 /* This is a hint we should probably handle, but how? */
673 ++i;
674 break;
676 case GLX_PRESERVED_CONTENTS:
677 /* The contents are always preserved with AppleSGLX with CGL. */
678 ++i;
679 break;
681 default:
682 return None;
686 if (apple_glx_pbuffer_create(dpy, config, width, height, &errorcode,
687 &result)) {
689 * apple_glx_pbuffer_create only sets the errorcode to core X11
690 * errors.
692 __glXSendError(dpy, errorcode, 0, X_GLXCreatePbuffer, true);
694 return None;
697 return result;
698 #else
699 for (i = 0; attrib_list[i * 2]; i++) {
700 switch (attrib_list[i * 2]) {
701 case GLX_PBUFFER_WIDTH:
702 width = attrib_list[i * 2 + 1];
703 break;
704 case GLX_PBUFFER_HEIGHT:
705 height = attrib_list[i * 2 + 1];
706 break;
710 return (GLXPbuffer) CreatePbuffer(dpy, (struct glx_config *) config,
711 width, height, attrib_list, GL_TRUE);
712 #endif
717 * Destroy an existing pbuffer.
719 _X_EXPORT void
720 glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf)
722 #ifdef GLX_USE_APPLEGL
723 if (apple_glx_pbuffer_destroy(dpy, pbuf)) {
724 __glXSendError(dpy, GLXBadPbuffer, pbuf, X_GLXDestroyPbuffer, false);
726 #else
727 DestroyPbuffer(dpy, pbuf);
728 #endif
733 * Query an attribute of a drawable.
735 _X_EXPORT void
736 glXQueryDrawable(Display * dpy, GLXDrawable drawable,
737 int attribute, unsigned int *value)
739 WARN_ONCE_GLX_1_3(dpy, __func__);
740 #ifdef GLX_USE_APPLEGL
741 Window root;
742 int x, y;
743 unsigned int width, height, bd, depth;
745 if (apple_glx_pixmap_query(drawable, attribute, value))
746 return; /*done */
748 if (apple_glx_pbuffer_query(drawable, attribute, value))
749 return; /*done */
752 * The OpenGL spec states that we should report GLXBadDrawable if
753 * the drawable is invalid, however doing so would require that we
754 * use XSetErrorHandler(), which is known to not be thread safe.
755 * If we use a round-trip call to validate the drawable, there could
756 * be a race, so instead we just opt in favor of letting the
757 * XGetGeometry request fail with a GetGeometry request X error
758 * rather than GLXBadDrawable, in what is hoped to be a rare
759 * case of an invalid drawable. In practice most and possibly all
760 * X11 apps using GLX shouldn't notice a difference.
762 if (XGetGeometry
763 (dpy, drawable, &root, &x, &y, &width, &height, &bd, &depth)) {
764 switch (attribute) {
765 case GLX_WIDTH:
766 *value = width;
767 break;
769 case GLX_HEIGHT:
770 *value = height;
771 break;
774 #else
775 GetDrawableAttribute(dpy, drawable, attribute, value);
776 #endif
780 #ifndef GLX_USE_APPLEGL
782 * Query an attribute of a pbuffer.
784 _X_EXPORT int
785 glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable,
786 int attribute, unsigned int *value)
788 return GetDrawableAttribute(dpy, drawable, attribute, value);
790 #endif
793 * Select the event mask for a drawable.
795 _X_EXPORT void
796 glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask)
798 #ifdef GLX_USE_APPLEGL
799 XWindowAttributes xwattr;
801 if (apple_glx_pbuffer_set_event_mask(drawable, mask))
802 return; /*done */
805 * The spec allows a window, but currently there are no valid
806 * events for a window, so do nothing.
808 if (XGetWindowAttributes(dpy, drawable, &xwattr))
809 return; /*done */
810 /* The drawable seems to be invalid. Report an error. */
812 __glXSendError(dpy, GLXBadDrawable, drawable,
813 X_GLXChangeDrawableAttributes, false);
814 #else
815 CARD32 attribs[2];
817 attribs[0] = (CARD32) GLX_EVENT_MASK;
818 attribs[1] = (CARD32) mask;
820 ChangeDrawableAttribute(dpy, drawable, attribs, 1);
821 #endif
826 * Get the selected event mask for a drawable.
828 _X_EXPORT void
829 glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask)
831 #ifdef GLX_USE_APPLEGL
832 XWindowAttributes xwattr;
834 if (apple_glx_pbuffer_get_event_mask(drawable, mask))
835 return; /*done */
838 * The spec allows a window, but currently there are no valid
839 * events for a window, so do nothing, but set the mask to 0.
841 if (XGetWindowAttributes(dpy, drawable, &xwattr)) {
842 /* The window is valid, so set the mask to 0. */
843 *mask = 0;
844 return; /*done */
846 /* The drawable seems to be invalid. Report an error. */
848 __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes,
849 true);
850 #else
851 unsigned int value;
854 /* The non-sense with value is required because on LP64 platforms
855 * sizeof(unsigned int) != sizeof(unsigned long). On little-endian
856 * we could just type-cast the pointer, but why?
859 GetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value);
860 *mask = value;
861 #endif
865 _X_EXPORT GLXPixmap
866 glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap,
867 const int *attrib_list)
869 WARN_ONCE_GLX_1_3(dpy, __func__);
871 #ifdef GLX_USE_APPLEGL
872 const struct glx_config *modes = (const struct glx_config *) config;
874 if (apple_glx_pixmap_create(dpy, modes->screen, pixmap, modes))
875 return None;
877 return pixmap;
878 #else
879 return CreateDrawable(dpy, (struct glx_config *) config,
880 (Drawable) pixmap, attrib_list, X_GLXCreatePixmap);
881 #endif
885 _X_EXPORT GLXWindow
886 glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
887 const int *attrib_list)
889 WARN_ONCE_GLX_1_3(dpy, __func__);
890 #ifdef GLX_USE_APPLEGL
891 XWindowAttributes xwattr;
892 XVisualInfo *visinfo;
894 (void) attrib_list; /*unused according to GLX 1.4 */
896 XGetWindowAttributes(dpy, win, &xwattr);
898 visinfo = glXGetVisualFromFBConfig(dpy, config);
900 if (NULL == visinfo) {
901 __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateWindow, false);
902 return None;
905 if (visinfo->visualid != XVisualIDFromVisual(xwattr.visual)) {
906 __glXSendError(dpy, BadMatch, 0, X_GLXCreateWindow, true);
907 return None;
910 XFree(visinfo);
912 return win;
913 #else
914 return CreateDrawable(dpy, (struct glx_config *) config,
915 (Drawable) win, attrib_list, X_GLXCreateWindow);
916 #endif
920 _X_EXPORT void
921 glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
923 WARN_ONCE_GLX_1_3(dpy, __func__);
924 #ifdef GLX_USE_APPLEGL
925 if (apple_glx_pixmap_destroy(dpy, pixmap))
926 __glXSendError(dpy, GLXBadPixmap, pixmap, X_GLXDestroyPixmap, false);
927 #else
928 DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap);
929 #endif
933 _X_EXPORT void
934 glXDestroyWindow(Display * dpy, GLXWindow win)
936 WARN_ONCE_GLX_1_3(dpy, __func__);
937 #ifndef GLX_USE_APPLEGL
938 DestroyDrawable(dpy, (GLXDrawable) win, X_GLXDestroyWindow);
939 #endif
942 #ifndef GLX_USE_APPLEGL
943 _X_EXPORT
944 GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
945 (Display * dpy, GLXPbufferSGIX pbuf),
946 (dpy, pbuf), glXDestroyPbuffer)
948 _X_EXPORT
949 GLX_ALIAS_VOID(glXSelectEventSGIX,
950 (Display * dpy, GLXDrawable drawable,
951 unsigned long mask), (dpy, drawable, mask), glXSelectEvent)
953 _X_EXPORT
954 GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
955 (Display * dpy, GLXDrawable drawable,
956 unsigned long *mask), (dpy, drawable, mask),
957 glXGetSelectedEvent)
958 #endif