diff --git a/FL/Fl_Gl_Window.H b/FL/Fl_Gl_Window.H
index 0951f3a107dc174c0d6e53802db66e74dbfcabae..8a7a0af741f5fcfa09f7beb0b393ee7b5e8729fc 100644
--- a/FL/Fl_Gl_Window.H
+++ b/FL/Fl_Gl_Window.H
@@ -1,5 +1,5 @@
 //
-// "$Id: Fl_Gl_Window.H,v 1.7.2.3 2001/01/22 15:13:37 easysw Exp $"
+// "$Id: Fl_Gl_Window.H,v 1.7.2.4 2001/03/14 17:20:01 spitzak Exp $"
 //
 // OpenGL header file for the Fast Light Tool Kit (FLTK).
 //
@@ -27,6 +27,10 @@
 
 #include "Fl_Window.H"
 
+#ifndef GLContext
+typedef void* GLContext; // actually a GLXContext or HGLDC
+#endif
+
 class Fl_Gl_Choice; // structure to hold result of glXChooseVisual
 
 class Fl_Gl_Window : public Fl_Window {
@@ -34,7 +38,7 @@ class Fl_Gl_Window : public Fl_Window {
   int mode_;
   const int *alist;
   Fl_Gl_Choice *g;
-  void * context; // actually a GLXContext
+  GLContext context_;
   char valid_;
   char damage1_; // damage() of back buffer
   virtual FL_EXPORT void draw_overlay();
@@ -66,14 +70,16 @@ public:
   int mode(int a) {return mode(a,0);}
   int mode(const int *a) {return mode(0, a);}
 
+  void* context() const {return context_;}
+  FL_EXPORT void context(void*, int destroy_flag = false);
+  FL_EXPORT void make_current();
+  FL_EXPORT void swap_buffers();
+  FL_EXPORT void ortho();
+
   FL_EXPORT int can_do_overlay();
   FL_EXPORT void redraw_overlay();
   FL_EXPORT void hide_overlay();
-
-  FL_EXPORT void make_current();
   FL_EXPORT void make_overlay_current();
-  FL_EXPORT void swap_buffers();
-  FL_EXPORT void ortho();
 
   FL_EXPORT ~Fl_Gl_Window();
   Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();}
@@ -84,5 +90,5 @@ public:
 #endif
 
 //
-// End of "$Id: Fl_Gl_Window.H,v 1.7.2.3 2001/01/22 15:13:37 easysw Exp $".
+// End of "$Id: Fl_Gl_Window.H,v 1.7.2.4 2001/03/14 17:20:01 spitzak Exp $".
 //
diff --git a/FL/glut.H b/FL/glut.H
index 8f8b2b446e3155b432b488c4f4e6e49d6ff55bc7..193e6f498e1fc1a47dd4a693d36fdc55e2e7c25e 100644
--- a/FL/glut.H
+++ b/FL/glut.H
@@ -1,5 +1,5 @@
 //
-// "$Id: glut.H,v 1.6.2.9 2001/01/22 15:13:38 easysw Exp $"
+// "$Id: glut.H,v 1.6.2.10 2001/03/14 17:20:01 spitzak Exp $"
 //
 // GLUT emulation header file for the Fast Light Tool Kit (FLTK).
 //
@@ -45,7 +45,7 @@
 #define __glut_h__
 
 #include <FL/gl.h>
-#include <GL/glu.h>
+//#include <GL/glu.h>
 
 ////////////////////////////////////////////////////////////////
 // Glut is emulated using this window class and these static variables
@@ -431,7 +431,7 @@ extern "C" {
 extern int APIENTRY glutExtensionSupported(char *name);
 
 /* Stroke font constants (use these in GLUT program). */
-#if defined(_WIN32) || defined(WIN32)
+#ifdef WIN32
 # define GLUT_STROKE_ROMAN		((void*)0)
 # define GLUT_STROKE_MONO_ROMAN		((void*)1)
 #else
@@ -470,5 +470,5 @@ extern void APIENTRY glutSolidIcosahedron();
 #endif                  /* __glut_h__ */
 
 //
-// End of "$Id: glut.H,v 1.6.2.9 2001/01/22 15:13:38 easysw Exp $".
+// End of "$Id: glut.H,v 1.6.2.10 2001/03/14 17:20:01 spitzak Exp $".
 //
diff --git a/Makefile b/Makefile
index 27c9491b3e424f2c74a02bf1bd8a357f2f438f2f..3dd59520325909e11fe21eb337baad9f9eceeca1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile,v 1.12.2.5 2001/01/22 15:13:37 easysw Exp $"
+# "$Id: Makefile,v 1.12.2.6 2001/03/14 17:20:01 spitzak Exp $"
 #
 # Top-level makefile for the Fast Light Tool Kit (FLTK).
 #
@@ -68,6 +68,9 @@ distclean: clean
 makeinclude: configure configh.in makeinclude.in
 	./configure
 
+configure: configure.in
+	autoconf
+
 #
-# End of "$Id: Makefile,v 1.12.2.5 2001/01/22 15:13:37 easysw Exp $".
+# End of "$Id: Makefile,v 1.12.2.6 2001/03/14 17:20:01 spitzak Exp $".
 #
diff --git a/documentation/Fl_Gl_Window.html b/documentation/Fl_Gl_Window.html
index 6e5ad96be8d326b7b1790d749eee64b25a6f555a..079fc5eecd517235fc7e8582140a9785c06ae96d 100644
--- a/documentation/Fl_Gl_Window.html
+++ b/documentation/Fl_Gl_Window.html
@@ -41,6 +41,7 @@ very well for single-buffered. </P>
 </UL>
 </TD><TD align=left valign=top>
 <UL>
+<LI><A href=#Fl_Gl_Window.context>context</A></LI>
 <LI><A href=#Fl_Gl_Window.draw>draw</A></LI>
 <LI><A href=#Fl_Gl_Window.draw_overlay>draw_overlay</A></LI>
 <LI><A href=#Fl_Gl_Window.handle>handle</A></LI>
@@ -120,6 +121,22 @@ window a child of another window if you wish to do this! </P>
 <BR> int Fl_Gl_Window::can_do() const</A></H4>
  Returns non-zero if the hardware supports the given or current OpenGL 
 mode. 
+
+<h4><a name=Fl_Gl_Window.context>void* Fl_Gl_Window::context() const;
+<br>void Fl_Gl_Window::context(void*, int destroy_flag = false);</a></h4>
+
+Return or set a pointer to the GLContext that this window is
+using. This is a system-dependent structure, but it is portable to copy
+the context from one window to another. You can also set it to NULL,
+which will force FLTK to recreate the context the next time <a
+href=#make_current><tt>make_current()</tt></a> is called, this is
+useful for getting around bugs in OpenGL implementations.
+
+<p>If <i>destroy_flag</i> is true the context will be destroyed by
+fltk when the window is destroyed, or when the <a
+href=#mode><tt>mode()</tt></a> is changed, or the next time
+<tt>context(x)</tt> is called.
+
 <H4><A name=Fl_Gl_Window.valid>char Fl_Gl_Window::valid() const
 <BR> void Fl_Gl_Window::valid(char i)</A></H4>
 <TT>Fl_Gl_Window::valid()</TT> is turned off when FLTK creates a new 
diff --git a/src/Fl_Gl_Choice.H b/src/Fl_Gl_Choice.H
index 986ee5d651ff95091d4ddfa4028f1ccc7387e808..2fd10c967f398801c0a2fd5d18225d7bb9759bd6 100644
--- a/src/Fl_Gl_Choice.H
+++ b/src/Fl_Gl_Choice.H
@@ -1,5 +1,5 @@
 //
-// "$Id: Fl_Gl_Choice.H,v 1.4.2.5 2001/01/22 15:13:39 easysw Exp $"
+// "$Id: Fl_Gl_Choice.H,v 1.4.2.6 2001/03/14 17:20:01 spitzak Exp $"
 //
 // OpenGL definitions for the Fast Light Tool Kit (FLTK).
 //
@@ -20,42 +20,49 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 // USA.
 //
-// Please report all bugs and problems to "fltk-bugs@fltk.org".
+// Please report all bugs and problems to "fltk-bugs@easysw.com".
 //
 
 // Internal interface to set up OpenGL.
 //
-// A "Fl_Gl_Choice" is used to cache results of calling the
-// OpenGL code for system-specific information needed to
-// implement a "mode".
-// For X this is a visual, and this must be called *before*
-// the X window is created.
-// For win32 this can be delayed to a more convienent time,
-// as it only returns information for modifying a device
-// context.
-// This is used by Fl_Gl_Window, gl_start(), and gl_visual()
+// A "Fl_Gl_Choice" is created from an OpenGL mode and holds information
+// necessary to create a window (on X) and to create an OpenGL "context"
+// (on both X and Win32).
+//
+// fl_create_gl_context takes a window (necessary only on Win32) and an
+// Fl_Gl_Choice and returns a new OpenGL context. All contexts share
+// display lists with each other.
+//
+// On X another fl_create_gl_context is provided to create it for any
+// X visual.
+//
+// fl_set_gl_context makes the given OpenGL context current and makes
+// it draw into the passed window. It tracks the current one context
+// to avoid calling the context switching code when the same context
+// is used, though it is a mystery to me why the GLX/WGL libraries
+// don't do this themselves...
+//
+// fl_no_gl_context clears that cache so the next fl_set_gl_context is
+// guaranteed to work.
+//
+// fl_delete_gl_context destroys the context.
+//
+// This code is used by Fl_Gl_Window, gl_start(), and gl_visual()
 
 #ifndef Fl_Gl_Choice_H
 #define Fl_Gl_Choice_H
 
+// Warning: whatever GLContext is defined to must take exactly the same
+// space in a structure as a void*!!!
 #ifdef WIN32
-# include <windows.h>
 # include <FL/gl.h>
-# define GLXContext HGLRC
-# define GLX_BUFFER_SIZE      1
-# define GLX_RGBA	      2
-# define GLX_GREEN_SIZE	      3
-# define GLX_ALPHA_SIZE	      4
-# define GLX_ACCUM_GREEN_SIZE 5
-# define GLX_ACCUM_ALPHA_SIZE 6
-# define GLX_DOUBLEBUFFER     7
-# define GLX_DEPTH_SIZE	      8
-# define GLX_STENCIL_SIZE     9
+# define GLContext HGLRC
 #else
 # include <GL/glx.h>
+# define GLContext GLXContext
 #endif
 
-// one of these structures is returned:
+// Describes crap needed to create a GLContext.
 class Fl_Gl_Choice {
   int mode;
   const int *alist;
@@ -68,28 +75,35 @@ public:
   XVisualInfo *vis;	// the visual to use
   Colormap colormap;	// a colormap for that visual
 #endif
-  uchar r,d,o;		// rgb mode, double buffered, overlay flags
   // 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:
   static Fl_Gl_Choice *find(int mode, const int *);
 };
 
-extern GLXContext fl_first_context; // used to make all contexts share
-extern GLXContext fl_current_context;
-
 class Fl_Window;
 
 #ifdef WIN32
-// This must be called before fl_set_gl_context works:
-HDC fl_private_dc(Fl_Window*, int, Fl_Gl_Choice **gp);
+
+GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
+
+#else
+
+GLContext fl_create_gl_context(XVisualInfo* vis);
+
+static inline
+GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g) {
+  return fl_create_gl_context(g->vis);
+}
+
 #endif
 
-void fl_set_gl_context(Fl_Window*, GLXContext);
+void fl_set_gl_context(Fl_Window*, GLContext);
 void fl_no_gl_context();
+void fl_delete_gl_context(GLContext);
 
 #endif
 
 //
-// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.5 2001/01/22 15:13:39 easysw Exp $".
+// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.6 2001/03/14 17:20:01 spitzak Exp $".
 //
diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx
index 31285e9c6ce110b02e1b5a2221ca97e91f97b6a9..420367348f9a4e1572c54710e93d2daeac3af8e4 100644
--- a/src/Fl_Gl_Choice.cxx
+++ b/src/Fl_Gl_Choice.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.5 2001/01/22 15:13:39 easysw Exp $"
+// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.6 2001/03/14 17:20:01 spitzak Exp $"
 //
 // OpenGL visual selection code for the Fast Light Tool Kit (FLTK).
 //
@@ -20,7 +20,7 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 // USA.
 //
-// Please report all bugs and problems to "fltk-bugs@fltk.org".
+// Please report all bugs and problems to "fltk-bugs@easysw.com".
 //
 
 #include <config.h>
@@ -32,7 +32,6 @@
 #include "Fl_Gl_Choice.H"
 
 static Fl_Gl_Choice *first;
-GLXContext fl_first_context;
 
 // this assummes one of the two arguments is zero:
 // We keep the list system in Win32 to stay compatible and interpret
@@ -143,16 +142,8 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) {
 #ifdef WIN32
   g->pixelformat = pixelformat;
   g->pfd = chosen_pfd;
-  g->d = ((mode&FL_DOUBLE) != 0);
-  g->r = (mode & FL_INDEX);
-  g->o = 0; // not an overlay
 #else
   g->vis = vis;
-  g->colormap = 0;
-  int i;
-  glXGetConfig(fl_display, vis, GLX_DOUBLEBUFFER, &i); g->d = i;
-  glXGetConfig(fl_display, vis, GLX_RGBA, &i); g->r = i;
-  glXGetConfig(fl_display, vis, GLX_LEVEL, &i); g->o = i;
 
   if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
       vis->visualid == fl_visual->visualid &&
@@ -166,36 +157,50 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) {
   return g;
 }
 
