Add support for X11+EGL.
authorSylvain Beucler <beuc@beuc.net>
Sun, 18 Mar 2012 12:38:07 +0000 (12:38 +0000)
committerSylvain Beucler <beuc@beuc.net>
Sun, 18 Mar 2012 12:38:07 +0000 (12:38 +0000)
The changes are made with minimalism and clarity in mind:
- Either the functions are common and are kept in _x11.c files
- Either the functions have small differences and dealt with #ifdef
- Either the functions are largely different, and split in:
  - Specialized portable code in egl/
  - Specialized GLX code in _x11_glx.c files

Using EGL or GLX is decided at compile time
(CMake FREEGLUT_GLES1 or FREEGLUT_GLES2 option enabled)..

git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1196 7f0cb862-5218-0410-a997-914c9d46530a

CMakeLists.txt
src/x11/fg_init_x11.c
src/x11/fg_internal_x11.h
src/x11/fg_state_x11.c
src/x11/fg_structure_x11.c
src/x11/fg_window_x11.c

index 9ca349d..2f0b146 100644 (file)
@@ -125,7 +125,6 @@ ELSEIF(ANDROID)
 ELSE()
     LIST(APPEND FREEGLUT_SRCS
         src/x11/fg_cursor_x11.c
-        src/x11/fg_display_x11.c
         src/x11/fg_ext_x11.c
         src/x11/fg_gamemode_x11.c
         src/x11/fg_glutfont_definitions_x11.c
@@ -141,6 +140,24 @@ ELSE()
         src/x11/fg_window_x11.c
         src/x11/fg_xinput_x11.c
     )
+    IF(FREEGLUT_GLES2 OR FREEGLUT_GLES1)
+        LIST(APPEND FREEGLUT_SRCS
+            src/egl/fg_internal_egl.h
+            src/egl/fg_display_egl.c
+            src/egl/fg_init_egl.c
+            src/egl/fg_state_egl.c
+            src/egl/fg_structure_egl.c
+            src/egl/fg_window_egl.c
+        )
+    ELSE()
+        LIST(APPEND FREEGLUT_SRCS
+            src/x11/fg_internal_x11_glx.h
+            src/x11/fg_display_x11_glx.c
+            src/x11/fg_state_x11_glx.c
+            src/x11/fg_window_x11_glx.c
+            src/x11/fg_window_x11_glx.h
+        )
+    ENDIF()
 ENDIF()
 
 # For OpenGL ES (GLES):
index 83fe287..45ac0d1 100644 (file)
@@ -174,9 +174,13 @@ void fgPlatformInitialize( const char* displayName )
     if( fgDisplay.pDisplay.Display == NULL )
         fgError( "failed to open display '%s'", XDisplayName( displayName ) );
 
+#ifdef EGL_VERSION_1_0
+    fghPlatformInitializeEGL();
+#else
     if( !glXQueryExtension( fgDisplay.pDisplay.Display, NULL, NULL ) )
         fgError( "OpenGL GLX extension not supported by display '%s'",
             XDisplayName( displayName ) );
+#endif
 
     fgDisplay.pDisplay.Screen = DefaultScreen( fgDisplay.pDisplay.Display );
     fgDisplay.pDisplay.RootWindow = RootWindow(
@@ -266,8 +270,10 @@ void fgPlatformCloseDisplay ( void )
 }
 
 
+#ifndef EGL_VERSION_1_0
 void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext )
 {
     /* Note that the MVisualInfo is not owned by the MenuContext! */
     glXDestroyContext( pDisplay.Display, MContext );
 }
+#endif
index 8a8e197..0d969f4 100644 (file)
 
 
 /* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */
+#ifdef EGL_VERSION_1_0
+#include "egl/fg_internal_egl.h"
+#else
 #include <GL/glx.h>
+#include "x11/fg_internal_x11_glx.h"
+#endif
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include <X11/keysym.h>
 #ifdef HAVE_X11_EXTENSIONS_XRANDR_H
 #    include <X11/extensions/Xrandr.h>
 #endif
-/* If GLX is too old, we will fail during runtime when multisampling
-   is requested, but at least freeglut compiles. */
-#ifndef GLX_SAMPLE_BUFFERS
-#    define GLX_SAMPLE_BUFFERS 0x80A8
-#endif
-#ifndef GLX_SAMPLES
-#    define GLX_SAMPLES 0x80A9
-#endif
-
 
 
 /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
