diff --git a/common/fltk/src/Fl.cxx b/common/fltk/src/Fl.cxx
new file mode 100644
index 0000000..900ff8f
--- /dev/null
+++ b/common/fltk/src/Fl.cxx
@@ -0,0 +1,2024 @@
+//
+// "$Id: Fl.cxx 8723 2011-05-23 16:49:02Z manolo $"
+//
+// Main event handling 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
+//
+
+
+// warning: the Apple Quartz version still uses some Quickdraw calls,
+//          mostly to get around the single active context in QD and
+//          to implement clipping. This should be changed into pure
+//          Quartz calls in the near future.
+#include <config.h>
+
+/* We require Windows 2000 features (e.g. VK definitions) */
+#if defined(WIN32)
+# if !defined(WINVER) || (WINVER < 0x0500)
+#  ifdef WINVER
+#   undef WINVER
+#  endif
+#  define WINVER 0x0500
+# endif
+# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
+#  ifdef _WIN32_WINNT
+#   undef _WIN32_WINNT
+#  endif
+#  define _WIN32_WINNT 0x0500
+# endif
+#endif
+
+// recent versions of MinGW warn: "Please include winsock2.h before windows.h",
+// hence we must include winsock2.h before FL/Fl.H (A.S. Dec. 2010, IMM May 2011)
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  include <winsock2.h>
+#endif
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Tooltip.H>
+#include <FL/x.H>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+#if defined(DEBUG) || defined(DEBUG_WATCH)
+#  include <stdio.h>
+#endif // DEBUG || DEBUG_WATCH
+
+#ifdef WIN32
+#  include <ole2.h>
+void fl_free_fonts(void);
+HBRUSH fl_brush_action(int action);
+void fl_cleanup_pens(void);
+void fl_release_dc(HWND,HDC);
+void fl_cleanup_dc_list(void);
+#elif defined(__APPLE__)
+extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle);
+#endif // WIN32
+
+//
+// Globals...
+//
+#if defined(__APPLE__) || defined(FL_DOXYGEN)
+const char *Fl_Mac_App_Menu::about = "About ";
+const char *Fl_Mac_App_Menu::print = "Print Front Window";
+const char *Fl_Mac_App_Menu::services = "Services";
+const char *Fl_Mac_App_Menu::hide = "Hide ";
+const char *Fl_Mac_App_Menu::hide_others = "Hide Others";
+const char *Fl_Mac_App_Menu::show = "Show All";
+const char *Fl_Mac_App_Menu::quit = "Quit ";
+#endif // __APPLE__
+#ifndef FL_DOXYGEN
+Fl_Widget	*Fl::belowmouse_,
+		*Fl::pushed_,
+		*Fl::focus_,
+		*Fl::selection_owner_;
+int		Fl::damage_,
+		Fl::e_number,
+		Fl::e_x,
+		Fl::e_y,
+		Fl::e_x_root,
+		Fl::e_y_root,
+		Fl::e_dx,
+		Fl::e_dy,
+		Fl::e_state,
+		Fl::e_clicks,
+		Fl::e_is_click,
+		Fl::e_keysym,
+                Fl::e_original_keysym,
+		Fl::scrollbar_size_ = 16;
+
+char		*Fl::e_text = (char *)"";
+int		Fl::e_length;
+
+Fl_Event_Dispatch Fl::e_dispatch = 0;
+
+unsigned char   Fl::options_[] = { 0, 0 };
+unsigned char   Fl::options_read_ = 0;
+
+
+Fl_Window *fl_xfocus;	// which window X thinks has focus
+Fl_Window *fl_xmousewin;// which window X thinks has FL_ENTER
+Fl_Window *Fl::grab_;	// most recent Fl::grab()
+Fl_Window *Fl::modal_;	// topmost modal() window
+
+#endif // FL_DOXYGEN
+
+//
+// 'Fl::version()' - Return the API version number...
+//
+
+double
+/**
+  Returns the compiled-in value of the FL_VERSION constant. This
+  is useful for checking the version of a shared library.
+*/
+Fl::version() {
+  return FL_VERSION;
+}
+
+/**
+  Gets the default scrollbar size used by
+  Fl_Browser_,
+  Fl_Help_View,
+  Fl_Scroll, and
+  Fl_Text_Display widgets.
+  \returns The default size for widget scrollbars, in pixels.
+*/
+int Fl::scrollbar_size() {
+  return scrollbar_size_;
+}
+
+/**
+  Sets the default scrollbar size that is used by the
+  Fl_Browser_,
+  Fl_Help_View,
+  Fl_Scroll, and
+  Fl_Text_Display widgets.
+  \param[in] W The new default size for widget scrollbars, in pixels.
+*/
+void Fl::scrollbar_size(int W) {
+  scrollbar_size_ = W;
+}
+
+
+/** Returns whether or not the mouse event is inside the given rectangle.
+
+    Returns non-zero if the current Fl::event_x() and Fl::event_y()
+    put it inside the given arbitrary bounding box.
+
+    You should always call this rather than doing your own comparison
+    so you are consistent about edge effects.
+
+    To find out, whether the event is inside a child widget of the
+    current window, you can use Fl::event_inside(const Fl_Widget *).
+
+    \param[in] xx,yy,ww,hh	bounding box
+    \return			non-zero, if mouse event is inside
+*/
+int Fl::event_inside(int xx,int yy,int ww,int hh) /*const*/ {
+  int mx = e_x - xx;
+  int my = e_y - yy;
+  return (mx >= 0 && mx < ww && my >= 0 && my < hh);
+}
+
+/** Returns whether or not the mouse event is inside a given child widget.
+
+    Returns non-zero if the current Fl::event_x() and Fl::event_y()
+    put it inside the given child widget's bounding box.
+
+    This method can only be used to check whether the mouse event is
+    inside a \b child widget of the window that handles the event, and
+    there must not be an intermediate subwindow (i.e. the widget must
+    not be inside a subwindow of the current window). However, it is
+    valid if the widget is inside a nested Fl_Group.
+
+    You must not use it with the window itself as the \p o argument
+    in a window's handle() method.
+
+    \note The mentioned restrictions are necessary, because this method
+    does not transform coordinates of child widgets, and thus the given
+    widget \p o must be within the \e same window that is handling the
+    current event. Otherwise the results are undefined.
+
+    You should always call this rather than doing your own comparison
+    so you are consistent about edge effects.
+
+    \see Fl::event_inside(int, int, int, int)
+
+    \param[in] o	child widget to be tested
+    \return		non-zero, if mouse event is inside the widget
+*/
+int Fl::event_inside(const Fl_Widget *o) /*const*/ {
+  int mx = e_x - o->x();
+  int my = e_y - o->y();
+  return (mx >= 0 && mx < o->w() && my >= 0 && my < o->h());
+}
+
+//
+//
+// timer support
+//
+
+#ifdef WIN32
+
+// implementation in Fl_win32.cxx
+
+#elif defined(__APPLE__)
+
+// implementation in Fl_mac.cxx
+
+#else
+
+//
+// X11 timers
+//
+
+
+////////////////////////////////////////////////////////////////////////
+// Timeouts are stored in a sorted list (*first_timeout), so only the
+// first one needs to be checked to see if any should be called.
+// Allocated, but unused (free) Timeout structs are stored in another
+// linked list (*free_timeout).
+
+struct Timeout {
+  double time;
+  void (*cb)(void*);
+  void* arg;
+  Timeout* next;
+};
+static Timeout* first_timeout, *free_timeout;
+
+#include <sys/time.h>
+
+// I avoid the overhead of getting the current time when we have no
+// timeouts by setting this flag instead of getting the time.
+// In this case calling elapse_timeouts() does nothing, but records
+// the current time, and the next call will actually elapse time.
+static char reset_clock = 1;
+
+static void elapse_timeouts() {
+  static struct timeval prevclock;
+  struct timeval newclock;
+  gettimeofday(&newclock, NULL);
+  double elapsed = newclock.tv_sec - prevclock.tv_sec +
+    (newclock.tv_usec - prevclock.tv_usec)/1000000.0;
+  prevclock.tv_sec = newclock.tv_sec;
+  prevclock.tv_usec = newclock.tv_usec;
+  if (reset_clock) {
+    reset_clock = 0;
+  } else if (elapsed > 0) {
+    for (Timeout* t = first_timeout; t; t = t->next) t->time -= elapsed;
+  }
+}
+
+// Continuously-adjusted error value, this is a number <= 0 for how late
+// we were at calling the last timeout. This appears to make repeat_timeout
+// very accurate even when processing takes a significant portion of the
+// time interval:
+static double missed_timeout_by;
+
+void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
+  elapse_timeouts();
+  repeat_timeout(time, cb, argp);
+}
+
+void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
+  time += missed_timeout_by; if (time < -.05) time = 0;
+  Timeout* t = free_timeout;
+  if (t) {
+      free_timeout = t->next;
+  } else {
+      t = new Timeout;
+  }
+  t->time = time;
+  t->cb = cb;
+  t->arg = argp;
+  // insert-sort the new timeout:
+  Timeout** p = &first_timeout;
+  while (*p && (*p)->time <= time) p = &((*p)->next);
+  t->next = *p;
+  *p = t;
+}
+
+/**
+  Returns true if the timeout exists and has not been called yet.
+*/
+int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) {
+  for (Timeout* t = first_timeout; t; t = t->next)
+    if (t->cb == cb && t->arg == argp) return 1;
+  return 0;
+}
+
+/**
+  Removes a timeout callback. It is harmless to remove a timeout
+  callback that no longer exists.
+
+  \note	This version removes all matching timeouts, not just the first one.
+	This may change in the future.
+*/
+void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) {
+  for (Timeout** p = &first_timeout; *p;) {
+    Timeout* t = *p;
+    if (t->cb == cb && (t->arg == argp || !argp)) {
+      *p = t->next;
+      t->next = free_timeout;
+      free_timeout = t;
+    } else {
+      p = &(t->next);
+    }
+  }
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////
+// Checks are just stored in a list. They are called in the reverse
+// order that they were added (this may change in the future).
+// This is a bit messy because I want to allow checks to be added,
+// removed, and have wait() called from inside them. To do this
+// next_check points at the next unprocessed one for the outermost
+// call to Fl::wait().
+
+struct Check {
+  void (*cb)(void*);
+  void* arg;
+  Check* next;
+};
+static Check *first_check, *next_check, *free_check;
+
+/**
+  FLTK will call this callback just before it flushes the display and
+  waits for events.  This is different than an idle callback because it
+  is only called once, then FLTK calls the system and tells it not to
+  return until an event happens.
+
+  This can be used by code that wants to monitor the
+  application's state, such as to keep a display up to date. The
+  advantage of using a check callback is that it is called only when no
+  events are pending. If events are coming in quickly, whole blocks of
+  them will be processed before this is called once. This can save
+  significant time and avoid the application falling behind the events.
+
+  Sample code:
+
+  \code
+  bool state_changed; // anything that changes the display turns this on
+
+  void callback(void*) {
+   if (!state_changed) return;
+   state_changed = false;
+   do_expensive_calculation();
+   widget-&gt;redraw();
+  }
+
+  main() {
+   Fl::add_check(callback);
+   return Fl::run();
+  }
+  \endcode
+*/
+void Fl::add_check(Fl_Timeout_Handler cb, void *argp) {
+  Check* t = free_check;
+  if (t) free_check = t->next;
+  else t = new Check;
+  t->cb = cb;
+  t->arg = argp;
+  t->next = first_check;
+  if (next_check == first_check) next_check = t;
+  first_check = t;
+}
+
+/**
+  Removes a check callback. It is harmless to remove a check
+  callback that no longer exists.
+*/
+void Fl::remove_check(Fl_Timeout_Handler cb, void *argp) {
+  for (Check** p = &first_check; *p;) {
+    Check* t = *p;
+    if (t->cb == cb && t->arg == argp) {
+      if (next_check == t) next_check = t->next;
+      *p = t->next;
+      t->next = free_check;
+      free_check = t;
+    } else {
+      p = &(t->next);
+    }
+  }
+}
+
+/**
+  Returns 1 if the check exists and has not been called yet, 0 otherwise.
+*/
+int Fl::has_check(Fl_Timeout_Handler cb, void *argp) {
+  for (Check** p = &first_check; *p;) {
+    Check* t = *p;
+    if (t->cb == cb && t->arg == argp) {
+      return 1;
+    } else {
+      p = &(t->next);
+    }
+  }
+  return 0;
+}
+
+static void run_checks()
+{
+  // checks are a bit messy so that add/remove and wait may be called
+  // from inside them without causing an infinite loop:
+  if (next_check == first_check) {
+    while (next_check) {
+      Check* checkp = next_check;
+      next_check = checkp->next;
+      (checkp->cb)(checkp->arg);
+    }
+    next_check = first_check;
+  }
+}
+
+#ifndef WIN32
+static char in_idle;
+#endif
+
+////////////////////////////////////////////////////////////////
+// wait/run/check/ready:
+
+void (*Fl::idle)(); // see Fl::add_idle.cxx for the add/remove functions
+
+extern int fl_ready(); // in Fl_<platform>.cxx
+extern int fl_wait(double time); // in Fl_<platform>.cxx
+
+/**
+  See int Fl::wait()
+*/
+double Fl::wait(double time_to_wait) {
+  // delete all widgets that were listed during callbacks
+  do_widget_deletion();
+
+#ifdef WIN32
+
+  return fl_wait(time_to_wait);
+
+#elif defined(__APPLE__)
+
+  run_checks();
+  if (idle) {
+    if (!in_idle) {
+      in_idle = 1;
+      idle();
+      in_idle = 0;
+    }
+    // the idle function may turn off idle, we can then wait:
+    if (idle) time_to_wait = 0.0;
+  }
+  return fl_mac_flush_and_wait(time_to_wait, in_idle);
+
+#else
+
+  if (first_timeout) {
+    elapse_timeouts();
+    Timeout *t;
+    while ((t = first_timeout)) {
+      if (t->time > 0) break;
+      // The first timeout in the array has expired.
+      missed_timeout_by = t->time;
+      // We must remove timeout from array before doing the callback:
+      void (*cb)(void*) = t->cb;
+      void *argp = t->arg;
+      first_timeout = t->next;
+      t->next = free_timeout;
+      free_timeout = t;
+      // Now it is safe for the callback to do add_timeout:
+      cb(argp);
+    }
+  } else {
+    reset_clock = 1; // we are not going to check the clock
+  }
+  run_checks();
+//  if (idle && !fl_ready()) {
+  if (idle) {
+    if (!in_idle) {
+      in_idle = 1;
+      idle();
+      in_idle = 0;
+    }
+    // the idle function may turn off idle, we can then wait:
+    if (idle) time_to_wait = 0.0;
+  }
+  if (first_timeout && first_timeout->time < time_to_wait)
+    time_to_wait = first_timeout->time;
+  if (time_to_wait <= 0.0) {
+    // do flush second so that the results of events are visible:
+    int ret = fl_wait(0.0);
+    flush();
+    return ret;
+  } else {
+    // do flush first so that user sees the display:
+    flush();
+    if (idle && !in_idle) // 'idle' may have been set within flush()
+      time_to_wait = 0.0;
+    return fl_wait(time_to_wait);
+  }
+#endif
+}
+
+#define FOREVER 1e20
+
+/**
+  As long as any windows are displayed this calls Fl::wait()
+  repeatedly.  When all the windows are closed it returns zero
+  (supposedly it would return non-zero on any errors, but FLTK calls
+  exit directly for these).  A normal program will end main()
+  with return Fl::run();.
+*/
+int Fl::run() {
+  while (Fl_X::first) wait(FOREVER);
+  return 0;
+}
+
+#ifdef WIN32
+
+// Function to initialize COM/OLE for usage. This must be done only once.
+// We define a flag to register whether we called it:
+static char oleInitialized = 0;
+
+// This calls the Windows function OleInitialize() exactly once.
+void fl_OleInitialize() {
+  if (!oleInitialized) {
+    OleInitialize(0L);
+    oleInitialized = 1;
+  }
+}
+
+// This calls the Windows function OleUninitialize() only, if
+// OleInitialize has been called before.
+void fl_OleUninitialize() {
+  if (oleInitialized) {
+    OleUninitialize();
+    oleInitialized = 0;
+  }
+}
+
+class Fl_Win32_At_Exit {
+public:
+  Fl_Win32_At_Exit() { }
+  ~Fl_Win32_At_Exit() {
+    fl_free_fonts();        // do some WIN32 cleanup
+    fl_cleanup_pens();
+    fl_OleUninitialize();
+    fl_brush_action(1);
+    fl_cleanup_dc_list();
+  }
+};
+static Fl_Win32_At_Exit win32_at_exit;
+#endif
+
+
+
+/**
+  Waits until "something happens" and then returns.  Call this
+  repeatedly to "run" your program.  You can also check what happened
+  each time after this returns, which is quite useful for managing
+  program state.
+
+  What this really does is call all idle callbacks, all elapsed
+  timeouts, call Fl::flush() to get the screen to update, and
+  then wait some time (zero if there are idle callbacks, the shortest of
+  all pending timeouts, or infinity), for any events from the user or
+  any Fl::add_fd() callbacks.  It then handles the events and
+  calls the callbacks and then returns.
+
+  The return value of Fl::wait() is non-zero if there are any
+  visible windows - this may change in future versions of FLTK.
+
+  Fl::wait(time) waits a maximum of \e time seconds.
+  <i>It can return much sooner if something happens.</i>
+
+  The return value is positive if an event or fd happens before the
+  time elapsed.  It is zero if nothing happens (on Win32 this will only
+  return zero if \e time is zero).  It is negative if an error
+  occurs (this will happen on UNIX if a signal happens).
+*/
+int Fl::wait() {
+  if (!Fl_X::first) return 0;
+  wait(FOREVER);
+  return Fl_X::first != 0; // return true if there is a window
+}
+
+/**
+  Same as Fl::wait(0).  Calling this during a big calculation
+  will keep the screen up to date and the interface responsive:
+
+  \code
+  while (!calculation_done()) {
+  calculate();
+  Fl::check();
+  if (user_hit_abort_button()) break;
+  }
+  \endcode
+
+  This returns non-zero if any windows are displayed, and 0 if no
+  windows are displayed (this is likely to change in future versions of
+  FLTK).
+*/
+int Fl::check() {
+  wait(0.0);
+  return Fl_X::first != 0; // return true if there is a window
+}
+
+/**
+  This is similar to Fl::check() except this does \e not
+  call Fl::flush() or any callbacks, which is useful if your
+  program is in a state where such callbacks are illegal.  This returns
+  true if Fl::check() would do anything (it will continue to
+  return true until you call Fl::check() or Fl::wait()).
+
+  \code
+  while (!calculation_done()) {
+    calculate();
+    if (Fl::ready()) {
+      do_expensive_cleanup();
+      Fl::check();
+      if (user_hit_abort_button()) break;
+    }
+  }
+  \endcode
+*/
+int Fl::ready() {
+#if ! defined( WIN32 )  &&  ! defined(__APPLE__)
+  if (first_timeout) {
+    elapse_timeouts();
+    if (first_timeout->time <= 0) return 1;
+  } else {
+    reset_clock = 1;
+  }
+#endif
+  return fl_ready();
+}
+
+////////////////////////////////////////////////////////////////
+// Window list management:
+
+#ifndef FL_DOXYGEN
+Fl_X* Fl_X::first;
+#endif
+
+Fl_Window* fl_find(Window xid) {
+  Fl_X *window;
+  for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next)
+#if defined(WIN32) || defined(USE_X11)
+   if (window->xid == xid)
+#elif defined(__APPLE_QUARTZ__)
+   if (window->xid == xid && !window->w->window())
+#else
+# error unsupported platform
+#endif // __APPLE__
+	{
+      if (window != Fl_X::first && !Fl::modal()) {
+	// make this window be first to speed up searches
+	// this is not done if modal is true to avoid messing up modal stack
+	*pp = window->next;
+	window->next = Fl_X::first;
+	Fl_X::first = window;
+      }
+      return window->w;
+    }
+  return 0;
+}
+
+/**
+  Returns the first top-level window in the list of shown() windows.  If
+  a modal() window is shown this is the top-most modal window, otherwise
+  it is the most recent window to get an event.
+*/
+Fl_Window* Fl::first_window() {
+  Fl_X* i = Fl_X::first;
+  return i ? i->w : 0;
+}
+
+/**
+  Returns the next top-level window in the list of shown() windows.
+  You can use this call to iterate through all the windows that are shown().
+  \param[in] window	must be shown and not NULL
+*/
+Fl_Window* Fl::next_window(const Fl_Window* window) {
+  Fl_X* i = Fl_X::i(window)->next;
+  return i ? i->w : 0;
+}
+
+/**
+ Sets the window that is returned by first_window().
+ The window is removed from wherever it is in the
+ list and inserted at the top.  This is not done if Fl::modal()
+ is on or if the window is not shown(). Because the first window
+ is used to set the "parent" of modal windows, this is often
+ useful.
+ */
+void Fl::first_window(Fl_Window* window) {
+  if (!window || !window->shown()) return;
+  fl_find( Fl_X::i(window)->xid );
+}
+
+/**
+  Redraws all widgets.
+*/
+void Fl::redraw() {
+  for (Fl_X* i = Fl_X::first; i; i = i->next) i->w->redraw();
+}
+
+/**
+  Causes all the windows that need it to be redrawn and graphics forced
+  out through the pipes.
+
+  This is what wait() does before looking for events.
+
+  Note: in multi-threaded applications you should only call Fl::flush()
+  from the main thread. If a child thread needs to trigger a redraw event,
+  it should instead call Fl::awake() to get the main thread to process the
+  event queue.
+*/
+void Fl::flush() {
+  if (damage()) {
+    damage_ = 0;
+    for (Fl_X* i = Fl_X::first; i; i = i->next) {
+      if (i->wait_for_expose) {damage_ = 1; continue;}
+      Fl_Window* wi = i->w;
+      if (!wi->visible_r()) continue;
+      if (wi->damage()) {i->flush(); wi->clear_damage();}
+      // destroy damage regions for windows that don't use them:
+      if (i->region) {XDestroyRegion(i->region); i->region = 0;}
+    }
+  }
+#if defined(USE_X11)
+  if (fl_display) XFlush(fl_display);
+#elif defined(WIN32)
+  GdiFlush();
+#elif defined (__APPLE_QUARTZ__)
+  if (fl_gc)
+    CGContextFlush(fl_gc);
+#else
+# error unsupported platform
+#endif
+}
+
+
+////////////////////////////////////////////////////////////////
+// Event handlers:
+
+
+struct handler_link {
+  int (*handle)(int);
+  handler_link *next;
+};
+
+
+static handler_link *handlers = 0;
+
+
+/**
+  Install a function to parse unrecognized events.  If FLTK cannot
+  figure out what to do with an event, it calls each of these functions
+  (most recent first) until one of them returns non-zero.  If none of
+  them returns non-zero then the event is ignored.  Events that cause
+  this to be called are:
+
+  - FL_SHORTCUT events that are not recognized by any widget.
+    This lets you provide global shortcut keys.
+  - System events that FLTK does not recognize.  See fl_xevent.
+  - \e Some other events when the widget FLTK selected returns
+    zero from its handle() method.  Exactly which ones may change
+    in future versions, however.
+
+ \see Fl::remove_handler(Fl_Event_Handler)
+ \see Fl::event_dispatch(Fl_Event_Dispatch d)
+ \see Fl::handle(int, Fl_Window*)
+*/
+void Fl::add_handler(Fl_Event_Handler ha) {
+  handler_link *l = new handler_link;
+  l->handle = ha;
+  l->next = handlers;
+  handlers = l;
+}
+
+
+/**
+ Removes a previously added event handler.
+ \see Fl::handle(int, Fl_Window*)
+*/
+void Fl::remove_handler(Fl_Event_Handler ha) {
+  handler_link *l, *p;
+
+  // Search for the handler in the list...
+  for (l = handlers, p = 0; l && l->handle != ha; p = l, l = l->next);
+
+  if (l) {
+    // Found it, so remove it from the list...
+    if (p) p->next = l->next;
+    else handlers = l->next;
+
+    // And free the record...
+    delete l;
+  }
+}
+
+int (*fl_local_grab)(int); // used by fl_dnd.cxx
+
+static int send_handlers(int e) {
+  for (const handler_link *hl = handlers; hl; hl = hl->next)
+    if (hl->handle(e)) return 1;
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Widget* fl_oldfocus; // kludge for Fl_Group...
+
+/**
+    Sets the widget that will receive FL_KEYBOARD events.
+
+    If you change Fl::focus(), the previous widget and all
+    parents (that don't contain the new widget) are sent FL_UNFOCUS
+    events.  Changing the focus does \e not send FL_FOCUS to
+    this or any widget, because sending FL_FOCUS is supposed to
+    \e test if the widget wants the focus (by it returning non-zero from
+    handle()).
+
+    \see Fl_Widget::take_focus()
+*/
+void Fl::focus(Fl_Widget *o) {
+  if (o && !o->visible_focus()) return;
+  if (grab()) return; // don't do anything while grab is on
+  Fl_Widget *p = focus_;
+  if (o != p) {
+    Fl::compose_reset();
+    focus_ = o;
+    // make sure that fl_xfocus is set to the top level window
+    // of this widget, or fl_fix_focus will clear our focus again
+    if (o) {
+      Fl_Window *win = 0, *w1 = o->as_window();
+      if (!w1) w1 = o->window();
+      while (w1) { win=w1; w1=win->window(); }
+      if (win) {
+#ifdef __APPLE__
+	if (fl_xfocus != win) {
+	  Fl_X *x = Fl_X::i(win);
+	  if (x) x->set_key_window();
+	  }
+#endif
+	fl_xfocus = win;
+	}
+    }
+    // take focus from the old focused window
+    fl_oldfocus = 0;
+    int old_event = e_number;
+    e_number = FL_UNFOCUS;
+    for (; p; p = p->parent()) {
+      p->handle(FL_UNFOCUS);
+      fl_oldfocus = p;
+    }
+    e_number = old_event;
+  }
+}
+
+static char dnd_flag = 0; // make 'belowmouse' send DND_LEAVE instead of LEAVE
+
+/**
+    Sets the widget that is below the mouse.  This is for
+    highlighting buttons.  It is not used to send FL_PUSH or
+    FL_MOVE directly, for several obscure reasons, but those events
+    typically go to this widget.  This is also the first widget tried for
+    FL_SHORTCUT events.
+
+    If you change the belowmouse widget, the previous one and all
+    parents (that don't contain the new widget) are sent FL_LEAVE
+    events.  Changing this does \e not send FL_ENTER to this
+    or any widget, because sending FL_ENTER is supposed to \e test
+    if the widget wants the mouse (by it returning non-zero from
+    handle()).
+*/
+void Fl::belowmouse(Fl_Widget *o) {
+  if (grab()) return; // don't do anything while grab is on
+  Fl_Widget *p = belowmouse_;
+  if (o != p) {
+    belowmouse_ = o;
+    int old_event = e_number;
+    e_number = dnd_flag ? FL_DND_LEAVE : FL_LEAVE;
+    for (; p && !p->contains(o); p = p->parent()) {
+      p->handle(e_number);
+    }
+    e_number = old_event;
+  }
+}
+
+/**
+    Sets the widget that is being pushed. FL_DRAG or
+    FL_RELEASE (and any more FL_PUSH) events will be sent to
+    this widget.
+
+    If you change the pushed widget, the previous one and all parents
+    (that don't contain the new widget) are sent FL_RELEASE
+    events.  Changing this does \e not send FL_PUSH to this
+    or any widget, because sending FL_PUSH is supposed to \e test
+    if the widget wants the mouse (by it returning non-zero from
+    handle()).
+*/
+ void Fl::pushed(Fl_Widget *o) {
+  pushed_ = o;
+}
+
+static void nothing(Fl_Widget *) {}
+void (*Fl_Tooltip::enter)(Fl_Widget *) = nothing;
+void (*Fl_Tooltip::exit)(Fl_Widget *) = nothing;
+
+// Update modal(), focus() and other state according to system state,
+// and send FL_ENTER, FL_LEAVE, FL_FOCUS, and/or FL_UNFOCUS events.
+// This is the only function that produces these events in response
+// to system activity.
+// This is called whenever a window is added or hidden, and whenever
+// X says the focus or mouse window have changed.
+
+void fl_fix_focus() {
+#ifdef DEBUG
+  puts("fl_fix_focus();");
+#endif // DEBUG
+
+  if (Fl::grab()) return; // don't do anything while grab is on.
+
+  // set focus based on Fl::modal() and fl_xfocus
+  Fl_Widget* w = fl_xfocus;
+  if (w) {
+    int saved = Fl::e_keysym;
+    if (Fl::e_keysym < (FL_Button + FL_LEFT_MOUSE) ||
+        Fl::e_keysym > (FL_Button + FL_RIGHT_MOUSE))
+      Fl::e_keysym = 0; // make sure widgets don't think a keystroke moved focus
+    while (w->parent()) w = w->parent();
+    if (Fl::modal()) w = Fl::modal();
+    if (!w->contains(Fl::focus()))
+      if (!w->take_focus()) Fl::focus(w);
+    Fl::e_keysym = saved;
+  } else
+    Fl::focus(0);
+
+// MRS: Originally we checked the button state, but a user reported that it
+//      broke click-to-focus in FLWM?!?
+//  if (!(Fl::event_state() & 0x7f00000 /*FL_BUTTONS*/)) {
+  if (!Fl::pushed()) {
+    // set belowmouse based on Fl::modal() and fl_xmousewin:
+    w = fl_xmousewin;
+    if (w) {
+      if (Fl::modal()) w = Fl::modal();
+      if (!w->contains(Fl::belowmouse())) {
+        int old_event = Fl::e_number;
+	w->handle(Fl::e_number = FL_ENTER);
+	Fl::e_number = old_event;
+	if (!w->contains(Fl::belowmouse())) Fl::belowmouse(w);
+      } else {
+	// send a FL_MOVE event so the enter/leave state is up to date
+	Fl::e_x = Fl::e_x_root-fl_xmousewin->x();
+	Fl::e_y = Fl::e_y_root-fl_xmousewin->y();
+        int old_event = Fl::e_number;
+	w->handle(Fl::e_number = FL_MOVE);
+	Fl::e_number = old_event;
+      }
+    } else {
+      Fl::belowmouse(0);
+      Fl_Tooltip::enter(0);
+    }
+  }
+}
+
+#if !(defined(WIN32) || defined(__APPLE__))
+extern Fl_Widget *fl_selection_requestor; // from Fl_x.cxx
+#endif
+
+// This function is called by ~Fl_Widget() and by Fl_Widget::deactivate()
+// and by Fl_Widget::hide().  It indicates that the widget does not want
+// to receive any more events, and also removes all global variables that
+// point at the widget.
+// I changed this from the 1.0.1 behavior, the older version could send
+// FL_LEAVE or FL_UNFOCUS events to the widget.  This appears to not be
+// desirable behavior and caused flwm to crash.
+
+void fl_throw_focus(Fl_Widget *o) {
+#ifdef DEBUG
+  printf("fl_throw_focus(o=%p)\n", o);
+#endif // DEBUG
+
+  if (o->contains(Fl::pushed())) Fl::pushed_ = 0;
+#if !(defined(WIN32) || defined(__APPLE__))
+  if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0;
+#endif
+  if (o->contains(Fl::belowmouse())) Fl::belowmouse_ = 0;
+  if (o->contains(Fl::focus())) Fl::focus_ = 0;
+  if (o == fl_xfocus) fl_xfocus = 0;
+  if (o == Fl_Tooltip::current()) Fl_Tooltip::current(0);
+  if (o == fl_xmousewin) fl_xmousewin = 0;
+  Fl_Tooltip::exit(o);
+  fl_fix_focus();
+}
+
+////////////////////////////////////////////////////////////////
+
+// Call to->handle(), but first replace the mouse x/y with the correct
+// values to account for nested windows. 'window' is the outermost
+// window the event was posted to by the system:
+static int send(int event, Fl_Widget* to, Fl_Window* window) {
+  int dx, dy;
+  int old_event = Fl::e_number;
+  if (window) {
+    dx = window->x();
+    dy = window->y();
+  } else {
+    dx = dy = 0;
+  }
+  for (const Fl_Widget* w = to; w; w = w->parent())
+    if (w->type()>=FL_WINDOW) {dx -= w->x(); dy -= w->y();}
+  int save_x = Fl::e_x; Fl::e_x += dx;
+  int save_y = Fl::e_y; Fl::e_y += dy;
+  int ret = to->handle(Fl::e_number = event);
+  Fl::e_number = old_event;
+  Fl::e_y = save_y;
+  Fl::e_x = save_x;
+  return ret;
+}
+
+
+/**
+ \brief Set a new event dispatch function.
+
+ The event dispatch function is called after native events are converted to
+ FLTK events, but before they are handled by FLTK. If the dispatch function
+ Fl_Event_Dispatch \p d is set, it is up to the dispatch function to call
+ Fl::handle_(int, Fl_Window*) or to ignore the event.
+
+ The dispatch function itself must return 0 if it ignored the event,
+ or non-zero if it used the event. If you call Fl::handle_(), then
+ this will return the correct value.
+
+ The event dispatch can be used to handle exceptions in FLTK events and
+ callbacks before they reach the native event handler:
+
+ \code
+ int myHandler(int e, Fl_Window *w) {
+   try {
+     return Fl::handle_(e, w);
+   } catch () {
+     ...
+   }
+ }
+
+ main() {
+   Fl::event_dispatch(myHandler);
+   ...
+   Fl::run();
+ }
+ \endcode
+
+ \param d new dispatch function, or NULL
+ \see Fl::add_handler(Fl_Event_Handler)
+ \see Fl::handle(int, Fl_Window*)
+ \see Fl::handle_(int, Fl_Window*)
+ */
+void Fl::event_dispatch(Fl_Event_Dispatch d)
+{
+  e_dispatch = d;
+}
+
+
+/**
+ \brief Return the current event dispatch function.
+ */
+Fl_Event_Dispatch Fl::event_dispatch()
+{
+  return e_dispatch;
+}
+
+
+/**
+ \brief Handle events from the window system.
+
+ This is called from the native event dispatch after native events have been
+ converted to FLTK notation. This function calls Fl::handle_(int, Fl_Window*)
+ unless the user sets a dispatch function. If a user dispatch function is set,
+ the user must make sure that Fl::handle_() is called, or the event will be
+ ignored.
+
+ \param e the event type (Fl::event_number() is not yet set)
+ \param window the window that caused this event
+ \return 0 if the event was not handled
+
+ \see Fl::add_handler(Fl_Event_Handler)
+ \see Fl::event_dispatch(Fl_Event_Dispatch)
+ */
+int Fl::handle(int e, Fl_Window* window)
+{
+  if (e_dispatch) {
+    return e_dispatch(e, window);
+  } else {
+    return handle_(e, window);
+  }
+}
+
+
+/**
+ \brief Handle events from the window system.
+
+ This function is called from the native event dispatch, unless the user sets
+ another dispatch function. In that case, the user dispatch function must
+ decide when to call Fl::handle_(int, Fl_Window*)
+
+ \param e the event type (Fl::event_number() is not yet set)
+ \param window the window that caused this event
+ \return 0 if the event was not handled
+
+ \see Fl::event_dispatch(Fl_Event_Dispatch)
+ */
+int Fl::handle_(int e, Fl_Window* window)
+{
+  e_number = e;
+  if (fl_local_grab) return fl_local_grab(e);
+
+  Fl_Widget* wi = window;
+
+  switch (e) {
+
+  case FL_CLOSE:
+    if ( grab() || (modal() && window != modal()) ) return 0;
+    wi->do_callback();
+    return 1;
+
+  case FL_SHOW:
+    wi->Fl_Widget::show(); // this calls Fl_Widget::show(), not Fl_Window::show()
+    return 1;
+
+  case FL_HIDE:
+    wi->Fl_Widget::hide(); // this calls Fl_Widget::hide(), not Fl_Window::hide()
+    return 1;
+
+  case FL_PUSH:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    if (grab()) wi = grab();
+    else if (modal() && wi != modal()) return 0;
+    pushed_ = wi;
+    Fl_Tooltip::current(wi);
+    if (send(e, wi, window)) return 1;
+    // raise windows that are clicked on:
+    window->show();
+    return 1;
+
+  case FL_DND_ENTER:
+  case FL_DND_DRAG:
+    dnd_flag = 1;
+    break;
+
+  case FL_DND_LEAVE:
+    dnd_flag = 1;
+    belowmouse(0);
+    dnd_flag = 0;
+    return 1;
+
+  case FL_DND_RELEASE:
+    wi = belowmouse();
+    break;
+
+  case FL_MOVE:
+  case FL_DRAG:
+    fl_xmousewin = window; // this should already be set, but just in case.
+    if (pushed()) {
+      wi = pushed();
+      if (grab()) wi = grab();
+      e_number = e = FL_DRAG;
+      break;
+    }
+    if (modal() && wi != modal()) wi = 0;
+    if (grab()) wi = grab();
+    { int ret;
+      Fl_Widget* pbm = belowmouse();
+#ifdef __APPLE__
+      if (fl_mac_os_version < 100500) {
+        // before 10.5, mouse moved events aren't sent to borderless windows such as tooltips
+	Fl_Window *tooltip = Fl_Tooltip::current_window();
+	int inside = 0;
+	if (tooltip && tooltip->shown() ) { // check if a tooltip window is currently opened
+	  // check if mouse is inside the tooltip
+	  inside = (Fl::event_x_root() >= tooltip->x() && Fl::event_x_root() < tooltip->x() + tooltip->w() &&
+	  Fl::event_y_root() >= tooltip->y() && Fl::event_y_root() < tooltip->y() + tooltip->h() );
+	}
+	// if inside, send event to tooltip window instead of background window
+	if (inside) ret = send(e, tooltip, window);
+	else ret = (wi && send(e, wi, window));
+      } else
+#endif
+      ret = (wi && send(e, wi, window));
+   if (pbm != belowmouse()) {
+#ifdef DEBUG
+      printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+      Fl_Tooltip::enter(belowmouse());
+    }
+    return ret;}
+
+  case FL_RELEASE: {
+//    printf("FL_RELEASE: window=%p, pushed() = %p, grab() = %p, modal() = %p\n",
+//           window, pushed(), grab(), modal());
+
+    if (grab()) {
+      wi = grab();
+      pushed_ = 0; // must be zero before callback is done!
+    } else if (pushed()) {
+      wi = pushed();
+      pushed_ = 0; // must be zero before callback is done!
+    } else if (modal() && wi != modal()) return 0;
+    int r = send(e, wi, window);
+    fl_fix_focus();
+    return r;}
+
+  case FL_UNFOCUS:
+    window = 0;
+  case FL_FOCUS:
+    fl_xfocus = window;
+    fl_fix_focus();
+    return 1;
+
+  case FL_KEYUP:
+    // Send the key-up to the current focus widget. This is not
+    // always the same widget that received the corresponding
+    // FL_KEYBOARD event because focus may have changed.
+    // Sending the KEYUP to the right KEYDOWN is possible, but
+    // would require that we track the KEYDOWN for every possible
+    // key stroke (users may hold down multiple keys!) and then
+    // make sure that the widget still exists before sending
+    // a KEYUP there. I believe that the current solution is
+    // "close enough".
+    for (wi = grab() ? grab() : focus(); wi; wi = wi->parent())
+      if (send(FL_KEYUP, wi, window)) return 1;
+    return 0;
+
+  case FL_KEYBOARD:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    Fl_Tooltip::enter((Fl_Widget*)0);
+
+    fl_xfocus = window; // this should not happen!  But maybe it does:
+
+    // Try it as keystroke, sending it to focus and all parents:
+    for (wi = grab() ? grab() : focus(); wi; wi = wi->parent())
+      if (send(FL_KEYBOARD, wi, window)) return 1;
+
+    // recursive call to try shortcut:
+    if (handle(FL_SHORTCUT, window)) return 1;
+
+    // and then try a shortcut with the case of the text swapped, by
+    // changing the text and falling through to FL_SHORTCUT case:
+    {unsigned char* c = (unsigned char*)event_text(); // cast away const
+    if (!isalpha(*c)) return 0;
+    *c = isupper(*c) ? tolower(*c) : toupper(*c);}
+    e_number = e = FL_SHORTCUT;
+
+  case FL_SHORTCUT:
+    if (grab()) {wi = grab(); break;} // send it to grab window
+
+    // Try it as shortcut, sending to mouse widget and all parents:
+    wi = belowmouse();
+    if (!wi) {
+      wi = modal();
+      if (!wi) wi = window;
+    } else if (wi->window() != first_window()) {
+      if (send(FL_SHORTCUT, first_window(), first_window())) return 1;
+    }
+
+    for (; wi; wi = wi->parent()) {
+      if (send(FL_SHORTCUT, wi, wi->window())) return 1;
+    }
+
+    // try using add_handle() functions:
+    if (send_handlers(FL_SHORTCUT)) return 1;
+
+    // make Escape key close windows:
+    if (event_key()==FL_Escape) {
+      wi = modal(); if (!wi) wi = window;
+      wi->do_callback();
+      return 1;
+    }
+
+    return 0;
+
+  case FL_ENTER:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    fl_xmousewin = window;
+    fl_fix_focus();
+    Fl_Tooltip::enter(belowmouse());
+    return 1;
+
+  case FL_LEAVE:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    if (!pushed_) {
+      belowmouse(0);
+      Fl_Tooltip::enter(0);
+    }
+    if (window == fl_xmousewin) {fl_xmousewin = 0; fl_fix_focus();}
+    return 1;
+
+  case FL_MOUSEWHEEL:
+    fl_xfocus = window; // this should not happen!  But maybe it does:
+
+    // Try sending it to the "grab" first
+    if (grab() && grab()!=modal() && grab()!=window) {
+      if (send(FL_MOUSEWHEEL, grab(), window)) return 1;
+    }
+    // Now try sending it to the "modal" window
+    if (modal()) {
+      send(FL_MOUSEWHEEL, modal(), window);
+      return 1;
+    }
+    // Finally try sending it to the window, the event occured in
+    if (send(FL_MOUSEWHEEL, window, window)) return 1;
+  default:
+    break;
+  }
+  if (wi && send(e, wi, window)) {
+    dnd_flag = 0;
+    return 1;
+  }
+  dnd_flag = 0;
+  return send_handlers(e);
+}
+
+////////////////////////////////////////////////////////////////
+// hide() destroys the X window, it does not do unmap!
+
+#if !defined(WIN32) && USE_XFT
+extern void fl_destroy_xft_draw(Window);
+#endif
+
+void Fl_Window::hide() {
+  clear_visible();
+
+  if (!shown()) return;
+
+  // remove from the list of windows:
+  Fl_X* ip = i;
+  Fl_X** pp = &Fl_X::first;
+  for (; *pp != ip; pp = &(*pp)->next) if (!*pp) return;
+  *pp = ip->next;
+#ifdef __APPLE__
+  ip->unlink();
+  // MacOS X manages a single pointer per application. Make sure that hiding
+  // a toplevel window will not leave us with some random pointer shape, or
+  // worst case, an invisible pointer
+  if (!parent()) cursor(FL_CURSOR_DEFAULT);
+#endif
+  i = 0;
+
+  // recursively remove any subwindows:
+  for (Fl_X *wi = Fl_X::first; wi;) {
+    Fl_Window* W = wi->w;
+    if (W->window() == this) {
+      W->hide();
+      W->set_visible();
+      wi = Fl_X::first;
+    } else wi = wi->next;
+  }
+
+  if (this == Fl::modal_) { // we are closing the modal window, find next one:
+    Fl_Window* W;
+    for (W = Fl::first_window(); W; W = Fl::next_window(W))
+      if (W->modal()) break;
+    Fl::modal_ = W;
+  }
+
+  // Make sure no events are sent to this window:
+  fl_throw_focus(this);
+  handle(FL_HIDE);
+
+#if defined(WIN32)
+  // this little trick keeps the current clipboard alive, even if we are about
+  // to destroy the window that owns the selection.
+  if (GetClipboardOwner()==ip->xid) {
+    Fl_Window *w1 = Fl::first_window();
+    if (w1 && OpenClipboard(fl_xid(w1))) {
+      EmptyClipboard();
+      SetClipboardData(CF_TEXT, NULL);
+      CloseClipboard();
+    }
+  }
+  // Send a message to myself so that I'll get out of the event loop...
+  PostMessage(ip->xid, WM_APP, 0, 0);
+  if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
+    if (ip->xid == fl_window && fl_gc) {
+      fl_release_dc(fl_window, fl_gc);
+      fl_window = (HWND)-1;
+      fl_gc = 0;
+# ifdef FLTK_USE_CAIRO
+      if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0);
+# endif
+    }
+#elif defined(__APPLE_QUARTZ__)
+  Fl_X::q_release_context(ip);
+  if ( ip->xid == fl_window && !parent() )
+    fl_window = 0;
+#endif
+
+  if (ip->region) XDestroyRegion(ip->region);
+
+#if defined(USE_X11)
+# if USE_XFT
+  fl_destroy_xft_draw(ip->xid);
+# endif
+  // this test makes sure ip->xid has not been destroyed already
+  if (ip->xid) XDestroyWindow(fl_display, ip->xid);
+#elif defined(WIN32)
+  // this little trickery seems to avoid the popup window stacking problem
+  HWND p = GetForegroundWindow();
+  if (p==GetParent(ip->xid)) {
+    ShowWindow(ip->xid, SW_HIDE);
+    ShowWindow(p, SW_SHOWNA);
+  }
+  XDestroyWindow(fl_display, ip->xid);
+#elif defined(__APPLE_QUARTZ__)
+  ip->destroy();
+#else
+# error unsupported platform
+#endif
+
+#ifdef WIN32
+  // Try to stop the annoying "raise another program" behavior
+  if (non_modal() && Fl::first_window() && Fl::first_window()->shown())
+    Fl::first_window()->show();
+#endif
+  delete ip;
+}
+
+Fl_Window::~Fl_Window() {
+  hide();
+  if (xclass_) {
+    free(xclass_);
+  }
+}
+
+// FL_SHOW and FL_HIDE are called whenever the visibility of this widget
+// or any parent changes.  We must correctly map/unmap the system's window.
+
+// For top-level windows it is assumed the window has already been
+// mapped or unmapped!!!  This is because this should only happen when
+// Fl_Window::show() or Fl_Window::hide() is called, or in response to
+// iconize/deiconize events from the system.
+
+int Fl_Window::handle(int ev)
+{
+  if (parent()) {
+    switch (ev) {
+    case FL_SHOW:
+      if (!shown()) show();
+      else {
+#if defined(USE_X11) || defined(WIN32)
+        XMapWindow(fl_display, fl_xid(this)); // extra map calls are harmless
+#elif defined(__APPLE_QUARTZ__)
+	i->map();
+#else
+# error unsupported platform
+#endif // __APPLE__
+      }
+      break;
+    case FL_HIDE:
+      if (shown()) {
+	// Find what really turned invisible, if it was a parent window
+	// we do nothing.  We need to avoid unnecessary unmap calls
+	// because they cause the display to blink when the parent is
+	// remapped.  However if this or any intermediate non-window
+	// widget has really had hide() called directly on it, we must
+	// unmap because when the parent window is remapped we don't
+	// want to reappear.
+	if (visible()) {
+	 Fl_Widget* p = parent(); for (;p->visible();p = p->parent()) {}
+	 if (p->type() >= FL_WINDOW) break; // don't do the unmap
+	}
+#if defined(USE_X11) || defined(WIN32)
+	XUnmapWindow(fl_display, fl_xid(this));
+#elif defined(__APPLE_QUARTZ__)
+	i->unmap();
+#else
+# error platform unsupported
+#endif
+      }
+      break;
+    }
+//  } else if (ev == FL_FOCUS || ev == FL_UNFOCUS) {
+//    Fl_Tooltip::exit(Fl_Tooltip::current());
+  }
+
+  return Fl_Group::handle(ev);
+}
+
+////////////////////////////////////////////////////////////////
+// Back compatibility cut & paste functions for fltk 1.1 only:
+
+/** Back-compatibility only: The single-argument call can be used to
+    move the selection to another widget or to set the owner to
+    NULL, without changing the actual text of the
+    selection. FL_SELECTIONCLEAR is sent to the previous
+    selection owner, if any.
+
+    <i>Copying the buffer every time the selection is changed is
+    obviously wasteful, especially for large selections.  An interface will
+    probably be added in a future version to allow the selection to be made
+    by a callback function.  The current interface will be emulated on top
+    of this.</i>
+*/
+void Fl::selection_owner(Fl_Widget *owner) {selection_owner_ = owner;}
+
+/**
+  Changes the current selection.  The block of text is
+  copied to an internal buffer by FLTK (be careful if doing this in
+  response to an FL_PASTE as this \e may be the same buffer
+  returned by event_text()).  The selection_owner()
+  widget is set to the passed owner.
+*/
+void Fl::selection(Fl_Widget &owner, const char* text, int len) {
+  selection_owner_ = &owner;
+  Fl::copy(text, len, 0);
+}
+
+/** Backward compatibility only.
+  This calls Fl::paste(receiver, 0);
+  \see Fl::paste(Fl_Widget &receiver, int clipboard)
+*/
+void Fl::paste(Fl_Widget &receiver) {
+  Fl::paste(receiver, 0);
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/fl_draw.H>
+
+void Fl_Widget::redraw() {
+  damage(FL_DAMAGE_ALL);
+}
+
+void Fl_Widget::redraw_label() {
+  if (window()) {
+    if (box() == FL_NO_BOX) {
+      // Widgets with the FL_NO_BOX boxtype need a parent to
+      // redraw, since it is responsible for redrawing the
+      // background...
+      int X = x() > 0 ? x() - 1 : 0;
+      int Y = y() > 0 ? y() - 1 : 0;
+      window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
+    }
+
+    if (align() && !(align() & FL_ALIGN_INSIDE) && window()->shown()) {
+      // If the label is not inside the widget, compute the location of
+      // the label and redraw the window within that bounding box...
+      int W = 0, H = 0;
+      label_.measure(W, H);
+      W += 5; // Add a little to the size of the label to cover overflow
+      H += 5;
+
+      // FIXME:
+      // This assumes that measure() returns the correct outline, which it does
+      // not in all possible cases of alignment combinedwith image and symbols.
+      switch (align() & 0x0f) {
+        case FL_ALIGN_TOP_LEFT:
+          window()->damage(FL_DAMAGE_EXPOSE, x(), y()-H, W, H); break;
+        case FL_ALIGN_TOP:
+          window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()-H, W, H); break;
+        case FL_ALIGN_TOP_RIGHT:
+          window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()-H, W, H); break;
+        case FL_ALIGN_LEFT_TOP:
+          window()->damage(FL_DAMAGE_EXPOSE, x()-W, y(), W, H); break;
+        case FL_ALIGN_RIGHT_TOP:
+          window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y(), W, H); break;
+        case FL_ALIGN_LEFT:
+          window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+(h()-H)/2, W, H); break;
+        case FL_ALIGN_RIGHT:
+          window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+(h()-H)/2, W, H); break;
+        case FL_ALIGN_LEFT_BOTTOM:
+          window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+h()-H, W, H); break;
+        case FL_ALIGN_RIGHT_BOTTOM:
+          window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+h()-H, W, H); break;
+        case FL_ALIGN_BOTTOM_LEFT:
+          window()->damage(FL_DAMAGE_EXPOSE, x(), y()+h(), W, H); break;
+        case FL_ALIGN_BOTTOM:
+          window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()+h(), W, H); break;
+        case FL_ALIGN_BOTTOM_RIGHT:
+          window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()+h(), W, H); break;
+        default:
+          window()->damage(FL_DAMAGE_ALL); break;
+      }
+    } else {
+      // The label is inside the widget, so just redraw the widget itself...
+      damage(FL_DAMAGE_ALL);
+    }
+  }
+}
+
+void Fl_Widget::damage(uchar fl) {
+  if (type() < FL_WINDOW) {
+    // damage only the rectangle covered by a child widget:
+    damage(fl, x(), y(), w(), h());
+  } else {
+    // damage entire window by deleting the region:
+    Fl_X* i = Fl_X::i((Fl_Window*)this);
+    if (!i) return; // window not mapped, so ignore it
+    if (i->region) {XDestroyRegion(i->region); i->region = 0;}
+    damage_ |= fl;
+    Fl::damage(FL_DAMAGE_CHILD);
+  }
+}
+
+void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) {
+  Fl_Widget* wi = this;
+  // mark all parent widgets between this and window with FL_DAMAGE_CHILD:
+  while (wi->type() < FL_WINDOW) {
+    wi->damage_ |= fl;
+    wi = wi->parent();
+    if (!wi) return;
+    fl = FL_DAMAGE_CHILD;
+  }
+  Fl_X* i = Fl_X::i((Fl_Window*)wi);
+  if (!i) return; // window not mapped, so ignore it
+
+  // clip the damage to the window and quit if none:
+  if (X < 0) {W += X; X = 0;}
+  if (Y < 0) {H += Y; Y = 0;}
+  if (W > wi->w()-X) W = wi->w()-X;
+  if (H > wi->h()-Y) H = wi->h()-Y;
+  if (W <= 0 || H <= 0) return;
+
+  if (!X && !Y && W==wi->w() && H==wi->h()) {
+    // if damage covers entire window delete region:
+    wi->damage(fl);
+    return;
+  }
+
+  if (wi->damage()) {
+    // if we already have damage we must merge with existing region:
+    if (i->region) {
+#if defined(USE_X11)
+      XRectangle R;
+      R.x = X; R.y = Y; R.width = W; R.height = H;
+      XUnionRectWithRegion(&R, i->region, i->region);
+#elif defined(WIN32)
+      Fl_Region R = XRectangleRegion(X, Y, W, H);
+      CombineRgn(i->region, i->region, R, RGN_OR);
+      XDestroyRegion(R);
+#elif defined(__APPLE_QUARTZ__)
+      CGRect arg = fl_cgrectmake_cocoa(X, Y, W, H);
+      int j; // don't add a rectangle totally inside the Fl_Region
+      for(j = 0; j < i->region->count; j++) {
+        if(CGRectContainsRect(i->region->rects[j], arg)) break;
+      }
+      if( j >= i->region->count) {
+        i->region->rects = (CGRect*)realloc(i->region->rects, (++(i->region->count)) * sizeof(CGRect));
+        i->region->rects[i->region->count - 1] = arg;
+      }
+#else
+# error unsupported platform
+#endif
+    }
+    wi->damage_ |= fl;
+  } else {
+    // create a new region:
+    if (i->region) XDestroyRegion(i->region);
+    i->region = XRectangleRegion(X,Y,W,H);
+    wi->damage_ = fl;
+  }
+  Fl::damage(FL_DAMAGE_CHILD);
+}
+void Fl_Window::flush() {
+  make_current();
+//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this;
+  fl_clip_region(i->region); i->region = 0;
+  draw();
+}
+
+#ifdef WIN32
+#  include "Fl_win32.cxx"
+//#elif defined(__APPLE__)
+#endif
+
+//
+// The following methods allow callbacks to schedule the deletion of
+// widgets at "safe" times.
+//
+
+static int		num_dwidgets = 0, alloc_dwidgets = 0;
+static Fl_Widget	**dwidgets = 0;
+
+/**
+  Schedules a widget for deletion at the next call to the event loop.
+  Use this method to delete a widget inside a callback function.
+
+  To avoid early deletion of widgets, this function should be called
+  toward the end of a callback and only after any call to the event
+  loop (Fl::wait(), Fl::flush(), Fl::check(), fl_ask(), etc.).
+
+  When deleting groups or windows, you must only delete the group or
+  window widget and not the individual child widgets.
+
+  \since FLTK 1.3 it is not necessary to remove widgets from their parent
+  groups or windows before calling this, because it will be done in the
+  widget's destructor, but it is not a failure to do this nevertheless.
+
+  \note In FLTK 1.1 you \b must remove widgets from their parent group
+  (or window) before deleting them.
+
+  \see Fl_Widget::~Fl_Widget()
+*/
+void Fl::delete_widget(Fl_Widget *wi) {
+  if (!wi) return;
+
+  if (num_dwidgets >= alloc_dwidgets) {
+    Fl_Widget	**temp;
+
+    temp = new Fl_Widget *[alloc_dwidgets + 10];
+    if (alloc_dwidgets) {
+      memcpy(temp, dwidgets, alloc_dwidgets * sizeof(Fl_Widget *));
+      delete[] dwidgets;
+    }
+
+    dwidgets = temp;
+    alloc_dwidgets += 10;
+  }
+
+  dwidgets[num_dwidgets] = wi;
+  num_dwidgets ++;
+}
+
+/**
+    Deletes widgets previously scheduled for deletion.
+
+    This is for internal use only. You should never call this directly.
+
+    Fl::do_widget_deletion() is called from the FLTK event loop or whenever
+    you call Fl::wait(). The previously scheduled widgets are deleted in the
+    same order they were scheduled by calling Fl::delete_widget().
+
+    \see Fl::delete_widget(Fl_Widget *wi)
+*/
+void Fl::do_widget_deletion() {
+  if (!num_dwidgets) return;
+
+  for (int i = 0; i < num_dwidgets; i ++)
+    delete dwidgets[i];
+
+  num_dwidgets = 0;
+}
+
+static Fl_Widget ***widget_watch = 0;
+static int num_widget_watch = 0;
+static int max_widget_watch = 0;
+
+/**
+  Adds a widget pointer to the widget watch list.
+
+  \note Internal use only, please use class Fl_Widget_Tracker instead.
+
+  This can be used, if it is possible that a widget might be deleted during
+  a callback or similar function. The widget pointer must be added to the
+  watch list before calling the callback. After the callback the widget
+  pointer can be queried, if it is NULL. \e If it is NULL, then the widget has been
+  deleted during the callback and must not be accessed anymore. If the widget
+  pointer is \e not NULL, then the widget has not been deleted and can be accessed
+  safely.
+
+  After accessing the widget, the widget pointer must be released from the
+  watch list by calling Fl::release_widget_pointer().
+
+  Example for a button that is clicked (from its handle() method):
+  \code
+    Fl_Widget *wp = this;		// save 'this' in a pointer variable
+    Fl::watch_widget_pointer(wp);	// add the pointer to the watch list
+    set_changed();			// set the changed flag
+    do_callback();			// call the callback
+    if (!wp) {				// the widget has been deleted
+
+      // DO NOT ACCESS THE DELETED WIDGET !
+
+    } else {				// the widget still exists
+      clear_changed();			// reset the changed flag
+    }
+
+    Fl::release_widget_pointer(wp);	// remove the pointer from the watch list
+   \endcode
+
+   This works, because all widgets call Fl::clear_widget_pointer() in their
+   destructors.
+
+   \see Fl::release_widget_pointer()
+   \see Fl::clear_widget_pointer()
+
+   An easier and more convenient method to control widget deletion during
+   callbacks is to use the class Fl_Widget_Tracker with a local (automatic)
+   variable.
+
+   \see class Fl_Widget_Tracker
+*/
+void Fl::watch_widget_pointer(Fl_Widget *&w)
+{
+  Fl_Widget **wp = &w;
+  int i;
+  for (i=0; i<num_widget_watch; ++i) {
+    if (widget_watch[i]==wp) return;
+  }
+  if (num_widget_watch==max_widget_watch) {
+    max_widget_watch += 8;
+    widget_watch = (Fl_Widget***)realloc(widget_watch, sizeof(Fl_Widget**)*max_widget_watch);
+  }
+  widget_watch[num_widget_watch++] = wp;
+#ifdef DEBUG_WATCH
+  printf ("\nwatch_widget_pointer:   (%d/%d) %8p => %8p\n",
+    num_widget_watch,num_widget_watch,wp,*wp);
+  fflush(stdout);
+#endif // DEBUG_WATCH
+}
+
+/**
+  Releases a widget pointer from the watch list.
+
+  This is used to remove a widget pointer that has been added to the watch list
+  with Fl::watch_widget_pointer(), when it is not needed anymore.
+
+  \note Internal use only, please use class Fl_Widget_Tracker instead.
+
+  \see Fl::watch_widget_pointer()
+*/
+void Fl::release_widget_pointer(Fl_Widget *&w)
+{
+  Fl_Widget **wp = &w;
+  int i,j=0;
+  for (i=0; i<num_widget_watch; ++i) {
+    if (widget_watch[i]!=wp) {
+      if (j<i) widget_watch[j] = widget_watch[i]; // fill gap
+      j++;
+    }
+#ifdef DEBUG_WATCH
+    else { // found widget pointer
+      printf ("release_widget_pointer: (%d/%d) %8p => %8p\n",
+	i+1,num_widget_watch,wp,*wp);
+    }
+#endif //DEBUG_WATCH
+  }
+  num_widget_watch = j;
+#ifdef DEBUG_WATCH
+  printf ("                        num_widget_watch = %d\n\n",num_widget_watch);
+  fflush(stdout);
+#endif // DEBUG_WATCH
+  return;
+}
+/**
+  Clears a widget pointer \e in the watch list.
+
+  This is called when a widget is destroyed (by its destructor). You should never
+  call this directly.
+
+  \note Internal use only !
+
+  This method searches the widget watch list for pointers to the widget and
+  clears each pointer that points to it. Widget pointers can be added to the
+  widget watch list by calling Fl::watch_widget_pointer() or by using the
+  helper class Fl_Widget_Tracker (recommended).
+
+  \see Fl::watch_widget_pointer()
+  \see class Fl_Widget_Tracker
+*/
+void Fl::clear_widget_pointer(Fl_Widget const *w)
+{
+  if (w==0L) return;
+  int i;
+  for (i=0; i<num_widget_watch; ++i) {
+    if (widget_watch[i] && *widget_watch[i]==w) {
+      *widget_watch[i] = 0L;
+    }
+  }
+}
+
+
+/**
+ \brief FLTK library options management.
+
+ This function needs to be documented in more detail. It can be used for more
+ optional settings, such as using a native file chooser instead of the FLTK one
+ wherever possible, disabling tooltips, disabling visible focus, disabling
+ FLTK file chooser preview, etc. .
+
+ There should be a command line option interface.
+
+ There should be an application that manages options system wide, per user, and
+ per application.
+
+ \note As of FLTK 1.3.0, options can be managed within fluid, using the menu
+ <i>Edit/Global FLTK Settings</i>.
+
+ \param opt which option
+ \return true or false
+ \see enum Fl::Fl_Option
+ \see Fl::option(Fl_Option, bool)
+
+ \since FLTK 1.3.0
+ */
+bool Fl::option(Fl_Option opt)
+{
+  if (!options_read_) {
+    int tmp;
+    { // first, read the system wide preferences
+      Fl_Preferences prefs(Fl_Preferences::SYSTEM, "fltk.org", "fltk");
+      Fl_Preferences opt_prefs(prefs, "options");
+      opt_prefs.get("ArrowFocus", tmp, 0);                      // default: off
+      options_[OPTION_ARROW_FOCUS] = tmp;
+      //opt_prefs.get("NativeFilechooser", tmp, 1);             // default: on
+      //options_[OPTION_NATIVE_FILECHOOSER] = tmp;
+      //opt_prefs.get("FilechooserPreview", tmp, 1);            // default: on
+      //options_[OPTION_FILECHOOSER_PREVIEW] = tmp;
+      opt_prefs.get("VisibleFocus", tmp, 1);                    // default: on
+      options_[OPTION_VISIBLE_FOCUS] = tmp;
+      opt_prefs.get("DNDText", tmp, 1);                         // default: on
+      options_[OPTION_DND_TEXT] = tmp;
+      opt_prefs.get("ShowTooltips", tmp, 1);                    // default: on
+      options_[OPTION_SHOW_TOOLTIPS] = tmp;
+    }
+    { // next, check the user preferences
+      // override system options only, if the option is set ( >= 0 )
+      Fl_Preferences prefs(Fl_Preferences::USER, "fltk.org", "fltk");
+      Fl_Preferences opt_prefs(prefs, "options");
+      opt_prefs.get("ArrowFocus", tmp, -1);
+      if (tmp >= 0) options_[OPTION_ARROW_FOCUS] = tmp;
+      //opt_prefs.get("NativeFilechooser", tmp, -1);
+      //if (tmp >= 0) options_[OPTION_NATIVE_FILECHOOSER] = tmp;
+      //opt_prefs.get("FilechooserPreview", tmp, -1);
+      //if (tmp >= 0) options_[OPTION_FILECHOOSER_PREVIEW] = tmp;
+      opt_prefs.get("VisibleFocus", tmp, -1);
+      if (tmp >= 0) options_[OPTION_VISIBLE_FOCUS] = tmp;
+      opt_prefs.get("DNDText", tmp, -1);
+      if (tmp >= 0) options_[OPTION_DND_TEXT] = tmp;
+      opt_prefs.get("ShowTooltips", tmp, -1);
+      if (tmp >= 0) options_[OPTION_SHOW_TOOLTIPS] = tmp;
+    }
+    { // now, if the developer has registered this app, we could as for per-application preferences
+    }
+    options_read_ = 1;
+  }
+  if (opt<0 || opt>=OPTION_LAST)
+    return false;
+  return (bool)(options_[opt]!=0);
+}
+
+/**
+ \brief Override an option while the application is running.
+
+ This function does not change any system or user settings.
+
+ \param opt which option
+ \param val set to true or false
+ \see enum Fl::Fl_Option
+ \see bool Fl::option(Fl_Option)
+ */
+void Fl::option(Fl_Option opt, bool val)
+{
+  if (opt<0 || opt>=OPTION_LAST)
+    return;
+  if (!options_read_) {
+    // first read this option, so we don't override our setting later
+    option(opt);
+  }
+  options_[opt] = val;
+}
+
+
+// Helper class Fl_Widget_Tracker
+
+/**
+  The constructor adds a widget to the watch list.
+*/
+Fl_Widget_Tracker::Fl_Widget_Tracker(Fl_Widget *wi)
+{
+  wp_ = wi;
+  Fl::watch_widget_pointer(wp_); // add pointer to watch list
+}
+
+/**
+  The destructor removes a widget from the watch list.
+*/
+Fl_Widget_Tracker::~Fl_Widget_Tracker()
+{
+  Fl::release_widget_pointer(wp_); // remove pointer from watch list
+}
+
+
+//
+// End of "$Id: Fl.cxx 8723 2011-05-23 16:49:02Z manolo $".
+//
