FLTK logo

[master] 1adaa3d - Create classes Fl_XXX_Gl_Window_Driver according to driver model.

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 1adaa3d - Create classes Fl_XXX_Gl_Window_Driver according to driver model. "ManoloFLTK" Feb 16, 2021  
 
commit 1adaa3def2138fafd40b9d9df212a068c57cdbf4
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Tue Feb 16 09:29:13 2021 +0100
Commit:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Tue Feb 16 09:29:13 2021 +0100

    Create classes Fl_XXX_Gl_Window_Driver according to driver model.

 CMake/options.cmake                                |   1 +
 src/CMakeLists.txt                                 |   8 +
 src/Fl_Gl_Choice.H                                 |  31 +-
 src/Fl_Gl_Choice.cxx                               | 417 +---------------
 src/Fl_Gl_Overlay.cxx                              | 223 ---------
 src/Fl_Gl_Window.cxx                               | 265 +---------
 src/Fl_Gl_Window_Driver.H                          | 113 +----
 src/Makefile                                       |   7 +
 src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx    | 248 ++++++++++
 src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx     |   2 -
 .../Quartz/Fl_Quartz_Copy_Surface_Driver.cxx       |   5 -
 .../Quartz/Fl_Quartz_Graphics_Driver_arci.cxx      |   5 -
 .../Quartz/Fl_Quartz_Graphics_Driver_color.cxx     |   5 -
 .../Quartz/Fl_Quartz_Graphics_Driver_font.cxx      |   6 -
 .../Fl_Quartz_Graphics_Driver_line_style.cxx       |   5 -
 .../Quartz/Fl_Quartz_Graphics_Driver_rect.cxx      |   6 -
 .../Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx    |   6 -
 .../Quartz/Fl_Quartz_Image_Surface_Driver.cxx      |   5 -
 src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx  | 404 +++++++++++++++
 src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx        | 549 +++++++++++++++++++++
 src/drivers/X11/Fl_X11_Window_Driver.cxx           |   9 +-
 src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx   |   3 -
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H         |   1 +
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx       |   1 +
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx |  18 +-
 .../Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx      |   1 -
 src/gl_draw.cxx                                    | 183 +------
 src/gl_start.cxx                                   |  36 +-
 28 files changed, 1264 insertions(+), 1299 deletions(-)

diff --git CMake/options.cmake CMake/options.cmake
index 2bb439a..142f345 100644
--- CMake/options.cmake
+++ CMake/options.cmake
@@ -485,6 +485,7 @@ if (X11_Xft_FOUND AND OPTION_USE_PANGO)
   if (APPLE AND OPTION_APPLE_X11)
     find_file(FINK_PREFIX NAMES /opt/sw /sw)
     list (APPEND CMAKE_INCLUDE_PATH  ${FINK_PREFIX}/include)
+    include_directories (${FINK_PREFIX}/include/cairo)
     list (APPEND CMAKE_LIBRARY_PATH  ${FINK_PREFIX}/lib)
   endif (APPLE AND OPTION_APPLE_X11)
   find_file(HAVE_PANGO_H pango-1.0/pango/pango.h ${CMAKE_INCLUDE_PATH})
diff --git src/CMakeLists.txt src/CMakeLists.txt
index ff15cf0..c2f606e 100644
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -398,6 +398,14 @@ set (GL_DRIVER_FILES
   drivers/OpenGL/Fl_OpenGL_Graphics_Driver_rect.cxx
   drivers/OpenGL/Fl_OpenGL_Graphics_Driver_vertex.cxx
 )
+if (USE_X11)
+  set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/X11/Fl_X11_Gl_Window_driver.cxx)
+elseif (APPLE)
+  set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Cocoa/Fl_Cocoa_Gl_Window_driver.cxx)
+elseif (WIN32)
+  set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/WinAPI/Fl_WinAPI_Gl_Window_driver.cxx)
+endif (USE_X11)
+
 set (GL_DRIVER_HEADER_FILES
   drivers/OpenGL/Fl_OpenGL_Display_Device.H
   drivers/OpenGL/Fl_OpenGL_Graphics_Driver.H
diff --git src/Fl_Gl_Choice.H src/Fl_Gl_Choice.H
index 7c83170..2d2f0fb 100644
--- src/Fl_Gl_Choice.H
+++ src/Fl_Gl_Choice.H
@@ -40,33 +40,7 @@
 #ifndef Fl_Gl_Choice_H
 #define Fl_Gl_Choice_H
 
-#ifdef FL_CFG_GFX_QUARTZ
-#  include <OpenGL/gl.h>
-#  define FL_GL_CHOICE_PLATFORM_SPECIFIC_MEMBERS  void* pixelformat;
-#endif // FL_CFG_GFX_QUARTZ
-
-
-#ifdef FL_CFG_GFX_XLIB
-#  include <GL/glx.h>
-#  if ! defined(GLX_VERSION_1_3)
-#    typedef void *GLXFBConfig;
-#  endif
-#  define FL_GL_CHOICE_PLATFORM_SPECIFIC_MEMBERS  \
-      XVisualInfo *vis; /* the visual to use */ \
-      Colormap colormap; /* a colormap for that visual */ \
-      GLXFBConfig best_fb;
-#endif // FL_CFG_GFX_XLIB*/
-
-
-#ifdef FL_CFG_GFX_GDI
-#  include <FL/gl.h>
-#  define FL_GL_CHOICE_PLATFORM_SPECIFIC_MEMBERS  \
-      int pixelformat;       /* the visual to use */ \
-      PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
-#endif // FL_CFG_GFX_GDI
-
-
-// Describes crap needed to create a GLContext.
+// Describes the platform-independent part of data needed to create a GLContext.
 class Fl_Gl_Choice {
   friend class Fl_Gl_Window_Driver;
   int mode;
@@ -74,9 +48,6 @@ class Fl_Gl_Choice {
   Fl_Gl_Choice *next;
 public:
   Fl_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : mode(m), alist(alistp), next(n) {}
-  FL_GL_CHOICE_PLATFORM_SPECIFIC_MEMBERS
 };
 
-#undef FL_GL_CHOICE_PLATFORM_SPECIFIC_MEMBERS
-
 #endif // Fl_Gl_Choice_H
diff --git src/Fl_Gl_Choice.cxx src/Fl_Gl_Choice.cxx
index 12bf46e..9936873 100644
--- src/Fl_Gl_Choice.cxx
+++ src/Fl_Gl_Choice.cxx
@@ -18,19 +18,16 @@
 #if HAVE_GL
 
 #  include <FL/Fl.H>
-#  include <stdlib.h>
 #  include "Fl_Gl_Choice.H"
 #  include <FL/Fl_Gl_Window.H>
 #  include "Fl_Gl_Window_Driver.H"
 #  include <FL/gl_draw.H>
-#  include "flstring.h"
-#  include <FL/fl_utf8.h>
 
+GLContext *Fl_Gl_Window_Driver::context_list = 0;
+int Fl_Gl_Window_Driver::nContext = 0;
+static int NContext = 0;
 
-static GLContext *context_list = 0;
-static int nContext = 0, NContext = 0;
-
-static void add_context(GLContext ctx) {
+void Fl_Gl_Window_Driver::add_context(GLContext ctx) {
   if (!ctx) return;
   if (nContext==NContext) {
     if (!NContext) NContext = 8;
@@ -41,7 +38,7 @@ static void add_context(GLContext ctx) {
   context_list[nContext++] = ctx;
 }
 
-static void del_context(GLContext ctx) {
+void Fl_Gl_Window_Driver::del_context(GLContext ctx) {
   int i;
   for (i=0; i<nContext; i++) {
     if (context_list[i]==ctx) {
@@ -54,7 +51,7 @@ static void del_context(GLContext ctx) {
   if (!nContext) gl_remove_displaylist_fonts();
 }
 
-static Fl_Gl_Choice *first;
+Fl_Gl_Choice *Fl_Gl_Window_Driver::first;
 
 /**
  \cond DriverDev
@@ -78,406 +75,4 @@ Fl_Gl_Choice *Fl_Gl_Window_Driver::find_begin(int m, const int *alistp) {
  \endcond
  */
 
-static GLContext cached_context;
-static Fl_Window* cached_window;
-
-
-#ifdef FL_CFG_GFX_QUARTZ
-#  include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H"
-#  include "Fl_Screen_Driver.H"
-
-extern void gl_texture_reset();
-
-Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp)
-{
-  Fl::screen_driver()->open_display(); // useful when called through gl_start()
-  Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
-  if (g) return g;
-  NSOpenGLPixelFormat* fmt = Fl_Cocoa_Window_Driver::mode_to_NSOpenGLPixelFormat(m, alistp);
-  if (!fmt) return 0;
-  g = new Fl_Gl_Choice(m, alistp, first);
-  first = g;
-  g->pixelformat = fmt;
-  return g;
-}
-
-GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
-  GLContext context, shared_ctx = 0;
-  if (context_list && nContext) shared_ctx = context_list[0];
-  // resets the pile of string textures used to draw strings
-  // necessary before the first context is created
-  if (!shared_ctx) gl_texture_reset();
-  context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window((NSOpenGLPixelFormat*)g->pixelformat, shared_ctx, window);
-  if (!context) return 0;
-  add_context(context);
-  return (context);
-}
-
-void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
-  if (context != cached_context || w != cached_window) {
-    cached_context = context;
-    cached_window = w;
-    Fl_Cocoa_Window_Driver::GLcontext_makecurrent(context);
-  }
-}
-
-void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) {
-  if (cached_context == context) {
-    cached_context = 0;
-    cached_window = 0;
-    Fl_Cocoa_Window_Driver::GL_cleardrawable();
-  }
-  Fl_Cocoa_Window_Driver::GLcontext_release(context);
-  del_context(context);
-}
-
-#endif // FL_CFG_GFX_QUARTZ
-
-#ifdef FL_CFG_GFX_GDI
-#  include <FL/platform.H>
-#  include <FL/Fl_Graphics_Driver.H>
-#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
-extern void fl_save_dc(HWND, HDC);
-
-// STR #3119: select pixel format with composition support
-// ... and no more than 32 color bits (8 bits/color)
-// Ref: PixelFormatDescriptor Object
-// https://msdn.microsoft.com/en-us/library/cc231189.aspx
-#if !defined(PFD_SUPPORT_COMPOSITION)
-# define PFD_SUPPORT_COMPOSITION (0x8000)
-#endif
-
-#define DEBUG_PFD (0) // 1 = PFD selection debug output, 0 = no debug output
-
-Fl_Gl_Choice *Fl_WinAPI_Gl_Window_Driver::find(int m, const int *alistp)
-{
-  Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
-  if (g) return g;
-
-  // Replacement for ChoosePixelFormat() that finds one with an overlay if possible:
-  HDC gc = (HDC)(fl_graphics_driver ? fl_graphics_driver->gc() : 0);
-  if (!gc) gc = fl_GetDC(0);
-  int pixelformat = 0;
-  PIXELFORMATDESCRIPTOR chosen_pfd;
-  for (int i = 1; ; i++) {
-    PIXELFORMATDESCRIPTOR pfd;
-    if (!DescribePixelFormat(gc, i, sizeof(pfd), &pfd)) break;
-    // continue if it does not satisfy our requirements:
-    if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue;
-    if (pfd.iPixelType != ((m&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue;
-    if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue;
-    if ((m & FL_ACCUM) && !pfd.cAccumBits) continue;
-    if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
-    if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue;
-    if ((m & FL_DEPTH) && !pfd.cDepthBits) continue;
-    if ((m & FL_STENCIL) && !pfd.cStencilBits) continue;
-
-#if DEBUG_PFD
-    printf("pfd #%d supports composition: %s\n", i, (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) ? "yes" : "no");
-    printf("    ... & PFD_GENERIC_FORMAT: %s\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) ? "generic" : "accelerated");
-    printf("    ... Overlay Planes      : %d\n", pfd.bReserved & 15);
-    printf("    ... Color & Depth       : %d, %d\n", pfd.cColorBits, pfd.cDepthBits);
-    if (pixelformat)
-      printf("        current pixelformat : %d\n", pixelformat);
-    fflush(stdout);
-#endif // DEBUG_PFD
-
-    // see if better than the one we have already:
-    if (pixelformat) {
-      // offering non-generic rendering is better (read: hardware acceleration)
-      if (!(chosen_pfd.dwFlags & PFD_GENERIC_FORMAT) &&
-          (pfd.dwFlags & PFD_GENERIC_FORMAT)) continue;
-      // offering overlay is better:
-      else if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {}
-      // otherwise prefer a format that supports composition (STR #3119)
-      else if ((chosen_pfd.dwFlags & PFD_SUPPORT_COMPOSITION) &&
-               !(pfd.dwFlags & PFD_SUPPORT_COMPOSITION)) continue;
-      // otherwise more bit planes is better, but no more than 32 (8 bits per channel):
-      else if (pfd.cColorBits > 32 || chosen_pfd.cColorBits > pfd.cColorBits) continue;
-      else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue;
-    }
-    pixelformat = i;
-    chosen_pfd = pfd;
-  }
-
-#if DEBUG_PFD
-  static int bb = 0;
-  if (!bb) {
-    bb = 1;
-    printf("PFD_SUPPORT_COMPOSITION = 0x%x\n", PFD_SUPPORT_COMPOSITION);
-  }
-  printf("Chosen pixel format is %d\n", pixelformat);
-  printf("Color bits = %d, Depth bits = %d\n", chosen_pfd.cColorBits, chosen_pfd.cDepthBits);
-  printf("Pixel format supports composition: %s\n", (chosen_pfd.dwFlags & PFD_SUPPORT_COMPOSITION) ? "yes" : "no");
-  fflush(stdout);
-#endif // DEBUG_PFD
-
-  if (!pixelformat) return 0;
-
-  g = new Fl_Gl_Choice(m, alistp, first);
-  first = g;
-
-  g->pixelformat = pixelformat;
-  g->pfd = chosen_pfd;
-
-  return g;
-}
-
-
-GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer)
-{
-  Fl_X* i = Fl_X::i(window);
-  HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc;
-  if (!hdc) {
-    hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
-    fl_save_dc(i->xid, hdc);
-    SetPixelFormat(hdc, g->pixelformat, (PIXELFORMATDESCRIPTOR*)(&g->pfd));
-#    if USE_COLORMAP
-    if (fl_palette) SelectPalette(hdc, fl_palette, FALSE);
-#    endif
-  }
-  GLContext context = layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc);
-  if (context) {
-    if (context_list && nContext)
-      wglShareLists(context_list[0], context);
-    add_context(context);
-  }
-  return context;
-}
-
-
-void Fl_WinAPI_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
-  if (context != cached_context || w != cached_window) {
-    cached_context = context;
-    cached_window = w;
-    wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context);
-  }
-}
-
-void Fl_WinAPI_Gl_Window_Driver::delete_gl_context(GLContext context) {
-  if (cached_context == context) {
-    cached_context = 0;
-    cached_window = 0;
-    wglMakeCurrent(0, 0);
-  }
-  wglDeleteContext(context);
-  del_context(context);
-}
-
-#endif // FL_CFG_GFX_GDI
-
-#ifdef FL_CFG_GFX_XLIB
-#  include <FL/platform.H>
-
-static XVisualInfo *gl3_getvisual(const int *blist, GLXFBConfig *pbestFB)
-{
-  int glx_major, glx_minor;
-
-  // FBConfigs were added in GLX version 1.3.
-  if ( !glXQueryVersion(fl_display, &glx_major, &glx_minor) ||
-      ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) {
-    return NULL;
-  }
-
-  //printf( "Getting matching framebuffer configs\n" );
-  int fbcount;
-  GLXFBConfig* fbc = glXChooseFBConfig(fl_display, DefaultScreen(fl_display), blist, &fbcount);
-  if (!fbc) {
-    //printf( "Failed to retrieve a framebuffer config\n" );
-    return NULL;
-  }
-  //printf( "Found %d matching FB configs.\n", fbcount );
-
-  // Pick the FB config/visual with the most samples per pixel
-  int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
-  for (int i = 0; i < fbcount; ++i)
-  {
-    XVisualInfo *vi = glXGetVisualFromFBConfig( fl_display, fbc[i] );
-    if (vi) {
-      int samp_buf, samples;
-      glXGetFBConfigAttrib(fl_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
-      glXGetFBConfigAttrib(fl_display, fbc[i], GLX_SAMPLES       , &samples );
-      /*printf( "  Matching fbconfig %d, visual ID 0x%2lx: SAMPLE_BUFFERS = %d, SAMPLES = %d\n",
-             i, vi -> visualid, samp_buf, samples );*/
-      if ( best_fbc < 0 || (samp_buf && samples > best_num_samp) )
-        best_fbc = i, best_num_samp = samples;
-      if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
-        worst_fbc = i, worst_num_samp = samples;
-    }
-    XFree(vi);
-  }
-
-  GLXFBConfig bestFbc = fbc[ best_fbc ];
-  // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
-  XFree(fbc);
-  // Get a visual
-  XVisualInfo *vi = glXGetVisualFromFBConfig(fl_display, bestFbc);
-  *pbestFB = bestFbc;
-  return vi;
-}
-
-Fl_Gl_Choice *Fl_X11_Gl_Window_Driver::find(int m, const int *alistp)
-{
-  Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
-  if (g) return g;
-
-  const int *blist;
-  int list[32];
-
-  if (alistp)
-    blist = alistp;
-  else {
-    int n = 0;
-    if (m & FL_INDEX) {
-      list[n++] = GLX_BUFFER_SIZE;
-      list[n++] = 8; // glut tries many sizes, but this should work...
-    } else {
-      list[n++] = GLX_RGBA;
-      list[n++] = GLX_GREEN_SIZE;
-      list[n++] = (m & FL_RGB8) ? 8 : 1;
-      if (m & FL_ALPHA) {
-        list[n++] = GLX_ALPHA_SIZE;
-        list[n++] = (m & FL_RGB8) ? 8 : 1;
-      }
-      if (m & FL_ACCUM) {
-        list[n++] = GLX_ACCUM_GREEN_SIZE;
-        list[n++] = 1;
-        if (m & FL_ALPHA) {
-          list[n++] = GLX_ACCUM_ALPHA_SIZE;
-          list[n++] = 1;
-        }
-      }
-    }
-    if (m & FL_DOUBLE) {
-      list[n++] = GLX_DOUBLEBUFFER;
-    }
-    if (m & FL_DEPTH) {
-      list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
-    }
-    if (m & FL_STENCIL) {
-      list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
-    }
-    if (m & FL_STEREO) {
-      list[n++] = GLX_STEREO;
-    }
-#    if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
-    if (m & FL_MULTISAMPLE) {
-      list[n++] = GLX_SAMPLES_SGIS;
-      list[n++] = 4; // value Glut uses
-    }
-#    endif
-    list[n] = 0;
-    blist = list;
-  }
-
-  fl_open_display();
-  XVisualInfo *visp = NULL;
-  GLXFBConfig best_fb = NULL;
-  if (m & FL_OPENGL3) {
-    visp = gl3_getvisual((const int *)blist, &best_fb);
-  }
-  if (!visp) {
-    visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
-    if (!visp) {
-#     if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
-        if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE, 0);
-#     endif
-      return 0;
-    }
-  }
-
-  g = new Fl_Gl_Choice(m, alistp, first);
-  first = g;
-
-  g->vis = visp;
-  g->best_fb = best_fb;
-
-  if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
-      visp->visualid == fl_visual->visualid &&
-      !fl_getenv("MESA_PRIVATE_CMAP"))
-    g->colormap = fl_colormap;
-  else
-    g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
-                                  visp->visual, AllocNone);
-  return g;
-}
-
-static bool ctxErrorOccurred = false;
-static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
-{
-  ctxErrorOccurred = true;
-  return 0;
-}
-
-GLContext Fl_X11_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
-  GLContext shared_ctx = 0;
-  if (context_list && nContext) shared_ctx = context_list[0];
-
-  typedef GLContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLContext, Bool, const int*);
-  // It is not necessary to create or make current to a context before calling glXGetProcAddressARB
-  static glXCreateContextAttribsARBProc glXCreateContextAttribsARB =
-#if defined(HAVE_GLXGETPROCADDRESSARB)
-    (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB");
-#else
-  NULL;
-#endif
-
-  GLContext ctx = 0;
-  // Check for the GLX_ARB_create_context extension string and the function.
-  // If either is not present, use GLX 1.3 context creation method.
-  const char *glxExts = glXQueryExtensionsString(fl_display, fl_screen);
-  if (g->best_fb && strstr(glxExts, "GLX_ARB_create_context") && glXCreateContextAttribsARB ) {
-    int context_attribs[] =
-    {
-      GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
-      GLX_CONTEXT_MINOR_VERSION_ARB, 2,
-      //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
-      //GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
-      None
-    };
-    ctxErrorOccurred = false;
-    XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
-    ctx = glXCreateContextAttribsARB(fl_display, g->best_fb, shared_ctx, true, context_attribs);
-    XSync(fl_display, false); // Sync to ensure any errors generated are processed.
-    if (ctxErrorOccurred) ctx = 0;
-    XSetErrorHandler(oldHandler);
-  }
-  if (!ctx) { // use OpenGL 1-style context creation
-    ctx = glXCreateContext(fl_display, g->vis, shared_ctx, true);
-  }
-  if (ctx)
-    add_context(ctx);
-//glXMakeCurrent(fl_display, fl_xid(window), ctx);printf("%s\n", glGetString(GL_VERSION));
-  return ctx;
-}
-
-GLContext Fl_X11_Gl_Window_Driver::create_gl_context(XVisualInfo *vis) {
-  GLContext shared_ctx = 0;
-  if (context_list && nContext) shared_ctx = context_list[0];
-  GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1);
-  if (context)
-    add_context(context);
-  return context;
-}
-
-void Fl_X11_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
-  if (context != cached_context || w != cached_window) {
-    cached_context = context;
-    cached_window = w;
-    glXMakeCurrent(fl_display, fl_xid(w), context);
-  }
-}
-
-void Fl_X11_Gl_Window_Driver::delete_gl_context(GLContext context) {
-  if (cached_context == context) {
-    cached_context = 0;
-    cached_window = 0;
-    glXMakeCurrent(fl_display, 0, 0);
-  }
-  glXDestroyContext(fl_display, context);
-  del_context(context);
-}
-
-#endif // FL_CFG_GFX_XLIB
-
 #endif // HAVE_GL