@@ -83,6 +79,10 @@ struct tagSFG_PlatformDisplay
     int             DisplayViewPortY;   /* saved Y location of the viewport  */
 #endif /* HAVE_X11_EXTENSIONS_XF86VMODE_H */
 
+#ifdef EGL_VERSION_1_0
+    struct tagSFG_PlatformDisplayEGL egl;
+#endif
+
     int             DisplayPointerX;    /* saved X location of the pointer   */
     int             DisplayPointerY;    /* saved Y location of the pointer   */
 };
@@ -93,11 +93,19 @@ struct tagSFG_PlatformDisplay
  * much conditionally-compiled code later in the library.
  */
 typedef Window     SFG_WindowHandleType ;
+#ifdef EGL_VERSION_1_0
+typedef EGLContext SFG_WindowContextType ;
+#else
 typedef GLXContext SFG_WindowContextType ;
+#endif
 typedef struct tagSFG_PlatformContext SFG_PlatformContext;
 struct tagSFG_PlatformContext
 {
-    GLXFBConfig*    FBConfig;        /* The window's FBConfig               */
+#ifdef EGL_VERSION_1_0
+    struct tagSFG_PlatformContextEGL egl;
+#else
+    GLXFBConfig    FBConfig;        /* The window's FBConfig               */
+#endif
 };
 
 
index 3523477..9765319 100644 (file)
 #include <GL/freeglut.h>
 #include "../fg_internal.h"
 
-/*
- * TODO BEFORE THE STABLE RELEASE:
- *
- *  fgPlatformChooseFBConfig()      -- OK, but what about glutInitDisplayString()?
- */
-
-/* A helper function to check if a display mode is possible to use */
-GLXFBConfig* fgPlatformChooseFBConfig( int* numcfgs );
-
-/*
- * Queries the GL context about some attributes
- */
-int fgPlatformGetConfig( int attribute )
-{
-  int returnValue = 0;
-  int result;  /*  Not checked  */
-
-  if( fgStructure.CurrentWindow )
-      result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-                                     *(fgStructure.CurrentWindow->Window.pContext.FBConfig),
-                                     attribute,
-                                     &returnValue );
-
-  return returnValue;
-}
-
-int fgPlatformGlutGet ( GLenum eWhat )
+int fgPlatformGlutDeviceGet ( GLenum eWhat )
 {
-    int nsamples = 0;
-
     switch( eWhat )
     {
-    /*
-     * The window/context specific queries are handled mostly by
-     * fgPlatformGetConfig().
-     */
-    case GLUT_WINDOW_NUM_SAMPLES:
-#ifdef GLX_VERSION_1_3
-        glGetIntegerv(GL_SAMPLES, &nsamples);
-#endif
-        return nsamples;
-
-    /*
-     * The rest of GLX queries under X are general enough to use a macro to
-     * check them
-     */
-#   define GLX_QUERY(a,b) case a: return fgPlatformGetConfig( b );
-
-    GLX_QUERY( GLUT_WINDOW_RGBA,                GLX_RGBA                );
-    GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER,        GLX_DOUBLEBUFFER        );
-    GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE,         GLX_BUFFER_SIZE         );
-    GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE,        GLX_STENCIL_SIZE        );
-    GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE,          GLX_DEPTH_SIZE          );
-    GLX_QUERY( GLUT_WINDOW_RED_SIZE,            GLX_RED_SIZE            );
-    GLX_QUERY( GLUT_WINDOW_GREEN_SIZE,          GLX_GREEN_SIZE          );
-    GLX_QUERY( GLUT_WINDOW_BLUE_SIZE,           GLX_BLUE_SIZE           );
-    GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE,          GLX_ALPHA_SIZE          );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE,      GLX_ACCUM_RED_SIZE      );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE,    GLX_ACCUM_GREEN_SIZE    );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE,     GLX_ACCUM_BLUE_SIZE     );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE,    GLX_ACCUM_ALPHA_SIZE    );
-    GLX_QUERY( GLUT_WINDOW_STEREO,              GLX_STEREO              );
+    case GLUT_HAS_KEYBOARD:
+        /*
+         * X11 has a core keyboard by definition, although it can
+         * be present as a virtual/dummy keyboard. For now, there
+         * is no reliable way to tell if a real keyboard is present.
+         */
+        return 1;
 
