1 } 2 3 #endif /* _WIN32 */ 4 5 /* ------------------------------------------------------------------------ */ 6 7 int main (int argc, char** argv) 8 { 9 GLuint err; 10 struct createParams params = 11 { 12 #if defined(GLEW_OSMESA) 13 #elif defined(GLEW_EGL) 14 #elif defined(_WIN32) 15 -1, /* pixelformat */ 16 #elif !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX) 17 "", /* display */ 18 -1, /* visual */ 19 #endif 20 0, /* major */ 21 0, /* minor */ 22 0, /* profile mask */ 23 0, /* flags */ 24 0 /* experimental */ 25 }; 26 27 #if defined(GLEW_EGL) 28 typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGPROC) (GLenum name); 29 PFNGLGETSTRINGPROC getString; 30 #endif 31 32 if (glewParseArgs(argc-1, argv+1, ¶ms)) 33 { 34 fprintf(stderr, "Usage: glewinfo " 35 #if defined(GLEW_OSMESA) 36 #elif defined(GLEW_EGL) 37 #elif defined(_WIN32) 38 "[-pf <pixelformat>] " 39 #elif !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX) 40 "[-display <display>] " 41 "[-visual <visual id>] " 42 #endif 43 "[-version <OpenGL version>] " 44 "[-profile core|compatibility] " 45 "[-flag debug|forward] " 46 "[-experimental]" 47 "\n"); 48 return 1; 49 } 50 51 if (GL_TRUE == glewCreateContext(¶ms)) 52 { 53 fprintf(stderr, "Error: glewCreateContext failed\n"); 54 glewDestroyContext(); 55 return 1; 56 } 57 glewExperimental = params.experimental ? GL_TRUE : GL_FALSE; 58 err = glewInit(); 59 if (GLEW_OK != err) 60 { 61 fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); 62 glewDestroyContext(); 63 return 1; 64 } 65 66 #if defined(GLEW_EGL) 67 getString = (PFNGLGETSTRINGPROC) eglGetProcAddress("glGetString"); 68 if (!getString) 69 { 70 fprintf(stderr, "Error: eglGetProcAddress failed to fetch glGetString\n"); 71 glewDestroyContext(); 72 return 1; 73 } 74 #endif 75 76 #if defined(_WIN32) 77 #if defined(_MSC_VER) && (_MSC_VER >= 1400) 78 if (fopen_s(&f, "glewinfo.txt", "w") != 0) 79 f = stdout; 80 #else 81 f = fopen("glewinfo.txt", "w"); 82 #endif 83 if (f == NULL) f = stdout; 84 #else 85 f = stdout; 86 #endif 87 fprintf(f, "---------------------------\n"); 88 fprintf(f, " GLEW Extension Info\n"); 89 fprintf(f, "---------------------------\n\n"); 90 fprintf(f, "GLEW version %s\n", glewGetString(GLEW_VERSION)); 91 #if defined(GLEW_OSMESA) 92 #elif defined(GLEW_EGL) 93 #elif defined(_WIN32) 94 fprintf(f, "Reporting capabilities of pixelformat %d\n", params.pixelformat); 95 #elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) 96 fprintf(f, "Reporting capabilities of display %s, visual 0x%x\n", 97 params.display == NULL ? getenv("DISPLAY") : params.display, params.visual); 98 #endif 99 #if defined(GLEW_EGL) 100 fprintf(f, "Running on a %s from %s\n", 101 getString(GL_RENDERER), getString(GL_VENDOR)); 102 fprintf(f, "OpenGL version %s is supported\n", getString(GL_VERSION)); 103 #else 104 fprintf(f, "Running on a %s from %s\n", 105 glGetString(GL_RENDERER), glGetString(GL_VENDOR)); 106 fprintf(f, "OpenGL version %s is supported\n", glGetString(GL_VERSION)); 107 #endif 108 glewInfo(); 109 #if defined(GLEW_OSMESA) 110 #elif defined(GLEW_EGL) 111 eglewInfo(); 112 #elif defined(_WIN32) 113 wglewInfo(); 114 #else 115 glxewInfo(); 116 #endif 117 if (f != stdout) fclose(f); 118 glewDestroyContext(); 119 return 0; 120 } 121 122 /* ------------------------------------------------------------------------ */ 123 124 GLboolean glewParseArgs (int argc, char** argv, struct createParams *params) 125 { 126 int p = 0; 127 while (p < argc) 128 { 129 if (!strcmp(argv[p], "-version")) 130 { 131 if (++p >= argc) return GL_TRUE; 132 #if defined(__STDC_LIB_EXT1__) || (defined(_MSC_VER) && (_MSC_VER >= 1400)) 133 if (sscanf_s(argv[p++], "%d.%d", ¶ms->major, ¶ms->minor) != 2) return GL_TRUE; 134 #else 135 if (sscanf(argv[p++], "%d.%d", ¶ms->major, ¶ms->minor) != 2) return GL_TRUE; 136 #endif 137 } 138 else if (!strcmp(argv[p], "-profile")) 139 { 140 if (++p >= argc) return GL_TRUE; 141 if (strcmp("core", argv[p]) == 0) params->profile |= 1; 142 else if (strcmp("compatibility",argv[p]) == 0) params->profile |= 2; 143 else return GL_TRUE; 144 ++p; 145 } 146 else if (!strcmp(argv[p], "-flag")) 147 { 148 if (++p >= argc) return GL_TRUE; 149 if (strcmp("debug", argv[p]) == 0) params->flags |= 1; 150 else if (strcmp("forward",argv[p]) == 0) params->flags |= 2; 151 else return GL_TRUE; 152 ++p; 153 } 154 #if defined(GLEW_OSMESA) 155 #elif defined(GLEW_EGL) 156 #elif defined(_WIN32) 157 else if (!strcmp(argv[p], "-pf") || !strcmp(argv[p], "-pixelformat")) 158 { 159 if (++p >= argc) return GL_TRUE; 160 params->pixelformat = strtol(argv[p++], NULL, 0); 161 } 162 #elif !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX) 163 else if (!strcmp(argv[p], "-display")) 164 { 165 if (++p >= argc) return GL_TRUE; 166 params->display = argv[p++]; 167 } 168 else if (!strcmp(argv[p], "-visual")) 169 { 170 if (++p >= argc) return GL_TRUE; 171 params->visual = (int)strtol(argv[p++], NULL, 0); 172 } 173 #endif 174 else if (!strcmp(argv[p], "-experimental")) 175 { 176 params->experimental = 1; 177 ++p; 178 } 179 else 180 return GL_TRUE; 181 } 182 return GL_FALSE; 183 } 184 185 /* ------------------------------------------------------------------------ */ 186 187 #if defined(GLEW_EGL) 188 EGLDisplay display; 189 EGLContext ctx; 190 191 /* See: http://stackoverflow.com/questions/12662227/opengl-es2-0-offscreen-context-for-fbo-rendering */ 192 193 GLboolean glewCreateContext (struct createParams *params) 194 { 195 EGLDeviceEXT devices[1]; 196 EGLint numDevices; 197 EGLSurface surface; 198 EGLint majorVersion, minorVersion; 199 EGLint configAttribs[] = { 200 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 201 EGL_RED_SIZE, 1, 202 EGL_GREEN_SIZE, 1, 203 EGL_BLUE_SIZE, 1, 204 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, 205 EGL_NONE 206 }; 207 static const EGLint contextAttribs[] = { 208 EGL_CONTEXT_CLIENT_VERSION, 2, 209 EGL_NONE 210 }; 211 static const EGLint pBufferAttribs[] = { 212 EGL_WIDTH, 128, 213 EGL_HEIGHT, 128, 214 EGL_NONE 215 }; 216 EGLConfig config; 217 EGLint numConfig; 218 EGLBoolean pBuffer; 219 220 PFNEGLQUERYDEVICESEXTPROC queryDevices = NULL; 221 PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = NULL; 222 PFNEGLGETERRORPROC getError = NULL; 223 PFNEGLGETDISPLAYPROC getDisplay = NULL; 224 PFNEGLINITIALIZEPROC initialize = NULL; 225 PFNEGLBINDAPIPROC bindAPI = NULL; 226 PFNEGLCHOOSECONFIGPROC chooseConfig = NULL; 227 PFNEGLCREATEWINDOWSURFACEPROC createWindowSurface = NULL; 228 PFNEGLCREATECONTEXTPROC createContext = NULL; 229 PFNEGLMAKECURRENTPROC makeCurrent = NULL; 230 PFNEGLCREATEPBUFFERSURFACEPROC createPbufferSurface = NULL; 231 232 /* Load necessary entry points */ 233 queryDevices = (PFNEGLQUERYDEVICESEXTPROC) eglGetProcAddress("eglQueryDevicesEXT"); 234 getPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress("eglGetPlatformDisplayEXT"); 235 getError = (PFNEGLGETERRORPROC) eglGetProcAddress("eglGetError"); 236 getDisplay = (PFNEGLGETDISPLAYPROC) eglGetProcAddress("eglGetDisplay"); 237 initialize = (PFNEGLINITIALIZEPROC) eglGetProcAddress("eglInitialize"); 238 bindAPI = (PFNEGLBINDAPIPROC) eglGetProcAddress("eglBindAPI"); 239 chooseConfig = (PFNEGLCHOOSECONFIGPROC) eglGetProcAddress("eglChooseConfig"); 240 createWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC) eglGetProcAddress("eglCreateWindowSurface"); 241 createPbufferSurface = (PFNEGLCREATEPBUFFERSURFACEPROC) eglGetProcAddress("eglCreatePbufferSurface"); 242 createContext = (PFNEGLCREATECONTEXTPROC) eglGetProcAddress("eglCreateContext"); 243 makeCurrent = (PFNEGLMAKECURRENTPROC) eglGetProcAddress("eglMakeCurrent"); 244 if (!getError || !getDisplay || !initialize || !bindAPI || !chooseConfig || !createWindowSurface || !createContext || !makeCurrent) 245 return GL_TRUE; 246 247 pBuffer = 0; 248 display = EGL_NO_DISPLAY; 249 if (queryDevices && getPlatformDisplay) 250 { 251 queryDevices(1, devices, &numDevices); 252 if (numDevices==1) 253 { 254 /* Nvidia EGL doesn't need X11 for p-buffer surface */ 255 display = getPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, devices[0], 0); 256 configAttribs[1] = EGL_PBUFFER_BIT; 257 pBuffer = 1; 258 } 259 } 260 if (display==EGL_NO_DISPLAY) 261 { 262 /* Fall-back to X11 surface, works on Mesa */ 263 display = getDisplay(EGL_DEFAULT_DISPLAY); 264 } 265 if (display == EGL_NO_DISPLAY) 266 return GL_TRUE; 267 268 eglewInit(display); 269 270 if (bindAPI(EGL_OPENGL_API) != EGL_TRUE) 271 return GL_TRUE; 272 273 if (chooseConfig(display, configAttribs, &config, 1, &numConfig) != EGL_TRUE || (numConfig != 1)) 274 return GL_TRUE; 275 276 ctx = createContext(display, config, EGL_NO_CONTEXT, pBuffer ? contextAttribs : NULL); 277 if (NULL == ctx) 278 return GL_TRUE; 279 280 surface = EGL_NO_SURFACE; 281 /* Create a p-buffer surface if possible */ 282 if (pBuffer && createPbufferSurface) 283 { 284 surface = createPbufferSurface(display, config, pBufferAttribs); 285 } 286 /* Create a generic surface without a native window, if necessary */ 287 if (surface==EGL_NO_SURFACE) 288 { 289 surface = createWindowSurface(display, config, (EGLNativeWindowType) NULL, NULL); 290 } 291 #if 0 292 if (surface == EGL_NO_SURFACE) 293 return GL_TRUE; 294 #endif 295 296 if (makeCurrent(display, surface, surface, ctx) != EGL_TRUE) 297 return GL_TRUE; 298 299 return GL_FALSE; 300 } 301 302 void glewDestroyContext () 303 { 304 if (NULL != ctx) eglDestroyContext(display, ctx); 305 } 306 307 #elif defined(GLEW_OSMESA) 308 OSMesaContext ctx; 309 310 static const GLint osmFormat = GL_UNSIGNED_BYTE; 311 static const GLint osmWidth = 640; 312 static const GLint osmHeight = 480; 313 static GLubyte *osmPixels = NULL; 314 315 GLboolean glewCreateContext (struct createParams *params) 316 { 317 ctx = OSMesaCreateContext(OSMESA_RGBA, NULL); 318 if (NULL == ctx) return GL_TRUE; 319 if (NULL == osmPixels) 320 { 321 osmPixels = (GLubyte *) calloc(osmWidth*osmHeight*4, 1); 322 } 323 if (!OSMesaMakeCurrent(ctx, osmPixels, GL_UNSIGNED_BYTE, osmWidth, osmHeight)) 324 { 325 return GL_TRUE; 326 } 327 return GL_FALSE; 328 } 329 330 void glewDestroyContext () 331 { 332 if (NULL != ctx) OSMesaDestroyContext(ctx); 333 } 334 335 #elif defined(_WIN32) 336 337 HWND wnd = NULL; 338 HDC dc = NULL; 339 HGLRC rc = NULL; 340 341 GLboolean glewCreateContext (struct createParams* params) 342 { 343 WNDCLASS wc; 344 PIXELFORMATDESCRIPTOR pfd; 345 /* register window class */ 346 ZeroMemory(&wc, sizeof(WNDCLASS)); 347 wc.hInstance = GetModuleHandle(NULL); 348 wc.lpfnWndProc = DefWindowProc; 349 wc.lpszClassName = "GLEW"; 350 if (0 == RegisterClass(&wc)) return GL_TRUE; 351 /* create window */ 352 wnd = CreateWindow("GLEW", "GLEW", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 353 CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL); 354 if (NULL == wnd) return GL_TRUE; 355 /* get the device context */ 356 dc = GetDC(wnd); 357 if (NULL == dc) return GL_TRUE; 358 /* find pixel format */ 359 ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); 360 if (params->pixelformat == -1) /* find default */ 361 { 362 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 363 pfd.nVersion = 1; 364 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; 365 params->pixelformat = ChoosePixelFormat(dc, &pfd); 366 if (params->pixelformat == 0) return GL_TRUE; 367 } 368 /* set the pixel format for the dc */ 369 if (FALSE == SetPixelFormat(dc, params->pixelformat, &pfd)) return GL_TRUE; 370 /* create rendering context */ 371 rc = wglCreateContext(dc); 372 if (NULL == rc) return GL_TRUE; 373 if (FALSE == wglMakeCurrent(dc, rc)) return GL_TRUE; 374 if (params->major || params->profile || params->flags) 375 { 376 HGLRC oldRC = rc; 377 int contextAttrs[20]; 378 int i; 379 380 wglewInit(); 381 382 /* Intel HD 3000 has WGL_ARB_create_context, but not WGL_ARB_create_context_profile */ 383 if (!wglewGetExtension("WGL_ARB_create_context")) 384 return GL_TRUE; 385 386 i = 0; 387 if (params->major) 388 { 389 contextAttrs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; 390 contextAttrs[i++] = params->major; 391 contextAttrs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; 392 contextAttrs[i++] = params->minor; 393 } 394 if (params->profile) 395 { 396 contextAttrs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; 397 contextAttrs[i++] = params->profile; 398 } 399 if (params->flags) 400 { 401 contextAttrs[i++] = WGL_CONTEXT_FLAGS_ARB; 402 contextAttrs[i++] = params->flags; 403 } 404 contextAttrs[i++] = 0; 405 rc = wglCreateContextAttribsARB(dc, 0, contextAttrs); 406 407 if (NULL == rc) return GL_TRUE; 408 if (!wglMakeCurrent(dc, rc)) return GL_TRUE; 409 410 wglDeleteContext(oldRC); 411 } 412 return GL_FALSE; 413 } 414 415 void glewDestroyContext () 416 { 417 if (NULL != rc) wglMakeCurrent(NULL, NULL); 418 if (NULL != rc) wglDeleteContext(rc); 419 if (NULL != wnd && NULL != dc) ReleaseDC(wnd, dc); 420 if (NULL != wnd) DestroyWindow(wnd); 421 UnregisterClass("GLEW", GetModuleHandle(NULL)); 422 } 423 424 /* ------------------------------------------------------------------------ */ 425 426 #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) 427 428 #include <OpenGL/OpenGL.h> 429 #include <OpenGL/CGLTypes.h> 430 431 CGLContextObj ctx, octx; 432 433 GLboolean glewCreateContext (struct createParams *params) 434 { 435 CGLPixelFormatAttribute contextAttrs[20]; 436 int i; 437 CGLPixelFormatObj pf; 438 GLint npix; 439 CGLError error; 440 441 i = 0; 442 contextAttrs[i++] = kCGLPFAAccelerated; /* No software rendering */ 443 444 /* MAC_OS_X_VERSION_10_7 == 1070 */ 445 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 446 if (params->profile & GL_CONTEXT_CORE_PROFILE_BIT) 447 { 448 if ((params->major==3 && params->minor>=2) || params->major>3) 449 { 450 contextAttrs[i++] = kCGLPFAOpenGLProfile; /* OSX 10.7 Lion onwards */ 451 contextAttrs[i++] = (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core; /* 3.2 Core Context */ 452 } 453 } 454 #endif 455 456 contextAttrs[i++] = 0; 457 458 error = CGLChoosePixelFormat(contextAttrs, &pf, &npix); 459 if (error) return GL_TRUE; 460 error = CGLCreateContext(pf, NULL, &ctx); 461 if (error) return GL_TRUE; 462 CGLReleasePixelFormat(pf); 463 octx = CGLGetCurrentContext(); 464 error = CGLSetCurrentContext(ctx); 465 if (error) return GL_TRUE; 466 /* Needed for Regal on the Mac */ 467 #if defined(GLEW_REGAL) && defined(__APPLE__) 468 RegalMakeCurrent(ctx); 469 #endif 470 return GL_FALSE; 471 } 472 473 void glewDestroyContext () 474 { 475 CGLSetCurrentContext(octx); 476 CGLReleaseContext(ctx); 477 } 478 479 /* ------------------------------------------------------------------------ */ 480 481 #elif defined(__HAIKU__) 482 483 GLboolean glewCreateContext (struct createParams *params) 484 { 485 /* TODO: Haiku: We need to call C++ code here */ 486 return GL_FALSE; 487 } 488 489 void glewDestroyContext () 490 { 491 /* TODO: Haiku: We need to call C++ code here */ 492 } 493 494 /* ------------------------------------------------------------------------ */ 495 496 #else /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ 497 498 Display* dpy = NULL; 499 XVisualInfo* vi = NULL; 500 XVisualInfo* vis = NULL; 501 GLXContext ctx = NULL; 502 Window wnd = 0; 503 Colormap cmap = 0; 504 505 GLboolean glewCreateContext (struct createParams *params) 506 { 507 int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; 508 int erb, evb; 509 XSetWindowAttributes swa; 510 /* open display */ 511 dpy = XOpenDisplay(params->display); 512 if (NULL == dpy) return GL_TRUE; 513 /* query for glx */ 514 if (!glXQueryExtension(dpy, &erb, &evb)) return GL_TRUE; 515 /* choose visual */ 516 if (params->visual == -1) 517 { 518 vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrib); 519 if (NULL == vi) return GL_TRUE; 520 params->visual = (int)XVisualIDFromVisual(vi->visual); 521 } 522 else 523 { 524 int n_vis, i; 525 vis = XGetVisualInfo(dpy, 0, NULL, &n_vis); 526 for (i=0; i<n_vis; i++) 527 { 528 if ((int)XVisualIDFromVisual(vis[i].visual) == params->visual) 529 vi = &vis[i]; 530 } 531 if (vi == NULL) return GL_TRUE; 532 } 533 /* create context */ 534 ctx = glXCreateContext(dpy, vi, None, True); 535 if (NULL == ctx) return GL_TRUE; 536 /* create window */ 537 /*wnd = XCreateSimpleWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 1, 0, 0);*/ 538 cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); 539 swa.border_pixel = 0; 540 swa.colormap = cmap; 541 wnd = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 542 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, 543 CWBorderPixel | CWColormap, &swa); 544 /* make context current */ 545 if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; 546 if (params->major || params->profile || params->flags) 547 { 548 GLXContext oldCtx = ctx; 549 GLXFBConfig *FBConfigs; 550 int FBConfigAttrs[] = { GLX_FBCONFIG_ID, 0, None }; 551 int contextAttrs[20]; 552 int nelems, i; 553 554 glxewInit(); 555 556 if (!glxewGetExtension("GLX_ARB_create_context")) 557 return GL_TRUE; 558 559 if (glXQueryContext(dpy, oldCtx, GLX_FBCONFIG_ID, &FBConfigAttrs[1])) 560 return GL_TRUE; 561 FBConfigs = glXChooseFBConfig(dpy, vi->screen, FBConfigAttrs, &nelems); 562 563 if (nelems < 1) 564 return GL_TRUE; 565 566 i = 0; 567 if (params->major) 568 { 569 contextAttrs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; 570 contextAttrs[i++] = params->major; 571 contextAttrs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; 572 contextAttrs[i++] = params->minor; 573 } 574 if (params->profile) 575 { 576 contextAttrs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; 577 contextAttrs[i++] = params->profile; 578 } 579 if (params->flags) 580 { 581 contextAttrs[i++] = GLX_CONTEXT_FLAGS_ARB; 582 contextAttrs[i++] = params->flags; 583 } 584 contextAttrs[i++] = None; 585 ctx = glXCreateContextAttribsARB(dpy, *FBConfigs, NULL, True, contextAttrs); 586 587 if (NULL == ctx) return GL_TRUE; 588 if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; 589 590 glXDestroyContext(dpy, oldCtx); 591 592 XFree(FBConfigs); 593 } 594 return GL_FALSE; 595 } 596 597 void glewDestroyContext () 598 { 599 if (NULL != dpy && NULL != ctx) glXDestroyContext(dpy, ctx); 600 if (NULL != dpy && 0 != wnd) XDestroyWindow(dpy, wnd); 601 if (NULL != dpy && 0 != cmap) XFreeColormap(dpy, cmap); 602 if (NULL != vis) 603 XFree(vis); 604 else if (NULL != vi) 605 XFree(vi); 606 if (NULL != dpy) XCloseDisplay(dpy); 607 } 608 609 #endif /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ 610