diff --git src/Fl_Gl_Overlay.cxx src/Fl_Gl_Overlay.cxx
index b03e139..04c906a 100644
--- src/Fl_Gl_Overlay.cxx
+++ src/Fl_Gl_Overlay.cxx
@@ -76,227 +76,4 @@ void Fl_Gl_Window::hide_overlay() {
   pGlWindowDriver->hide_overlay();
 }
 
-
-// Methods on Fl_Gl_Window that create an overlay window.  Because
-// many programs don't need the overlay, this is separated into this
-// source file so it is not linked in if not used.
-
-// Under X this is done by creating another window, of class _Fl_Gl_Overlay
-// which is a subclass of Fl_Gl_Window except it uses the overlay planes.
-// A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.
-
-// Under win32 another GLX context is created to draw into the overlay
-// and it is stored in the "overlay" pointer.
-
-// In both cases if overlay hardware is unavailable, the overlay is
-// "faked" by drawing into the main layers.  This is indicated by
-// setting overlay == this.
-
-#ifdef FL_CFG_GFX_QUARTZ
-
-void Fl_Cocoa_Gl_Window_Driver::make_overlay_current() {
-  // this is not very useful, but unfortunately, Apple decided
-  // that front buffer drawing can no longer (OS X 10.4) be supported on their platforms.
-  pWindow->make_current();
-}
-
-void Fl_Cocoa_Gl_Window_Driver::redraw_overlay() {
-  pWindow->redraw();
-}
-
-#endif // FL_CFG_GFX_QUARTZ
-
-
-#ifdef FL_CFG_GFX_XLIB
-#include <FL/platform.H>
-////////////////////////////////////////////////////////////////
-// X version
-
-void Fl_X11_Gl_Window_Driver::make_overlay_current() {
-#if HAVE_GL_OVERLAY
-  if (overlay() != pWindow) {
-    ((Fl_Gl_Window*)overlay())->make_current();
-  } else
-#endif
-    glDrawBuffer(GL_FRONT);
-}
-
-void Fl_X11_Gl_Window_Driver::redraw_overlay() {
-  if (overlay() != pWindow)
-    ((Fl_Gl_Window*)overlay())->redraw();
-  else
-    pWindow->damage(FL_DAMAGE_OVERLAY);
-}
-
-#if HAVE_GL_OVERLAY
-
-extern XVisualInfo *fl_find_overlay_visual();
-extern XVisualInfo *fl_overlay_visual;
-extern Colormap fl_overlay_colormap;
-extern unsigned long fl_transparent_pixel;
-extern uchar fl_overlay;
-
-class _Fl_Gl_Overlay : public Fl_Gl_Window {
-  void flush();
-  void draw();
-public:
-  void show();
-  _Fl_Gl_Overlay(int x, int y, int w, int h) :
-    Fl_Gl_Window(x,y,w,h) {
-    set_flag(INACTIVE);
-  }
-};
-
-void _Fl_Gl_Overlay::flush() {
-  make_current();
-#ifdef BOXX_BUGS
-  // The BoXX overlay is broken and you must not call swap-buffers. This
-  // code will make it work, but we lose because machines that do support
-  // double-buffered overlays will blink when they don't have to
-  glDrawBuffer(GL_FRONT);
-  draw();
-#else
-  draw();
-  swap_buffers();
-#endif
-  glFlush();
-  valid(1);
-}
-
-void _Fl_Gl_Overlay::draw() {
-  if (!valid()) glClearIndex((GLfloat)fl_transparent_pixel);
-  if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
-  Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
-  uchar save_valid = w->valid();
-  w->valid(valid());
-  fl_overlay = 1;
-  w->gl_driver()->draw_overlay();
-  fl_overlay = 0;
-  valid(w->valid());
-  w->valid(save_valid);
-}
-
-void _Fl_Gl_Overlay::show() {
-  if (!shown()) {
-    fl_background_pixel = int(fl_transparent_pixel);
-    Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
-    fl_background_pixel = -1;
-    // find the outermost window to tell wm about the colormap:
-    Fl_Window *w = window();
-    for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
-    XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
-    context(Fl_X11_Gl_Window_Driver::create_gl_context(fl_overlay_visual), 1);
-    valid(0);
-  }
-  Fl_Gl_Window::show();
-}
-
-void Fl_X11_Gl_Window_Driver::hide_overlay() {
-  if (overlay() && overlay() != pWindow) ((Fl_Gl_Window*)overlay())->hide();
-}
-
-int Fl_X11_Gl_Window_Driver::can_do_overlay() {
-  return fl_find_overlay_visual() != 0;
-}
-
-
-void Fl_X11_Gl_Window_Driver::make_overlay(void *&current) {
-  if (current) return;
-  if (can_do_overlay()) {
-    _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0, 0, pWindow->w(), pWindow->h());
-    current = o;
-    pWindow->add(*o);
-    o->show();
-  } else {
-    current = pWindow; // fake the overlay
-  }
-}
-#endif // HAVE_GL_OVERLAY
-
-#endif // FL_CFG_GFX_XLIB
-
-
-#ifdef FL_CFG_GFX_GDI
-#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
-
-////////////////////////////////////////////////////////////////
-// Windows version:
-
-#if HAVE_GL_OVERLAY
-void Fl_WinAPI_Gl_Window_Driver::gl_hide_before(void *& overlay) {
-  if (overlay && overlay != pWindow) {
-    delete_gl_context((GLContext)overlay);
-    overlay = 0;
-  }
-}
-#endif
-
-
-void Fl_WinAPI_Gl_Window_Driver::make_overlay_current() {
-#if HAVE_GL_OVERLAY
-  if (overlay() != this) {
-    set_gl_context(pWindow, (GLContext)overlay());
-    //  if (fl_overlay_depth)
-    //    wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
-  } else
-#endif
-    glDrawBuffer(GL_FRONT);
-}
-
-void Fl_WinAPI_Gl_Window_Driver::redraw_overlay() {
-  pWindow->damage(FL_DAMAGE_OVERLAY);
-}
-
-#if HAVE_GL_OVERLAY
-#  include "Fl_Gl_Choice.H"
-
-//static COLORREF *palette;
-extern int fl_overlay_depth;
-
-void Fl_WinAPI_Gl_Window_Driver::make_overlay(void*&overlay) {
-  if (overlay) return;
-
-  GLContext context = create_gl_context(pWindow, g(), 1);
-  if (!context) {overlay = pWindow; return;} // fake the overlay
-
-  HDC hdc = Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc;
-  overlay = context;
-  LAYERPLANEDESCRIPTOR pfd;
-  wglDescribeLayerPlane(hdc, g()->pixelformat, 1, sizeof(pfd), &pfd);
-  if (!pfd.iPixelType) {
-    ; // full-color overlay
-  } else {
-    fl_overlay_depth = pfd.cColorBits; // used by gl_color()
-    if (fl_overlay_depth > 8) fl_overlay_depth = 8;
-    COLORREF palette[256];
-    int n = (1<<fl_overlay_depth)-1;
-    // copy all colors except #0 into the overlay palette:
-    for (int i = 0; i <= n; i++) {
-      uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
-      palette[i] = RGB(r,g,b);
-    }
-    // always provide black & white in the last 2 pixels:
-    if (fl_overlay_depth < 8) {
-      palette[n-1] = RGB(0,0,0);
-      palette[n] = RGB(255,255,255);
-    }
-    // and use it:
-    wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
-    wglRealizeLayerPalette(hdc, 1, TRUE);
-  }
-  pWindow->valid(0);
-  return;
-}
-
-int Fl_WinAPI_Gl_Window_Driver::can_do_overlay() {
-  if (!g()) {
-    g( find(mode(), alist()) );
-    if (!g()) return 0;
-  }
-  return (g()->pfd.bReserved & 15) != 0;
-}
-#endif // HAVE_GL_OVERLAY
-
-#endif // FL_CFG_GFX_GDI
-
 #endif // HAVE_GL
