1706f2543Smrg/* 2706f2543Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 3706f2543Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 4706f2543Smrg * 5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6706f2543Smrg * copy of this software and associated documentation files (the "Software"), 7706f2543Smrg * to deal in the Software without restriction, including without limitation 8706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 10706f2543Smrg * Software is furnished to do so, subject to the following conditions: 11706f2543Smrg * 12706f2543Smrg * The above copyright notice including the dates of first publication and 13706f2543Smrg * either this permission notice or a reference to 14706f2543Smrg * http://oss.sgi.com/projects/FreeB/ 15706f2543Smrg * shall be included in all copies or substantial portions of the Software. 16706f2543Smrg * 17706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18706f2543Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20706f2543Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23706f2543Smrg * SOFTWARE. 24706f2543Smrg * 25706f2543Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc. 26706f2543Smrg * shall not be used in advertising or otherwise to promote the sale, use or 27706f2543Smrg * other dealings in this Software without prior written authorization from 28706f2543Smrg * Silicon Graphics, Inc. 29706f2543Smrg */ 30706f2543Smrg 31706f2543Smrg#ifdef HAVE_DMX_CONFIG_H 32706f2543Smrg#include <dmx-config.h> 33706f2543Smrg#endif 34706f2543Smrg 35706f2543Smrg#include "dmx.h" 36706f2543Smrg#include "dmxlog.h" 37706f2543Smrg 38706f2543Smrg#include "glxserver.h" 39706f2543Smrg 40706f2543Smrg#include <windowstr.h> 41706f2543Smrg 42706f2543Smrg#include "glxfbconfig.h" 43706f2543Smrg 44706f2543Smrg#ifdef PANORAMIX 45706f2543Smrg#include "panoramiXsrv.h" 46706f2543Smrg#endif 47706f2543Smrg 48706f2543Smrg__GLXscreenInfo *__glXActiveScreens; 49706f2543SmrgGLint __glXNumActiveScreens; 50706f2543Smrg 51706f2543Smrg__GLXFBConfig **__glXFBConfigs; 52706f2543Smrgint __glXNumFBConfigs; 53706f2543Smrg 54706f2543Smrgstatic char GLXServerVendorName[] = "SGI DMX/glxProxy"; 55706f2543Smrgstatic char GLXServerVersion[64]; 56706f2543Smrgstatic char GLXServerExtensions[] = 57706f2543Smrg "GLX_EXT_visual_info " 58706f2543Smrg "GLX_EXT_visual_rating " 59706f2543Smrg "GLX_EXT_import_context " 60706f2543Smrg "GLX_SGIX_fbconfig " 61706f2543Smrg "GLX_SGI_make_current_read " 62706f2543Smrg "GLX_SGI_swap_control " 63706f2543Smrg ; 64706f2543Smrg 65706f2543Smrgstatic char ExtensionsString[1024]; 66706f2543Smrg 67706f2543Smrgstatic void CalcServerVersionAndExtensions( void ) 68706f2543Smrg{ 69706f2543Smrg int s; 70706f2543Smrg xGLXQueryVersionReq *req; 71706f2543Smrg xGLXQueryVersionReply reply; 72706f2543Smrg char **be_extensions; 73706f2543Smrg char *ext; 74706f2543Smrg char *denied_extensions; 75706f2543Smrg 76706f2543Smrg /* 77706f2543Smrg * set the server glx version to be the minimum version 78706f2543Smrg * supported by all back-end servers 79706f2543Smrg */ 80706f2543Smrg __glXVersionMajor = 0; 81706f2543Smrg __glXVersionMinor = 0; 82706f2543Smrg for (s=0; s<__glXNumActiveScreens; s++) { 83706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[s]; 84706f2543Smrg Display *dpy = dmxScreen->beDisplay; 85706f2543Smrg 86706f2543Smrg /* Send the glXQueryVersion request */ 87706f2543Smrg LockDisplay(dpy); 88706f2543Smrg GetReq(GLXQueryVersion,req); 89706f2543Smrg req->reqType = dmxScreen->glxMajorOpcode; 90706f2543Smrg req->glxCode = X_GLXQueryVersion; 91706f2543Smrg req->majorVersion = GLX_SERVER_MAJOR_VERSION; 92706f2543Smrg req->minorVersion = GLX_SERVER_MINOR_VERSION; 93706f2543Smrg _XReply(dpy, (xReply*) &reply, 0, False); 94706f2543Smrg UnlockDisplay(dpy); 95706f2543Smrg SyncHandle(); 96706f2543Smrg 97706f2543Smrg if (s == 0) { 98706f2543Smrg __glXVersionMajor = reply.majorVersion; 99706f2543Smrg __glXVersionMinor = reply.minorVersion; 100706f2543Smrg } 101706f2543Smrg else { 102706f2543Smrg if (reply.majorVersion < __glXVersionMajor) { 103706f2543Smrg __glXVersionMajor = reply.majorVersion; 104706f2543Smrg __glXVersionMinor = reply.minorVersion; 105706f2543Smrg } 106706f2543Smrg else if ( (reply.majorVersion == __glXVersionMajor) && 107706f2543Smrg (reply.minorVersion < __glXVersionMinor) ) { 108706f2543Smrg __glXVersionMinor = reply.minorVersion; 109706f2543Smrg } 110706f2543Smrg } 111706f2543Smrg 112706f2543Smrg } 113706f2543Smrg 114706f2543Smrg if (GLX_SERVER_MAJOR_VERSION < __glXVersionMajor) { 115706f2543Smrg __glXVersionMajor = GLX_SERVER_MAJOR_VERSION; 116706f2543Smrg __glXVersionMinor = GLX_SERVER_MINOR_VERSION; 117706f2543Smrg } 118706f2543Smrg else if ( (GLX_SERVER_MAJOR_VERSION == __glXVersionMajor) && 119706f2543Smrg (GLX_SERVER_MINOR_VERSION < __glXVersionMinor) ) { 120706f2543Smrg __glXVersionMinor = GLX_SERVER_MINOR_VERSION; 121706f2543Smrg } 122706f2543Smrg 123706f2543Smrg sprintf(GLXServerVersion, "%d.%d DMX %d back-end server(s)", 124706f2543Smrg __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens ); 125706f2543Smrg /* 126706f2543Smrg * set the ExtensionsString to the minimum extensions string 127706f2543Smrg */ 128706f2543Smrg ExtensionsString[0] = '\0'; 129706f2543Smrg 130706f2543Smrg /* 131706f2543Smrg * read extensions strings of all back-end servers 132706f2543Smrg */ 133706f2543Smrg be_extensions = (char **)malloc( __glXNumActiveScreens * sizeof(char *) ); 134706f2543Smrg if (!be_extensions) 135706f2543Smrg return; 136706f2543Smrg 137706f2543Smrg for (s=0; s<__glXNumActiveScreens; s++) { 138706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[s]; 139706f2543Smrg Display *dpy = dmxScreen->beDisplay; 140706f2543Smrg xGLXQueryServerStringReq *req; 141706f2543Smrg xGLXQueryServerStringReply reply; 142706f2543Smrg int length, numbytes, slop; 143706f2543Smrg 144706f2543Smrg /* Send the glXQueryServerString request */ 145706f2543Smrg LockDisplay(dpy); 146706f2543Smrg GetReq(GLXQueryServerString,req); 147706f2543Smrg req->reqType = dmxScreen->glxMajorOpcode; 148706f2543Smrg req->glxCode = X_GLXQueryServerString; 149706f2543Smrg req->screen = DefaultScreen(dpy); 150706f2543Smrg req->name = GLX_EXTENSIONS; 151706f2543Smrg _XReply(dpy, (xReply*) &reply, 0, False); 152706f2543Smrg 153706f2543Smrg length = (int)reply.length; 154706f2543Smrg numbytes = (int)reply.n; 155706f2543Smrg slop = numbytes * __GLX_SIZE_INT8 & 3; 156706f2543Smrg be_extensions[s] = (char *)malloc(numbytes); 157706f2543Smrg if (!be_extensions[s]) { 158706f2543Smrg /* Throw data on the floor */ 159706f2543Smrg _XEatData(dpy, length); 160706f2543Smrg } else { 161706f2543Smrg _XRead(dpy, (char *)be_extensions[s], numbytes); 162706f2543Smrg if (slop) _XEatData(dpy,4-slop); 163706f2543Smrg } 164706f2543Smrg UnlockDisplay(dpy); 165706f2543Smrg SyncHandle(); 166706f2543Smrg } 167706f2543Smrg 168706f2543Smrg /* 169706f2543Smrg * extensions string will include only extensions that our 170706f2543Smrg * server supports as well as all back-end servers supports. 171706f2543Smrg * extensions that are in the DMX_DENY_EXTENSIONS string will 172706f2543Smrg * not be supported. 173706f2543Smrg */ 174706f2543Smrg denied_extensions = getenv("DMX_DENY_GLX_EXTENSIONS"); 175706f2543Smrg ext = strtok(GLXServerExtensions, " "); 176706f2543Smrg while( ext ) { 177706f2543Smrg int supported = 1; 178706f2543Smrg 179706f2543Smrg if (denied_extensions && strstr(denied_extensions, ext)) { 180706f2543Smrg supported = 0; 181706f2543Smrg } 182706f2543Smrg else { 183706f2543Smrg for (s=0; s<__glXNumActiveScreens && supported; s++) { 184706f2543Smrg if ( !strstr(be_extensions[s], ext) ) { 185706f2543Smrg supported = 0; 186706f2543Smrg } 187706f2543Smrg } 188706f2543Smrg } 189706f2543Smrg 190706f2543Smrg if (supported) { 191706f2543Smrg strcat(ExtensionsString, ext); 192706f2543Smrg strcat(ExtensionsString, " "); 193706f2543Smrg } 194706f2543Smrg 195706f2543Smrg ext = strtok(NULL, " "); 196706f2543Smrg } 197706f2543Smrg 198706f2543Smrg /* 199706f2543Smrg * release temporary storage 200706f2543Smrg */ 201706f2543Smrg for (s=0; s<__glXNumActiveScreens; s++) { 202706f2543Smrg free(be_extensions[s]); 203706f2543Smrg } 204706f2543Smrg free( be_extensions ); 205706f2543Smrg 206706f2543Smrg if (dmxGLXSwapGroupSupport) { 207706f2543Smrg if (!denied_extensions || 208706f2543Smrg !strstr(denied_extensions, "GLX_SGIX_swap_group")) { 209706f2543Smrg strcat(ExtensionsString, "GLX_SGIX_swap_group"); 210706f2543Smrg if (!denied_extensions || 211706f2543Smrg !strstr(denied_extensions, "GLX_SGIX_swap_barrier")) { 212706f2543Smrg strcat(ExtensionsString, " GLX_SGIX_swap_barrier"); 213706f2543Smrg } 214706f2543Smrg } 215706f2543Smrg } 216706f2543Smrg 217706f2543Smrg} 218706f2543Smrg 219706f2543Smrgvoid __glXScreenInit(GLint numscreens) 220706f2543Smrg{ 221706f2543Smrg int s; 222706f2543Smrg int c; 223706f2543Smrg DMXScreenInfo *dmxScreen0 = &dmxScreens[0]; 224706f2543Smrg __glXNumActiveScreens = numscreens; 225706f2543Smrg 226706f2543Smrg 227706f2543Smrg CalcServerVersionAndExtensions(); 228706f2543Smrg 229706f2543Smrg 230706f2543Smrg __glXFBConfigs = NULL; 231706f2543Smrg __glXNumFBConfigs = 0; 232706f2543Smrg 233706f2543Smrg if ( (__glXVersionMajor == 1 && __glXVersionMinor >= 3) || 234706f2543Smrg (__glXVersionMajor > 1) || 235706f2543Smrg ( strstr(ExtensionsString, "GLX_SGIX_fbconfig") ) ) { 236706f2543Smrg 237706f2543Smrg /* 238706f2543Smrg // Initialize FBConfig info. 239706f2543Smrg // find the set of FBConfigs that are present on all back-end 240706f2543Smrg // servers - only those configs will be supported 241706f2543Smrg */ 242706f2543Smrg __glXFBConfigs = (__GLXFBConfig **)malloc( dmxScreen0->numFBConfigs * 243706f2543Smrg (numscreens+1) * sizeof(__GLXFBConfig *) ); 244706f2543Smrg __glXNumFBConfigs = 0; 245706f2543Smrg 246706f2543Smrg for (c=0; c<dmxScreen0->numFBConfigs; c++) { 247706f2543Smrg __GLXFBConfig *cfg = NULL; 248706f2543Smrg 249706f2543Smrg if (numscreens > 1) { 250706f2543Smrg for (s=1; s<numscreens; s++) { 251706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[s]; 252706f2543Smrg 253706f2543Smrg cfg = FindMatchingFBConfig( &dmxScreen0->fbconfigs[c], 254706f2543Smrg dmxScreen->fbconfigs, 255706f2543Smrg dmxScreen->numFBConfigs ); 256706f2543Smrg __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + s + 1 ] = cfg; 257706f2543Smrg if (!cfg) { 258706f2543Smrg dmxLog(dmxInfo,"screen0 FBConfig 0x%x is missing on screen#%d\n", dmxScreen0->fbconfigs[c].id, s); 259706f2543Smrg break; 260706f2543Smrg } 261706f2543Smrg else { 262706f2543Smrg dmxLog(dmxInfo,"screen0 FBConfig 0x%x matched to 0x%x on screen#%d\n", dmxScreen0->fbconfigs[c].id, cfg->id, s); 263706f2543Smrg } 264706f2543Smrg } 265706f2543Smrg } 266706f2543Smrg else { 267706f2543Smrg cfg = &dmxScreen0->fbconfigs[c]; 268706f2543Smrg } 269706f2543Smrg 270706f2543Smrg if (cfg) { 271706f2543Smrg 272706f2543Smrg /* filter out overlay visuals */ 273706f2543Smrg if (cfg->level == 0) { 274706f2543Smrg __GLXFBConfig *proxy_cfg; 275706f2543Smrg 276706f2543Smrg __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 1 ] = 277706f2543Smrg &dmxScreen0->fbconfigs[c]; 278706f2543Smrg 279706f2543Smrg proxy_cfg = malloc( sizeof(__GLXFBConfig) ); 280706f2543Smrg memcpy( proxy_cfg, cfg, sizeof(__GLXFBConfig) ); 281706f2543Smrg proxy_cfg->id = FakeClientID(0); 282706f2543Smrg /* visual will be associated later in __glXGetFBConfigs */ 283706f2543Smrg proxy_cfg->associatedVisualId = (unsigned int)-1; 284706f2543Smrg 285706f2543Smrg __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 0 ] = proxy_cfg; 286706f2543Smrg 287706f2543Smrg __glXNumFBConfigs++; 288706f2543Smrg } 289706f2543Smrg 290706f2543Smrg } 291706f2543Smrg 292706f2543Smrg } 293706f2543Smrg 294706f2543Smrg } 295706f2543Smrg 296706f2543Smrg} 297706f2543Smrg 298706f2543Smrgvoid __glXScreenReset(void) 299706f2543Smrg{ 300706f2543Smrg __glXNumActiveScreens = 0; 301706f2543Smrg} 302706f2543Smrg 303706f2543Smrgchar *__glXGetServerString( unsigned int name ) 304706f2543Smrg{ 305706f2543Smrg char *ret = NULL; 306706f2543Smrg 307706f2543Smrg switch( name) { 308706f2543Smrg 309706f2543Smrg case GLX_VENDOR: 310706f2543Smrg ret = GLXServerVendorName; 311706f2543Smrg break; 312706f2543Smrg 313706f2543Smrg case GLX_VERSION: 314706f2543Smrg ret = GLXServerVersion; 315706f2543Smrg break; 316706f2543Smrg 317706f2543Smrg case GLX_EXTENSIONS: 318706f2543Smrg ret = ExtensionsString; 319706f2543Smrg break; 320706f2543Smrg 321706f2543Smrg default: 322706f2543Smrg break; 323706f2543Smrg } 324706f2543Smrg 325706f2543Smrg return ret; 326706f2543Smrg 327706f2543Smrg} 328706f2543Smrg 329706f2543Smrg 330706f2543Smrg__GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id ) 331706f2543Smrg{ 332706f2543Smrg int i,j; 333706f2543Smrg 334706f2543Smrg for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) { 335706f2543Smrg if ( __glXFBConfigs[j]->id == id) 336706f2543Smrg return __glXFBConfigs[j]; 337706f2543Smrg } 338706f2543Smrg 339706f2543Smrg return NULL; 340706f2543Smrg} 341706f2543Smrg 342706f2543Smrg__GLXFBConfig *glxLookupFBConfigByVID( VisualID vid ) 343706f2543Smrg{ 344706f2543Smrg int i,j; 345706f2543Smrg 346706f2543Smrg for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) { 347706f2543Smrg if ( __glXFBConfigs[j]->associatedVisualId == vid) 348706f2543Smrg return __glXFBConfigs[j]; 349706f2543Smrg } 350706f2543Smrg 351706f2543Smrg return NULL; 352706f2543Smrg} 353706f2543Smrg 354706f2543Smrg__GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen ) 355706f2543Smrg{ 356706f2543Smrg int i; 357706f2543Smrg int j; 358706f2543Smrg 359706f2543Smrg for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) { 360706f2543Smrg if ( __glXFBConfigs[j]->id == id) 361706f2543Smrg return __glXFBConfigs[j+screen+1]; 362706f2543Smrg } 363706f2543Smrg 364706f2543Smrg return NULL; 365706f2543Smrg 366706f2543Smrg} 367706f2543Smrg 368706f2543Smrgint glxIsExtensionSupported( char *ext ) 369706f2543Smrg{ 370706f2543Smrg return( strstr(ExtensionsString, ext) != NULL ); 371706f2543Smrg} 372