FLTK logo

[Library] r9009 - in branches/branch-3.0: include/fltk3gl src/fltk3gl

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

[Library] r9009 - in branches/branch-3.0: include/fltk3gl src/fltk3gl fltk-dev Aug 25, 2011  
 
Author: matt
Date: 2011-08-25 03:53:58 -0700 (Thu, 25 Aug 2011)
New Revision: 9009
Log:
More OpenGL renaming

Added:
   branches/branch-3.0/include/fltk3gl/GL_Window.h
   branches/branch-3.0/src/fltk3gl/GL_Choice.cxx
   branches/branch-3.0/src/fltk3gl/GL_Choice.h
   branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx
   branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx
   branches/branch-3.0/src/fltk3gl/GL_Window.cxx
Removed:
   branches/branch-3.0/include/fltk3gl/GlWindow.h
   branches/branch-3.0/src/fltk3gl/GlChoice.cxx
   branches/branch-3.0/src/fltk3gl/GlChoice.h
   branches/branch-3.0/src/fltk3gl/GlDevicePlugin.cxx
   branches/branch-3.0/src/fltk3gl/GlOverlay.cxx
   branches/branch-3.0/src/fltk3gl/GlWindow.cxx

Copied: branches/branch-3.0/include/fltk3gl/GL_Window.h (from rev 9008, branches/branch-3.0/include/fltk3gl/GlWindow.h)
===================================================================
--- branches/branch-3.0/include/fltk3gl/GL_Window.h	                        (rev 0)
+++ branches/branch-3.0/include/fltk3gl/GL_Window.h	2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,248 @@
+//
+// "$Id: GlWindow.h 8157 2011-01-01 14:01:53Z AlbrechtS $"
+//
+// OpenGL header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/* \file
+ fltk3::GlWindow widget . */
+
+#ifndef Fltk3_Gl_Window_H
+#define Fltk3_Gl_Window_H
+
+#include "Window.h"
+
+#ifndef GLContext
+/**
+ Opaque pointer type to hide system specific implementation.
+ */
+typedef void* GLContext; // actually a GLXContext or HGLDC
+#endif
+
+class Fl_Gl_Window;
+
+namespace fltk3 {
+  
+  class GlChoice; // structure to hold result of glXChooseVisual
+
+  /**
+   The fltk3::GlWindow widget sets things up so OpenGL works.
+   
+   It also keeps an OpenGL "context" for that window, so that changes to the
+   lighting and projection may be reused between redraws. fltk3::GlWindow
+   also flushes the OpenGL streams and swaps buffers after draw() returns.
+   
+   OpenGL hardware typically provides some overlay bit planes, which
+   are very useful for drawing UI controls atop your 3D graphics.  If the
+   overlay hardware is not provided, FLTK tries to simulate the overlay.
+   This works pretty well if your graphics are double buffered, but not
+   very well for single-buffered.
+   
+   Please note that the FLTK drawing and clipping functions
+   will not work inside an fltk3::GlWindow. All drawing
+   should be done using OpenGL calls exclusively.
+   Even though fltk3::GlWindow is derived from fltk3::Group, 
+   it is not useful to add other FLTK Widgets as children,
+   unless those widgets are modified to draw using OpenGL calls.
+   */
+  class FLTK3_EXPORT GlWindow : public fltk3::Window {
+    
+    friend class ::Fl_Gl_Window;
+
+    int mode_;
+    const int *alist;
+    GlChoice *g;
+    GLContext context_;
+    char valid_f_;
+    char damage1_; // damage() of back buffer
+    virtual void draw_overlay();
+    void init();
+    
+    void *overlay;
+    void make_overlay();
+    friend class _Fl_Gl_Overlay;
+    
+    static int can_do(int, const int *);
+    int mode(int, const int *);
+    
+  public:
+    
+    void show();
+    void show(int a, char **b) {Window::show(a,b);}
+    void flush();
+    void hide();
+    void resize(int,int,int,int);
+    int handle(int);
+    
+    /**
+     Is turned off when FLTK creates a new context for this window or 
+     when the window resizes, and is turned on \e after draw() is called.
+     You can use this inside your draw() method to avoid unnecessarily
+     initializing the OpenGL context. Just do this:
+     \code
+     void mywindow::draw() {
+     if (!valid()) {
+     glViewport(0,0,w(),h());
+     glFrustum(...);
+     ...other initialization...
+     }
+     if (!context_valid()) {
+     ...load textures, etc. ...
+     }
+     ... draw your geometry here ...
+     }
+     \endcode
+     
+     You can turn valid() on by calling valid(1).  You
+     should only do this after fixing the transformation inside a draw()
+     or after make_current().  This is done automatically after 
+     draw() returns.
+     */
+    char valid() const {return valid_f_ & 1;}
+    /**
+     See char fltk3::GlWindow::valid() const 
+     */
+    void valid(char v) {if (v) valid_f_ |= 1; else valid_f_ &= 0xfe;}
+    void invalidate();
+    
+    /**
+     Will only be set if the 
+     OpenGL context is created or recreated. It differs from
+     fltk3::GlWindow::valid() which is also set whenever the context
+     changes size.
+     */
+    char context_valid() const {return valid_f_ & 2;}
+    /**
+     See char fltk3::GlWindow::context_valid() const 
+     */
+    void context_valid(char v) {if (v) valid_f_ |= 2; else valid_f_ &= 0xfd;}
+    
+    /**  Returns non-zero if the hardware supports the given or current OpenGL mode. */
+    static int can_do(int m) {return can_do(m,0);}
+    /**  Returns non-zero if the hardware supports the given or current OpenGL mode. */
+    static int can_do(const int *m) {return can_do(0, m);}
+    /**  Returns non-zero if the hardware supports the given or current OpenGL mode. */
+    int can_do() {return can_do(mode_,alist);}
+    /**
+     Set or change the OpenGL capabilites of the window.  The value can be
+     any of the following OR'd together:
+     
+     - \c fltk3::RGB - RGB color (not indexed)
+     - \c fltk3::RGB8 - RGB color with at least 8 bits of each color
+     - \c fltk3::INDEX - Indexed mode
+     - \c fltk3::SINGLE - not double buffered
+     - \c fltk3::DOUBLE - double buffered
+     - \c fltk3::ACCUM - accumulation buffer
+     - \c fltk3::ALPHA - alpha channel in color
+     - \c fltk3::DEPTH - depth buffer
+     - \c fltk3::STENCIL - stencil buffer
+     - \c fltk3::MULTISAMPLE - multisample antialiasing
+     
+     fltk3::RGB and fltk3::SINGLE have a value of zero, so they
+     are "on" unless you give fltk3::INDEX or fltk3::DOUBLE.
+     
+     If the desired combination cannot be done, FLTK will try turning off 
+     fltk3::MULTISAMPLE.  If this also fails the show() will call 
+     fltk3::error() and not show the window.
+     
+     You can change the mode while the window is displayed.  This is most
+     useful for turning double-buffering on and off.  Under X this will
+     cause the old X window to be destroyed and a new one to be created.  If
+     this is a top-level window this will unfortunately also cause the
+     window to blink, raise to the top, and be de-iconized, and the xid()
+     will change, possibly breaking other code.  It is best to make the GL
+     window a child of another window if you wish to do this!
+     
+     mode() must not be called within draw() since it
+     changes the current context.
+     */
+    fltk3::Mode mode() const {return (fltk3::Mode)mode_;}
+    /** See fltk3::Mode mode() const */
+    int mode(int a) {return mode(a,0);}
+    /** See fltk3::Mode mode() const */
+    int mode(const int *a) {return mode(0, a);}
+    /** void See void context(void* v, int destroy_flag) */
+    void* context() const {return context_;}
+    void context(void*, int destroy_flag = 0);
+    void make_current();
+    void swap_buffers();
+    void ortho();
+    
+    /**
+     Returns true if the hardware overlay is possible.  If this is false,
+     FLTK will try to simulate the overlay, with significant loss of update
+     speed.  Calling this will cause FLTK to open the display.
+     */
+    int can_do_overlay();
+    /**
+     This method causes draw_overlay() to be called at a later time.
+     Initially the overlay is clear. If you want the window to display
+     something in the overlay when it first appears, you must call this
+     immediately after you show() your window.
+     */
+    void redraw_overlay();
+    void hide_overlay();
+    /**
+     The make_overlay_current() method selects the OpenGL context
+     for the widget's overlay.  It is called automatically prior to the 
+     draw_overlay() method being called and can also be used to
+     implement feedback and/or selection within the handle()
+     method.
+     */
+    void make_overlay_current();
+    
+    // Note: Doxygen docs in Widget.h to avoid redundancy.
+    virtual fltk3::GlWindow* as_gl_window() {return this;}
+    
+    ~GlWindow();
+    /**
+     Creates a new fltk3::GlWindow widget using the given size, and label string. 
+     The default boxtype is fltk3::NO_BOX. The default mode is fltk3::RGB|fltk3::DOUBLE|fltk3::DEPTH.
+     */
+    GlWindow(int W, int H, const char *l=0) : fltk3::Window(W,H,l) {init();}
+    /**
+     Creates a new fltk3::GlWindow widget using the given position,
+     size, and label string. The default boxtype is fltk3::NO_BOX. The
+     default mode is fltk3::RGB|fltk3::DOUBLE|fltk3::DEPTH.
+     */
+    
+    GlWindow(int X, int Y, int W, int H, const char *l=0)
+    : fltk3::Window(X,Y,W,H,l) {init();}
+    
+  protected:
+    /**
+     Draws the fltk3::GlWindow.
+     
+     You \e \b must override the draw() method.
+     */
+    virtual void draw();
+  };
+  
+}
+
+#endif
+
+//
+// End of "$Id: GlWindow.h 8157 2011-01-01 14:01:53Z AlbrechtS $".
+//