diff --git src/Fl_Gl_Window.cxx src/Fl_Gl_Window.cxx
index bc0d0d9..fb4376a 100644
--- src/Fl_Gl_Window.cxx
+++ src/Fl_Gl_Window.cxx
@@ -64,6 +64,11 @@ static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable
 
 ////////////////////////////////////////////////////////////////
 
+int Fl_Gl_Window_Driver::copy = COPY;
+GLContext Fl_Gl_Window_Driver::cached_context = NULL;
+Fl_Window* Fl_Gl_Window_Driver::cached_window = NULL;
+float Fl_Gl_Window_Driver::gl_scale = 1; // scaling factor between FLTK and GL drawing units: GL = FLTK * gl_scale
+
 /**  Returns non-zero if the hardware supports the given or current OpenGL  mode. */
 int Fl_Gl_Window::can_do(int a, const int *b) {
   return Fl_Gl_Window_Driver::global()->find(a,b) != 0;
@@ -501,266 +506,6 @@ Fl_Font_Descriptor** Fl_Gl_Window_Driver::fontnum_to_fontdescriptor(int fnum) {
   return &(fl_fonts[fnum].first);
 }
 
-#ifdef FL_CFG_GFX_QUARTZ
-#include <FL/platform.H>
-#include <OpenGL/OpenGL.h>
-#include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H"
-
-Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
-{
-  return new Fl_Cocoa_Gl_Window_Driver(w);
-}
-
-void Fl_Cocoa_Gl_Window_Driver::before_show(int& need_after) {
-  need_after = 1;
-}
-
-void Fl_Cocoa_Gl_Window_Driver::after_show() {
-  // Makes sure the GL context is created to avoid drawing twice the window when first shown
-  pWindow->make_current();
-}
-
-float Fl_Cocoa_Gl_Window_Driver::pixels_per_unit()
-{
-  int retina = (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(pWindow) &&
-          Fl_Cocoa_Window_Driver::driver(pWindow)->mapped_to_retina()) ? 2 : 1;
-  return retina * Fl_Graphics_Driver::default_driver().scale();
-}
-
-int Fl_Cocoa_Gl_Window_Driver::mode_(int m, const int *a) {
-  if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
-    // the FL_DOUBLE flag must be set in the mode_ member variable
-    const int *aa = a;
-    while (*aa) {
-      if (*(aa++) ==
-          kCGLPFADoubleBuffer
-          ) { m |= FL_DOUBLE; break; }
-    }
-  }
-  pWindow->context(0);
-  mode( m); alist(a);
-  if (pWindow->shown()) {
-    g( find(m, a) );
-    pWindow->redraw();
-  } else {
-    g(0);
-  }
-  return 1;
-}
-
-void Fl_Cocoa_Gl_Window_Driver::make_current_before() {
-  // detect if the window was moved between low and high resolution displays
-  Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(pWindow);
-  if (d->changed_resolution()){
-    d->changed_resolution(false);
-    pWindow->invalidate();
-    Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context());
-  }
-}
-
-void Fl_Cocoa_Gl_Window_Driver::swap_buffers() {
-  if (overlay() != NULL) {
-    // STR# 2944 [1]
-    //    Save matrixmode/proj/modelview/rasterpos before doing overlay.
-    //
-    int wo = pWindow->pixel_w(), ho = pWindow->pixel_h();
-    GLint matrixmode;
-    GLfloat pos[4];
-    glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
-    glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);       // save original glRasterPos
-    glMatrixMode(GL_PROJECTION);                        // save proj/model matrices
-    glPushMatrix();
-    glLoadIdentity();
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
-    glScalef(2.0f/wo, 2.0f/ho, 1.0f);
-    glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f);         // set transform so 0,0 is bottom/left of Gl_Window
-    glRasterPos2i(0,0);                             // set glRasterPos to bottom left corner
-    {
-      // Emulate overlay by doing copypixels
-      glReadBuffer(GL_BACK);
-      glDrawBuffer(GL_FRONT);
-      glCopyPixels(0, 0, wo, ho, GL_COLOR);         // copy GL_BACK to GL_FRONT
-    }
-    glPopMatrix(); // GL_MODELVIEW                  // restore model/proj matrices
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode(matrixmode);
-    glRasterPos3f(pos[0], pos[1], pos[2]);              // restore original glRasterPos
-  }
-   else
-     Fl_Cocoa_Window_Driver::flush_context(pWindow->context());//aglSwapBuffers((AGLContext)context_);
-}
-
-char Fl_Cocoa_Gl_Window_Driver::swap_type() {return COPY;}
-
-void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) {
-  Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context());
-}
-
-#endif // FL_CFG_GFX_QUARTZ
-
-#if defined(FL_CFG_GFX_GDI)
-#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
-#include <FL/platform.H>
-#include <FL/Fl_Graphics_Driver.H>
-#include "Fl_Screen_Driver.H"
-
-Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
-{
-  return new Fl_WinAPI_Gl_Window_Driver(w);
-}
-
-float Fl_WinAPI_Gl_Window_Driver::pixels_per_unit()
-{
-  int ns = Fl_Window_Driver::driver(pWindow)->screen_num();
-  return Fl::screen_driver()->scale(ns);
-}
-
-
-int Fl_WinAPI_Gl_Window_Driver::mode_(int m, const int *a) {
-  int oldmode = mode();
-  pWindow->context(0);
-  mode( m); alist(a);
-  if (pWindow->shown()) {
-    g( find(m, a) );
-    if (!g() || (oldmode^m)&(FL_DOUBLE|FL_STEREO)) {
-      pWindow->hide();
-      pWindow->show();
-    }
-  } else {
-    g(0);
-  }
-  return 1;
-}
-
-void Fl_WinAPI_Gl_Window_Driver::make_current_after() {
-#if USE_COLORMAP
-  if (fl_palette) {
-    fl_GetDC(fl_xid(pWindow));
-    SelectPalette((HDC)fl_graphics_driver->gc(), fl_palette, FALSE);
-    RealizePalette((HDC)fl_graphics_driver->gc());
-  }
-#endif // USE_COLORMAP
-}
-
-//#define HAVE_GL_OVERLAY 1 //test only
-
-void Fl_WinAPI_Gl_Window_Driver::swap_buffers() {
-#  if HAVE_GL_OVERLAY
-  // Do not swap the overlay, to match GLX:
-  BOOL ret = wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, WGL_SWAP_MAIN_PLANE);
-  DWORD err = GetLastError();
-#  else
-  SwapBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc);
-#  endif
-}
-
-#if HAVE_GL_OVERLAY
-uchar fl_overlay; // changes how fl_color() works
-int fl_overlay_depth = 0;
-#endif
-
-int Fl_WinAPI_Gl_Window_Driver::flush_begin(char& valid_f_) {
-#if HAVE_GL_OVERLAY
-  char save_valid_f = valid_f_;
-  // Draw into hardware overlay planes if they are damaged:
-  if (overlay() && overlay() != pWindow
-      && (pWindow->damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid_f & 1)) {
-    set_gl_context(pWindow, (GLContext)overlay());
-    if (fl_overlay_depth)
-      wglRealizeLayerPalette(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, 1, TRUE);
-    glDisable(GL_SCISSOR_TEST);
-    glClear(GL_COLOR_BUFFER_BIT);
-    fl_overlay = 1;
-    draw_overlay();
-    fl_overlay = 0;
-    valid_f_ = save_valid_f;
-    wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, WGL_SWAP_OVERLAY1);
-    // if only the overlay was damaged we are done, leave main layer alone:
-    if (pWindow->damage() == FL_DAMAGE_OVERLAY) {
-      return 1;
-    }
-  }
-#endif
-  return 0;
-}
-
-void* Fl_WinAPI_Gl_Window_Driver::GetProcAddress(const char *procName) {
-  return (void*)wglGetProcAddress((LPCSTR)procName);
-}
-
-#endif // FL_CFG_GFX_GDI
-
-
-#if defined(FL_CFG_GFX_XLIB)
-#include <FL/platform.H>
-#include "Fl_Gl_Choice.H"
-#include "Fl_Screen_Driver.H"
-#include "Fl_Window_Driver.H"
-
-Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
-{
-  return new Fl_X11_Gl_Window_Driver(w);
-}
-
-void Fl_X11_Gl_Window_Driver::before_show(int&) {
-  Fl_X::make_xid(pWindow, g()->vis, g()->colormap);
-  if (overlay() && overlay() != pWindow) ((Fl_Gl_Window*)overlay())->show();
-}
-
-float Fl_X11_Gl_Window_Driver::pixels_per_unit()
-{
-  int ns = Fl_Window_Driver::driver(pWindow)->screen_num();
-  return Fl::screen_driver()->scale(ns);
-}
-
-int Fl_X11_Gl_Window_Driver::mode_(int m, const int *a) {
-  int oldmode = mode();
-  if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
-    // the FL_DOUBLE flag must be set in the mode_ member variable
-    const int *aa = a;
-    while (*aa) {
-      if (*(aa++) ==
-          GLX_DOUBLEBUFFER
-          ) { m |= FL_DOUBLE; break; }
-    }
-  }
-  Fl_Gl_Choice* oldg = g();
-  pWindow->context(0);
-  mode(m); alist(a);
-  if (pWindow->shown()) {
-    g( find(m, a) );
-    // under X, if the visual changes we must make a new X window (yuck!):
-    if (!g() || g()->vis->visualid != oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) {
-      pWindow->hide();
-      pWindow->show();
-    }
-  } else {
-    g(0);
-  }
-  return 1;
-}
-
-void Fl_X11_Gl_Window_Driver::swap_buffers() {
-  glXSwapBuffers(fl_display, fl_xid(pWindow));
-}
-
-void Fl_X11_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
-  if (is_a_resize && !pWindow->resizable() && overlay() && overlay() != pWindow) {
-    ((Fl_Gl_Window*)overlay())->resize(0,0,W,H);
-  }
-}
-
-char Fl_X11_Gl_Window_Driver::swap_type() {return COPY;}
-
-void Fl_X11_Gl_Window_Driver::waitGL() {
-  glXWaitGL();
-}
-
-#endif // FL_CFG_GFX_XLIB
-
 /**
  \}
  \endcond
diff --git src/Fl_Gl_Window_Driver.H src/Fl_Gl_Window_Driver.H
index 94a54b5..d2670e2 100644
--- src/Fl_Gl_Window_Driver.H
+++ src/Fl_Gl_Window_Driver.H
@@ -36,6 +36,14 @@ class Fl_Gl_Window_Driver {
 protected:
   Fl_Gl_Window *pWindow;
 public:
+  static GLContext cached_context;
+  static Fl_Window* cached_window;
+  static int nContext;
+  static GLContext *context_list;
+  static Fl_Gl_Choice *first;
+  static int copy;
+  static float gl_scale;
+  static GLContext gl_start_context;
   Fl_Gl_Choice* g() {return pWindow->g;}
   void g(Fl_Gl_Choice *c) {pWindow->g = c;}
   int mode() {return pWindow->mode_;}
@@ -62,6 +70,8 @@ public:
   virtual int flush_begin(char& valid_f) {return 0;}
   virtual void gl_hide_before(void *& overlay) {} // the default implementation may be enough
   static Fl_Gl_Choice *find_begin(int m, const int *alistp);
+  static void add_context(GLContext ctx);
+  static void del_context(GLContext ctx);
   // Return one of these structures for a given gl mode.
   // The second argument is a glX attribute list, and is used if mode is zero.
   // This is not supported on Win32:
@@ -91,109 +101,6 @@ public:
   virtual Fl_Font_Descriptor** fontnum_to_fontdescriptor(int fnum);
 };
 
-#ifdef FL_CFG_GFX_QUARTZ
-#ifdef __OBJC__
-@class NSOpenGLPixelFormat;
-#else
-class NSOpenGLPixelFormat;
-#endif // __OBJC__
-
-class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver {
-  friend class Fl_Gl_Window_Driver;
-  friend class Fl_OpenGL_Display_Device;
-  Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
-  virtual float pixels_per_unit();
-  virtual void before_show(int& need_after);
-  virtual void after_show();
-  virtual int mode_(int m, const int *a);
-  virtual void make_current_before();
-  virtual void swap_buffers();
-  virtual void resize(int is_a_resize, int w, int h);
-  virtual char swap_type();
-  virtual Fl_Gl_Choice *find(int m, const int *alistp);
-  virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
-  virtual void set_gl_context(Fl_Window* w, GLContext context);
-  virtual void delete_gl_context(GLContext);
-  virtual void make_overlay_current();
-  virtual void redraw_overlay();
-  virtual void gl_start();
-  virtual char *alpha_mask_for_string(const char *str, int n, int w, int h);
-};
-#endif // FL_CFG_GFX_QUARTZ
-
-
-#ifdef FL_CFG_GFX_GDI
-
-class Fl_WinAPI_Gl_Window_Driver : public Fl_Gl_Window_Driver {
-  friend class Fl_Gl_Window_Driver;
-  Fl_WinAPI_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
-  virtual float pixels_per_unit();
-  virtual int mode_(int m, const int *a);
-  virtual void make_current_after();
-  virtual void swap_buffers();
-  virtual void invalidate() {}
-  virtual int flush_begin(char& valid_f);
-  virtual Fl_Gl_Choice *find(int m, const int *alistp);
-  virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
-  virtual void set_gl_context(Fl_Window* w, GLContext context);
-  virtual void delete_gl_context(GLContext);
-  virtual void make_overlay_current();
-  virtual void redraw_overlay();
-  virtual void* GetProcAddress(const char *procName);
-  virtual void draw_string_legacy(const char* str, int n);
-  virtual void gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize);
-  virtual void get_list(Fl_Font_Descriptor *fd, int r);
-  virtual int genlistsize();
-#if HAVE_GL_OVERLAY
-  virtual void gl_hide_before(void *& overlay);
-  virtual int can_do_overlay();
-  virtual int overlay_color(Fl_Color i);
-  void make_overlay(void*&overlay);
-#endif
-};
-
-#endif // FL_CFG_GFX_GDI
-
-
-#ifdef FL_CFG_GFX_XLIB
-#include <X11/Xutil.h> // for XVisualInfo
-class Fl_X11_Gl_Window_Driver : public Fl_Gl_Window_Driver {
-  friend class Fl_Gl_Window_Driver;
-  Fl_X11_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
-  virtual float pixels_per_unit();
-  virtual void before_show(int& need_after);
-  virtual int mode_(int m, const int *a);
-  virtual void swap_buffers();
-  virtual void resize(int is_a_resize, int w, int h);
-  virtual char swap_type();
-  virtual Fl_Gl_Choice *find(int m, const int *alistp);
-  virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
-  virtual void set_gl_context(Fl_Window* w, GLContext context);
-  virtual void delete_gl_context(GLContext);
-#if HAVE_GL_OVERLAY
-  virtual void make_overlay(void *&o);
-  virtual int can_do_overlay();
-  virtual void hide_overlay();
-  virtual int overlay_color(Fl_Color i);
-#endif
-  virtual void make_overlay_current();
-  virtual void redraw_overlay();
-  virtual void waitGL();
-  virtual void gl_visual(Fl_Gl_Choice*); // support for Fl::gl_visual()
-  virtual void gl_start();
-  virtual void draw_string_legacy(const char* str, int n);
-  virtual void gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize);
-  virtual void get_list(Fl_Font_Descriptor *fd, int r);
-  virtual int genlistsize();
-#if !USE_XFT
-  virtual Fl_Font_Descriptor** fontnum_to_fontdescriptor(int fnum);
-#endif
-  public:
-  static GLContext create_gl_context(XVisualInfo* vis);
-};
-
-#endif // FL_CFG_GFX_XLIB
-
 #endif /* Fl_Gl_Window_Driver_H */
 
 /**
diff --git src/Makefile src/Makefile
index c2577c0..00e02c0 100644
--- src/Makefile
+++ src/Makefile
@@ -198,6 +198,13 @@ GLCPPFILES = \
 	drivers/OpenGL/Fl_OpenGL_Graphics_Driver_rect.cxx \
 	drivers/OpenGL/Fl_OpenGL_Graphics_Driver_vertex.cxx
 
+GLCPPFILES_OSX = drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
+GLCPPFILES_X11 = drivers/X11/Fl_X11_Gl_Window_Driver.cxx
+GLCPPFILES_XFT = $(GLCPPFILES_X11)
+GLCPPFILES_WIN = drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx
+
+GLCPPFILES += $(GLCPPFILES_$(BUILD))
+
 #	the following file currently doesn't contribute code to GLCPPFILES
 #	drivers/OpenGL/Fl_OpenGL_Graphics_Driver.cxx
 
diff --git src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
new file mode 100644
index 0000000..188f4fe
--- /dev/null
+++ src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
@@ -0,0 +1,248 @@
+//
+// Class Fl_Cocoa_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2021 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file.  If this
+// file is missing or damaged, see the license at:
+//
+//     https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+//     https://www.fltk.org/bugs.php
+//
+
+#include <config.h>
+#if HAVE_GL
+#include <FL/platform.H>
+#include <FL/gl.h>
+#include "../../Fl_Gl_Choice.H"
+#include "../../Fl_Screen_Driver.H"
+#include "Fl_Cocoa_Window_Driver.H"
+#include "../../Fl_Gl_Window_Driver.H"
+#include <FL/Fl_Graphics_Driver.H>
+#include <OpenGL/OpenGL.h>
+#include <FL/Fl_Image_Surface.H>
+
+extern void gl_texture_reset();
+
+#ifdef __OBJC__
+@class NSOpenGLPixelFormat;
+#else
+class NSOpenGLPixelFormat;
+#endif // __OBJC__
+
+class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver {
+  friend class Fl_Gl_Window_Driver;
+  friend class Fl_OpenGL_Display_Device;
+  Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
+  virtual float pixels_per_unit();
+  virtual void before_show(int& need_after);
+  virtual void after_show();
+  virtual int mode_(int m, const int *a);
+  virtual void make_current_before();
+  virtual void swap_buffers();
+  virtual void resize(int is_a_resize, int w, int h);
+  virtual char swap_type();
+  virtual Fl_Gl_Choice *find(int m, const int *alistp);
+  virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
+  virtual void set_gl_context(Fl_Window* w, GLContext context);
+  virtual void delete_gl_context(GLContext);
+  virtual void make_overlay_current();
+  virtual void redraw_overlay();
+  virtual void gl_start();
+  virtual char *alpha_mask_for_string(const char *str, int n, int w, int h);
+};
+
+// Describes crap needed to create a GLContext.
+class Fl_Cocoa_Gl_Choice : public Fl_Gl_Choice {
+  friend class Fl_Cocoa_Gl_Window_Driver;
+private:
+  NSOpenGLPixelFormat* pixelformat;
+public:
+  Fl_Cocoa_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : Fl_Gl_Choice(m, alistp, n) {
+    pixelformat = NULL;
+  }
+};
+
+
+Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp)
+{
+  Fl::screen_driver()->open_display(); // useful when called through gl_start()
+  Fl_Cocoa_Gl_Choice *g = (Fl_Cocoa_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp);
+  if (g) return g;
+  NSOpenGLPixelFormat* fmt = Fl_Cocoa_Window_Driver::mode_to_NSOpenGLPixelFormat(m, alistp);
+  if (!fmt) return 0;
+  g = new Fl_Cocoa_Gl_Choice(m, alistp, first);
+  first = g;
+  g->pixelformat = fmt;
+  return g;
+}
+
+GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+  GLContext context, shared_ctx = 0;
+  if (context_list && nContext) shared_ctx = context_list[0];
+  // resets the pile of string textures used to draw strings
+  // necessary before the first context is created
+  if (!shared_ctx) gl_texture_reset();
+  context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, shared_ctx, window);
+  if (!context) return 0;
+  add_context(context);
+  return (context);
+}
+
+void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
+  if (context != cached_context || w != cached_window) {
+    cached_context = context;
+    cached_window = w;
+    Fl_Cocoa_Window_Driver::GLcontext_makecurrent(context);
+  }
+}
+
+void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) {
+  if (cached_context == context) {
+    cached_context = 0;
+    cached_window = 0;
+    Fl_Cocoa_Window_Driver::GL_cleardrawable();
+  }
+  Fl_Cocoa_Window_Driver::GLcontext_release(context);
+  del_context(context);
+}
+
+void Fl_Cocoa_Gl_Window_Driver::make_overlay_current() {
+  // this is not very useful, but unfortunately, Apple decided
+  // that front buffer drawing can no longer (OS X 10.4) be supported on their platforms.
+  pWindow->make_current();
+}
+
+void Fl_Cocoa_Gl_Window_Driver::redraw_overlay() {
+  pWindow->redraw();
+}
+
+
+Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
+{
+  return new Fl_Cocoa_Gl_Window_Driver(w);
+}
+
+void Fl_Cocoa_Gl_Window_Driver::before_show(int& need_after) {
+  need_after = 1;
+}
+
+void Fl_Cocoa_Gl_Window_Driver::after_show() {
+  // Makes sure the GL context is created to avoid drawing twice the window when first shown
+  pWindow->make_current();
+}
+
+float Fl_Cocoa_Gl_Window_Driver::pixels_per_unit()
+{
+  int retina = (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(pWindow) &&
+          Fl_Cocoa_Window_Driver::driver(pWindow)->mapped_to_retina()) ? 2 : 1;
+  return retina * Fl_Graphics_Driver::default_driver().scale();
+}
+
+int Fl_Cocoa_Gl_Window_Driver::mode_(int m, const int *a) {
+  if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
+    // the FL_DOUBLE flag must be set in the mode_ member variable
+    const int *aa = a;
+    while (*aa) {
+      if (*(aa++) ==
+          kCGLPFADoubleBuffer
+          ) { m |= FL_DOUBLE; break; }
+    }
+  }
+  pWindow->context(0);
+  mode( m); alist(a);
+  if (pWindow->shown()) {
+    g( find(m, a) );
+    pWindow->redraw();
+  } else {
+    g(0);
+  }
+  return 1;
+}
+
+void Fl_Cocoa_Gl_Window_Driver::make_current_before() {
+  // detect if the window was moved between low and high resolution displays
+  Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(pWindow);
+  if (d->changed_resolution()){
+    d->changed_resolution(false);
+    pWindow->invalidate();
+    Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context());
+  }
+}
+
+void Fl_Cocoa_Gl_Window_Driver::swap_buffers() {
+  if (overlay() != NULL) {
+    // STR# 2944 [1]
+    //    Save matrixmode/proj/modelview/rasterpos before doing overlay.
+    //
+    int wo = pWindow->pixel_w(), ho = pWindow->pixel_h();
+    GLint matrixmode;
+    GLfloat pos[4];
+    glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
+    glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);       // save original glRasterPos
+    glMatrixMode(GL_PROJECTION);                        // save proj/model matrices
+    glPushMatrix();
+    glLoadIdentity();
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+    glScalef(2.0f/wo, 2.0f/ho, 1.0f);
+    glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f);         // set transform so 0,0 is bottom/left of Gl_Window
+    glRasterPos2i(0,0);                             // set glRasterPos to bottom left corner
+    {
+      // Emulate overlay by doing copypixels
+      glReadBuffer(GL_BACK);
+      glDrawBuffer(GL_FRONT);
+      glCopyPixels(0, 0, wo, ho, GL_COLOR);         // copy GL_BACK to GL_FRONT
+    }
+    glPopMatrix(); // GL_MODELVIEW                  // restore model/proj matrices
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(matrixmode);
+    glRasterPos3f(pos[0], pos[1], pos[2]);              // restore original glRasterPos
+  }
+   else
+     Fl_Cocoa_Window_Driver::flush_context(pWindow->context());//aglSwapBuffers((AGLContext)context_);
+}
+
+char Fl_Cocoa_Gl_Window_Driver::swap_type() {return copy;}
+
+void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) {
+  Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context());
+}
+
+/* Some old Apple hardware doesn't implement the GL_EXT_texture_rectangle extension.
+ For it, draw_string_legacy_glut() is used to draw text. */
+
+char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h)
+{
+  // write str to a bitmap just big enough
+  Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
+  Fl_Font f=fl_font(); Fl_Fontsize s=fl_size();
+  Fl_Surface_Device::push_current(surf);
+  fl_color(FL_WHITE);
+  fl_font(f, s * gl_scale);
+  fl_draw(str, n, 0, fl_height() - fl_descent());
+  // get the alpha channel only of the bitmap
+  char *alpha_buf = new char[w*h], *r = alpha_buf, *q;
+  q = (char*)CGBitmapContextGetData(surf->offscreen());
+  for (int i = 0; i < h; i++) {
+    for (int j = 0; j < w; j++) {
+      *r++ = *(q+3);
+      q += 4;
+    }
+  }
+  Fl_Surface_Device::pop_current();
+  delete surf;
+  return alpha_buf;
+}
+
+void Fl_Cocoa_Gl_Window_Driver::gl_start() {
+  Fl_Cocoa_Window_Driver::gl_start(gl_start_context);
+}
+
+#endif // HAVE_GL
diff --git src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
index 9cb5a42..f435894 100644
--- src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
+++ src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
@@ -16,7 +16,6 @@
 
 #include "../../config_lib.h"
 
