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"
44 #define GLX_PREFIX(x) x
45 #endif /* IN_DOXYGEN */
47 static void ChangeDrawableAttribute( Display
* dpy
, GLXDrawable drawable
,
48 const CARD32
* attribs
, size_t num_attribs
);
50 static void DestroyPbuffer( Display
* dpy
, GLXDrawable drawable
);
52 static GLXDrawable
CreatePbuffer( Display
*dpy
,
53 const __GLcontextModes
* fbconfig
, unsigned int width
, unsigned int height
,
54 const int *attrib_list
, GLboolean size_in_attribs
);
56 static int GetDrawableAttribute( Display
*dpy
, GLXDrawable drawable
,
57 int attribute
, unsigned int *value
);
61 * Change a drawable's attribute.
63 * This function is used to implement \c glXSelectEvent and
64 * \c glXSelectEventSGIX.
67 * This function dynamically determines whether to use the SGIX_pbuffer
68 * version of the protocol or the GLX 1.3 version of the protocol.
71 * This function needs to be modified to work with direct-rendering drivers.
74 ChangeDrawableAttribute( Display
* dpy
, GLXDrawable drawable
,
75 const CARD32
* attribs
, size_t num_attribs
)
77 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
81 if ( (dpy
== NULL
) || (drawable
== 0) ) {
88 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
89 xGLXChangeDrawableAttributesReq
*req
;
91 GetReqExtra( GLXChangeDrawableAttributes
, 8 + (8 * num_attribs
), req
);
92 output
= (CARD32
*) (req
+ 1);
94 req
->reqType
= __glXSetupForCommand(dpy
);
95 req
->glxCode
= X_GLXChangeDrawableAttributes
;
96 req
->drawable
= drawable
;
97 req
->numAttribs
= (CARD32
) num_attribs
;
100 xGLXVendorPrivateWithReplyReq
*vpreq
;
102 GetReqExtra( GLXVendorPrivateWithReply
, 4 + (8 * num_attribs
), vpreq
);
103 output
= (CARD32
*) (vpreq
+ 1);
105 vpreq
->reqType
= __glXSetupForCommand(dpy
);
106 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
107 vpreq
->vendorCode
= X_GLXvop_ChangeDrawableAttributesSGIX
;
109 output
[0] = (CARD32
) drawable
;
113 (void) memcpy( output
, attribs
, sizeof( CARD32
) * 2 * num_attribs
);
125 * This function is used to implement \c glXDestroyPbuffer and
126 * \c glXDestroyGLXPbufferSGIX.
129 * This function dynamically determines whether to use the SGIX_pbuffer
130 * version of the protocol or the GLX 1.3 version of the protocol.
133 * This function needs to be modified to work with direct-rendering drivers.
136 DestroyPbuffer( Display
* dpy
, GLXDrawable drawable
)
138 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
140 if ( (dpy
== NULL
) || (drawable
== 0) ) {
147 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
148 xGLXDestroyPbufferReq
* req
;
150 GetReqExtra( GLXDestroyPbuffer
, 4, req
);
151 req
->reqType
= __glXSetupForCommand(dpy
);
152 req
->glxCode
= X_GLXDestroyPbuffer
;
153 req
->pbuffer
= (GLXPbuffer
) drawable
;
156 xGLXVendorPrivateWithReplyReq
*vpreq
;
159 GetReqExtra( GLXVendorPrivateWithReply
, 4, vpreq
);
160 data
= (CARD32
*) (vpreq
+ 1);
162 data
[0] = (CARD32
) drawable
;
164 vpreq
->reqType
= __glXSetupForCommand(dpy
);
165 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
166 vpreq
->vendorCode
= X_GLXvop_DestroyGLXPbufferSGIX
;
177 * Get a drawable's attribute.
179 * This function is used to implement \c glXGetSelectedEvent and
180 * \c glXGetSelectedEventSGIX.
183 * This function dynamically determines whether to use the SGIX_pbuffer
184 * version of the protocol or the GLX 1.3 version of the protocol.
187 * The number of attributes returned is likely to be small, probably less than
188 * 10. Given that, this routine should try to use an array on the stack to
189 * capture the reply rather than always calling Xmalloc.
192 * This function needs to be modified to work with direct-rendering drivers.
195 GetDrawableAttribute( Display
*dpy
, GLXDrawable drawable
,
196 int attribute
, unsigned int *value
)
198 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
199 xGLXGetDrawableAttributesReply reply
;
203 unsigned int num_attributes
;
204 GLboolean use_glx_1_3
= ((priv
->majorVersion
> 1)
205 || (priv
->minorVersion
>= 3));
208 if ( (dpy
== NULL
) || (drawable
== 0) ) {
216 xGLXGetDrawableAttributesReq
*req
;
218 GetReqExtra( GLXGetDrawableAttributes
, 4, req
);
219 req
->reqType
= __glXSetupForCommand(dpy
);
220 req
->glxCode
= X_GLXGetDrawableAttributes
;
221 req
->drawable
= drawable
;
224 xGLXVendorPrivateWithReplyReq
*vpreq
;
226 GetReqExtra( GLXVendorPrivateWithReply
, 4, vpreq
);
227 data
= (CARD32
*) (vpreq
+ 1);
228 data
[0] = (CARD32
) drawable
;
230 vpreq
->reqType
= __glXSetupForCommand(dpy
);
231 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
232 vpreq
->vendorCode
= X_GLXvop_GetDrawableAttributesSGIX
;
235 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
237 length
= reply
.length
;
238 num_attributes
= (use_glx_1_3
) ? reply
.numAttribs
: length
/ 2;
239 data
= (CARD32
*) Xmalloc( length
* sizeof(CARD32
) );
240 if ( data
== NULL
) {
241 /* Throw data on the floor */
242 _XEatData(dpy
, length
);
244 _XRead(dpy
, (char *)data
, length
* sizeof(CARD32
) );
251 /* Search the set of returned attributes for the attribute requested by
255 for ( i
= 0 ; i
< num_attributes
; i
++ ) {
256 if ( data
[i
*2] == attribute
) {
257 *value
= data
[ (i
*2) + 1 ];
269 * Create a non-pbuffer GLX drawable.
272 * This function needs to be modified to work with direct-rendering drivers.
275 CreateDrawable( Display
*dpy
, const __GLcontextModes
* fbconfig
,
276 Drawable drawable
, const int *attrib_list
,
279 xGLXCreateWindowReq
* req
;
284 for ( i
= 0 ; attrib_list
[i
* 2] != None
; i
++ )
288 GetReqExtra( GLXCreateWindow
, 20 + (8 * i
), req
);
289 data
= (CARD32
*) (req
+ 1);
291 req
->reqType
= __glXSetupForCommand(dpy
);
292 req
->glxCode
= glxCode
;
293 req
->screen
= (CARD32
) fbconfig
->screen
;
294 req
->fbconfig
= fbconfig
->fbconfigID
;
295 req
->window
= (GLXPbuffer
) drawable
;
296 req
->numAttribs
= (CARD32
) i
;
306 * Destroy a non-pbuffer GLX drawable.
309 * This function needs to be modified to work with direct-rendering drivers.
312 DestroyDrawable( Display
* dpy
, GLXDrawable drawable
, CARD32 glxCode
)
314 xGLXDestroyPbufferReq
* req
;
316 if ( (dpy
== NULL
) || (drawable
== 0) ) {
323 GetReqExtra( GLXDestroyPbuffer
, 4, req
);
324 req
->reqType
= __glXSetupForCommand(dpy
);
325 req
->glxCode
= glxCode
;
326 req
->pbuffer
= (GLXPbuffer
) drawable
;
338 * This function is used to implement \c glXCreatePbuffer and
339 * \c glXCreateGLXPbufferSGIX.
342 * This function dynamically determines whether to use the SGIX_pbuffer
343 * version of the protocol or the GLX 1.3 version of the protocol.
346 * This function needs to be modified to work with direct-rendering drivers.
349 CreatePbuffer( Display
*dpy
, const __GLcontextModes
* fbconfig
,
350 unsigned int width
, unsigned int height
,
351 const int *attrib_list
, GLboolean size_in_attribs
)
353 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
359 for ( i
= 0 ; attrib_list
[i
* 2] != None
; i
++ )
366 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
367 xGLXCreatePbufferReq
* req
;
368 unsigned int extra
= (size_in_attribs
) ? 0 : 2;
370 GetReqExtra( GLXCreatePbuffer
, (8 * (i
+ extra
)), req
);
371 data
= (CARD32
*) (req
+ 1);
373 req
->reqType
= __glXSetupForCommand(dpy
);
374 req
->glxCode
= X_GLXCreatePbuffer
;
375 req
->screen
= (CARD32
) fbconfig
->screen
;
376 req
->fbconfig
= fbconfig
->fbconfigID
;
377 req
->pbuffer
= (GLXPbuffer
) id
;
378 req
->numAttribs
= (CARD32
) (i
+ extra
);
380 if ( ! size_in_attribs
) {
381 data
[(2 * i
) + 0] = GLX_PBUFFER_WIDTH
;
382 data
[(2 * i
) + 1] = width
;
383 data
[(2 * i
) + 2] = GLX_PBUFFER_HEIGHT
;
384 data
[(2 * i
) + 3] = height
;
389 xGLXVendorPrivateReq
*vpreq
;
391 GetReqExtra( GLXVendorPrivate
, 20 + (8 * i
), vpreq
);
392 data
= (CARD32
*) (vpreq
+ 1);
394 vpreq
->reqType
= __glXSetupForCommand(dpy
);
395 vpreq
->glxCode
= X_GLXVendorPrivate
;
396 vpreq
->vendorCode
= X_GLXvop_CreateGLXPbufferSGIX
;
398 data
[0] = (CARD32
) fbconfig
->screen
;
399 data
[1] = (CARD32
) fbconfig
->fbconfigID
;
400 data
[2] = (CARD32
) id
;
401 data
[3] = (CARD32
) width
;
402 data
[4] = (CARD32
) height
;
406 (void) memcpy( data
, attrib_list
, sizeof(CARD32
) * 2 * i
);
416 * Create a new pbuffer.
418 PUBLIC GLXPbufferSGIX
419 GLX_PREFIX(glXCreateGLXPbufferSGIX
)(Display
*dpy
, GLXFBConfigSGIX config
,
420 unsigned int width
, unsigned int height
,
423 return (GLXPbufferSGIX
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
425 attrib_list
, GL_FALSE
);
430 * Create a new pbuffer.
433 GLX_PREFIX(glXCreatePbuffer
)(Display
*dpy
, GLXFBConfig config
,
434 const int *attrib_list
)
436 return (GLXPbuffer
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
438 attrib_list
, GL_TRUE
);
443 * Destroy an existing pbuffer.
446 GLX_PREFIX(glXDestroyPbuffer
)(Display
*dpy
, GLXPbuffer pbuf
)
448 DestroyPbuffer( dpy
, pbuf
);
453 * Query an attribute of a drawable.
456 GLX_PREFIX(glXQueryDrawable
)(Display
*dpy
, GLXDrawable drawable
,
457 int attribute
, unsigned int *value
)
459 GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
464 * Query an attribute of a pbuffer.
467 GLX_PREFIX(glXQueryGLXPbufferSGIX
)(Display
*dpy
, GLXPbufferSGIX drawable
,
468 int attribute
, unsigned int *value
)
470 return GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
475 * Select the event mask for a drawable.
478 GLX_PREFIX(glXSelectEvent
)(Display
*dpy
, GLXDrawable drawable
,
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 GLX_PREFIX(glXGetSelectedEvent
)(Display
*dpy
, GLXDrawable drawable
,
500 /* The non-sense with value is required because on LP64 platforms
501 * sizeof(unsigned int) != sizeof(unsigned long). On little-endian
502 * we could just type-cast the pointer, but why?
505 GetDrawableAttribute( dpy
, drawable
, GLX_EVENT_MASK_SGIX
, & value
);
511 GLX_PREFIX(glXCreatePixmap
)( Display
*dpy
, GLXFBConfig config
, Pixmap pixmap
,
512 const int *attrib_list
)
514 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
515 (Drawable
) pixmap
, attrib_list
,
521 GLX_PREFIX(glXCreateWindow
)( Display
*dpy
, GLXFBConfig config
, Window win
,
522 const int *attrib_list
)
524 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
525 (Drawable
) win
, attrib_list
,
531 GLX_PREFIX(glXDestroyPixmap
)(Display
*dpy
, GLXPixmap pixmap
)
533 DestroyDrawable( dpy
, (GLXDrawable
) pixmap
, X_GLXDestroyPixmap
);
538 GLX_PREFIX(glXDestroyWindow
)(Display
*dpy
, GLXWindow win
)
540 DestroyDrawable( dpy
, (GLXDrawable
) win
, X_GLXDestroyWindow
);
544 PUBLIC
GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX
,
545 (Display
*dpy
, GLXPbufferSGIX pbuf
),
549 PUBLIC
GLX_ALIAS_VOID(glXSelectEventSGIX
,
550 (Display
*dpy
, GLXDrawable drawable
, unsigned long mask
),
551 (dpy
, drawable
, mask
),
554 PUBLIC
GLX_ALIAS_VOID(glXGetSelectedEventSGIX
,
555 (Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
),
556 (dpy
, drawable
, mask
),