src/video/cybergfx/SDL_cgxgl.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. CGX_GL_GetVisual
  2. CGX_GL_CreateWindow
  3. CGX_GL_CreateContext
  4. CGX_GL_Shutdown
  5. CGX_GL_MakeCurrent
  6. CGX_GL_GetAttribute
  7. CGX_GL_SwapBuffers
  8. CGX_GL_UnloadLibrary
  9. CGX_GL_LoadLibrary
  10. CGX_GL_GetProcAddress

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 of the License, or (at your option) any later version.
   9 
  10     This library is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_cgxgl.c,v 1.1.2.2 2001/02/10 07:20:06 hercules Exp $";
  26 #endif
  27 
  28 // #include <stdlib.h>  /* For getenv() prototype */
  29 // #include <string.h>
  30 
  31 #include "SDL_events_c.h"
  32 #include "SDL_error.h"
  33 #include "SDL_cgxvideo.h"
  34 #include "SDL_cgxgl_c.h"
  35 
  36 #define DEFAULT_OPENGL  "libGL.so.1"
  37 
  38 /* return the preferred visual to use for openGL graphics */
  39 void *CGX_GL_GetVisual(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
  40 {
  41 #ifdef HAVE_OPENGL
  42         /* 64 seems nice. */
  43         int attribs[64];
  44         int i;
  45 
  46         /* load the gl driver from a default path */
  47         if ( ! this->gl_config.driver_loaded ) {
  48                 /* no driver has been loaded, use default (ourselves) */
  49                 if ( X11_GL_LoadLibrary(this, NULL) < 0 ) {
  50                         return NULL;
  51                 }
  52         }
  53 
  54         /* See if we already have a window which we must use */
  55         if ( SDL_windowid ) {
  56                 XWindowAttributes a;
  57                 XVisualInfo vi_in;
  58                 int out_count;
  59 
  60                 XGetWindowAttributes(SDL_Display, SDL_Window, &a);
  61                 vi_in.screen = SDL_Screen;
  62                 vi_in.visualid = XVisualIDFromVisual(a.visual);
  63                 glx_visualinfo = XGetVisualInfo(SDL_Display,
  64                              VisualScreenMask|VisualIDMask, &vi_in, &out_count);
  65                 return glx_visualinfo;
  66         }
  67 
  68         /* Setup our GLX attributes according to the gl_config. */
  69         i = 0;
  70         attribs[i++] = GLX_RGBA;
  71         attribs[i++] = GLX_RED_SIZE;
  72         attribs[i++] = this->gl_config.red_size;
  73         attribs[i++] = GLX_GREEN_SIZE;
  74         attribs[i++] = this->gl_config.green_size;
  75         attribs[i++] = GLX_BLUE_SIZE;
  76         attribs[i++] = this->gl_config.blue_size;
  77 
  78         if( this->gl_config.alpha_size ) {
  79                 attribs[i++] = GLX_ALPHA_SIZE;
  80                 attribs[i++] = this->gl_config.alpha_size;
  81         }
  82 
  83         if( this->gl_config.buffer_size ) {
  84                 attribs[i++] = GLX_BUFFER_SIZE;
  85                 attribs[i++] = this->gl_config.buffer_size;
  86         }
  87 
  88         if( this->gl_config.double_buffer ) {
  89                 attribs[i++] = GLX_DOUBLEBUFFER;
  90         }
  91 
  92         attribs[i++] = GLX_DEPTH_SIZE;
  93         attribs[i++] = this->gl_config.depth_size;
  94 
  95         if( this->gl_config.stencil_size ) {
  96                 attribs[i++] = GLX_STENCIL_SIZE;
  97                 attribs[i++] = this->gl_config.stencil_size;
  98         }
  99 
 100         if( this->gl_config.accum_red_size ) {
 101                 attribs[i++] = GLX_ACCUM_RED_SIZE;
 102                 attribs[i++] = this->gl_config.accum_red_size;
 103         }
 104 
 105         if( this->gl_config.accum_green_size ) {
 106                 attribs[i++] = GLX_ACCUM_GREEN_SIZE;
 107                 attribs[i++] = this->gl_config.accum_green_size;
 108         }
 109 
 110         if( this->gl_config.accum_blue_size ) {
 111                 attribs[i++] = GLX_ACCUM_BLUE_SIZE;
 112                 attribs[i++] = this->gl_config.accum_blue_size;
 113         }
 114 
 115         if( this->gl_config.accum_alpha_size ) {
 116                 attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
 117                 attribs[i++] = this->gl_config.accum_alpha_size;
 118         }
 119 
 120         attribs[i++] = None;
 121 
 122         glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display, 
 123                                                   SDL_Screen, attribs);
 124         if( !glx_visualinfo ) {
 125                 SDL_SetError( "Couldn't find matching GLX visual");
 126                 return NULL;
 127         }
 128         return glx_visualinfo;
 129 #else
 130         SDL_SetError("CGX driver is not yet supporting OpenGL");
 131         return NULL;
 132 #endif
 133 }
 134 
 135 int CGX_GL_CreateWindow(_THIS, int w, int h)
     /* [<][>][^][v][top][bottom][index][help] */
 136 {
 137         int retval;
 138 #ifdef HAVE_OPENGL
 139         XSetWindowAttributes attributes;
 140         unsigned long mask;
 141         unsigned long black;
 142 
 143         black = (glx_visualinfo->visual == DefaultVisual(SDL_Display,
 144                                                         SDL_Screen))
 145                 ? BlackPixel(SDL_Display, SDL_Screen) : 0;
 146         attributes.background_pixel = black;
 147         attributes.border_pixel = black;
 148         attributes.colormap = SDL_XColorMap;
 149         mask = CWBackPixel | CWBorderPixel | CWColormap;
 150 
 151         SDL_Window = XCreateWindow(SDL_Display, WMwindow,
 152                         0, 0, w, h, 0, glx_visualinfo->depth,
 153                         InputOutput, glx_visualinfo->visual,
 154                         mask, &attributes);
 155         if ( !SDL_Window ) {
 156                 SDL_SetError("Could not create window");
 157                 return -1;
 158         }
 159         retval = 0;
 160 #else
 161         SDL_SetError("CGX driver is not yet supporting OpenGL");
 162         retval = -1;
 163 #endif
 164         return(retval);
 165 }
 166 
 167 int CGX_GL_CreateContext(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 168 {
 169         int retval;
 170 #ifdef HAVE_OPENGL
 171         /* We do this to create a clean separation between X and GLX errors. */
 172         XSync( SDL_Display, False );
 173         glx_context = this->gl_data->glXCreateContext(GFX_Display, 
 174                                      glx_visualinfo, NULL, True);
 175         XSync( GFX_Display, False );
 176 
 177         if (glx_context == NULL) {
 178                 SDL_SetError("Could not create GL context");
 179                 return -1;
 180         }
 181 
 182         gl_active = 1;
 183 #else
 184         SDL_SetError("CGX driver is not yet supporting OpenGL");
 185 #endif
 186         if ( gl_active ) {
 187                 retval = 0;
 188         } else {
 189                 retval = -1;
 190         }
 191         return(retval);
 192 }
 193 
 194 void CGX_GL_Shutdown(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 195 {
 196 #ifdef HAVE_OPENGL
 197         /* Clean up OpenGL */
 198         if( glx_context ) {
 199                 this->gl_data->glXMakeCurrent(GFX_Display, None, NULL);
 200 
 201                 if (glx_context != NULL)
 202                         this->gl_data->glXDestroyContext(GFX_Display, glx_context);
 203 
 204                 if( this->gl_data->glXReleaseBuffersMESA ) {
 205                     this->gl_data->glXReleaseBuffersMESA(GFX_Display,SDL_Window);
 206                 }
 207                 glx_context = NULL;
 208         }
 209         gl_active = 0;
 210 #endif /* HAVE_OPENGL */
 211 }
 212 
 213 #ifdef HAVE_OPENGL
 214 
 215 /* Make the current context active */
 216 int CGX_GL_MakeCurrent(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 217 {
 218         int retval;
 219 
 220         retval = 0;
 221         if ( ! this->gl_data->glXMakeCurrent(GFX_Display,
 222                                              SDL_Window, glx_context) ) {
 223                 SDL_SetError("Unable to make GL context current");
 224                 retval = -1;
 225         }
 226         XSync( GFX_Display, False );
 227 
 228         /* More Voodoo X server workarounds... Grr... */
 229         SDL_Lock_EventThread();
 230         X11_CheckDGAMouse(this);
 231         SDL_Unlock_EventThread();
 232 
 233         return(retval);
 234 }
 235 
 236 /* Get attribute data from glX. */
 237 int CGX_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
     /* [<][>][^][v][top][bottom][index][help] */
 238 {
 239         int retval;
 240         int glx_attrib = None;
 241 
 242         switch( attrib ) {
 243             case SDL_GL_RED_SIZE:
 244                 glx_attrib = GLX_RED_SIZE;
 245                 break;
 246             case SDL_GL_GREEN_SIZE:
 247                 glx_attrib = GLX_GREEN_SIZE;
 248                 break;
 249             case SDL_GL_BLUE_SIZE:
 250                 glx_attrib = GLX_BLUE_SIZE;
 251                 break;
 252             case SDL_GL_ALPHA_SIZE:
 253                 glx_attrib = GLX_ALPHA_SIZE;
 254                 break;
 255             case SDL_GL_DOUBLEBUFFER:
 256                 glx_attrib = GLX_DOUBLEBUFFER;
 257                 break;
 258             case SDL_GL_BUFFER_SIZE:
 259                 glx_attrib = GLX_BUFFER_SIZE;
 260                 break;
 261             case SDL_GL_DEPTH_SIZE:
 262                 glx_attrib = GLX_DEPTH_SIZE;
 263                 break;
 264             case SDL_GL_STENCIL_SIZE:
 265                 glx_attrib = GLX_STENCIL_SIZE;
 266                 break;
 267             case SDL_GL_ACCUM_RED_SIZE:
 268                 glx_attrib = GLX_ACCUM_RED_SIZE;
 269                 break;
 270             case SDL_GL_ACCUM_GREEN_SIZE:
 271                 glx_attrib = GLX_ACCUM_GREEN_SIZE;
 272                 break;
 273             case SDL_GL_ACCUM_BLUE_SIZE:
 274                 glx_attrib = GLX_ACCUM_BLUE_SIZE;
 275                 break;
 276             case SDL_GL_ACCUM_ALPHA_SIZE:
 277                 glx_attrib = GLX_ACCUM_ALPHA_SIZE;
 278                 break;
 279             default:
 280                 return(-1);
 281         }
 282 
 283         retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value);
 284 
 285         return retval;
 286 }
 287 
 288 void CGX_GL_SwapBuffers(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 289 {
 290         this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window);
 291 }
 292 
 293 #endif /* HAVE_OPENGL */
 294 
 295 void CGX_GL_UnloadLibrary(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 296 {
 297 #ifdef HAVE_OPENGL
 298         if ( this->gl_config.driver_loaded ) {
 299                 dlclose(this->gl_config.dll_handle);
 300 
 301                 this->gl_data->glXChooseVisual = NULL;
 302                 this->gl_data->glXCreateContext = NULL;
 303                 this->gl_data->glXDestroyContext = NULL;
 304                 this->gl_data->glXMakeCurrent = NULL;
 305                 this->gl_data->glXSwapBuffers = NULL;
 306 
 307                 this->gl_config.dll_handle = NULL;
 308                 this->gl_config.driver_loaded = 0;
 309         }
 310 #endif
 311 }
 312 
 313 #ifdef HAVE_OPENGL
 314 
 315 /* Passing a NULL path means load pointers from the application */
 316 int CGX_GL_LoadLibrary(_THIS, const char* path) 
     /* [<][>][^][v][top][bottom][index][help] */
 317 {
 318         void* handle;
 319         int dlopen_flags;
 320 
 321         if ( gl_active ) {
 322                 SDL_SetError("OpenGL context already created");
 323                 return -1;
 324         }
 325 
 326 #ifdef RTLD_GLOBAL
 327         dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
 328 #else
 329         dlopen_flags = RTLD_LAZY;
 330 #endif
 331         handle = dlopen(path, dlopen_flags);
 332         /* Catch the case where the application isn't linked with GL */
 333         if ( (dlsym(handle, "glXChooseVisual") == NULL) && (path == NULL) ) {
 334                 dlclose(handle);
 335                 path = getenv("SDL_VIDEO_GL_DRIVER");
 336                 if ( path == NULL ) {
 337                         path = DEFAULT_OPENGL;
 338                 }
 339                 handle = dlopen(path, dlopen_flags);
 340         }
 341         if ( handle == NULL ) {
 342                 SDL_SetError("Could not load OpenGL library");
 343                 return -1;
 344         }
 345 
 346         /* Unload the old driver and reset the pointers */
 347         X11_GL_UnloadLibrary(this);
 348 
 349         /* Load new function pointers */
 350         this->gl_data->glXChooseVisual = dlsym(handle, "glXChooseVisual");
 351         this->gl_data->glXCreateContext = dlsym(handle, "glXCreateContext");
 352         this->gl_data->glXDestroyContext = dlsym(handle, "glXDestroyContext");
 353         this->gl_data->glXMakeCurrent = dlsym(handle, "glXMakeCurrent");
 354         this->gl_data->glXSwapBuffers = dlsym(handle, "glXSwapBuffers");
 355         this->gl_data->glXGetConfig = dlsym(handle, "glXGetConfig");
 356         /* We don't compare below for this in case we're not using Mesa. */
 357         this->gl_data->glXReleaseBuffersMESA = dlsym( handle, "glXReleaseBuffersMESA" );
 358 
 359         if ( (this->gl_data->glXChooseVisual == NULL) || 
 360              (this->gl_data->glXCreateContext == NULL) ||
 361              (this->gl_data->glXDestroyContext == NULL) ||
 362              (this->gl_data->glXMakeCurrent == NULL) ||
 363              (this->gl_data->glXSwapBuffers == NULL) ||
 364              (this->gl_data->glXGetConfig == NULL) ) {
 365                 SDL_SetError("Could not retrieve OpenGL functions");
 366                 return -1;
 367         }
 368 
 369         this->gl_config.dll_handle = handle;
 370         this->gl_config.driver_loaded = 1;
 371         if ( path ) {
 372                 strncpy(this->gl_config.driver_path, path,
 373                         sizeof(this->gl_config.driver_path)-1);
 374         } else {
 375                 strcpy(this->gl_config.driver_path, "");
 376         }
 377         return 0;
 378 }
 379 
 380 void *CGX_GL_GetProcAddress(_THIS, const char* proc)
     /* [<][>][^][v][top][bottom][index][help] */
 381 {
 382         void* handle;
 383         
 384         handle = this->gl_config.dll_handle;
 385 
 386         return dlsym(handle, proc);
 387 }
 388 
 389 #endif /* HAVE_OPENGL */

/* [<][>][^][v][top][bottom][index][help] */