-#ifdef FL_CFG_GFX_GDI
 #include <FL/Fl_Copy_Surface.H>
 #include <FL/platform.H>
 #include "Fl_GDI_Graphics_Driver.H"
@@ -113,4 +112,3 @@ void Fl_GDI_Copy_Surface_Driver::translate(int x, int y) {
 void Fl_GDI_Copy_Surface_Driver::untranslate() {
   ((Fl_GDI_Graphics_Driver*)driver())->untranslate_all();
 }
-#endif // FL_CFG_GFX_GDI
diff --git src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx
index 4a913ab..0933a4a 100644
--- src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx
+++ src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx
@@ -14,9 +14,6 @@
 //     https://www.fltk.org/bugs.php
 //
 
-#include "../../config_lib.h"
-
-#ifdef FL_CFG_GFX_QUARTZ
 #include <FL/Fl_Copy_Surface.H>
 #include <FL/platform.H>
 #include "Fl_Quartz_Graphics_Driver.H"
@@ -86,5 +83,3 @@ void Fl_Quartz_Copy_Surface_Driver::translate(int x, int y) {
 void Fl_Quartz_Copy_Surface_Driver::untranslate() {
   CGContextRestoreGState(gc);
 }
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx
index 2cc7a12..4163de6 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx
@@ -14,9 +14,6 @@
 //     https://www.fltk.org/bugs.php
 //
 
-#include "../../config_lib.h"
-#ifdef FL_CFG_GFX_QUARTZ
-
 #include "Fl_Quartz_Graphics_Driver.H"
 #include <FL/platform.H>
 
@@ -66,5 +63,3 @@ void Fl_Quartz_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2)
   CGContextFillPath(gc_);
   CGContextSetShouldAntialias(gc_, false);
 }
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx
index cd03a8c..f11c295 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx
@@ -14,9 +14,6 @@
 //     https://www.fltk.org/bugs.php
 //
 
-#include "../../config_lib.h"
-#ifdef FL_CFG_GFX_QUARTZ
-
 // The fltk "colormap".  This allows ui colors to be stored in 8-bit
 // locations, and provides a level of indirection so that global color
 // changes can be made.  Not to be confused with the X colormap, which