+static GLContext first_context;
+
 #ifdef WIN32
 
-HDC fl_private_dc(Fl_Window* w, int mode, Fl_Gl_Choice **gp) {
-  Fl_X* i = Fl_X::i(w);
-  if (!i->private_dc) {
-    i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
-    Fl_Gl_Choice *g = Fl_Gl_Choice::find(mode, 0);
-    if (gp) *gp = g;
+GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+  Fl_X* i = Fl_X::i(window);
+  HDC hdc = i->private_dc;
+  if (!hdc) {
+    hdc = i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
     SetPixelFormat(i->private_dc, g->pixelformat, &g->pfd);
 #if USE_COLORMAP
     if (fl_palette) SelectPalette(i->private_dc, fl_palette, FALSE);
 #endif
   }
-  return i->private_dc;
+  GLContext context =
+    layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc);
+  if (context) {
+    if (first_context) wglShareLists(first_context, context);
+    else first_context = context;
+  }
+  return context;
 }
 
-#endif
+#else
 
-static GLXContext cached_context;
+GLContext fl_create_gl_context(XVisualInfo* vis) {
+  GLContext context = glXCreateContext(fl_display, vis, first_context, 1);
+  if (!first_context) first_context = context;
+  return context;
+}
+
+#endif
 
+static GLContext cached_context;
 static Fl_Window* cached_window;
 
