blob: 0e74e7ccd0e92fe4c773f26259c89eb2b8cd0756 [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{
Adam Jackson48331042011-03-31 20:43:57 +0000244 return GL_FALSE;
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;
329 data = (CARD32 *) Xmalloc(length * sizeof(CARD32));
330 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
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200360 Xfree(data);
361 }
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;
399 CARD32 *data;
Ian Romanickb47731f2005-03-04 17:53:24 +0000400 unsigned int i;
David Reveman342d1de2006-04-11 12:07:41 +0000401 CARD8 opcode;
Adam Jacksona95ec182011-05-25 06:11:20 -0400402 GLXDrawable xid;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000403
Ian Romanickb47731f2005-03-04 17:53:24 +0000404 i = 0;
405 if (attrib_list) {
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200406 while (attrib_list[i * 2] != None)
407 i++;
Ian Romanickb47731f2005-03-04 17:53:24 +0000408 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000409
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000410 opcode = __glXSetupForCommand(dpy);
411 if (!opcode)
412 return None;
David Reveman342d1de2006-04-11 12:07:41 +0000413
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000414 LockDisplay(dpy);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200415 GetReqExtra(GLXCreateWindow, 8 * i, req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000416 data = (CARD32 *) (req + 1);
417
David Reveman342d1de2006-04-11 12:07:41 +0000418 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000419 req->glxCode = glxCode;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400420 req->screen = config->screen;
421 req->fbconfig = config->fbconfigID;
422 req->window = drawable;
Adam Jacksona95ec182011-05-25 06:11:20 -0400423 req->glxwindow = xid = XAllocID(dpy);
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400424 req->numAttribs = i;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000425
Brian Paul5f40a7a2010-03-02 07:34:29 -0700426 if (attrib_list)
427 memcpy(data, attrib_list, 8 * i);
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200428
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000429 UnlockDisplay(dpy);
430 SyncHandle();
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200431
Adam Jackson48331042011-03-31 20:43:57 +0000432 if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
433 if (glxCode == X_GLXCreatePixmap)
434 glxCode = X_GLXDestroyPixmap;
435 else
436 glxCode = X_GLXDestroyWindow;
437 protocolDestroyDrawable(dpy, xid, glxCode);
438 xid = None;
439 }
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400440
Adam Jacksona95ec182011-05-25 06:11:20 -0400441 return xid;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000442}
443
444
445/**
446 * Destroy a non-pbuffer GLX drawable.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000447 */
448static void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200449DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000450{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200451 if ((dpy == NULL) || (drawable == 0)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000452 return;
453 }
454
Adam Jackson48331042011-03-31 20:43:57 +0000455 protocolDestroyDrawable(dpy, drawable, glxCode);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000456
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400457 DestroyDRIDrawable(dpy, drawable, GL_FALSE);
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400458
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000459 return;
460}
461
462
463/**
464 * Create a pbuffer.
465 *
466 * This function is used to implement \c glXCreatePbuffer and
467 * \c glXCreateGLXPbufferSGIX.
468 *
469 * \note
470 * This function dynamically determines whether to use the SGIX_pbuffer
471 * version of the protocol or the GLX 1.3 version of the protocol.
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000472 */
473static GLXDrawable
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400474CreatePbuffer(Display * dpy, struct glx_config *config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200475 unsigned int width, unsigned int height,
476 const int *attrib_list, GLboolean size_in_attribs)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000477{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400478 struct glx_display *priv = __glXInitialize(dpy);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000479 GLXDrawable id = 0;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200480 CARD32 *data;
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000481 CARD8 opcode;
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200482 unsigned int i;
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400483 Pixmap pixmap;
Adam Jackson48331042011-03-31 20:43:57 +0000484 GLboolean glx_1_3 = GL_FALSE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000485
Ian Romanickb47731f2005-03-04 17:53:24 +0000486 i = 0;
487 if (attrib_list) {
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200488 while (attrib_list[i * 2])
489 i++;
Ian Romanickb47731f2005-03-04 17:53:24 +0000490 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000491
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000492 opcode = __glXSetupForCommand(dpy);
493 if (!opcode)
494 return None;
495
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000496 LockDisplay(dpy);
497 id = XAllocID(dpy);
498
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200499 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
500 xGLXCreatePbufferReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000501 unsigned int extra = (size_in_attribs) ? 0 : 2;
502
Adam Jackson48331042011-03-31 20:43:57 +0000503 glx_1_3 = GL_TRUE;
504
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200505 GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000506 data = (CARD32 *) (req + 1);
507
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000508 req->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000509 req->glxCode = X_GLXCreatePbuffer;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400510 req->screen = config->screen;
511 req->fbconfig = config->fbconfigID;
512 req->pbuffer = id;
513 req->numAttribs = i + extra;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000514
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200515 if (!size_in_attribs) {
516 data[(2 * i) + 0] = GLX_PBUFFER_WIDTH;
517 data[(2 * i) + 1] = width;
518 data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT;
519 data[(2 * i) + 3] = height;
520 data += 4;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000521 }
522 }
523 else {
524 xGLXVendorPrivateReq *vpreq;
525
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200526 GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000527 data = (CARD32 *) (vpreq + 1);
528
Kristian Høgsbergc25eb992006-06-13 01:41:18 +0000529 vpreq->reqType = opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000530 vpreq->glxCode = X_GLXVendorPrivate;
531 vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX;
532
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400533 data[0] = config->screen;
534 data[1] = config->fbconfigID;
535 data[2] = id;
536 data[3] = width;
537 data[4] = height;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000538 data += 5;
539 }
540
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200541 (void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000542
543 UnlockDisplay(dpy);
544 SyncHandle();
545
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400546 pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
547 width, height, config->rgbBits);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400548
Adam Jackson48331042011-03-31 20:43:57 +0000549 if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) {
550 CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX;
551 XFreePixmap(dpy, pixmap);
552 protocolDestroyDrawable(dpy, id, o);
553 id = None;
554 }
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400555
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000556 return id;
557}
558
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400559/**
560 * Destroy a pbuffer.
561 *
562 * This function is used to implement \c glXDestroyPbuffer and
563 * \c glXDestroyGLXPbufferSGIX.
564 *
565 * \note
566 * This function dynamically determines whether to use the SGIX_pbuffer
567 * version of the protocol or the GLX 1.3 version of the protocol.
568 */
569static void
570DestroyPbuffer(Display * dpy, GLXDrawable drawable)
571{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400572 struct glx_display *priv = __glXInitialize(dpy);
Kristian Høgsberg5a43dba2010-04-09 17:16:33 -0400573 CARD8 opcode;
574
575 if ((dpy == NULL) || (drawable == 0)) {
576 return;
577 }
578
579 opcode = __glXSetupForCommand(dpy);
580 if (!opcode)
581 return;
582
583 LockDisplay(dpy);
584
585 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
586 xGLXDestroyPbufferReq *req;
587
588 GetReq(GLXDestroyPbuffer, req);
589 req->reqType = opcode;
590 req->glxCode = X_GLXDestroyPbuffer;
591 req->pbuffer = (GLXPbuffer) drawable;
592 }
593 else {
594 xGLXVendorPrivateWithReplyReq *vpreq;
595 CARD32 *data;
596
597 GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
598 data = (CARD32 *) (vpreq + 1);
599
600 data[0] = (CARD32) drawable;
601
602 vpreq->reqType = opcode;
603 vpreq->glxCode = X_GLXVendorPrivateWithReply;
604 vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX;
605 }
606
607 UnlockDisplay(dpy);
608 SyncHandle();
609
610 DestroyDRIDrawable(dpy, drawable, GL_TRUE);
611
612 return;
613}
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000614
615/**
616 * Create a new pbuffer.
617 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400618_X_EXPORT GLXPbufferSGIX
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200619glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config,
620 unsigned int width, unsigned int height,
621 int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000622{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400623 return (GLXPbufferSGIX) CreatePbuffer(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200624 width, height,
625 attrib_list, GL_FALSE);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000626}
627
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700628#endif /* GLX_USE_APPLEGL */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000629
630/**
631 * Create a new pbuffer.
632 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400633_X_EXPORT GLXPbuffer
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200634glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000635{
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400636 int i, width, height;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700637#ifdef GLX_USE_APPLEGL
638 GLXPbuffer result;
639 int errorcode;
640#endif
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400641
642 width = 0;
643 height = 0;
644
Tormod Voldene8573032009-09-20 20:20:01 +0200645 WARN_ONCE_GLX_1_3(dpy, __func__);
Ian Romanick1f309c42009-09-15 13:12:22 -0700646
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700647#ifdef GLX_USE_APPLEGL
648 for (i = 0; attrib_list[i]; ++i) {
649 switch (attrib_list[i]) {
650 case GLX_PBUFFER_WIDTH:
651 width = attrib_list[i + 1];
652 ++i;
653 break;
654
655 case GLX_PBUFFER_HEIGHT:
656 height = attrib_list[i + 1];
657 ++i;
658 break;
659
660 case GLX_LARGEST_PBUFFER:
661 /* This is a hint we should probably handle, but how? */
662 ++i;
663 break;
664
665 case GLX_PRESERVED_CONTENTS:
666 /* The contents are always preserved with AppleSGLX with CGL. */
667 ++i;
668 break;
669
670 default:
671 return None;
672 }
673 }
674
675 if (apple_glx_pbuffer_create(dpy, config, width, height, &errorcode,
676 &result)) {
677 /*
678 * apple_glx_pbuffer_create only sets the errorcode to core X11
679 * errors.
680 */
681 __glXSendError(dpy, errorcode, 0, X_GLXCreatePbuffer, true);
682
683 return None;
684 }
685
686 return result;
687#else
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400688 for (i = 0; attrib_list[i * 2]; i++) {
689 switch (attrib_list[i * 2]) {
690 case GLX_PBUFFER_WIDTH:
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200691 width = attrib_list[i * 2 + 1];
692 break;
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400693 case GLX_PBUFFER_HEIGHT:
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200694 height = attrib_list[i * 2 + 1];
695 break;
Kristian Høgsberg8b204112007-08-27 14:16:30 -0400696 }
697 }
698
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400699 return (GLXPbuffer) CreatePbuffer(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200700 width, height, attrib_list, GL_TRUE);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700701#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000702}
703
704
705/**
706 * Destroy an existing pbuffer.
707 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400708_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200709glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000710{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700711#ifdef GLX_USE_APPLEGL
712 if (apple_glx_pbuffer_destroy(dpy, pbuf)) {
713 __glXSendError(dpy, GLXBadPbuffer, pbuf, X_GLXDestroyPbuffer, false);
714 }
715#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200716 DestroyPbuffer(dpy, pbuf);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700717#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000718}
719
720
721/**
722 * Query an attribute of a drawable.
723 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400724_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200725glXQueryDrawable(Display * dpy, GLXDrawable drawable,
726 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000727{
Tormod Voldene8573032009-09-20 20:20:01 +0200728 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700729#ifdef GLX_USE_APPLEGL
730 Window root;
731 int x, y;
732 unsigned int width, height, bd, depth;
733
734 if (apple_glx_pixmap_query(drawable, attribute, value))
735 return; /*done */
736
737 if (apple_glx_pbuffer_query(drawable, attribute, value))
738 return; /*done */
739
740 /*
741 * The OpenGL spec states that we should report GLXBadDrawable if
742 * the drawable is invalid, however doing so would require that we
743 * use XSetErrorHandler(), which is known to not be thread safe.
744 * If we use a round-trip call to validate the drawable, there could
745 * be a race, so instead we just opt in favor of letting the
746 * XGetGeometry request fail with a GetGeometry request X error
747 * rather than GLXBadDrawable, in what is hoped to be a rare
748 * case of an invalid drawable. In practice most and possibly all
749 * X11 apps using GLX shouldn't notice a difference.
750 */
751 if (XGetGeometry
752 (dpy, drawable, &root, &x, &y, &width, &height, &bd, &depth)) {
753 switch (attribute) {
754 case GLX_WIDTH:
755 *value = width;
756 break;
757
758 case GLX_HEIGHT:
759 *value = height;
760 break;
761 }
762 }
763#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200764 GetDrawableAttribute(dpy, drawable, attribute, value);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700765#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000766}
767
768
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700769#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000770/**
771 * Query an attribute of a pbuffer.
772 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400773_X_EXPORT int
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200774glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable,
775 int attribute, unsigned int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000776{
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200777 return GetDrawableAttribute(dpy, drawable, attribute, value);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000778}
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700779#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000780
781/**
782 * Select the event mask for a drawable.
783 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400784_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200785glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000786{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700787#ifdef GLX_USE_APPLEGL
788 XWindowAttributes xwattr;
789
790 if (apple_glx_pbuffer_set_event_mask(drawable, mask))
791 return; /*done */
792
793 /*
794 * The spec allows a window, but currently there are no valid
795 * events for a window, so do nothing.
796 */
797 if (XGetWindowAttributes(dpy, drawable, &xwattr))
798 return; /*done */
799 /* The drawable seems to be invalid. Report an error. */
800
801 __glXSendError(dpy, GLXBadDrawable, drawable,
802 X_GLXChangeDrawableAttributes, false);
803#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000804 CARD32 attribs[2];
805
806 attribs[0] = (CARD32) GLX_EVENT_MASK;
807 attribs[1] = (CARD32) mask;
808
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200809 ChangeDrawableAttribute(dpy, drawable, attribs, 1);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700810#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000811}
812
813
814/**
815 * Get the selected event mask for a drawable.
816 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400817_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200818glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000819{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700820#ifdef GLX_USE_APPLEGL
821 XWindowAttributes xwattr;
822
823 if (apple_glx_pbuffer_get_event_mask(drawable, mask))
824 return; /*done */
825
826 /*
827 * The spec allows a window, but currently there are no valid
828 * events for a window, so do nothing, but set the mask to 0.
829 */
830 if (XGetWindowAttributes(dpy, drawable, &xwattr)) {
831 /* The window is valid, so set the mask to 0. */
832 *mask = 0;
833 return; /*done */
834 }
835 /* The drawable seems to be invalid. Report an error. */
836
837 __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes,
838 true);
839#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000840 unsigned int value;
841
842
843 /* The non-sense with value is required because on LP64 platforms
844 * sizeof(unsigned int) != sizeof(unsigned long). On little-endian
845 * we could just type-cast the pointer, but why?
846 */
847
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200848 GetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000849 *mask = value;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700850#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000851}
852
853
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400854_X_EXPORT GLXPixmap
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200855glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap,
856 const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000857{
Tormod Voldene8573032009-09-20 20:20:01 +0200858 WARN_ONCE_GLX_1_3(dpy, __func__);
Ian Romanick1f309c42009-09-15 13:12:22 -0700859
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700860#ifdef GLX_USE_APPLEGL
Jeremy Huddlestonbb621cb2011-06-05 17:02:33 -0400861 const struct glx_config *modes = (const struct glx_config *) config;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700862
863 if (apple_glx_pixmap_create(dpy, modes->screen, pixmap, modes))
864 return None;
865
866 return pixmap;
867#else
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400868 return CreateDrawable(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200869 (Drawable) pixmap, attrib_list, X_GLXCreatePixmap);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700870#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000871}
872
873
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400874_X_EXPORT GLXWindow
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200875glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
876 const int *attrib_list)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000877{
Tormod Voldene8573032009-09-20 20:20:01 +0200878 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700879#ifdef GLX_USE_APPLEGL
880 XWindowAttributes xwattr;
881 XVisualInfo *visinfo;
Ian Romanick1f309c42009-09-15 13:12:22 -0700882
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700883 (void) attrib_list; /*unused according to GLX 1.4 */
884
885 XGetWindowAttributes(dpy, win, &xwattr);
886
887 visinfo = glXGetVisualFromFBConfig(dpy, config);
888
889 if (NULL == visinfo) {
890 __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateWindow, false);
891 return None;
892 }
893
894 if (visinfo->visualid != XVisualIDFromVisual(xwattr.visual)) {
895 __glXSendError(dpy, BadMatch, 0, X_GLXCreateWindow, true);
896 return None;
897 }
898
899 XFree(visinfo);
900
901 return win;
902#else
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400903 return CreateDrawable(dpy, (struct glx_config *) config,
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200904 (Drawable) win, attrib_list, X_GLXCreateWindow);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700905#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000906}
907
908
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400909_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200910glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000911{
Tormod Voldene8573032009-09-20 20:20:01 +0200912 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700913#ifdef GLX_USE_APPLEGL
914 if (apple_glx_pixmap_destroy(dpy, pixmap))
915 __glXSendError(dpy, GLXBadPixmap, pixmap, X_GLXDestroyPixmap, false);
916#else
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200917 DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700918#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000919}
920
921
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400922_X_EXPORT void
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200923glXDestroyWindow(Display * dpy, GLXWindow win)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000924{
Tormod Voldene8573032009-09-20 20:20:01 +0200925 WARN_ONCE_GLX_1_3(dpy, __func__);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700926#ifndef GLX_USE_APPLEGL
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200927 DestroyDrawable(dpy, (GLXDrawable) win, X_GLXDestroyWindow);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700928#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000929}
930
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700931#ifndef GLX_USE_APPLEGL
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400932_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200933GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
934 (Display * dpy, GLXPbufferSGIX pbuf),
935 (dpy, pbuf), glXDestroyPbuffer)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000936
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400937_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200938GLX_ALIAS_VOID(glXSelectEventSGIX,
939 (Display * dpy, GLXDrawable drawable,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200940 unsigned long mask), (dpy, drawable, mask), glXSelectEvent)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000941
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400942_X_EXPORT
RALOVICH, Kristóf2d4c26b2008-10-13 14:12:02 +0200943GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
944 (Display * dpy, GLXDrawable drawable,
945 unsigned long *mask), (dpy, drawable, mask),
946 glXGetSelectedEvent)
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700947#endif