@@ -75,5 +72,3 @@ void Fl_Quartz_Graphics_Driver::set_color(Fl_Color i, unsigned c) {
     fl_cmap[i] = c;
   }
 }
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
index fe43f0c..335e028 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
@@ -69,10 +69,6 @@
 
  */
 
-
-#include "../../config_lib.h"
-#ifdef FL_CFG_GFX_QUARTZ
-
 #include "Fl_Quartz_Graphics_Driver.H"
 #include "Fl_Font.H"
 #include <math.h>
@@ -878,5 +874,3 @@ Fl_Font Fl_Quartz_Graphics_Driver::ADD_SUFFIX(set_fonts, _ATSU)(const char* xsta
 }
 
 #endif // HAS_ATSU
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx
index 8dfa309..8e17f87 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx
@@ -14,9 +14,6 @@
 //     https://www.fltk.org/bugs.php
 //
 
-#include "../../config_lib.h"
-#ifdef FL_CFG_GFX_QUARTZ
-
 #include <FL/fl_draw.H>
 #include <FL/platform.H>
 
@@ -84,5 +81,3 @@ void Fl_Quartz_Graphics_Driver::line_style(int style, int width, char* dashes) {
   }
   quartz_restore_line_style();
 }
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx
index caf4277..b238e9a 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx
@@ -15,9 +15,6 @@
 //
 
 
-#include "../../config_lib.h"
-#ifdef FL_CFG_GFX_QUARTZ
-
 #include <FL/Fl.H>
 #include <FL/platform.H>
 
@@ -297,6 +294,3 @@ void Fl_Quartz_Graphics_Driver::restore_clip() {
     }
   }
 }
-
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx
index 5ee8f92..3b0b3f0 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx
@@ -14,9 +14,6 @@
 //     https://www.fltk.org/bugs.php
 //
 
