blob: 231ab206045e28168a4c2a27d7af768c613e6101 [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>
Jon TURNEY5a459a02014-05-12 10:47:07 +010042#include "apple/apple_glx_drawable.h"
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070043#endif
44
Ian Romanickd5aee172013-08-08 18:17:24 -070045#include "glx_error.h"
46
Tormod Voldene8573032009-09-20 20:20:01 +020047#define WARN_ONCE_GLX_1_3(a, b) { \
48 static int warned=1; \
49 if(warned) { \
50 warn_GLX_1_3((a), b ); \
51 warned=0; \
52 } \
53 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +000054
55/**
Ian Romanick1f309c42009-09-15 13:12:22 -070056 * Emit a warning when clients use GLX 1.3 functions on pre-1.3 systems.
57 */
58static void
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070059warn_GLX_1_3(Display * dpy, const char *function_name)
Ian Romanick1f309c42009-09-15 13:12:22 -070060{
Kristian Høgsbergc356f582010-07-28 11:16:00 -040061 struct glx_display *priv = __glXInitialize(dpy);
Ian Romanick1f309c42009-09-15 13:12:22 -070062
Juha-Pekka Heikkilae5036092014-02-07 14:44:00 +020063 if (priv && priv->minorVersion < 3) {
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070064 fprintf(stderr,
65 "WARNING: Application calling GLX 1.3 function \"%s\" "
66 "when GLX 1.3 is not supported! This is an application bug!\n",
67 function_name);
Ian Romanick1f309c42009-09-15 13:12:22 -070068 }
69}
70
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070071#ifndef GLX_USE_APPLEGL
Ian Romanick1f309c42009-09-15 13:12:22 -070072/**
Adam Jacksoncb3610e2004-10-25 21:09:16 +000073 * Change a drawable's attribute.
74 *
75 * This function is used to implement \c glXSelectEvent and
76 * \c glXSelectEventSGIX.
77 *
78 * \note
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.
Adam Jacksoncb3610e2004-10-25 21:09:16 +000081 */
82static void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +020083ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable,
84 const CARD32 * attribs, size_t num_attribs)
Adam Jacksoncb3610e2004-10-25 21:09:16 +000085{
Kristian Høgsbergc356f582010-07-28 11:16:00 -040086 struct glx_display *priv = __glXInitialize(dpy);
Jon TURNEYae9487c2010-08-09 14:47:26 +010087#ifdef GLX_DIRECT_RENDERING
Vinson Lee5c9e54f2010-07-15 00:20:41 -070088 __GLXDRIdrawable *pdraw;
Jon TURNEYae9487c2010-08-09 14:47:26 +010089#endif
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +020090 CARD32 *output;
Kristian Høgsbergc25eb992006-06-13 01:41:18 +000091 CARD8 opcode;
Nick Bowlerf8d81c32010-07-14 12:01:49 -040092 int i;
Adam Jacksoncb3610e2004-10-25 21:09:16 +000093
Juha-Pekka Heikkilae5036092014-02-07 14:44:00 +020094 if ((priv == NULL) || (dpy == NULL) || (drawable == 0)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +000095 return;
96 }
97
Kristian Høgsbergc25eb992006-06-13 01:41:18 +000098 opcode = __glXSetupForCommand(dpy);
99 if (!opcode)
100 return;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000101
102 LockDisplay(dpy);
103
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200104 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000105 xGLXChangeDrawableAttributesReq *req;
106
Julien Cristau4324d6f2011-01-23 08:26:35 -0800107 GetReqExtra(GLXChangeDrawableAttributes, 8 * num_attribs, req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000108 output = (CARD32 *) (req + 1);
109
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000110 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000111 req->glxCode = X_GLXChangeDrawableAttributes;
112 req->drawable = drawable;
113 req->numAttribs = (CARD32) num_attribs;
114 }
115 else {
116 xGLXVendorPrivateWithReplyReq *vpreq;
117
Julien Cristaue27913f2011-01-26 04:03:16 -0800118 GetReqExtra(GLXVendorPrivateWithReply, 8 + (8 * num_attribs), vpreq);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000119 output = (CARD32 *) (vpreq + 1);
120
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000121 vpreq->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000122 vpreq->glxCode = X_GLXVendorPrivateWithReply;
123 vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX;
124
125 output[0] = (CARD32) drawable;
Julien Cristaue27913f2011-01-26 04:03:16 -0800126 output[1] = num_attribs;
127 output += 2;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000128 }
129
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200130 (void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000131
132 UnlockDisplay(dpy);
133 SyncHandle();
134
Jon TURNEYae9487c2010-08-09 14:47:26 +0100135#ifdef GLX_DIRECT_RENDERING
136 pdraw = GetGLXDRIDrawable(dpy, drawable);
137
Jesse Barnes6ae9e8c2011-05-03 10:20:14 -0700138 if (!pdraw)
139 return;
140
Nick Bowlerf8d81c32010-07-14 12:01:49 -0400141 for (i = 0; i < num_attribs; i++) {
142 switch(attribs[i * 2]) {
143 case GLX_EVENT_MASK:
144 /* Keep a local copy for masking out DRI2 proto events as needed */
145 pdraw->eventMask = attribs[i * 2 + 1];
146 break;
147 }
148 }
Jon TURNEYae9487c2010-08-09 14:47:26 +0100149#endif
Nick Bowlerf8d81c32010-07-14 12:01:49 -0400150
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000151 return;
152}
153
154
Michel Dänzer236355102008-04-10 15:45:52 -0400155#ifdef GLX_DIRECT_RENDERING
Michel Dänzer236355102008-04-10 15:45:52 -0400156static GLenum
157determineTextureTarget(const int *attribs, int numAttribs)
158{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200159 GLenum target = 0;
160 int i;
Michel Dänzer236355102008-04-10 15:45:52 -0400161
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200162 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;
167 break;
168 case GLX_TEXTURE_RECTANGLE_EXT:
169 target = GL_TEXTURE_RECTANGLE_ARB;
170 break;
171 }
172 }
173 }
174
175 return target;
Michel Dänzer236355102008-04-10 15:45:52 -0400176}
Eric Anholt66175aa2009-03-18 12:07:09 -0700177
Eric Anholt66175aa2009-03-18 12:07:09 -0700178static GLenum
179determineTextureFormat(const int *attribs, int numAttribs)
180{
Eric Anholt66175aa2009-03-18 12:07:09 -0700181 int i;
182
183 for (i = 0; i < numAttribs; i++) {
184 if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200185 return attribs[2 * i + 1];
Eric Anholt66175aa2009-03-18 12:07:09 -0700186 }
187
188 return 0;
189}
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400190
Adam Jackson48331042011-03-31 20:43:57 +0000191static GLboolean
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400192CreateDRIDrawable(Display *dpy, struct glx_config *config,
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400193 XID drawable, XID glxdrawable,
194 const int *attrib_list, size_t num_attribs)
195{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400196 struct glx_display *const priv = __glXInitialize(dpy);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400197 __GLXDRIdrawable *pdraw;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400198 struct glx_screen *psc;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400199
Juha-Pekka Heikkilae5036092014-02-07 14:44:00 +0200200 if (priv == NULL) {
201 fprintf(stderr, "failed to create drawable\n");
202 return GL_FALSE;
203 }
204
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400205 psc = priv->screens[config->screen];
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400206 if (psc->driScreen == NULL)
Adam Jackson48331042011-03-31 20:43:57 +0000207 return GL_TRUE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400208
209 pdraw = psc->driScreen->createDrawable(psc, drawable,
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400210 glxdrawable, config);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400211 if (pdraw == NULL) {
212 fprintf(stderr, "failed to create drawable\n");
Adam Jackson48331042011-03-31 20:43:57 +0000213 return GL_FALSE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400214 }
215
Kristian Høgsberge3e81962010-07-19 21:15:50 -0400216 if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400217 (*pdraw->destroyDrawable) (pdraw);
Adam Jackson48331042011-03-31 20:43:57 +0000218 return GL_FALSE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400219 }
220
221 pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
222 pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);
Adam Jackson48331042011-03-31 20:43:57 +0000223
224 return GL_TRUE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400225}
226
227static void
228DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
229{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400230 struct glx_display *const priv = __glXInitialize(dpy);
Kristian Høgsbergeeaab202010-07-22 22:36:37 -0400231 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
Kristian Høgsberg80e48dd2010-09-09 08:06:40 -0400232 XID xid;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400233
Juha-Pekka Heikkilae5036092014-02-07 14:44:00 +0200234 if (priv != NULL && pdraw != NULL) {
Kristian Høgsberg80e48dd2010-09-09 08:06:40 -0400235 xid = pdraw->xDrawable;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400236 (*pdraw->destroyDrawable) (pdraw);
Kristian Høgsberge3e81962010-07-19 21:15:50 -0400237 __glxHashDelete(priv->drawHash, drawable);
Kristian Høgsbergd8ab9aa2010-09-08 20:55:02 -0400238 if (destroy_xdrawable)
Kristian Høgsberg80e48dd2010-09-09 08:06:40 -0400239 XFreePixmap(priv->dpy, xid);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400240 }
241}
242
243#else
244
Adam Jackson48331042011-03-31 20:43:57 +0000245static GLboolean
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400246CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig,
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400247 XID drawable, XID glxdrawable,
248 const int *attrib_list, size_t num_attribs)
249{
Jon TURNEYf816a9f2013-02-26 15:47:44 +0000250 return GL_TRUE;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400251}
252
253static void
254DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
255{
256}
257
Michel Dänzer236355102008-04-10 15:45:52 -0400258#endif
259
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000260/**
261 * Get a drawable's attribute.
262 *
263 * This function is used to implement \c glXGetSelectedEvent and
264 * \c glXGetSelectedEventSGIX.
265 *
266 * \note
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.
269 *
270 * \todo
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.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000274 */
275static int
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200276GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
277 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000278{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400279 struct glx_display *priv;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000280 xGLXGetDrawableAttributesReply reply;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200281 CARD32 *data;
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000282 CARD8 opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000283 unsigned int length;
284 unsigned int i;
285 unsigned int num_attributes;
Owain G. Ainsworthb4866f82009-01-11 20:40:07 +0000286 GLboolean use_glx_1_3;
Adam Jacksond25ad502006-04-07 00:05:50 +0000287
Adel Gadllaha69fabc2014-02-24 20:44:42 +0100288#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
289 __GLXDRIdrawable *pdraw;
290#endif
291
Ian Romanickd5aee172013-08-08 18:17:24 -0700292 if (dpy == NULL)
293 return 0;
294
295 /* Page 38 (page 52 of the PDF) of glxencode1.3.pdf says:
296 *
297 * "If drawable is not a valid GLX drawable, a GLXBadDrawable error is
298 * generated."
299 */
300 if (drawable == 0) {
301 __glXSendError(dpy, GLXBadDrawable, 0, X_GLXGetDrawableAttributes, false);
Adam Jacksond25ad502006-04-07 00:05:50 +0000302 return 0;
303 }
304
305 priv = __glXInitialize(dpy);
Juha-Pekka Heikkilae5036092014-02-07 14:44:00 +0200306 if (priv == NULL)
307 return 0;
308
Owain G. Ainsworthb4866f82009-01-11 20:40:07 +0000309 use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3));
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000310
Brian Paul42725d62006-02-07 00:39:56 +0000311 *value = 0;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000312
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000313
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000314 opcode = __glXSetupForCommand(dpy);
315 if (!opcode)
316 return 0;
317
Adel Gadllaha69fabc2014-02-24 20:44:42 +0100318#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
319 pdraw = GetGLXDRIDrawable(dpy, drawable);
320
321 if (attribute == GLX_BACK_BUFFER_AGE_EXT) {
Adel Gadllaha69fabc2014-02-24 20:44:42 +0100322 struct glx_context *gc = __glXGetCurrentContext();
Juha-Pekka Heikkila2670d0f2014-04-25 11:16:50 +0300323 struct glx_screen *psc;
Adel Gadllaha69fabc2014-02-24 20:44:42 +0100324
325 /* The GLX_EXT_buffer_age spec says:
326 *
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
329 * generated."
330 */
Juha-Pekka Heikkila2670d0f2014-04-25 11:16:50 +0300331 if (pdraw == NULL || gc == NULL || gc->currentDpy != dpy ||
332 (gc->currentDrawable != drawable &&
333 gc->currentReadable != drawable)) {
334 __glXSendError(dpy, GLXBadDrawable, drawable,
335 X_GLXGetDrawableAttributes, false);
Adel Gadllaha69fabc2014-02-24 20:44:42 +0100336 return 0;
337 }
338
Juha-Pekka Heikkila2670d0f2014-04-25 11:16:50 +0300339 psc = pdraw->psc;
340
Adel Gadllaha69fabc2014-02-24 20:44:42 +0100341 if (psc->driScreen->getBufferAge != NULL)
342 *value = psc->driScreen->getBufferAge(pdraw);
343
344 return 0;
345 }
346#endif
347
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000348 LockDisplay(dpy);
349
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200350 if (use_glx_1_3) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000351 xGLXGetDrawableAttributesReq *req;
352
Julien Cristau4324d6f2011-01-23 08:26:35 -0800353 GetReq(GLXGetDrawableAttributes, req);
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000354 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000355 req->glxCode = X_GLXGetDrawableAttributes;
356 req->drawable = drawable;
357 }
358 else {
359 xGLXVendorPrivateWithReplyReq *vpreq;
360
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200361 GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000362 data = (CARD32 *) (vpreq + 1);
363 data[0] = (CARD32) drawable;
364
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000365 vpreq->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000366 vpreq->glxCode = X_GLXVendorPrivateWithReply;
367 vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX;
368 }
369
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200370 _XReply(dpy, (xReply *) & reply, 0, False);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000371
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200372 if (reply.type == X_Error) {
373 UnlockDisplay(dpy);
374 SyncHandle();
375 return 0;
Brian Paul42725d62006-02-07 00:39:56 +0000376 }
377
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000378 length = reply.length;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200379 if (length) {
380 num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
Matt Turner2b7a9722012-09-03 19:44:00 -0700381 data = malloc(length * sizeof(CARD32));
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200382 if (data == NULL) {
383 /* Throw data on the floor */
384 _XEatData(dpy, length);
385 }
386 else {
387 _XRead(dpy, (char *) data, length * sizeof(CARD32));
Brian Paul42725d62006-02-07 00:39:56 +0000388
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200389 /* Search the set of returned attributes for the attribute requested by
390 * the caller.
391 */
392 for (i = 0; i < num_attributes; i++) {
393 if (data[i * 2] == attribute) {
394 *value = data[(i * 2) + 1];
395 break;
396 }
397 }
Brian Paul42725d62006-02-07 00:39:56 +0000398
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700399#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Adel Gadllahb972e552014-02-24 20:44:41 +0100400 if (pdraw != NULL) {
401 if (!pdraw->textureTarget)
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200402 pdraw->textureTarget =
403 determineTextureTarget((const int *) data, num_attributes);
Adel Gadllahb972e552014-02-24 20:44:41 +0100404 if (!pdraw->textureFormat)
Eric Anholt66175aa2009-03-18 12:07:09 -0700405 pdraw->textureFormat =
406 determineTextureFormat((const int *) data, num_attributes);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200407 }
Michel Dänzer236355102008-04-10 15:45:52 -0400408#endif
409
Matt Turner7c7b7b02012-09-04 22:52:36 -0700410 free(data);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200411 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000412 }
413
414 UnlockDisplay(dpy);
415 SyncHandle();
416
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000417 return 0;
418}
419
Adam Jackson48331042011-03-31 20:43:57 +0000420static void
421protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode)
422{
423 xGLXDestroyPbufferReq *req;
424 CARD8 opcode;
425
426 opcode = __glXSetupForCommand(dpy);
427 if (!opcode)
428 return;
429
430 LockDisplay(dpy);
431
432 GetReq(GLXDestroyPbuffer, req);
433 req->reqType = opcode;
434 req->glxCode = glxCode;
435 req->pbuffer = (GLXPbuffer) drawable;
436
437 UnlockDisplay(dpy);
438 SyncHandle();
439}
440
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000441/**
442 * Create a non-pbuffer GLX drawable.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000443 */
444static GLXDrawable
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400445CreateDrawable(Display *dpy, struct glx_config *config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200446 Drawable drawable, const int *attrib_list, CARD8 glxCode)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000447{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200448 xGLXCreateWindowReq *req;
Jesse Barnes4df13762011-05-06 10:31:24 -0700449 struct glx_drawable *glxDraw;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200450 CARD32 *data;
Ian Romanickb47731f2005-03-04 17:53:24 +0000451 unsigned int i;
David Reveman342d1de2006-04-11 12:07:41 +0000452 CARD8 opcode;
Adam Jacksona95ec182011-05-25 06:11:20 -0400453 GLXDrawable xid;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000454
Ian Romanickb47731f2005-03-04 17:53:24 +0000455 i = 0;
456 if (attrib_list) {
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200457 while (attrib_list[i * 2] != None)
458 i++;
Ian Romanickb47731f2005-03-04 17:53:24 +0000459 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000460
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000461 opcode = __glXSetupForCommand(dpy);
462 if (!opcode)
463 return None;
David Reveman342d1de2006-04-11 12:07:41 +0000464
Matt Turner7c7b7b02012-09-04 22:52:36 -0700465 glxDraw = malloc(sizeof(*glxDraw));
Jesse Barnes4df13762011-05-06 10:31:24 -0700466 if (!glxDraw)
467 return None;
468
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000469 LockDisplay(dpy);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200470 GetReqExtra(GLXCreateWindow, 8 * i, req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000471 data = (CARD32 *) (req + 1);
472
David Reveman342d1de2006-04-11 12:07:41 +0000473 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000474 req->glxCode = glxCode;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400475 req->screen = config->screen;
476 req->fbconfig = config->fbconfigID;
477 req->window = drawable;
Adam Jacksona95ec182011-05-25 06:11:20 -0400478 req->glxwindow = xid = XAllocID(dpy);
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400479 req->numAttribs = i;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000480
Brian Paul5f40a7a2010-03-02 07:34:29 -0700481 if (attrib_list)
482 memcpy(data, attrib_list, 8 * i);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200483
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000484 UnlockDisplay(dpy);
485 SyncHandle();
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200486
Jesse Barnes4df13762011-05-06 10:31:24 -0700487 if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) {
488 free(glxDraw);
489 return None;
490 }
491
Adam Jackson48331042011-03-31 20:43:57 +0000492 if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
493 if (glxCode == X_GLXCreatePixmap)
494 glxCode = X_GLXDestroyPixmap;
495 else
496 glxCode = X_GLXDestroyWindow;
497 protocolDestroyDrawable(dpy, xid, glxCode);
498 xid = None;
499 }
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400500
Adam Jacksona95ec182011-05-25 06:11:20 -0400501 return xid;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000502}
503
504
505/**
506 * Destroy a non-pbuffer GLX drawable.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000507 */
508static void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200509DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000510{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200511 if ((dpy == NULL) || (drawable == 0)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000512 return;
513 }
514
Adam Jackson48331042011-03-31 20:43:57 +0000515 protocolDestroyDrawable(dpy, drawable, glxCode);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000516
Jesse Barnes4df13762011-05-06 10:31:24 -0700517 DestroyGLXDrawable(dpy, drawable);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400518 DestroyDRIDrawable(dpy, drawable, GL_FALSE);
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400519
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000520 return;
521}
522
523
524/**
525 * Create a pbuffer.
526 *
527 * This function is used to implement \c glXCreatePbuffer and
528 * \c glXCreateGLXPbufferSGIX.
529 *
530 * \note
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.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000533 */
534static GLXDrawable
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400535CreatePbuffer(Display * dpy, struct glx_config *config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200536 unsigned int width, unsigned int height,
537 const int *attrib_list, GLboolean size_in_attribs)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000538{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400539 struct glx_display *priv = __glXInitialize(dpy);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000540 GLXDrawable id = 0;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200541 CARD32 *data;
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000542 CARD8 opcode;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200543 unsigned int i;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400544 Pixmap pixmap;
Adam Jackson48331042011-03-31 20:43:57 +0000545 GLboolean glx_1_3 = GL_FALSE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000546
Juha-Pekka Heikkilae5036092014-02-07 14:44:00 +0200547 if (priv == NULL)
548 return None;
549
Ian Romanickb47731f2005-03-04 17:53:24 +0000550 i = 0;
551 if (attrib_list) {
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200552 while (attrib_list[i * 2])
553 i++;
Ian Romanickb47731f2005-03-04 17:53:24 +0000554 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000555
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000556 opcode = __glXSetupForCommand(dpy);
557 if (!opcode)
558 return None;
559
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000560 LockDisplay(dpy);
561 id = XAllocID(dpy);
562
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200563 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
564 xGLXCreatePbufferReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000565 unsigned int extra = (size_in_attribs) ? 0 : 2;
566
Adam Jackson48331042011-03-31 20:43:57 +0000567 glx_1_3 = GL_TRUE;
568
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200569 GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000570 data = (CARD32 *) (req + 1);
571
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000572 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000573 req->glxCode = X_GLXCreatePbuffer;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400574 req->screen = config->screen;
575 req->fbconfig = config->fbconfigID;
576 req->pbuffer = id;
577 req->numAttribs = i + extra;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000578
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200579 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;
584 data += 4;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000585 }
586 }
587 else {
588 xGLXVendorPrivateReq *vpreq;
589
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200590 GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000591 data = (CARD32 *) (vpreq + 1);
592
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000593 vpreq->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000594 vpreq->glxCode = X_GLXVendorPrivate;
595 vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX;
596
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400597 data[0] = config->screen;
598 data[1] = config->fbconfigID;
599 data[2] = id;
600 data[3] = width;
601 data[4] = height;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000602 data += 5;
603 }
604
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200605 (void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000606
607 UnlockDisplay(dpy);
608 SyncHandle();
609
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400610 pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
611 width, height, config->rgbBits);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400612
Adam Jackson48331042011-03-31 20:43:57 +0000613 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);
617 id = None;
618 }
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400619
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000620 return id;
621}
622
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400623/**
624 * Destroy a pbuffer.
625 *
626 * This function is used to implement \c glXDestroyPbuffer and
627 * \c glXDestroyGLXPbufferSGIX.
628 *
629 * \note
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.
632 */
633static void
634DestroyPbuffer(Display * dpy, GLXDrawable drawable)
635{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400636 struct glx_display *priv = __glXInitialize(dpy);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400637 CARD8 opcode;
638
Juha-Pekka Heikkilae5036092014-02-07 14:44:00 +0200639 if ((priv == NULL) || (dpy == NULL) || (drawable == 0)) {
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400640 return;
641 }
642
643 opcode = __glXSetupForCommand(dpy);
644 if (!opcode)
645 return;
646
647 LockDisplay(dpy);
648
649 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
650 xGLXDestroyPbufferReq *req;
651
652 GetReq(GLXDestroyPbuffer, req);
653 req->reqType = opcode;
654 req->glxCode = X_GLXDestroyPbuffer;
655 req->pbuffer = (GLXPbuffer) drawable;
656 }
657 else {
658 xGLXVendorPrivateWithReplyReq *vpreq;
659 CARD32 *data;
660
661 GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
662 data = (CARD32 *) (vpreq + 1);
663
664 data[0] = (CARD32) drawable;
665
666 vpreq->reqType = opcode;
667 vpreq->glxCode = X_GLXVendorPrivateWithReply;
668 vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX;
669 }
670
671 UnlockDisplay(dpy);
672 SyncHandle();
673
674 DestroyDRIDrawable(dpy, drawable, GL_TRUE);
675
676 return;
677}
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000678
679/**
680 * Create a new pbuffer.
681 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400682_X_EXPORT GLXPbufferSGIX
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200683glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config,
684 unsigned int width, unsigned int height,
685 int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000686{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400687 return (GLXPbufferSGIX) CreatePbuffer(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200688 width, height,
689 attrib_list, GL_FALSE);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000690}
691
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700692#endif /* GLX_USE_APPLEGL */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000693
694/**
695 * Create a new pbuffer.
696 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400697_X_EXPORT GLXPbuffer
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200698glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000699{
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400700 int i, width, height;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700701#ifdef GLX_USE_APPLEGL
702 GLXPbuffer result;
703 int errorcode;
704#endif
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400705
706 width = 0;
707 height = 0;
708
Tormod Voldene8573032009-09-20 20:20:01 +0200709 WARN_ONCE_GLX_1_3(dpy, __func__);
Ian Romanick1f309c42009-09-15 13:12:22 -0700710
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700711#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];
716 ++i;
717 break;
718
719 case GLX_PBUFFER_HEIGHT:
720 height = attrib_list[i + 1];
721 ++i;
722 break;
723
724 case GLX_LARGEST_PBUFFER:
725 /* This is a hint we should probably handle, but how? */
726 ++i;
727 break;
728
729 case GLX_PRESERVED_CONTENTS:
730 /* The contents are always preserved with AppleSGLX with CGL. */
731 ++i;
732 break;
733
734 default:
735 return None;
736 }
737 }
738
739 if (apple_glx_pbuffer_create(dpy, config, width, height, &errorcode,
740 &result)) {
741 /*
742 * apple_glx_pbuffer_create only sets the errorcode to core X11
743 * errors.
744 */
745 __glXSendError(dpy, errorcode, 0, X_GLXCreatePbuffer, true);
746
747 return None;
748 }
749
750 return result;
751#else
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400752 for (i = 0; attrib_list[i * 2]; i++) {
753 switch (attrib_list[i * 2]) {
754 case GLX_PBUFFER_WIDTH:
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200755 width = attrib_list[i * 2 + 1];
756 break;
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400757 case GLX_PBUFFER_HEIGHT:
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200758 height = attrib_list[i * 2 + 1];
759 break;
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400760 }
761 }
762
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400763 return (GLXPbuffer) CreatePbuffer(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200764 width, height, attrib_list, GL_TRUE);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700765#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000766}
767
768
769/**
770 * Destroy an existing pbuffer.
771 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400772_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200773glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000774{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700775#ifdef GLX_USE_APPLEGL
776 if (apple_glx_pbuffer_destroy(dpy, pbuf)) {
777 __glXSendError(dpy, GLXBadPbuffer, pbuf, X_GLXDestroyPbuffer, false);
778 }
779#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200780 DestroyPbuffer(dpy, pbuf);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700781#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000782}
783
784
785/**
786 * Query an attribute of a drawable.
787 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400788_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200789glXQueryDrawable(Display * dpy, GLXDrawable drawable,
790 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000791{
Tormod Voldene8573032009-09-20 20:20:01 +0200792 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700793#ifdef GLX_USE_APPLEGL
794 Window root;
795 int x, y;
796 unsigned int width, height, bd, depth;
797
798 if (apple_glx_pixmap_query(drawable, attribute, value))
799 return; /*done */
800
801 if (apple_glx_pbuffer_query(drawable, attribute, value))
802 return; /*done */
803
804 /*
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.
814 */
815 if (XGetGeometry
816 (dpy, drawable, &root, &x, &y, &width, &height, &bd, &depth)) {
817 switch (attribute) {
818 case GLX_WIDTH:
819 *value = width;
820 break;
821
822 case GLX_HEIGHT:
823 *value = height;
824 break;
825 }
826 }
827#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200828 GetDrawableAttribute(dpy, drawable, attribute, value);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700829#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000830}
831
832
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700833#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000834/**
835 * Query an attribute of a pbuffer.
836 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400837_X_EXPORT int
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200838glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable,
839 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000840{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200841 return GetDrawableAttribute(dpy, drawable, attribute, value);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000842}
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700843#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000844
845/**
846 * Select the event mask for a drawable.
847 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400848_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200849glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000850{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700851#ifdef GLX_USE_APPLEGL
852 XWindowAttributes xwattr;
853
854 if (apple_glx_pbuffer_set_event_mask(drawable, mask))
855 return; /*done */
856
857 /*
858 * The spec allows a window, but currently there are no valid
859 * events for a window, so do nothing.
860 */
861 if (XGetWindowAttributes(dpy, drawable, &xwattr))
862 return; /*done */
863 /* The drawable seems to be invalid. Report an error. */
864
865 __glXSendError(dpy, GLXBadDrawable, drawable,
866 X_GLXChangeDrawableAttributes, false);
867#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000868 CARD32 attribs[2];
869
870 attribs[0] = (CARD32) GLX_EVENT_MASK;
871 attribs[1] = (CARD32) mask;
872
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200873 ChangeDrawableAttribute(dpy, drawable, attribs, 1);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700874#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000875}
876
877
878/**
879 * Get the selected event mask for a drawable.
880 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400881_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200882glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000883{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700884#ifdef GLX_USE_APPLEGL
885 XWindowAttributes xwattr;
886
887 if (apple_glx_pbuffer_get_event_mask(drawable, mask))
888 return; /*done */
889
890 /*
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.
893 */
894 if (XGetWindowAttributes(dpy, drawable, &xwattr)) {
895 /* The window is valid, so set the mask to 0. */
896 *mask = 0;
897 return; /*done */
898 }
899 /* The drawable seems to be invalid. Report an error. */
900
901 __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes,
902 true);
903#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000904 unsigned int value;
905
906
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?
910 */
911
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200912 GetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000913 *mask = value;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700914#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000915}
916
917
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400918_X_EXPORT GLXPixmap
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200919glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap,
920 const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000921{
Tormod Voldene8573032009-09-20 20:20:01 +0200922 WARN_ONCE_GLX_1_3(dpy, __func__);
Ian Romanick1f309c42009-09-15 13:12:22 -0700923
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700924#ifdef GLX_USE_APPLEGL
Jeremy Huddlestonbb621cb2011-06-05 17:02:33 -0400925 const struct glx_config *modes = (const struct glx_config *) config;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700926
927 if (apple_glx_pixmap_create(dpy, modes->screen, pixmap, modes))
928 return None;
929
930 return pixmap;
931#else
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400932 return CreateDrawable(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200933 (Drawable) pixmap, attrib_list, X_GLXCreatePixmap);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700934#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000935}
936
937
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400938_X_EXPORT GLXWindow
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200939glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
940 const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000941{
Tormod Voldene8573032009-09-20 20:20:01 +0200942 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700943#ifdef GLX_USE_APPLEGL
944 XWindowAttributes xwattr;
945 XVisualInfo *visinfo;
Ian Romanick1f309c42009-09-15 13:12:22 -0700946
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700947 (void) attrib_list; /*unused according to GLX 1.4 */
948
949 XGetWindowAttributes(dpy, win, &xwattr);
950
951 visinfo = glXGetVisualFromFBConfig(dpy, config);
952
953 if (NULL == visinfo) {
954 __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateWindow, false);
955 return None;
956 }
957
958 if (visinfo->visualid != XVisualIDFromVisual(xwattr.visual)) {
959 __glXSendError(dpy, BadMatch, 0, X_GLXCreateWindow, true);
960 return None;
961 }
962
Matt Turner7c7b7b02012-09-04 22:52:36 -0700963 free(visinfo);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700964
965 return win;
966#else
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400967 return CreateDrawable(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200968 (Drawable) win, attrib_list, X_GLXCreateWindow);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700969#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000970}
971
972
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400973_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200974glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000975{
Tormod Voldene8573032009-09-20 20:20:01 +0200976 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700977#ifdef GLX_USE_APPLEGL
978 if (apple_glx_pixmap_destroy(dpy, pixmap))
979 __glXSendError(dpy, GLXBadPixmap, pixmap, X_GLXDestroyPixmap, false);
980#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200981 DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700982#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000983}
984
985
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400986_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200987glXDestroyWindow(Display * dpy, GLXWindow win)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000988{
Tormod Voldene8573032009-09-20 20:20:01 +0200989 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700990#ifndef GLX_USE_APPLEGL
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200991 DestroyDrawable(dpy, (GLXDrawable) win, X_GLXDestroyWindow);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700992#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000993}
994
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700995#ifndef GLX_USE_APPLEGL
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400996_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200997GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
998 (Display * dpy, GLXPbufferSGIX pbuf),
999 (dpy, pbuf), glXDestroyPbuffer)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001000
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001001_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +02001002GLX_ALIAS_VOID(glXSelectEventSGIX,
1003 (Display * dpy, GLXDrawable drawable,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001004 unsigned long mask), (dpy, drawable, mask), glXSelectEvent)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001005
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001006_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +02001007GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
1008 (Display * dpy, GLXDrawable drawable,
1009 unsigned long *mask), (dpy, drawable, mask),
1010 glXGetSelectedEvent)
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001011#endif