-void fl_set_gl_context(Fl_Window* w, GLXContext c) {
-  if (c != cached_context || w != cached_window) {
-    cached_context = c;
+void fl_set_gl_context(Fl_Window* w, GLContext context) {
+  if (context != cached_context || w != cached_window) {
+    cached_context = context;
     cached_window = w;
 #ifdef WIN32
-    wglMakeCurrent(Fl_X::i(w)->private_dc, c);
+    wglMakeCurrent(Fl_X::i(w)->private_dc, context);
 #else
-    glXMakeCurrent(fl_display, fl_xid(w), c);
+    glXMakeCurrent(fl_display, fl_xid(w), context);
 #endif
   }
 }
@@ -210,8 +215,19 @@ void fl_no_gl_context() {
 #endif
 }
 
+void fl_delete_gl_context(GLContext context) {
+  if (cached_context == context) fl_no_gl_context();
+  if (context != first_context) {
+#ifdef WIN32
+    wglDeleteContext(context);
+#else
+    glXDestroyContext(fl_display, context);
+#endif
+  }
+}
+
 #endif
 
 //
-// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.5 2001/01/22 15:13:39 easysw Exp $".
+// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.6 2001/03/14 17:20:01 spitzak Exp $".
 //
diff --git a/src/Fl_Gl_Overlay.cxx b/src/Fl_Gl_Overlay.cxx
index fd040abb0e66ca7f944b82810f2472c01bb04eed..1272c11a2807f7f439d0a8bee7f7c27d6f6673d1 100644
--- a/src/Fl_Gl_Overlay.cxx
+++ b/src/Fl_Gl_Overlay.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.14 2001/01/22 15:13:39 easysw Exp $"
+// "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.15 2001/03/14 17:20:01 spitzak Exp $"
 //
 // OpenGL overlay code for the Fast Light Tool Kit (FLTK).
 //
@@ -20,21 +20,25 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 // USA.
 //
-// Please report all bugs and problems to "fltk-bugs@fltk.org".
+// Please report all bugs and problems to "fltk-bugs@easysw.com".
 //
 
 #include <config.h>
 #if HAVE_GL
 
 #include <FL/Fl.H>
-#include <FL/Fl_Gl_Window.H>
 #include <FL/x.H>
 #include "Fl_Gl_Choice.H"
+#include <FL/Fl_Gl_Window.H>
 #include <stdlib.h>
 
-#if HAVE_GL_OVERLAY
+#if !HAVE_GL_OVERLAY
+
+int Fl_Gl_Window::can_do_overlay() {return 0;}
+
+void Fl_Gl_Window::make_overlay() {overlay = this;}
 
-#if !defined(_WIN32) && !defined(WIN32)
+#else
 
 // Methods on Fl_Gl_Window that create an overlay window.  Because
 // many programs don't need the overlay, this is seperated into this
@@ -51,11 +55,14 @@
 // "faked" by drawing into the main layers.  This is indicated by
 // setting overlay == this.
 
+#ifndef WIN32
+////////////////////////////////////////////////////////////////
+// X version
+
 extern XVisualInfo *fl_find_overlay_visual();
 extern XVisualInfo *fl_overlay_visual;
 extern Colormap fl_overlay_colormap;
 extern unsigned long fl_transparent_pixel;
-static Fl_Gl_Choice overlay_choice;
 extern uchar fl_overlay;
 
 class _Fl_Gl_Overlay : public Fl_Gl_Window {
@@ -65,12 +72,6 @@ public:
   _Fl_Gl_Overlay(int x, int y, int w, int h) :
     Fl_Gl_Window(x,y,w,h) {
     set_flag(INACTIVE);
-    overlay_choice.vis = fl_overlay_visual;
-    overlay_choice.colormap = fl_overlay_colormap;
-    overlay_choice.r = 0;
-    overlay_choice.d = 0;
-    overlay_choice.o = 1;
-    g = &overlay_choice;
   }
 };
 
@@ -88,91 +89,87 @@ void _Fl_Gl_Overlay::draw() {
 }
 
 void _Fl_Gl_Overlay::show() {
-  if (shown()) {Fl_Gl_Window::show(); return;}
-  fl_background_pixel = int(fl_transparent_pixel);
+  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_create_gl_context(fl_overlay_visual), 1);
+    valid(0);
+  }
   Fl_Gl_Window::show();
-  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);
 }
 
 int Fl_Gl_Window::can_do_overlay() {
   return fl_find_overlay_visual() != 0;
 }
 