-#include "../../config_lib.h"
-#ifdef FL_CFG_GFX_QUARTZ
-
 /**
   \file quartz_vertex.cxx
   \brief  Portable drawing code for drawing arbitrary shapes with
@@ -148,6 +145,3 @@ void Fl_Quartz_Graphics_Driver::transformed_vertex0(float x, float y) {
 void Fl_Quartz_Graphics_Driver::fixloop() {  // remove equal points from closed path
   while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--;
 }
-
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx
index e0146c8..388d2d2 100644
--- src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx
+++ src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx
@@ -14,9 +14,6 @@
 //     https://www.fltk.org/bugs.php
 //
 
-#include "../../config_lib.h"
-
-#ifdef FL_CFG_GFX_QUARTZ
 #include <FL/platform.H>
 #include <FL/fl_draw.H>
 #include <FL/Fl_Image_Surface.H>
@@ -137,5 +134,3 @@ void Fl_Quartz_Image_Surface_Driver::end_current()
   fl_window = pre_window;
   Fl_Surface_Device::end_current();
 }
-
-#endif // FL_CFG_GFX_QUARTZ
diff --git src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx
new file mode 100644
index 0000000..1dbc9f7
--- /dev/null
+++ src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx
@@ -0,0 +1,404 @@
+//
+// Class Fl_WinAPI_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2021 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file.  If this
+// file is missing or damaged, see the license at:
+//
+//     https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+//     https://www.fltk.org/bugs.php
+//
+
+#include <config.h>
+#if HAVE_GL
+#include <FL/platform.H>
+#include "../../Fl_Screen_Driver.H"
+#include <FL/gl.h>
+#include "../../Fl_Gl_Window_Driver.H"
+#include "../../Fl_Gl_Choice.H"
+#include "Fl_WinAPI_Window_Driver.H"
+#include "../GDI/Fl_Font.H"
+extern void fl_save_dc(HWND, HDC);
+
+// STR #3119: select pixel format with composition support
+// ... and no more than 32 color bits (8 bits/color)
+// Ref: PixelFormatDescriptor Object
+// https://msdn.microsoft.com/en-us/library/cc231189.aspx
+#if !defined(PFD_SUPPORT_COMPOSITION)
+# define PFD_SUPPORT_COMPOSITION (0x8000)
+#endif
+
+#define DEBUG_PFD (0) // 1 = PFD selection debug output, 0 = no debug output
+
+
+class Fl_WinAPI_Gl_Window_Driver : public Fl_Gl_Window_Driver {
+  friend class Fl_Gl_Window_Driver;
+  Fl_WinAPI_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
+  virtual float pixels_per_unit();
+  virtual int mode_(int m, const int *a);
+  virtual void make_current_after();
+  virtual void swap_buffers();
+  virtual void invalidate() {}
+  virtual int flush_begin(char& valid_f);
+  virtual Fl_Gl_Choice *find(int m, const int *alistp);
+  virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
+  virtual void set_gl_context(Fl_Window* w, GLContext context);
+  virtual void delete_gl_context(GLContext);
+  virtual void make_overlay_current();
+  virtual void redraw_overlay();
+  virtual void* GetProcAddress(const char *procName);
+  virtual void draw_string_legacy(const char* str, int n);
+  virtual void gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize);
+  virtual void get_list(Fl_Font_Descriptor *fd, int r);
+  virtual int genlistsize();
+#if HAVE_GL_OVERLAY
+  virtual void gl_hide_before(void *& overlay);
+  virtual int can_do_overlay();
+  virtual int overlay_color(Fl_Color i);
+  void make_overlay(void*&overlay);
+#endif
+};
+
+// Describes crap needed to create a GLContext.
+class Fl_WinAPI_Gl_Choice : public Fl_Gl_Choice {
+  friend class Fl_WinAPI_Gl_Window_Driver;
+private:
+  int pixelformat;           // the visual to use
+  PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
+public:
+  Fl_WinAPI_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : Fl_Gl_Choice(m, alistp, n) {
+    pixelformat = 0;
+  }
+};
+
+
+Fl_Gl_Choice *Fl_WinAPI_Gl_Window_Driver::find(int m, const int *alistp)
+{
+  Fl_WinAPI_Gl_Choice *g = (Fl_WinAPI_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp);
+  if (g) return g;
+
+  // Replacement for ChoosePixelFormat() that finds one with an overlay if possible:
+  HDC gc = (HDC)(fl_graphics_driver ? fl_graphics_driver->gc() : 0);
+  if (!gc) gc = fl_GetDC(0);
+  int pixelformat = 0;
+  PIXELFORMATDESCRIPTOR chosen_pfd;
+  for (int i = 1; ; i++) {
+    PIXELFORMATDESCRIPTOR pfd;
+    if (!DescribePixelFormat(gc, i, sizeof(pfd), &pfd)) break;
+    // continue if it does not satisfy our requirements:
+    if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue;
+    if (pfd.iPixelType != ((m&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue;
+    if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue;
+    if ((m & FL_ACCUM) && !pfd.cAccumBits) continue;
+    if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
+    if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue;
+    if ((m & FL_DEPTH) && !pfd.cDepthBits) continue;
+    if ((m & FL_STENCIL) && !pfd.cStencilBits) continue;
+
+#if DEBUG_PFD
+    printf("pfd #%d supports composition: %s\n", i, (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) ? "yes" : "no");
+    printf("    ... & PFD_GENERIC_FORMAT: %s\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) ? "generic" : "accelerated");
+    printf("    ... Overlay Planes      : %d\n", pfd.bReserved & 15);
+    printf("    ... Color & Depth       : %d, %d\n", pfd.cColorBits, pfd.cDepthBits);
+    if (pixelformat)
+      printf("        current pixelformat : %d\n", pixelformat);
+    fflush(stdout);
+#endif // DEBUG_PFD
+
+    // see if better than the one we have already:
+    if (pixelformat) {
+      // offering non-generic rendering is better (read: hardware acceleration)
+      if (!(chosen_pfd.dwFlags & PFD_GENERIC_FORMAT) &&
+          (pfd.dwFlags & PFD_GENERIC_FORMAT)) continue;
+      // offering overlay is better:
+      else if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {}
+      // otherwise prefer a format that supports composition (STR #3119)
+      else if ((chosen_pfd.dwFlags & PFD_SUPPORT_COMPOSITION) &&
+               !(pfd.dwFlags & PFD_SUPPORT_COMPOSITION)) continue;
+      // otherwise more bit planes is better, but no more than 32 (8 bits per channel):
+      else if (pfd.cColorBits > 32 || chosen_pfd.cColorBits > pfd.cColorBits) continue;
+      else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue;
+    }
+    pixelformat = i;
+    chosen_pfd = pfd;
+  }
+
+#if DEBUG_PFD
+  static int bb = 0;
+  if (!bb) {
+    bb = 1;
+    printf("PFD_SUPPORT_COMPOSITION = 0x%x\n", PFD_SUPPORT_COMPOSITION);
+  }
+  printf("Chosen pixel format is %d\n", pixelformat);
+  printf("Color bits = %d, Depth bits = %d\n", chosen_pfd.cColorBits, chosen_pfd.cDepthBits);
+  printf("Pixel format supports composition: %s\n", (chosen_pfd.dwFlags & PFD_SUPPORT_COMPOSITION) ? "yes" : "no");
+  fflush(stdout);
+#endif // DEBUG_PFD
+
+  if (!pixelformat) return 0;
+
+  g = new Fl_WinAPI_Gl_Choice(m, alistp, first);
+  first = g;
+
+  g->pixelformat = pixelformat;
+  g->pfd = chosen_pfd;
+
+  return g;
+}
+
+
+GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer)
+{
+  Fl_X* i = Fl_X::i(window);
+  HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc;
+  if (!hdc) {
+    hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
+    fl_save_dc(i->xid, hdc);
+    SetPixelFormat(hdc, ((Fl_WinAPI_Gl_Choice*)g)->pixelformat, (PIXELFORMATDESCRIPTOR*)(&((Fl_WinAPI_Gl_Choice*)g)->pfd));
+#    if USE_COLORMAP
+    if (fl_palette) SelectPalette(hdc, fl_palette, FALSE);
+#    endif
+  }
+  GLContext context = layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc);
+  if (context) {
+    if (context_list && nContext)
+      wglShareLists(context_list[0], context);
+    add_context(context);
+  }
+  return context;
+}
+
+
+void Fl_WinAPI_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
+  if (context != cached_context || w != cached_window) {
+    cached_context = context;
+    cached_window = w;
+    wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context);
+  }
+}
+
+void Fl_WinAPI_Gl_Window_Driver::delete_gl_context(GLContext context) {
+  if (cached_context == context) {
+    cached_context = 0;
+    cached_window = 0;
+    wglMakeCurrent(0, 0);
+  }
+  wglDeleteContext(context);
+  del_context(context);
+}
+
+
+void Fl_WinAPI_Gl_Window_Driver::make_overlay_current() {
+#if HAVE_GL_OVERLAY
+  if (overlay() != this) {
+    set_gl_context(pWindow, (GLContext)overlay());
+    //  if (fl_overlay_depth)
+    //    wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
+  } else
+#endif
+    glDrawBuffer(GL_FRONT);
+}
+
+void Fl_WinAPI_Gl_Window_Driver::redraw_overlay() {
+  pWindow->damage(FL_DAMAGE_OVERLAY);
+}
+
+#if HAVE_GL_OVERLAY
+
+// Methods on Fl_Gl_Window_driver that create an overlay window.
+
+// Under win32 another GLX context is created to draw into the overlay
+// and it is stored in the "overlay" pointer.
+
+// If overlay hardware is unavailable, the overlay is
+// "faked" by drawing into the main layers.  This is indicated by
+// setting overlay == this.
+
+//static COLORREF *palette;
+static int fl_overlay_depth = 0;
+
+void Fl_WinAPI_Gl_Window_Driver::gl_hide_before(void *& overlay) {
+  if (overlay && overlay != pWindow) {
+    delete_gl_context((GLContext)overlay);
+    overlay = 0;
+  }
+}
+
+void Fl_WinAPI_Gl_Window_Driver::make_overlay(void*&overlay) {
+  if (overlay) return;
+
+  GLContext context = create_gl_context(pWindow, g(), 1);
+  if (!context) {overlay = pWindow; return;} // fake the overlay
+
+  HDC hdc = Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc;
+  overlay = context;
+  LAYERPLANEDESCRIPTOR pfd;
+  wglDescribeLayerPlane(hdc, g()->pixelformat, 1, sizeof(pfd), &pfd);
+  if (!pfd.iPixelType) {
+    ; // full-color overlay
+  } else {
+    fl_overlay_depth = pfd.cColorBits; // used by gl_color()
+    if (fl_overlay_depth > 8) fl_overlay_depth = 8;
+    COLORREF palette[256];
+    int n = (1<<fl_overlay_depth)-1;
+    // copy all colors except #0 into the overlay palette:
+    for (int i = 0; i <= n; i++) {
+      uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
+      palette[i] = RGB(r,g,b);
+    }
+    // always provide black & white in the last 2 pixels:
+    if (fl_overlay_depth < 8) {
+      palette[n-1] = RGB(0,0,0);
+      palette[n] = RGB(255,255,255);
+    }
+    // and use it:
+    wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
+    wglRealizeLayerPalette(hdc, 1, TRUE);
+  }
+  pWindow->valid(0);
+  return;
+}
+
+int Fl_WinAPI_Gl_Window_Driver::can_do_overlay() {
+  if (!g()) {
+    g( find(mode(), alist()) );
+    if (!g()) return 0;
+  }
+  return (g()->pfd.bReserved & 15) != 0;
+}
+
+int Fl_WinAPI_Gl_Window_Driver::overlay_color(Fl_Color i) {
+  if (Fl_Xlib_Graphics_Driver::fl_overlay && fl_overlay_depth) {
+    if (fl_overlay_depth < 8) {
+      // only black & white produce the expected colors.  This could
+      // be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
+      int size = 1<<fl_overlay_depth;
+      if (!i) glIndexi(size-2);
+      else if (i >= size-2) glIndexi(size-1);
+      else glIndexi(i);
+    } else {
+      glIndexi(i ? i : FL_GRAY_RAMP);
+    }
+    return 1;
+  }
+  return 0;
+}
+
+#endif // HAVE_GL_OVERLAY
+
+
+Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
+{
+  return new Fl_WinAPI_Gl_Window_Driver(w);
+}
+
+float Fl_WinAPI_Gl_Window_Driver::pixels_per_unit()
+{
+  int ns = Fl_Window_Driver::driver(pWindow)->screen_num();
+  return Fl::screen_driver()->scale(ns);
+}
+
+
+int Fl_WinAPI_Gl_Window_Driver::mode_(int m, const int *a) {
+  int oldmode = mode();
+  pWindow->context(0);
+  mode( m); alist(a);
+  if (pWindow->shown()) {
+    g( find(m, a) );
+    if (!g() || (oldmode^m)&(FL_DOUBLE|FL_STEREO)) {
+      pWindow->hide();
+      pWindow->show();
+    }
+  } else {
+    g(0);
+  }
+  return 1;
+}
+
+void Fl_WinAPI_Gl_Window_Driver::make_current_after() {
+#if USE_COLORMAP
+  if (fl_palette) {
+    fl_GetDC(fl_xid(pWindow));
+    SelectPalette((HDC)fl_graphics_driver->gc(), fl_palette, FALSE);
+    RealizePalette((HDC)fl_graphics_driver->gc());
+  }
+#endif // USE_COLORMAP
+}
+
+//#define HAVE_GL_OVERLAY 1 //test only
+
+void Fl_WinAPI_Gl_Window_Driver::swap_buffers() {
+#  if HAVE_GL_OVERLAY
+  // Do not swap the overlay, to match GLX:
+  BOOL ret = wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, WGL_SWAP_MAIN_PLANE);
+  DWORD err = GetLastError();
+#  else
+  SwapBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc);
+#  endif
+}
+
+#if HAVE_GL_OVERLAY
+#endif
+
+int Fl_WinAPI_Gl_Window_Driver::flush_begin(char& valid_f_) {
+#if HAVE_GL_OVERLAY
+  char save_valid_f = valid_f_;
+  // Draw into hardware overlay planes if they are damaged:
+  if (overlay() && overlay() != pWindow
+      && (pWindow->damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid_f & 1)) {
+    set_gl_context(pWindow, (GLContext)overlay());
+    if (fl_overlay_depth)
+      wglRealizeLayerPalette(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, 1, TRUE);
+    glDisable(GL_SCISSOR_TEST);
+    glClear(GL_COLOR_BUFFER_BIT);
+    Fl_Xlib_Graphics_Driver::fl_overlay = 1;
+    draw_overlay();
+    Fl_Xlib_Graphics_Driver::fl_overlay = 0;
+    valid_f_ = save_valid_f;
+    wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, WGL_SWAP_OVERLAY1);
+    // if only the overlay was damaged we are done, leave main layer alone:
+    if (pWindow->damage() == FL_DAMAGE_OVERLAY) {
+      return 1;
+    }
+  }
+#endif
+  return 0;
+}
+
+void* Fl_WinAPI_Gl_Window_Driver::GetProcAddress(const char *procName) {
+  return (void*)wglGetProcAddress((LPCSTR)procName);
+}
+
+
+void Fl_WinAPI_Gl_Window_Driver::draw_string_legacy(const char* str, int n) {
+  draw_string_legacy_get_list(str, n);
+}
+
+int Fl_WinAPI_Gl_Window_Driver::genlistsize() {
+  return 0x10000;
+}
+
+void Fl_WinAPI_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
+  if (!fl_fontsize->listbase) {
+    fl_fontsize->listbase = glGenLists(genlistsize());
+  }
+  glListBase(fl_fontsize->listbase);
+}
+
+void Fl_WinAPI_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) {
+  Fl_GDI_Font_Descriptor* gl_fd = (Fl_GDI_Font_Descriptor*)fd;
+  if (gl_fd->glok[r]) return;
+  gl_fd->glok[r] = 1;
+  unsigned int ii = r * 0x400;
+  HFONT oldFid = (HFONT)SelectObject((HDC)fl_graphics_driver->gc(), gl_fd->fid);
+  wglUseFontBitmapsW((HDC)fl_graphics_driver->gc(), ii, 0x400, gl_fd->listbase+ii);
+  SelectObject((HDC)fl_graphics_driver->gc(), oldFid);
+}
+
+
+#endif // HAVE_GL
diff --git src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
new file mode 100644
index 0000000..a52d4c7
--- /dev/null
+++ src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
@@ -0,0 +1,549 @@
+//
+// Class Fl_X11_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2021 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file.  If this
+// file is missing or damaged, see the license at:
+//
+//     https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+//     https://www.fltk.org/bugs.php
+//
+
+#include <config.h>
+#if HAVE_GL
+#include <FL/platform.H>
+#include "../../Fl_Gl_Choice.H"
+#include "../../Fl_Screen_Driver.H"
+#include "../../Fl_Window_Driver.H"
+#include "../../Fl_Gl_Window_Driver.H"
+#include "../Xlib/Fl_Font.H"
+#include "../Xlib/Fl_Xlib_Graphics_Driver.H"
+#  include <GL/glx.h>
+#  if ! defined(GLX_VERSION_1_3)
+#    typedef void *GLXFBConfig;
+#  endif
+
+class Fl_X11_Gl_Window_Driver : public Fl_Gl_Window_Driver {
+  friend class Fl_Gl_Window_Driver;
+  Fl_X11_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
+  virtual float pixels_per_unit();
+  virtual void before_show(int& need_after);
+  virtual int mode_(int m, const int *a);
+  virtual void swap_buffers();
+  virtual void resize(int is_a_resize, int w, int h);
+  virtual char swap_type();
+  virtual Fl_Gl_Choice *find(int m, const int *alistp);
+  virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
+  virtual void set_gl_context(Fl_Window* w, GLContext context);
+  virtual void delete_gl_context(GLContext);
+#if HAVE_GL_OVERLAY
+  virtual void make_overlay(void *&o);
+  virtual int can_do_overlay();
+  virtual void hide_overlay();
+  virtual int overlay_color(Fl_Color i);
+#endif
+  virtual void make_overlay_current();
+  virtual void redraw_overlay();
+  virtual void waitGL();
+  virtual void gl_visual(Fl_Gl_Choice*); // support for Fl::gl_visual()
+  virtual void gl_start();
+  virtual void draw_string_legacy(const char* str, int n);
+  virtual void gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize);
+  virtual void get_list(Fl_Font_Descriptor *fd, int r);
+  virtual int genlistsize();
+#if !USE_XFT
+  virtual Fl_Font_Descriptor** fontnum_to_fontdescriptor(int fnum);
+#endif
+  public:
+  static GLContext create_gl_context(XVisualInfo* vis);
+};
+
+// Describes crap needed to create a GLContext.
+class Fl_X11_Gl_Choice : public Fl_Gl_Choice {
+  friend class Fl_X11_Gl_Window_Driver;
+private:
+  XVisualInfo *vis; /* the visual to use */
+  Colormap colormap; /* a colormap for that visual */
+  GLXFBConfig best_fb;
+public:
+  Fl_X11_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : Fl_Gl_Choice(m, alistp, n) {
+    vis = NULL;
+    colormap = 0;
+    best_fb = NULL;
+  }
+};
+
+void Fl_X11_Gl_Window_Driver::draw_string_legacy(const char* str, int n) {
+  draw_string_legacy_get_list(str, n);
+}
+
+int Fl_X11_Gl_Window_Driver::genlistsize() {
+#if USE_XFT
+  return 256;
+#else
+  return 0x10000;
+#endif
+}
+
+void Fl_X11_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
+  /* This method should ONLY be triggered if our GL font texture pile mechanism
+   * is not working on this platform. This code might not reliably render glyphs
+   * from higher codepoints. */
+  if (!fl_fontsize->listbase) {
+#if USE_XFT
+    /* Ideally, for XFT, we need a glXUseXftFont implementation here... But we
+     * do not have such a thing. Instead, we try to find a legacy Xlib font that
+     * matches the current XFT font and use that.
+     * Ideally, we never come here - we hope the texture pile implementation
+     * will work correctly so that XFT can render the face directly without the
+     * need for this workaround. */
+    XFontStruct *font = fl_xfont.value();
+    int base = font->min_char_or_byte2;
+    int count = font->max_char_or_byte2 - base + 1;
+    fl_fontsize->listbase = glGenLists(genlistsize());
+    glXUseXFont(font->fid, base, count, fl_fontsize->listbase+base);
+#else
+    /* Not using XFT to render text - the legacy Xlib fonts can usually be rendered
+     * directly by using glXUseXFont mechanisms. */
+    fl_fontsize->listbase = glGenLists(genlistsize());
+#endif // !USE_XFT
+  }
+  glListBase(fl_fontsize->listbase);
+}
+
+
+void Fl_X11_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) {
+# if USE_XFT
+  /* We hope not to come here: We hope that any system using XFT will also
+   * have sufficient GL capability to support our font texture pile mechansim,
+   * allowing XFT to render the face directly. */
+  // Face already set by gl_bitmap_font in this case.
+# else
+  Fl_Xlib_Font_Descriptor *gl_fd = (Fl_Xlib_Font_Descriptor*)fd;
+  if (gl_fd->glok[r]) return;
+  gl_fd->glok[r] = 1;
+  unsigned int ii = r * 0x400;
+  for (int i = 0; i < 0x400; i++) {
+    XFontStruct *font = NULL;
+    unsigned short id;
+    fl_XGetUtf8FontAndGlyph(gl_fd->font, ii, &font, &id);
+    if (font) glXUseXFont(font->fid, id, 1, gl_fd->listbase+ii);
+    ii++;
+  }
+# endif
+}
+
+#if !USE_XFT
+Fl_Font_Descriptor** Fl_X11_Gl_Window_Driver::fontnum_to_fontdescriptor(int fnum) {
+  Fl_Xlib_Fontdesc *s = ((Fl_Xlib_Fontdesc*)fl_fonts) + fnum;
+  return &(s->first);
+}
+#endif
+
+
+static XVisualInfo *gl3_getvisual(const int *blist, GLXFBConfig *pbestFB)
+{
+  int glx_major, glx_minor;
+
+  // FBConfigs were added in GLX version 1.3.
+  if ( !glXQueryVersion(fl_display, &glx_major, &glx_minor) ||
+      ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) {
+    return NULL;
+  }
+
+  //printf( "Getting matching framebuffer configs\n" );
+  int fbcount;
+  GLXFBConfig* fbc = glXChooseFBConfig(fl_display, DefaultScreen(fl_display), blist, &fbcount);
+  if (!fbc) {
+    //printf( "Failed to retrieve a framebuffer config\n" );
+    return NULL;
+  }
+  //printf( "Found %d matching FB configs.\n", fbcount );
+
+  // Pick the FB config/visual with the most samples per pixel
+  int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
+  for (int i = 0; i < fbcount; ++i)
+  {
+    XVisualInfo *vi = glXGetVisualFromFBConfig( fl_display, fbc[i] );
+    if (vi) {
+      int samp_buf, samples;
+      glXGetFBConfigAttrib(fl_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
+      glXGetFBConfigAttrib(fl_display, fbc[i], GLX_SAMPLES       , &samples );
+      /*printf( "  Matching fbconfig %d, visual ID 0x%2lx: SAMPLE_BUFFERS = %d, SAMPLES = %d\n",
+             i, vi -> visualid, samp_buf, samples );*/
+      if ( best_fbc < 0 || (samp_buf && samples > best_num_samp) )
+        best_fbc = i, best_num_samp = samples;
+      if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
+        worst_fbc = i, worst_num_samp = samples;
+    }
+    XFree(vi);
+  }
+
+  GLXFBConfig bestFbc = fbc[ best_fbc ];
+  // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
+  XFree(fbc);
+  // Get a visual
+  XVisualInfo *vi = glXGetVisualFromFBConfig(fl_display, bestFbc);
+  *pbestFB = bestFbc;
+  return vi;
+}
+
+Fl_Gl_Choice *Fl_X11_Gl_Window_Driver::find(int m, const int *alistp)
+{
+  Fl_X11_Gl_Choice *g = (Fl_X11_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp);
+  if (g) return g;
+
+  const int *blist;
+  int list[32];
+
+  if (alistp)
+    blist = alistp;
+  else {
+    int n = 0;
+    if (m & FL_INDEX) {
+      list[n++] = GLX_BUFFER_SIZE;
+      list[n++] = 8; // glut tries many sizes, but this should work...
+    } else {
+      list[n++] = GLX_RGBA;
+      list[n++] = GLX_GREEN_SIZE;
+      list[n++] = (m & FL_RGB8) ? 8 : 1;
+      if (m & FL_ALPHA) {
+        list[n++] = GLX_ALPHA_SIZE;
+        list[n++] = (m & FL_RGB8) ? 8 : 1;
+      }
+      if (m & FL_ACCUM) {
+        list[n++] = GLX_ACCUM_GREEN_SIZE;
+        list[n++] = 1;
+        if (m & FL_ALPHA) {
+          list[n++] = GLX_ACCUM_ALPHA_SIZE;
+          list[n++] = 1;
+        }
+      }
+    }
+    if (m & FL_DOUBLE) {
+      list[n++] = GLX_DOUBLEBUFFER;
+    }
+    if (m & FL_DEPTH) {
+      list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
+    }
+    if (m & FL_STENCIL) {
+      list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
+    }
+    if (m & FL_STEREO) {
+      list[n++] = GLX_STEREO;
+    }
+#    if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+    if (m & FL_MULTISAMPLE) {
+      list[n++] = GLX_SAMPLES_SGIS;
+      list[n++] = 4; // value Glut uses
+    }
+#    endif
+    list[n] = 0;
+    blist = list;
+  }
+
+  fl_open_display();
+  XVisualInfo *visp = NULL;
+  GLXFBConfig best_fb = NULL;
+  if (m & FL_OPENGL3) {
+    visp = gl3_getvisual((const int *)blist, &best_fb);
+  }
+  if (!visp) {
+    visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
+    if (!visp) {
+#     if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+        if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE, 0);
+#     endif
+      return 0;
+    }
+  }
+
+  g = new Fl_X11_Gl_Choice(m, alistp, first);
+  first = g;
+
+  g->vis = visp;
+  g->best_fb = best_fb;
+
+  if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
+      visp->visualid == fl_visual->visualid &&
+      !fl_getenv("MESA_PRIVATE_CMAP"))
+    g->colormap = fl_colormap;
+  else
+    g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+                                  visp->visual, AllocNone);
+  return g;
+}
+
+static bool ctxErrorOccurred = false;
+static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
+{
+  ctxErrorOccurred = true;
+  return 0;
+}
+
+GLContext Fl_X11_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+  GLContext shared_ctx = 0;
+  if (context_list && nContext) shared_ctx = context_list[0];
+
+  typedef GLContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLContext, Bool, const int*);
+  // It is not necessary to create or make current to a context before calling glXGetProcAddressARB
+  static glXCreateContextAttribsARBProc glXCreateContextAttribsARB =
+#if defined(HAVE_GLXGETPROCADDRESSARB)
+    (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB");
+#else
+  NULL;
+#endif
+
+  GLContext ctx = 0;
+  // Check for the GLX_ARB_create_context extension string and the function.
+  // If either is not present, use GLX 1.3 context creation method.
+  const char *glxExts = glXQueryExtensionsString(fl_display, fl_screen);
+  if (((Fl_X11_Gl_Choice*)g)->best_fb && strstr(glxExts, "GLX_ARB_create_context") && glXCreateContextAttribsARB ) {
+    int context_attribs[] =
+    {
+      GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+      GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+      //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+      //GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+      None
+    };
+    ctxErrorOccurred = false;
+    XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
+    ctx = glXCreateContextAttribsARB(fl_display, ((Fl_X11_Gl_Choice*)g)->best_fb, shared_ctx, true, context_attribs);
+    XSync(fl_display, false); // Sync to ensure any errors generated are processed.
+    if (ctxErrorOccurred) ctx = 0;
+    XSetErrorHandler(oldHandler);
+  }
+  if (!ctx) { // use OpenGL 1-style context creation
+    ctx = glXCreateContext(fl_display, ((Fl_X11_Gl_Choice*)g)->vis, shared_ctx, true);
+  }
+  if (ctx)
+    add_context(ctx);
+//glXMakeCurrent(fl_display, fl_xid(window), ctx);printf("%s\n", glGetString(GL_VERSION));
+  return ctx;
+}
+
+GLContext Fl_X11_Gl_Window_Driver::create_gl_context(XVisualInfo *vis) {
+  GLContext shared_ctx = 0;
+  if (context_list && nContext) shared_ctx = context_list[0];
+  GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1);
+  if (context)
+    add_context(context);
+  return context;
+}
+
+void Fl_X11_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
+  if (context != cached_context || w != cached_window) {
+    cached_context = context;
+    cached_window = w;
+    glXMakeCurrent(fl_display, fl_xid(w), context);
+  }
+}
+
+void Fl_X11_Gl_Window_Driver::delete_gl_context(GLContext context) {
+  if (cached_context == context) {
+    cached_context = 0;
+    cached_window = 0;
+    glXMakeCurrent(fl_display, 0, 0);
+  }
+  glXDestroyContext(fl_display, context);
+  del_context(context);
+}
+
+
+void Fl_X11_Gl_Window_Driver::make_overlay_current() {
+#if HAVE_GL_OVERLAY
+  if (overlay() != pWindow) {
+    ((Fl_Gl_Window*)overlay())->make_current();
+  } else
+#endif
+    glDrawBuffer(GL_FRONT);
+}
+
+void Fl_X11_Gl_Window_Driver::redraw_overlay() {
+  if (overlay() != pWindow)
+    ((Fl_Gl_Window*)overlay())->redraw();
+  else
+    pWindow->damage(FL_DAMAGE_OVERLAY);
+}
+
+#if HAVE_GL_OVERLAY
+
+// Methods on Fl_Gl_Window_Driver that create an overlay window.
+
+// Under X this is done by creating another window, of class _Fl_Gl_Overlay
+// which is a subclass of Fl_Gl_Window except it uses the overlay planes.
+// A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.
+
+// If overlay hardware is unavailable, the overlay is
+// "faked" by drawing into the main layers.  This is indicated by
+// setting overlay == this.
+
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+//extern uchar fl_overlay;
+
+int Fl_X11_Gl_Window_Driver::overlay_color(Fl_Color i) {
+  if (Fl_Xlib_Graphics_Driver::fl_overlay) {glIndexi(int(fl_xpixel(i))); return 1;}
+  return 0;
+}
+
+
+class _Fl_Gl_Overlay : public Fl_Gl_Window {
+  void flush();
+  void draw();
+public:
+  void show();
+  _Fl_Gl_Overlay(int x, int y, int w, int h) :
+    Fl_Gl_Window(x,y,w,h) {
+    set_flag(INACTIVE);
+  }
+};
+
+void _Fl_Gl_Overlay::flush() {
+  make_current();
+#ifdef BOXX_BUGS
+  // The BoXX overlay is broken and you must not call swap-buffers. This
+  // code will make it work, but we lose because machines that do support
+  // double-buffered overlays will blink when they don't have to
+  glDrawBuffer(GL_FRONT);
+  draw();
+#else
+  draw();
+  swap_buffers();
+#endif
+  glFlush();
+  valid(1);
+}
+
+void _Fl_Gl_Overlay::draw() {
+  if (!valid()) glClearIndex((GLfloat)fl_transparent_pixel);
+  if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
+  Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
+  uchar save_valid = w->valid();
+  w->valid(valid());
+  Fl_Xlib_Graphics_Driver::fl_overlay = 1;
+  w->gl_driver()->draw_overlay();
+  Fl_Xlib_Graphics_Driver::fl_overlay = 0;
+  valid(w->valid());
+  w->valid(save_valid);
+}
+
+void _Fl_Gl_Overlay::show() {
+  if (!shown()) {
+    fl_background_pixel = int(fl_transparent_pixel);
+    Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+    fl_background_pixel = -1;
+    // find the outermost window to tell wm about the colormap:
+    Fl_Window *w = window();
+    for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
+    XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
+    context(Fl_X11_Gl_Window_Driver::create_gl_context(fl_overlay_visual), 1);
+    valid(0);
+  }
+  Fl_Gl_Window::show();
+}
+
+void Fl_X11_Gl_Window_Driver::hide_overlay() {
+  if (overlay() && overlay() != pWindow) ((Fl_Gl_Window*)overlay())->hide();
+}
+
+int Fl_X11_Gl_Window_Driver::can_do_overlay() {
+  return fl_find_overlay_visual() != 0;
+}
+
+
+void Fl_X11_Gl_Window_Driver::make_overlay(void *&current) {
+  if (current) return;
+  if (can_do_overlay()) {
+    _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0, 0, pWindow->w(), pWindow->h());
+    current = o;
+    pWindow->add(*o);
+    o->show();
+  } else {
+    current = pWindow; // fake the overlay
+  }
+}
+#endif // HAVE_GL_OVERLAY
+
+
+Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
+{
+  return new Fl_X11_Gl_Window_Driver(w);
+}
+
+void Fl_X11_Gl_Window_Driver::before_show(int&) {
+  Fl_X11_Gl_Choice *g = (Fl_X11_Gl_Choice*)this->g();
+  Fl_X::make_xid(pWindow, g->vis, g->colormap);
+  if (overlay() && overlay() != pWindow) ((Fl_Gl_Window*)overlay())->show();
+}
+
+float Fl_X11_Gl_Window_Driver::pixels_per_unit()
+{
+  int ns = Fl_Window_Driver::driver(pWindow)->screen_num();
+  return Fl::screen_driver()->scale(ns);
+}
+
+int Fl_X11_Gl_Window_Driver::mode_(int m, const int *a) {
+  int oldmode = mode();
+  if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
+    // the FL_DOUBLE flag must be set in the mode_ member variable
+    const int *aa = a;
+    while (*aa) {
+      if (*(aa++) ==
+          GLX_DOUBLEBUFFER
+          ) { m |= FL_DOUBLE; break; }
+    }
+  }
+  Fl_X11_Gl_Choice* oldg = (Fl_X11_Gl_Choice*)g();
+  pWindow->context(0);
+  mode(m); alist(a);
+  if (pWindow->shown()) {
+    g( find(m, a) );
+    // under X, if the visual changes we must make a new X window (yuck!):
+    Fl_X11_Gl_Choice* g = (Fl_X11_Gl_Choice*)this->g();
+    if (!g || g->vis->visualid != oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) {
+      pWindow->hide();
+      pWindow->show();
+    }
+  } else {
+    g(0);
+  }
+  return 1;
+}
+
+void Fl_X11_Gl_Window_Driver::swap_buffers() {
+  glXSwapBuffers(fl_display, fl_xid(pWindow));
+}
+
+void Fl_X11_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
+  if (is_a_resize && !pWindow->resizable() && overlay() && overlay() != pWindow) {
+    ((Fl_Gl_Window*)overlay())->resize(0,0,W,H);
+  }
+}
+
+char Fl_X11_Gl_Window_Driver::swap_type() {return copy;}
+
+void Fl_X11_Gl_Window_Driver::waitGL() {
+  glXWaitGL();
+}
+
+
+void Fl_X11_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) {
+  Fl_Gl_Window_Driver::gl_visual(c);
+  fl_visual = ((Fl_X11_Gl_Choice*)c)->vis;
+  fl_colormap = ((Fl_X11_Gl_Choice*)c)->colormap;
+}
+
+void Fl_X11_Gl_Window_Driver::gl_start() {
+  glXWaitX();
+}
+
+#endif // HAVE_GL
diff --git src/drivers/X11/Fl_X11_Window_Driver.cxx src/drivers/X11/Fl_X11_Window_Driver.cxx
index 19fc70b..d757aa7 100644
--- src/drivers/X11/Fl_X11_Window_Driver.cxx
+++ src/drivers/X11/Fl_X11_Window_Driver.cxx
@@ -40,7 +40,6 @@ extern XVisualInfo *fl_find_overlay_visual();
 extern XVisualInfo *fl_overlay_visual;
 extern Colormap fl_overlay_colormap;
 extern unsigned long fl_transparent_pixel;