Deleted: branches/branch-3.0/include/fltk3gl/GlWindow.h

Copied: branches/branch-3.0/src/fltk3gl/GL_Choice.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlChoice.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Choice.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Choice.cxx	2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,426 @@
+//
+// "$Id$"
+//
+// OpenGL visual selection code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <config.h>
+#if HAVE_GL
+
+#  include <fltk3/run.h>
+#  include <fltk3/x.h>
+#  include <stdlib.h>
+#  include "Fl_Gl_Choice.H"
+#  include <fltk3/glDraw.h>
+#  include "flstring.h"
+#  include <fltk3/utf8.h>
+
+#  ifdef __APPLE__
+#    include <ApplicationServices/ApplicationServices.h>
+#    include <fltk3/Window.h>
+#  endif
+
+#  ifdef WIN32
+void fl_save_dc(HWND, HDC);
+#  endif
+
+static fltk3::GlChoice *first;
+
+// this assumes one of the two arguments is zero:
+// We keep the list system in Win32 to stay compatible and interpret
+// the list later...
+fltk3::GlChoice *fltk3::GlChoice::find(int m, const int *alistp) {
+  fltk3::GlChoice *g;
+  
+  for (g = first; g; g = g->next)
+    if (g->mode == m && g->alist == alistp) 
+      return g;
+
+#if defined(USE_X11)    
+  const int *blist;
+  int list[32];
+    
+  if (alistp)
+    blist = alistp;
+  else {
+    int n = 0;
+    if (m & fltk3::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 & fltk3::RGB8) ? 8 : 1;
+      if (m & fltk3::ALPHA) {
+	list[n++] = GLX_ALPHA_SIZE;
+	list[n++] = (m & fltk3::RGB8) ? 8 : 1;
+      }
+      if (m & fltk3::ACCUM) {
+	list[n++] = GLX_ACCUM_GREEN_SIZE;
+	list[n++] = 1;
+	if (m & fltk3::ALPHA) {
+	  list[n++] = GLX_ACCUM_ALPHA_SIZE;
+	  list[n++] = 1;
+	}
+      }
+    }
+    if (m & fltk3::DOUBLE) {
+      list[n++] = GLX_DOUBLEBUFFER;
+    }
+    if (m & fltk3::DEPTH) {
+      list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
+    }
+    if (m & fltk3::STENCIL) {
+      list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
+    }
+    if (m & fltk3::STEREO) {
+      list[n++] = GLX_STEREO;
+    }
+#    if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+    if (m & fltk3::MULTISAMPLE) {
+      list[n++] = GLX_SAMPLES_SGIS;
+      list[n++] = 4; // value Glut uses
+    }
+#    endif
+    list[n] = 0;
+    blist = list;
+  }
+    
+  fl_open_display();
+  XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
+  if (!visp) {
+#    if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+    if (m&fltk3::MULTISAMPLE) return find(m&~fltk3::MULTISAMPLE,0);
+#    endif
+    return 0;
+  }
+
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  const int *blist;
+  int list[32];
+   
+  if (alistp)
+    blist = alistp;
+  else {
+    int n = 0;
+    if (m & fltk3::INDEX) {
+      list[n++] = AGL_BUFFER_SIZE;
+      list[n++] = 8; // glut tries many sizes, but this should work...
+    } else {
+      list[n++] = AGL_RGBA;
+      list[n++] = AGL_GREEN_SIZE;
+      list[n++] = (m & fltk3::RGB8) ? 8 : 1;
+      if (m & fltk3::ALPHA) {
+        list[n++] = AGL_ALPHA_SIZE;
+        list[n++] = (m & fltk3::RGB8) ? 8 : 1;
+      }
+      if (m & fltk3::ACCUM) {
+        list[n++] = AGL_ACCUM_GREEN_SIZE;
+        list[n++] = 1;
+        if (m & fltk3::ALPHA) {
+          list[n++] = AGL_ACCUM_ALPHA_SIZE;
+          list[n++] = 1;
+        }
+      }
+    }
+    if (m & fltk3::DOUBLE) {
+      list[n++] = AGL_DOUBLEBUFFER;
+    }
+    if (m & fltk3::DEPTH) {
+      list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
+    }
+    if (m & fltk3::STENCIL) {
+      list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
+    }
+#    ifdef AGL_STEREO
+    if (m & fltk3::STEREO) {
+      list[n++] = AGL_STEREO;
+    }
+#    endif
+    list[n] = AGL_NONE;
+    blist = list;
+  }
+  fl_open_display();
+  AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, (GLint*)blist);
+  if (!fmt) return 0;
+  
+#elif defined(WIN32)
+
+  // Replacement for ChoosePixelFormat() that finds one with an overlay
+  // if possible:
+  if (!fl_gc) fl_GetDC(0);
+  int pixelformat = 0;
+  PIXELFORMATDESCRIPTOR chosen_pfd;
+  for (int i = 1; ; i++) {
+    PIXELFORMATDESCRIPTOR pfd;
+    if (!DescribePixelFormat(fl_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&fltk3::INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue;
+    if ((m & fltk3::ALPHA) && !pfd.cAlphaBits) continue;
+    if ((m & fltk3::ACCUM) && !pfd.cAccumBits) continue;
+    if ((!(m & fltk3::DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
+    if ((!(m & fltk3::STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue;
+    if ((m & fltk3::DEPTH) && !pfd.cDepthBits) continue;
+    if ((m & fltk3::STENCIL) && !pfd.cStencilBits) continue;
+    // see if better than the one we have already:
+    if (pixelformat) {
+      // offering non-generic rendering is better (read: hardware accelleration)
+      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 more bit planes is better:
+      else if (chosen_pfd.cColorBits > pfd.cColorBits) continue;
+      else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue;
+    }
+    pixelformat = i;
+    chosen_pfd = pfd;
+  }
+  //printf("Chosen pixel format is %d\n", pixelformat);
+  if (!pixelformat) return 0;
+#else
+# error platform unsupported
+#endif
+
+  g = new fltk3::GlChoice;
+  g->mode = m;
+  g->alist = alistp;
+  g->next = first;
+  first = g;
+
+#if defined(USE_X11)
+  g->vis = visp;
+
+  if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
+      visp->visualid == fl_visual->visualid &&
+      !fltk3::getenv("MESA_PRIVATE_CMAP"))
+    g->colormap = fl_colormap;
+  else
+    g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+				  visp->visual, AllocNone);
+#  elif defined(WIN32)
+  g->pixelformat = pixelformat;
+  g->pfd = chosen_pfd;
+#  elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  g->pixelformat = fmt;
+#  else
+#    error unsupported platform
+#  endif
+
+  return g;
+}
+
+static GLContext *context_list = 0;
+static int nContext = 0, NContext = 0;
+
+static void add_context(GLContext ctx) {
+  if (!ctx) return;
+  if (nContext==NContext) {
+    if (!NContext) NContext = 8;
+    NContext *= 2;
+    context_list = (GLContext*)realloc(
+      context_list, NContext*sizeof(GLContext));
+  }
+  context_list[nContext++] = ctx;
+}
+
+static void del_context(GLContext ctx) {
+  int i; 
+  for (i=0; i<nContext; i++) {
+    if (context_list[i]==ctx) {
+      memmove(context_list+i, context_list+i+1,
+        (nContext-i-1) * sizeof(GLContext));
+      context_list[--nContext] = 0;
+      break;
+    }
+  }
+  if (!nContext) gl_remove_displaylist_fonts();
+}
+
+#if defined(USE_X11)
+
+GLContext fl_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;
+}
+
+#elif defined(WIN32)
+
+GLContext fl_create_gl_context(fltk3::Window* window, const fltk3::GlChoice* 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);
+    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;
+}
+
+#  elif defined(__APPLE_QUARTZ__)
+#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && __LP64__)
+static CGrafPtr fl_GetWindowPort(WindowRef window)
+{
+  typedef CGrafPtr (*wf)(WindowRef);
+  static wf f = NULL;
+  if ( ! f) f = (wf)Fl_X::get_carbon_function("GetWindowPort");
+  return (*f)(window);
+}
+#endif
+
+// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+GLContext fl_create_gl_context(fltk3::Window* window, const fltk3::GlChoice* g, int layer) {
+  GLContext context, shared_ctx = 0;
+  if (context_list && nContext) shared_ctx = context_list[0];
+  context = aglCreateContext( g->pixelformat, shared_ctx);
+  if (!context) return 0;
+  add_context((GLContext)context);
+  if ( window->parent() ) {
+    int H = window->window()->h();
+    GLint rect[] = { window->x(), H-window->h()-window->y(), window->w(), window->h() };
+    aglSetInteger( (GLContext)context, AGL_BUFFER_RECT, rect );
+    aglEnable( (GLContext)context, AGL_BUFFER_RECT );
+  }
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if __LP64__
+  // 64 bit version
+  aglSetWindowRef(context, Fl_X::i(window)->window_ref() );
+#else
+  // 32 bit version >= 10.5
+  if (aglSetWindowRef != NULL)
+    aglSetWindowRef(context, Fl_X::i(window)->window_ref() );
+  else
+    aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) );
+#endif
+#else
+  // 32 bit version < 10.5
+  aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) );
+#endif
+  return (context);
+}
+#  else
+#    error unsupported platform
+#  endif
+
+static GLContext cached_context;
+static fltk3::Window* cached_window;
+
+void fl_set_gl_context(fltk3::Window* w, GLContext context) {
+  if (context != cached_context || w != cached_window) {
+    cached_context = context;
+    cached_window = w;
+#  if defined(USE_X11)
+    glXMakeCurrent(fl_display, fl_xid(w), context);
+#  elif defined(WIN32)
+    wglMakeCurrent(Fl_X::i(w)->private_dc, context);
+#  elif defined(__APPLE_QUARTZ__)
+    // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+    if ( w->parent() ) { //: resize our GL buffer rectangle
+      int H = w->window()->h();
+      GLint rect[] = { w->x(), H-w->h()-w->y(), w->w(), w->h() };
+      aglSetInteger( context, AGL_BUFFER_RECT, rect );
+      aglEnable( context, AGL_BUFFER_RECT );
+    }
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if __LP64__
+    // 64 bit version
+    aglSetWindowRef(context, Fl_X::i(w)->window_ref() );
+#else
+    // 32 bit version >= 10.5
+    if (aglSetWindowRef != NULL)
+      aglSetWindowRef(context, Fl_X::i(w)->window_ref() );
+    else
+      aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) );
+#endif
+#else
+    // 32 bit version < 10.5
+    aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) );
+#endif
+    aglSetCurrentContext(context);
+#  else
+#   error unsupported platform
+#  endif
+  }
+}
+
+void fl_no_gl_context() {
+  cached_context = 0;
+  cached_window = 0;
+#  if defined(USE_X11)
+  glXMakeCurrent(fl_display, 0, 0);
+#  elif defined(WIN32)
+  wglMakeCurrent(0, 0);
+#  elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  AGLContext ctx = aglGetCurrentContext();  
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+  if (aglSetWindowRef != NULL)
+    { if(ctx) aglSetWindowRef(ctx, NULL ); }
+  else
+#endif
+  if(ctx) aglSetDrawable( ctx, NULL );
+  aglSetCurrentContext(0);
+#  else
+#    error unsupported platform
+#  endif
+}
+
+void fl_delete_gl_context(GLContext context) {
+  if (cached_context == context) fl_no_gl_context();
+#  if defined(USE_X11)
+  glXDestroyContext(fl_display, context);
+#  elif defined(WIN32)
+  wglDeleteContext(context);
+#  elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  aglDestroyContext( context );
+#  else
+#    error unsupported platform
+#  endif
+  del_context(context);
+}
+
+#endif // HAVE_GL
+
+
+//
+// End of "$Id$".
+//

