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_Device_Plugin.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_Gl_Device_Plugin.cxx 7715 2010-10-11 18:10:32Z greg.ercolano $"
00003 //
00004 // implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 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 to:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 #include <config.h>
00029 #include <FL/Fl_Printer.H>
00030 #include <FL/Fl_Gl_Window.H>
00031 #include "Fl_Gl_Choice.H"
00032 #include "FL/Fl.H"
00033 #ifndef __APPLE__
00034 #include "FL/fl_draw.H"
00035 #endif
00036 
00037 #if defined(__APPLE__)
00038 static void imgProviderReleaseData (void *info, const void *data, size_t size)
00039 {
00040   free((void *)data);
00041 }
00042 #endif
00043 
00044 static void print_gl_window(Fl_Gl_Window *glw, int x, int y, int height)
00045 {
00046 #ifdef WIN32
00047   HDC save_gc = fl_gc;
00048   const int bytesperpixel = 3;
00049 #elif defined(__APPLE__)
00050   CGContextRef save_gc = fl_gc;
00051   const int bytesperpixel = 4;
00052 #else
00053   _XGC *save_gc = fl_gc;
00054   const int bytesperpixel = 3;
00055 #endif
00056   fl_gc = NULL;
00057 #ifdef WIN32
00058   Fl::check();
00059   Fl_Window *win = (Fl_Window*)glw;
00060   while( win->window() ) win = win->window();
00061   win->redraw();
00062   Fl::check();
00063   glw->make_current();
00064 #else
00065   glw->make_current();
00066   glw->redraw();
00067   glFlush();
00068   Fl::check();
00069   glFinish();
00070 #endif
00071   // Read OpenGL context pixels directly.
00072   // For extra safety, save & restore OpenGL states that are changed
00073   glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
00074   glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
00075   glPixelStorei(GL_PACK_ROW_LENGTH, 0);
00076   glPixelStorei(GL_PACK_SKIP_ROWS, 0);
00077   glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
00078   // Read a block of pixels from the frame buffer
00079   int mByteWidth = glw->w() * bytesperpixel;                
00080   mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes
00081   uchar *baseAddress = (uchar*)malloc(mByteWidth * glw->h());
00082   glReadPixels(0, 0, glw->w(), glw->h(), 
00083 #ifdef WIN32
00084                GL_RGB, GL_UNSIGNED_BYTE,
00085 #elif defined(__APPLE__)
00086                GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
00087 #else // FIXME Linux/Unix
00088                GL_RGB, GL_UNSIGNED_BYTE,
00089 #endif
00090                baseAddress);
00091   glPopClientAttrib();
00092   fl_gc = save_gc;
00093 #if defined(__APPLE__)
00094 // kCGBitmapByteOrder32Host and CGBitmapInfo are supposed to arrive with 10.4
00095 // but some 10.4 don't have kCGBitmapByteOrder32Host, so we play a little #define game
00096 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
00097 #define kCGBitmapByteOrder32Host 0
00098 #define CGBitmapInfo CGImageAlphaInfo
00099 #elif ! defined(kCGBitmapByteOrder32Host)
00100 #ifdef __BIG_ENDIAN__
00101 #define kCGBitmapByteOrder32Host (4 << 12)
00102 #else    /* Little endian. */
00103 #define kCGBitmapByteOrder32Host (2 << 12)
00104 #endif
00105 #endif
00106   CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
00107   CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, mByteWidth * glw->h(), imgProviderReleaseData);
00108   CGImageRef image = CGImageCreate(glw->w(), glw->h(), 8, 8*bytesperpixel, mByteWidth, cSpace, 
00109                                    (CGBitmapInfo)(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host), 
00110                                    provider, NULL, false, kCGRenderingIntentDefault);
00111   if(image == NULL) return;
00112   CGContextSaveGState(fl_gc);
00113   CGContextTranslateCTM(fl_gc, 0, height);
00114   CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
00115   CGRect rect = { { x, height - y - glw->h() }, { glw->w(), glw->h() } };
00116   Fl_X::q_begin_image(rect, 0, 0, glw->w(), glw->h());
00117   CGContextDrawImage(fl_gc, rect, image);
00118   Fl_X::q_end_image();
00119   CGContextRestoreGState(fl_gc);
00120   CGImageRelease(image);
00121   CGColorSpaceRelease(cSpace);
00122   CGDataProviderRelease(provider);  
00123 #else
00124   fl_draw_image(baseAddress + (glw->h() - 1) * mByteWidth, x, y , glw->w(), glw->h(), bytesperpixel, - mByteWidth);
00125   free(baseAddress);
00126 #endif // __APPLE__
00127 }
00128 
00133 class Fl_Gl_Device_Plugin : public Fl_Device_Plugin {
00134 public:
00135   Fl_Gl_Device_Plugin() : Fl_Device_Plugin(name()) { }
00136   virtual const char *name() { return "opengl.device.fltk.org"; }
00137   virtual int print(Fl_Widget *w, int x, int y, int height) {
00138     Fl_Gl_Window *glw = w->as_gl_window();
00139     if (!glw) return 0;
00140     print_gl_window(glw, x, y, height);
00141     return 1; 
00142   }
00143 };
00144 
00145 static Fl_Gl_Device_Plugin Gl_Device_Plugin;
00146 
00147 // The purpose of this variable, used in Fl_Gl_Window.cxx, is only to force this file to be loaded
00148 // whenever Fl_Gl_Window.cxx is loaded, that is, whenever fltk_gl is.
00149 FL_EXPORT int fl_gl_load_plugin = 0;
00150 
00151 //
00152 // End of "$Id: Fl_Gl_Device_Plugin.cxx 7715 2010-10-11 18:10:32Z greg.ercolano $".
00153 //