-#   undef GLX_QUERY
+    /* X11 has a mouse by definition */
+    case GLUT_HAS_MOUSE:
+        return 1 ;
 
-    /* Colormap size is handled in a bit different way than all the rest */
-    case GLUT_WINDOW_COLORMAP_SIZE:
-        if( (fgPlatformGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) )
+    case GLUT_NUM_MOUSE_BUTTONS:
+        /* We should be able to pass NULL when the last argument is zero,
+         * but at least one X server has a bug where this causes a segfault.
+         *
+         * In XFree86/Xorg servers, a mouse wheel is seen as two buttons
+         * rather than an Axis; "freeglut_main.c" expects this when
+         * checking for a wheel event.
+         */
         {
-            /*
-             * We've got a RGBA visual, so there is no colormap at all.
-             * The other possibility is that we have no current window set.
-             */
-            return 0;
+            unsigned char map;
+            int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0);
+            return nbuttons;
         }
-        else
-        {
-          const GLXFBConfig * fbconfig =
-                fgStructure.CurrentWindow->Window.pContext.FBConfig;
 
-          XVisualInfo * visualInfo =
-                glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, *fbconfig );
+    default:
+        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
+        break;
+    }
 
-          const int result = visualInfo->visual->map_entries;
+    /* And now -- the failure. */
+    return -1;
+}
 
-          XFree(visualInfo);
 
