391 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			391 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
| /* $XFree86: xc/programs/Xserver/GL/glx/glxscreens.c,v 1.6 2001/03/21 16:29:36 dawes Exp $ */
 | |
| /*
 | |
| ** License Applicability. Except to the extent portions of this file are
 | |
| ** made subject to an alternative license as permitted in the SGI Free
 | |
| ** Software License B, Version 1.1 (the "License"), the contents of this
 | |
| ** file are subject only to the provisions of the License. You may not use
 | |
| ** this file except in compliance with the License. You may obtain a copy
 | |
| ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
 | |
| ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
 | |
| ** 
 | |
| ** http://oss.sgi.com/projects/FreeB
 | |
| ** 
 | |
| ** Note that, as provided in the License, the Software is distributed on an
 | |
| ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
 | |
| ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
 | |
| ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
 | |
| ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
 | |
| ** 
 | |
| ** Original Code. The Original Code is: OpenGL Sample Implementation,
 | |
| ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
 | |
| ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
 | |
| ** Copyright in any portions created by third parties is as indicated
 | |
| ** elsewhere herein. All Rights Reserved.
 | |
| ** 
 | |
| ** Additional Notice Provisions: The application programming interfaces
 | |
| ** established by SGI in conjunction with the Original Code are The
 | |
| ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
 | |
| ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
 | |
| ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
 | |
| ** Window System(R) (Version 1.3), released October 19, 1998. This software
 | |
| ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
 | |
| ** published by SGI, but has not been independently verified as being
 | |
| ** compliant with the OpenGL(R) version 1.2.1 Specification.
 | |
| **
 | |
| */
 | |
| 
 | |
| #ifdef HAVE_DMX_CONFIG_H
 | |
| #include <dmx-config.h>
 | |
| #endif
 | |
| 
 | |
| #include "dmx.h"
 | |
| #include "dmxlog.h"
 | |
| 
 | |
| #undef Xmalloc
 | |
| #undef Xcalloc
 | |
| #undef Xrealloc
 | |
| #undef Xfree
 | |
| 
 | |
| #include "glxserver.h"
 | |
| 
 | |
| #ifdef IN_MODULE
 | |
| #include <xf86_ansic.h>
 | |
| #else
 | |
| #include <string.h>
 | |
| #include <signal.h>
 | |
| #endif
 | |
| 
 | |
| #include <windowstr.h>
 | |
| 
 | |
| #include "glxfbconfig.h"
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
| #include "panoramiXsrv.h"
 | |
| #endif
 | |
| 
 | |
| __GLXscreenInfo *__glXActiveScreens;
 | |
| GLint __glXNumActiveScreens;
 | |
| 
 | |
| __GLXFBConfig **__glXFBConfigs;
 | |
| int            __glXNumFBConfigs;
 | |
| 
 | |
| static char GLXServerVendorName[] = "SGI DMX/glxProxy";
 | |
| static char GLXServerVersion[64];
 | |
| static char GLXServerExtensions[] =
 | |
|             "GLX_EXT_visual_info "
 | |
|             "GLX_EXT_visual_rating "
 | |
|             "GLX_EXT_import_context "
 | |
| 	    "GLX_SGIX_fbconfig "
 | |
| 	    "GLX_SGI_make_current_read "
 | |
| 	    "GLX_SGI_swap_control "
 | |
|             ;
 | |
| 
 | |
| static char ExtensionsString[1024];
 | |
| 
 | |
| static void CalcServerVersionAndExtensions( void )
 | |
