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 Apps      FLTK Library      Forums      Links     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-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.