-          return result;
-        }
+int fgPlatformGlutGet ( GLenum eWhat )
+{
+    switch( eWhat )
+    {
 
     /*
      * Those calls are somewhat similiar, as they use XGetWindowAttributes()
@@ -177,187 +132,53 @@ int fgPlatformGlutGet ( GLenum eWhat )
         case GLUT_WINDOW_HEIGHT:           return winAttributes.height ;
         }
     }
-
-    /* I do not know yet if there will be a fgChooseVisual() function for Win32 */
-    case GLUT_DISPLAY_MODE_POSSIBLE:
-    {
-        /*  We should not have to call fgPlatformChooseFBConfig again here.  */
-        GLXFBConfig * fbconfig;
-        int isPossible;
-
-        fbconfig = fgPlatformChooseFBConfig(NULL);
-
-        if (fbconfig == NULL)
-        {
-            isPossible = 0;
-        }
-        else
+    
+    /* Colormap size is handled in a bit different way than all the rest */
+    case GLUT_WINDOW_COLORMAP_SIZE:
+        if(
+#ifndef EGL_VERSION_1_0
+          fgPlatformGetConfig( GLX_RGBA ) ||
+#endif
+          fgStructure.CurrentWindow == NULL)
         {
-            isPossible = 1;
-            XFree(fbconfig);
-        }
-
-        return isPossible;
-    }
-
-    /* This is system-dependant */
-    case GLUT_WINDOW_FORMAT_ID:
-        if( fgStructure.CurrentWindow == NULL )
+            /*
+             * We've got a RGBA visual, so there is no colormap at all.
+             * The other possibility is that we have no current window set.
+             */
             return 0;
-
-        return fgPlatformGetConfig( GLX_VISUAL_ID );
-
-    default:
-        fgWarning( "glutGet(): missing enum handle %d", eWhat );
-        break;
-    }
-
-       return -1;
-}
-
-
-int fgPlatformGlutDeviceGet ( GLenum eWhat )
-{
-    switch( eWhat )
-    {
-    case GLUT_HAS_KEYBOARD:
-        /*
-         * X11 has a core keyboard by definition, although it can
-         * be present as a virtual/dummy keyboard. For now, there
-         * is no reliable way to tell if a real keyboard is present.
-         */
-        return 1;
-
-    /* X11 has a mouse by definition */
-    case GLUT_HAS_MOUSE:
-        return 1 ;
-
-    case GLUT_NUM_MOUSE_BUTTONS:
-        /* We should be able to pass NULL when the last argument is zero,
-         * but at least one X server has a bug where this causes a segfault.
-         *
-         * In XFree86/Xorg servers, a mouse wheel is seen as two buttons
-         * rather than an Axis; "freeglut_main.c" expects this when
-         * checking for a wheel event.
-         */
-        {
-            unsigned char map;
-            int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0);
-            return nbuttons;
         }
-
-    default:
-        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
-        break;
-    }
-
-    /* And now -- the failure. */
-    return -1;
-}
-
-
-int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
-{
-  int *array;
-
-  int attributes[9];
-  GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
-  int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
-  int attribute_name = 0;
-
-  array = NULL;
-  *size = 0;
-
-  switch (eWhat)
-    {
-    case GLUT_AUX:
-    case GLUT_MULTISAMPLE:
-
-      attributes[0] = GLX_BUFFER_SIZE;
-      attributes[1] = GLX_DONT_CARE;
-
-      switch (eWhat)
-        {
-        case GLUT_AUX:
-          /*
-            FBConfigs are now sorted by increasing number of auxiliary
-            buffers.  We want at least one buffer.
-          */
-          attributes[2] = GLX_AUX_BUFFERS;
-          attributes[3] = 1;
-          attributes[4] = None;
-
-          attribute_name = GLX_AUX_BUFFERS;
-
-          break;
-
-
-        case GLUT_MULTISAMPLE:
-          attributes[2] = GLX_AUX_BUFFERS;
-          attributes[3] = GLX_DONT_CARE;
-          attributes[4] = GLX_SAMPLE_BUFFERS;
-          attributes[5] = 1;
-          /*
-            FBConfigs are now sorted by increasing number of samples per
-            pixel.  We want at least one sample.
-          */
-          attributes[6] = GLX_SAMPLES;
-          attributes[7] = 1;
-          attributes[8] = None;
-
-          attribute_name = GLX_SAMPLES;
-
-          break;
-        }
-
-      fbconfigArray = glXChooseFBConfig(fgDisplay.pDisplay.Display,
-                                        fgDisplay.pDisplay.Screen,
-                                        attributes,
-                                        &fbconfigArraySize);
-
-      if (fbconfigArray != NULL)
+        else
         {
-          int * temp_array;
-          int result;   /*  Returned by glXGetFBConfigAttrib. Not checked.  */
-          int previous_value;
-          int i;
-
-          temp_array = malloc(sizeof(int) * fbconfigArraySize);
-          previous_value = 0;
-
-          for (i = 0; i < fbconfigArraySize; i++)
-            {
-              int value;
+          XVisualInfo * visualInfo;
+#ifdef EGL_VERSION_1_0
+         EGLint vid = 0;
+         XVisualInfo visualTemplate;
+         int num_visuals;
+         if (!eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display,
+                                 fgStructure.CurrentWindow->Window.pContext.egl.Config,
+                                 EGL_NATIVE_VISUAL_ID, &vid))
+           fgError("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed");
+         visualTemplate.visualid = vid;
+         visualInfo = XGetVisualInfo(fgDisplay.pDisplay.Display, VisualIDMask, &visualTemplate, &num_visuals);
+#else
+          const GLXFBConfig fbconfig =
+                fgStructure.CurrentWindow->Window.pContext.FBConfig;
 
-              result = glXGetFBConfigAttrib(fgDisplay.pDisplay.Display,
-                                            fbconfigArray[i],
-                                            attribute_name,
-                                            &value);
-              if (value > previous_value)
-                {
-                  temp_array[*size] = value;
-                  previous_value = value;
-                  (*size)++;
-                }
-            }
+          visualInfo =
+                glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, fbconfig );
+#endif
+          const int result = visualInfo->visual->map_entries;
 
-          array = malloc(sizeof(int) * (*size));
-          for (i = 0; i < *size; i++)
-            {
-              array[i] = temp_array[i];
-            }
+          XFree(visualInfo);
 
-          free(temp_array);
-          XFree(fbconfigArray);
+          return result;
         }
 
-      break;
-
     default:
-      break;
+#ifdef EGL_VERSION_1_0
+      return fghPlatformGlutGetEGL(eWhat);
+#else
+      return fghPlatformGlutGetGLX(eWhat);
+#endif
     }
-
-  return array;
 }
-
-
index cbc9129..e1d5eb4 100644 (file)
@@ -33,7 +33,11 @@ extern SFG_Structure fgStructure;
 
 void fgPlatformCreateWindow ( SFG_Window *window )
 {
+#ifdef EGL_VERSION_1_0
+    fghPlatformCreateWindowEGL(window);
+#else
     window->Window.pContext.FBConfig = NULL;
+#endif
 
     window->State.pWState.OldHeight = window->State.pWState.OldWidth = -1;
 }