| {
 | |
|    int s;
 | |
|    xGLXQueryVersionReq *req;
 | |
|    xGLXQueryVersionReply reply;
 | |
|    char **be_extensions;
 | |
|    char *ext;
 | |
|    char *denied_extensions;
 | |
| 
 | |
|    /*
 | |
|     * set the server glx version to be the minimum version
 | |
|     * supported by all back-end servers
 | |
|     */
 | |
|    __glXVersionMajor = 0;
 | |
|    __glXVersionMinor = 0;
 | |
|    for (s=0; s<__glXNumActiveScreens; s++) {
 | |
|       DMXScreenInfo *dmxScreen = &dmxScreens[s];
 | |
|       Display *dpy = dmxScreen->beDisplay;
 | |
| 
 | |
|       /* Send the glXQueryVersion request */
 | |
|       LockDisplay(dpy);
 | |
|       GetReq(GLXQueryVersion,req);
 | |
|       req->reqType = dmxScreen->glxMajorOpcode;
 | |
|       req->glxCode = X_GLXQueryVersion;
 | |
|       req->majorVersion = GLX_SERVER_MAJOR_VERSION;
 | |
|       req->minorVersion = GLX_SERVER_MINOR_VERSION;
 | |
|       _XReply(dpy, (xReply*) &reply, 0, False);
 | |
|       UnlockDisplay(dpy);
 | |
|       SyncHandle();
 | |
| 
 | |
|       if (s == 0) {
 | |
| 	 __glXVersionMajor = reply.majorVersion;
 | |
| 	 __glXVersionMinor = reply.minorVersion;
 | |
|       }
 | |
|       else {
 | |
| 	 if (reply.majorVersion < __glXVersionMajor) {
 | |
| 	    __glXVersionMajor = reply.majorVersion;
 | |
| 	    __glXVersionMinor = reply.minorVersion;
 | |
| 	 }
 | |
| 	 else if ( (reply.majorVersion == __glXVersionMajor) &&
 | |
| 	           (reply.minorVersion < __glXVersionMinor)  ) {
 | |
| 	    __glXVersionMinor = reply.minorVersion;
 | |
| 	 }
 | |
|       }
 | |
| 
 | |
|    }
 | |
| 
 | |
|    if (GLX_SERVER_MAJOR_VERSION < __glXVersionMajor) {
 | |
|       __glXVersionMajor = GLX_SERVER_MAJOR_VERSION;
 | |
|       __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
 | |
|    }
 | |
|    else if ( (GLX_SERVER_MAJOR_VERSION == __glXVersionMajor) &&
 | |
| 	     (GLX_SERVER_MINOR_VERSION < __glXVersionMinor)  ) {
 | |
|       __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
 | |
|    }
 | |
| 
 | |
|    sprintf(GLXServerVersion, "%d.%d DMX %d back-end server(s)",
 | |
|               __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens );	 
 | |
|    /*
 | |
|     * set the ExtensionsString to the minimum extensions string
 | |
|     */
 | |
|    ExtensionsString[0] = '\0';
 | |
| 
 | |
|    /*
 | |
|     * read extensions strings of all back-end servers
 | |
|     */
 | |
|    be_extensions = (char **)Xalloc( __glXNumActiveScreens * sizeof(char *) );
 | |
|    if (!be_extensions)
 | |
|       return;
 | |
| 
 | |
|    for (s=0; s<__glXNumActiveScreens; s++) {
 | |
|       DMXScreenInfo *dmxScreen = &dmxScreens[s];
 | |
|       Display *dpy = dmxScreen->beDisplay;
 | |
|       xGLXQueryServerStringReq *req;
 | |
|       xGLXQueryServerStringReply reply;
 | |
|       int length, numbytes, slop;
 | |
| 
 | |
|       /* Send the glXQueryServerString request */
 | |
|       LockDisplay(dpy);
 | |
|       GetReq(GLXQueryServerString,req);
 | |
|       req->reqType = dmxScreen->glxMajorOpcode;
 | |
|       req->glxCode = X_GLXQueryServerString;
 | |
|       req->screen = DefaultScreen(dpy);
 | |
|       req->name = GLX_EXTENSIONS;
 | |
|       _XReply(dpy, (xReply*) &reply, 0, False);
 | |
| 
 | |
|       length = (int)reply.length;
 | |
|       numbytes = (int)reply.n;
 | |
|       slop = numbytes * __GLX_SIZE_INT8 & 3;
 | |
|       be_extensions[s] = (char *)Xalloc(numbytes);
 | |
|       if (!be_extensions[s]) {
 | |
| 	 /* Throw data on the floor */
 | |
| 	 _XEatData(dpy, length);
 | |
|       } else {
 | |
| 	 _XRead(dpy, (char *)be_extensions[s], numbytes);
 | |
| 	 if (slop) _XEatData(dpy,4-slop);
 | |
|       }
 | |
|       UnlockDisplay(dpy);
 | |
|       SyncHandle();
 | |
|    }
 | |
| 
 | |
|    /*
 | |
|     * extensions string will include only extensions that our
 | |
|     * server supports as well as all back-end servers supports.
 | |
|     * extensions that are in the DMX_DENY_EXTENSIONS string will
 | |
|     * not be supported.
 | |
|     */
 | |
|    denied_extensions = getenv("DMX_DENY_GLX_EXTENSIONS");
 | |
|    ext = strtok(GLXServerExtensions, " ");
 | |
|    while( ext ) {
 | |
|       int supported = 1;
 | |
| 
 | |
|       if (denied_extensions && strstr(denied_extensions, ext)) {
 | |
| 	 supported = 0;
 | |
|       }
 | |
|       else {
 | |
| 	 for (s=0; s<__glXNumActiveScreens && supported; s++) {
 | |
| 	    if ( !strstr(be_extensions[s], ext) ) {
 | |
| 	       supported = 0;
 | |
| 	    }
 | |
| 	 }
 | |
|       }
 | |
| 
 | |
|       if (supported) {
 | |
| 	 strcat(ExtensionsString, ext);
 | |
| 	 strcat(ExtensionsString, " ");
 | |
|       }
 | |
| 
 | |
|       ext = strtok(NULL, " ");
 | |
|    }
 | |
| 
 | |
|    /*
 | |
|     * release temporary storage
 | |
|     */
 | |
|    for (s=0; s<__glXNumActiveScreens; s++) {
 | |
|       if (be_extensions[s]) Xfree(be_extensions[s]); 
 | |
|    }
 | |
|    Xfree( be_extensions );
 | |
| 
 | |
|    if (dmxGLXSwapGroupSupport) {
 | |
|        if (!denied_extensions ||
 | |
| 	   !strstr(denied_extensions, "GLX_SGIX_swap_group")) {
 | |
| 	   strcat(ExtensionsString, "GLX_SGIX_swap_group");
 | |
| 	   if (!denied_extensions ||
 | |
| 	       !strstr(denied_extensions, "GLX_SGIX_swap_barrier")) {
 | |
| 	       strcat(ExtensionsString, " GLX_SGIX_swap_barrier");
 | |
| 	   }
 | |
|        }
 | |
|    }
 | |
| 
 | |
| }
 | |