Copied: branches/branch-3.0/src/fltk3gl/GL_Choice.h (from rev 9008, branches/branch-3.0/src/fltk3gl/GlChoice.h)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Choice.h	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Choice.h	2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,129 @@
+//
+// "$Id$"
+//
+// OpenGL definitions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Internal interface to set up OpenGL.
+//
+// A "fltk3::GlChoice" 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
+// fltk3::GlChoice 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 fltk3::GlWindow, 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 <fltk3/gl.h>
+#  define GLContext HGLRC
+#elif defined(__APPLE_QUARTZ__)
+// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+#  include <OpenGL/gl.h>
+#  include <AGL/agl.h>
+#  define GLContext AGLContext
+#else
+#  include <GL/glx.h>
+#  define GLContext GLXContext
+#endif
+
+namespace fltk3 {
+  
+  // Describes crap needed to create a GLContext.
+  class GlChoice {
+    int mode;
+    const int *alist;
+    fltk3::GlChoice *next;
+  public:
+#ifdef WIN32
+    int pixelformat;	// the visual to use
+    PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
+#elif defined(__APPLE_QUARTZ__)
+    // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+    AGLPixelFormat pixelformat;
+#else
+    XVisualInfo *vis;	// the visual to use
+    Colormap colormap;	// a colormap for that visual
+#endif
+    // 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 fltk3::GlChoice *find(int mode, const int *);
+  };
+  
+  class Window;
+
+} // namespace
+
+
+#ifdef WIN32
+  
+  GLContext fl_create_gl_context(fltk3::Window*, const fltk3::GlChoice*, int layer=0);
+  
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  
+  GLContext fl_create_gl_context(fltk3::Window*, const fltk3::GlChoice*, int layer=0);
+  
+#else
+  
+  GLContext fl_create_gl_context(XVisualInfo* vis);
+  
+  static inline
+  GLContext fl_create_gl_context(fltk3::Window*, const fltk3::GlChoice* g) {
+    return fl_create_gl_context(g->vis);
+  }
+  
+#endif
+  
+  void fl_set_gl_context(fltk3::Window*, GLContext);
+  void fl_no_gl_context();
+  void fl_delete_gl_context(GLContext);
+  
+#endif
+
+//
+// End of "$Id$".
+//

