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"
39 #include "glxextensions.h"
40 #include "glcontextmodes.h"
43 #define GLX_PREFIX(x) x
44 #endif /* IN_DOXYGEN */
46 static void ChangeDrawableAttribute( Display
* dpy
, GLXDrawable drawable
,
47 const CARD32
* attribs
, size_t num_attribs
);
49 static void DestroyPbuffer( Display
* dpy
, GLXDrawable drawable
);
51 static GLXDrawable
CreatePbuffer( Display
*dpy
,
52 const __GLcontextModes
* fbconfig
, unsigned int width
, unsigned int height
,
53 const int *attrib_list
, GLboolean size_in_attribs
);
55 static int GetDrawableAttribute( Display
*dpy
, GLXDrawable drawable
,
56 int attribute
, unsigned int *value
);
60 * Change a drawable's attribute.
62 * This function is used to implement \c glXSelectEvent and
63 * \c glXSelectEventSGIX.
66 * This function dynamically determines whether to use the SGIX_pbuffer
67 * version of the protocol or the GLX 1.3 version of the protocol.
70 * This function needs to be modified to work with direct-rendering drivers.
73 ChangeDrawableAttribute( Display
* dpy
, GLXDrawable drawable
,
74 const CARD32
* attribs
, size_t num_attribs
)
76 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
80 if ( (dpy
== NULL
) || (drawable
== 0) ) {
87 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
88 xGLXChangeDrawableAttributesReq
*req
;
90 GetReqExtra( GLXChangeDrawableAttributes
, 8 + (8 * num_attribs
), req
);
91 output
= (CARD32
*) (req
+ 1);
93 req
->reqType
= __glXSetupForCommand(dpy
);
94 req
->glxCode
= X_GLXChangeDrawableAttributes
;
95 req
->drawable
= drawable
;
96 req
->numAttribs
= (CARD32
) num_attribs
;
99 xGLXVendorPrivateWithReplyReq
*vpreq
;
101 GetReqExtra( GLXVendorPrivateWithReply
, 4 + (8 * num_attribs
), vpreq
);
102 output
= (CARD32
*) (vpreq
+ 1);
104 vpreq
->reqType
= __glXSetupForCommand(dpy
);
105 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
106 vpreq
->vendorCode
= X_GLXvop_ChangeDrawableAttributesSGIX
;
108 output
[0] = (CARD32
) drawable
;
112 (void) memcpy( output
, attribs
, sizeof( CARD32
) * 2 * num_attribs
);
124 * This function is used to implement \c glXDestroyPbuffer and
125 * \c glXDestroyGLXPbufferSGIX.
128 * This function dynamically determines whether to use the SGIX_pbuffer
129 * version of the protocol or the GLX 1.3 version of the protocol.
132 * This function needs to be modified to work with direct-rendering drivers.
135 DestroyPbuffer( Display
* dpy
, GLXDrawable drawable
)
137 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
139 if ( (dpy
== NULL
) || (drawable
== 0) ) {
146 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
147 xGLXDestroyPbufferReq
* req
;
149 GetReqExtra( GLXDestroyPbuffer
, 4, req
);
150 req
->reqType
= __glXSetupForCommand(dpy
);
151 req
->glxCode
= X_GLXDestroyPbuffer
;
152 req
->pbuffer
= (GLXPbuffer
) drawable
;
155 xGLXVendorPrivateWithReplyReq
*vpreq
;
158 GetReqExtra( GLXVendorPrivateWithReply
, 4, vpreq
);
159 data
= (CARD32
*) (vpreq
+ 1);
161 data
[0] = (CARD32
) drawable
;
163 vpreq
->reqType
= __glXSetupForCommand(dpy
);
164 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
165 vpreq
->vendorCode
= X_GLXvop_DestroyGLXPbufferSGIX
;
176 * Get a drawable's attribute.
178 * This function is used to implement \c glXGetSelectedEvent and
179 * \c glXGetSelectedEventSGIX.
182 * This function dynamically determines whether to use the SGIX_pbuffer
183 * version of the protocol or the GLX 1.3 version of the protocol.
186 * The number of attributes returned is likely to be small, probably less than
187 * 10. Given that, this routine should try to use an array on the stack to
188 * capture the reply rather than always calling Xmalloc.
191 * This function needs to be modified to work with direct-rendering drivers.
194 GetDrawableAttribute( Display
*dpy
, GLXDrawable drawable
,
195 int attribute
, unsigned int *value
)
197 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
198 xGLXGetDrawableAttributesReply reply
;
202 unsigned int num_attributes
;
203 GLboolean use_glx_1_3
= ((priv
->majorVersion
> 1)
204 || (priv
->minorVersion
>= 3));
207 if ( (dpy
== NULL
) || (drawable
== 0) ) {
215 xGLXGetDrawableAttributesReq
*req
;
217 GetReqExtra( GLXGetDrawableAttributes
, 4, req
);
218 req
->reqType
= __glXSetupForCommand(dpy
);
219 req
->glxCode
= X_GLXGetDrawableAttributes
;
220 req
->drawable
= drawable
;
223 xGLXVendorPrivateWithReplyReq
*vpreq
;
225 GetReqExtra( GLXVendorPrivateWithReply
, 4, vpreq
);
226 data
= (CARD32
*) (vpreq
+ 1);
227 data
[0] = (CARD32
) drawable
;
229 vpreq
->reqType
= __glXSetupForCommand(dpy
);
230 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
231 vpreq
->vendorCode
= X_GLXvop_GetDrawableAttributesSGIX
;
234 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
236 length
= reply
.length
;
237 num_attributes
= (use_glx_1_3
) ? reply
.numAttribs
: length
/ 2;
238 data
= (CARD32
*) Xmalloc( length
* sizeof(CARD32
) );
239 if ( data
== NULL
) {
240 /* Throw data on the floor */
241 _XEatData(dpy
, length
);
243 _XRead(dpy
, (char *)data
, length
* sizeof(CARD32
) );
250 /* Search the set of returned attributes for the attribute requested by
254 for ( i
= 0 ; i
< num_attributes
; i
++ ) {
255 if ( data
[i
*2] == attribute
) {
256 *value
= data
[ (i
*2) + 1 ];
268 * Create a non-pbuffer GLX drawable.
271 * This function needs to be modified to work with direct-rendering drivers.
274 CreateDrawable( Display
*dpy
, const __GLcontextModes
* fbconfig
,
275 Drawable drawable
, const int *attrib_list
,
278 xGLXCreateWindowReq
* req
;
283 for ( i
= 0 ; attrib_list
[i
* 2] != None
; i
++ )
287 GetReqExtra( GLXCreateWindow
, 20 + (8 * i
), req
);
288 data
= (CARD32
*) (req
+ 1);
290 req
->reqType
= __glXSetupForCommand(dpy
);
291 req
->glxCode
= glxCode
;
292 req
->screen
= (CARD32
) fbconfig
->screen
;
293 req
->fbconfig
= fbconfig
->fbconfigID
;
294 req
->window
= (GLXPbuffer
) drawable
;
295 req
->numAttribs
= (CARD32
) i
;
305 * Destroy a non-pbuffer GLX drawable.
308 * This function needs to be modified to work with direct-rendering drivers.
311 DestroyDrawable( Display
* dpy
, GLXDrawable drawable
, CARD32 glxCode
)
313 xGLXDestroyPbufferReq
* req
;
315 if ( (dpy
== NULL
) || (drawable
== 0) ) {
322 GetReqExtra( GLXDestroyPbuffer
, 4, req
);
323 req
->reqType
= __glXSetupForCommand(dpy
);
324 req
->glxCode
= glxCode
;
325 req
->pbuffer
= (GLXPbuffer
) drawable
;
337 * This function is used to implement \c glXCreatePbuffer and
338 * \c glXCreateGLXPbufferSGIX.
341 * This function dynamically determines whether to use the SGIX_pbuffer
342 * version of the protocol or the GLX 1.3 version of the protocol.
345 * This function needs to be modified to work with direct-rendering drivers.
348 CreatePbuffer( Display
*dpy
, const __GLcontextModes
* fbconfig
,
349 unsigned int width
, unsigned int height
,
350 const int *attrib_list
, GLboolean size_in_attribs
)
352 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
358 for ( i
= 0 ; attrib_list
[i
* 2] != None
; i
++ )
365 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
366 xGLXCreatePbufferReq
* req
;
367 unsigned int extra
= (size_in_attribs
) ? 0 : 2;
369 GetReqExtra( GLXCreatePbuffer
, (8 * (i
+ extra
)), req
);
370 data
= (CARD32
*) (req
+ 1);
372 req
->reqType
= __glXSetupForCommand(dpy
);
373 req
->glxCode
= X_GLXCreatePbuffer
;
374 req
->screen
= (CARD32
) fbconfig
->screen
;
375 req
->fbconfig
= fbconfig
->fbconfigID
;
376 req
->pbuffer
= (GLXPbuffer
) id
;
377 req
->numAttribs
= (CARD32
) (i
+ extra
);
379 if ( ! size_in_attribs
) {
380 data
[(2 * i
) + 0] = GLX_PBUFFER_WIDTH
;
381 data
[(2 * i
) + 1] = width
;
382 data
[(2 * i
) + 2] = GLX_PBUFFER_HEIGHT
;
383 data
[(2 * i
) + 3] = height
;
388 xGLXVendorPrivateReq
*vpreq
;
390 GetReqExtra( GLXVendorPrivate
, 20 + (8 * i
), vpreq
);
391 data
= (CARD32
*) (vpreq
+ 1);
393 vpreq
->reqType
= __glXSetupForCommand(dpy
);
394 vpreq
->glxCode
= X_GLXVendorPrivate
;
395 vpreq
->vendorCode
= X_GLXvop_CreateGLXPbufferSGIX
;
397 data
[0] = (CARD32
) fbconfig
->screen
;
398 data
[1] = (CARD32
) fbconfig
->fbconfigID
;
399 data
[2] = (CARD32
) id
;
400 data
[3] = (CARD32
) width
;
401 data
[4] = (CARD32
) height
;
405 (void) memcpy( data
, attrib_list
, sizeof(CARD32
) * 2 * i
);
415 * Create a new pbuffer.
418 GLX_PREFIX(glXCreateGLXPbufferSGIX
)(Display
*dpy
, GLXFBConfigSGIX config
,
419 unsigned int width
, unsigned int height
,
422 return (GLXPbufferSGIX
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
424 attrib_list
, GL_FALSE
);
429 * Create a new pbuffer.
432 GLX_PREFIX(glXCreatePbuffer
)(Display
*dpy
, GLXFBConfig config
,
433 const int *attrib_list
)
435 return (GLXPbuffer
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
437 attrib_list
, GL_TRUE
);
442 * Destroy an existing pbuffer.
445 GLX_PREFIX(glXDestroyPbuffer
)(Display
*dpy
, GLXPbuffer pbuf
)
447 DestroyPbuffer( dpy
, pbuf
);
452 * Query an attribute of a drawable.
455 GLX_PREFIX(glXQueryDrawable
)(Display
*dpy
, GLXDrawable drawable
,
456 int attribute
, unsigned int *value
)
458 GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
463 * Query an attribute of a pbuffer.
466 GLX_PREFIX(glXQueryGLXPbufferSGIX
)(Display
*dpy
, GLXPbufferSGIX drawable
,
467 int attribute
, unsigned int *value
)
469 return GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
474 * Select the event mask for a drawable.
477 GLX_PREFIX(glXSelectEvent
)(Display
*dpy
, GLXDrawable drawable
,
482 attribs
[0] = (CARD32
) GLX_EVENT_MASK
;
483 attribs
[1] = (CARD32
) mask
;
485 ChangeDrawableAttribute( dpy
, drawable
, attribs
, 1 );
490 * Get the selected event mask for a drawable.
493 GLX_PREFIX(glXGetSelectedEvent
)(Display
*dpy
, GLXDrawable drawable
,
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 GLX_PREFIX(glXCreatePixmap
)( Display
*dpy
, GLXFBConfig config
, Pixmap pixmap
,
511 const int *attrib_list
)
513 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
514 (Drawable
) pixmap
, attrib_list
,
520 GLX_PREFIX(glXCreateWindow
)( Display
*dpy
, GLXFBConfig config
, Window win
,
521 const int *attrib_list
)
523 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
524 (Drawable
) win
, attrib_list
,
530 GLX_PREFIX(glXDestroyPixmap
)(Display
*dpy
, GLXPixmap pixmap
)
532 DestroyDrawable( dpy
, (GLXDrawable
) pixmap
, X_GLXDestroyPixmap
);
537 GLX_PREFIX(glXDestroyWindow
)(Display
*dpy
, GLXWindow win
)
539 DestroyDrawable( dpy
, (GLXDrawable
) win
, X_GLXDestroyWindow
);
543 GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX
,
544 (Display
*dpy
, GLXPbufferSGIX pbuf
),
548 GLX_ALIAS_VOID(glXSelectEventSGIX
,
549 (Display
*dpy
, GLXDrawable drawable
, unsigned long mask
),
550 (dpy
, drawable
, mask
),
553 GLX_ALIAS_VOID(glXGetSelectedEventSGIX
,
554 (Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
),
555 (dpy
, drawable
, mask
),