-extern uchar fl_overlay; // changes how fl_color(x) works
 #endif
 
 Window fl_window;
@@ -595,13 +594,13 @@ void _Fl_Overlay::flush() {
 #if defined(FLTK_USE_CAIRO)
   if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately
 #endif
-  fl_overlay = 1;
+  Fl_Xlib_Graphics_Driver::fl_overlay = 1;
   Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent();
   Fl_X *myi = Fl_X::i(this);
   if (damage() != FL_DAMAGE_EXPOSE) XClearWindow(fl_display, fl_xid(this));
   fl_clip_region(myi->region); myi->region = 0;
   w->draw_overlay();
-  fl_overlay = 0;
+  Fl_Xlib_Graphics_Driver::fl_overlay = 0;
 }
 #endif // HAVE_OVERLAY
 
@@ -648,10 +647,10 @@ void Fl_X11_Window_Driver::flush_menu() {
    // capture gc changes automatically to update the cairo context adequately
    if(Fl::autolink_context()) Fl::cairo_make_current(fl_graphics_driver->gc());
 # endif
-   fl_overlay = 1;
+  Fl_Xlib_Graphics_Driver::fl_overlay = 1;
    fl_clip_region(myi->region); myi->region = 0; current(pWindow);
    draw();
-   fl_overlay = 0;
+  Fl_Xlib_Graphics_Driver::fl_overlay = 0;
 #else
    flush_Fl_Window();
 #endif
diff --git src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
index 373cf9e..738b5a4 100644
--- src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
+++ src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
@@ -16,7 +16,6 @@
 
 #include "../../config_lib.h"
 
-#ifdef FL_CFG_GFX_XLIB
 #include <FL/Fl_Copy_Surface.H>
 #include <FL/Fl.H>
 #include <FL/platform.H>
@@ -91,5 +90,3 @@ void Fl_Xlib_Copy_Surface_Driver::translate(int x, int y) {
 void Fl_Xlib_Copy_Surface_Driver::untranslate() {
   ((Fl_Xlib_Graphics_Driver*)driver())->untranslate_all();
 }
-
-#endif // FL_CFG_GFX_XLIB
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
index 4f1906d..6340374 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
@@ -116,6 +116,7 @@ public:
 #if USE_XFT
   static void destroy_xft_draw(Window id);
 #endif
+  static int fl_overlay;
 
   // --- bitmap stuff
   Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
index 15ea319..46f4446 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
@@ -39,6 +39,7 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
 }
 
 GC Fl_Xlib_Graphics_Driver::gc_ = NULL;
+int Fl_Xlib_Graphics_Driver::fl_overlay = 0;
 
 /* Reference to the current graphics context
  For back-compatibility only. The preferred procedure to get this pointer is
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx
index 937ed7c..9106817 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx
@@ -96,16 +96,12 @@ static void figure_out_visual() {
 #  if HAVE_OVERLAY
 /** HAVE_OVERLAY determines whether fl_xmap is one or two planes */
 Fl_XColor fl_xmap[2][256];
-/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */
-uchar fl_overlay;
 Colormap fl_overlay_colormap;
 XVisualInfo* fl_overlay_visual;
 ulong fl_transparent_pixel;
 #  else
 /** HAVE_OVERLAY determines whether fl_xmap is one or two planes */
 Fl_XColor fl_xmap[1][256];
-/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */
-#    define fl_overlay 0
 #  endif
 
 void Fl_Xlib_Graphics_Driver::color(Fl_Color i) {
@@ -147,7 +143,7 @@ ulong fl_xpixel(uchar r,uchar g,uchar b) {
     // find closest entry in the colormap:
     Fl_Color i =
       fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256);
-    Fl_XColor &xmap = fl_xmap[fl_overlay][i];
+    Fl_XColor &xmap = fl_xmap[Fl_Xlib_Graphics_Driver::fl_overlay][i];
     if (xmap.mapped) return xmap.pixel;
     // if not black or white, change the entry to be an exact match:
     if (i != FL_COLOR_CUBE && i != 0xFF)
@@ -198,7 +194,7 @@ ulong fl_xpixel(Fl_Color i) {
     return fl_xpixel((i >> 24) & 255, (i >> 16) & 255, (i >> 8) & 255);
   }
 
-  Fl_XColor &xmap = fl_xmap[fl_overlay][i];
+  Fl_XColor &xmap = fl_xmap[Fl_Xlib_Graphics_Driver::fl_overlay][i];
   if (xmap.mapped) return xmap.pixel;
 
   if (!beenhere) figure_out_visual();
@@ -209,7 +205,7 @@ ulong fl_xpixel(Fl_Color i) {
 #  if USE_COLORMAP
   Colormap colormap = fl_colormap;
 #    if HAVE_OVERLAY
-  if (fl_overlay) colormap = fl_overlay_colormap; else
+  if (Fl_Xlib_Graphics_Driver::fl_overlay) colormap = fl_overlay_colormap; else
 #    endif
   if (fl_redmask) {
 #  endif
@@ -227,9 +223,9 @@ ulong fl_xpixel(Fl_Color i) {
   }
 #    if HAVE_OVERLAY
   static XColor* ac[2];
-  XColor*& allcolors = ac[fl_overlay];
+  XColor*& allcolors = ac[Fl_Xlib_Graphics_Driver::fl_overlay];
   static int nc[2];
-  int& numcolors = nc[fl_overlay];
+  int& numcolors = nc[Fl_Xlib_Graphics_Driver::fl_overlay];
 #    else
   static XColor *allcolors;
   static int numcolors;
@@ -254,7 +250,7 @@ ulong fl_xpixel(Fl_Color i) {
     // of round-trips to the X server, even though other programs may alter
     // the colormap after this and make decisions here wrong.
 #    if HAVE_OVERLAY
-    if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else
+    if (Fl_Xlib_Graphics_Driver::fl_overlay) numcolors = fl_overlay_visual->colormap_size; else
 #    endif
       numcolors = fl_visual->colormap_size;
     if (!allcolors) allcolors = new XColor[numcolors];
@@ -267,7 +263,7 @@ ulong fl_xpixel(Fl_Color i) {
   unsigned int bestmatch = 0;
   for (unsigned int n = numcolors; n--;) {
 #    if HAVE_OVERLAY
-    if (fl_overlay && n == fl_transparent_pixel) continue;
+    if (Fl_Xlib_Graphics_Driver::fl_overlay && n == fl_transparent_pixel) continue;
 #    endif
     XColor &a = allcolors[n];
     int d, t;
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
index 5c88ec1..2f38a82 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
@@ -36,7 +36,6 @@
 #if USE_OVERLAY
 // Currently Xft does not work with colormapped visuals, so this probably
 // does not work unless you have a true-color overlay.
-extern bool fl_overlay;
 extern Colormap fl_overlay_colormap;
 extern XVisualInfo* fl_overlay_visual;
 #endif
diff --git src/gl_draw.cxx src/gl_draw.cxx
index d16e98a..125e68c 100644
--- src/gl_draw.cxx
+++ src/gl_draw.cxx
@@ -250,8 +250,6 @@ void gl_color(Fl_Color i) {
     2) draw the texture using the current GL color.
 */
 
-static float gl_scale = 1; // scaling factor between FLTK and GL drawing units: GL = FLTK * gl_scale
-
 // manages a fifo pile of pre-computed string textures
 class gl_texture_fifo {
   friend class Fl_Gl_Window_Driver;
@@ -301,7 +299,7 @@ int gl_texture_fifo::already_known(const char *str, int n)
   for ( rank = 0; rank <= last; rank++) {
     if ((fifo[rank].str_len == n) &&
         (fifo[rank].fdesc == gl_fontsize) &&
-        (fifo[rank].scale == gl_scale) &&
+        (fifo[rank].scale == Fl_Gl_Window_Driver::gl_scale) &&
         (memcmp(str, fifo[rank].utf8, n) == 0)) {
       return rank;
     }
@@ -332,8 +330,8 @@ void gl_texture_fifo::display_texture(int rank)
   glMatrixMode (GL_MODELVIEW);
   glPushMatrix();
   glLoadIdentity ();
-  float winw = gl_scale * Fl_Window::current()->w();
-  float winh = gl_scale * Fl_Window::current()->h();
+  float winw = Fl_Gl_Window_Driver::gl_scale * Fl_Window::current()->w();
+  float winh = Fl_Gl_Window_Driver::gl_scale * Fl_Window::current()->h();
   // GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable
   glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
   glDisable (GL_DEPTH_TEST); // ensure text is not removed by depth buffer test.
@@ -358,7 +356,7 @@ void gl_texture_fifo::display_texture(int rank)
   //write the texture on screen
   glBegin (GL_QUADS);
   float ox = pos[0];
-  float oy = pos[1] + height - gl_scale * fl_descent();
+  float oy = pos[1] + height - Fl_Gl_Window_Driver::gl_scale * fl_descent();
   glTexCoord2f (0.0f, 0.0f); // draw lower left in world coordinates
   glVertex2f (ox, oy);
   glTexCoord2f (0.0f, height); // draw upper left in world coordinates
@@ -407,12 +405,12 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
   fifo[current].str_len = n; // record length of text in utf8
   fl_graphics_driver->font_descriptor(gl_fontsize);
   int w, h;
-  w = fl_width(fifo[current].utf8, n) * gl_scale;
+  w = fl_width(fifo[current].utf8, n) * Fl_Gl_Window_Driver::gl_scale;
   // Hack - make w be aligned
   w = (w + 3) & (~3);
-  h = fl_height() * gl_scale;
+  h = fl_height() * Fl_Gl_Window_Driver::gl_scale;
 
-  fifo[current].scale = gl_scale;
+  fifo[current].scale = Fl_Gl_Window_Driver::gl_scale;
   fifo[current].fdesc = gl_fontsize;
   char *alpha_buf = Fl_Gl_Window_Driver::global()->alpha_mask_for_string(str, n, w, h);
 
@@ -628,173 +626,6 @@ void Fl_Gl_Window_Driver::draw_string_legacy_glut(const char* str, int n)
   glRasterPos2d(objX, objY);
 }
 
-
-#if  defined(FL_CFG_GFX_XLIB)
-#  include "drivers/Xlib/Fl_Font.H"
-#  include <FL/platform.H>
-#  include <GL/glx.h>
-
-void Fl_X11_Gl_Window_Driver::draw_string_legacy(const char* str, int n) {
-  draw_string_legacy_get_list(str, n);
-}
-
-int Fl_X11_Gl_Window_Driver::genlistsize() {
-#if USE_XFT
-  return 256;
-#else
-  return 0x10000;
-#endif
-}
-
-void Fl_X11_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
-  /* This method should ONLY be triggered if our GL font texture pile mechanism
-   * is not working on this platform. This code might not reliably render glyphs
-   * from higher codepoints. */
-  if (!fl_fontsize->listbase) {
-#if USE_XFT
-    /* Ideally, for XFT, we need a glXUseXftFont implementation here... But we
-     * do not have such a thing. Instead, we try to find a legacy Xlib font that
-     * matches the current XFT font and use that.
-     * Ideally, we never come here - we hope the texture pile implementation
-     * will work correctly so that XFT can render the face directly without the
-     * need for this workaround. */
-    XFontStruct *font = fl_xfont.value();
-    int base = font->min_char_or_byte2;
-    int count = font->max_char_or_byte2 - base + 1;
-    fl_fontsize->listbase = glGenLists(genlistsize());
-    glXUseXFont(font->fid, base, count, fl_fontsize->listbase+base);
-#else
-    /* Not using XFT to render text - the legacy Xlib fonts can usually be rendered
-     * directly by using glXUseXFont mechanisms. */
-    fl_fontsize->listbase = glGenLists(genlistsize());
-#endif // !USE_XFT
-  }
-  glListBase(fl_fontsize->listbase);
-}
-
-
-void Fl_X11_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) {
-# if USE_XFT
-  /* We hope not to come here: We hope that any system using XFT will also
-   * have sufficient GL capability to support our font texture pile mechansim,
-   * allowing XFT to render the face directly. */
-  // Face already set by gl_bitmap_font in this case.
-# else
-  Fl_Xlib_Font_Descriptor *gl_fd = (Fl_Xlib_Font_Descriptor*)fd;
-  if (gl_fd->glok[r]) return;
-  gl_fd->glok[r] = 1;
-  unsigned int ii = r * 0x400;
-  for (int i = 0; i < 0x400; i++) {
-    XFontStruct *font = NULL;
-    unsigned short id;
-    fl_XGetUtf8FontAndGlyph(gl_fd->font, ii, &font, &id);
-    if (font) glXUseXFont(font->fid, id, 1, gl_fd->listbase+ii);
-    ii++;
-  }
-# endif
-}
-
-#if !USE_XFT
-Fl_Font_Descriptor** Fl_X11_Gl_Window_Driver::fontnum_to_fontdescriptor(int fnum) {
-  Fl_Xlib_Fontdesc *s = ((Fl_Xlib_Fontdesc*)fl_fonts) + fnum;
-  return &(s->first);
-}
-#endif
-
-#if HAVE_GL_OVERLAY
-extern uchar fl_overlay;
-int Fl_X11_Gl_Window_Driver::overlay_color(Fl_Color i) {
-  if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return 1;}
-  return 0;
-}
-#endif // HAVE_GL_OVERLAY
-
-#endif // FL_CFG_GFX_XLIB
-
-
-#if defined(FL_CFG_GFX_GDI)
-#  include "drivers/GDI/Fl_Font.H"
-
-void Fl_WinAPI_Gl_Window_Driver::draw_string_legacy(const char* str, int n) {
-  draw_string_legacy_get_list(str, n);
-}
-
-int Fl_WinAPI_Gl_Window_Driver::genlistsize() {
-  return 0x10000;
-}
-
-void Fl_WinAPI_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) {
-  if (!fl_fontsize->listbase) {
-    fl_fontsize->listbase = glGenLists(genlistsize());
-  }
-  glListBase(fl_fontsize->listbase);
-}
-
-void Fl_WinAPI_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) {
-  Fl_GDI_Font_Descriptor* gl_fd = (Fl_GDI_Font_Descriptor*)fd;
-  if (gl_fd->glok[r]) return;
-  gl_fd->glok[r] = 1;
-  unsigned int ii = r * 0x400;
-  HFONT oldFid = (HFONT)SelectObject((HDC)fl_graphics_driver->gc(), gl_fd->fid);
-  wglUseFontBitmapsW((HDC)fl_graphics_driver->gc(), ii, 0x400, gl_fd->listbase+ii);
-  SelectObject((HDC)fl_graphics_driver->gc(), oldFid);
-}
-
-#if HAVE_GL_OVERLAY
-extern uchar fl_overlay;
-extern int fl_overlay_depth;
-int Fl_WinAPI_Gl_Window_Driver::overlay_color(Fl_Color i) {
-  if (fl_overlay && fl_overlay_depth) {
-    if (fl_overlay_depth < 8) {
-      // only black & white produce the expected colors.  This could
-      // be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
-      int size = 1<<fl_overlay_depth;
-      if (!i) glIndexi(size-2);
-      else if (i >= size-2) glIndexi(size-1);
-      else glIndexi(i);
-    } else {
-      glIndexi(i ? i : FL_GRAY_RAMP);
-    }
-    return 1;
-  }
-  return 0;
-}
-#endif // HAVE_GL_OVERLAY
-#endif // FL_CFG_GFX_GDI
-
-
-#if defined(FL_CFG_GFX_QUARTZ)
-#include <FL/platform.H>
-#include <FL/Fl_Image_Surface.H>
-
-/* Some old Apple hardware doesn't implement the GL_EXT_texture_rectangle extension.
- For it, draw_string_legacy_glut() is used to draw text. */
-
-char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h)
-{
-  // write str to a bitmap just big enough
-  Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
-  Fl_Font f=fl_font(); Fl_Fontsize s=fl_size();
-  Fl_Surface_Device::push_current(surf);
-  fl_color(FL_WHITE);
-  fl_font(f, s * gl_scale);
-  fl_draw(str, n, 0, fl_height() - fl_descent());
-  // get the alpha channel only of the bitmap
-  char *alpha_buf = new char[w*h], *r = alpha_buf, *q;
-  q = (char*)CGBitmapContextGetData(surf->offscreen());
-  for (int i = 0; i < h; i++) {
-    for (int j = 0; j < w; j++) {
-      *r++ = *(q+3);
-      q += 4;
-    }
-  }
-  Fl_Surface_Device::pop_current();
-  delete surf;
-  return alpha_buf;
-}
-
-#endif // FL_CFG_GFX_QUARTZ
-
 /**
  \}
  \endcond
diff --git src/gl_start.cxx src/gl_start.cxx
index 250bca2..f96786c 100644
--- src/gl_start.cxx
+++ src/gl_start.cxx
@@ -37,21 +37,21 @@ class Fl_Gl_Choice;
 #include <FL/Fl_Gl_Window.H>
 #include "Fl_Gl_Window_Driver.H"
 
-static GLContext context;
+GLContext Fl_Gl_Window_Driver::gl_start_context;
 static int clip_state_number=-1;
 static int pw, ph;
 float gl_start_scale = 1;
 
-static Fl_Gl_Choice* gl_choice;
+static Fl_Gl_Choice* gl_choice = NULL;
 
 /** Creates an OpenGL context */
 void gl_start() {
   gl_start_scale = Fl_Display_Device::display_device()->driver()->scale();
-  if (!context) {
+  if (!Fl_Gl_Window_Driver::gl_start_context) {
     if (!gl_choice) Fl::gl_visual(0);
-    context = Fl_Gl_Window_Driver::global()->create_gl_context(Fl_Window::current(), gl_choice);
+    Fl_Gl_Window_Driver::gl_start_context = Fl_Gl_Window_Driver::global()->create_gl_context(Fl_Window::current(), gl_choice);
   }
-  Fl_Gl_Window_Driver::global()->set_gl_context(Fl_Window::current(), context);
+  Fl_Gl_Window_Driver::global()->set_gl_context(Fl_Window::current(), Fl_Gl_Window_Driver::gl_start_context);
   Fl_Gl_Window_Driver::global()->gl_start();
   if (pw != int(Fl_Window::current()->w() * gl_start_scale) || ph != int(Fl_Window::current()->h() * gl_start_scale)) {
     pw = int(Fl_Window::current()->w() * gl_start_scale);
@@ -94,32 +94,6 @@ void Fl_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) {
   gl_choice = c;
 }
 
-#ifdef FL_CFG_GFX_QUARTZ
-#include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H"
-
-void Fl_Cocoa_Gl_Window_Driver::gl_start() {
-  Fl_Cocoa_Window_Driver::gl_start(context);
-}
-
-#endif
-
-
-#ifdef FL_CFG_GFX_XLIB
-#include <FL/platform.H>
-#include "Fl_Gl_Choice.H"
-
-void Fl_X11_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) {
-  Fl_Gl_Window_Driver::gl_visual(c);
-  fl_visual = c->vis;
-  fl_colormap = c->colormap;
-}
-
-void Fl_X11_Gl_Window_Driver::gl_start() {
-  glXWaitX();
-}
-
-#endif // FL_CFG_GFX_XLIB
-
 int Fl::gl_visual(int mode, int *alist) {
   Fl_Gl_Choice *c = Fl_Gl_Window_Driver::global()->find(mode,alist);
   if (!c) return 0;
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.