2 * (C) Copyright IBM Corporation 2004
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
27 * Implementation of pbuffer related functions.
29 * \author Ian Romanick <idr@us.ibm.com>
33 #include "glxclient.h"
34 #include <X11/extensions/extutil.h>
35 #include <X11/extensions/Xext.h>
39 #include "glxextensions.h"
40 #include "glcontextmodes.h"
43 static void ChangeDrawableAttribute( Display
* dpy
, GLXDrawable drawable
,
44 const CARD32
* attribs
, size_t num_attribs
);
46 static void DestroyPbuffer( Display
* dpy
, GLXDrawable drawable
);
48 static GLXDrawable
CreatePbuffer( Display
*dpy
,
49 const __GLcontextModes
* fbconfig
, unsigned int width
, unsigned int height
,
50 const int *attrib_list
, GLboolean size_in_attribs
);
52 static int GetDrawableAttribute( Display
*dpy
, GLXDrawable drawable
,
53 int attribute
, unsigned int *value
);
57 * Change a drawable's attribute.
59 * This function is used to implement \c glXSelectEvent and
60 * \c glXSelectEventSGIX.
63 * This function dynamically determines whether to use the SGIX_pbuffer
64 * version of the protocol or the GLX 1.3 version of the protocol.
67 * This function needs to be modified to work with direct-rendering drivers.
70 ChangeDrawableAttribute( Display
* dpy
, GLXDrawable drawable
,
71 const CARD32
* attribs
, size_t num_attribs
)
73 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
77 if ( (dpy
== NULL
) || (drawable
== 0) ) {
84 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
85 xGLXChangeDrawableAttributesReq
*req
;
87 GetReqExtra( GLXChangeDrawableAttributes
, 8 + (8 * num_attribs
), req
);
88 output
= (CARD32
*) (req
+ 1);
90 req
->reqType
= __glXSetupForCommand(dpy
);
91 req
->glxCode
= X_GLXChangeDrawableAttributes
;
92 req
->drawable
= drawable
;
93 req
->numAttribs
= (CARD32
) num_attribs
;
96 xGLXVendorPrivateWithReplyReq
*vpreq
;
98 GetReqExtra( GLXVendorPrivateWithReply
, 4 + (8 * num_attribs
), vpreq
);
99 output
= (CARD32
*) (vpreq
+ 1);
101 vpreq
->reqType
= __glXSetupForCommand(dpy
);
102 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
103 vpreq
->vendorCode
= X_GLXvop_ChangeDrawableAttributesSGIX
;
105 output
[0] = (CARD32
) drawable
;
109 (void) memcpy( output
, attribs
, sizeof( CARD32
) * 2 * num_attribs
);
121 * This function is used to implement \c glXDestroyPbuffer and
122 * \c glXDestroyGLXPbufferSGIX.
125 * This function dynamically determines whether to use the SGIX_pbuffer
126 * version of the protocol or the GLX 1.3 version of the protocol.
129 * This function needs to be modified to work with direct-rendering drivers.
132 DestroyPbuffer( Display
* dpy
, GLXDrawable drawable
)
134 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
136 if ( (dpy
== NULL
) || (drawable
== 0) ) {
143 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
144 xGLXDestroyPbufferReq
* req
;
146 GetReqExtra( GLXDestroyPbuffer
, 4, req
);
147 req
->reqType
= __glXSetupForCommand(dpy
);
148 req
->glxCode
= X_GLXDestroyPbuffer
;
149 req
->pbuffer
= (GLXPbuffer
) drawable
;
152 xGLXVendorPrivateWithReplyReq
*vpreq
;
155 GetReqExtra( GLXVendorPrivateWithReply
, 4, vpreq
);
156 data
= (CARD32
*) (vpreq
+ 1);
158 data
[0] = (CARD32
) drawable
;
160 vpreq
->reqType
= __glXSetupForCommand(dpy
);
161 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
162 vpreq
->vendorCode
= X_GLXvop_DestroyGLXPbufferSGIX
;
173 * Get a drawable's attribute.
175 * This function is used to implement \c glXGetSelectedEvent and
176 * \c glXGetSelectedEventSGIX.
179 * This function dynamically determines whether to use the SGIX_pbuffer
180 * version of the protocol or the GLX 1.3 version of the protocol.
183 * The number of attributes returned is likely to be small, probably less than
184 * 10. Given that, this routine should try to use an array on the stack to
185 * capture the reply rather than always calling Xmalloc.
188 * This function needs to be modified to work with direct-rendering drivers.
191 GetDrawableAttribute( Display
*dpy
, GLXDrawable drawable
,
192 int attribute
, unsigned int *value
)
194 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
195 xGLXGetDrawableAttributesReply reply
;
199 unsigned int num_attributes
;
200 GLboolean use_glx_1_3
= ((priv
->majorVersion
> 1)
201 || (priv
->minorVersion
>= 3));
204 if ( (dpy
== NULL
) || (drawable
== 0) ) {
212 xGLXGetDrawableAttributesReq
*req
;
214 GetReqExtra( GLXGetDrawableAttributes
, 4, req
);
215 req
->reqType
= __glXSetupForCommand(dpy
);
216 req
->glxCode
= X_GLXGetDrawableAttributes
;
217 req
->drawable
= drawable
;
220 xGLXVendorPrivateWithReplyReq
*vpreq
;
222 GetReqExtra( GLXVendorPrivateWithReply
, 4, vpreq
);
223 data
= (CARD32
*) (vpreq
+ 1);
224 data
[0] = (CARD32
) drawable
;
226 vpreq
->reqType
= __glXSetupForCommand(dpy
);
227 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
228 vpreq
->vendorCode
= X_GLXvop_GetDrawableAttributesSGIX
;
231 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
233 length
= reply
.length
;
234 num_attributes
= (use_glx_1_3
) ? reply
.numAttribs
: length
/ 2;
235 data
= (CARD32
*) Xmalloc( length
* sizeof(CARD32
) );
236 if ( data
== NULL
) {
237 /* Throw data on the floor */
238 _XEatData(dpy
, length
);
240 _XRead(dpy
, (char *)data
, length
* sizeof(CARD32
) );
247 /* Search the set of returned attributes for the attribute requested by
251 for ( i
= 0 ; i
< num_attributes
; i
++ ) {
252 if ( data
[i
*2] == attribute
) {
253 *value
= data
[ (i
*2) + 1 ];
265 * Create a non-pbuffer GLX drawable.
268 * This function needs to be modified to work with direct-rendering drivers.
271 CreateDrawable( Display
*dpy
, const __GLcontextModes
* fbconfig
,
272 Drawable drawable
, const int *attrib_list
,
275 xGLXCreateWindowReq
* req
;
281 while (attrib_list
[i
* 2] != None
)
286 GetReqExtra( GLXCreateWindow
, 8 * i
, req
);
287 data
= (CARD32
*) (req
+ 1);
289 req
->reqType
= __glXSetupForCommand(dpy
);
290 req
->glxCode
= glxCode
;
291 req
->screen
= (CARD32
) fbconfig
->screen
;
292 req
->fbconfig
= fbconfig
->fbconfigID
;
293 req
->window
= (GLXPbuffer
) drawable
;
294 req
->glxwindow
= (GLXWindow
) XAllocID(dpy
);
295 req
->numAttribs
= (CARD32
) i
;
297 memcpy( data
, attrib_list
, 8 * i
);
302 return (GLXDrawable
)req
->glxwindow
;
307 * Destroy a non-pbuffer GLX drawable.
310 * This function needs to be modified to work with direct-rendering drivers.
313 DestroyDrawable( Display
* dpy
, GLXDrawable drawable
, CARD32 glxCode
)
315 xGLXDestroyPbufferReq
* req
;
317 if ( (dpy
== NULL
) || (drawable
== 0) ) {
324 GetReqExtra( GLXDestroyPbuffer
, 4, req
);
325 req
->reqType
= __glXSetupForCommand(dpy
);
326 req
->glxCode
= glxCode
;
327 req
->pbuffer
= (GLXPbuffer
) drawable
;
339 * This function is used to implement \c glXCreatePbuffer and
340 * \c glXCreateGLXPbufferSGIX.
343 * This function dynamically determines whether to use the SGIX_pbuffer
344 * version of the protocol or the GLX 1.3 version of the protocol.
347 * This function needs to be modified to work with direct-rendering drivers.
350 CreatePbuffer( Display
*dpy
, const __GLcontextModes
* fbconfig
,
351 unsigned int width
, unsigned int height
,
352 const int *attrib_list
, GLboolean size_in_attribs
)
354 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
361 while (attrib_list
[i
* 2])
368 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
369 xGLXCreatePbufferReq
* req
;
370 unsigned int extra
= (size_in_attribs
) ? 0 : 2;
372 GetReqExtra( GLXCreatePbuffer
, (8 * (i
+ extra
)), req
);
373 data
= (CARD32
*) (req
+ 1);
375 req
->reqType
= __glXSetupForCommand(dpy
);
376 req
->glxCode
= X_GLXCreatePbuffer
;
377 req
->screen
= (CARD32
) fbconfig
->screen
;
378 req
->fbconfig
= fbconfig
->fbconfigID
;
379 req
->pbuffer
= (GLXPbuffer
) id
;
380 req
->numAttribs
= (CARD32
) (i
+ extra
);
382 if ( ! size_in_attribs
) {
383 data
[(2 * i
) + 0] = GLX_PBUFFER_WIDTH
;
384 data
[(2 * i
) + 1] = width
;
385 data
[(2 * i
) + 2] = GLX_PBUFFER_HEIGHT
;
386 data
[(2 * i
) + 3] = height
;
391 xGLXVendorPrivateReq
*vpreq
;
393 GetReqExtra( GLXVendorPrivate
, 20 + (8 * i
), vpreq
);
394 data
= (CARD32
*) (vpreq
+ 1);
396 vpreq
->reqType
= __glXSetupForCommand(dpy
);
397 vpreq
->glxCode
= X_GLXVendorPrivate
;
398 vpreq
->vendorCode
= X_GLXvop_CreateGLXPbufferSGIX
;
400 data
[0] = (CARD32
) fbconfig
->screen
;
401 data
[1] = (CARD32
) fbconfig
->fbconfigID
;
402 data
[2] = (CARD32
) id
;
403 data
[3] = (CARD32
) width
;
404 data
[4] = (CARD32
) height
;
408 (void) memcpy( data
, attrib_list
, sizeof(CARD32
) * 2 * i
);
418 * Create a new pbuffer.
420 PUBLIC GLXPbufferSGIX
421 glXCreateGLXPbufferSGIX(Display
*dpy
, GLXFBConfigSGIX config
,
422 unsigned int width
, unsigned int height
,
425 return (GLXPbufferSGIX
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
427 attrib_list
, GL_FALSE
);
432 * Create a new pbuffer.
435 glXCreatePbuffer(Display
*dpy
, GLXFBConfig config
, const int *attrib_list
)
437 return (GLXPbuffer
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
439 attrib_list
, GL_TRUE
);
444 * Destroy an existing pbuffer.
447 glXDestroyPbuffer(Display
*dpy
, GLXPbuffer pbuf
)
449 DestroyPbuffer( dpy
, pbuf
);
454 * Query an attribute of a drawable.
457 glXQueryDrawable(Display
*dpy
, GLXDrawable drawable
,
458 int attribute
, unsigned int *value
)
460 GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
465 * Query an attribute of a pbuffer.
468 glXQueryGLXPbufferSGIX(Display
*dpy
, GLXPbufferSGIX drawable
,
469 int attribute
, unsigned int *value
)
471 return GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
476 * Select the event mask for a drawable.
479 glXSelectEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long mask
)
483 attribs
[0] = (CARD32
) GLX_EVENT_MASK
;
484 attribs
[1] = (CARD32
) mask
;
486 ChangeDrawableAttribute( dpy
, drawable
, attribs
, 1 );
491 * Get the selected event mask for a drawable.
494 glXGetSelectedEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
)
499 /* The non-sense with value is required because on LP64 platforms
500 * sizeof(unsigned int) != sizeof(unsigned long). On little-endian
501 * we could just type-cast the pointer, but why?
504 GetDrawableAttribute( dpy
, drawable
, GLX_EVENT_MASK_SGIX
, & value
);
510 glXCreatePixmap( Display
*dpy
, GLXFBConfig config
, Pixmap pixmap
,
511 const int *attrib_list
)
513 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
514 (Drawable
) pixmap
, attrib_list
,
520 glXCreateWindow( Display
*dpy
, GLXFBConfig config
, Window win
,
521 const int *attrib_list
)
523 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
524 (Drawable
) win
, attrib_list
,
530 glXDestroyPixmap(Display
*dpy
, GLXPixmap pixmap
)
532 DestroyDrawable( dpy
, (GLXDrawable
) pixmap
, X_GLXDestroyPixmap
);
537 glXDestroyWindow(Display
*dpy
, GLXWindow win
)
539 DestroyDrawable( dpy
, (GLXDrawable
) win
, X_GLXDestroyWindow
);
543 PUBLIC
GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX
,
544 (Display
*dpy
, GLXPbufferSGIX pbuf
),
548 PUBLIC
GLX_ALIAS_VOID(glXSelectEventSGIX
,
549 (Display
*dpy
, GLXDrawable drawable
, unsigned long mask
),
550 (dpy
, drawable
, mask
),
553 PUBLIC
GLX_ALIAS_VOID(glXGetSelectedEventSGIX
,
554 (Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
),
555 (dpy
, drawable
, mask
),