Copied: branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlDevicePlugin.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx	2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,156 @@
+//
+// "$Id$"
+//
+// implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <config.h>
+#include <fltk3/Printer.h>
+#include <fltk3/GlWindow.h>
+#include "Fl_Gl_Choice.H"
+#include <fltk3/run.h>
+#ifndef __APPLE__
+#include <fltk3/draw.h>
+#endif
+
+#if defined(__APPLE__)
+static void imgProviderReleaseData (void *info, const void *data, size_t size)
+{
+  free((void *)data);
+}
+#endif
+
+static void print_gl_window(fltk3::GlWindow *glw, int x, int y, int height)
+{
+#ifdef WIN32
+  HDC save_gc = fl_gc;
+  const int bytesperpixel = 3;
+#elif defined(__APPLE__)
+  CGContextRef save_gc = fl_gc;
+  const int bytesperpixel = 4;
+#else
+  _XGC *save_gc = fl_gc;
+  const int bytesperpixel = 3;
+#endif
+  fltk3::SurfaceDevice *save_surface = fltk3::SurfaceDevice::surface();
+  fl_gc = NULL;
+  fltk3::DisplayDevice::display_device()->set_current();
+#ifdef WIN32
+  fltk3::check();
+  fltk3::Window *win = (fltk3::Window*)glw;
+  while( win->window() ) win = win->window();
+  win->redraw();
+  fltk3::check();
+  glw->make_current();
+#else
+  glw->make_current();
+  glw->redraw();
+  glFlush();
+  fltk3::check();
+  glFinish();
+#endif
+  // Read OpenGL context pixels directly.
+  // For extra safety, save & restore OpenGL states that are changed
+  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+  glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
+  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+  // Read a block of pixels from the frame buffer
+  int mByteWidth = glw->w() * bytesperpixel;                
+  mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes
+  uchar *baseAddress = (uchar*)malloc(mByteWidth * glw->h());
+  glReadPixels(0, 0, glw->w(), glw->h(), 
+#ifdef WIN32
+	       GL_RGB, GL_UNSIGNED_BYTE,
+#elif defined(__APPLE__)
+	       GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+#else // FIXME Linux/Unix
+	       GL_RGB, GL_UNSIGNED_BYTE,
+#endif
+	       baseAddress);
+  glPopClientAttrib();
+  save_surface->set_current();
+  fl_gc = save_gc;
+#if defined(__APPLE__)
+// kCGBitmapByteOrder32Host and CGBitmapInfo are supposed to arrive with 10.4
+// but some 10.4 don't have kCGBitmapByteOrder32Host, so we play a little #define game
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
+#define kCGBitmapByteOrder32Host 0
+#define CGBitmapInfo CGImageAlphaInfo
+#elif ! defined(kCGBitmapByteOrder32Host)
+#ifdef __BIG_ENDIAN__
+#define kCGBitmapByteOrder32Host (4 << 12)
+#else    /* Little endian. */
+#define kCGBitmapByteOrder32Host (2 << 12)
+#endif
+#endif
+  CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
+  CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, mByteWidth * glw->h(), imgProviderReleaseData);
+  CGImageRef image = CGImageCreate(glw->w(), glw->h(), 8, 8*bytesperpixel, mByteWidth, cSpace, 
+				   (CGBitmapInfo)(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host), 
+				   provider, NULL, false, kCGRenderingIntentDefault);
+  if(image == NULL) return;
+  CGContextSaveGState(fl_gc);
+  CGContextTranslateCTM(fl_gc, 0, height);
+  CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
+  CGRect rect = { { x, height - y - glw->h() }, { glw->w(), glw->h() } };
+  Fl_X::q_begin_image(rect, 0, 0, glw->w(), glw->h());
+  CGContextDrawImage(fl_gc, rect, image);
+  Fl_X::q_end_image();
+  CGContextRestoreGState(fl_gc);
+  CGImageRelease(image);
+  CGColorSpaceRelease(cSpace);
+  CGDataProviderRelease(provider);  
+#else
+  fltk3::draw_image(baseAddress + (glw->h() - 1) * mByteWidth, x, y , glw->w(), glw->h(), bytesperpixel, - mByteWidth);
+  free(baseAddress);
+#endif // __APPLE__
+}
+
+/**
+ This class will make sure that OpenGL printing is available if fltk_gl
+ was linked to the program.
+ */
+class Fl_Gl_Device_Plugin : public fltk3::DevicePlugin {
+public:
+  Fl_Gl_Device_Plugin() : fltk3::DevicePlugin(name()) { }
+  virtual const char *name() { return "opengl.device.fltk.org"; }
+  virtual int print(fltk3::Widget *w, int x, int y, int height) {
+    fltk3::GlWindow *glw = w->as_gl_window();
+    if (!glw) return 0;
+    print_gl_window(glw, x, y, height);
+    return 1; 
+  }
+};
+
+static Fl_Gl_Device_Plugin Gl_Device_Plugin;
+
+// The purpose of this variable, used in fltk3::GlWindow.cxx, is only to force this file to be loaded
+// whenever fltk3::GlWindow.cxx is loaded, that is, whenever fltk_gl is.
+FLTK3_EXPORT int fl_gl_load_plugin = 0;
+
+//
+// End of "$Id$".
+//

