glxcmds.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 3848b8605Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 4848b8605Smrg * 5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg * copy of this software and associated documentation files (the "Software"), 7848b8605Smrg * to deal in the Software without restriction, including without limitation 8848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 10848b8605Smrg * Software is furnished to do so, subject to the following conditions: 11848b8605Smrg * 12848b8605Smrg * The above copyright notice including the dates of first publication and 13848b8605Smrg * either this permission notice or a reference to 14848b8605Smrg * http://oss.sgi.com/projects/FreeB/ 15848b8605Smrg * shall be included in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21848b8605Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22848b8605Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23848b8605Smrg * SOFTWARE. 24848b8605Smrg * 25848b8605Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc. 26848b8605Smrg * shall not be used in advertising or otherwise to promote the sale, use or 27848b8605Smrg * other dealings in this Software without prior written authorization from 28848b8605Smrg * Silicon Graphics, Inc. 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg/** 32848b8605Smrg * \file glxcmds.c 33848b8605Smrg * Client-side GLX interface. 34848b8605Smrg */ 35848b8605Smrg 36848b8605Smrg#include "glxclient.h" 37848b8605Smrg#include "glapi.h" 38848b8605Smrg#include "glxextensions.h" 39848b8605Smrg#include "indirect.h" 40848b8605Smrg#include "glx_error.h" 41848b8605Smrg 42848b8605Smrg#ifdef GLX_DIRECT_RENDERING 43848b8605Smrg#ifdef GLX_USE_APPLEGL 44848b8605Smrg#include "apple/apple_glx_context.h" 45848b8605Smrg#include "apple/apple_glx.h" 46848b8605Smrg#else 47848b8605Smrg#include <sys/time.h> 48848b8605Smrg#ifdef XF86VIDMODE 49848b8605Smrg#include <X11/extensions/xf86vmode.h> 50848b8605Smrg#endif 51848b8605Smrg#endif 52848b8605Smrg#endif 53848b8605Smrg 54848b8605Smrg#include <X11/Xlib-xcb.h> 55848b8605Smrg#include <xcb/xcb.h> 56848b8605Smrg#include <xcb/glx.h> 57848b8605Smrg 58848b8605Smrgstatic const char __glXGLXClientVendorName[] = "Mesa Project and SGI"; 59848b8605Smrgstatic const char __glXGLXClientVersion[] = "1.4"; 60848b8605Smrg 61848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 62848b8605Smrg 63848b8605Smrg/** 64848b8605Smrg * Get the __DRIdrawable for the drawable associated with a GLXContext 65848b8605Smrg * 66848b8605Smrg * \param dpy The display associated with \c drawable. 67848b8605Smrg * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved. 68848b8605Smrg * \param scrn_num If non-NULL, the drawables screen is stored there 69848b8605Smrg * \returns A pointer to the context's __DRIdrawable on success, or NULL if 70848b8605Smrg * the drawable is not associated with a direct-rendering context. 71848b8605Smrg */ 72848b8605Smrg_X_HIDDEN __GLXDRIdrawable * 73848b8605SmrgGetGLXDRIDrawable(Display * dpy, GLXDrawable drawable) 74848b8605Smrg{ 75848b8605Smrg struct glx_display *priv = __glXInitialize(dpy); 76848b8605Smrg __GLXDRIdrawable *pdraw; 77848b8605Smrg 78848b8605Smrg if (priv == NULL) 79848b8605Smrg return NULL; 80848b8605Smrg 81848b8605Smrg if (__glxHashLookup(priv->drawHash, drawable, (void *) &pdraw) == 0) 82848b8605Smrg return pdraw; 83848b8605Smrg 84848b8605Smrg return NULL; 85848b8605Smrg} 86848b8605Smrg 87848b8605Smrg#endif 88848b8605Smrg 89848b8605Smrg_X_HIDDEN struct glx_drawable * 90848b8605SmrgGetGLXDrawable(Display *dpy, GLXDrawable drawable) 91848b8605Smrg{ 92848b8605Smrg struct glx_display *priv = __glXInitialize(dpy); 93848b8605Smrg struct glx_drawable *glxDraw; 94848b8605Smrg 95848b8605Smrg if (priv == NULL) 96848b8605Smrg return NULL; 97848b8605Smrg 98848b8605Smrg if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0) 99848b8605Smrg return glxDraw; 100848b8605Smrg 101848b8605Smrg return NULL; 102848b8605Smrg} 103848b8605Smrg 104848b8605Smrg_X_HIDDEN int 105848b8605SmrgInitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable, 106848b8605Smrg GLXDrawable drawable) 107848b8605Smrg{ 108848b8605Smrg struct glx_display *priv = __glXInitialize(dpy); 109848b8605Smrg 110848b8605Smrg if (!priv) 111848b8605Smrg return -1; 112848b8605Smrg 113848b8605Smrg glxDraw->xDrawable = xDrawable; 114848b8605Smrg glxDraw->drawable = drawable; 115848b8605Smrg glxDraw->lastEventSbc = 0; 116848b8605Smrg glxDraw->eventSbcWrap = 0; 117848b8605Smrg 118848b8605Smrg return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw); 119848b8605Smrg} 120848b8605Smrg 121848b8605Smrg_X_HIDDEN void 122848b8605SmrgDestroyGLXDrawable(Display *dpy, GLXDrawable drawable) 123848b8605Smrg{ 124848b8605Smrg struct glx_display *priv = __glXInitialize(dpy); 125848b8605Smrg struct glx_drawable *glxDraw; 126848b8605Smrg 127848b8605Smrg if (!priv) 128848b8605Smrg return; 129848b8605Smrg 130848b8605Smrg glxDraw = GetGLXDrawable(dpy, drawable); 131848b8605Smrg __glxHashDelete(priv->glXDrawHash, drawable); 132848b8605Smrg free(glxDraw); 133848b8605Smrg} 134848b8605Smrg 135848b8605Smrg/** 136848b8605Smrg * Get the GLX per-screen data structure associated with a GLX context. 137848b8605Smrg * 138848b8605Smrg * \param dpy Display for which the GLX per-screen information is to be 139848b8605Smrg * retrieved. 140848b8605Smrg * \param scrn Screen on \c dpy for which the GLX per-screen information is 141848b8605Smrg * to be retrieved. 142848b8605Smrg * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn 143848b8605Smrg * specify a valid GLX screen, or NULL otherwise. 144848b8605Smrg * 145848b8605Smrg * \todo Should this function validate that \c scrn is within the screen 146848b8605Smrg * number range for \c dpy? 147848b8605Smrg */ 148848b8605Smrg 149848b8605Smrg_X_HIDDEN struct glx_screen * 150848b8605SmrgGetGLXScreenConfigs(Display * dpy, int scrn) 151848b8605Smrg{ 152848b8605Smrg struct glx_display *const priv = __glXInitialize(dpy); 153848b8605Smrg 154848b8605Smrg return (priv 155848b8605Smrg && priv->screens != 156848b8605Smrg NULL) ? priv->screens[scrn] : NULL; 157848b8605Smrg} 158848b8605Smrg 159848b8605Smrg 160848b8605Smrgstatic int 161848b8605SmrgGetGLXPrivScreenConfig(Display * dpy, int scrn, struct glx_display ** ppriv, 162848b8605Smrg struct glx_screen ** ppsc) 163848b8605Smrg{ 164848b8605Smrg /* Initialize the extension, if needed . This has the added value 165848b8605Smrg * of initializing/allocating the display private 166848b8605Smrg */ 167848b8605Smrg 168848b8605Smrg if (dpy == NULL) { 169848b8605Smrg return GLX_NO_EXTENSION; 170848b8605Smrg } 171848b8605Smrg 172848b8605Smrg *ppriv = __glXInitialize(dpy); 173848b8605Smrg if (*ppriv == NULL) { 174848b8605Smrg return GLX_NO_EXTENSION; 175848b8605Smrg } 176848b8605Smrg 177848b8605Smrg /* Check screen number to see if its valid */ 178848b8605Smrg if ((scrn < 0) || (scrn >= ScreenCount(dpy))) { 179848b8605Smrg return GLX_BAD_SCREEN; 180848b8605Smrg } 181848b8605Smrg 182848b8605Smrg /* Check to see if the GL is supported on this screen */ 183848b8605Smrg *ppsc = (*ppriv)->screens[scrn]; 184848b8605Smrg if ((*ppsc)->configs == NULL && (*ppsc)->visuals == NULL) { 185848b8605Smrg /* No support for GL on this screen regardless of visual */ 186848b8605Smrg return GLX_BAD_VISUAL; 187848b8605Smrg } 188848b8605Smrg 189848b8605Smrg return Success; 190848b8605Smrg} 191848b8605Smrg 192848b8605Smrg 193848b8605Smrg/** 194848b8605Smrg * Determine if a \c GLXFBConfig supplied by the application is valid. 195848b8605Smrg * 196848b8605Smrg * \param dpy Application supplied \c Display pointer. 197848b8605Smrg * \param config Application supplied \c GLXFBConfig. 198848b8605Smrg * 199848b8605Smrg * \returns If the \c GLXFBConfig is valid, the a pointer to the matching 200848b8605Smrg * \c struct glx_config structure is returned. Otherwise, \c NULL 201848b8605Smrg * is returned. 202848b8605Smrg */ 203848b8605Smrgstatic struct glx_config * 204848b8605SmrgValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig) 205848b8605Smrg{ 206848b8605Smrg struct glx_display *const priv = __glXInitialize(dpy); 207848b8605Smrg int num_screens = ScreenCount(dpy); 208848b8605Smrg unsigned i; 209848b8605Smrg struct glx_config *config; 210848b8605Smrg 211848b8605Smrg if (priv != NULL) { 212848b8605Smrg for (i = 0; i < num_screens; i++) { 213848b8605Smrg for (config = priv->screens[i]->configs; config != NULL; 214848b8605Smrg config = config->next) { 215848b8605Smrg if (config == (struct glx_config *) fbconfig) { 216848b8605Smrg return config; 217848b8605Smrg } 218848b8605Smrg } 219848b8605Smrg } 220848b8605Smrg } 221848b8605Smrg 222848b8605Smrg return NULL; 223848b8605Smrg} 224848b8605Smrg 225848b8605Smrg/** 226848b8605Smrg * Verifies context's GLX_RENDER_TYPE value with config. 227848b8605Smrg * 228848b8605Smrg * \param config GLX FBConfig which will support the returned renderType. 229848b8605Smrg * \param renderType The context render type to be verified. 230848b8605Smrg * \return True if the value of context renderType was approved, or 0 if no 231848b8605Smrg * valid value was found. 232848b8605Smrg */ 233848b8605SmrgBool 234848b8605Smrgvalidate_renderType_against_config(const struct glx_config *config, 235848b8605Smrg int renderType) 236848b8605Smrg{ 237848b8605Smrg switch (renderType) { 238848b8605Smrg case GLX_RGBA_TYPE: 239848b8605Smrg return (config->renderType & GLX_RGBA_BIT) != 0; 240848b8605Smrg case GLX_COLOR_INDEX_TYPE: 241848b8605Smrg return (config->renderType & GLX_COLOR_INDEX_BIT) != 0; 242848b8605Smrg case GLX_RGBA_FLOAT_TYPE_ARB: 243848b8605Smrg return (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) != 0; 244848b8605Smrg case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT: 245848b8605Smrg return (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) != 0; 246848b8605Smrg default: 247848b8605Smrg break; 248848b8605Smrg } 249848b8605Smrg return 0; 250848b8605Smrg} 251848b8605Smrg 252848b8605Smrg_X_HIDDEN Bool 253848b8605Smrgglx_context_init(struct glx_context *gc, 254848b8605Smrg struct glx_screen *psc, struct glx_config *config) 255848b8605Smrg{ 256848b8605Smrg gc->majorOpcode = __glXSetupForCommand(psc->display->dpy); 257848b8605Smrg if (!gc->majorOpcode) 258848b8605Smrg return False; 259848b8605Smrg 260848b8605Smrg gc->screen = psc->scr; 261848b8605Smrg gc->psc = psc; 262848b8605Smrg gc->config = config; 263848b8605Smrg gc->isDirect = GL_TRUE; 264848b8605Smrg gc->currentContextTag = -1; 265848b8605Smrg 266848b8605Smrg return True; 267848b8605Smrg} 268848b8605Smrg 269848b8605Smrg 270848b8605Smrg/** 271848b8605Smrg * Create a new context. 272848b8605Smrg * 273848b8605Smrg * \param renderType For FBConfigs, what is the rendering type? 274848b8605Smrg */ 275848b8605Smrg 276848b8605Smrgstatic GLXContext 277848b8605SmrgCreateContext(Display *dpy, int generic_id, struct glx_config *config, 278848b8605Smrg GLXContext shareList_user, Bool allowDirect, 279848b8605Smrg unsigned code, int renderType, int screen) 280848b8605Smrg{ 281848b8605Smrg struct glx_context *gc; 282848b8605Smrg struct glx_screen *psc; 283848b8605Smrg struct glx_context *shareList = (struct glx_context *) shareList_user; 284848b8605Smrg if (dpy == NULL) 285848b8605Smrg return NULL; 286848b8605Smrg 287848b8605Smrg psc = GetGLXScreenConfigs(dpy, screen); 288848b8605Smrg if (psc == NULL) 289848b8605Smrg return NULL; 290848b8605Smrg 291848b8605Smrg if (generic_id == None) 292848b8605Smrg return NULL; 293848b8605Smrg 294848b8605Smrg gc = NULL; 295848b8605Smrg#ifdef GLX_USE_APPLEGL 296848b8605Smrg gc = applegl_create_context(psc, config, shareList, renderType); 297848b8605Smrg#else 298848b8605Smrg if (allowDirect && psc->vtable->create_context) 299848b8605Smrg gc = psc->vtable->create_context(psc, config, shareList, renderType); 300848b8605Smrg if (!gc) 301848b8605Smrg gc = indirect_create_context(psc, config, shareList, renderType); 302848b8605Smrg#endif 303848b8605Smrg if (!gc) 304848b8605Smrg return NULL; 305848b8605Smrg 306848b8605Smrg LockDisplay(dpy); 307848b8605Smrg switch (code) { 308848b8605Smrg case X_GLXCreateContext: { 309848b8605Smrg xGLXCreateContextReq *req; 310848b8605Smrg 311848b8605Smrg /* Send the glXCreateContext request */ 312848b8605Smrg GetReq(GLXCreateContext, req); 313848b8605Smrg req->reqType = gc->majorOpcode; 314848b8605Smrg req->glxCode = X_GLXCreateContext; 315848b8605Smrg req->context = gc->xid = XAllocID(dpy); 316848b8605Smrg req->visual = generic_id; 317848b8605Smrg req->screen = screen; 318848b8605Smrg req->shareList = shareList ? shareList->xid : None; 319848b8605Smrg req->isDirect = gc->isDirect; 320848b8605Smrg break; 321848b8605Smrg } 322848b8605Smrg 323848b8605Smrg case X_GLXCreateNewContext: { 324848b8605Smrg xGLXCreateNewContextReq *req; 325848b8605Smrg 326848b8605Smrg /* Send the glXCreateNewContext request */ 327848b8605Smrg GetReq(GLXCreateNewContext, req); 328848b8605Smrg req->reqType = gc->majorOpcode; 329848b8605Smrg req->glxCode = X_GLXCreateNewContext; 330848b8605Smrg req->context = gc->xid = XAllocID(dpy); 331848b8605Smrg req->fbconfig = generic_id; 332848b8605Smrg req->screen = screen; 333848b8605Smrg req->renderType = renderType; 334848b8605Smrg req->shareList = shareList ? shareList->xid : None; 335848b8605Smrg req->isDirect = gc->isDirect; 336848b8605Smrg break; 337848b8605Smrg } 338848b8605Smrg 339848b8605Smrg case X_GLXvop_CreateContextWithConfigSGIX: { 340848b8605Smrg xGLXVendorPrivateWithReplyReq *vpreq; 341848b8605Smrg xGLXCreateContextWithConfigSGIXReq *req; 342848b8605Smrg 343848b8605Smrg /* Send the glXCreateNewContext request */ 344848b8605Smrg GetReqExtra(GLXVendorPrivateWithReply, 345848b8605Smrg sz_xGLXCreateContextWithConfigSGIXReq - 346848b8605Smrg sz_xGLXVendorPrivateWithReplyReq, vpreq); 347848b8605Smrg req = (xGLXCreateContextWithConfigSGIXReq *) vpreq; 348848b8605Smrg req->reqType = gc->majorOpcode; 349848b8605Smrg req->glxCode = X_GLXVendorPrivateWithReply; 350848b8605Smrg req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; 351848b8605Smrg req->context = gc->xid = XAllocID(dpy); 352848b8605Smrg req->fbconfig = generic_id; 353848b8605Smrg req->screen = screen; 354848b8605Smrg req->renderType = renderType; 355848b8605Smrg req->shareList = shareList ? shareList->xid : None; 356848b8605Smrg req->isDirect = gc->isDirect; 357848b8605Smrg break; 358848b8605Smrg } 359848b8605Smrg 360848b8605Smrg default: 361848b8605Smrg /* What to do here? This case is the sign of an internal error. It 362848b8605Smrg * should never be reachable. 363848b8605Smrg */ 364848b8605Smrg break; 365848b8605Smrg } 366848b8605Smrg 367848b8605Smrg UnlockDisplay(dpy); 368848b8605Smrg SyncHandle(); 369848b8605Smrg 370848b8605Smrg gc->share_xid = shareList ? shareList->xid : None; 371848b8605Smrg gc->imported = GL_FALSE; 372848b8605Smrg 373848b8605Smrg return (GLXContext) gc; 374848b8605Smrg} 375848b8605Smrg 376848b8605Smrg_X_EXPORT GLXContext 377848b8605SmrgglXCreateContext(Display * dpy, XVisualInfo * vis, 378848b8605Smrg GLXContext shareList, Bool allowDirect) 379848b8605Smrg{ 380848b8605Smrg struct glx_config *config = NULL; 381848b8605Smrg int renderType = GLX_RGBA_TYPE; 382848b8605Smrg 383848b8605Smrg#if defined(GLX_DIRECT_RENDERING) || defined(GLX_USE_APPLEGL) 384848b8605Smrg struct glx_screen *const psc = GetGLXScreenConfigs(dpy, vis->screen); 385848b8605Smrg 386848b8605Smrg if (psc) 387848b8605Smrg config = glx_config_find_visual(psc->visuals, vis->visualid); 388848b8605Smrg 389848b8605Smrg if (config == NULL) { 390848b8605Smrg xError error; 391848b8605Smrg 392848b8605Smrg error.errorCode = BadValue; 393848b8605Smrg error.resourceID = vis->visualid; 394848b8605Smrg error.sequenceNumber = dpy->request; 395848b8605Smrg error.type = X_Error; 396848b8605Smrg error.majorCode = __glXSetupForCommand(dpy); 397848b8605Smrg error.minorCode = X_GLXCreateContext; 398848b8605Smrg _XError(dpy, &error); 399848b8605Smrg return None; 400848b8605Smrg } 401848b8605Smrg 402848b8605Smrg /* Choose the context render type based on DRI config values. It is 403848b8605Smrg * unusual to set this type from config, but we have no other choice, as 404848b8605Smrg * this old API does not provide renderType parameter. 405848b8605Smrg */ 406848b8605Smrg if (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) { 407848b8605Smrg renderType = GLX_RGBA_FLOAT_TYPE_ARB; 408848b8605Smrg } else if (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) { 409848b8605Smrg renderType = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT; 410848b8605Smrg } else if (config->renderType & GLX_RGBA_BIT) { 411848b8605Smrg renderType = GLX_RGBA_TYPE; 412848b8605Smrg } else if (config->renderType & GLX_COLOR_INDEX_BIT) { 413848b8605Smrg renderType = GLX_COLOR_INDEX_TYPE; 414848b8605Smrg } else if (config->rgbMode) { 415848b8605Smrg /* If we're here, then renderType is not set correctly. Let's use a 416848b8605Smrg * safeguard - any TrueColor or DirectColor mode is RGB mode. Such 417848b8605Smrg * default value is needed by old DRI drivers, which didn't set 418848b8605Smrg * renderType correctly as the value was just ignored. 419848b8605Smrg */ 420848b8605Smrg renderType = GLX_RGBA_TYPE; 421848b8605Smrg } else { 422848b8605Smrg /* Safeguard - only one option left, all non-RGB modes are indexed 423848b8605Smrg * modes. Again, this allows drivers with invalid renderType to work 424848b8605Smrg * properly. 425848b8605Smrg */ 426848b8605Smrg renderType = GLX_COLOR_INDEX_TYPE; 427848b8605Smrg } 428848b8605Smrg#endif 429848b8605Smrg 430848b8605Smrg return CreateContext(dpy, vis->visualid, config, shareList, allowDirect, 431848b8605Smrg X_GLXCreateContext, renderType, vis->screen); 432848b8605Smrg} 433848b8605Smrg 434848b8605Smrgstatic void 435848b8605Smrgglx_send_destroy_context(Display *dpy, XID xid) 436848b8605Smrg{ 437848b8605Smrg CARD8 opcode = __glXSetupForCommand(dpy); 438848b8605Smrg xGLXDestroyContextReq *req; 439848b8605Smrg 440848b8605Smrg LockDisplay(dpy); 441848b8605Smrg GetReq(GLXDestroyContext, req); 442848b8605Smrg req->reqType = opcode; 443848b8605Smrg req->glxCode = X_GLXDestroyContext; 444848b8605Smrg req->context = xid; 445848b8605Smrg UnlockDisplay(dpy); 446848b8605Smrg SyncHandle(); 447848b8605Smrg} 448848b8605Smrg 449848b8605Smrg/* 450848b8605Smrg** Destroy the named context 451848b8605Smrg*/ 452848b8605Smrg 453848b8605Smrg_X_EXPORT void 454848b8605SmrgglXDestroyContext(Display * dpy, GLXContext ctx) 455848b8605Smrg{ 456848b8605Smrg struct glx_context *gc = (struct glx_context *) ctx; 457848b8605Smrg 458848b8605Smrg if (gc == NULL || gc->xid == None) 459848b8605Smrg return; 460848b8605Smrg 461848b8605Smrg __glXLock(); 462848b8605Smrg if (!gc->imported) 463848b8605Smrg glx_send_destroy_context(dpy, gc->xid); 464848b8605Smrg 465848b8605Smrg if (gc->currentDpy) { 466848b8605Smrg /* This context is bound to some thread. According to the man page, 467848b8605Smrg * we should not actually delete the context until it's unbound. 468848b8605Smrg * Note that we set gc->xid = None above. In MakeContextCurrent() 469848b8605Smrg * we check for that and delete the context there. 470848b8605Smrg */ 471848b8605Smrg gc->xid = None; 472848b8605Smrg } else { 473848b8605Smrg gc->vtable->destroy(gc); 474848b8605Smrg } 475848b8605Smrg __glXUnlock(); 476848b8605Smrg} 477848b8605Smrg 478848b8605Smrg/* 479848b8605Smrg** Return the major and minor version #s for the GLX extension 480848b8605Smrg*/ 481848b8605Smrg_X_EXPORT Bool 482848b8605SmrgglXQueryVersion(Display * dpy, int *major, int *minor) 483848b8605Smrg{ 484848b8605Smrg struct glx_display *priv; 485848b8605Smrg 486848b8605Smrg /* Init the extension. This fetches the major and minor version. */ 487848b8605Smrg priv = __glXInitialize(dpy); 488848b8605Smrg if (!priv) 489848b8605Smrg return False; 490848b8605Smrg 491848b8605Smrg if (major) 492848b8605Smrg *major = priv->majorVersion; 493848b8605Smrg if (minor) 494848b8605Smrg *minor = priv->minorVersion; 495848b8605Smrg return True; 496848b8605Smrg} 497848b8605Smrg 498848b8605Smrg/* 499848b8605Smrg** Query the existance of the GLX extension 500848b8605Smrg*/ 501848b8605Smrg_X_EXPORT Bool 502848b8605SmrgglXQueryExtension(Display * dpy, int *errorBase, int *eventBase) 503848b8605Smrg{ 504848b8605Smrg int major_op, erb, evb; 505848b8605Smrg Bool rv; 506848b8605Smrg 507848b8605Smrg rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb); 508848b8605Smrg if (rv) { 509848b8605Smrg if (errorBase) 510848b8605Smrg *errorBase = erb; 511848b8605Smrg if (eventBase) 512848b8605Smrg *eventBase = evb; 513848b8605Smrg } 514848b8605Smrg return rv; 515848b8605Smrg} 516848b8605Smrg 517848b8605Smrg/* 518848b8605Smrg** Put a barrier in the token stream that forces the GL to finish its 519848b8605Smrg** work before X can proceed. 520848b8605Smrg*/ 521848b8605Smrg_X_EXPORT void 522848b8605SmrgglXWaitGL(void) 523848b8605Smrg{ 524848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 525848b8605Smrg 526848b8605Smrg if (gc && gc->vtable->wait_gl) 527848b8605Smrg gc->vtable->wait_gl(gc); 528848b8605Smrg} 529848b8605Smrg 530848b8605Smrg/* 531848b8605Smrg** Put a barrier in the token stream that forces X to finish its 532848b8605Smrg** work before GL can proceed. 533848b8605Smrg*/ 534848b8605Smrg_X_EXPORT void 535848b8605SmrgglXWaitX(void) 536848b8605Smrg{ 537848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 538848b8605Smrg 539848b8605Smrg if (gc && gc->vtable->wait_x) 540848b8605Smrg gc->vtable->wait_x(gc); 541848b8605Smrg} 542848b8605Smrg 543848b8605Smrg_X_EXPORT void 544848b8605SmrgglXUseXFont(Font font, int first, int count, int listBase) 545848b8605Smrg{ 546848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 547848b8605Smrg 548848b8605Smrg if (gc && gc->vtable->use_x_font) 549848b8605Smrg gc->vtable->use_x_font(gc, font, first, count, listBase); 550848b8605Smrg} 551848b8605Smrg 552848b8605Smrg/************************************************************************/ 553848b8605Smrg 554848b8605Smrg/* 555848b8605Smrg** Copy the source context to the destination context using the 556848b8605Smrg** attribute "mask". 557848b8605Smrg*/ 558848b8605Smrg_X_EXPORT void 559848b8605SmrgglXCopyContext(Display * dpy, GLXContext source_user, 560848b8605Smrg GLXContext dest_user, unsigned long mask) 561848b8605Smrg{ 562848b8605Smrg struct glx_context *source = (struct glx_context *) source_user; 563848b8605Smrg struct glx_context *dest = (struct glx_context *) dest_user; 564848b8605Smrg#ifdef GLX_USE_APPLEGL 565848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 566848b8605Smrg int errorcode; 567848b8605Smrg bool x11error; 568848b8605Smrg 569848b8605Smrg if(apple_glx_copy_context(gc->driContext, source->driContext, dest->driContext, 570848b8605Smrg mask, &errorcode, &x11error)) { 571848b8605Smrg __glXSendError(dpy, errorcode, 0, X_GLXCopyContext, x11error); 572848b8605Smrg } 573848b8605Smrg 574848b8605Smrg#else 575848b8605Smrg xGLXCopyContextReq *req; 576848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 577848b8605Smrg GLXContextTag tag; 578848b8605Smrg CARD8 opcode; 579848b8605Smrg 580848b8605Smrg opcode = __glXSetupForCommand(dpy); 581848b8605Smrg if (!opcode) { 582848b8605Smrg return; 583848b8605Smrg } 584848b8605Smrg 585848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 586848b8605Smrg if (gc->isDirect) { 587848b8605Smrg /* NOT_DONE: This does not work yet */ 588848b8605Smrg } 589848b8605Smrg#endif 590848b8605Smrg 591848b8605Smrg /* 592848b8605Smrg ** If the source is the current context, send its tag so that the context 593848b8605Smrg ** can be flushed before the copy. 594848b8605Smrg */ 595848b8605Smrg if (source == gc && dpy == gc->currentDpy) { 596848b8605Smrg tag = gc->currentContextTag; 597848b8605Smrg } 598848b8605Smrg else { 599848b8605Smrg tag = 0; 600848b8605Smrg } 601848b8605Smrg 602848b8605Smrg /* Send the glXCopyContext request */ 603848b8605Smrg LockDisplay(dpy); 604848b8605Smrg GetReq(GLXCopyContext, req); 605848b8605Smrg req->reqType = opcode; 606848b8605Smrg req->glxCode = X_GLXCopyContext; 607848b8605Smrg req->source = source ? source->xid : None; 608848b8605Smrg req->dest = dest ? dest->xid : None; 609848b8605Smrg req->mask = mask; 610848b8605Smrg req->contextTag = tag; 611848b8605Smrg UnlockDisplay(dpy); 612848b8605Smrg SyncHandle(); 613848b8605Smrg#endif /* GLX_USE_APPLEGL */ 614848b8605Smrg} 615848b8605Smrg 616848b8605Smrg 617848b8605Smrg/** 618848b8605Smrg * Determine if a context uses direct rendering. 619848b8605Smrg * 620848b8605Smrg * \param dpy Display where the context was created. 621848b8605Smrg * \param contextID ID of the context to be tested. 622848b8605Smrg * 623848b8605Smrg * \returns \c True if the context is direct rendering or not. 624848b8605Smrg */ 625848b8605Smrgstatic Bool 626848b8605Smrg__glXIsDirect(Display * dpy, GLXContextID contextID) 627848b8605Smrg{ 628848b8605Smrg CARD8 opcode; 629848b8605Smrg xcb_connection_t *c; 630848b8605Smrg xcb_generic_error_t *err; 631848b8605Smrg xcb_glx_is_direct_reply_t *reply; 632848b8605Smrg Bool is_direct; 633848b8605Smrg 634848b8605Smrg opcode = __glXSetupForCommand(dpy); 635848b8605Smrg if (!opcode) { 636848b8605Smrg return False; 637848b8605Smrg } 638848b8605Smrg 639848b8605Smrg c = XGetXCBConnection(dpy); 640848b8605Smrg reply = xcb_glx_is_direct_reply(c, xcb_glx_is_direct(c, contextID), &err); 641848b8605Smrg is_direct = (reply != NULL && reply->is_direct) ? True : False; 642848b8605Smrg 643848b8605Smrg if (err != NULL) { 644848b8605Smrg __glXSendErrorForXcb(dpy, err); 645848b8605Smrg free(err); 646848b8605Smrg } 647848b8605Smrg 648848b8605Smrg free(reply); 649848b8605Smrg 650848b8605Smrg return is_direct; 651848b8605Smrg} 652848b8605Smrg 653848b8605Smrg/** 654848b8605Smrg * \todo 655848b8605Smrg * Shouldn't this function \b always return \c False when 656848b8605Smrg * \c GLX_DIRECT_RENDERING is not defined? Do we really need to bother with 657848b8605Smrg * the GLX protocol here at all? 658848b8605Smrg */ 659848b8605Smrg_X_EXPORT Bool 660848b8605SmrgglXIsDirect(Display * dpy, GLXContext gc_user) 661848b8605Smrg{ 662848b8605Smrg struct glx_context *gc = (struct glx_context *) gc_user; 663848b8605Smrg 664848b8605Smrg if (!gc) { 665848b8605Smrg return False; 666848b8605Smrg } 667848b8605Smrg else if (gc->isDirect) { 668848b8605Smrg return True; 669848b8605Smrg } 670848b8605Smrg#ifdef GLX_USE_APPLEGL /* TODO: indirect on darwin */ 671848b8605Smrg return False; 672848b8605Smrg#else 673848b8605Smrg return __glXIsDirect(dpy, gc->xid); 674848b8605Smrg#endif 675848b8605Smrg} 676848b8605Smrg 677848b8605Smrg_X_EXPORT GLXPixmap 678848b8605SmrgglXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) 679848b8605Smrg{ 680848b8605Smrg#ifdef GLX_USE_APPLEGL 681848b8605Smrg int screen = vis->screen; 682848b8605Smrg struct glx_screen *const psc = GetGLXScreenConfigs(dpy, screen); 683848b8605Smrg const struct glx_config *config; 684848b8605Smrg 685848b8605Smrg config = glx_config_find_visual(psc->visuals, vis->visualid); 686848b8605Smrg 687848b8605Smrg if(apple_glx_pixmap_create(dpy, vis->screen, pixmap, config)) 688848b8605Smrg return None; 689848b8605Smrg 690848b8605Smrg return pixmap; 691848b8605Smrg#else 692848b8605Smrg xGLXCreateGLXPixmapReq *req; 693848b8605Smrg struct glx_drawable *glxDraw; 694848b8605Smrg GLXPixmap xid; 695848b8605Smrg CARD8 opcode; 696848b8605Smrg 697848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 698848b8605Smrg struct glx_display *const priv = __glXInitialize(dpy); 699848b8605Smrg 700848b8605Smrg if (priv == NULL) 701848b8605Smrg return None; 702848b8605Smrg#endif 703848b8605Smrg 704848b8605Smrg opcode = __glXSetupForCommand(dpy); 705848b8605Smrg if (!opcode) { 706848b8605Smrg return None; 707848b8605Smrg } 708848b8605Smrg 709848b8605Smrg glxDraw = malloc(sizeof(*glxDraw)); 710848b8605Smrg if (!glxDraw) 711848b8605Smrg return None; 712848b8605Smrg 713848b8605Smrg /* Send the glXCreateGLXPixmap request */ 714848b8605Smrg LockDisplay(dpy); 715848b8605Smrg GetReq(GLXCreateGLXPixmap, req); 716848b8605Smrg req->reqType = opcode; 717848b8605Smrg req->glxCode = X_GLXCreateGLXPixmap; 718848b8605Smrg req->screen = vis->screen; 719848b8605Smrg req->visual = vis->visualid; 720848b8605Smrg req->pixmap = pixmap; 721848b8605Smrg req->glxpixmap = xid = XAllocID(dpy); 722848b8605Smrg UnlockDisplay(dpy); 723848b8605Smrg SyncHandle(); 724848b8605Smrg 725848b8605Smrg if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) { 726848b8605Smrg free(glxDraw); 727848b8605Smrg return None; 728848b8605Smrg } 729848b8605Smrg 730848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 731848b8605Smrg do { 732848b8605Smrg /* FIXME: Maybe delay __DRIdrawable creation until the drawable 733848b8605Smrg * is actually bound to a context... */ 734848b8605Smrg 735848b8605Smrg __GLXDRIdrawable *pdraw; 736848b8605Smrg struct glx_screen *psc; 737848b8605Smrg struct glx_config *config; 738848b8605Smrg 739848b8605Smrg psc = priv->screens[vis->screen]; 740848b8605Smrg if (psc->driScreen == NULL) 741848b8605Smrg return xid; 742848b8605Smrg 743848b8605Smrg config = glx_config_find_visual(psc->visuals, vis->visualid); 744848b8605Smrg pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config); 745848b8605Smrg if (pdraw == NULL) { 746848b8605Smrg fprintf(stderr, "failed to create pixmap\n"); 747848b8605Smrg xid = None; 748848b8605Smrg break; 749848b8605Smrg } 750848b8605Smrg 751848b8605Smrg if (__glxHashInsert(priv->drawHash, xid, pdraw)) { 752848b8605Smrg (*pdraw->destroyDrawable) (pdraw); 753848b8605Smrg xid = None; 754848b8605Smrg break; 755848b8605Smrg } 756848b8605Smrg } while (0); 757848b8605Smrg 758848b8605Smrg if (xid == None) { 759848b8605Smrg xGLXDestroyGLXPixmapReq *dreq; 760848b8605Smrg LockDisplay(dpy); 761848b8605Smrg GetReq(GLXDestroyGLXPixmap, dreq); 762848b8605Smrg dreq->reqType = opcode; 763848b8605Smrg dreq->glxCode = X_GLXDestroyGLXPixmap; 764848b8605Smrg dreq->glxpixmap = xid; 765848b8605Smrg UnlockDisplay(dpy); 766848b8605Smrg SyncHandle(); 767848b8605Smrg } 768848b8605Smrg#endif 769848b8605Smrg 770848b8605Smrg return xid; 771848b8605Smrg#endif 772848b8605Smrg} 773848b8605Smrg 774848b8605Smrg/* 775848b8605Smrg** Destroy the named pixmap 776848b8605Smrg*/ 777848b8605Smrg_X_EXPORT void 778848b8605SmrgglXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) 779848b8605Smrg{ 780848b8605Smrg#ifdef GLX_USE_APPLEGL 781848b8605Smrg if(apple_glx_pixmap_destroy(dpy, glxpixmap)) 782848b8605Smrg __glXSendError(dpy, GLXBadPixmap, glxpixmap, X_GLXDestroyPixmap, false); 783848b8605Smrg#else 784848b8605Smrg xGLXDestroyGLXPixmapReq *req; 785848b8605Smrg CARD8 opcode; 786848b8605Smrg 787848b8605Smrg opcode = __glXSetupForCommand(dpy); 788848b8605Smrg if (!opcode) { 789848b8605Smrg return; 790848b8605Smrg } 791848b8605Smrg 792848b8605Smrg /* Send the glXDestroyGLXPixmap request */ 793848b8605Smrg LockDisplay(dpy); 794848b8605Smrg GetReq(GLXDestroyGLXPixmap, req); 795848b8605Smrg req->reqType = opcode; 796848b8605Smrg req->glxCode = X_GLXDestroyGLXPixmap; 797848b8605Smrg req->glxpixmap = glxpixmap; 798848b8605Smrg UnlockDisplay(dpy); 799848b8605Smrg SyncHandle(); 800848b8605Smrg 801848b8605Smrg DestroyGLXDrawable(dpy, glxpixmap); 802848b8605Smrg 803848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 804848b8605Smrg { 805848b8605Smrg struct glx_display *const priv = __glXInitialize(dpy); 806848b8605Smrg __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap); 807848b8605Smrg 808848b8605Smrg if (priv != NULL && pdraw != NULL) { 809848b8605Smrg (*pdraw->destroyDrawable) (pdraw); 810848b8605Smrg __glxHashDelete(priv->drawHash, glxpixmap); 811848b8605Smrg } 812848b8605Smrg } 813848b8605Smrg#endif 814848b8605Smrg#endif /* GLX_USE_APPLEGL */ 815848b8605Smrg} 816848b8605Smrg 817848b8605Smrg_X_EXPORT void 818848b8605SmrgglXSwapBuffers(Display * dpy, GLXDrawable drawable) 819848b8605Smrg{ 820848b8605Smrg#ifdef GLX_USE_APPLEGL 821848b8605Smrg struct glx_context * gc = __glXGetCurrentContext(); 822848b8605Smrg if(gc && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) { 823848b8605Smrg apple_glx_swap_buffers(gc->driContext); 824848b8605Smrg } else { 825848b8605Smrg __glXSendError(dpy, GLXBadCurrentWindow, 0, X_GLXSwapBuffers, false); 826848b8605Smrg } 827848b8605Smrg#else 828848b8605Smrg struct glx_context *gc; 829848b8605Smrg GLXContextTag tag; 830848b8605Smrg CARD8 opcode; 831848b8605Smrg xcb_connection_t *c; 832848b8605Smrg 833848b8605Smrg gc = __glXGetCurrentContext(); 834848b8605Smrg 835848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 836848b8605Smrg { 837848b8605Smrg __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); 838848b8605Smrg 839848b8605Smrg if (pdraw != NULL) { 840848b8605Smrg Bool flush = gc && drawable == gc->currentDrawable; 841848b8605Smrg 842848b8605Smrg (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0, flush); 843848b8605Smrg return; 844848b8605Smrg } 845848b8605Smrg } 846848b8605Smrg#endif 847848b8605Smrg 848848b8605Smrg opcode = __glXSetupForCommand(dpy); 849848b8605Smrg if (!opcode) { 850848b8605Smrg return; 851848b8605Smrg } 852848b8605Smrg 853848b8605Smrg /* 854848b8605Smrg ** The calling thread may or may not have a current context. If it 855848b8605Smrg ** does, send the context tag so the server can do a flush. 856848b8605Smrg */ 857848b8605Smrg if ((gc != NULL) && (dpy == gc->currentDpy) && 858848b8605Smrg ((drawable == gc->currentDrawable) 859848b8605Smrg || (drawable == gc->currentReadable))) { 860848b8605Smrg tag = gc->currentContextTag; 861848b8605Smrg } 862848b8605Smrg else { 863848b8605Smrg tag = 0; 864848b8605Smrg } 865848b8605Smrg 866848b8605Smrg c = XGetXCBConnection(dpy); 867848b8605Smrg xcb_glx_swap_buffers(c, tag, drawable); 868848b8605Smrg xcb_flush(c); 869848b8605Smrg#endif /* GLX_USE_APPLEGL */ 870848b8605Smrg} 871848b8605Smrg 872848b8605Smrg 873848b8605Smrg/* 874848b8605Smrg** Return configuration information for the given display, screen and 875848b8605Smrg** visual combination. 876848b8605Smrg*/ 877848b8605Smrg_X_EXPORT int 878848b8605SmrgglXGetConfig(Display * dpy, XVisualInfo * vis, int attribute, 879848b8605Smrg int *value_return) 880848b8605Smrg{ 881848b8605Smrg struct glx_display *priv; 882848b8605Smrg struct glx_screen *psc; 883848b8605Smrg struct glx_config *config; 884848b8605Smrg int status; 885848b8605Smrg 886848b8605Smrg status = GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc); 887848b8605Smrg if (status == Success) { 888848b8605Smrg config = glx_config_find_visual(psc->visuals, vis->visualid); 889848b8605Smrg 890848b8605Smrg /* Lookup attribute after first finding a match on the visual */ 891848b8605Smrg if (config != NULL) { 892848b8605Smrg return glx_config_get(config, attribute, value_return); 893848b8605Smrg } 894848b8605Smrg 895848b8605Smrg status = GLX_BAD_VISUAL; 896848b8605Smrg } 897848b8605Smrg 898848b8605Smrg /* 899848b8605Smrg ** If we can't find the config for this visual, this visual is not 900848b8605Smrg ** supported by the OpenGL implementation on the server. 901848b8605Smrg */ 902848b8605Smrg if ((status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL)) { 903848b8605Smrg *value_return = False; 904848b8605Smrg status = Success; 905848b8605Smrg } 906848b8605Smrg 907848b8605Smrg return status; 908848b8605Smrg} 909848b8605Smrg 910848b8605Smrg/************************************************************************/ 911848b8605Smrg 912848b8605Smrgstatic void 913848b8605Smrginit_fbconfig_for_chooser(struct glx_config * config, 914848b8605Smrg GLboolean fbconfig_style_tags) 915848b8605Smrg{ 916848b8605Smrg memset(config, 0, sizeof(struct glx_config)); 917848b8605Smrg config->visualID = (XID) GLX_DONT_CARE; 918848b8605Smrg config->visualType = GLX_DONT_CARE; 919848b8605Smrg 920848b8605Smrg /* glXChooseFBConfig specifies different defaults for these properties than 921848b8605Smrg * glXChooseVisual. 922848b8605Smrg */ 923848b8605Smrg if (fbconfig_style_tags) { 924848b8605Smrg config->rgbMode = GL_TRUE; 925848b8605Smrg config->doubleBufferMode = GLX_DONT_CARE; 926848b8605Smrg config->renderType = GLX_RGBA_BIT; 927848b8605Smrg } 928848b8605Smrg 929848b8605Smrg config->drawableType = GLX_WINDOW_BIT; 930848b8605Smrg config->visualRating = GLX_DONT_CARE; 931848b8605Smrg config->transparentPixel = GLX_NONE; 932848b8605Smrg config->transparentRed = GLX_DONT_CARE; 933848b8605Smrg config->transparentGreen = GLX_DONT_CARE; 934848b8605Smrg config->transparentBlue = GLX_DONT_CARE; 935848b8605Smrg config->transparentAlpha = GLX_DONT_CARE; 936848b8605Smrg config->transparentIndex = GLX_DONT_CARE; 937848b8605Smrg 938848b8605Smrg config->xRenderable = GLX_DONT_CARE; 939848b8605Smrg config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE); 940848b8605Smrg 941848b8605Smrg config->swapMethod = GLX_DONT_CARE; 942848b8605Smrg} 943848b8605Smrg 944848b8605Smrg#define MATCH_DONT_CARE( param ) \ 945848b8605Smrg do { \ 946848b8605Smrg if ( ((int) a-> param != (int) GLX_DONT_CARE) \ 947848b8605Smrg && (a-> param != b-> param) ) { \ 948848b8605Smrg return False; \ 949848b8605Smrg } \ 950848b8605Smrg } while ( 0 ) 951848b8605Smrg 952848b8605Smrg#define MATCH_MINIMUM( param ) \ 953848b8605Smrg do { \ 954848b8605Smrg if ( ((int) a-> param != (int) GLX_DONT_CARE) \ 955848b8605Smrg && (a-> param > b-> param) ) { \ 956848b8605Smrg return False; \ 957848b8605Smrg } \ 958848b8605Smrg } while ( 0 ) 959848b8605Smrg 960848b8605Smrg#define MATCH_EXACT( param ) \ 961848b8605Smrg do { \ 962848b8605Smrg if ( a-> param != b-> param) { \ 963848b8605Smrg return False; \ 964848b8605Smrg } \ 965848b8605Smrg } while ( 0 ) 966848b8605Smrg 967848b8605Smrg/* Test that all bits from a are contained in b */ 968848b8605Smrg#define MATCH_MASK(param) \ 969848b8605Smrg do { \ 970848b8605Smrg if ( ((int) a-> param != (int) GLX_DONT_CARE) \ 971848b8605Smrg && ((a->param & ~b->param) != 0) ) { \ 972848b8605Smrg return False; \ 973848b8605Smrg } \ 974848b8605Smrg } while (0); 975848b8605Smrg 976848b8605Smrg/** 977848b8605Smrg * Determine if two GLXFBConfigs are compatible. 978848b8605Smrg * 979848b8605Smrg * \param a Application specified config to test. 980848b8605Smrg * \param b Server specified config to test against \c a. 981848b8605Smrg */ 982848b8605Smrgstatic Bool 983848b8605Smrgfbconfigs_compatible(const struct glx_config * const a, 984848b8605Smrg const struct glx_config * const b) 985848b8605Smrg{ 986848b8605Smrg MATCH_DONT_CARE(doubleBufferMode); 987848b8605Smrg MATCH_DONT_CARE(visualType); 988848b8605Smrg MATCH_DONT_CARE(visualRating); 989848b8605Smrg MATCH_DONT_CARE(xRenderable); 990848b8605Smrg MATCH_DONT_CARE(fbconfigID); 991848b8605Smrg MATCH_DONT_CARE(swapMethod); 992848b8605Smrg 993848b8605Smrg MATCH_MINIMUM(rgbBits); 994848b8605Smrg MATCH_MINIMUM(numAuxBuffers); 995848b8605Smrg MATCH_MINIMUM(redBits); 996848b8605Smrg MATCH_MINIMUM(greenBits); 997848b8605Smrg MATCH_MINIMUM(blueBits); 998848b8605Smrg MATCH_MINIMUM(alphaBits); 999848b8605Smrg MATCH_MINIMUM(depthBits); 1000848b8605Smrg MATCH_MINIMUM(stencilBits); 1001848b8605Smrg MATCH_MINIMUM(accumRedBits); 1002848b8605Smrg MATCH_MINIMUM(accumGreenBits); 1003848b8605Smrg MATCH_MINIMUM(accumBlueBits); 1004848b8605Smrg MATCH_MINIMUM(accumAlphaBits); 1005848b8605Smrg MATCH_MINIMUM(sampleBuffers); 1006848b8605Smrg MATCH_MINIMUM(maxPbufferWidth); 1007848b8605Smrg MATCH_MINIMUM(maxPbufferHeight); 1008848b8605Smrg MATCH_MINIMUM(maxPbufferPixels); 1009848b8605Smrg MATCH_MINIMUM(samples); 1010848b8605Smrg 1011848b8605Smrg MATCH_DONT_CARE(stereoMode); 1012848b8605Smrg MATCH_EXACT(level); 1013848b8605Smrg 1014848b8605Smrg MATCH_MASK(drawableType); 1015848b8605Smrg MATCH_MASK(renderType); 1016848b8605Smrg 1017848b8605Smrg /* There is a bug in a few of the XFree86 DDX drivers. They contain 1018848b8605Smrg * visuals with a "transparent type" of 0 when they really mean GLX_NONE. 1019848b8605Smrg * Technically speaking, it is a bug in the DDX driver, but there is 1020848b8605Smrg * enough of an installed base to work around the problem here. In any 1021848b8605Smrg * case, 0 is not a valid value of the transparent type, so we'll treat 0 1022848b8605Smrg * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and 1023848b8605Smrg * 0 from the server to be a match to maintain backward compatibility with 1024848b8605Smrg * the (broken) drivers. 1025848b8605Smrg */ 1026848b8605Smrg 1027848b8605Smrg if (a->transparentPixel != (int) GLX_DONT_CARE && a->transparentPixel != 0) { 1028848b8605Smrg if (a->transparentPixel == GLX_NONE) { 1029848b8605Smrg if (b->transparentPixel != GLX_NONE && b->transparentPixel != 0) 1030848b8605Smrg return False; 1031848b8605Smrg } 1032848b8605Smrg else { 1033848b8605Smrg MATCH_EXACT(transparentPixel); 1034848b8605Smrg } 1035848b8605Smrg 1036848b8605Smrg switch (a->transparentPixel) { 1037848b8605Smrg case GLX_TRANSPARENT_RGB: 1038848b8605Smrg MATCH_DONT_CARE(transparentRed); 1039848b8605Smrg MATCH_DONT_CARE(transparentGreen); 1040848b8605Smrg MATCH_DONT_CARE(transparentBlue); 1041848b8605Smrg MATCH_DONT_CARE(transparentAlpha); 1042848b8605Smrg break; 1043848b8605Smrg 1044848b8605Smrg case GLX_TRANSPARENT_INDEX: 1045848b8605Smrg MATCH_DONT_CARE(transparentIndex); 1046848b8605Smrg break; 1047848b8605Smrg 1048848b8605Smrg default: 1049848b8605Smrg break; 1050848b8605Smrg } 1051848b8605Smrg } 1052848b8605Smrg 1053848b8605Smrg return True; 1054848b8605Smrg} 1055848b8605Smrg 1056848b8605Smrg 1057848b8605Smrg/* There's some trickly language in the GLX spec about how this is supposed 1058848b8605Smrg * to work. Basically, if a given component size is either not specified 1059848b8605Smrg * or the requested size is zero, it is supposed to act like PERFER_SMALLER. 1060848b8605Smrg * Well, that's really hard to do with the code as-is. This behavior is 1061848b8605Smrg * closer to correct, but still not technically right. 1062848b8605Smrg */ 1063848b8605Smrg#define PREFER_LARGER_OR_ZERO(comp) \ 1064848b8605Smrg do { \ 1065848b8605Smrg if ( ((*a)-> comp) != ((*b)-> comp) ) { \ 1066848b8605Smrg if ( ((*a)-> comp) == 0 ) { \ 1067848b8605Smrg return -1; \ 1068848b8605Smrg } \ 1069848b8605Smrg else if ( ((*b)-> comp) == 0 ) { \ 1070848b8605Smrg return 1; \ 1071848b8605Smrg } \ 1072848b8605Smrg else { \ 1073848b8605Smrg return ((*b)-> comp) - ((*a)-> comp) ; \ 1074848b8605Smrg } \ 1075848b8605Smrg } \ 1076848b8605Smrg } while( 0 ) 1077848b8605Smrg 1078848b8605Smrg#define PREFER_LARGER(comp) \ 1079848b8605Smrg do { \ 1080848b8605Smrg if ( ((*a)-> comp) != ((*b)-> comp) ) { \ 1081848b8605Smrg return ((*b)-> comp) - ((*a)-> comp) ; \ 1082848b8605Smrg } \ 1083848b8605Smrg } while( 0 ) 1084848b8605Smrg 1085848b8605Smrg#define PREFER_SMALLER(comp) \ 1086848b8605Smrg do { \ 1087848b8605Smrg if ( ((*a)-> comp) != ((*b)-> comp) ) { \ 1088848b8605Smrg return ((*a)-> comp) - ((*b)-> comp) ; \ 1089848b8605Smrg } \ 1090848b8605Smrg } while( 0 ) 1091848b8605Smrg 1092848b8605Smrg/** 1093848b8605Smrg * Compare two GLXFBConfigs. This function is intended to be used as the 1094848b8605Smrg * compare function passed in to qsort. 1095848b8605Smrg * 1096848b8605Smrg * \returns If \c a is a "better" config, according to the specification of 1097848b8605Smrg * SGIX_fbconfig, a number less than zero is returned. If \c b is 1098848b8605Smrg * better, then a number greater than zero is return. If both are 1099848b8605Smrg * equal, zero is returned. 1100848b8605Smrg * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX 1101848b8605Smrg */ 1102848b8605Smrgstatic int 1103848b8605Smrgfbconfig_compare(struct glx_config **a, struct glx_config **b) 1104848b8605Smrg{ 1105848b8605Smrg /* The order of these comparisons must NOT change. It is defined by 1106848b8605Smrg * the GLX 1.4 specification. 1107848b8605Smrg */ 1108848b8605Smrg 1109848b8605Smrg PREFER_SMALLER(visualSelectGroup); 1110848b8605Smrg 1111848b8605Smrg /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and 1112848b8605Smrg * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the 1113848b8605Smrg * numerical sort order of the enums (0x8000, 0x8001, and 0x800D). 1114848b8605Smrg */ 1115848b8605Smrg PREFER_SMALLER(visualRating); 1116848b8605Smrg 1117848b8605Smrg /* This isn't quite right. It is supposed to compare the sum of the 1118848b8605Smrg * components the user specifically set minimums for. 1119848b8605Smrg */ 1120848b8605Smrg PREFER_LARGER_OR_ZERO(redBits); 1121848b8605Smrg PREFER_LARGER_OR_ZERO(greenBits); 1122848b8605Smrg PREFER_LARGER_OR_ZERO(blueBits); 1123848b8605Smrg PREFER_LARGER_OR_ZERO(alphaBits); 1124848b8605Smrg 1125848b8605Smrg PREFER_SMALLER(rgbBits); 1126848b8605Smrg 1127848b8605Smrg if (((*a)->doubleBufferMode != (*b)->doubleBufferMode)) { 1128848b8605Smrg /* Prefer single-buffer. 1129848b8605Smrg */ 1130848b8605Smrg return (!(*a)->doubleBufferMode) ? -1 : 1; 1131848b8605Smrg } 1132848b8605Smrg 1133848b8605Smrg PREFER_SMALLER(numAuxBuffers); 1134848b8605Smrg 1135848b8605Smrg PREFER_SMALLER(sampleBuffers); 1136848b8605Smrg PREFER_SMALLER(samples); 1137848b8605Smrg 1138848b8605Smrg PREFER_LARGER_OR_ZERO(depthBits); 1139848b8605Smrg PREFER_SMALLER(stencilBits); 1140848b8605Smrg 1141848b8605Smrg /* This isn't quite right. It is supposed to compare the sum of the 1142848b8605Smrg * components the user specifically set minimums for. 1143848b8605Smrg */ 1144848b8605Smrg PREFER_LARGER_OR_ZERO(accumRedBits); 1145848b8605Smrg PREFER_LARGER_OR_ZERO(accumGreenBits); 1146848b8605Smrg PREFER_LARGER_OR_ZERO(accumBlueBits); 1147848b8605Smrg PREFER_LARGER_OR_ZERO(accumAlphaBits); 1148848b8605Smrg 1149848b8605Smrg PREFER_SMALLER(visualType); 1150848b8605Smrg 1151848b8605Smrg /* None of the pbuffer or fbconfig specs say that this comparison needs 1152848b8605Smrg * to happen at all, but it seems like it should. 1153848b8605Smrg */ 1154848b8605Smrg PREFER_LARGER(maxPbufferWidth); 1155848b8605Smrg PREFER_LARGER(maxPbufferHeight); 1156848b8605Smrg PREFER_LARGER(maxPbufferPixels); 1157848b8605Smrg 1158848b8605Smrg return 0; 1159848b8605Smrg} 1160848b8605Smrg 1161848b8605Smrg 1162848b8605Smrg/** 1163848b8605Smrg * Selects and sorts a subset of the supplied configs based on the attributes. 1164848b8605Smrg * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig, 1165848b8605Smrg * and \c glXChooseFBConfigSGIX. 1166848b8605Smrg * 1167848b8605Smrg * \param configs Array of pointers to possible configs. The elements of 1168848b8605Smrg * this array that do not meet the criteria will be set to 1169848b8605Smrg * NULL. The remaining elements will be sorted according to 1170848b8605Smrg * the various visual / FBConfig selection rules. 1171848b8605Smrg * \param num_configs Number of elements in the \c configs array. 1172848b8605Smrg * \param attribList Attributes used select from \c configs. This array is 1173848b8605Smrg * terminated by a \c None tag. The array can either take 1174848b8605Smrg * the form expected by \c glXChooseVisual (where boolean 1175848b8605Smrg * tags do not have a value) or by \c glXChooseFBConfig 1176848b8605Smrg * (where every tag has a value). 1177848b8605Smrg * \param fbconfig_style_tags Selects whether \c attribList is in 1178848b8605Smrg * \c glXChooseVisual style or 1179848b8605Smrg * \c glXChooseFBConfig style. 1180848b8605Smrg * \returns The number of valid elements left in \c configs. 1181848b8605Smrg * 1182848b8605Smrg * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX 1183848b8605Smrg */ 1184848b8605Smrgstatic int 1185848b8605Smrgchoose_visual(struct glx_config ** configs, int num_configs, 1186848b8605Smrg const int *attribList, GLboolean fbconfig_style_tags) 1187848b8605Smrg{ 1188848b8605Smrg struct glx_config test_config; 1189848b8605Smrg int base; 1190848b8605Smrg int i; 1191848b8605Smrg 1192848b8605Smrg /* This is a fairly direct implementation of the selection method 1193848b8605Smrg * described by GLX_SGIX_fbconfig. Start by culling out all the 1194848b8605Smrg * configs that are not compatible with the selected parameter 1195848b8605Smrg * list. 1196848b8605Smrg */ 1197848b8605Smrg 1198848b8605Smrg init_fbconfig_for_chooser(&test_config, fbconfig_style_tags); 1199848b8605Smrg __glXInitializeVisualConfigFromTags(&test_config, 512, 1200848b8605Smrg (const INT32 *) attribList, 1201848b8605Smrg GL_TRUE, fbconfig_style_tags); 1202848b8605Smrg 1203848b8605Smrg base = 0; 1204848b8605Smrg for (i = 0; i < num_configs; i++) { 1205848b8605Smrg if (fbconfigs_compatible(&test_config, configs[i])) { 1206848b8605Smrg configs[base] = configs[i]; 1207848b8605Smrg base++; 1208848b8605Smrg } 1209848b8605Smrg } 1210848b8605Smrg 1211848b8605Smrg if (base == 0) { 1212848b8605Smrg return 0; 1213848b8605Smrg } 1214848b8605Smrg 1215848b8605Smrg if (base < num_configs) { 1216848b8605Smrg (void) memset(&configs[base], 0, sizeof(void *) * (num_configs - base)); 1217848b8605Smrg } 1218848b8605Smrg 1219848b8605Smrg /* After the incompatible configs are removed, the resulting 1220848b8605Smrg * list is sorted according to the rules set out in the various 1221848b8605Smrg * specifications. 1222848b8605Smrg */ 1223848b8605Smrg 1224848b8605Smrg qsort(configs, base, sizeof(struct glx_config *), 1225848b8605Smrg (int (*)(const void *, const void *)) fbconfig_compare); 1226848b8605Smrg return base; 1227848b8605Smrg} 1228848b8605Smrg 1229848b8605Smrg 1230848b8605Smrg 1231848b8605Smrg 1232848b8605Smrg/* 1233848b8605Smrg** Return the visual that best matches the template. Return None if no 1234848b8605Smrg** visual matches the template. 1235848b8605Smrg*/ 1236848b8605Smrg_X_EXPORT XVisualInfo * 1237848b8605SmrgglXChooseVisual(Display * dpy, int screen, int *attribList) 1238848b8605Smrg{ 1239848b8605Smrg XVisualInfo *visualList = NULL; 1240848b8605Smrg struct glx_display *priv; 1241848b8605Smrg struct glx_screen *psc; 1242848b8605Smrg struct glx_config test_config; 1243848b8605Smrg struct glx_config *config; 1244848b8605Smrg struct glx_config *best_config = NULL; 1245848b8605Smrg 1246848b8605Smrg /* 1247848b8605Smrg ** Get a list of all visuals, return if list is empty 1248848b8605Smrg */ 1249848b8605Smrg if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) { 1250848b8605Smrg return None; 1251848b8605Smrg } 1252848b8605Smrg 1253848b8605Smrg 1254848b8605Smrg /* 1255848b8605Smrg ** Build a template from the defaults and the attribute list 1256848b8605Smrg ** Free visual list and return if an unexpected token is encountered 1257848b8605Smrg */ 1258848b8605Smrg init_fbconfig_for_chooser(&test_config, GL_FALSE); 1259848b8605Smrg __glXInitializeVisualConfigFromTags(&test_config, 512, 1260848b8605Smrg (const INT32 *) attribList, 1261848b8605Smrg GL_TRUE, GL_FALSE); 1262848b8605Smrg 1263848b8605Smrg /* 1264848b8605Smrg ** Eliminate visuals that don't meet minimum requirements 1265848b8605Smrg ** Compute a score for those that do 1266848b8605Smrg ** Remember which visual, if any, got the highest score 1267848b8605Smrg ** If no visual is acceptable, return None 1268848b8605Smrg ** Otherwise, create an XVisualInfo list with just the selected X visual 1269848b8605Smrg ** and return this. 1270848b8605Smrg */ 1271848b8605Smrg for (config = psc->visuals; config != NULL; config = config->next) { 1272848b8605Smrg if (fbconfigs_compatible(&test_config, config) 1273848b8605Smrg && ((best_config == NULL) || 1274848b8605Smrg (fbconfig_compare (&config, &best_config) < 0))) { 1275848b8605Smrg XVisualInfo visualTemplate; 1276848b8605Smrg XVisualInfo *newList; 1277848b8605Smrg int i; 1278848b8605Smrg 1279848b8605Smrg visualTemplate.screen = screen; 1280848b8605Smrg visualTemplate.visualid = config->visualID; 1281848b8605Smrg newList = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask, 1282848b8605Smrg &visualTemplate, &i); 1283848b8605Smrg 1284848b8605Smrg if (newList) { 1285848b8605Smrg free(visualList); 1286848b8605Smrg visualList = newList; 1287848b8605Smrg best_config = config; 1288848b8605Smrg } 1289848b8605Smrg } 1290848b8605Smrg } 1291848b8605Smrg 1292848b8605Smrg#ifdef GLX_USE_APPLEGL 1293848b8605Smrg if(visualList && getenv("LIBGL_DUMP_VISUALID")) { 1294848b8605Smrg printf("visualid 0x%lx\n", visualList[0].visualid); 1295848b8605Smrg } 1296848b8605Smrg#endif 1297848b8605Smrg 1298848b8605Smrg return visualList; 1299848b8605Smrg} 1300848b8605Smrg 1301848b8605Smrg 1302848b8605Smrg_X_EXPORT const char * 1303848b8605SmrgglXQueryExtensionsString(Display * dpy, int screen) 1304848b8605Smrg{ 1305848b8605Smrg struct glx_screen *psc; 1306848b8605Smrg struct glx_display *priv; 1307848b8605Smrg 1308848b8605Smrg if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) { 1309848b8605Smrg return NULL; 1310848b8605Smrg } 1311848b8605Smrg 1312848b8605Smrg if (!psc->effectiveGLXexts) { 1313848b8605Smrg if (!psc->serverGLXexts) { 1314848b8605Smrg psc->serverGLXexts = 1315848b8605Smrg __glXQueryServerString(dpy, priv->majorOpcode, screen, 1316848b8605Smrg GLX_EXTENSIONS); 1317848b8605Smrg } 1318848b8605Smrg 1319848b8605Smrg __glXCalculateUsableExtensions(psc, 1320848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 1321848b8605Smrg (psc->driScreen != NULL), 1322848b8605Smrg#else 1323848b8605Smrg GL_FALSE, 1324848b8605Smrg#endif 1325848b8605Smrg priv->minorVersion); 1326848b8605Smrg } 1327848b8605Smrg 1328848b8605Smrg return psc->effectiveGLXexts; 1329848b8605Smrg} 1330848b8605Smrg 1331848b8605Smrg_X_EXPORT const char * 1332848b8605SmrgglXGetClientString(Display * dpy, int name) 1333848b8605Smrg{ 1334848b8605Smrg (void) dpy; 1335848b8605Smrg 1336848b8605Smrg switch (name) { 1337848b8605Smrg case GLX_VENDOR: 1338848b8605Smrg return (__glXGLXClientVendorName); 1339848b8605Smrg case GLX_VERSION: 1340848b8605Smrg return (__glXGLXClientVersion); 1341848b8605Smrg case GLX_EXTENSIONS: 1342848b8605Smrg return (__glXGetClientExtensions()); 1343848b8605Smrg default: 1344848b8605Smrg return NULL; 1345848b8605Smrg } 1346848b8605Smrg} 1347848b8605Smrg 1348848b8605Smrg_X_EXPORT const char * 1349848b8605SmrgglXQueryServerString(Display * dpy, int screen, int name) 1350848b8605Smrg{ 1351848b8605Smrg struct glx_screen *psc; 1352848b8605Smrg struct glx_display *priv; 1353848b8605Smrg const char **str; 1354848b8605Smrg 1355848b8605Smrg 1356848b8605Smrg if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) { 1357848b8605Smrg return NULL; 1358848b8605Smrg } 1359848b8605Smrg 1360848b8605Smrg switch (name) { 1361848b8605Smrg case GLX_VENDOR: 1362848b8605Smrg str = &priv->serverGLXvendor; 1363848b8605Smrg break; 1364848b8605Smrg case GLX_VERSION: 1365848b8605Smrg str = &priv->serverGLXversion; 1366848b8605Smrg break; 1367848b8605Smrg case GLX_EXTENSIONS: 1368848b8605Smrg str = &psc->serverGLXexts; 1369848b8605Smrg break; 1370848b8605Smrg default: 1371848b8605Smrg return NULL; 1372848b8605Smrg } 1373848b8605Smrg 1374848b8605Smrg if (*str == NULL) { 1375848b8605Smrg *str = __glXQueryServerString(dpy, priv->majorOpcode, screen, name); 1376848b8605Smrg } 1377848b8605Smrg 1378848b8605Smrg return *str; 1379848b8605Smrg} 1380848b8605Smrg 1381848b8605Smrg 1382848b8605Smrg/* 1383848b8605Smrg** EXT_import_context 1384848b8605Smrg*/ 1385848b8605Smrg 1386848b8605Smrg_X_EXPORT Display * 1387848b8605SmrgglXGetCurrentDisplay(void) 1388848b8605Smrg{ 1389848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 1390848b8605Smrg if (NULL == gc) 1391848b8605Smrg return NULL; 1392848b8605Smrg return gc->currentDpy; 1393848b8605Smrg} 1394848b8605Smrg 1395848b8605Smrg_X_EXPORT 1396848b8605SmrgGLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (), 1397848b8605Smrg glXGetCurrentDisplay) 1398848b8605Smrg 1399848b8605Smrg#ifndef GLX_USE_APPLEGL 1400848b8605Smrg_X_EXPORT GLXContext 1401848b8605SmrgglXImportContextEXT(Display *dpy, GLXContextID contextID) 1402848b8605Smrg{ 1403848b8605Smrg struct glx_display *priv = __glXInitialize(dpy); 1404848b8605Smrg struct glx_screen *psc = NULL; 1405848b8605Smrg xGLXQueryContextReply reply; 1406848b8605Smrg CARD8 opcode; 1407848b8605Smrg struct glx_context *ctx; 1408848b8605Smrg 1409848b8605Smrg /* This GLX implementation knows about 5 different properties, so 1410848b8605Smrg * allow the server to send us one of each. 1411848b8605Smrg */ 1412848b8605Smrg int propList[5 * 2], *pProp, nPropListBytes; 1413848b8605Smrg int numProps; 1414848b8605Smrg int i, renderType; 1415848b8605Smrg XID share; 1416848b8605Smrg struct glx_config *mode; 1417848b8605Smrg uint32_t fbconfigID = 0; 1418848b8605Smrg uint32_t visualID = 0; 1419848b8605Smrg uint32_t screen = 0; 1420848b8605Smrg Bool got_screen = False; 1421848b8605Smrg 1422848b8605Smrg if (priv == NULL) 1423848b8605Smrg return NULL; 1424848b8605Smrg 1425848b8605Smrg /* The GLX_EXT_import_context spec says: 1426848b8605Smrg * 1427848b8605Smrg * "If <contextID> does not refer to a valid context, then a BadContext 1428848b8605Smrg * error is generated; if <contextID> refers to direct rendering 1429848b8605Smrg * context then no error is generated but glXImportContextEXT returns 1430848b8605Smrg * NULL." 1431848b8605Smrg * 1432848b8605Smrg * If contextID is None, generate BadContext on the client-side. Other 1433848b8605Smrg * sorts of invalid contexts will be detected by the server in the 1434848b8605Smrg * __glXIsDirect call. 1435848b8605Smrg */ 1436848b8605Smrg if (contextID == None) { 1437848b8605Smrg __glXSendError(dpy, GLXBadContext, contextID, X_GLXIsDirect, false); 1438848b8605Smrg return NULL; 1439848b8605Smrg } 1440848b8605Smrg 1441848b8605Smrg if (__glXIsDirect(dpy, contextID)) 1442848b8605Smrg return NULL; 1443848b8605Smrg 1444848b8605Smrg opcode = __glXSetupForCommand(dpy); 1445848b8605Smrg if (!opcode) 1446848b8605Smrg return 0; 1447848b8605Smrg 1448848b8605Smrg /* Send the glXQueryContextInfoEXT request */ 1449848b8605Smrg LockDisplay(dpy); 1450848b8605Smrg 1451848b8605Smrg if (priv->majorVersion > 1 || priv->minorVersion >= 3) { 1452848b8605Smrg xGLXQueryContextReq *req; 1453848b8605Smrg 1454848b8605Smrg GetReq(GLXQueryContext, req); 1455848b8605Smrg 1456848b8605Smrg req->reqType = opcode; 1457848b8605Smrg req->glxCode = X_GLXQueryContext; 1458848b8605Smrg req->context = contextID; 1459848b8605Smrg } 1460848b8605Smrg else { 1461848b8605Smrg xGLXVendorPrivateReq *vpreq; 1462848b8605Smrg xGLXQueryContextInfoEXTReq *req; 1463848b8605Smrg 1464848b8605Smrg GetReqExtra(GLXVendorPrivate, 1465848b8605Smrg sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq, 1466848b8605Smrg vpreq); 1467848b8605Smrg req = (xGLXQueryContextInfoEXTReq *) vpreq; 1468848b8605Smrg req->reqType = opcode; 1469848b8605Smrg req->glxCode = X_GLXVendorPrivateWithReply; 1470848b8605Smrg req->vendorCode = X_GLXvop_QueryContextInfoEXT; 1471848b8605Smrg req->context = contextID; 1472848b8605Smrg } 1473848b8605Smrg 1474848b8605Smrg _XReply(dpy, (xReply *) & reply, 0, False); 1475848b8605Smrg 1476848b8605Smrg if (reply.n <= __GLX_MAX_CONTEXT_PROPS) 1477848b8605Smrg nPropListBytes = reply.n * 2 * sizeof propList[0]; 1478848b8605Smrg else 1479848b8605Smrg nPropListBytes = 0; 1480848b8605Smrg _XRead(dpy, (char *) propList, nPropListBytes); 1481848b8605Smrg UnlockDisplay(dpy); 1482848b8605Smrg SyncHandle(); 1483848b8605Smrg 1484848b8605Smrg numProps = nPropListBytes / (2 * sizeof(propList[0])); 1485848b8605Smrg share = None; 1486848b8605Smrg mode = NULL; 1487848b8605Smrg renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */ 1488848b8605Smrg pProp = propList; 1489848b8605Smrg 1490848b8605Smrg for (i = 0, pProp = propList; i < numProps; i++, pProp += 2) 1491848b8605Smrg switch (pProp[0]) { 1492848b8605Smrg case GLX_SCREEN: 1493848b8605Smrg screen = pProp[1]; 1494848b8605Smrg got_screen = True; 1495848b8605Smrg break; 1496848b8605Smrg case GLX_SHARE_CONTEXT_EXT: 1497848b8605Smrg share = pProp[1]; 1498848b8605Smrg break; 1499848b8605Smrg case GLX_VISUAL_ID_EXT: 1500848b8605Smrg visualID = pProp[1]; 1501848b8605Smrg break; 1502848b8605Smrg case GLX_FBCONFIG_ID: 1503848b8605Smrg fbconfigID = pProp[1]; 1504848b8605Smrg break; 1505848b8605Smrg case GLX_RENDER_TYPE: 1506848b8605Smrg renderType = pProp[1]; 1507848b8605Smrg break; 1508848b8605Smrg } 1509848b8605Smrg 1510848b8605Smrg if (!got_screen) 1511848b8605Smrg return NULL; 1512848b8605Smrg 1513848b8605Smrg psc = GetGLXScreenConfigs(dpy, screen); 1514848b8605Smrg if (psc == NULL) 1515848b8605Smrg return NULL; 1516848b8605Smrg 1517848b8605Smrg if (fbconfigID != 0) { 1518848b8605Smrg mode = glx_config_find_fbconfig(psc->configs, fbconfigID); 1519848b8605Smrg } else if (visualID != 0) { 1520848b8605Smrg mode = glx_config_find_visual(psc->visuals, visualID); 1521848b8605Smrg } 1522848b8605Smrg 1523848b8605Smrg if (mode == NULL) 1524848b8605Smrg return NULL; 1525848b8605Smrg 1526848b8605Smrg ctx = indirect_create_context(psc, mode, NULL, renderType); 1527848b8605Smrg if (ctx == NULL) 1528848b8605Smrg return NULL; 1529848b8605Smrg 1530848b8605Smrg ctx->xid = contextID; 1531848b8605Smrg ctx->imported = GL_TRUE; 1532848b8605Smrg ctx->share_xid = share; 1533848b8605Smrg 1534848b8605Smrg return (GLXContext) ctx; 1535848b8605Smrg} 1536848b8605Smrg 1537848b8605Smrg#endif 1538848b8605Smrg 1539848b8605Smrg_X_EXPORT int 1540848b8605SmrgglXQueryContext(Display * dpy, GLXContext ctx_user, int attribute, int *value) 1541848b8605Smrg{ 1542848b8605Smrg struct glx_context *ctx = (struct glx_context *) ctx_user; 1543848b8605Smrg 1544848b8605Smrg switch (attribute) { 1545848b8605Smrg case GLX_SHARE_CONTEXT_EXT: 1546848b8605Smrg *value = ctx->share_xid; 1547848b8605Smrg break; 1548848b8605Smrg case GLX_VISUAL_ID_EXT: 1549848b8605Smrg *value = ctx->config ? ctx->config->visualID : None; 1550848b8605Smrg break; 1551848b8605Smrg case GLX_SCREEN: 1552848b8605Smrg *value = ctx->screen; 1553848b8605Smrg break; 1554848b8605Smrg case GLX_FBCONFIG_ID: 1555848b8605Smrg *value = ctx->config ? ctx->config->fbconfigID : None; 1556848b8605Smrg break; 1557848b8605Smrg case GLX_RENDER_TYPE: 1558848b8605Smrg *value = ctx->renderType; 1559848b8605Smrg break; 1560848b8605Smrg default: 1561848b8605Smrg return GLX_BAD_ATTRIBUTE; 1562848b8605Smrg } 1563848b8605Smrg return Success; 1564848b8605Smrg} 1565848b8605Smrg 1566848b8605Smrg_X_EXPORT 1567848b8605SmrgGLX_ALIAS(int, glXQueryContextInfoEXT, 1568848b8605Smrg (Display * dpy, GLXContext ctx, int attribute, int *value), 1569848b8605Smrg (dpy, ctx, attribute, value), glXQueryContext) 1570848b8605Smrg 1571848b8605Smrg_X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user) 1572848b8605Smrg{ 1573848b8605Smrg struct glx_context *ctx = (struct glx_context *) ctx_user; 1574848b8605Smrg 1575848b8605Smrg return (ctx == NULL) ? None : ctx->xid; 1576848b8605Smrg} 1577848b8605Smrg 1578848b8605Smrg_X_EXPORT void 1579848b8605SmrgglXFreeContextEXT(Display *dpy, GLXContext ctx) 1580848b8605Smrg{ 1581848b8605Smrg struct glx_context *gc = (struct glx_context *) ctx; 1582848b8605Smrg 1583848b8605Smrg if (gc == NULL || gc->xid == None) 1584848b8605Smrg return; 1585848b8605Smrg 1586848b8605Smrg /* The GLX_EXT_import_context spec says: 1587848b8605Smrg * 1588848b8605Smrg * "glXFreeContext does not free the server-side context information or 1589848b8605Smrg * the XID associated with the server-side context." 1590848b8605Smrg * 1591848b8605Smrg * Don't send any protocol. Just destroy the client-side tracking of the 1592848b8605Smrg * context. Also, only release the context structure if it's not current. 1593848b8605Smrg */ 1594848b8605Smrg __glXLock(); 1595848b8605Smrg if (gc->currentDpy) { 1596848b8605Smrg gc->xid = None; 1597848b8605Smrg } else { 1598848b8605Smrg gc->vtable->destroy(gc); 1599848b8605Smrg } 1600848b8605Smrg __glXUnlock(); 1601848b8605Smrg} 1602848b8605Smrg 1603848b8605Smrg_X_EXPORT GLXFBConfig * 1604848b8605SmrgglXChooseFBConfig(Display * dpy, int screen, 1605848b8605Smrg const int *attribList, int *nitems) 1606848b8605Smrg{ 1607848b8605Smrg struct glx_config **config_list; 1608848b8605Smrg int list_size; 1609848b8605Smrg 1610848b8605Smrg 1611848b8605Smrg config_list = (struct glx_config **) 1612848b8605Smrg glXGetFBConfigs(dpy, screen, &list_size); 1613848b8605Smrg 1614848b8605Smrg if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) { 1615848b8605Smrg list_size = choose_visual(config_list, list_size, attribList, GL_TRUE); 1616848b8605Smrg if (list_size == 0) { 1617848b8605Smrg free(config_list); 1618848b8605Smrg config_list = NULL; 1619848b8605Smrg } 1620848b8605Smrg } 1621848b8605Smrg 1622848b8605Smrg *nitems = list_size; 1623848b8605Smrg return (GLXFBConfig *) config_list; 1624848b8605Smrg} 1625848b8605Smrg 1626848b8605Smrg 1627848b8605Smrg_X_EXPORT GLXContext 1628848b8605SmrgglXCreateNewContext(Display * dpy, GLXFBConfig fbconfig, 1629848b8605Smrg int renderType, GLXContext shareList, Bool allowDirect) 1630848b8605Smrg{ 1631848b8605Smrg struct glx_config *config = (struct glx_config *) fbconfig; 1632848b8605Smrg 1633848b8605Smrg return CreateContext(dpy, config->fbconfigID, config, shareList, 1634848b8605Smrg allowDirect, X_GLXCreateNewContext, renderType, 1635848b8605Smrg config->screen); 1636848b8605Smrg} 1637848b8605Smrg 1638848b8605Smrg 1639848b8605Smrg_X_EXPORT GLXDrawable 1640848b8605SmrgglXGetCurrentReadDrawable(void) 1641848b8605Smrg{ 1642848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 1643848b8605Smrg 1644848b8605Smrg return gc->currentReadable; 1645848b8605Smrg} 1646848b8605Smrg 1647848b8605Smrg 1648848b8605Smrg_X_EXPORT GLXFBConfig * 1649848b8605SmrgglXGetFBConfigs(Display * dpy, int screen, int *nelements) 1650848b8605Smrg{ 1651848b8605Smrg struct glx_display *priv = __glXInitialize(dpy); 1652848b8605Smrg struct glx_config **config_list = NULL; 1653848b8605Smrg struct glx_config *config; 1654848b8605Smrg unsigned num_configs = 0; 1655848b8605Smrg int i; 1656848b8605Smrg 1657848b8605Smrg *nelements = 0; 1658848b8605Smrg if (priv && (priv->screens != NULL) 1659848b8605Smrg && (screen >= 0) && (screen <= ScreenCount(dpy)) 1660848b8605Smrg && (priv->screens[screen]->configs != NULL) 1661848b8605Smrg && (priv->screens[screen]->configs->fbconfigID 1662848b8605Smrg != (int) GLX_DONT_CARE)) { 1663848b8605Smrg 1664848b8605Smrg for (config = priv->screens[screen]->configs; config != NULL; 1665848b8605Smrg config = config->next) { 1666848b8605Smrg if (config->fbconfigID != (int) GLX_DONT_CARE) { 1667848b8605Smrg num_configs++; 1668848b8605Smrg } 1669848b8605Smrg } 1670848b8605Smrg 1671848b8605Smrg config_list = malloc(num_configs * sizeof *config_list); 1672848b8605Smrg if (config_list != NULL) { 1673848b8605Smrg *nelements = num_configs; 1674848b8605Smrg i = 0; 1675848b8605Smrg for (config = priv->screens[screen]->configs; config != NULL; 1676848b8605Smrg config = config->next) { 1677848b8605Smrg if (config->fbconfigID != (int) GLX_DONT_CARE) { 1678848b8605Smrg config_list[i] = config; 1679848b8605Smrg i++; 1680848b8605Smrg } 1681848b8605Smrg } 1682848b8605Smrg } 1683848b8605Smrg } 1684848b8605Smrg 1685848b8605Smrg return (GLXFBConfig *) config_list; 1686848b8605Smrg} 1687848b8605Smrg 1688848b8605Smrg 1689848b8605Smrg_X_EXPORT int 1690848b8605SmrgglXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig, 1691848b8605Smrg int attribute, int *value) 1692848b8605Smrg{ 1693848b8605Smrg struct glx_config *config = ValidateGLXFBConfig(dpy, fbconfig); 1694848b8605Smrg 1695848b8605Smrg if (config == NULL) 1696848b8605Smrg return GLXBadFBConfig; 1697848b8605Smrg 1698848b8605Smrg return glx_config_get(config, attribute, value); 1699848b8605Smrg} 1700848b8605Smrg 1701848b8605Smrg 1702848b8605Smrg_X_EXPORT XVisualInfo * 1703848b8605SmrgglXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig) 1704848b8605Smrg{ 1705848b8605Smrg XVisualInfo visualTemplate; 1706848b8605Smrg struct glx_config *config = (struct glx_config *) fbconfig; 1707848b8605Smrg int count; 1708848b8605Smrg 1709848b8605Smrg /* 1710848b8605Smrg ** Get a list of all visuals, return if list is empty 1711848b8605Smrg */ 1712848b8605Smrg visualTemplate.visualid = config->visualID; 1713848b8605Smrg return XGetVisualInfo(dpy, VisualIDMask, &visualTemplate, &count); 1714848b8605Smrg} 1715848b8605Smrg 1716848b8605Smrg#ifndef GLX_USE_APPLEGL 1717848b8605Smrg/* 1718848b8605Smrg** GLX_SGI_swap_control 1719848b8605Smrg*/ 1720848b8605Smrgstatic int 1721848b8605Smrg__glXSwapIntervalSGI(int interval) 1722848b8605Smrg{ 1723848b8605Smrg xGLXVendorPrivateReq *req; 1724848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 1725848b8605Smrg struct glx_screen *psc; 1726848b8605Smrg Display *dpy; 1727848b8605Smrg CARD32 *interval_ptr; 1728848b8605Smrg CARD8 opcode; 1729848b8605Smrg 1730848b8605Smrg if (gc == NULL) { 1731848b8605Smrg return GLX_BAD_CONTEXT; 1732848b8605Smrg } 1733848b8605Smrg 1734848b8605Smrg if (interval <= 0) { 1735848b8605Smrg return GLX_BAD_VALUE; 1736848b8605Smrg } 1737848b8605Smrg 1738848b8605Smrg psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); 1739848b8605Smrg 1740848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1741848b8605Smrg if (gc->isDirect && psc && psc->driScreen && 1742848b8605Smrg psc->driScreen->setSwapInterval) { 1743848b8605Smrg __GLXDRIdrawable *pdraw = 1744848b8605Smrg GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); 1745848b8605Smrg psc->driScreen->setSwapInterval(pdraw, interval); 1746848b8605Smrg return 0; 1747848b8605Smrg } 1748848b8605Smrg#endif 1749848b8605Smrg 1750848b8605Smrg dpy = gc->currentDpy; 1751848b8605Smrg opcode = __glXSetupForCommand(dpy); 1752848b8605Smrg if (!opcode) { 1753848b8605Smrg return 0; 1754848b8605Smrg } 1755848b8605Smrg 1756848b8605Smrg /* Send the glXSwapIntervalSGI request */ 1757848b8605Smrg LockDisplay(dpy); 1758848b8605Smrg GetReqExtra(GLXVendorPrivate, sizeof(CARD32), req); 1759848b8605Smrg req->reqType = opcode; 1760848b8605Smrg req->glxCode = X_GLXVendorPrivate; 1761848b8605Smrg req->vendorCode = X_GLXvop_SwapIntervalSGI; 1762848b8605Smrg req->contextTag = gc->currentContextTag; 1763848b8605Smrg 1764848b8605Smrg interval_ptr = (CARD32 *) (req + 1); 1765848b8605Smrg *interval_ptr = interval; 1766848b8605Smrg 1767848b8605Smrg UnlockDisplay(dpy); 1768848b8605Smrg SyncHandle(); 1769848b8605Smrg XFlush(dpy); 1770848b8605Smrg 1771848b8605Smrg return 0; 1772848b8605Smrg} 1773848b8605Smrg 1774848b8605Smrg 1775848b8605Smrg/* 1776848b8605Smrg** GLX_MESA_swap_control 1777848b8605Smrg*/ 1778848b8605Smrgstatic int 1779848b8605Smrg__glXSwapIntervalMESA(unsigned int interval) 1780848b8605Smrg{ 1781848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1782848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 1783848b8605Smrg 1784848b8605Smrg if (gc != NULL && gc->isDirect) { 1785848b8605Smrg struct glx_screen *psc; 1786848b8605Smrg 1787848b8605Smrg psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); 1788848b8605Smrg if (psc && psc->driScreen && psc->driScreen->setSwapInterval) { 1789848b8605Smrg __GLXDRIdrawable *pdraw = 1790848b8605Smrg GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); 1791848b8605Smrg return psc->driScreen->setSwapInterval(pdraw, interval); 1792848b8605Smrg } 1793848b8605Smrg } 1794848b8605Smrg#endif 1795848b8605Smrg 1796848b8605Smrg return GLX_BAD_CONTEXT; 1797848b8605Smrg} 1798848b8605Smrg 1799848b8605Smrg 1800848b8605Smrgstatic int 1801848b8605Smrg__glXGetSwapIntervalMESA(void) 1802848b8605Smrg{ 1803848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1804848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 1805848b8605Smrg 1806848b8605Smrg if (gc != NULL && gc->isDirect) { 1807848b8605Smrg struct glx_screen *psc; 1808848b8605Smrg 1809848b8605Smrg psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); 1810848b8605Smrg if (psc && psc->driScreen && psc->driScreen->getSwapInterval) { 1811848b8605Smrg __GLXDRIdrawable *pdraw = 1812848b8605Smrg GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); 1813848b8605Smrg return psc->driScreen->getSwapInterval(pdraw); 1814848b8605Smrg } 1815848b8605Smrg } 1816848b8605Smrg#endif 1817848b8605Smrg 1818848b8605Smrg return 0; 1819848b8605Smrg} 1820848b8605Smrg 1821848b8605Smrg 1822848b8605Smrg/* 1823848b8605Smrg** GLX_SGI_video_sync 1824848b8605Smrg*/ 1825848b8605Smrgstatic int 1826848b8605Smrg__glXGetVideoSyncSGI(unsigned int *count) 1827848b8605Smrg{ 1828848b8605Smrg int64_t ust, msc, sbc; 1829848b8605Smrg int ret; 1830848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 1831848b8605Smrg struct glx_screen *psc; 1832848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1833848b8605Smrg __GLXDRIdrawable *pdraw; 1834848b8605Smrg#endif 1835848b8605Smrg 1836848b8605Smrg if (!gc) 1837848b8605Smrg return GLX_BAD_CONTEXT; 1838848b8605Smrg 1839848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1840848b8605Smrg if (!gc->isDirect) 1841848b8605Smrg return GLX_BAD_CONTEXT; 1842848b8605Smrg#endif 1843848b8605Smrg 1844848b8605Smrg psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen); 1845848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1846848b8605Smrg pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); 1847848b8605Smrg#endif 1848848b8605Smrg 1849848b8605Smrg /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry, 1850848b8605Smrg * FIXME: there should be a GLX encoding for this call. I can find no 1851848b8605Smrg * FIXME: documentation for the GLX encoding. 1852848b8605Smrg */ 1853848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1854848b8605Smrg if (psc && psc->driScreen && psc->driScreen->getDrawableMSC) { 1855848b8605Smrg ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc); 1856848b8605Smrg *count = (unsigned) msc; 1857848b8605Smrg return (ret == True) ? 0 : GLX_BAD_CONTEXT; 1858848b8605Smrg } 1859848b8605Smrg#endif 1860848b8605Smrg 1861848b8605Smrg return GLX_BAD_CONTEXT; 1862848b8605Smrg} 1863848b8605Smrg 1864848b8605Smrgstatic int 1865848b8605Smrg__glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) 1866848b8605Smrg{ 1867848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 1868848b8605Smrg struct glx_screen *psc; 1869848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1870848b8605Smrg __GLXDRIdrawable *pdraw; 1871848b8605Smrg#endif 1872848b8605Smrg int64_t ust, msc, sbc; 1873848b8605Smrg int ret; 1874848b8605Smrg 1875848b8605Smrg if (divisor <= 0 || remainder < 0) 1876848b8605Smrg return GLX_BAD_VALUE; 1877848b8605Smrg 1878848b8605Smrg if (!gc) 1879848b8605Smrg return GLX_BAD_CONTEXT; 1880848b8605Smrg 1881848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1882848b8605Smrg if (!gc->isDirect) 1883848b8605Smrg return GLX_BAD_CONTEXT; 1884848b8605Smrg#endif 1885848b8605Smrg 1886848b8605Smrg psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); 1887848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1888848b8605Smrg pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); 1889848b8605Smrg#endif 1890848b8605Smrg 1891848b8605Smrg#ifdef GLX_DIRECT_RENDERING 1892848b8605Smrg if (psc && psc->driScreen && psc->driScreen->waitForMSC) { 1893848b8605Smrg ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc, 1894848b8605Smrg &sbc); 1895848b8605Smrg *count = (unsigned) msc; 1896848b8605Smrg return (ret == True) ? 0 : GLX_BAD_CONTEXT; 1897848b8605Smrg } 1898848b8605Smrg#endif 1899848b8605Smrg 1900848b8605Smrg return GLX_BAD_CONTEXT; 1901848b8605Smrg} 1902848b8605Smrg 1903848b8605Smrg#endif /* GLX_USE_APPLEGL */ 1904848b8605Smrg 1905848b8605Smrg/* 1906848b8605Smrg** GLX_SGIX_fbconfig 1907848b8605Smrg** Many of these functions are aliased to GLX 1.3 entry points in the 1908848b8605Smrg** GLX_functions table. 1909848b8605Smrg*/ 1910848b8605Smrg 1911848b8605Smrg_X_EXPORT 1912848b8605SmrgGLX_ALIAS(int, glXGetFBConfigAttribSGIX, 1913848b8605Smrg (Display * dpy, GLXFBConfigSGIX config, int attribute, int *value), 1914848b8605Smrg (dpy, config, attribute, value), glXGetFBConfigAttrib) 1915848b8605Smrg 1916848b8605Smrg_X_EXPORT GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX, 1917848b8605Smrg (Display * dpy, int screen, int *attrib_list, 1918848b8605Smrg int *nelements), (dpy, screen, attrib_list, nelements), 1919848b8605Smrg glXChooseFBConfig) 1920848b8605Smrg 1921848b8605Smrg_X_EXPORT GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX, 1922848b8605Smrg (Display * dpy, GLXFBConfigSGIX config), 1923848b8605Smrg (dpy, config), glXGetVisualFromFBConfig) 1924848b8605Smrg 1925848b8605Smrg_X_EXPORT GLXPixmap 1926848b8605SmrgglXCreateGLXPixmapWithConfigSGIX(Display * dpy, 1927848b8605Smrg GLXFBConfigSGIX fbconfig, 1928848b8605Smrg Pixmap pixmap) 1929848b8605Smrg{ 1930848b8605Smrg#ifndef GLX_USE_APPLEGL 1931848b8605Smrg xGLXVendorPrivateWithReplyReq *vpreq; 1932848b8605Smrg xGLXCreateGLXPixmapWithConfigSGIXReq *req; 1933848b8605Smrg GLXPixmap xid = None; 1934848b8605Smrg CARD8 opcode; 1935848b8605Smrg struct glx_screen *psc; 1936848b8605Smrg#endif 1937848b8605Smrg struct glx_config *config = (struct glx_config *) fbconfig; 1938848b8605Smrg 1939848b8605Smrg 1940848b8605Smrg if ((dpy == NULL) || (config == NULL)) { 1941848b8605Smrg return None; 1942848b8605Smrg } 1943848b8605Smrg#ifdef GLX_USE_APPLEGL 1944848b8605Smrg if(apple_glx_pixmap_create(dpy, config->screen, pixmap, config)) 1945848b8605Smrg return None; 1946848b8605Smrg return pixmap; 1947848b8605Smrg#else 1948848b8605Smrg 1949848b8605Smrg psc = GetGLXScreenConfigs(dpy, config->screen); 1950848b8605Smrg if ((psc != NULL) 1951848b8605Smrg && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) { 1952848b8605Smrg opcode = __glXSetupForCommand(dpy); 1953848b8605Smrg if (!opcode) { 1954848b8605Smrg return None; 1955848b8605Smrg } 1956848b8605Smrg 1957848b8605Smrg /* Send the glXCreateGLXPixmapWithConfigSGIX request */ 1958848b8605Smrg LockDisplay(dpy); 1959848b8605Smrg GetReqExtra(GLXVendorPrivateWithReply, 1960848b8605Smrg sz_xGLXCreateGLXPixmapWithConfigSGIXReq - 1961848b8605Smrg sz_xGLXVendorPrivateWithReplyReq, vpreq); 1962848b8605Smrg req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) vpreq; 1963848b8605Smrg req->reqType = opcode; 1964848b8605Smrg req->glxCode = X_GLXVendorPrivateWithReply; 1965848b8605Smrg req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; 1966848b8605Smrg req->screen = config->screen; 1967848b8605Smrg req->fbconfig = config->fbconfigID; 1968848b8605Smrg req->pixmap = pixmap; 1969848b8605Smrg req->glxpixmap = xid = XAllocID(dpy); 1970848b8605Smrg UnlockDisplay(dpy); 1971848b8605Smrg SyncHandle(); 1972848b8605Smrg } 1973848b8605Smrg 1974848b8605Smrg return xid; 1975848b8605Smrg#endif 1976848b8605Smrg} 1977848b8605Smrg 1978848b8605Smrg_X_EXPORT GLXContext 1979848b8605SmrgglXCreateContextWithConfigSGIX(Display * dpy, 1980848b8605Smrg GLXFBConfigSGIX fbconfig, int renderType, 1981848b8605Smrg GLXContext shareList, Bool allowDirect) 1982848b8605Smrg{ 1983848b8605Smrg GLXContext gc = NULL; 1984848b8605Smrg struct glx_config *config = (struct glx_config *) fbconfig; 1985848b8605Smrg struct glx_screen *psc; 1986848b8605Smrg 1987848b8605Smrg 1988848b8605Smrg if ((dpy == NULL) || (config == NULL)) { 1989848b8605Smrg return None; 1990848b8605Smrg } 1991848b8605Smrg 1992848b8605Smrg psc = GetGLXScreenConfigs(dpy, config->screen); 1993848b8605Smrg if ((psc != NULL) 1994848b8605Smrg && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) { 1995848b8605Smrg gc = CreateContext(dpy, config->fbconfigID, config, shareList, 1996848b8605Smrg allowDirect, 1997848b8605Smrg X_GLXvop_CreateContextWithConfigSGIX, renderType, 1998848b8605Smrg config->screen); 1999848b8605Smrg } 2000848b8605Smrg 2001848b8605Smrg return gc; 2002848b8605Smrg} 2003848b8605Smrg 2004848b8605Smrg 2005848b8605Smrg_X_EXPORT GLXFBConfigSGIX 2006848b8605SmrgglXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis) 2007848b8605Smrg{ 2008848b8605Smrg struct glx_display *priv; 2009848b8605Smrg struct glx_screen *psc = NULL; 2010848b8605Smrg 2011848b8605Smrg if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) == Success) 2012848b8605Smrg && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit) 2013848b8605Smrg && (psc->configs->fbconfigID != (int) GLX_DONT_CARE)) { 2014848b8605Smrg return (GLXFBConfigSGIX) glx_config_find_visual(psc->configs, 2015848b8605Smrg vis->visualid); 2016848b8605Smrg } 2017848b8605Smrg 2018848b8605Smrg return NULL; 2019848b8605Smrg} 2020848b8605Smrg 2021848b8605Smrg#ifndef GLX_USE_APPLEGL 2022848b8605Smrg/* 2023848b8605Smrg** GLX_SGIX_swap_group 2024848b8605Smrg*/ 2025848b8605Smrgstatic void 2026848b8605Smrg__glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable, 2027848b8605Smrg GLXDrawable member) 2028848b8605Smrg{ 2029848b8605Smrg (void) dpy; 2030848b8605Smrg (void) drawable; 2031848b8605Smrg (void) member; 2032848b8605Smrg} 2033848b8605Smrg 2034848b8605Smrg 2035848b8605Smrg/* 2036848b8605Smrg** GLX_SGIX_swap_barrier 2037848b8605Smrg*/ 2038848b8605Smrgstatic void 2039848b8605Smrg__glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier) 2040848b8605Smrg{ 2041848b8605Smrg (void) dpy; 2042848b8605Smrg (void) drawable; 2043848b8605Smrg (void) barrier; 2044848b8605Smrg} 2045848b8605Smrg 2046848b8605Smrgstatic Bool 2047848b8605Smrg__glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int *max) 2048848b8605Smrg{ 2049848b8605Smrg (void) dpy; 2050848b8605Smrg (void) screen; 2051848b8605Smrg (void) max; 2052848b8605Smrg return False; 2053848b8605Smrg} 2054848b8605Smrg 2055848b8605Smrg 2056848b8605Smrg/* 2057848b8605Smrg** GLX_OML_sync_control 2058848b8605Smrg*/ 2059848b8605Smrgstatic Bool 2060848b8605Smrg__glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable, 2061848b8605Smrg int64_t * ust, int64_t * msc, int64_t * sbc) 2062848b8605Smrg{ 2063848b8605Smrg struct glx_display * const priv = __glXInitialize(dpy); 2064848b8605Smrg int ret; 2065848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2066848b8605Smrg __GLXDRIdrawable *pdraw; 2067848b8605Smrg#endif 2068848b8605Smrg struct glx_screen *psc; 2069848b8605Smrg 2070848b8605Smrg if (!priv) 2071848b8605Smrg return False; 2072848b8605Smrg 2073848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2074848b8605Smrg pdraw = GetGLXDRIDrawable(dpy, drawable); 2075848b8605Smrg psc = pdraw ? pdraw->psc : NULL; 2076848b8605Smrg if (pdraw && psc->driScreen->getDrawableMSC) { 2077848b8605Smrg ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc); 2078848b8605Smrg return ret; 2079848b8605Smrg } 2080848b8605Smrg#endif 2081848b8605Smrg 2082848b8605Smrg return False; 2083848b8605Smrg} 2084848b8605Smrg 2085848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 2086848b8605Smrg_X_HIDDEN GLboolean 2087848b8605Smrg__glxGetMscRate(struct glx_screen *psc, 2088848b8605Smrg int32_t * numerator, int32_t * denominator) 2089848b8605Smrg{ 2090848b8605Smrg#ifdef XF86VIDMODE 2091848b8605Smrg XF86VidModeModeLine mode_line; 2092848b8605Smrg int dot_clock; 2093848b8605Smrg int i; 2094848b8605Smrg 2095848b8605Smrg if (XF86VidModeQueryVersion(psc->dpy, &i, &i) && 2096848b8605Smrg XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line)) { 2097848b8605Smrg unsigned n = dot_clock * 1000; 2098848b8605Smrg unsigned d = mode_line.vtotal * mode_line.htotal; 2099848b8605Smrg 2100848b8605Smrg# define V_INTERLACE 0x010 2101848b8605Smrg# define V_DBLSCAN 0x020 2102848b8605Smrg 2103848b8605Smrg if (mode_line.flags & V_INTERLACE) 2104848b8605Smrg n *= 2; 2105848b8605Smrg else if (mode_line.flags & V_DBLSCAN) 2106848b8605Smrg d *= 2; 2107848b8605Smrg 2108848b8605Smrg /* The OML_sync_control spec requires that if the refresh rate is a 2109848b8605Smrg * whole number, that the returned numerator be equal to the refresh 2110848b8605Smrg * rate and the denominator be 1. 2111848b8605Smrg */ 2112848b8605Smrg 2113848b8605Smrg if (n % d == 0) { 2114848b8605Smrg n /= d; 2115848b8605Smrg d = 1; 2116848b8605Smrg } 2117848b8605Smrg else { 2118848b8605Smrg static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 }; 2119848b8605Smrg 2120848b8605Smrg /* This is a poor man's way to reduce a fraction. It's far from 2121848b8605Smrg * perfect, but it will work well enough for this situation. 2122848b8605Smrg */ 2123848b8605Smrg 2124848b8605Smrg for (i = 0; f[i] != 0; i++) { 2125848b8605Smrg while (n % f[i] == 0 && d % f[i] == 0) { 2126848b8605Smrg d /= f[i]; 2127848b8605Smrg n /= f[i]; 2128848b8605Smrg } 2129848b8605Smrg } 2130848b8605Smrg } 2131848b8605Smrg 2132848b8605Smrg *numerator = n; 2133848b8605Smrg *denominator = d; 2134848b8605Smrg 2135848b8605Smrg return True; 2136848b8605Smrg } 2137848b8605Smrg else 2138848b8605Smrg#endif 2139848b8605Smrg 2140848b8605Smrg return False; 2141848b8605Smrg} 2142848b8605Smrg#endif 2143848b8605Smrg 2144848b8605Smrg/** 2145848b8605Smrg * Determine the refresh rate of the specified drawable and display. 2146848b8605Smrg * 2147848b8605Smrg * \param dpy Display whose refresh rate is to be determined. 2148848b8605Smrg * \param drawable Drawable whose refresh rate is to be determined. 2149848b8605Smrg * \param numerator Numerator of the refresh rate. 2150848b8605Smrg * \param demoninator Denominator of the refresh rate. 2151848b8605Smrg * \return If the refresh rate for the specified display and drawable could 2152848b8605Smrg * be calculated, True is returned. Otherwise False is returned. 2153848b8605Smrg * 2154848b8605Smrg * \note This function is implemented entirely client-side. A lot of other 2155848b8605Smrg * functionality is required to export GLX_OML_sync_control, so on 2156848b8605Smrg * XFree86 this function can be called for direct-rendering contexts 2157848b8605Smrg * when GLX_OML_sync_control appears in the client extension string. 2158848b8605Smrg */ 2159848b8605Smrg 2160848b8605Smrg_X_HIDDEN GLboolean 2161848b8605Smrg__glXGetMscRateOML(Display * dpy, GLXDrawable drawable, 2162848b8605Smrg int32_t * numerator, int32_t * denominator) 2163848b8605Smrg{ 2164848b8605Smrg#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE ) 2165848b8605Smrg __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable); 2166848b8605Smrg 2167848b8605Smrg if (draw == NULL) 2168848b8605Smrg return False; 2169848b8605Smrg 2170848b8605Smrg return __glxGetMscRate(draw->psc, numerator, denominator); 2171848b8605Smrg#else 2172848b8605Smrg (void) dpy; 2173848b8605Smrg (void) drawable; 2174848b8605Smrg (void) numerator; 2175848b8605Smrg (void) denominator; 2176848b8605Smrg#endif 2177848b8605Smrg return False; 2178848b8605Smrg} 2179848b8605Smrg 2180848b8605Smrg 2181848b8605Smrgstatic int64_t 2182848b8605Smrg__glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, 2183848b8605Smrg int64_t target_msc, int64_t divisor, int64_t remainder) 2184848b8605Smrg{ 2185848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 2186848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2187848b8605Smrg __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); 2188848b8605Smrg struct glx_screen *psc = pdraw ? pdraw->psc : NULL; 2189848b8605Smrg#endif 2190848b8605Smrg 2191848b8605Smrg if (!gc) /* no GLX for this */ 2192848b8605Smrg return -1; 2193848b8605Smrg 2194848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2195848b8605Smrg if (!pdraw || !gc->isDirect) 2196848b8605Smrg return -1; 2197848b8605Smrg#endif 2198848b8605Smrg 2199848b8605Smrg /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE 2200848b8605Smrg * error", but it also says "It [glXSwapBuffersMscOML] will return a value 2201848b8605Smrg * of -1 if the function failed because of errors detected in the input 2202848b8605Smrg * parameters" 2203848b8605Smrg */ 2204848b8605Smrg if (divisor < 0 || remainder < 0 || target_msc < 0) 2205848b8605Smrg return -1; 2206848b8605Smrg if (divisor > 0 && remainder >= divisor) 2207848b8605Smrg return -1; 2208848b8605Smrg 2209848b8605Smrg if (target_msc == 0 && divisor == 0 && remainder == 0) 2210848b8605Smrg remainder = 1; 2211848b8605Smrg 2212848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2213848b8605Smrg if (psc->driScreen && psc->driScreen->swapBuffers) 2214848b8605Smrg return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor, 2215848b8605Smrg remainder, False); 2216848b8605Smrg#endif 2217848b8605Smrg 2218848b8605Smrg return -1; 2219848b8605Smrg} 2220848b8605Smrg 2221848b8605Smrg 2222848b8605Smrgstatic Bool 2223848b8605Smrg__glXWaitForMscOML(Display * dpy, GLXDrawable drawable, 2224848b8605Smrg int64_t target_msc, int64_t divisor, 2225848b8605Smrg int64_t remainder, int64_t * ust, 2226848b8605Smrg int64_t * msc, int64_t * sbc) 2227848b8605Smrg{ 2228848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2229848b8605Smrg __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); 2230848b8605Smrg struct glx_screen *psc = pdraw ? pdraw->psc : NULL; 2231848b8605Smrg int ret; 2232848b8605Smrg#endif 2233848b8605Smrg 2234848b8605Smrg 2235848b8605Smrg /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE 2236848b8605Smrg * error", but the return type in the spec is Bool. 2237848b8605Smrg */ 2238848b8605Smrg if (divisor < 0 || remainder < 0 || target_msc < 0) 2239848b8605Smrg return False; 2240848b8605Smrg if (divisor > 0 && remainder >= divisor) 2241848b8605Smrg return False; 2242848b8605Smrg 2243848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2244848b8605Smrg if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) { 2245848b8605Smrg ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder, 2246848b8605Smrg ust, msc, sbc); 2247848b8605Smrg return ret; 2248848b8605Smrg } 2249848b8605Smrg#endif 2250848b8605Smrg 2251848b8605Smrg return False; 2252848b8605Smrg} 2253848b8605Smrg 2254848b8605Smrg 2255848b8605Smrgstatic Bool 2256848b8605Smrg__glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, 2257848b8605Smrg int64_t target_sbc, int64_t * ust, 2258848b8605Smrg int64_t * msc, int64_t * sbc) 2259848b8605Smrg{ 2260848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2261848b8605Smrg __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); 2262848b8605Smrg struct glx_screen *psc = pdraw ? pdraw->psc : NULL; 2263848b8605Smrg int ret; 2264848b8605Smrg#endif 2265848b8605Smrg 2266848b8605Smrg /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE 2267848b8605Smrg * error", but the return type in the spec is Bool. 2268848b8605Smrg */ 2269848b8605Smrg if (target_sbc < 0) 2270848b8605Smrg return False; 2271848b8605Smrg 2272848b8605Smrg#ifdef GLX_DIRECT_RENDERING 2273848b8605Smrg if (pdraw && psc->driScreen && psc->driScreen->waitForSBC) { 2274848b8605Smrg ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc); 2275848b8605Smrg return ret; 2276848b8605Smrg } 2277848b8605Smrg#endif 2278848b8605Smrg 2279848b8605Smrg return False; 2280848b8605Smrg} 2281848b8605Smrg 2282848b8605Smrg/*@}*/ 2283848b8605Smrg 2284848b8605Smrg 2285848b8605Smrg/** 2286848b8605Smrg * Mesa extension stubs. These will help reduce portability problems. 2287848b8605Smrg */ 2288848b8605Smrg/*@{*/ 2289848b8605Smrg 2290848b8605Smrg/** 2291848b8605Smrg * Release all buffers associated with the specified GLX drawable. 2292848b8605Smrg * 2293848b8605Smrg * \todo 2294848b8605Smrg * This function was intended for stand-alone Mesa. The issue there is that 2295848b8605Smrg * the library doesn't get any notification when a window is closed. In 2296848b8605Smrg * DRI there is a similar but slightly different issue. When GLX 1.3 is 2297848b8605Smrg * supported, there are 3 different functions to destroy a drawable. It 2298848b8605Smrg * should be possible to create GLX protocol (or have it determine which 2299848b8605Smrg * protocol to use based on the type of the drawable) to have one function 2300848b8605Smrg * do the work of 3. For the direct-rendering case, this function could 2301848b8605Smrg * just call the driver's \c __DRIdrawableRec::destroyDrawable function. 2302848b8605Smrg * This would reduce the frequency with which \c __driGarbageCollectDrawables 2303848b8605Smrg * would need to be used. This really should be done as part of the new DRI 2304848b8605Smrg * interface work. 2305848b8605Smrg * 2306848b8605Smrg * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt 2307848b8605Smrg * __driGarbageCollectDrawables 2308848b8605Smrg * glXDestroyGLXPixmap 2309848b8605Smrg * glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow 2310848b8605Smrg * glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX 2311848b8605Smrg */ 2312848b8605Smrgstatic Bool 2313848b8605Smrg__glXReleaseBuffersMESA(Display * dpy, GLXDrawable d) 2314848b8605Smrg{ 2315848b8605Smrg (void) dpy; 2316848b8605Smrg (void) d; 2317848b8605Smrg return False; 2318848b8605Smrg} 2319848b8605Smrg 2320848b8605Smrg 2321848b8605Smrg_X_EXPORT GLXPixmap 2322848b8605SmrgglXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual, 2323848b8605Smrg Pixmap pixmap, Colormap cmap) 2324848b8605Smrg{ 2325848b8605Smrg (void) dpy; 2326848b8605Smrg (void) visual; 2327848b8605Smrg (void) pixmap; 2328848b8605Smrg (void) cmap; 2329848b8605Smrg return 0; 2330848b8605Smrg} 2331848b8605Smrg 2332848b8605Smrg/*@}*/ 2333848b8605Smrg 2334848b8605Smrg 2335848b8605Smrg/** 2336848b8605Smrg * GLX_MESA_copy_sub_buffer 2337848b8605Smrg */ 2338848b8605Smrg#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */ 2339848b8605Smrgstatic void 2340848b8605Smrg__glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, 2341848b8605Smrg int x, int y, int width, int height) 2342848b8605Smrg{ 2343848b8605Smrg xGLXVendorPrivateReq *req; 2344848b8605Smrg struct glx_context *gc; 2345848b8605Smrg GLXContextTag tag; 2346848b8605Smrg CARD32 *drawable_ptr; 2347848b8605Smrg INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr; 2348848b8605Smrg CARD8 opcode; 2349848b8605Smrg 2350848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 2351848b8605Smrg __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); 2352848b8605Smrg if (pdraw != NULL) { 2353848b8605Smrg struct glx_screen *psc = pdraw->psc; 2354848b8605Smrg if (psc->driScreen->copySubBuffer != NULL) { 2355848b8605Smrg (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height, True); 2356848b8605Smrg } 2357848b8605Smrg 2358848b8605Smrg return; 2359848b8605Smrg } 2360848b8605Smrg#endif 2361848b8605Smrg 2362848b8605Smrg opcode = __glXSetupForCommand(dpy); 2363848b8605Smrg if (!opcode) 2364848b8605Smrg return; 2365848b8605Smrg 2366848b8605Smrg /* 2367848b8605Smrg ** The calling thread may or may not have a current context. If it 2368848b8605Smrg ** does, send the context tag so the server can do a flush. 2369848b8605Smrg */ 2370848b8605Smrg gc = __glXGetCurrentContext(); 2371848b8605Smrg if ((gc != NULL) && (dpy == gc->currentDpy) && 2372848b8605Smrg ((drawable == gc->currentDrawable) || 2373848b8605Smrg (drawable == gc->currentReadable))) { 2374848b8605Smrg tag = gc->currentContextTag; 2375848b8605Smrg } 2376848b8605Smrg else { 2377848b8605Smrg tag = 0; 2378848b8605Smrg } 2379848b8605Smrg 2380848b8605Smrg LockDisplay(dpy); 2381848b8605Smrg GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4, req); 2382848b8605Smrg req->reqType = opcode; 2383848b8605Smrg req->glxCode = X_GLXVendorPrivate; 2384848b8605Smrg req->vendorCode = X_GLXvop_CopySubBufferMESA; 2385848b8605Smrg req->contextTag = tag; 2386848b8605Smrg 2387848b8605Smrg drawable_ptr = (CARD32 *) (req + 1); 2388848b8605Smrg x_ptr = (INT32 *) (drawable_ptr + 1); 2389848b8605Smrg y_ptr = (INT32 *) (drawable_ptr + 2); 2390848b8605Smrg w_ptr = (INT32 *) (drawable_ptr + 3); 2391848b8605Smrg h_ptr = (INT32 *) (drawable_ptr + 4); 2392848b8605Smrg 2393848b8605Smrg *drawable_ptr = drawable; 2394848b8605Smrg *x_ptr = x; 2395848b8605Smrg *y_ptr = y; 2396848b8605Smrg *w_ptr = width; 2397848b8605Smrg *h_ptr = height; 2398848b8605Smrg 2399848b8605Smrg UnlockDisplay(dpy); 2400848b8605Smrg SyncHandle(); 2401848b8605Smrg} 2402848b8605Smrg 2403848b8605Smrg/*@{*/ 2404848b8605Smrgstatic void 2405848b8605Smrg__glXBindTexImageEXT(Display * dpy, 2406848b8605Smrg GLXDrawable drawable, int buffer, const int *attrib_list) 2407848b8605Smrg{ 2408848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 2409848b8605Smrg 2410848b8605Smrg if (gc == NULL || gc->vtable->bind_tex_image == NULL) 2411848b8605Smrg return; 2412848b8605Smrg 2413848b8605Smrg gc->vtable->bind_tex_image(dpy, drawable, buffer, attrib_list); 2414848b8605Smrg} 2415848b8605Smrg 2416848b8605Smrgstatic void 2417848b8605Smrg__glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer) 2418848b8605Smrg{ 2419848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 2420848b8605Smrg 2421848b8605Smrg if (gc == NULL || gc->vtable->release_tex_image == NULL) 2422848b8605Smrg return; 2423848b8605Smrg 2424848b8605Smrg gc->vtable->release_tex_image(dpy, drawable, buffer); 2425848b8605Smrg} 2426848b8605Smrg 2427848b8605Smrg/*@}*/ 2428848b8605Smrg 2429848b8605Smrg#endif /* GLX_USE_APPLEGL */ 2430848b8605Smrg 2431848b8605Smrg/** 2432848b8605Smrg * \c strdup is actually not a standard ANSI C or POSIX routine. 2433848b8605Smrg * Irix will not define it if ANSI mode is in effect. 2434848b8605Smrg * 2435848b8605Smrg * \sa strdup 2436848b8605Smrg */ 2437848b8605Smrg_X_HIDDEN char * 2438848b8605Smrg__glXstrdup(const char *str) 2439848b8605Smrg{ 2440848b8605Smrg char *copy; 2441848b8605Smrg copy = malloc(strlen(str) + 1); 2442848b8605Smrg if (!copy) 2443848b8605Smrg return NULL; 2444848b8605Smrg strcpy(copy, str); 2445848b8605Smrg return copy; 2446848b8605Smrg} 2447848b8605Smrg 2448848b8605Smrg/* 2449848b8605Smrg** glXGetProcAddress support 2450848b8605Smrg*/ 2451848b8605Smrg 2452848b8605Smrgstruct name_address_pair 2453848b8605Smrg{ 2454848b8605Smrg const char *Name; 2455848b8605Smrg GLvoid *Address; 2456848b8605Smrg}; 2457848b8605Smrg 2458848b8605Smrg#define GLX_FUNCTION(f) { # f, (GLvoid *) f } 2459848b8605Smrg#define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f } 2460848b8605Smrg 2461848b8605Smrgstatic const struct name_address_pair GLX_functions[] = { 2462848b8605Smrg /*** GLX_VERSION_1_0 ***/ 2463848b8605Smrg GLX_FUNCTION(glXChooseVisual), 2464848b8605Smrg GLX_FUNCTION(glXCopyContext), 2465848b8605Smrg GLX_FUNCTION(glXCreateContext), 2466848b8605Smrg GLX_FUNCTION(glXCreateGLXPixmap), 2467848b8605Smrg GLX_FUNCTION(glXDestroyContext), 2468848b8605Smrg GLX_FUNCTION(glXDestroyGLXPixmap), 2469848b8605Smrg GLX_FUNCTION(glXGetConfig), 2470848b8605Smrg GLX_FUNCTION(glXGetCurrentContext), 2471848b8605Smrg GLX_FUNCTION(glXGetCurrentDrawable), 2472848b8605Smrg GLX_FUNCTION(glXIsDirect), 2473848b8605Smrg GLX_FUNCTION(glXMakeCurrent), 2474848b8605Smrg GLX_FUNCTION(glXQueryExtension), 2475848b8605Smrg GLX_FUNCTION(glXQueryVersion), 2476848b8605Smrg GLX_FUNCTION(glXSwapBuffers), 2477848b8605Smrg GLX_FUNCTION(glXUseXFont), 2478848b8605Smrg GLX_FUNCTION(glXWaitGL), 2479848b8605Smrg GLX_FUNCTION(glXWaitX), 2480848b8605Smrg 2481848b8605Smrg /*** GLX_VERSION_1_1 ***/ 2482848b8605Smrg GLX_FUNCTION(glXGetClientString), 2483848b8605Smrg GLX_FUNCTION(glXQueryExtensionsString), 2484848b8605Smrg GLX_FUNCTION(glXQueryServerString), 2485848b8605Smrg 2486848b8605Smrg /*** GLX_VERSION_1_2 ***/ 2487848b8605Smrg GLX_FUNCTION(glXGetCurrentDisplay), 2488848b8605Smrg 2489848b8605Smrg /*** GLX_VERSION_1_3 ***/ 2490848b8605Smrg GLX_FUNCTION(glXChooseFBConfig), 2491848b8605Smrg GLX_FUNCTION(glXCreateNewContext), 2492848b8605Smrg GLX_FUNCTION(glXCreatePbuffer), 2493848b8605Smrg GLX_FUNCTION(glXCreatePixmap), 2494848b8605Smrg GLX_FUNCTION(glXCreateWindow), 2495848b8605Smrg GLX_FUNCTION(glXDestroyPbuffer), 2496848b8605Smrg GLX_FUNCTION(glXDestroyPixmap), 2497848b8605Smrg GLX_FUNCTION(glXDestroyWindow), 2498848b8605Smrg GLX_FUNCTION(glXGetCurrentReadDrawable), 2499848b8605Smrg GLX_FUNCTION(glXGetFBConfigAttrib), 2500848b8605Smrg GLX_FUNCTION(glXGetFBConfigs), 2501848b8605Smrg GLX_FUNCTION(glXGetSelectedEvent), 2502848b8605Smrg GLX_FUNCTION(glXGetVisualFromFBConfig), 2503848b8605Smrg GLX_FUNCTION(glXMakeContextCurrent), 2504848b8605Smrg GLX_FUNCTION(glXQueryContext), 2505848b8605Smrg GLX_FUNCTION(glXQueryDrawable), 2506848b8605Smrg GLX_FUNCTION(glXSelectEvent), 2507848b8605Smrg 2508848b8605Smrg#ifndef GLX_USE_APPLEGL 2509848b8605Smrg /*** GLX_SGI_swap_control ***/ 2510848b8605Smrg GLX_FUNCTION2(glXSwapIntervalSGI, __glXSwapIntervalSGI), 2511848b8605Smrg 2512848b8605Smrg /*** GLX_SGI_video_sync ***/ 2513848b8605Smrg GLX_FUNCTION2(glXGetVideoSyncSGI, __glXGetVideoSyncSGI), 2514848b8605Smrg GLX_FUNCTION2(glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI), 2515848b8605Smrg 2516848b8605Smrg /*** GLX_SGI_make_current_read ***/ 2517848b8605Smrg GLX_FUNCTION2(glXMakeCurrentReadSGI, glXMakeContextCurrent), 2518848b8605Smrg GLX_FUNCTION2(glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable), 2519848b8605Smrg 2520848b8605Smrg /*** GLX_EXT_import_context ***/ 2521848b8605Smrg GLX_FUNCTION(glXFreeContextEXT), 2522848b8605Smrg GLX_FUNCTION(glXGetContextIDEXT), 2523848b8605Smrg GLX_FUNCTION2(glXGetCurrentDisplayEXT, glXGetCurrentDisplay), 2524848b8605Smrg GLX_FUNCTION(glXImportContextEXT), 2525848b8605Smrg GLX_FUNCTION2(glXQueryContextInfoEXT, glXQueryContext), 2526848b8605Smrg#endif 2527848b8605Smrg 2528848b8605Smrg /*** GLX_SGIX_fbconfig ***/ 2529848b8605Smrg GLX_FUNCTION2(glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib), 2530848b8605Smrg GLX_FUNCTION2(glXChooseFBConfigSGIX, glXChooseFBConfig), 2531848b8605Smrg GLX_FUNCTION(glXCreateGLXPixmapWithConfigSGIX), 2532848b8605Smrg GLX_FUNCTION(glXCreateContextWithConfigSGIX), 2533848b8605Smrg GLX_FUNCTION2(glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig), 2534848b8605Smrg GLX_FUNCTION(glXGetFBConfigFromVisualSGIX), 2535848b8605Smrg 2536848b8605Smrg#ifndef GLX_USE_APPLEGL 2537848b8605Smrg /*** GLX_SGIX_pbuffer ***/ 2538848b8605Smrg GLX_FUNCTION(glXCreateGLXPbufferSGIX), 2539848b8605Smrg GLX_FUNCTION(glXDestroyGLXPbufferSGIX), 2540848b8605Smrg GLX_FUNCTION(glXQueryGLXPbufferSGIX), 2541848b8605Smrg GLX_FUNCTION(glXSelectEventSGIX), 2542848b8605Smrg GLX_FUNCTION(glXGetSelectedEventSGIX), 2543848b8605Smrg 2544848b8605Smrg /*** GLX_SGIX_swap_group ***/ 2545848b8605Smrg GLX_FUNCTION2(glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX), 2546848b8605Smrg 2547848b8605Smrg /*** GLX_SGIX_swap_barrier ***/ 2548848b8605Smrg GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX), 2549848b8605Smrg GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX), 2550848b8605Smrg 2551848b8605Smrg /*** GLX_MESA_copy_sub_buffer ***/ 2552848b8605Smrg GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA), 2553848b8605Smrg 2554848b8605Smrg /*** GLX_MESA_pixmap_colormap ***/ 2555848b8605Smrg GLX_FUNCTION(glXCreateGLXPixmapMESA), 2556848b8605Smrg 2557848b8605Smrg /*** GLX_MESA_release_buffers ***/ 2558848b8605Smrg GLX_FUNCTION2(glXReleaseBuffersMESA, __glXReleaseBuffersMESA), 2559848b8605Smrg 2560848b8605Smrg /*** GLX_MESA_swap_control ***/ 2561848b8605Smrg GLX_FUNCTION2(glXSwapIntervalMESA, __glXSwapIntervalMESA), 2562848b8605Smrg GLX_FUNCTION2(glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA), 2563848b8605Smrg#endif 2564848b8605Smrg 2565848b8605Smrg /*** GLX_ARB_get_proc_address ***/ 2566848b8605Smrg GLX_FUNCTION(glXGetProcAddressARB), 2567848b8605Smrg 2568848b8605Smrg /*** GLX 1.4 ***/ 2569848b8605Smrg GLX_FUNCTION2(glXGetProcAddress, glXGetProcAddressARB), 2570848b8605Smrg 2571848b8605Smrg#ifndef GLX_USE_APPLEGL 2572848b8605Smrg /*** GLX_OML_sync_control ***/ 2573848b8605Smrg GLX_FUNCTION2(glXWaitForSbcOML, __glXWaitForSbcOML), 2574848b8605Smrg GLX_FUNCTION2(glXWaitForMscOML, __glXWaitForMscOML), 2575848b8605Smrg GLX_FUNCTION2(glXSwapBuffersMscOML, __glXSwapBuffersMscOML), 2576848b8605Smrg GLX_FUNCTION2(glXGetMscRateOML, __glXGetMscRateOML), 2577848b8605Smrg GLX_FUNCTION2(glXGetSyncValuesOML, __glXGetSyncValuesOML), 2578848b8605Smrg 2579848b8605Smrg /*** GLX_EXT_texture_from_pixmap ***/ 2580848b8605Smrg GLX_FUNCTION2(glXBindTexImageEXT, __glXBindTexImageEXT), 2581848b8605Smrg GLX_FUNCTION2(glXReleaseTexImageEXT, __glXReleaseTexImageEXT), 2582848b8605Smrg#endif 2583848b8605Smrg 2584848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_DRM) 2585848b8605Smrg /*** DRI configuration ***/ 2586848b8605Smrg GLX_FUNCTION(glXGetScreenDriver), 2587848b8605Smrg GLX_FUNCTION(glXGetDriverConfig), 2588848b8605Smrg#endif 2589848b8605Smrg 2590848b8605Smrg /*** GLX_ARB_create_context and GLX_ARB_create_context_profile ***/ 2591848b8605Smrg GLX_FUNCTION(glXCreateContextAttribsARB), 2592848b8605Smrg 2593848b8605Smrg /*** GLX_MESA_query_renderer ***/ 2594848b8605Smrg GLX_FUNCTION(glXQueryRendererIntegerMESA), 2595848b8605Smrg GLX_FUNCTION(glXQueryRendererStringMESA), 2596848b8605Smrg GLX_FUNCTION(glXQueryCurrentRendererIntegerMESA), 2597848b8605Smrg GLX_FUNCTION(glXQueryCurrentRendererStringMESA), 2598848b8605Smrg 2599848b8605Smrg {NULL, NULL} /* end of list */ 2600848b8605Smrg}; 2601848b8605Smrg 2602848b8605Smrgstatic const GLvoid * 2603848b8605Smrgget_glx_proc_address(const char *funcName) 2604848b8605Smrg{ 2605848b8605Smrg GLuint i; 2606848b8605Smrg 2607848b8605Smrg /* try static functions */ 2608848b8605Smrg for (i = 0; GLX_functions[i].Name; i++) { 2609848b8605Smrg if (strcmp(GLX_functions[i].Name, funcName) == 0) 2610848b8605Smrg return GLX_functions[i].Address; 2611848b8605Smrg } 2612848b8605Smrg 2613848b8605Smrg return NULL; 2614848b8605Smrg} 2615848b8605Smrg 2616848b8605Smrg/** 2617848b8605Smrg * Get the address of a named GL function. This is the pre-GLX 1.4 name for 2618848b8605Smrg * \c glXGetProcAddress. 2619848b8605Smrg * 2620848b8605Smrg * \param procName Name of a GL or GLX function. 2621848b8605Smrg * \returns A pointer to the named function 2622848b8605Smrg * 2623848b8605Smrg * \sa glXGetProcAddress 2624848b8605Smrg */ 2625848b8605Smrg_X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void) 2626848b8605Smrg{ 2627848b8605Smrg typedef void (*gl_function) (void); 2628848b8605Smrg gl_function f; 2629848b8605Smrg 2630848b8605Smrg 2631848b8605Smrg /* Search the table of GLX and internal functions first. If that 2632848b8605Smrg * fails and the supplied name could be a valid core GL name, try 2633848b8605Smrg * searching the core GL function table. This check is done to prevent 2634848b8605Smrg * DRI based drivers from searching the core GL function table for 2635848b8605Smrg * internal API functions. 2636848b8605Smrg */ 2637848b8605Smrg f = (gl_function) get_glx_proc_address((const char *) procName); 2638848b8605Smrg if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l') 2639848b8605Smrg && (procName[2] != 'X')) { 2640848b8605Smrg#ifdef GLX_SHARED_GLAPI 2641848b8605Smrg f = (gl_function) __indirect_get_proc_address((const char *) procName); 2642848b8605Smrg#endif 2643848b8605Smrg if (!f) 2644848b8605Smrg f = (gl_function) _glapi_get_proc_address((const char *) procName); 2645848b8605Smrg if (!f) { 2646848b8605Smrg struct glx_context *gc = __glXGetCurrentContext(); 2647848b8605Smrg 2648848b8605Smrg if (gc != NULL && gc->vtable->get_proc_address != NULL) 2649848b8605Smrg f = gc->vtable->get_proc_address((const char *) procName); 2650848b8605Smrg } 2651848b8605Smrg } 2652848b8605Smrg return f; 2653848b8605Smrg} 2654848b8605Smrg 2655848b8605Smrg/** 2656848b8605Smrg * Get the address of a named GL function. This is the GLX 1.4 name for 2657848b8605Smrg * \c glXGetProcAddressARB. 2658848b8605Smrg * 2659848b8605Smrg * \param procName Name of a GL or GLX function. 2660848b8605Smrg * \returns A pointer to the named function 2661848b8605Smrg * 2662848b8605Smrg * \sa glXGetProcAddressARB 2663848b8605Smrg */ 2664848b8605Smrg_X_EXPORT void (*glXGetProcAddress(const GLubyte * procName)) (void) 2665848b8605Smrg#if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED) 2666848b8605Smrg __attribute__ ((alias("glXGetProcAddressARB"))); 2667848b8605Smrg#else 2668848b8605Smrg{ 2669848b8605Smrg return glXGetProcAddressARB(procName); 2670848b8605Smrg} 2671848b8605Smrg#endif /* __GNUC__ */ 2672848b8605Smrg 2673848b8605Smrg 2674848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 2675848b8605Smrg/** 2676848b8605Smrg * Get the unadjusted system time (UST). Currently, the UST is measured in 2677848b8605Smrg * microseconds since Epoc. The actual resolution of the UST may vary from 2678848b8605Smrg * system to system, and the units may vary from release to release. 2679848b8605Smrg * Drivers should not call this function directly. They should instead use 2680848b8605Smrg * \c glXGetProcAddress to obtain a pointer to the function. 2681848b8605Smrg * 2682848b8605Smrg * \param ust Location to store the 64-bit UST 2683848b8605Smrg * \returns Zero on success or a negative errno value on failure. 2684848b8605Smrg * 2685848b8605Smrg * \sa glXGetProcAddress, PFNGLXGETUSTPROC 2686848b8605Smrg * 2687848b8605Smrg * \since Internal API version 20030317. 2688848b8605Smrg */ 2689848b8605Smrg_X_HIDDEN int 2690848b8605Smrg__glXGetUST(int64_t * ust) 2691848b8605Smrg{ 2692848b8605Smrg struct timeval tv; 2693848b8605Smrg 2694848b8605Smrg if (ust == NULL) { 2695848b8605Smrg return -EFAULT; 2696848b8605Smrg } 2697848b8605Smrg 2698848b8605Smrg if (gettimeofday(&tv, NULL) == 0) { 2699848b8605Smrg ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; 2700848b8605Smrg return 0; 2701848b8605Smrg } 2702848b8605Smrg else { 2703848b8605Smrg return -errno; 2704848b8605Smrg } 2705848b8605Smrg} 2706848b8605Smrg#endif /* GLX_DIRECT_RENDERING */ 2707