| 
 | |
| void __glXScreenInit(GLint numscreens)
 | |
| {
 | |
|    int s;
 | |
|    int c;
 | |
|    DMXScreenInfo *dmxScreen0 = &dmxScreens[0];
 | |
|     __glXNumActiveScreens = numscreens;
 | |
| 
 | |
| 
 | |
|    CalcServerVersionAndExtensions();
 | |
| 
 | |
| 
 | |
|    __glXFBConfigs = NULL;
 | |
|    __glXNumFBConfigs = 0;
 | |
| 
 | |
|    if ( (__glXVersionMajor == 1 && __glXVersionMinor >= 3) ||
 | |
|         (__glXVersionMajor > 1) ||
 | |
| 	( strstr(ExtensionsString, "GLX_SGIX_fbconfig") )      ) {
 | |
| 
 | |
|       /*
 | |
|       // Initialize FBConfig info.
 | |
|       // find the set of FBConfigs that are present on all back-end
 | |
|       // servers - only those configs will be supported
 | |
|        */
 | |
|       __glXFBConfigs = (__GLXFBConfig **)Xalloc( dmxScreen0->numFBConfigs * 
 | |
| 	                      (numscreens+1) * sizeof(__GLXFBConfig *) );
 | |
|       __glXNumFBConfigs = 0;
 | |
|    
 | |
|       for (c=0; c<dmxScreen0->numFBConfigs; c++) { 
 | |
| 	 __GLXFBConfig *cfg = NULL;
 | |
| 
 | |
| 	 if (numscreens > 1) {
 | |
| 	    for (s=1; s<numscreens; s++) {
 | |
| 	       DMXScreenInfo *dmxScreen = &dmxScreens[s];
 | |
| 	       __GLXscreenInfo *glxScreen = &__glXActiveScreens[s];
 | |
| 	  
 | |
| 	       cfg = FindMatchingFBConfig( &dmxScreen0->fbconfigs[c],
 | |
| 		                           dmxScreen->fbconfigs, 
 | |
| 		                           dmxScreen->numFBConfigs );
 | |
| 	       __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + s + 1 ] = cfg;
 | |
| 	       if (!cfg) {
 | |
| 		  dmxLog(dmxInfo,"screen0 FBConfig 0x%x is missing on screen#%d\n", dmxScreen0->fbconfigs[c].id, s);
 | |
| 		  break;
 | |
| 	       }
 | |
| 	       else {
 | |
| 		  dmxLog(dmxInfo,"screen0 FBConfig 0x%x matched to  0x%x on screen#%d\n", dmxScreen0->fbconfigs[c].id, cfg->id, s);
 | |
| 	       }
 | |
| 	    }
 | |
|          }
 | |
| 	 else {
 | |
| 	    cfg = &dmxScreen0->fbconfigs[c];
 | |
| 	 }
 | |
| 
 | |
| 	 if (cfg) {
 | |
| 
 | |
| 	    /* filter out overlay visuals */
 | |
| 	    if (cfg->level == 0) {
 | |
| 	       __GLXFBConfig *proxy_cfg;
 | |
| 
 | |
| 	       __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 1 ] = 
 | |
| 	               &dmxScreen0->fbconfigs[c];
 | |
| 
 | |
| 	       proxy_cfg = Xalloc( sizeof(__GLXFBConfig) );
 | |
| 	       memcpy( proxy_cfg, cfg, sizeof(__GLXFBConfig) );
 | |
| 	       proxy_cfg->id =  FakeClientID(0);
 | |
| 	       /* visual will be associated later in __glXGetFBConfigs */
 | |
| 	       proxy_cfg->associatedVisualId =  (unsigned int)-1;
 | |
| 
 | |
| 	       __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 0 ] = proxy_cfg;
 | |
| 
 | |
| 	       __glXNumFBConfigs++;
 | |
| 	    }
 | |
| 
 | |
| 	 }
 | |