-#else // _WIN32:
-
-int Fl_Gl_Window::can_do_overlay() {
-  Fl_Gl_Choice* choice = Fl_Gl_Choice::find(0,0);
-  return (choice && (choice->pfd.bReserved & 15));
+void Fl_Gl_Window::make_overlay() {
+  if (overlay) return;
+  if (can_do_overlay()) {
+    _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
+    overlay = o;
+    add(*o);
+    o->show();
+  } else {
+    overlay = this; // fake the overlay
+  }
 }
 
-extern int fl_overlay_depth;
-
-#endif
-
 #else
+////////////////////////////////////////////////////////////////
+// WIN32 version:
 
-int Fl_Gl_Window::can_do_overlay() {return 0;}
-
-#endif
+//static COLORREF *palette;
+extern int fl_overlay_depth;
 
 void Fl_Gl_Window::make_overlay() {
-  if (!overlay) {
-#if HAVE_GL_OVERLAY
-#if defined(_WIN32) || defined(WIN32)
-    HDC hdc = fl_private_dc(this, mode_,&g);
-    GLXContext context = wglCreateLayerContext(hdc, 1);
-    if (context) { // we found a usable overlay context
-      if (fl_first_context) wglShareLists(fl_first_context, context);
-      else fl_first_context = context;
-      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);
-      }
-      valid(0);
-      return;
+  if (overlay) return;
+
+  GLContext context = fl_create_gl_context(this, g, 1);
+  if (!context) {overlay = this; return;} // fake the overlay
+
+  HDC hdc = Fl_X::i(this)->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);
     }
-#else
-    if (can_do_overlay()) {
-      _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
-      overlay = o;
-      add(*o);
-      o->show();
-      return;
+    // 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);
     }
