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"
45 * Change a drawable's attribute.
47 * This function is used to implement \c glXSelectEvent and
48 * \c glXSelectEventSGIX.
51 * This function dynamically determines whether to use the SGIX_pbuffer
52 * version of the protocol or the GLX 1.3 version of the protocol.
55 * This function needs to be modified to work with direct-rendering drivers.
58 ChangeDrawableAttribute( Display
* dpy
, GLXDrawable drawable
,
59 const CARD32
* attribs
, size_t num_attribs
)
61 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
65 if ( (dpy
== NULL
) || (drawable
== 0) ) {
69 opcode
= __glXSetupForCommand(dpy
);
75 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
76 xGLXChangeDrawableAttributesReq
*req
;
78 GetReqExtra( GLXChangeDrawableAttributes
, 8 + (8 * num_attribs
), req
);
79 output
= (CARD32
*) (req
+ 1);
81 req
->reqType
= opcode
;
82 req
->glxCode
= X_GLXChangeDrawableAttributes
;
83 req
->drawable
= drawable
;
84 req
->numAttribs
= (CARD32
) num_attribs
;
87 xGLXVendorPrivateWithReplyReq
*vpreq
;
89 GetReqExtra( GLXVendorPrivateWithReply
, 4 + (8 * num_attribs
), vpreq
);
90 output
= (CARD32
*) (vpreq
+ 1);
92 vpreq
->reqType
= opcode
;
93 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
94 vpreq
->vendorCode
= X_GLXvop_ChangeDrawableAttributesSGIX
;
96 output
[0] = (CARD32
) drawable
;
100 (void) memcpy( output
, attribs
, sizeof( CARD32
) * 2 * num_attribs
);
112 * This function is used to implement \c glXDestroyPbuffer and
113 * \c glXDestroyGLXPbufferSGIX.
116 * This function dynamically determines whether to use the SGIX_pbuffer
117 * version of the protocol or the GLX 1.3 version of the protocol.
120 * This function needs to be modified to work with direct-rendering drivers.
123 DestroyPbuffer( Display
* dpy
, GLXDrawable drawable
)
125 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
128 if ( (dpy
== NULL
) || (drawable
== 0) ) {
132 opcode
= __glXSetupForCommand(dpy
);
138 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
139 xGLXDestroyPbufferReq
* req
;
141 GetReq( GLXDestroyPbuffer
, req
);
142 req
->reqType
= opcode
;
143 req
->glxCode
= X_GLXDestroyPbuffer
;
144 req
->pbuffer
= (GLXPbuffer
) drawable
;
147 xGLXVendorPrivateWithReplyReq
*vpreq
;
150 GetReqExtra( GLXVendorPrivateWithReply
, 4, vpreq
);
151 data
= (CARD32
*) (vpreq
+ 1);
153 data
[0] = (CARD32
) drawable
;
155 vpreq
->reqType
= opcode
;
156 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
157 vpreq
->vendorCode
= X_GLXvop_DestroyGLXPbufferSGIX
;
168 * Get a drawable's attribute.
170 * This function is used to implement \c glXGetSelectedEvent and
171 * \c glXGetSelectedEventSGIX.
174 * This function dynamically determines whether to use the SGIX_pbuffer
175 * version of the protocol or the GLX 1.3 version of the protocol.
178 * The number of attributes returned is likely to be small, probably less than
179 * 10. Given that, this routine should try to use an array on the stack to
180 * capture the reply rather than always calling Xmalloc.
183 * This function needs to be modified to work with direct-rendering drivers.
186 GetDrawableAttribute( Display
*dpy
, GLXDrawable drawable
,
187 int attribute
, unsigned int *value
)
189 __GLXdisplayPrivate
*priv
;
190 xGLXGetDrawableAttributesReply reply
;
195 unsigned int num_attributes
;
197 if ( (dpy
== NULL
) || (drawable
== 0) ) {
201 priv
= __glXInitialize(dpy
);
202 GLboolean use_glx_1_3
= ((priv
->majorVersion
> 1)
203 || (priv
->minorVersion
>= 3));
208 opcode
= __glXSetupForCommand(dpy
);
215 xGLXGetDrawableAttributesReq
*req
;
217 GetReqExtra( GLXGetDrawableAttributes
, 4, req
);
218 req
->reqType
= opcode
;
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
= opcode
;
230 vpreq
->glxCode
= X_GLXVendorPrivateWithReply
;
231 vpreq
->vendorCode
= X_GLXvop_GetDrawableAttributesSGIX
;
234 _XReply(dpy
, (xReply
*) &reply
, 0, False
);
236 if (reply
.type
== X_Error
)
243 length
= reply
.length
;
246 num_attributes
= (use_glx_1_3
) ? reply
.numAttribs
: length
/ 2;
247 data
= (CARD32
*) Xmalloc( length
* sizeof(CARD32
) );
248 if ( data
== NULL
) {
249 /* Throw data on the floor */
250 _XEatData(dpy
, length
);
252 _XRead(dpy
, (char *)data
, length
* sizeof(CARD32
) );
254 /* Search the set of returned attributes for the attribute requested by
257 for ( i
= 0 ; i
< num_attributes
; i
++ ) {
258 if ( data
[i
*2] == attribute
) {
259 *value
= data
[ (i
*2) + 1 ];
276 * Create a non-pbuffer GLX drawable.
279 * This function needs to be modified to work with direct-rendering drivers.
282 CreateDrawable( Display
*dpy
, const __GLcontextModes
* fbconfig
,
283 Drawable drawable
, const int *attrib_list
,
286 xGLXCreateWindowReq
* req
;
293 while (attrib_list
[i
* 2] != None
)
297 opcode
= __glXSetupForCommand(dpy
);
302 GetReqExtra( GLXCreateWindow
, 8 * i
, req
);
303 data
= (CARD32
*) (req
+ 1);
305 req
->reqType
= opcode
;
306 req
->glxCode
= glxCode
;
307 req
->screen
= (CARD32
) fbconfig
->screen
;
308 req
->fbconfig
= fbconfig
->fbconfigID
;
309 req
->window
= (GLXPbuffer
) drawable
;
310 req
->glxwindow
= (GLXWindow
) XAllocID(dpy
);
311 req
->numAttribs
= (CARD32
) i
;
313 memcpy( data
, attrib_list
, 8 * i
);
318 return (GLXDrawable
)req
->glxwindow
;
323 * Destroy a non-pbuffer GLX drawable.
326 * This function needs to be modified to work with direct-rendering drivers.
329 DestroyDrawable( Display
* dpy
, GLXDrawable drawable
, CARD32 glxCode
)
331 xGLXDestroyPbufferReq
* req
;
334 if ( (dpy
== NULL
) || (drawable
== 0) ) {
339 opcode
= __glXSetupForCommand(dpy
);
345 GetReqExtra( GLXDestroyPbuffer
, 4, req
);
346 req
->reqType
= opcode
;
347 req
->glxCode
= glxCode
;
348 req
->pbuffer
= (GLXPbuffer
) drawable
;
360 * This function is used to implement \c glXCreatePbuffer and
361 * \c glXCreateGLXPbufferSGIX.
364 * This function dynamically determines whether to use the SGIX_pbuffer
365 * version of the protocol or the GLX 1.3 version of the protocol.
368 * This function needs to be modified to work with direct-rendering drivers.
371 CreatePbuffer( Display
*dpy
, const __GLcontextModes
* fbconfig
,
372 unsigned int width
, unsigned int height
,
373 const int *attrib_list
, GLboolean size_in_attribs
)
375 __GLXdisplayPrivate
*priv
= __glXInitialize(dpy
);
383 while (attrib_list
[i
* 2])
387 opcode
= __glXSetupForCommand(dpy
);
394 if ( (priv
->majorVersion
> 1) || (priv
->minorVersion
>= 3) ) {
395 xGLXCreatePbufferReq
* req
;
396 unsigned int extra
= (size_in_attribs
) ? 0 : 2;
398 GetReqExtra( GLXCreatePbuffer
, (8 * (i
+ extra
)), req
);
399 data
= (CARD32
*) (req
+ 1);
401 req
->reqType
= opcode
;
402 req
->glxCode
= X_GLXCreatePbuffer
;
403 req
->screen
= (CARD32
) fbconfig
->screen
;
404 req
->fbconfig
= fbconfig
->fbconfigID
;
405 req
->pbuffer
= (GLXPbuffer
) id
;
406 req
->numAttribs
= (CARD32
) (i
+ extra
);
408 if ( ! size_in_attribs
) {
409 data
[(2 * i
) + 0] = GLX_PBUFFER_WIDTH
;
410 data
[(2 * i
) + 1] = width
;
411 data
[(2 * i
) + 2] = GLX_PBUFFER_HEIGHT
;
412 data
[(2 * i
) + 3] = height
;
417 xGLXVendorPrivateReq
*vpreq
;
419 GetReqExtra( GLXVendorPrivate
, 20 + (8 * i
), vpreq
);
420 data
= (CARD32
*) (vpreq
+ 1);
422 vpreq
->reqType
= opcode
;
423 vpreq
->glxCode
= X_GLXVendorPrivate
;
424 vpreq
->vendorCode
= X_GLXvop_CreateGLXPbufferSGIX
;
426 data
[0] = (CARD32
) fbconfig
->screen
;
427 data
[1] = (CARD32
) fbconfig
->fbconfigID
;
428 data
[2] = (CARD32
) id
;
429 data
[3] = (CARD32
) width
;
430 data
[4] = (CARD32
) height
;
434 (void) memcpy( data
, attrib_list
, sizeof(CARD32
) * 2 * i
);
444 * Create a new pbuffer.
446 PUBLIC GLXPbufferSGIX
447 glXCreateGLXPbufferSGIX(Display
*dpy
, GLXFBConfigSGIX config
,
448 unsigned int width
, unsigned int height
,
451 return (GLXPbufferSGIX
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
453 attrib_list
, GL_FALSE
);
458 * Create a new pbuffer.
461 glXCreatePbuffer(Display
*dpy
, GLXFBConfig config
, const int *attrib_list
)
463 return (GLXPbuffer
) CreatePbuffer( dpy
, (__GLcontextModes
*) config
,
465 attrib_list
, GL_TRUE
);
470 * Destroy an existing pbuffer.
473 glXDestroyPbuffer(Display
*dpy
, GLXPbuffer pbuf
)
475 DestroyPbuffer( dpy
, pbuf
);
480 * Query an attribute of a drawable.
483 glXQueryDrawable(Display
*dpy
, GLXDrawable drawable
,
484 int attribute
, unsigned int *value
)
486 GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
491 * Query an attribute of a pbuffer.
494 glXQueryGLXPbufferSGIX(Display
*dpy
, GLXPbufferSGIX drawable
,
495 int attribute
, unsigned int *value
)
497 return GetDrawableAttribute( dpy
, drawable
, attribute
, value
);
502 * Select the event mask for a drawable.
505 glXSelectEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long mask
)
509 attribs
[0] = (CARD32
) GLX_EVENT_MASK
;
510 attribs
[1] = (CARD32
) mask
;
512 ChangeDrawableAttribute( dpy
, drawable
, attribs
, 1 );
517 * Get the selected event mask for a drawable.
520 glXGetSelectedEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
)
525 /* The non-sense with value is required because on LP64 platforms
526 * sizeof(unsigned int) != sizeof(unsigned long). On little-endian
527 * we could just type-cast the pointer, but why?
530 GetDrawableAttribute( dpy
, drawable
, GLX_EVENT_MASK_SGIX
, & value
);
536 glXCreatePixmap( Display
*dpy
, GLXFBConfig config
, Pixmap pixmap
,
537 const int *attrib_list
)
539 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
540 (Drawable
) pixmap
, attrib_list
,
546 glXCreateWindow( Display
*dpy
, GLXFBConfig config
, Window win
,
547 const int *attrib_list
)
549 return CreateDrawable( dpy
, (__GLcontextModes
*) config
,
550 (Drawable
) win
, attrib_list
,
556 glXDestroyPixmap(Display
*dpy
, GLXPixmap pixmap
)
558 DestroyDrawable( dpy
, (GLXDrawable
) pixmap
, X_GLXDestroyPixmap
);
563 glXDestroyWindow(Display
*dpy
, GLXWindow win
)
565 DestroyDrawable( dpy
, (GLXDrawable
) win
, X_GLXDestroyWindow
);
569 PUBLIC
GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX
,
570 (Display
*dpy
, GLXPbufferSGIX pbuf
),
574 PUBLIC
GLX_ALIAS_VOID(glXSelectEventSGIX
,
575 (Display
*dpy
, GLXDrawable drawable
, unsigned long mask
),
576 (dpy
, drawable
, mask
),
579 PUBLIC
GLX_ALIAS_VOID(glXGetSelectedEventSGIX
,
580 (Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
),
581 (dpy
, drawable
, mask
),