fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_Gl_Overlay.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // OpenGL overlay code for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 #include <config.h>
00029 #if HAVE_GL
00030 
00031 #include <FL/Fl.H>
00032 #include <FL/x.H>
00033 #include "Fl_Gl_Choice.H"
00034 #include <FL/Fl_Gl_Window.H>
00035 #include <stdlib.h>
00036 
00037 #if !HAVE_GL_OVERLAY
00038 
00039 int Fl_Gl_Window::can_do_overlay() {return 0;}
00040 
00041 void Fl_Gl_Window::make_overlay() {overlay = this;}
00042 
00043 #else
00044 
00045 // Methods on Fl_Gl_Window that create an overlay window.  Because
00046 // many programs don't need the overlay, this is separated into this
00047 // source file so it is not linked in if not used.
00048 
00049 // Under X this is done by creating another window, of class _Fl_Gl_Overlay
00050 // which is a subclass of Fl_Gl_Window except it uses the overlay planes.
00051 // A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.
00052 
00053 // Under win32 another GLX context is created to draw into the overlay
00054 // and it is stored in the "overlay" pointer.
00055 
00056 // In both cases if overlay hardware is unavailable, the overlay is
00057 // "faked" by drawing into the main layers.  This is indicated by
00058 // setting overlay == this.
00059 
00060 #ifndef WIN32
00061 
00062 // X version
00063 
00064 extern XVisualInfo *fl_find_overlay_visual();
00065 extern XVisualInfo *fl_overlay_visual;
00066 extern Colormap fl_overlay_colormap;
00067 extern unsigned long fl_transparent_pixel;
00068 extern uchar fl_overlay;
00069 
00070 class _Fl_Gl_Overlay : public Fl_Gl_Window {
00071   void flush();
00072   void draw();
00073 public:
00074   void show();
00075   _Fl_Gl_Overlay(int x, int y, int w, int h) :
00076     Fl_Gl_Window(x,y,w,h) {
00077     set_flag(INACTIVE);
00078   }
00079 };
00080 
00081 void _Fl_Gl_Overlay::flush() {
00082   make_current();
00083 #ifdef BOXX_BUGS
00084   // The BoXX overlay is broken and you must not call swap-buffers. This
00085   // code will make it work, but we lose because machines that do support
00086   // double-buffered overlays will blink when they don't have to
00087   glDrawBuffer(GL_FRONT);
00088   draw();
00089 #else
00090   draw();
00091   swap_buffers();
00092 #endif
00093   glFlush();
00094   valid(1);
00095 }
00096 
00097 void _Fl_Gl_Overlay::draw() {
00098   if (!valid()) glClearIndex((GLfloat)fl_transparent_pixel);
00099   if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
00100   Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
00101   uchar save_valid = w->valid();
00102   w->valid(valid());
00103   fl_overlay = 1;
00104   w->draw_overlay();
00105   fl_overlay = 0;
00106   valid(w->valid());
00107   w->valid(save_valid);
00108 }
00109 
00110 void _Fl_Gl_Overlay::show() {
00111   if (!shown()) {
00112     fl_background_pixel = int(fl_transparent_pixel);
00113     Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
00114     fl_background_pixel = -1;
00115     // find the outermost window to tell wm about the colormap:
00116     Fl_Window *w = window();
00117     for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
00118     XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
00119     context(fl_create_gl_context(fl_overlay_visual), 1);
00120     valid(0);
00121   }
00122   Fl_Gl_Window::show();
00123 }
00124 
00125 int Fl_Gl_Window::can_do_overlay() {
00126   return fl_find_overlay_visual() != 0;
00127 }
00128 
00129 void Fl_Gl_Window::make_overlay() {
00130   if (overlay) return;
00131   if (can_do_overlay()) {
00132     _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
00133     overlay = o;
00134     add(*o);
00135     o->show();
00136   } else {
00137     overlay = this; // fake the overlay
00138   }
00139 }
00140 
00141 #else
00142 
00143 // WIN32 version:
00144 
00145 //static COLORREF *palette;
00146 extern int fl_overlay_depth;
00147 
00148 void Fl_Gl_Window::make_overlay() {
00149   if (overlay) return;
00150 
00151   GLContext context = fl_create_gl_context(this, g, 1);
00152   if (!context) {overlay = this; return;} // fake the overlay
00153 
00154   HDC hdc = Fl_X::i(this)->private_dc;
00155   overlay = context;
00156   LAYERPLANEDESCRIPTOR pfd;
00157   wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd);
00158   if (!pfd.iPixelType) {
00159     ; // full-color overlay
00160   } else {
00161     fl_overlay_depth = pfd.cColorBits; // used by gl_color()
00162     if (fl_overlay_depth > 8) fl_overlay_depth = 8;
00163     COLORREF palette[256];
00164     int n = (1<<fl_overlay_depth)-1;
00165     // copy all colors except #0 into the overlay palette:
00166     for (int i = 0; i <= n; i++) {
00167       uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
00168       palette[i] = RGB(r,g,b);
00169     }
00170     // always provide black & white in the last 2 pixels:
00171     if (fl_overlay_depth < 8) {
00172       palette[n-1] = RGB(0,0,0);
00173       palette[n] = RGB(255,255,255);
00174     }
00175     // and use it:
00176     wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
00177     wglRealizeLayerPalette(hdc, 1, TRUE);
00178   }
00179   valid(0);
00180   return;
00181 }
00182 
00183 int Fl_Gl_Window::can_do_overlay() {
00184   if (!g) {
00185     g = Fl_Gl_Choice::find(mode_,alist);
00186     if (!g) return 0;
00187   }
00188   return (g->pfd.bReserved & 15) != 0;
00189 }
00190 
00192 #endif
00193 
00194 #endif
00195 
00196 void Fl_Gl_Window::redraw_overlay() {
00197   if (!shown()) return;
00198   make_overlay();
00199 #ifdef __APPLE__
00200   redraw();
00201 #else
00202 #ifndef WIN32
00203   if (overlay != this)
00204     ((Fl_Gl_Window*)overlay)->redraw();
00205   else
00206 #endif
00207     damage(FL_DAMAGE_OVERLAY);
00208 #endif
00209 }
00210 
00211 void Fl_Gl_Window::make_overlay_current() {
00212   make_overlay();
00213 #ifdef __APPLE__
00214   // this is not very useful, but unfortunately, Apple decided
00215   // that front buffer drawing can no longer (OS X 10.4) be 
00216   // supported on their platforms.
00217   make_current();
00218 #else
00219 #if HAVE_GL_OVERLAY
00220   if (overlay != this) {
00221 #ifdef WIN32
00222     fl_set_gl_context(this, (GLContext)overlay);
00223 //  if (fl_overlay_depth)
00224 //    wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
00225 #else
00226     ((Fl_Gl_Window*)overlay)->make_current();
00227 #endif
00228   } else
00229 #endif
00230     glDrawBuffer(GL_FRONT);
00231 #endif
00232 }
00234 void Fl_Gl_Window::hide_overlay() {
00235 #if HAVE_GL_OVERLAY
00236 #ifdef WIN32
00237   // nothing needs to be done?  Or should it be erased?
00238 #else
00239   if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
00240 #endif
00241 #endif
00242 }
00243 
00244 #endif
00245 
00246 //
00247 // End of "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $".
00248 //