index 44c9952..2b9012c 100644 (file)
 #include <unistd.h>  /* usleep */
 #include "../fg_internal.h"
 
-/* pushing attribute/value pairs into an array */
-#define ATTRIB(a) attributes[where++]=(a)
-#define ATTRIB_VAL(a,v) {ATTRIB(a); ATTRIB(v);}
-
-
-#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB
-#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
-#endif
-
-#ifndef GLX_CONTEXT_MAJOR_VERSION_ARB
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#endif
-
-#ifndef GLX_CONTEXT_MINOR_VERSION_ARB
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-#endif
-
-#ifndef GLX_CONTEXT_FLAGS_ARB
-#define GLX_CONTEXT_FLAGS_ARB 0x2094
-#endif
-
-#ifndef GLX_CONTEXT_PROFILE_MASK_ARB
-#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
-#endif
-
-#ifndef GLX_CONTEXT_DEBUG_BIT_ARB
-#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
-#endif
-
-#ifndef GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
-#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
-#endif
-
-#ifndef GLX_CONTEXT_CORE_PROFILE_BIT_ARB
-#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#endif
-
-#ifndef GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
-#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#endif
-
-#ifndef GLX_RGBA_FLOAT_TYPE
-#define GLX_RGBA_FLOAT_TYPE 0x20B9
+#ifdef EGL_VERSION_1_0
+#include "egl/fg_window_egl.h"
+#define fghCreateNewContext fghCreateNewContextEGL
+#else
+#include "x11/fg_window_x11_glx.h"
 #endif
 
