blob: f11305a41df014114e9152fc35e7a7126d7e55ab [file] [log] [blame]
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001/*
2 * (C) Copyright IBM Corporation 2004
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * 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:
11 *
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.
15 *
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.
23 */
24
25/**
26 * \file glx_pbuffer.c
27 * Implementation of pbuffer related functions.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020028 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +000029 * \author Ian Romanick <idr@us.ibm.com>
30 */
31
32#include <inttypes.h>
33#include "glxclient.h"
Brian Paul82dfd4b2005-08-11 14:18:53 +000034#include <X11/extensions/extutil.h>
35#include <X11/extensions/Xext.h>
Adam Jacksoncb3610e2004-10-25 21:09:16 +000036#include <assert.h>
37#include <string.h>
Adam Jacksoncb3610e2004-10-25 21:09:16 +000038#include "glxextensions.h"
Adam Jacksoncb3610e2004-10-25 21:09:16 +000039
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070040#ifdef GLX_USE_APPLEGL
41#include <pthread.h>
42#include "apple_glx_drawable.h"
43#include "glx_error.h"
44#endif
45
Tormod Voldene8573032009-09-20 20:20:01 +020046#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 } \
52 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +000053
54/**
Ian Romanick1f309c42009-09-15 13:12:22 -070055 * Emit a warning when clients use GLX 1.3 functions on pre-1.3 systems.
56 */
57static void
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070058warn_GLX_1_3(Display * dpy, const char *function_name)
Ian Romanick1f309c42009-09-15 13:12:22 -070059{
Kristian Høgsbergc356f582010-07-28 11:16:00 -040060 struct glx_display *priv = __glXInitialize(dpy);
Ian Romanick1f309c42009-09-15 13:12:22 -070061
62 if (priv->minorVersion < 3) {
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070063 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);
Ian Romanick1f309c42009-09-15 13:12:22 -070067 }
68}
69
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070070#ifndef GLX_USE_APPLEGL
Ian Romanick1f309c42009-09-15 13:12:22 -070071/**
Adam Jacksoncb3610e2004-10-25 21:09:16 +000072 * Change a drawable's attribute.
73 *
74 * This function is used to implement \c glXSelectEvent and
75 * \c glXSelectEventSGIX.
76 *
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.
Adam Jacksoncb3610e2004-10-25 21:09:16 +000080 */
81static void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +020082ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable,
83 const CARD32 * attribs, size_t num_attribs)
Adam Jacksoncb3610e2004-10-25 21:09:16 +000084{
Kristian Høgsbergc356f582010-07-28 11:16:00 -040085 struct glx_display *priv = __glXInitialize(dpy);
Jon TURNEYae9487c2010-08-09 14:47:26 +010086#ifdef GLX_DIRECT_RENDERING
Vinson Lee5c9e54f2010-07-15 00:20:41 -070087 __GLXDRIdrawable *pdraw;
Jon TURNEYae9487c2010-08-09 14:47:26 +010088#endif
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +020089 CARD32 *output;
Kristian Høgsbergc25eb992006-06-13 01:41:18 +000090 CARD8 opcode;
Nick Bowlerf8d81c32010-07-14 12:01:49 -040091 int i;
Adam Jacksoncb3610e2004-10-25 21:09:16 +000092
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +020093 if ((dpy == NULL) || (drawable == 0)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +000094 return;
95 }
96
Kristian Høgsbergc25eb992006-06-13 01:41:18 +000097 opcode = __glXSetupForCommand(dpy);
98 if (!opcode)
99 return;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000100
101 LockDisplay(dpy);
102
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200103 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000104 xGLXChangeDrawableAttributesReq *req;
105
Julien Cristau4324d6f2011-01-23 08:26:35 -0800106 GetReqExtra(GLXChangeDrawableAttributes, 8 * num_attribs, req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000107 output = (CARD32 *) (req + 1);
108
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000109 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000110 req->glxCode = X_GLXChangeDrawableAttributes;
111 req->drawable = drawable;
112 req->numAttribs = (CARD32) num_attribs;
113 }
114 else {
115 xGLXVendorPrivateWithReplyReq *vpreq;
116
Julien Cristaue27913f2011-01-26 04:03:16 -0800117 GetReqExtra(GLXVendorPrivateWithReply, 8 + (8 * num_attribs), vpreq);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000118 output = (CARD32 *) (vpreq + 1);
119
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000120 vpreq->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000121 vpreq->glxCode = X_GLXVendorPrivateWithReply;
122 vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX;
123
124 output[0] = (CARD32) drawable;
Julien Cristaue27913f2011-01-26 04:03:16 -0800125 output[1] = num_attribs;
126 output += 2;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000127 }
128
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200129 (void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000130
131 UnlockDisplay(dpy);
132 SyncHandle();
133
Jon TURNEYae9487c2010-08-09 14:47:26 +0100134#ifdef GLX_DIRECT_RENDERING
135 pdraw = GetGLXDRIDrawable(dpy, drawable);
136
Jesse Barnes6ae9e8c2011-05-03 10:20:14 -0700137 if (!pdraw)
138 return;
139
Nick Bowlerf8d81c32010-07-14 12:01:49 -0400140 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;
146 }
147 }
Jon TURNEYae9487c2010-08-09 14:47:26 +0100148#endif
Nick Bowlerf8d81c32010-07-14 12:01:49 -0400149
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000150 return;
151}
152
153
Michel Dänzer236355102008-04-10 15:45:52 -0400154#ifdef GLX_DIRECT_RENDERING
Michel Dänzer236355102008-04-10 15:45:52 -0400155static GLenum
156determineTextureTarget(const int *attribs, int numAttribs)
157{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200158 GLenum target = 0;
159 int i;
Michel Dänzer236355102008-04-10 15:45:52 -0400160
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200161 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;
170 }
171 }
172 }
173
174 return target;
Michel Dänzer236355102008-04-10 15:45:52 -0400175}
Eric Anholt66175aa2009-03-18 12:07:09 -0700176
Eric Anholt66175aa2009-03-18 12:07:09 -0700177static GLenum
178determineTextureFormat(const int *attribs, int numAttribs)
179{
Eric Anholt66175aa2009-03-18 12:07:09 -0700180 int i;
181
182 for (i = 0; i < numAttribs; i++) {
183 if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200184 return attribs[2 * i + 1];
Eric Anholt66175aa2009-03-18 12:07:09 -0700185 }
186
187 return 0;
188}
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400189
Adam Jackson48331042011-03-31 20:43:57 +0000190static GLboolean
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400191CreateDRIDrawable(Display *dpy, struct glx_config *config,
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400192 XID drawable, XID glxdrawable,
193 const int *attrib_list, size_t num_attribs)
194{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400195 struct glx_display *const priv = __glXInitialize(dpy);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400196 __GLXDRIdrawable *pdraw;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400197 struct glx_screen *psc;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400198
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400199 psc = priv->screens[config->screen];
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400200 if (psc->driScreen == NULL)
Adam Jackson48331042011-03-31 20:43:57 +0000201 return GL_TRUE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400202
203 pdraw = psc->driScreen->createDrawable(psc, drawable,
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400204 glxdrawable, config);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400205 if (pdraw == NULL) {
206 fprintf(stderr, "failed to create drawable\n");
Adam Jackson48331042011-03-31 20:43:57 +0000207 return GL_FALSE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400208 }
209
Kristian Høgsberge3e81962010-07-19 21:15:50 -0400210 if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400211 (*pdraw->destroyDrawable) (pdraw);
Adam Jackson48331042011-03-31 20:43:57 +0000212 return GL_FALSE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400213 }
214
215 pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
216 pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);
Adam Jackson48331042011-03-31 20:43:57 +0000217
218 return GL_TRUE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400219}
220
221static void
222DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
223{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400224 struct glx_display *const priv = __glXInitialize(dpy);
Kristian Høgsbergeeaab202010-07-22 22:36:37 -0400225 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
Kristian Høgsberg80e48dd2010-09-09 08:06:40 -0400226 XID xid;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400227
228 if (pdraw != NULL) {
Kristian Høgsberg80e48dd2010-09-09 08:06:40 -0400229 xid = pdraw->xDrawable;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400230 (*pdraw->destroyDrawable) (pdraw);
Kristian Høgsberge3e81962010-07-19 21:15:50 -0400231 __glxHashDelete(priv->drawHash, drawable);
Kristian Høgsbergd8ab9aa2010-09-08 20:55:02 -0400232 if (destroy_xdrawable)
Kristian Høgsberg80e48dd2010-09-09 08:06:40 -0400233 XFreePixmap(priv->dpy, xid);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400234 }
235}
236
237#else
238
Adam Jackson48331042011-03-31 20:43:57 +0000239static GLboolean
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400240CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig,
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400241 XID drawable, XID glxdrawable,
242 const int *attrib_list, size_t num_attribs)
243{
Jon TURNEYf816a9f2013-02-26 15:47:44 +0000244 return GL_TRUE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400245}
246
247static void
248DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
249{
250}
251
Michel Dänzer236355102008-04-10 15:45:52 -0400252#endif
253
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000254/**
255 * Get a drawable's attribute.
256 *
257 * This function is used to implement \c glXGetSelectedEvent and
258 * \c glXGetSelectedEventSGIX.
259 *
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.
263 *
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.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000268 */
269static int
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200270GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
271 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000272{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400273 struct glx_display *priv;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000274 xGLXGetDrawableAttributesReply reply;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200275 CARD32 *data;
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000276 CARD8 opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000277 unsigned int length;
278 unsigned int i;
279 unsigned int num_attributes;
Owain G. Ainsworthb4866f82009-01-11 20:40:07 +0000280 GLboolean use_glx_1_3;
Adam Jacksond25ad502006-04-07 00:05:50 +0000281
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200282 if ((dpy == NULL) || (drawable == 0)) {
Adam Jacksond25ad502006-04-07 00:05:50 +0000283 return 0;
284 }
285
286 priv = __glXInitialize(dpy);
Owain G. Ainsworthb4866f82009-01-11 20:40:07 +0000287 use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3));
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000288
Brian Paul42725d62006-02-07 00:39:56 +0000289 *value = 0;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000290
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000291
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000292 opcode = __glXSetupForCommand(dpy);
293 if (!opcode)
294 return 0;
295
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000296 LockDisplay(dpy);
297
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200298 if (use_glx_1_3) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000299 xGLXGetDrawableAttributesReq *req;
300
Julien Cristau4324d6f2011-01-23 08:26:35 -0800301 GetReq(GLXGetDrawableAttributes, req);
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000302 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000303 req->glxCode = X_GLXGetDrawableAttributes;
304 req->drawable = drawable;
305 }
306 else {
307 xGLXVendorPrivateWithReplyReq *vpreq;
308
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200309 GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000310 data = (CARD32 *) (vpreq + 1);
311 data[0] = (CARD32) drawable;
312
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000313 vpreq->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000314 vpreq->glxCode = X_GLXVendorPrivateWithReply;
315 vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX;
316 }
317
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200318 _XReply(dpy, (xReply *) & reply, 0, False);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000319
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200320 if (reply.type == X_Error) {
321 UnlockDisplay(dpy);
322 SyncHandle();
323 return 0;
Brian Paul42725d62006-02-07 00:39:56 +0000324 }
325
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000326 length = reply.length;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200327 if (length) {
328 num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
Matt Turner2b7a9722012-09-03 19:44:00 -0700329 data = malloc(length * sizeof(CARD32));
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200330 if (data == NULL) {
331 /* Throw data on the floor */
332 _XEatData(dpy, length);
333 }
334 else {
335 _XRead(dpy, (char *) data, length * sizeof(CARD32));
Brian Paul42725d62006-02-07 00:39:56 +0000336
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200337 /* Search the set of returned attributes for the attribute requested by
338 * the caller.
339 */
340 for (i = 0; i < num_attributes; i++) {
341 if (data[i * 2] == attribute) {
342 *value = data[(i * 2) + 1];
343 break;
344 }
345 }
Brian Paul42725d62006-02-07 00:39:56 +0000346
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700347#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200348 {
Kristian Høgsbergeeaab202010-07-22 22:36:37 -0400349 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
Michel Dänzer236355102008-04-10 15:45:52 -0400350
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200351 if (pdraw != NULL && !pdraw->textureTarget)
352 pdraw->textureTarget =
353 determineTextureTarget((const int *) data, num_attributes);
Eric Anholt66175aa2009-03-18 12:07:09 -0700354 if (pdraw != NULL && !pdraw->textureFormat)
355 pdraw->textureFormat =
356 determineTextureFormat((const int *) data, num_attributes);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200357 }
Michel Dänzer236355102008-04-10 15:45:52 -0400358#endif
359
Matt Turner7c7b7b02012-09-04 22:52:36 -0700360 free(data);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200361 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000362 }
363
364 UnlockDisplay(dpy);
365 SyncHandle();
366
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000367 return 0;
368}
369
Adam Jackson48331042011-03-31 20:43:57 +0000370static void
371protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode)
372{
373 xGLXDestroyPbufferReq *req;
374 CARD8 opcode;
375
376 opcode = __glXSetupForCommand(dpy);
377 if (!opcode)
378 return;
379
380 LockDisplay(dpy);
381
382 GetReq(GLXDestroyPbuffer, req);
383 req->reqType = opcode;
384 req->glxCode = glxCode;
385 req->pbuffer = (GLXPbuffer) drawable;
386
387 UnlockDisplay(dpy);
388 SyncHandle();
389}
390
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000391/**
392 * Create a non-pbuffer GLX drawable.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000393 */
394static GLXDrawable
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400395CreateDrawable(Display *dpy, struct glx_config *config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200396 Drawable drawable, const int *attrib_list, CARD8 glxCode)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000397{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200398 xGLXCreateWindowReq *req;
Jesse Barnes4df13762011-05-06 10:31:24 -0700399 struct glx_drawable *glxDraw;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200400 CARD32 *data;
Ian Romanickb47731f2005-03-04 17:53:24 +0000401 unsigned int i;
David Reveman342d1de2006-04-11 12:07:41 +0000402 CARD8 opcode;
Adam Jacksona95ec182011-05-25 06:11:20 -0400403 GLXDrawable xid;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000404
Ian Romanickb47731f2005-03-04 17:53:24 +0000405 i = 0;
406 if (attrib_list) {
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200407 while (attrib_list[i * 2] != None)
408 i++;
Ian Romanickb47731f2005-03-04 17:53:24 +0000409 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000410
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000411 opcode = __glXSetupForCommand(dpy);
412 if (!opcode)
413 return None;
David Reveman342d1de2006-04-11 12:07:41 +0000414
Matt Turner7c7b7b02012-09-04 22:52:36 -0700415 glxDraw = malloc(sizeof(*glxDraw));
Jesse Barnes4df13762011-05-06 10:31:24 -0700416 if (!glxDraw)
417 return None;
418
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000419 LockDisplay(dpy);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200420 GetReqExtra(GLXCreateWindow, 8 * i, req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000421 data = (CARD32 *) (req + 1);
422
David Reveman342d1de2006-04-11 12:07:41 +0000423 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000424 req->glxCode = glxCode;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400425 req->screen = config->screen;
426 req->fbconfig = config->fbconfigID;
427 req->window = drawable;
Adam Jacksona95ec182011-05-25 06:11:20 -0400428 req->glxwindow = xid = XAllocID(dpy);
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400429 req->numAttribs = i;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000430
Brian Paul5f40a7a2010-03-02 07:34:29 -0700431 if (attrib_list)
432 memcpy(data, attrib_list, 8 * i);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200433
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000434 UnlockDisplay(dpy);
435 SyncHandle();
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200436
Jesse Barnes4df13762011-05-06 10:31:24 -0700437 if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) {
438 free(glxDraw);
439 return None;
440 }
441
Adam Jackson48331042011-03-31 20:43:57 +0000442 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;
449 }
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400450
Adam Jacksona95ec182011-05-25 06:11:20 -0400451 return xid;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000452}
453
454
455/**
456 * Destroy a non-pbuffer GLX drawable.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000457 */
458static void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200459DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000460{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200461 if ((dpy == NULL) || (drawable == 0)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000462 return;
463 }
464
Adam Jackson48331042011-03-31 20:43:57 +0000465 protocolDestroyDrawable(dpy, drawable, glxCode);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000466
Jesse Barnes4df13762011-05-06 10:31:24 -0700467 DestroyGLXDrawable(dpy, drawable);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400468 DestroyDRIDrawable(dpy, drawable, GL_FALSE);
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400469
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000470 return;
471}
472
473
474/**
475 * Create a pbuffer.
476 *
477 * This function is used to implement \c glXCreatePbuffer and
478 * \c glXCreateGLXPbufferSGIX.
479 *
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.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000483 */
484static GLXDrawable
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400485CreatePbuffer(Display * dpy, struct glx_config *config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200486 unsigned int width, unsigned int height,
487 const int *attrib_list, GLboolean size_in_attribs)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000488{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400489 struct glx_display *priv = __glXInitialize(dpy);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000490 GLXDrawable id = 0;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200491 CARD32 *data;
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000492 CARD8 opcode;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200493 unsigned int i;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400494 Pixmap pixmap;
Adam Jackson48331042011-03-31 20:43:57 +0000495 GLboolean glx_1_3 = GL_FALSE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000496
Ian Romanickb47731f2005-03-04 17:53:24 +0000497 i = 0;
498 if (attrib_list) {
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200499 while (attrib_list[i * 2])
500 i++;
Ian Romanickb47731f2005-03-04 17:53:24 +0000501 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000502
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000503 opcode = __glXSetupForCommand(dpy);
504 if (!opcode)
505 return None;
506
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000507 LockDisplay(dpy);
508 id = XAllocID(dpy);
509
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200510 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
511 xGLXCreatePbufferReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000512 unsigned int extra = (size_in_attribs) ? 0 : 2;
513
Adam Jackson48331042011-03-31 20:43:57 +0000514 glx_1_3 = GL_TRUE;
515
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200516 GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000517 data = (CARD32 *) (req + 1);
518
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000519 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000520 req->glxCode = X_GLXCreatePbuffer;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400521 req->screen = config->screen;
522 req->fbconfig = config->fbconfigID;
523 req->pbuffer = id;
524 req->numAttribs = i + extra;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000525
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200526 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;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000532 }
533 }
534 else {
535 xGLXVendorPrivateReq *vpreq;
536
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200537 GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000538 data = (CARD32 *) (vpreq + 1);
539
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000540 vpreq->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000541 vpreq->glxCode = X_GLXVendorPrivate;
542 vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX;
543
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400544 data[0] = config->screen;
545 data[1] = config->fbconfigID;
546 data[2] = id;
547 data[3] = width;
548 data[4] = height;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000549 data += 5;
550 }
551
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200552 (void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000553
554 UnlockDisplay(dpy);
555 SyncHandle();
556
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400557 pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
558 width, height, config->rgbBits);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400559
Adam Jackson48331042011-03-31 20:43:57 +0000560 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;
565 }
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400566
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000567 return id;
568}
569
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400570/**
571 * Destroy a pbuffer.
572 *
573 * This function is used to implement \c glXDestroyPbuffer and
574 * \c glXDestroyGLXPbufferSGIX.
575 *
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.
579 */
580static void
581DestroyPbuffer(Display * dpy, GLXDrawable drawable)
582{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400583 struct glx_display *priv = __glXInitialize(dpy);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400584 CARD8 opcode;
585
586 if ((dpy == NULL) || (drawable == 0)) {
587 return;
588 }
589
590 opcode = __glXSetupForCommand(dpy);
591 if (!opcode)
592 return;
593
594 LockDisplay(dpy);
595
596 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
597 xGLXDestroyPbufferReq *req;
598
599 GetReq(GLXDestroyPbuffer, req);
600 req->reqType = opcode;
601 req->glxCode = X_GLXDestroyPbuffer;
602 req->pbuffer = (GLXPbuffer) drawable;
603 }
604 else {
605 xGLXVendorPrivateWithReplyReq *vpreq;
606 CARD32 *data;
607
608 GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
609 data = (CARD32 *) (vpreq + 1);
610
611 data[0] = (CARD32) drawable;
612
613 vpreq->reqType = opcode;
614 vpreq->glxCode = X_GLXVendorPrivateWithReply;
615 vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX;
616 }
617
618 UnlockDisplay(dpy);
619 SyncHandle();
620
621 DestroyDRIDrawable(dpy, drawable, GL_TRUE);
622
623 return;
624}
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000625
626/**
627 * Create a new pbuffer.
628 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400629_X_EXPORT GLXPbufferSGIX
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200630glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config,
631 unsigned int width, unsigned int height,
632 int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000633{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400634 return (GLXPbufferSGIX) CreatePbuffer(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200635 width, height,
636 attrib_list, GL_FALSE);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000637}
638
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700639#endif /* GLX_USE_APPLEGL */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000640
641/**
642 * Create a new pbuffer.
643 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400644_X_EXPORT GLXPbuffer
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200645glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000646{
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400647 int i, width, height;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700648#ifdef GLX_USE_APPLEGL
649 GLXPbuffer result;
650 int errorcode;
651#endif
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400652
653 width = 0;
654 height = 0;
655
Tormod Voldene8573032009-09-20 20:20:01 +0200656 WARN_ONCE_GLX_1_3(dpy, __func__);
Ian Romanick1f309c42009-09-15 13:12:22 -0700657
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700658#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;
665
666 case GLX_PBUFFER_HEIGHT:
667 height = attrib_list[i + 1];
668 ++i;
669 break;
670
671 case GLX_LARGEST_PBUFFER:
672 /* This is a hint we should probably handle, but how? */
673 ++i;
674 break;
675
676 case GLX_PRESERVED_CONTENTS:
677 /* The contents are always preserved with AppleSGLX with CGL. */
678 ++i;
679 break;
680
681 default:
682 return None;
683 }
684 }
685
686 if (apple_glx_pbuffer_create(dpy, config, width, height, &errorcode,
687 &result)) {
688 /*
689 * apple_glx_pbuffer_create only sets the errorcode to core X11
690 * errors.
691 */
692 __glXSendError(dpy, errorcode, 0, X_GLXCreatePbuffer, true);
693
694 return None;
695 }
696
697 return result;
698#else
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400699 for (i = 0; attrib_list[i * 2]; i++) {
700 switch (attrib_list[i * 2]) {
701 case GLX_PBUFFER_WIDTH:
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200702 width = attrib_list[i * 2 + 1];
703 break;
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400704 case GLX_PBUFFER_HEIGHT:
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200705 height = attrib_list[i * 2 + 1];
706 break;
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400707 }
708 }
709
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400710 return (GLXPbuffer) CreatePbuffer(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200711 width, height, attrib_list, GL_TRUE);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700712#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000713}
714
715
716/**
717 * Destroy an existing pbuffer.
718 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400719_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200720glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000721{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700722#ifdef GLX_USE_APPLEGL
723 if (apple_glx_pbuffer_destroy(dpy, pbuf)) {
724 __glXSendError(dpy, GLXBadPbuffer, pbuf, X_GLXDestroyPbuffer, false);
725 }
726#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200727 DestroyPbuffer(dpy, pbuf);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700728#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000729}
730
731
732/**
733 * Query an attribute of a drawable.
734 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400735_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200736glXQueryDrawable(Display * dpy, GLXDrawable drawable,
737 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000738{
Tormod Voldene8573032009-09-20 20:20:01 +0200739 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700740#ifdef GLX_USE_APPLEGL
741 Window root;
742 int x, y;
743 unsigned int width, height, bd, depth;
744
745 if (apple_glx_pixmap_query(drawable, attribute, value))
746 return; /*done */
747
748 if (apple_glx_pbuffer_query(drawable, attribute, value))
749 return; /*done */
750
751 /*
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.
761 */
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;
768
769 case GLX_HEIGHT:
770 *value = height;
771 break;
772 }
773 }
774#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200775 GetDrawableAttribute(dpy, drawable, attribute, value);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700776#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000777}
778
779
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700780#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000781/**
782 * Query an attribute of a pbuffer.
783 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400784_X_EXPORT int
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200785glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable,
786 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000787{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200788 return GetDrawableAttribute(dpy, drawable, attribute, value);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000789}
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700790#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000791
792/**
793 * Select the event mask for a drawable.
794 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400795_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200796glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000797{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700798#ifdef GLX_USE_APPLEGL
799 XWindowAttributes xwattr;
800
801 if (apple_glx_pbuffer_set_event_mask(drawable, mask))
802 return; /*done */
803
804 /*
805 * The spec allows a window, but currently there are no valid
806 * events for a window, so do nothing.
807 */
808 if (XGetWindowAttributes(dpy, drawable, &xwattr))
809 return; /*done */
810 /* The drawable seems to be invalid. Report an error. */
811
812 __glXSendError(dpy, GLXBadDrawable, drawable,
813 X_GLXChangeDrawableAttributes, false);
814#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000815 CARD32 attribs[2];
816
817 attribs[0] = (CARD32) GLX_EVENT_MASK;
818 attribs[1] = (CARD32) mask;
819
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200820 ChangeDrawableAttribute(dpy, drawable, attribs, 1);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700821#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000822}
823
824
825/**
826 * Get the selected event mask for a drawable.
827 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400828_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200829glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000830{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700831#ifdef GLX_USE_APPLEGL
832 XWindowAttributes xwattr;
833
834 if (apple_glx_pbuffer_get_event_mask(drawable, mask))
835 return; /*done */
836
837 /*
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.
840 */
841 if (XGetWindowAttributes(dpy, drawable, &xwattr)) {
842 /* The window is valid, so set the mask to 0. */
843 *mask = 0;
844 return; /*done */
845 }
846 /* The drawable seems to be invalid. Report an error. */
847
848 __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes,
849 true);
850#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000851 unsigned int value;
852
853
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?
857 */
858
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200859 GetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000860 *mask = value;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700861#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000862}
863
864
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400865_X_EXPORT GLXPixmap
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200866glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap,
867 const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000868{
Tormod Voldene8573032009-09-20 20:20:01 +0200869 WARN_ONCE_GLX_1_3(dpy, __func__);
Ian Romanick1f309c42009-09-15 13:12:22 -0700870
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700871#ifdef GLX_USE_APPLEGL
Jeremy Huddlestonbb621cb2011-06-05 17:02:33 -0400872 const struct glx_config *modes = (const struct glx_config *) config;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700873
874 if (apple_glx_pixmap_create(dpy, modes->screen, pixmap, modes))
875 return None;
876
877 return pixmap;
878#else
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400879 return CreateDrawable(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200880 (Drawable) pixmap, attrib_list, X_GLXCreatePixmap);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700881#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000882}
883
884
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400885_X_EXPORT GLXWindow
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200886glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
887 const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000888{
Tormod Voldene8573032009-09-20 20:20:01 +0200889 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700890#ifdef GLX_USE_APPLEGL
891 XWindowAttributes xwattr;
892 XVisualInfo *visinfo;
Ian Romanick1f309c42009-09-15 13:12:22 -0700893
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700894 (void) attrib_list; /*unused according to GLX 1.4 */
895
896 XGetWindowAttributes(dpy, win, &xwattr);
897
898 visinfo = glXGetVisualFromFBConfig(dpy, config);
899
900 if (NULL == visinfo) {
901 __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateWindow, false);
902 return None;
903 }
904
905 if (visinfo->visualid != XVisualIDFromVisual(xwattr.visual)) {
906 __glXSendError(dpy, BadMatch, 0, X_GLXCreateWindow, true);
907 return None;
908 }
909
Matt Turner7c7b7b02012-09-04 22:52:36 -0700910 free(visinfo);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700911
912 return win;
913#else
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400914 return CreateDrawable(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200915 (Drawable) win, attrib_list, X_GLXCreateWindow);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700916#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000917}
918
919
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400920_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200921glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000922{
Tormod Voldene8573032009-09-20 20:20:01 +0200923 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700924#ifdef GLX_USE_APPLEGL
925 if (apple_glx_pixmap_destroy(dpy, pixmap))
926 __glXSendError(dpy, GLXBadPixmap, pixmap, X_GLXDestroyPixmap, false);
927#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200928 DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700929#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000930}
931
932
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400933_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200934glXDestroyWindow(Display * dpy, GLXWindow win)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000935{
Tormod Voldene8573032009-09-20 20:20:01 +0200936 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700937#ifndef GLX_USE_APPLEGL
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200938 DestroyDrawable(dpy, (GLXDrawable) win, X_GLXDestroyWindow);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700939#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000940}
941
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700942#ifndef GLX_USE_APPLEGL
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400943_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200944GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
945 (Display * dpy, GLXPbufferSGIX pbuf),
946 (dpy, pbuf), glXDestroyPbuffer)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000947
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400948_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200949GLX_ALIAS_VOID(glXSelectEventSGIX,
950 (Display * dpy, GLXDrawable drawable,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200951 unsigned long mask), (dpy, drawable, mask), glXSelectEvent)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000952
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400953_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200954GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
955 (Display * dpy, GLXDrawable drawable,
956 unsigned long *mask), (dpy, drawable, mask),
957 glXGetSelectedEvent)
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700958#endif