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

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_Overlay_Window.cxx 8198 2011-01-06 10:24:58Z manolo $"
00003 //
00004 // Overlay window 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 
00035 // A window using double-buffering and able to draw an overlay
00036 // on top of that.  Uses the hardware to draw the overlay if
00037 // possible, otherwise it just draws in the front buffer.
00038 
00039 #include <config.h>
00040 #include <FL/Fl.H>
00041 #include <FL/Fl_Overlay_Window.H>
00042 #include <FL/fl_draw.H>
00043 #include <FL/x.H>
00044 
00045 void Fl_Overlay_Window::show() {
00046   Fl_Double_Window::show();
00047   if (overlay_ && overlay_ != this) overlay_->show();
00048 }
00049 
00050 void Fl_Overlay_Window::hide() {
00051   Fl_Double_Window::hide();
00052 }
00053 
00054 void Fl_Overlay_Window::flush() {
00055 #ifdef BOXX_BUGS
00056   if (overlay_ && overlay_ != this && overlay_->shown()) {
00057     // all drawing to windows hidden by overlay windows is ignored, fix this
00058     XUnmapWindow(fl_display, fl_xid(overlay_));
00059     Fl_Double_Window::flush(0);
00060     XMapWindow(fl_display, fl_xid(overlay_));
00061     return;
00062   }
00063 #endif
00064   int erase_overlay = (damage()&FL_DAMAGE_OVERLAY) | (overlay_ == this);
00065   clear_damage((uchar)(damage()&~FL_DAMAGE_OVERLAY));
00066   Fl_Double_Window::flush(erase_overlay);
00067   if (overlay_ == this) draw_overlay();
00068 }
00069 
00070 void Fl_Overlay_Window::resize(int X, int Y, int W, int H) {
00071   Fl_Double_Window::resize(X,Y,W,H);
00072   if (overlay_ && overlay_!=this) overlay_->resize(0,0,w(),h());
00073 }
00074 
00078 Fl_Overlay_Window::~Fl_Overlay_Window() {
00079   hide();
00080 //  delete overlay; this is done by ~Fl_Group
00081 }
00082 
00083 #if !HAVE_OVERLAY
00084 
00085 int Fl_Overlay_Window::can_do_overlay() {return 0;}
00086 
00093 void Fl_Overlay_Window::redraw_overlay() {
00094   overlay_ = this;
00095   clear_damage((uchar)(damage()|FL_DAMAGE_OVERLAY));
00096   Fl::damage(FL_DAMAGE_CHILD);
00097 }
00098 
00099 #else
00100 
00101 extern XVisualInfo *fl_find_overlay_visual();
00102 extern XVisualInfo *fl_overlay_visual;
00103 extern Colormap fl_overlay_colormap;
00104 extern unsigned long fl_transparent_pixel;
00105 static GC gc;   // the GC used by all X windows
00106 extern uchar fl_overlay; // changes how fl_color(x) works
00107 
00108 class _Fl_Overlay : public Fl_Window {
00109   friend class Fl_Overlay_Window;
00110   void flush();
00111   void show();
00112 public:
00113   _Fl_Overlay(int x, int y, int w, int h) :
00114     Fl_Window(x,y,w,h) {set_flag(INACTIVE);}
00115 };
00116 
00117 int Fl_Overlay_Window::can_do_overlay() {
00118   return fl_find_overlay_visual() != 0;
00119 }
00120 
00121 void _Fl_Overlay::show() {
00122   if (shown()) {Fl_Window::show(); return;}
00123   fl_background_pixel = int(fl_transparent_pixel);
00124   Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
00125   fl_background_pixel = -1;
00126   // find the outermost window to tell wm about the colormap:
00127   Fl_Window *w = window();
00128   for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
00129   XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
00130 }
00131 
00132 void _Fl_Overlay::flush() {
00133   fl_window = fl_xid(this);
00134   if (!gc) {
00135           gc = XCreateGC(fl_display, fl_xid(this), 0, 0);
00136   }
00137   fl_gc = gc;
00138 #if defined(FLTK_USE_CAIRO)
00139       if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately
00140 #endif
00141   fl_overlay = 1;
00142   Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent();
00143   Fl_X *myi = Fl_X::i(this);
00144   if (damage() != FL_DAMAGE_EXPOSE) XClearWindow(fl_display, fl_xid(this));
00145   fl_clip_region(myi->region); myi->region = 0;
00146   w->draw_overlay();
00147   fl_overlay = 0;
00148 }
00149 
00150 void Fl_Overlay_Window::redraw_overlay() {
00151   if (!fl_display) return; // this prevents fluid -c from opening display
00152   if (!overlay_) {
00153     if (can_do_overlay()) {
00154       Fl_Group::current(this);
00155       overlay_ = new _Fl_Overlay(0,0,w(),h());
00156       Fl_Group::current(0);
00157     } else {
00158       overlay_ = this;  // fake the overlay
00159     }
00160   }
00161   if (shown()) {
00162     if (overlay_ == this) {
00163       clear_damage(damage()|FL_DAMAGE_OVERLAY);
00164       Fl::damage(FL_DAMAGE_CHILD);
00165     } else if (!overlay_->shown())
00166       overlay_->show();
00167     else
00168       overlay_->redraw();
00169   }
00170 }
00171 
00172 #endif
00173 
00174 //
00175 // End of "$Id: Fl_Overlay_Window.cxx 8198 2011-01-06 10:24:58Z manolo $".
00176 //