Copied: branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlOverlay.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx	2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,248 @@
+//
+// "$Id$"
+//
+// OpenGL overlay code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <config.h>
+#if HAVE_GL
+
+#include <fltk3/run.h>
+#include <fltk3/x.h>
+#include "Fl_Gl_Choice.H"
+#include <fltk3/GlWindow.h>
+#include <stdlib.h>
+
+#if !HAVE_GL_OVERLAY
+
+int fltk3::GlWindow::can_do_overlay() {return 0;}
+
+void fltk3::GlWindow::make_overlay() {overlay = this;}
+
+#else
+
+// Methods on fltk3::GlWindow 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 fltk3::GlWindow except it uses the overlay planes.
+// A pointer to this is stored in the "overlay" pointer of the fltk3::GlWindow.
+
+// 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.
+
+#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;
+extern uchar fl_overlay;
+
+class _Fl_Gl_Overlay : public fltk3::GlWindow {
+  void flush();
+  void draw();
+public:
+  void show();
+  _Fl_Gl_Overlay(int x, int y, int w, int h) :
+    fltk3::GlWindow(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() != fltk3::DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
+  fltk3::GlWindow *w = (fltk3::GlWindow *)parent();
+  uchar save_valid = w->valid();
+  w->valid(valid());
+  fl_overlay = 1;
+  w->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:
+    fltk3::Window *w = window();
+    for (;;) {fltk3::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);
+  }
+  fltk3::GlWindow::show();
+}
+
+int fltk3::GlWindow::can_do_overlay() {
+  return fl_find_overlay_visual() != 0;
+}
+
+void fltk3::GlWindow::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
+  }
+}
+
+#else
+////////////////////////////////////////////////////////////////
+// WIN32 version:
+
+//static COLORREF *palette;
+extern int fl_overlay_depth;
+
+void fltk3::GlWindow::make_overlay() {
+  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; fltk3::get_color((fltk3::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;
+}
+
+int fltk3::GlWindow::can_do_overlay() {
+  if (!g) {
+    g = fltk3::GlChoice::find(mode_,alist);
+    if (!g) return 0;
+  }
+  return (g->pfd.bReserved & 15) != 0;
+}
+
+////////////////////////////////////////////////////////////////
+#endif
+
+#endif
+
+void fltk3::GlWindow::redraw_overlay() {
+  if (!shown()) return;
+  make_overlay();
+#ifdef __APPLE__
+  redraw();
+#else
+#ifndef WIN32
+  if (overlay != this)
+    ((fltk3::GlWindow*)overlay)->redraw();
+  else
+#endif
+    damage(fltk3::DAMAGE_OVERLAY);
+#endif
+}
+
+void fltk3::GlWindow::make_overlay_current() {
+  make_overlay();
+#ifdef __APPLE__
+  // 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.
+  make_current();
+#else
+#if HAVE_GL_OVERLAY
+  if (overlay != this) {
+#ifdef WIN32
+    fl_set_gl_context(this, (GLContext)overlay);
+//  if (fl_overlay_depth)
+//    wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
+#else
+    ((fltk3::GlWindow*)overlay)->make_current();
+#endif
+  } else
+#endif
+    glDrawBuffer(GL_FRONT);
+#endif
+}
+/** Hides the window if it is not this window, does nothing in WIN32. */
+void fltk3::GlWindow::hide_overlay() {
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+  // nothing needs to be done?  Or should it be erased?
+#else
+  if (overlay && overlay!=this) ((fltk3::GlWindow*)overlay)->hide();
+#endif
+#endif
+}
+
+#endif
+
+//
+// End of "$Id$".
+//

Copied: branches/branch-3.0/src/fltk3gl/GL_Window.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlWindow.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Window.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Window.cxx	2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,554 @@
+//
+// "$Id$"
+//
+// OpenGL window code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include "flstring.h"
+#if HAVE_GL
+
+extern int fl_gl_load_plugin;
+
+static int temp = fl_gl_load_plugin;
+
+#include <fltk3/Wrapper.h>
+#include <fltk3/run.h>
+#include <fltk3/x.h>
+#ifdef __APPLE__
+#include <fltk3/gl.h>
+#endif
+#include "Fl_Gl_Choice.H"
+#include <fltk3/GlWindow.h>
+#include <stdlib.h>
+#include <fltk3/utf8.h>
+
+////////////////////////////////////////////////////////////////
+
+// The symbol SWAP_TYPE defines what is in the back buffer after doing
+// a glXSwapBuffers().
+
+// The OpenGl documentation says that the contents of the backbuffer
+// are "undefined" after glXSwapBuffers().  However, if we know what
+// is in the backbuffers then we can save a good deal of time.  For
+// this reason you can define some symbols to describe what is left in
+// the back buffer.
+
+// Having not found any way to determine this from glx (or wgl) I have
+// resorted to letting the user specify it with an environment variable,
+// GL_SWAP_TYPE, it should be equal to one of these symbols:
+
+// contents of back buffer after glXSwapBuffers():
+#define UNDEFINED 1 	// anything
+#define SWAP 2		// former front buffer (same as unknown)
+#define COPY 3		// unchanged
+#define NODAMAGE 4	// unchanged even by X expose() events
+
+static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable
+
+////////////////////////////////////////////////////////////////
+
+/**  Returns non-zero if the hardware supports the given or current OpenGL  mode. */
+int fltk3::GlWindow::can_do(int a, const int *b) {
+  return fltk3::GlChoice::find(a,b) != 0;
+}
+
+void fltk3::GlWindow::show() {
+#if defined(__APPLE__)
+  int need_redraw = 0;
+#endif
+  if (!shown()) {
+    if (!g) {
+      g = fltk3::GlChoice::find(mode_,alist);
+
+      if (!g && (mode_ & fltk3::DOUBLE) == fltk3::SINGLE) {
+        g = fltk3::GlChoice::find(mode_ | fltk3::DOUBLE,alist);
+	if (g) mode_ |= fltk3::FAKE_SINGLE;
+      }
+
+      if (!g) {
+        fltk3::error("Insufficient GL support");
+	return;
+      }
+    }
+#if !defined(WIN32) && !defined(__APPLE__)
+    Fl_X::make_xid(this, g->vis, g->colormap);
+    if (overlay && overlay != this) ((fltk3::GlWindow*)overlay)->show();
+#elif defined(__APPLE__)
+	if( ! parent() ) need_redraw=1;
+#endif
+  }
+  Window::show();
+
+#ifdef __APPLE__
+  set_visible();
+  if(need_redraw) redraw();//necessary only after creation of a top-level GL window
+#endif /* __APPLE__ */
+}
+
+/**
+  The invalidate() method turns off valid() and is
+  equivalent to calling value(0).
+*/
+void fltk3::GlWindow::invalidate() {
+  valid(0);
+  context_valid(0);
+#ifndef WIN32
+  if (overlay) {
+    ((fltk3::GlWindow*)overlay)->valid(0);
+    ((fltk3::GlWindow*)overlay)->context_valid(0);
+  }
+#endif
+}
+
+/**
+  See const int fltk3::GlWindow::mode() const 
+*/
+int fltk3::GlWindow::mode(int m, const int *a) {
+  if (m == mode_ && a == alist) return 0;
+#ifndef __APPLE__
+  int oldmode = mode_;
+#endif // !__APPLE__
+#if !defined(WIN32) && !defined(__APPLE__)
+  fltk3::GlChoice* oldg = g;
+#endif // !WIN32 && !__APPLE__
+  context(0);
+  mode_ = m; alist = a;
+  if (shown()) {
+    g = fltk3::GlChoice::find(m, a);
+
+#if defined(USE_X11)
+    // under X, if the visual changes we must make a new X window (yuck!):
+    if (!g || g->vis->visualid!=oldg->vis->visualid || (oldmode^m)&fltk3::DOUBLE) {
+      hide();
+      show();
+    }
+#elif defined(WIN32)
+    if (!g || (oldmode^m)&(fltk3::DOUBLE|fltk3::STEREO)) {
+      hide();
+      show();
+    }
+#elif defined(__APPLE_QUARTZ__)
+    // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+    redraw();
+#else
+#  error unsupported platform
+#endif
+  } else {
+    g = 0;
+  }
+  return 1;
+}
+
+#define NON_LOCAL_CONTEXT 0x80000000
+
+/**
+  The make_current() method selects the OpenGL context for the
+  widget.  It is called automatically prior to the draw() method
+  being called and can also be used to implement feedback and/or
+  selection within the handle() method.
+*/
+
+void fltk3::GlWindow::make_current() {
+//  puts("fltk3::GlWindow::make_current()");
+//  printf("make_current: context_=%p\n", context_);
+  if (!context_) {
+    mode_ &= ~NON_LOCAL_CONTEXT;
+    context_ = fl_create_gl_context(this, g);
+    valid(0);
+    context_valid(0);
+  }
+  fl_set_gl_context(this, context_);
+
+#ifdef __APPLE__
+  // Set the buffer rectangle here, since in resize() we won't have the
+  // correct parent window size to work with...
+  GLint xywh[4];
+
+  if (window()) {
+    xywh[0] = x();
+    xywh[1] = window()->h() - y() - h();
+  } else {
+    xywh[0] = 0;
+    xywh[1] = 0;
+  }
+
+  xywh[2] = w();
+  xywh[3] = h();
+
+  aglSetInteger(context_, AGL_BUFFER_RECT, xywh);
+  aglEnable(context_, AGL_BUFFER_RECT);
+//  printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]);
+#endif // __APPLE__
+
+#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 (mode_ & fltk3::FAKE_SINGLE) {
+    glDrawBuffer(GL_FRONT);
+    glReadBuffer(GL_FRONT);
+  }
+  current_ = this;
+}
+
+/**
+  Sets the projection so 0,0 is in the lower left of the window and each
+  pixel is 1 unit wide/tall.  If you are drawing 2D images, your 
+  draw() method may want to call this if valid() is false.
+*/
+void fltk3::GlWindow::ortho() {
+// Alpha NT seems to have a broken OpenGL that does not like negative coords:
+#ifdef _M_ALPHA
+  glLoadIdentity();
+  glViewport(0, 0, w(), h());
+  glOrtho(0, w(), 0, h(), -1, 1);
+#else
+  GLint v[2];
+  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v);
+  glLoadIdentity();
+  glViewport(w()-v[0], h()-v[1], v[0], v[1]);
+  glOrtho(w()-v[0], w(), h()-v[1], h(), -1, 1);
+#endif
+}
+
+/**
+  The swap_buffers() method swaps the back and front buffers.
+  It is called automatically after the draw() method is called.
+*/
+void fltk3::GlWindow::swap_buffers() {
+#if defined(USE_X11)
+  glXSwapBuffers(fl_display, fl_xid(this));
+#elif defined(WIN32)
+#  if HAVE_GL_OVERLAY
+  // Do not swap the overlay, to match GLX:
+  BOOL ret = wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE);
+  DWORD err = GetLastError();;
+#  else
+  SwapBuffers(Fl_X::i(this)->private_dc);
+#  endif
+#elif defined(__APPLE_QUARTZ__)
+  if(overlay != NULL) {
+    //aglSwapBuffers does not work well with overlays under cocoa
+    glReadBuffer(GL_BACK);
+    glDrawBuffer(GL_FRONT);
+    glCopyPixels(0,0,w(),h(),GL_COLOR);
+  }
+  else
+    aglSwapBuffers((AGLContext)context_);
+#else
+# error unsupported platform
+#endif
+}
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+uchar fl_overlay; // changes how fltk3::color() works
+int fl_overlay_depth = 0;
+#endif
+
+
+void fltk3::GlWindow::flush() {
+  uchar save_valid = valid_f_ & 1;
+#if HAVE_GL_OVERLAY && defined(WIN32)
+  uchar save_valid_f = valid_f_;
+#endif
+
+#if defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  //: clear previous clipping in this shared port
+#if ! __LP64__
+/*GrafPtr port = GetWindowPort( Fl_X::i(this)->window_ref() );
+  Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff );
+  GrafPtr old; GetPort( &old );
+  SetPort( port );
+  ClipRect( &rect );
+  SetPort( old );*/
+#endif
+#endif
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+
+  bool fixcursor = false; // for fixing the SGI 320 bug
+
+  // Draw into hardware overlay planes if they are damaged:
+  if (overlay && overlay != this
+      && (damage()&(fltk3::DAMAGE_OVERLAY|fltk3::DAMAGE_EXPOSE) || !save_valid)) {
+    // SGI 320 messes up overlay with user-defined cursors:
+    if (Fl_X::i(this)->cursor && Fl_X::i(this)->cursor != fl_default_cursor) {
+      fixcursor = true; // make it restore cursor later
+      SetCursor(0);
+    }
+    fl_set_gl_context(this, (GLContext)overlay);
+    if (fl_overlay_depth)
+      wglRealizeLayerPalette(Fl_X::i(this)->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_X::i(this)->private_dc, WGL_SWAP_OVERLAY1);
+    // if only the overlay was damaged we are done, leave main layer alone:
+    if (damage() == fltk3::DAMAGE_OVERLAY) {
+      if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
+      return;
+    }
+  }
+#endif
+
+  make_current();
+
+  if (mode_ & fltk3::DOUBLE) {
+
+    glDrawBuffer(GL_BACK);
+
+    if (!SWAP_TYPE) {
+#if defined (__APPLE_QUARTZ__) || defined (USE_X11)
+      SWAP_TYPE = COPY;
+#else
+      SWAP_TYPE = UNDEFINED;
+#endif
+      const char* c = fltk3::getenv("GL_SWAP_TYPE");
+      if (c) {
+	if (!strcmp(c,"COPY")) SWAP_TYPE = COPY;
+	else if (!strcmp(c, "NODAMAGE")) SWAP_TYPE = NODAMAGE;
+	else if (!strcmp(c, "SWAP")) SWAP_TYPE = SWAP;
+	else SWAP_TYPE = UNDEFINED;
+      }
+    }
+
+    if (SWAP_TYPE == NODAMAGE) {
+
+      // don't draw if only overlay damage or expose events:
+      if ((damage()&~(fltk3::DAMAGE_OVERLAY|fltk3::DAMAGE_EXPOSE)) || !save_valid)
+	draw();
+      swap_buffers();
+
+    } else if (SWAP_TYPE == COPY) {
+
+      // don't draw if only the overlay is damaged:
+      if (damage() != fltk3::DAMAGE_OVERLAY || !save_valid) draw();
+	  swap_buffers();
+
+    } else if (SWAP_TYPE == SWAP){
+      damage(fltk3::DAMAGE_ALL);
+      draw();
+      if (overlay == this) draw_overlay();
+      swap_buffers();
+    } else if (SWAP_TYPE == UNDEFINED){ // SWAP_TYPE == UNDEFINED
+
+      // If we are faking the overlay, use CopyPixels to act like
+      // SWAP_TYPE == COPY.  Otherwise overlay redraw is way too slow.
+      if (overlay == this) {
+	// don't draw if only the overlay is damaged:
+	if (damage1_ || damage() != fltk3::DAMAGE_OVERLAY || !save_valid) draw();
+	// we use a separate context for the copy because rasterpos must be 0
+	// and depth test needs to be off:
+	static GLContext ortho_context = 0;
+	static fltk3::GlWindow* ortho_window = 0;
+	int orthoinit = !ortho_context;
+	if (orthoinit) ortho_context = fl_create_gl_context(this, g);
+	fl_set_gl_context(this, ortho_context);
+	if (orthoinit || !save_valid || ortho_window != this) {
+	  glDisable(GL_DEPTH_TEST);
+	  glReadBuffer(GL_BACK);
+	  glDrawBuffer(GL_FRONT);
+	  glLoadIdentity();
+	  glViewport(0, 0, w(), h());
+	  glOrtho(0, w(), 0, h(), -1, 1);
+	  glRasterPos2i(0,0);
+	  ortho_window = this;
+	}
+	glCopyPixels(0,0,w(),h(),GL_COLOR);
+	make_current(); // set current context back to draw overlay
+	damage1_ = 0;
+
+      } else {
+	damage1_ = damage();
+	clear_damage(0xff); draw();
+	swap_buffers();
+      }
+
+    }
+
+    if (overlay==this && SWAP_TYPE != SWAP) { // fake overlay in front buffer
+      glDrawBuffer(GL_FRONT);
+      draw_overlay();
+      glDrawBuffer(GL_BACK);
+      glFlush();
+    }
+
+  } else {	// single-buffered context is simpler:
+
+    draw();
+    if (overlay == this) draw_overlay();
+    glFlush();
+
+  }
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+  if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
+#endif
+  valid(1);
+  context_valid(1);
+}
+
+void fltk3::GlWindow::resize(int X,int Y,int W,int H) {
+//  printf("fltk3::GlWindow::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H);
+//  printf("current: x()=%d, y()=%d, w()=%d, h()=%d\n", x(), y(), w(), h());
+
+  if (W != w() || H != h()) valid(0);
+
+#ifdef __APPLE__
+  if (X != x() || Y != y() || W != w() || H != h()) aglUpdateContext(context_);
+#elif !defined(WIN32)
+  if ((W != w() || H != h()) && !resizable() && overlay && overlay != this) {
+    ((fltk3::GlWindow*)overlay)->resize(0,0,W,H);
+  }
+#endif
+
+  Window::resize(X,Y,W,H);
+}
+
+/**
+  Returns or sets 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 make_current()
+  is called, this is useful for getting around bugs in OpenGL implementations.
+  
+  If <i>destroy_flag</i> is true the context will be destroyed by
+  fltk when the window is destroyed, or when the mode() is changed, 
+  or the next time context(x) is called.
+*/
+void fltk3::GlWindow::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;
+}    
+
+/**
+  Hides the window and destroys the OpenGL context.
+*/
+void fltk3::GlWindow::hide() {
+  context(0);
+#if HAVE_GL_OVERLAY && defined(WIN32)
+  if (overlay && overlay != this) {
+    fl_delete_gl_context((GLContext)overlay);
+    overlay = 0;
+  }
+#endif
+  Window::hide();
+}
+
+/**
+  The destructor removes the widget and destroys the OpenGL context
+  associated with it.
+*/
+fltk3::GlWindow::~GlWindow() {
+  hide();
+//  delete overlay; this is done by ~Fl_Group
+#ifdef __APPLE__
+  // resets the pile of string textures used to draw strings
+  extern void gl_texture_reset();
+  gl_texture_reset();
+#endif
+}
+
+void fltk3::GlWindow::init() {
+  end(); // we probably don't want any children
+  box(fltk3::NO_BOX);
+
+  mode_    = fltk3::RGB | fltk3::DEPTH | fltk3::DOUBLE;
+  alist    = 0;
+  context_ = 0;
+  g        = 0;
+  overlay  = 0;
+  valid_f_ = 0;
+  damage1_ = 0;
+
+#if 0 // This breaks resizing on Linux/X11
+  int H = h();
+  h(1); // Make sure we actually do something in resize()...
+  resize(x(), y(), w(), H);
+#endif // 0
+}
+
+/**
+  You must implement this virtual function if you want to draw into the
+  overlay.  The overlay is cleared before this is called.  You should
+  draw anything that is not clear using OpenGL.  You must use 
+  gl_color(i) to choose colors (it allocates them from the colormap
+  using system-specific calls), and remember that you are in an indexed
+  OpenGL mode and drawing anything other than flat-shaded will probably
+  not work.
+
+  Both this function and fltk3::GlWindow::draw() should check 
+  fltk3::GlWindow::valid() and set the same transformation.  If you
+  don't your code may not work on other systems.  Depending on the OS,
+  and on whether overlays are real or simulated, the OpenGL context may
+  be the same or different between the overlay and main window.
+*/
+void fltk3::GlWindow::draw_overlay() {
+  FLTK3_OBJECT_VCALLS_WRAPPER(draw_overlay(), DrawOverlay)
+}
+
+#endif
+
+  /**
+  You \e \b must subclass fltk3::GlWindow and provide an implementation for 
+  draw().  You may also provide an implementation of draw_overlay()
+  if you want to draw into the overlay planes.  You can avoid
+  reinitializing the viewport and lights and other things by checking 
+  valid() at the start of draw() and only doing the
+  initialization if it is false.
+
+  The draw() method can <I>only</I> use OpenGL calls.  Do not
+  attempt to call X, any of the functions in <fltk3/draw.h>, or glX
+  directly.  Do not call gl_start() or gl_finish().
+
+  If double-buffering is enabled in the window, the back and front
+  buffers are swapped after this function is completed.
+*/
+void fltk3::GlWindow::draw() {
+  FLTK3_OBJECT_VCALLS_WRAPPER(draw(), Draw)
+  fltk3::fatal("fltk3::GlWindow::draw() *must* be overriden. Please refer to the documentation.");
+}
+
+
+/**
+ Handle some FLTK events as needed.
+ */
+int fltk3::GlWindow::handle(int event) 
+{
+  FLTK3_OBJECT_VCALLS_WRAPPER_RET(int, handle(event), Handle)
+  return Window::handle(event);
+}
+
+//
+// End of "$Id$".
+//

Deleted: branches/branch-3.0/src/fltk3gl/GlChoice.cxx

Deleted: branches/branch-3.0/src/fltk3gl/GlChoice.h

Deleted: branches/branch-3.0/src/fltk3gl/GlDevicePlugin.cxx

Deleted: branches/branch-3.0/src/fltk3gl/GlOverlay.cxx

Deleted: branches/branch-3.0/src/fltk3gl/GlWindow.cxx

Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

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