| 
 | |
|       }
 | |
| 
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| void __glXScreenReset(void)
 | |
| {
 | |
|   __glXNumActiveScreens = 0;
 | |
| }
 | |
| 
 | |
| char *__glXGetServerString( unsigned int name ) 
 | |
| {
 | |
|    char *ret = NULL;
 | |
| 
 | |
|    switch( name) {
 | |
| 
 | |
|       case GLX_VENDOR:
 | |
| 	 ret = GLXServerVendorName;
 | |
| 	 break;
 | |
| 
 | |
|       case GLX_VERSION:
 | |
| 	 ret = GLXServerVersion;
 | |
| 	 break;
 | |
| 
 | |
|       case GLX_EXTENSIONS:
 | |
| 	 ret = ExtensionsString;
 | |
| 	 break;
 | |
| 
 | |
|       default:
 | |
| 	 break;
 | |
|    }
 | |
| 
 | |
|    return( ret );
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id )
 | |
| {
 | |
|    int i,j;
 | |
| 
 | |
|    for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
 | |
|       if ( __glXFBConfigs[j]->id == id) 
 | |
| 	 return( __glXFBConfigs[j] );
 | |
|    }
 | |
| 
 | |
|    return(NULL);
 | |
| }
 | |
| 
 | |
| __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid )
 | |
| {
 | |
|    int i,j;
 | |
| 
 | |
|    for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
 | |
|       if ( __glXFBConfigs[j]->associatedVisualId == vid) 
 | |
| 	 return( __glXFBConfigs[j] );
 | |
|    }
 | |
| 
 | |
|    return(NULL);
 | |
| }
 | |
| 
 | |
| __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen )
 | |
| {
 | |
|    int i;
 | |
|    int j;
 | |
| 
 | |
|    for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
 | |
|       if ( __glXFBConfigs[j]->id == id) 
 | |
| 	 return( __glXFBConfigs[j+screen+1] );
 | |
|    }
 | |
| 
 | |
|    return(NULL);
 | |
| 
 | |
| }
 | |
| 
 | |
| int glxIsExtensionSupported( char *ext )
 | |
| {
 | |
|    return( strstr(ExtensionsString, ext) != NULL );
 | |
| }
 |