1/* 2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice including the dates of first publication and 13 * either this permission notice or a reference to 14 * http://oss.sgi.com/projects/FreeB/ 15 * shall be included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Except as contained in this notice, the name of Silicon Graphics, Inc. 26 * shall not be used in advertising or otherwise to promote the sale, use or 27 * other dealings in this Software without prior written authorization from 28 * Silicon Graphics, Inc. 29 */ 30 31#ifdef HAVE_DMX_CONFIG_H 32#include <dmx-config.h> 33#endif 34 35#include "dmx.h" 36#include "dmxlog.h" 37 38#include "glxserver.h" 39 40#include <windowstr.h> 41 42#include "glxfbconfig.h" 43 44#ifdef PANORAMIX 45#include "panoramiXsrv.h" 46#endif 47 48__GLXscreenInfo *__glXActiveScreens; 49GLint __glXNumActiveScreens; 50 51__GLXFBConfig **__glXFBConfigs; 52int __glXNumFBConfigs; 53 54static char GLXServerVendorName[] = "SGI DMX/glxProxy"; 55static char GLXServerVersion[64]; 56static char GLXServerExtensions[] = 57 "GLX_EXT_visual_info " 58 "GLX_EXT_visual_rating " 59 "GLX_EXT_import_context " 60 "GLX_SGIX_fbconfig " 61 "GLX_SGI_make_current_read " 62 "GLX_SGI_swap_control " 63 ; 64 65static char ExtensionsString[1024]; 66 67static void CalcServerVersionAndExtensions( void ) 68{ 69 int s; 70 xGLXQueryVersionReq *req; 71 xGLXQueryVersionReply reply; 72 char **be_extensions; 73 char *ext; 74 char *denied_extensions; 75 76 /* 77 * set the server glx version to be the minimum version 78 * supported by all back-end servers 79 */ 80 __glXVersionMajor = 0; 81 __glXVersionMinor = 0; 82 for (s=0; s<__glXNumActiveScreens; s++) { 83 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 84 Display *dpy = dmxScreen->beDisplay; 85 86 /* Send the glXQueryVersion request */ 87 LockDisplay(dpy); 88 GetReq(GLXQueryVersion,req); 89 req->reqType = dmxScreen->glxMajorOpcode; 90 req->glxCode = X_GLXQueryVersion; 91 req->majorVersion = GLX_SERVER_MAJOR_VERSION; 92 req->minorVersion = GLX_SERVER_MINOR_VERSION; 93 _XReply(dpy, (xReply*) &reply, 0, False); 94 UnlockDisplay(dpy); 95 SyncHandle(); 96 97 if (s == 0) { 98 __glXVersionMajor = reply.majorVersion; 99 __glXVersionMinor = reply.minorVersion; 100 } 101 else { 102 if (reply.majorVersion < __glXVersionMajor) { 103 __glXVersionMajor = reply.majorVersion; 104 __glXVersionMinor = reply.minorVersion; 105 } 106 else if ( (reply.majorVersion == __glXVersionMajor) && 107 (reply.minorVersion < __glXVersionMinor) ) { 108 __glXVersionMinor = reply.minorVersion; 109 } 110 } 111 112 } 113 114 if (GLX_SERVER_MAJOR_VERSION < __glXVersionMajor) { 115 __glXVersionMajor = GLX_SERVER_MAJOR_VERSION; 116 __glXVersionMinor = GLX_SERVER_MINOR_VERSION; 117 } 118 else if ( (GLX_SERVER_MAJOR_VERSION == __glXVersionMajor) && 119 (GLX_SERVER_MINOR_VERSION < __glXVersionMinor) ) { 120 __glXVersionMinor = GLX_SERVER_MINOR_VERSION; 121 } 122 123 sprintf(GLXServerVersion, "%d.%d DMX %d back-end server(s)", 124 __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens ); 125 /* 126 * set the ExtensionsString to the minimum extensions string 127 */ 128 ExtensionsString[0] = '\0'; 129 130 /* 131 * read extensions strings of all back-end servers 132 */ 133 be_extensions = (char **)malloc( __glXNumActiveScreens * sizeof(char *) ); 134 if (!be_extensions) 135 return; 136 137 for (s=0; s<__glXNumActiveScreens; s++) { 138 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 139 Display *dpy = dmxScreen->beDisplay; 140 xGLXQueryServerStringReq *req; 141 xGLXQueryServerStringReply reply; 142 int length, numbytes, slop; 143 144 /* Send the glXQueryServerString request */ 145 LockDisplay(dpy); 146 GetReq(GLXQueryServerString,req); 147 req->reqType = dmxScreen->glxMajorOpcode; 148 req->glxCode = X_GLXQueryServerString; 149 req->screen = DefaultScreen(dpy); 150 req->name = GLX_EXTENSIONS; 151 _XReply(dpy, (xReply*) &reply, 0, False); 152 153 length = (int)reply.length; 154 numbytes = (int)reply.n; 155 slop = numbytes * __GLX_SIZE_INT8 & 3; 156 be_extensions[s] = (char *)malloc(numbytes); 157 if (!be_extensions[s]) { 158 /* Throw data on the floor */ 159 _XEatData(dpy, length); 160 } else { 161 _XRead(dpy, (char *)be_extensions[s], numbytes); 162 if (slop) _XEatData(dpy,4-slop); 163 } 164 UnlockDisplay(dpy); 165 SyncHandle(); 166 } 167 168 /* 169 * extensions string will include only extensions that our 170 * server supports as well as all back-end servers supports. 171 * extensions that are in the DMX_DENY_EXTENSIONS string will 172 * not be supported. 173 */ 174 denied_extensions = getenv("DMX_DENY_GLX_EXTENSIONS"); 175 ext = strtok(GLXServerExtensions, " "); 176 while( ext ) { 177 int supported = 1; 178 179 if (denied_extensions && strstr(denied_extensions, ext)) { 180 supported = 0; 181 } 182 else { 183 for (s=0; s<__glXNumActiveScreens && supported; s++) { 184 if ( !strstr(be_extensions[s], ext) ) { 185 supported = 0; 186 } 187 } 188 } 189 190 if (supported) { 191 strcat(ExtensionsString, ext); 192 strcat(ExtensionsString, " "); 193 } 194 195 ext = strtok(NULL, " "); 196 } 197 198 /* 199 * release temporary storage 200 */ 201 for (s=0; s<__glXNumActiveScreens; s++) { 202 free(be_extensions[s]); 203 } 204 free( be_extensions ); 205 206 if (dmxGLXSwapGroupSupport) { 207 if (!denied_extensions || 208 !strstr(denied_extensions, "GLX_SGIX_swap_group")) { 209 strcat(ExtensionsString, "GLX_SGIX_swap_group"); 210 if (!denied_extensions || 211 !strstr(denied_extensions, "GLX_SGIX_swap_barrier")) { 212 strcat(ExtensionsString, " GLX_SGIX_swap_barrier"); 213 } 214 } 215 } 216 217} 218 219void __glXScreenInit(GLint numscreens) 220{ 221 int s; 222 int c; 223 DMXScreenInfo *dmxScreen0 = &dmxScreens[0]; 224 __glXNumActiveScreens = numscreens; 225 226 227 CalcServerVersionAndExtensions(); 228 229 230 __glXFBConfigs = NULL; 231 __glXNumFBConfigs = 0; 232 233 if ( (__glXVersionMajor == 1 && __glXVersionMinor >= 3) || 234 (__glXVersionMajor > 1) || 235 ( strstr(ExtensionsString, "GLX_SGIX_fbconfig") ) ) { 236 237 /* 238 // Initialize FBConfig info. 239 // find the set of FBConfigs that are present on all back-end 240 // servers - only those configs will be supported 241 */ 242 __glXFBConfigs = (__GLXFBConfig **)malloc( dmxScreen0->numFBConfigs * 243 (numscreens+1) * sizeof(__GLXFBConfig *) ); 244 __glXNumFBConfigs = 0; 245 246 for (c=0; c<dmxScreen0->numFBConfigs; c++) { 247 __GLXFBConfig *cfg = NULL; 248 249 if (numscreens > 1) { 250 for (s=1; s<numscreens; s++) { 251 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 252 253 cfg = FindMatchingFBConfig( &dmxScreen0->fbconfigs[c], 254 dmxScreen->fbconfigs, 255 dmxScreen->numFBConfigs ); 256 __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + s + 1 ] = cfg; 257 if (!cfg) { 258 dmxLog(dmxInfo,"screen0 FBConfig 0x%x is missing on screen#%d\n", dmxScreen0->fbconfigs[c].id, s); 259 break; 260 } 261 else { 262 dmxLog(dmxInfo,"screen0 FBConfig 0x%x matched to 0x%x on screen#%d\n", dmxScreen0->fbconfigs[c].id, cfg->id, s); 263 } 264 } 265 } 266 else { 267 cfg = &dmxScreen0->fbconfigs[c]; 268 } 269 270 if (cfg) { 271 272 /* filter out overlay visuals */ 273 if (cfg->level == 0) { 274 __GLXFBConfig *proxy_cfg; 275 276 __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 1 ] = 277 &dmxScreen0->fbconfigs[c]; 278 279 proxy_cfg = malloc( sizeof(__GLXFBConfig) ); 280 memcpy( proxy_cfg, cfg, sizeof(__GLXFBConfig) ); 281 proxy_cfg->id = FakeClientID(0); 282 /* visual will be associated later in __glXGetFBConfigs */ 283 proxy_cfg->associatedVisualId = (unsigned int)-1; 284 285 __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 0 ] = proxy_cfg; 286 287 __glXNumFBConfigs++; 288 } 289 290 } 291 292 } 293 294 } 295 296} 297 298void __glXScreenReset(void) 299{ 300 __glXNumActiveScreens = 0; 301} 302 303char *__glXGetServerString( unsigned int name ) 304{ 305 char *ret = NULL; 306 307 switch( name) { 308 309 case GLX_VENDOR: 310 ret = GLXServerVendorName; 311 break; 312 313 case GLX_VERSION: 314 ret = GLXServerVersion; 315 break; 316 317 case GLX_EXTENSIONS: 318 ret = ExtensionsString; 319 break; 320 321 default: 322 break; 323 } 324 325 return ret; 326 327} 328 329 330__GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id ) 331{ 332 int i,j; 333 334 for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) { 335 if ( __glXFBConfigs[j]->id == id) 336 return __glXFBConfigs[j]; 337 } 338 339 return NULL; 340} 341 342__GLXFBConfig *glxLookupFBConfigByVID( VisualID vid ) 343{ 344 int i,j; 345 346 for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) { 347 if ( __glXFBConfigs[j]->associatedVisualId == vid) 348 return __glXFBConfigs[j]; 349 } 350 351 return NULL; 352} 353 354__GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen ) 355{ 356 int i; 357 int j; 358 359 for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) { 360 if ( __glXFBConfigs[j]->id == id) 361 return __glXFBConfigs[j+screen+1]; 362 } 363 364 return NULL; 365 366} 367 368int glxIsExtensionSupported( char *ext ) 369{ 370 return( strstr(ExtensionsString, ext) != NULL ); 371} 372