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;
195 xGLXGetDrawableAttributesReply reply;
199 unsigned int num_attributes;
201 if ( (dpy == NULL) || (drawable == 0) ) {
205 priv = __glXInitialize(dpy);
206 GLboolean use_glx_1_3 = ((priv->majorVersion > 1)
207 || (priv->minorVersion >= 3));
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 if (reply.type == X_Error)
244 length = reply.length;
247 num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
248 data = (CARD32 *) Xmalloc( length * sizeof(CARD32) );
249 if ( data == NULL ) {
250 /* Throw data on the floor */
251 _XEatData(dpy, length);
253 _XRead(dpy, (char *)data, length * sizeof(CARD32) );
255 /* Search the set of returned attributes for the attribute requested by
258 for ( i = 0 ; i < num_attributes ; i++ ) {
259 if ( data[i*2] == attribute ) {
260 *value = data[ (i*2) + 1 ];
277 * Create a non-pbuffer GLX drawable.
280 * This function needs to be modified to work with direct-rendering drivers.
283 CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig,
284 Drawable drawable, const int *attrib_list,
287 xGLXCreateWindowReq * req;
293 while (attrib_list[i * 2] != None)
298 GetReqExtra( GLXCreateWindow, 8 * i, req );
299 data = (CARD32 *) (req + 1);
301 req->reqType = __glXSetupForCommand(dpy);
302 req->glxCode = glxCode;
303 req->screen = (CARD32) fbconfig->screen;
304 req->fbconfig = fbconfig->fbconfigID;
305 req->window = (GLXPbuffer) drawable;
306 req->glxwindow = (GLXWindow) XAllocID(dpy);
307 req->numAttribs = (CARD32) i;
309 memcpy( data, attrib_list, 8 * i );
314 return (GLXDrawable)req->glxwindow;
319 * Destroy a non-pbuffer GLX drawable.
322 * This function needs to be modified to work with direct-rendering drivers.
325 DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode )
327 xGLXDestroyPbufferReq * req;
329 if ( (dpy == NULL) || (drawable == 0) ) {
336 GetReqExtra( GLXDestroyPbuffer, 4, req );
337 req->reqType = __glXSetupForCommand(dpy);
338 req->glxCode = glxCode;
339 req->pbuffer = (GLXPbuffer) drawable;
351 * This function is used to implement \c glXCreatePbuffer and
352 * \c glXCreateGLXPbufferSGIX.
355 * This function dynamically determines whether to use the SGIX_pbuffer
356 * version of the protocol or the GLX 1.3 version of the protocol.
359 * This function needs to be modified to work with direct-rendering drivers.
362 CreatePbuffer( Display *dpy, const __GLcontextModes * fbconfig,
363 unsigned int width, unsigned int height,
364 const int *attrib_list, GLboolean size_in_attribs )
366 __GLXdisplayPrivate *priv = __glXInitialize(dpy);
373 while (attrib_list[i * 2])
380 if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) {
381 xGLXCreatePbufferReq * req;
382 unsigned int extra = (size_in_attribs) ? 0 : 2;
384 GetReqExtra( GLXCreatePbuffer, (8 * (i + extra)), req );
385 data = (CARD32 *) (req + 1);
387 req->reqType = __glXSetupForCommand(dpy);
388 req->glxCode = X_GLXCreatePbuffer;
389 req->screen = (CARD32) fbconfig->screen;
390 req->fbconfig = fbconfig->fbconfigID;
391 req->pbuffer = (GLXPbuffer) id;
392 req->numAttribs = (CARD32) (i + extra);
394 if ( ! size_in_attribs ) {
395 data[(2 * i) + 0] = GLX_PBUFFER_WIDTH;
396 data[(2 * i) + 1] = width;
397 data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT;
398 data[(2 * i) + 3] = height;
403 xGLXVendorPrivateReq *vpreq;
405 GetReqExtra( GLXVendorPrivate, 20 + (8 * i), vpreq );
406 data = (CARD32 *) (vpreq + 1);
408 vpreq->reqType = __glXSetupForCommand(dpy);
409 vpreq->glxCode = X_GLXVendorPrivate;
410 vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX;
412 data[0] = (CARD32) fbconfig->screen;
413 data[1] = (CARD32) fbconfig->fbconfigID;
414 data[2] = (CARD32) id;
415 data[3] = (CARD32) width;
416 data[4] = (CARD32) height;
420 (void) memcpy( data, attrib_list, sizeof(CARD32) * 2 * i );
430 * Create a new pbuffer.
432 PUBLIC GLXPbufferSGIX
433 glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
434 unsigned int width, unsigned int height,
437 return (GLXPbufferSGIX) CreatePbuffer( dpy, (__GLcontextModes *) config,
439 attrib_list, GL_FALSE );
444 * Create a new pbuffer.
447 glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
449 return (GLXPbuffer) CreatePbuffer( dpy, (__GLcontextModes *) config,
451 attrib_list, GL_TRUE );
456 * Destroy an existing pbuffer.
459 glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
461 DestroyPbuffer( dpy, pbuf );
466 * Query an attribute of a drawable.
469 glXQueryDrawable(Display *dpy, GLXDrawable drawable,
470 int attribute, unsigned int *value)
472 GetDrawableAttribute( dpy, drawable, attribute, value );
477 * Query an attribute of a pbuffer.
480 glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX drawable,
481 int attribute, unsigned int *value)
483 return GetDrawableAttribute( dpy, drawable, attribute, value );
488 * Select the event mask for a drawable.
491 glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
495 attribs[0] = (CARD32) GLX_EVENT_MASK;
496 attribs[1] = (CARD32) mask;
498 ChangeDrawableAttribute( dpy, drawable, attribs, 1 );
503 * Get the selected event mask for a drawable.
506 glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
511 /* The non-sense with value is required because on LP64 platforms
512 * sizeof(unsigned int) != sizeof(unsigned long). On little-endian
513 * we could just type-cast the pointer, but why?
516 GetDrawableAttribute( dpy, drawable, GLX_EVENT_MASK_SGIX, & value );
522 glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
523 const int *attrib_list )
525 return CreateDrawable( dpy, (__GLcontextModes *) config,
526 (Drawable) pixmap, attrib_list,
532 glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
533 const int *attrib_list )
535 return CreateDrawable( dpy, (__GLcontextModes *) config,
536 (Drawable) win, attrib_list,
542 glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
544 DestroyDrawable( dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap );
549 glXDestroyWindow(Display *dpy, GLXWindow win)
551 DestroyDrawable( dpy, (GLXDrawable) win, X_GLXDestroyWindow );
555 PUBLIC GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
556 (Display *dpy, GLXPbufferSGIX pbuf),
560 PUBLIC GLX_ALIAS_VOID(glXSelectEventSGIX,
561 (Display *dpy, GLXDrawable drawable, unsigned long mask),
562 (dpy, drawable, mask),
565 PUBLIC GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
566 (Display *dpy, GLXDrawable drawable, unsigned long *mask),
567 (dpy, drawable, mask),