-#endif
-#endif
-    overlay = this; // fake the overlay
+    // and use it:
+    wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
+    wglRealizeLayerPalette(hdc, 1, TRUE);
   }
+  valid(0);
+  return;
 }
 
+////////////////////////////////////////////////////////////////
+#endif
+
+#endif
+
 void Fl_Gl_Window::redraw_overlay() {
   if (!shown()) return;
   make_overlay();
-#if !defined(_WIN32) && !defined(WIN32)
+#ifndef WIN32
   if (overlay != this)
     ((Fl_Gl_Window*)overlay)->redraw();
   else
@@ -184,8 +181,8 @@ void Fl_Gl_Window::make_overlay_current() {
   make_overlay();
 #if HAVE_GL_OVERLAY
   if (overlay != this) {
-#if defined(_WIN32) || defined(WIN32)
-    fl_set_gl_context(this, (GLXContext)overlay);
+#ifdef WIN32
+    fl_set_gl_context(this, (GLContext)overlay);
 //  if (fl_overlay_depth)
 //    wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
 #else
@@ -198,7 +195,7 @@ void Fl_Gl_Window::make_overlay_current() {
 
 void Fl_Gl_Window::hide_overlay() {
 #if HAVE_GL_OVERLAY
-#if defined(_WIN32) || defined(WIN32)
+#ifdef WIN32
   // nothing needs to be done?  Or should it be erased?
 #else
   if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
@@ -209,5 +206,5 @@ void Fl_Gl_Window::hide_overlay() {
 #endif
 
 //
-// End of "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.14 2001/01/22 15:13:39 easysw Exp $".
+// End of "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.15 2001/03/14 17:20:01 spitzak Exp $".
 //
diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx
index 87806a54aa4030f8fdedc4967e18ae2d33498613..70d46ab68a144da517600546b963766775cf277c 100644
--- a/src/Fl_Gl_Window.cxx
+++ b/src/Fl_Gl_Window.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: Fl_Gl_Window.cxx,v 1.12.2.20 2001/01/22 15:13:39 easysw Exp $"
+// "$Id: Fl_Gl_Window.cxx,v 1.12.2.21 2001/03/14 17:20:01 spitzak Exp $"
 //
 // OpenGL window code for the Fast Light Tool Kit (FLTK).
 //
@@ -28,8 +28,8 @@
 
 #include <FL/Fl.H>
 #include <FL/x.H>
-#include <FL/Fl_Gl_Window.H>
 #include "Fl_Gl_Choice.H"
+#include <FL/Fl_Gl_Window.H>
 #include <stdlib.h>
 #include <string.h>
 
@@ -63,66 +63,65 @@ int Fl_Gl_Window::can_do(int a, const int *b) {
 }
 
 void Fl_Gl_Window::show() {
-#if !defined(_WIN32) && !defined(WIN32)
   if (!shown()) {
     if (!g) {
       g = Fl_Gl_Choice::find(mode_,alist);
       if (!g) {Fl::error("Insufficient GL support"); return;}
     }
+#ifndef WIN32
     Fl_X::make_xid(this, g->vis, g->colormap);
     if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show();
-  }
 #endif
+  }
   Fl_Window::show();
 }
 
 void Fl_Gl_Window::invalidate() {
   valid(0);
-#if !defined(_WIN32) && !defined(WIN32)
+#ifndef WIN32
   if (overlay) ((Fl_Gl_Window*)overlay)->valid(0);
 #endif
 }
 
 int Fl_Gl_Window::mode(int m, const int *a) {
   if (m == mode_ && a == alist) return 0;
+#ifndef WIN32
+  int oldmode = mode_;
+  Fl_Gl_Choice* oldg = g;
+#endif
+  context(0);
   mode_ = m; alist = a;
-#if defined(_WIN32) || defined(WIN32)
-  // destroy context and g:
-  if (shown()) {hide(); show();}
-#else
-  // under X, if the visual changes we must make a new X window (!):
   if (shown()) {
-    Fl_Gl_Choice *g1 = g;
-    g = Fl_Gl_Choice::find(mode_,alist);
-    if (!g || g->vis->visualid != g1->vis->visualid || g->d != g1->d) {
-      hide(); show();
+    g = Fl_Gl_Choice::find(m, a);
+#ifndef WIN32
+    // 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) {
+      hide();
+      show();
     }
-  }
 #endif
+  } else {
+    g = 0;
+  }
   return 1;
 }
 
+#define NON_LOCAL_CONTEXT 0x80000000
+
 void Fl_Gl_Window::make_current() {
-  if (!context) {
-#if defined(_WIN32) || defined(WIN32)
-    context = wglCreateContext(fl_private_dc(this, mode_,&g));
-    if (fl_first_context) wglShareLists(fl_first_context, (GLXContext)context);
-    else fl_first_context = (GLXContext)context;
-#else
-    context = glXCreateContext(fl_display, g->vis, fl_first_context, 1);
-    if (!fl_first_context) fl_first_context = (GLXContext)context;
-#endif
+  if (!context_) {
+    mode_ &= ~NON_LOCAL_CONTEXT;
+    context_ = fl_create_gl_context(this, g);
     valid(0);
   }
-  fl_set_gl_context(this, (GLXContext)context);
-#if (defined(_WIN32) || defined(WIN32)) && USE_COLORMAP
+  fl_set_gl_context(this, context_);
+#if defined(WIN32) && USE_COLORMAP
   if (fl_palette) {
     fl_GetDC(fl_xid(this));
     SelectPalette(fl_gc, fl_palette, FALSE);
     RealizePalette(fl_gc);
   }
 #endif // USE_COLORMAP
-  if (g->d) glDrawBuffer(GL_BACK);
   current_ = this;
 }
 
@@ -142,7 +141,7 @@ void Fl_Gl_Window::ortho() {
 }
 
 void Fl_Gl_Window::swap_buffers() {
-#if defined(_WIN32) || defined(WIN32)
+#ifdef WIN32
 #if HAVE_GL_OVERLAY
   // Do not swap the overlay, to match GLX:
   wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE);
@@ -154,25 +153,25 @@ void Fl_Gl_Window::swap_buffers() {
 #endif
 }
 
-#if HAVE_GL_OVERLAY && defined(_WIN32)
+#if HAVE_GL_OVERLAY && defined(WIN32)
 uchar fl_overlay; // changes how fl_color() works
 int fl_overlay_depth = 0;
 #endif
 
 void Fl_Gl_Window::flush() {
   uchar save_valid = valid_;
-#if defined(_WIN32) || defined(WIN32)
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+
   // SGI 320 messes up overlay with user-defined cursors:
   bool fixcursor =
     Fl_X::i(this)->cursor && Fl_X::i(this)->cursor != fl_default_cursor;
   if (fixcursor) SetCursor(0);
-#endif
 
-#if HAVE_GL_OVERLAY && (defined(_WIN32) || defined(WIN32))
   // Draw into hardware overlay planes:
   if (overlay && overlay != this
       && (damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid)) {
-    fl_set_gl_context(this, (GLXContext)overlay);
+    fl_set_gl_context(this, (GLContext)overlay);
     if (fl_overlay_depth)
       wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
     glDisable(GL_SCISSOR_TEST);
@@ -191,7 +190,9 @@ void Fl_Gl_Window::flush() {
 
   make_current();
 
-  if (g->d) {
+  if (mode_ & FL_DOUBLE) {
+
+    glDrawBuffer(GL_BACK);
 
     if (!SWAP_TYPE) {
       SWAP_TYPE = UNDEFINED;
@@ -224,16 +225,10 @@ void Fl_Gl_Window::flush() {
 	if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw();
 	// we use a seperate context for the copy because rasterpos must be 0
 	// and depth test needs to be off:
-	static GLXContext ortho_context = 0;
+	static GLContext ortho_context = 0;
 	static Fl_Gl_Window* ortho_window = 0;
 	int init = !ortho_context;
-	if (init) {
-#if defined(_WIN32) || defined(WIN32)
-	  ortho_context = wglCreateContext(Fl_X::i(this)->private_dc);
-#else
-	  ortho_context =glXCreateContext(fl_display,g->vis,fl_first_context,1);
-#endif
-	}
+	if (init) ortho_context = fl_create_gl_context(this, g);
 	fl_set_gl_context(this, ortho_context);
 	if (init || !save_valid || ortho_window != this) {
 	  glDisable(GL_DEPTH_TEST);
@@ -274,7 +269,7 @@ void Fl_Gl_Window::flush() {
 
   }
 
-#if defined(_WIN32) || defined(WIN32)
+#if HAVE_GL_OVERLAY && defined(WIN32)
   if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
 #endif
   valid(1);
@@ -283,7 +278,7 @@ void Fl_Gl_Window::flush() {
 void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
   if (W != w() || H != h()) {
     valid(0);
-#if !defined(_WIN32) && !defined(WIN32)
+#ifndef WIN32
     if (!resizable() && overlay && overlay != this)
       ((Fl_Gl_Window*)overlay)->resize(0,0,W,H);
 #endif
@@ -291,26 +286,18 @@ void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
   Fl_Window::resize(X,Y,W,H);
 }
 
+void Fl_Gl_Window::context(void* v, int destroy_flag) {
+  if (context_ && !(mode_&NON_LOCAL_CONTEXT)) fl_delete_gl_context(context_);
+  context_ = (GLContext)v;
+  if (destroy_flag) mode_ &= ~NON_LOCAL_CONTEXT;
+  else mode_ |= NON_LOCAL_CONTEXT;
+}    
+
 void Fl_Gl_Window::hide() {
-  if (context) {
-    fl_no_gl_context();
-    if (context != fl_first_context) {
-#if defined(_WIN32) || defined(WIN32)
-      wglDeleteContext((GLXContext)context);
-#else
-      glXDestroyContext(fl_display, (GLXContext)context);
-#endif
-    }
-// This causes incompatibility with some OpenGL libraries
-// I don't think this is not necessary in any case, right?
-//#ifdef GLX_MESA_release_buffers
-//    glXReleaseBuffersMESA(fl_display, fl_xid(this));
-//#endif
-    context = 0;
-  }
-#if HAVE_GL_OVERLAY && (defined(_WIN32) || defined(WIN32))
-  if (overlay && overlay != this && (GLXContext)overlay != fl_first_context) {
-    wglDeleteContext((GLXContext)overlay);
+  context(0);
+#if HAVE_GL_OVERLAY && defined(WIN32)
+  if (overlay && overlay != this) {
+    fl_delete_gl_context((GLContext)overlay);
     overlay = 0;
   }
 #endif
@@ -327,7 +314,7 @@ void Fl_Gl_Window::init() {
   box(FL_NO_BOX);
   mode_ = FL_RGB | FL_DEPTH | FL_DOUBLE;
   alist = 0;
-  context = 0;
+  context_ = 0;
   g = 0;
   overlay = 0;
 }
@@ -337,5 +324,5 @@ void Fl_Gl_Window::draw_overlay() {}
 #endif
 
 //
-// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.20 2001/01/22 15:13:39 easysw Exp $".
+// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.21 2001/03/14 17:20:01 spitzak Exp $".
 //
diff --git a/src/Fl_compose.cxx b/src/Fl_compose.cxx
index 8fa620be539817555424378726bd461bf187b504..5b9a9f619722913d1176d41645f2df9ffb5778f8 100644
--- a/src/Fl_compose.cxx
+++ b/src/Fl_compose.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: Fl_compose.cxx,v 1.1.2.6 2001/01/22 15:13:40 easysw Exp $"
+// "$Id: Fl_compose.cxx,v 1.1.2.7 2001/03/14 17:20:01 spitzak Exp $"
 //
 // Character compose processing for the Fast Light Tool Kit (FLTK).
 //
@@ -30,7 +30,7 @@ static const char* const compose_pairs =
 "`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss"
 "`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y";
 
-#if !defined(_WIN32) && !defined(WIN32) // X only
+#ifndef WIN32 // X only
 // X dead-key lookup table.  This turns a dead-key keysym into the
 // first of two characters for one of the compose sequences.  These
 // keysyms start at 0xFE50.
@@ -113,7 +113,7 @@ int Fl::compose(int& del) {
     return 1;
   }
 
-#if !defined(_WIN32) && !defined(WIN32) // X only
+#ifndef WIN32 // X only
   // See if they typed a dead key.  This gets it into the same state as
   // typing prefix+accent:
   if (i >= 0xfe50 && i <= 0xfe5b) {
diff --git a/src/fl_file_chooser.cxx b/src/fl_file_chooser.cxx
index 70987668eb223b2b9af14cc93deb3b103cc760f3..1e6b463e3358827f8e391a57b068de8bd4f66ff2 100644
--- a/src/fl_file_chooser.cxx
+++ b/src/fl_file_chooser.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: fl_file_chooser.cxx,v 1.10.2.8 2001/01/22 15:13:41 easysw Exp $"
+// "$Id: fl_file_chooser.cxx,v 1.10.2.9 2001/03/14 17:20:02 spitzak Exp $"
 //
 // File chooser widget for the Fast Light Tool Kit (FLTK).
 //
@@ -231,7 +231,7 @@ int FCB::get(char* buf) {
       for (dirent** r = q+1; n && r < last; r++) {
 	if (!item_height(*r, 0)) continue;
 	int i;
-#if defined(_WIN32) || defined(WIN32)
+#ifdef WIN32
 	for (i=0; i<n && tolower((*q)->d_name[i])==tolower((*r)->d_name[i]); i++) {}
 #else
 	for (i=0; i<n && (*q)->d_name[i]==(*r)->d_name[i]; i++) {}
@@ -632,5 +632,5 @@ char* fl_file_chooser(const char* message, const char* pat, const char* fname)
 }
 
 //
-// End of "$Id: fl_file_chooser.cxx,v 1.10.2.8 2001/01/22 15:13:41 easysw Exp $".
+// End of "$Id: fl_file_chooser.cxx,v 1.10.2.9 2001/03/14 17:20:02 spitzak Exp $".
 //
diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx
index c24463c5d11a00898d5dcbb3ced0a2ea66fb8048..2b0348c60e09d71f3d9af50ba70f489a60e0770c 100644
--- a/src/gl_draw.cxx
+++ b/src/gl_draw.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: gl_draw.cxx,v 1.7.2.4 2001/01/22 15:13:41 easysw Exp $"
+// "$Id: gl_draw.cxx,v 1.7.2.5 2001/03/14 17:20:02 spitzak Exp $"
 //
 // OpenGL drawing support routines for the Fast Light Tool Kit (FLTK).
 //
@@ -37,14 +37,14 @@
 #include "Fl_Font.H"
 #include <string.h>
 
-void  gl_font(int fontid, int size) {fl_font(fontid, size);}
 int   gl_height() {return fl_height();}
 int   gl_descent() {return fl_descent();}
 double gl_width(const char* s) {return fl_width(s);}
 double gl_width(const char* s, int n) {return fl_width(s,n);}
 double gl_width(uchar c) {return fl_width(c);}
 
-void gl_draw(const char* str, int n) {
+void  gl_font(int fontid, int size) {
+  fl_font(fontid, size);
   if (!fl_fontsize->listbase) {
 #ifdef WIN32
     int base = fl_fontsize->metr.tmFirstChar;
@@ -60,11 +60,11 @@ void gl_draw(const char* str, int n) {
     glXUseXFont(fl_xfont->fid, base, size, fl_fontsize->listbase+base);
 #endif
   }
+  glListBase(fl_fontsize->listbase);
+}
 
-  glPushAttrib(GL_LIST_BIT);
-    glListBase(fl_fontsize->listbase);
-    glCallLists(n, GL_UNSIGNED_BYTE, str);
-  glPopAttrib();
+void gl_draw(const char* str, int n) {
+  glCallLists(n, GL_UNSIGNED_BYTE, str);
 }
 
 void gl_draw(const char* str, int n, int x, int y) {
@@ -155,5 +155,5 @@ void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
 #endif
 
 //
-// End of "$Id: gl_draw.cxx,v 1.7.2.4 2001/01/22 15:13:41 easysw Exp $".
+// End of "$Id: gl_draw.cxx,v 1.7.2.5 2001/03/14 17:20:02 spitzak Exp $".
 //
diff --git a/src/gl_start.cxx b/src/gl_start.cxx
index 3438fc46411e4419c3910583fa22fb76ed03a4e0..f0274eaf473bc280505e413f34e9d02d7be89af1 100644
--- a/src/gl_start.cxx
+++ b/src/gl_start.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: gl_start.cxx,v 1.6.2.4 2001/01/22 15:13:41 easysw Exp $"
+// "$Id: gl_start.cxx,v 1.6.2.5 2001/03/14 17:20:02 spitzak Exp $"
 //
 // OpenGL context routines for the Fast Light Tool Kit (FLTK).
 //
@@ -20,7 +20,7 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 // USA.
 //
-// Please report all bugs and problems to "fltk-bugs@fltk.org".
+// Please report all bugs and problems to "fltk-bugs@easysw.com".
 //
 
 // You MUST use gl_visual() to select the default visual before doing
@@ -42,35 +42,27 @@
 #include <FL/Fl_Window.H>
 #include <FL/x.H>
 #include <FL/fl_draw.H>
-
 #include "Fl_Gl_Choice.H"
 
-extern GLXContext fl_first_context; // in Fl_Gl_Choice.C
 extern int fl_clip_state_number; // in fl_rect.C
 
-static GLXContext context;
+static GLContext context;
 static int clip_state_number=-1;
 static int pw, ph;
 
 #ifdef WIN32
-static int default_mode;
+static Fl_Gl_Choice* gl_choice;
 #endif
 
 Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.C
 
 void gl_start() {
-#ifdef WIN32
-  HDC hdc = fl_private_dc(Fl_Window::current(), default_mode,0);
-#endif
   if (!context) {
 #ifdef WIN32
-    context = wglCreateContext(hdc);
-    if (!fl_first_context) fl_first_context = context;
-    else wglShareLists(fl_first_context, context);
+    if (!gl_choice) Fl::gl_visual(0);
+    context = fl_create_gl_context(Fl_Window::current(), gl_choice);
 #else
-    context = glXCreateContext(fl_display, fl_visual, fl_first_context, 1);
-    if (!context) Fl::fatal("OpenGL does not support this visual");
-    if (!fl_first_context) fl_first_context = context;
+    context = fl_create_gl_context(fl_visual);
 #endif
   }
   fl_set_gl_context(Fl_Window::current(), context);
@@ -100,19 +92,18 @@ void gl_start() {
 }
 
 void gl_finish() {
-#ifdef WIN32
   glFlush();
-#else
+#ifndef WIN32
   glXWaitGL();
 #endif
 }
 
 int Fl::gl_visual(int mode, int *alist) {
-#ifdef WIN32
-  default_mode = mode;
-#else
   Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist);
   if (!c) return 0;
+#ifdef WIN32
+  gl_choice = c;
+#else
   fl_visual = c->vis;
   fl_colormap = c->colormap;
 #endif
@@ -122,5 +113,5 @@ int Fl::gl_visual(int mode, int *alist) {
 #endif
 
 //
-// End of "$Id: gl_start.cxx,v 1.6.2.4 2001/01/22 15:13:41 easysw Exp $".
+// End of "$Id: gl_start.cxx,v 1.6.2.5 2001/03/14 17:20:02 spitzak Exp $".
 //
diff --git a/test/cube.cxx b/test/cube.cxx
index 0236b3ba72ae306d9709d6d00c7f3e9157404294..58d9d7579709f406f4d779d89a482b52ba4973ca 100644
--- a/test/cube.cxx
+++ b/test/cube.cxx
@@ -1,5 +1,5 @@
 //
-// "$Id: cube.cxx,v 1.4.2.4 2001/01/22 15:13:41 easysw Exp $"
+// "$Id: cube.cxx,v 1.4.2.5 2001/03/14 17:20:02 spitzak Exp $"
 //
 // Another forms test program for the Fast Light Tool Kit (FLTK).
 //
@@ -152,6 +152,16 @@ int main(int argc, char **argv) {
   form->show(argc,argv);
   cube->show();
   cube2->show();
+#if 0
+  // This demonstrates how to manipulate OpenGL contexts.
+  // In this case the same context is used by multiple windows (I'm not
+  // sure if this is allowed on Win32, can somebody check?).
+  // This fixes a bug on the XFree86 3.0 OpenGL where only one context
+  // per program seems to work, but there are probably better uses for
+  // this!
+  cube->make_current(); // causes context to be created
+  cube2->context(cube->context()); // share the contexts
+#endif
   for (;;) {
     if (form->visible() && speed->value())
       {if (!Fl::check()) break;}	// returns immediately
@@ -169,5 +179,5 @@ int main(int argc, char **argv) {
 }
 
 //
-// End of "$Id: cube.cxx,v 1.4.2.4 2001/01/22 15:13:41 easysw Exp $".
+// End of "$Id: cube.cxx,v 1.4.2.5 2001/03/14 17:20:02 spitzak Exp $".
 //