-#ifndef GLX_RGBA_FLOAT_BIT
-#define GLX_RGBA_FLOAT_BIT 0x00000004
-#endif
-
-
-/*
- * Chooses a visual basing on the current display mode settings
- */
-
-GLXFBConfig* fgPlatformChooseFBConfig( int *numcfgs )
-{
-  GLboolean wantIndexedMode = GL_FALSE;
-  int attributes[ 100 ];
-  int where = 0, numAuxBuffers;
-
-  /* First we have to process the display mode settings... */
-  if( fgState.DisplayMode & GLUT_INDEX ) {
-    ATTRIB_VAL( GLX_BUFFER_SIZE, 8 );
-    /*  Buffer size is selected later.  */
-
-    ATTRIB_VAL( GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT );
-    wantIndexedMode = GL_TRUE;
-  } else {
-    ATTRIB_VAL( GLX_RED_SIZE,   1 );
-    ATTRIB_VAL( GLX_GREEN_SIZE, 1 );
-    ATTRIB_VAL( GLX_BLUE_SIZE,  1 );
-    if( fgState.DisplayMode & GLUT_ALPHA ) {
-      ATTRIB_VAL( GLX_ALPHA_SIZE, 1 );
-    }
-  }
-
-  if( fgState.DisplayMode & GLUT_DOUBLE ) {
-    ATTRIB_VAL( GLX_DOUBLEBUFFER, True );
-  }
-
-  if( fgState.DisplayMode & GLUT_STEREO ) {
-    ATTRIB_VAL( GLX_STEREO, True );
-  }
-
-  if( fgState.DisplayMode & GLUT_DEPTH ) {
-    ATTRIB_VAL( GLX_DEPTH_SIZE, 1 );
-  }
-
-  if( fgState.DisplayMode & GLUT_STENCIL ) {
-    ATTRIB_VAL( GLX_STENCIL_SIZE, 1 );
-  }
-
-  if( fgState.DisplayMode & GLUT_ACCUM ) {
-    ATTRIB_VAL( GLX_ACCUM_RED_SIZE, 1 );
-    ATTRIB_VAL( GLX_ACCUM_GREEN_SIZE, 1 );
-    ATTRIB_VAL( GLX_ACCUM_BLUE_SIZE, 1 );
-    if( fgState.DisplayMode & GLUT_ALPHA ) {
-      ATTRIB_VAL( GLX_ACCUM_ALPHA_SIZE, 1 );
-    }
-  }
-
-  numAuxBuffers = fghNumberOfAuxBuffersRequested();
-  if ( numAuxBuffers > 0 ) {
-    ATTRIB_VAL( GLX_AUX_BUFFERS, numAuxBuffers );
-  }
-
-  if( fgState.DisplayMode & GLUT_SRGB ) {
-    ATTRIB_VAL( GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True );
-  }
-
-  if (fgState.DisplayMode & GLUT_MULTISAMPLE) {
-    ATTRIB_VAL(GLX_SAMPLE_BUFFERS, 1);
-    ATTRIB_VAL(GLX_SAMPLES, fgState.SampleNumber);
-  }
-
-  /* Push a terminator at the end of the list */
-  ATTRIB( None );
-
-    {
-        GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
-        GLXFBConfig * fbconfig;       /*  The FBConfig we want  */
-        int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
-
-
-        /*  Get all FBConfigs that match "attributes".  */
-        fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
-                                           fgDisplay.pDisplay.Screen,
-                                           attributes,
-                                           &fbconfigArraySize );
-
-        if (fbconfigArray != NULL)
-        {
-            int result;  /* Returned by glXGetFBConfigAttrib, not checked. */
-
-
-            if( wantIndexedMode )
-            {
-                /*
-                 * In index mode, we want the largest buffer size, i.e. visual
-                 * depth.  Here, FBConfigs are sorted by increasing buffer size
-                 * first, so FBConfigs with the largest size come last.
-                 */
-
-                int bufferSizeMin, bufferSizeMax;
-
-                /*  Get bufferSizeMin.  */
-                result =
-                  glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-                                        fbconfigArray[0],
-                                        GLX_BUFFER_SIZE,
-                                        &bufferSizeMin );
-                /*  Get bufferSizeMax.  */
-                result =
-                  glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-                                        fbconfigArray[fbconfigArraySize - 1],
-                                        GLX_BUFFER_SIZE,
-                                        &bufferSizeMax );
-
-                if (bufferSizeMax > bufferSizeMin)
-                {
-                    /* 
-                     * Free and reallocate fbconfigArray, keeping only FBConfigs
-                     * with the largest buffer size.
-                     */
-                    XFree(fbconfigArray);
-
-                    /*  Add buffer size token at the end of the list.  */
-                    where--;
-                    ATTRIB_VAL( GLX_BUFFER_SIZE, bufferSizeMax );
-                    ATTRIB( None );
-
-                    fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
-                                                       fgDisplay.pDisplay.Screen,
-                                                       attributes,
-                                                       &fbconfigArraySize );
-                }
-            }
-
-            /*
-             * We now have an array of FBConfigs, the first one being the "best"
-             * one.  So we should return only this FBConfig:
-             *
-             * int fbconfigXID;
-             *
-             *  - pick the XID of the FBConfig we want
-             * result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-             *                                fbconfigArray[0],
-             *                                GLX_FBCONFIG_ID,
-             *                                &fbconfigXID );
-             *
-             * - free the array
-             * XFree(fbconfigArray);
-             *
-             * - reset "attributes" with the XID
-             * where = 0;
-             * ATTRIB_VAL( GLX_FBCONFIG_ID, fbconfigXID );
-             * ATTRIB( None );
-             *
-             * - get our FBConfig only
-             * fbconfig = glXChooseFBConfig( fgDisplay.pDisplay.Display,
-             *                               fgDisplay.pDisplay.Screen,
-             *                               attributes,
-             *                               &fbconfigArraySize );
-             *
-             * However, for some configurations (for instance multisampling with
-             * Mesa 6.5.2 and ATI drivers), this does not work:
-             * glXChooseFBConfig returns NULL, whereas fbconfigXID is a valid
-             * XID.  Further investigation is needed.
-             *
-             * So, for now, we return the whole array of FBConfigs.  This should
-             * not produce any side effects elsewhere.
-             */
-            fbconfig = fbconfigArray;
-        }
-        else
-        {
-           fbconfig = NULL;
-        }
-
-       if (numcfgs)
-               *numcfgs = fbconfigArraySize;
-
-        return fbconfig;
-    }
-}
-
-
-static void fghFillContextAttributes( int *attributes ) {
-  int where = 0, contextFlags, contextProfile;
-
-  if ( !fghIsLegacyContextVersionRequested() ) {
-    ATTRIB_VAL( GLX_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion );
-    ATTRIB_VAL( GLX_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion );
-  }
-
-  contextFlags =
-    fghMapBit( fgState.ContextFlags, GLUT_DEBUG, GLX_CONTEXT_DEBUG_BIT_ARB ) |
-    fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB );
-  if ( contextFlags != 0 ) {
-    ATTRIB_VAL( GLX_CONTEXT_FLAGS_ARB, contextFlags );
-  }
-
-  contextProfile =
-    fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB ) |
-    fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB );
-  if ( contextProfile != 0 ) {
-    ATTRIB_VAL( GLX_CONTEXT_PROFILE_MASK_ARB, contextProfile );
-  }
-
-  ATTRIB( 0 );
-}
-
-typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config,
-                                              GLXContext share_list, Bool direct,
-                                              const int *attrib_list);
-
-static GLXContext fghCreateNewContext( SFG_Window* window )
-{
-  /* for color model calculation */
-  int menu = ( window->IsMenu && !fgStructure.MenuContext );
-  int index_mode = ( fgState.DisplayMode & GLUT_INDEX );
-
-  /* "classic" context creation */
-  Display *dpy = fgDisplay.pDisplay.Display;
-  GLXFBConfig config = *(window->Window.pContext.FBConfig);
-  int render_type = ( !menu && index_mode ) ? GLX_COLOR_INDEX_TYPE : GLX_RGBA_TYPE;
-  GLXContext share_list = NULL;
-  Bool direct = ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT );
-  GLXContext context;
-
-  /* new context creation */
-  int attributes[9];
-  CreateContextAttribsProc createContextAttribs = (CreateContextAttribsProc) fgPlatformGetProcAddress( "glXCreateContextAttribsARB" );
-  /* glXCreateContextAttribsARB not found, yet the user has requested the new context creation */
-  if ( !createContextAttribs && !fghIsLegacyContextRequested() ) {
-    fgWarning( "OpenGL >2.1 context requested but glXCreateContextAttribsARB is not available! Falling back to legacy context creation" );
-       fgState.MajorVersion = 2;
-       fgState.MinorVersion = 1;
-  }
-
-  /* If nothing fancy has been required, simply use the old context creation GLX API entry */
-  if ( fghIsLegacyContextRequested() || !createContextAttribs )
-  {
-    context = glXCreateNewContext( dpy, config, render_type, share_list, direct );
-    if ( context == NULL ) {
-      fghContextCreationError();
-    }
-    return context;
-  }
-
-  /* color index mode is not available anymore with OpenGL 3.0 */
-  if ( render_type == GLX_COLOR_INDEX_TYPE ) {
-    fgWarning( "color index mode is deprecated, using RGBA mode" );
-  }
-
-  fghFillContextAttributes( attributes );
-
-  context = createContextAttribs( dpy, config, share_list, direct, attributes );
-  if ( context == NULL ) {
-    fghContextCreationError();
-  }
-  return context;
-}
-
-
-#define _NET_WM_STATE_TOGGLE    2
 static int fghResizeFullscrToggle(void)
 {
     XWindowAttributes attributes;
@@ -370,6 +70,7 @@ static int fghResizeFullscrToggle(void)
     return 0;
 }
 
