glxcmds.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 2,495 行 · 第 1/5 页
C
2,495 行
case GLX_TRANSPARENT_INDEX: MATCH_DONT_CARE( transparentIndex ); break; default: break; } } return True;}/* There's some trickly language in the GLX spec about how this is supposed * to work. Basically, if a given component size is either not specified * or the requested size is zero, it is supposed to act like PERFER_SMALLER. * Well, that's really hard to do with the code as-is. This behavior is * closer to correct, but still not technically right. */#define PREFER_LARGER_OR_ZERO(comp) \ do { \ if ( ((*a)-> comp) != ((*b)-> comp) ) { \ if ( ((*a)-> comp) == 0 ) { \ return -1; \ } \ else if ( ((*b)-> comp) == 0 ) { \ return 1; \ } \ else { \ return ((*b)-> comp) - ((*a)-> comp) ; \ } \ } \ } while( 0 )#define PREFER_LARGER(comp) \ do { \ if ( ((*a)-> comp) != ((*b)-> comp) ) { \ return ((*b)-> comp) - ((*a)-> comp) ; \ } \ } while( 0 )#define PREFER_SMALLER(comp) \ do { \ if ( ((*a)-> comp) != ((*b)-> comp) ) { \ return ((*a)-> comp) - ((*b)-> comp) ; \ } \ } while( 0 )/** * Compare two GLXFBConfigs. This function is intended to be used as the * compare function passed in to qsort. * * \returns If \c a is a "better" config, according to the specification of * SGIX_fbconfig, a number less than zero is returned. If \c b is * better, then a number greater than zero is return. If both are * equal, zero is returned. * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX */static intfbconfig_compare( const __GLcontextModes * const * const a, const __GLcontextModes * const * const b ){ /* The order of these comparisons must NOT change. It is defined by * the GLX 1.3 spec and ARB_multisample. */ PREFER_SMALLER( visualSelectGroup ); /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the * numerical sort order of the enums (0x8000, 0x8001, and 0x800D). */ PREFER_SMALLER( visualRating ); /* This isn't quite right. It is supposed to compare the sum of the * components the user specifically set minimums for. */ PREFER_LARGER_OR_ZERO( redBits ); PREFER_LARGER_OR_ZERO( greenBits ); PREFER_LARGER_OR_ZERO( blueBits ); PREFER_LARGER_OR_ZERO( alphaBits ); PREFER_SMALLER( rgbBits ); if ( ((*a)->doubleBufferMode != (*b)->doubleBufferMode) ) { /* Prefer single-buffer. */ return ( !(*a)->doubleBufferMode ) ? -1 : 1; } PREFER_SMALLER( numAuxBuffers ); PREFER_LARGER_OR_ZERO( depthBits ); PREFER_SMALLER( stencilBits ); /* This isn't quite right. It is supposed to compare the sum of the * components the user specifically set minimums for. */ PREFER_LARGER_OR_ZERO( accumRedBits ); PREFER_LARGER_OR_ZERO( accumGreenBits ); PREFER_LARGER_OR_ZERO( accumBlueBits ); PREFER_LARGER_OR_ZERO( accumAlphaBits ); PREFER_SMALLER( visualType ); /* None of the multisample specs say where this comparison should happen, * so I put it near the end. */ PREFER_SMALLER( sampleBuffers ); PREFER_SMALLER( samples ); /* None of the pbuffer or fbconfig specs say that this comparison needs * to happen at all, but it seems like it should. */ PREFER_LARGER( maxPbufferWidth ); PREFER_LARGER( maxPbufferHeight ); PREFER_LARGER( maxPbufferPixels ); return 0;}/** * Selects and sorts a subset of the supplied configs based on the attributes. * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig, * and \c glXChooseFBConfigSGIX. * * \param configs Array of pointers to possible configs. The elements of * this array that do not meet the criteria will be set to * NULL. The remaining elements will be sorted according to * the various visual / FBConfig selection rules. * \param num_configs Number of elements in the \c configs array. * \param attribList Attributes used select from \c configs. This array is * terminated by a \c None tag. The array can either take * the form expected by \c glXChooseVisual (where boolean * tags do not have a value) or by \c glXChooseFBConfig * (where every tag has a value). * \param fbconfig_style_tags Selects whether \c attribList is in * \c glXChooseVisual style or * \c glXChooseFBConfig style. * \returns The number of valid elements left in \c configs. * * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX */static intchoose_visual( __GLcontextModes ** configs, int num_configs, const int *attribList, GLboolean fbconfig_style_tags ){ __GLcontextModes test_config; int base; int i; /* This is a fairly direct implementation of the selection method * described by GLX_SGIX_fbconfig. Start by culling out all the * configs that are not compatible with the selected parameter * list. */ init_fbconfig_for_chooser( & test_config, fbconfig_style_tags ); __glXInitializeVisualConfigFromTags( & test_config, 512, (const INT32 *) attribList, GL_TRUE, fbconfig_style_tags ); base = 0; for ( i = 0 ; i < num_configs ; i++ ) { if ( fbconfigs_compatible( & test_config, configs[i] ) ) { configs[ base ] = configs[ i ]; base++; } } if ( base == 0 ) { return 0; } if ( base < num_configs ) { (void) memset( & configs[ base ], 0, sizeof( void * ) * (num_configs - base) ); } /* After the incompatible configs are removed, the resulting * list is sorted according to the rules set out in the various * specifications. */ qsort( configs, base, sizeof( __GLcontextModes * ), (int (*)(const void*, const void*)) fbconfig_compare ); return base;}/*** Return the visual that best matches the template. Return None if no** visual matches the template.*/PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList){ XVisualInfo *visualList = NULL; __GLXdisplayPrivate *priv; __GLXscreenConfigs *psc; __GLcontextModes test_config; __GLcontextModes *modes; const __GLcontextModes *best_config = NULL; /* ** Get a list of all visuals, return if list is empty */ if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) { return None; } /* ** Build a template from the defaults and the attribute list ** Free visual list and return if an unexpected token is encountered */ init_fbconfig_for_chooser( & test_config, GL_FALSE ); __glXInitializeVisualConfigFromTags( & test_config, 512, (const INT32 *) attribList, GL_TRUE, GL_FALSE ); /* ** Eliminate visuals that don't meet minimum requirements ** Compute a score for those that do ** Remember which visual, if any, got the highest score */ for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) { if ( fbconfigs_compatible( & test_config, modes ) && ((best_config == NULL) || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) { best_config = modes; } } /* ** If no visual is acceptable, return None ** Otherwise, create an XVisualInfo list with just the selected X visual ** and return this. */ if (best_config != NULL) { XVisualInfo visualTemplate; int i; visualTemplate.screen = screen; visualTemplate.visualid = best_config->visualID; visualList = XGetVisualInfo( dpy, VisualScreenMask|VisualIDMask, &visualTemplate, &i ); } return visualList;}PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen ){ __GLXscreenConfigs *psc; __GLXdisplayPrivate *priv; if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) { return NULL; } if (!psc->effectiveGLXexts) { if (!psc->serverGLXexts) { psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode, X_GLXQueryServerString, screen, GLX_EXTENSIONS); } __glXCalculateUsableExtensions(psc,#ifdef GLX_DIRECT_RENDERING (psc->driScreen.private != NULL),#else GL_FALSE,#endif priv->minorVersion); } return psc->effectiveGLXexts;}PUBLIC const char *glXGetClientString( Display *dpy, int name ){ switch(name) { case GLX_VENDOR: return (__glXGLXClientVendorName); case GLX_VERSION: return (__glXGLXClientVersion); case GLX_EXTENSIONS: return (__glXGetClientExtensions()); default: return NULL; }}PUBLIC const char *glXQueryServerString( Display *dpy, int screen, int name ){ __GLXscreenConfigs *psc; __GLXdisplayPrivate *priv; const char ** str; if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) { return NULL; } switch(name) { case GLX_VENDOR: str = & priv->serverGLXvendor; break; case GLX_VERSION: str = & priv->serverGLXversion; break; case GLX_EXTENSIONS: str = & psc->serverGLXexts; break; default: return NULL; } if ( *str == NULL ) { *str = __glXGetStringFromServer(dpy, priv->majorOpcode, X_GLXQueryServerString, screen, name); } return *str;}void __glXClientInfo ( Display *dpy, int opcode ){ xGLXClientInfoReq *req; int size; char * ext_str = __glXGetClientGLExtensionString(); /* Send the glXClientInfo request */ LockDisplay(dpy); GetReq(GLXClientInfo,req); req->reqType = opcode; req->glxCode = X_GLXClientInfo; req->major = GLX_MAJOR_VERSION; req->minor = GLX_MINOR_VERSION; size = strlen( ext_str ) + 1; req->length += (size + 3) >> 2; req->numbytes = size; Data(dpy, ext_str, size); UnlockDisplay(dpy); SyncHandle(); Xfree( ext_str );}/*** EXT_import_context*/PUBLIC Display *glXGetCurrentDisplay(void){ GLXContext gc = __glXGetCurrentContext(); if (NULL == gc) return NULL; return gc->currentDpy;}PUBLIC GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (), glXGetCurrentDisplay)/** * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests * to the X-server. * * \param dpy Display where \c ctx was created. * \param ctx Context to query. * \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid, * or zero if the request failed due to internal problems (i.e., * unable to allocate temporary memory, etc.) * * \note * This function dynamically determines whether to use the EXT_import_context * version of the protocol or the GLX 1.3 version of the protocol. */static int __glXQueryContextInfo(Display *dpy, GLXContext ctx){ __GLXdisplayPrivate *priv = __glXInitialize(dpy); xGLXQueryContextReply reply; CARD8 opcode; GLuint numValues; int retval; if (ctx == NULL) { return GLX_BAD_CONTEXT; } opcode = __glXSetupForCommand(dpy); if (!opcode) { return 0; } /* Send the glXQueryContextInfoEXT request */ LockDisplay(dpy); if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { xGLXQueryContextReq *req; GetReq(GLXQueryContext, req); req->reqType = opcode; req->glxCode = X_GLXQueryContext; req->context = (unsigned int)(ctx->xid); } else { xGLXVendorPrivateReq *vpreq; xGLXQueryContextInfoEXTReq *req; GetReqExtra( GLXVendorPrivate, sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq, vpreq ); req = (xGLXQueryContextInfoEXTReq *)vpreq; req->reqType = opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_QueryContextInfoEXT; req->context = (unsigned int)(ctx->xid); } _XReply(dpy, (xReply*) &reply, 0, False); numValues = reply.n; if (numValues == 0) retval = Success; else if (numValues > __GLX_MAX_CONTEXT_PROPS) retval = 0; else { int *propList, *pProp; int nPropListBytes; int i; nPropListBytes = numValues << 3; propList = (int *) Xmalloc(nPropListBytes); if (NULL == propList) { retval = 0; } else { _XRead(dpy, (char *)propList, nPropListBytes); pProp = propList; for (i=0; i < numValues; i++) { switch (*pProp++) { case GLX_SHARE_CONTEXT_EXT: ctx->share_xid = *pProp++; break; case GLX_VISUAL_ID_EXT: ctx->vid = *pProp++; break; case GLX_SCREEN: ctx->screen = *pProp++; break; case GLX_FBCONFIG_ID: ctx->fbconfigID = *pProp++; break; case GLX_RENDER_TYPE: ctx->renderType = *pProp++; break; default: pProp++; continue; } } Xfree((char *)propList); retval = Success; } } UnlockDisplay(dpy); SyncHandle(); return retval;}PUBLIC intglXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value){ int retVal; /* get the information from the server if we don't have it already */ if (!ctx->isDirect && (ctx->vid == None)) { retVal = __glXQueryContextInfo(dpy, ctx); if (Success != retVal) return retVal; } switch (attribute) { case GLX_SHARE_CONTEXT_EXT: *value = (int)(ctx->share_xid); break; case GLX_VISUAL_ID_EXT: *value = (int)(ctx->vid); break; case GLX_SCREEN: *value = (int)(ctx->screen); break; case GLX_FBCONFIG_ID: *value = (int)(ctx->fbconfigID);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?