+#define _NET_WM_STATE_TOGGLE    2
 static int fghEwmhFullscrToggle(void)
 {
     XEvent xev;
@@ -409,19 +110,6 @@ static int fghToggleFullscreen(void)
     return -1;
 }
 
-void fgPlatformSetWindow ( SFG_Window *window )
-{
-    if ( window )
-    {
-        glXMakeContextCurrent(
-            fgDisplay.pDisplay.Display,
-            window->Window.Handle,
-            window->Window.Handle,
-            window->Window.Context
-        );
-    }
-}
-
 static Bool fghWindowIsVisible( Display *display, XEvent *event, XPointer arg)
 {
     Window window = (Window)arg;
@@ -451,43 +139,56 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     if( window->IsMenu && ( ! fgStructure.MenuContext ) )
         fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;
 
-    window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
+#ifdef EGL_VERSION_1_0
+#define WINDOW_CONFIG window->Window.pContext.egl.Config
+#else
+#define WINDOW_CONFIG window->Window.pContext.FBConfig
+#endif
+    fghChooseConfig(&WINDOW_CONFIG);
 
     if( window->IsMenu && ( ! fgStructure.MenuContext ) )
         fgState.DisplayMode = current_DisplayMode ;
 
-    if( ! window->Window.pContext.FBConfig )
+    if( ! WINDOW_CONFIG )
     {
         /*
-         * The "fgPlatformChooseFBConfig" returned a null meaning that the visual
+         * The "fghChooseConfig" returned a null meaning that the visual
          * context is not available.
          * Try a couple of variations to see if they will work.
          */
+#ifndef EGL_VERSION_1_0
         if( !( fgState.DisplayMode & GLUT_DOUBLE ) )
         {
             fgState.DisplayMode |= GLUT_DOUBLE ;
-            window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
+            fghChooseConfig(&WINDOW_CONFIG);
             fgState.DisplayMode &= ~GLUT_DOUBLE;
         }
+#endif
 
         if( fgState.DisplayMode & GLUT_MULTISAMPLE )
         {
             fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
-            window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
+            fghChooseConfig(&WINDOW_CONFIG);
             fgState.DisplayMode |= GLUT_MULTISAMPLE;
         }
     }
 
-    FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.FBConfig != NULL,
+    FREEGLUT_INTERNAL_ERROR_EXIT( WINDOW_CONFIG != NULL,
                                   "FBConfig with necessary capabilities not found", "fgOpenWindow" );
 
     /*  Get the X visual.  */
-    for (i = 0; i < num_FBConfigs; i++) {
-           visualInfo = glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display,
-                                                  window->Window.pContext.FBConfig[i] );
-           if (visualInfo)
-               break;
-    }
+#ifdef EGL_VERSION_1_0
+    EGLint vid = 0;
+    XVisualInfo visualTemplate;
+    int num_visuals;
+    if (!eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Config, EGL_NATIVE_VISUAL_ID, &vid))
+      fgError("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed");
+    visualTemplate.visualid = vid;
+    visualInfo = XGetVisualInfo(fgDisplay.pDisplay.Display, VisualIDMask, &visualTemplate, &num_visuals);
+#else
+    visualInfo = glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display,
+                                          window->Window.pContext.FBConfig );
+#endif
 
     FREEGLUT_INTERNAL_ERROR_EXIT( visualInfo != NULL,
                                   "visualInfo could not be retrieved from FBConfig", "fgOpenWindow" );
@@ -562,7 +263,12 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     }
     else if( fgState.UseCurrentContext )
     {
+
+#ifdef EGL_VERSION_1_0
+        window->Window.Context = eglGetCurrentContext( );
+#else
         window->Window.Context = glXGetCurrentContext( );
+#endif
 
         if( ! window->Window.Context )
             window->Window.Context = fghCreateNewContext( window );
@@ -570,7 +276,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     else
         window->Window.Context = fghCreateNewContext( window );
 
-#if !defined( __FreeBSD__ ) && !defined( __NetBSD__ )
+#if !defined( __FreeBSD__ ) && !defined( __NetBSD__ ) && !defined(EGL_VERSION_1_0)
     if(  !glXIsDirect( fgDisplay.pDisplay.Display, window->Window.Context ) )
     {
       if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
@@ -625,12 +331,16 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     XSetWMProtocols( fgDisplay.pDisplay.Display, window->Window.Handle,
                      &fgDisplay.pDisplay.DeleteWindow, 1 );
 
+#ifdef EGL_VERSION_1_0
+    fghPlatformOpenWindowEGL(window);
+#else
     glXMakeContextCurrent(
         fgDisplay.pDisplay.Display,
         window->Window.Handle,
         window->Window.Handle,
         window->Window.Context
     );
+#endif
 
     /* register extension events _before_ window is mapped */
     #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
@@ -643,6 +353,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
 
     if( !isSubWindow)
         XPeekIfEvent( fgDisplay.pDisplay.Display, &eventReturnBuffer, &fghWindowIsVisible, (XPointer)(window->Window.Handle) );
+#undef WINDOW_CONFIG
 }
 
 
@@ -651,9 +362,13 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
  */
 void fgPlatformCloseWindow( SFG_Window* window )
 {
+#ifdef EGL_VERSION_1_0
+    fghPlatformCloseWindowEGL(window);
+#else
     if( window->Window.Context )
         glXDestroyContext( fgDisplay.pDisplay.Display, window->Window.Context );
-    XFree( window->Window.pContext.FBConfig );
+    window->Window.pContext.FBConfig = NULL;
+#endif
 
     if( window->Window.Handle ) {
         XDestroyWindow( fgDisplay.pDisplay.Display, window->Window.Handle );