Submitted By: Bruce Dubbs <bdubbs at linuxfromscratch dot org>
Date: 2014-06-13
Initial Package Version: 1.3.2
Upstream Status: Not Submitted
Origin: Archlinux
Description: Fixes for tigervnc integration

diff -Nur fltk-1.3.2.orig/CMakeLists.txt fltk-1.3.2/CMakeLists.txt
--- fltk-1.3.2.orig/CMakeLists.txt	2012-09-13 16:19:01.000000000 +0200
+++ fltk-1.3.2/CMakeLists.txt	2013-07-17 19:37:45.782342898 +0200
@@ -515,6 +515,34 @@
 endif(OPTION_USE_XINERAMA)
 
 #######################################################################
+if(X11_Xfixes_FOUND)
+   option(OPTION_USE_XFIXES "use lib XFIXES" ON)
+endif(X11_Xfixes_FOUND)
+
+if(OPTION_USE_XFIXES)
+   set(HAVE_XFIXES ${X11_Xfixes_FOUND})
+   include_directories(${X11_Xfixes_INCLUDE_PATH})
+   list(APPEND FLTK_LDLIBS -lXfixes)
+   set(FLTK_XFIXES_FOUND TRUE)
+else()
+   set(FLTK_XFIXES_FOUND FALSE)
+endif(OPTION_USE_XFIXES)
+
+#######################################################################
+if(X11_Xcursor_FOUND)
+   option(OPTION_USE_XCURSOR "use lib XCURSOR" ON)
+endif(X11_Xcursor_FOUND)
+
+if(OPTION_USE_XCURSOR)
+   set(HAVE_XCURSOR ${X11_Xcursor_FOUND})
+   include_directories(${X11_Xcursor_INCLUDE_PATH})
+   list(APPEND FLTK_LDLIBS -lXcursor)
+   set(FLTK_XCURSOR_FOUND TRUE)
+else()
+   set(FLTK_XCURSOR_FOUND FALSE)
+endif(OPTION_USE_XCURSOR)
+
+#######################################################################
 if(X11_Xft_FOUND)
    option(OPTION_USE_XFT "use lib Xft" ON)
 endif(X11_Xft_FOUND)
diff -Nur fltk-1.3.2.orig/configh.cmake.in fltk-1.3.2/configh.cmake.in
--- fltk-1.3.2.orig/configh.cmake.in	2011-07-19 06:49:30.000000000 +0200
+++ fltk-1.3.2/configh.cmake.in	2013-07-17 19:37:45.782342898 +0200
@@ -108,6 +108,22 @@
 #define USE_XDBE HAVE_XDBE
 
 /*
+ * HAVE_XFIXES:
+ *
+ * Do we have the X fixes extension?
+ */
+
+#cmakedefine01 HAVE_XFIXES
+
+/*
+ * HAVE_XCURSOR:
+ *
+ * Do we have the X cursor library?
+ */
+
+#cmakedefine01 HAVE_XCURSOR
+
+/*
  * __APPLE_QUARTZ__:
  *
  * If __APPLE_QUARTZ__ is defined, FLTK will be
diff -Nur fltk-1.3.2.orig/configh.in fltk-1.3.2/configh.in
--- fltk-1.3.2.orig/configh.in	2011-10-04 11:21:47.000000000 +0200
+++ fltk-1.3.2/configh.in	2013-07-17 19:37:45.783342892 +0200
@@ -108,6 +108,22 @@
 #define USE_XDBE HAVE_XDBE
 
 /*
+ * HAVE_XFIXES:
+ *
+ * Do we have the X fixes extension?
+ */
+
+#define HAVE_XFIXES 0
+
+/*
+ * HAVE_XCURSOR:
+ *
+ * Do we have the X cursor library?
+ */
+
+#define HAVE_XCURSOR 0
+
+/*
  * __APPLE_QUARTZ__:
  *
  * All Apple implementations are now based on Quartz and Cocoa,
diff -Nur fltk-1.3.2.orig/configure.in fltk-1.3.2/configure.in
--- fltk-1.3.2.orig/configure.in	2012-11-06 22:13:54.000000000 +0100
+++ fltk-1.3.2/configure.in	2013-07-17 19:37:45.784342888 +0200
@@ -997,6 +997,26 @@
 		LIBS="-lXext $LIBS")
 	fi
 
+	dnl Check for the Xfixes extension unless disabled...
+        AC_ARG_ENABLE(xfixes, [  --enable-xfixes       turn on Xfixes support [default=yes]])
+
+	if test x$enable_xfixes != xno; then
+	    AC_CHECK_HEADER(X11/extensions/Xfixes.h, AC_DEFINE(HAVE_XFIXES),,
+	        [#include <X11/Xlib.h>])
+	    AC_CHECK_LIB(Xfixes, XFixesQueryExtension,
+		LIBS="-lXfixes $LIBS")
+	fi
+
+	dnl Check for the Xcursor library unless disabled...
+        AC_ARG_ENABLE(xcursor, [  --enable-xcursor        turn on Xcursor support [default=yes]])
+
+	if test x$enable_xcursor != xno; then
+	    AC_CHECK_HEADER(X11/Xcursor/Xcursor.h, AC_DEFINE(HAVE_XCURSOR),,
+	        [#include <X11/Xlib.h>])
+	    AC_CHECK_LIB(Xcursor, XcursorImageCreate,
+		LIBS="-lXcursor $LIBS")
+	fi
+
 	dnl Check for overlay visuals...
 	AC_PATH_PROG(XPROP, xprop)
 	AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay,
diff -Nur fltk-1.3.2.orig/FL/Enumerations.H fltk-1.3.2/FL/Enumerations.H
--- fltk-1.3.2.orig/FL/Enumerations.H	2012-12-09 19:45:57.000000000 +0100
+++ fltk-1.3.2/FL/Enumerations.H	2013-07-17 19:37:45.785342886 +0200
@@ -879,35 +879,36 @@
 
 /** The following constants define the mouse cursors that are available in FLTK.
 
-    The double-headed arrows are bitmaps provided by FLTK on X, the others
-    are provided by system-defined cursors.
+    Cursors are provided by the system when available, or bitmaps built into
+    FLTK as a fallback.
 
     \todo enum Fl_Cursor needs maybe an image.
 */
 enum Fl_Cursor {
   FL_CURSOR_DEFAULT	=  0, /**< the default cursor, usually an arrow. */
-  FL_CURSOR_ARROW	= 35, /**< an arrow pointer. */
-  FL_CURSOR_CROSS	= 66, /**< crosshair. */
-  FL_CURSOR_WAIT	= 76, /**< watch or hourglass. */
-  FL_CURSOR_INSERT	= 77, /**< I-beam. */
-  FL_CURSOR_HAND	= 31, /**< hand (uparrow on MSWindows). */
-  FL_CURSOR_HELP	= 47, /**< question mark. */
-  FL_CURSOR_MOVE	= 27, /**< 4-pointed arrow. */
-  // fltk provides bitmaps for these:
-  FL_CURSOR_NS		= 78, /**< up/down arrow. */
-  FL_CURSOR_WE		= 79, /**< left/right arrow. */
-  FL_CURSOR_NWSE	= 80, /**< diagonal arrow. */
-  FL_CURSOR_NESW	= 81, /**< diagonal arrow. */
-  FL_CURSOR_NONE	=255, /**< invisible. */
-  // for back compatibility (non MSWindows ones):
-  FL_CURSOR_N		= 70, /**< for back compatibility. */
-  FL_CURSOR_NE		= 69, /**< for back compatibility. */
-  FL_CURSOR_E		= 49, /**< for back compatibility. */
-  FL_CURSOR_SE		=  8, /**< for back compatibility. */
-  FL_CURSOR_S		=  9, /**< for back compatibility. */
-  FL_CURSOR_SW		=  7, /**< for back compatibility. */
-  FL_CURSOR_W		= 36, /**< for back compatibility. */
-  FL_CURSOR_NW		= 68 /**< for back compatibility. */
+  FL_CURSOR_ARROW   = 1,    /**< an arrow pointer. */
+  FL_CURSOR_CROSS   = 2,    /**< crosshair. */
+  FL_CURSOR_WAIT    = 3,    /**< busy indicator (e.g. hourglass). */
+  FL_CURSOR_INSERT  = 4,    /**< I-beam. */
+  FL_CURSOR_HAND    = 5,    /**< pointing hand. */
+  FL_CURSOR_HELP    = 6,    /**< question mark pointer. */
+  FL_CURSOR_MOVE    = 7,    /**< 4-pointed arrow or hand. */
+
+  /* Resize indicators */
+  FL_CURSOR_NS      = 101,  /**< up/down resize. */
+  FL_CURSOR_WE      = 102,  /**< left/right resize. */
+  FL_CURSOR_NWSE    = 103,  /**< diagonal resize. */
+  FL_CURSOR_NESW    = 104,  /**< diagonal resize. */
+  FL_CURSOR_NE      = 110,  /**< upwards, right resize. */
+  FL_CURSOR_N       = 111,  /**< upwards resize. */
+  FL_CURSOR_NW      = 112,  /**< upwards, left resize. */
+  FL_CURSOR_E       = 113,  /**< leftwards resize. */
+  FL_CURSOR_W       = 114,  /**< rightwards resize. */
+  FL_CURSOR_SE      = 115,  /**< downwards, right resize. */
+  FL_CURSOR_S       = 116,  /**< downwards resize. */
+  FL_CURSOR_SW      = 117,  /**< downwards, left resize. */
+
+  FL_CURSOR_NONE    = 255,  /**< invisible. */
 };
 /*@}*/		// group: Cursors  
 
diff -Nur fltk-1.3.2.orig/FL/fl_draw.H fltk-1.3.2/FL/fl_draw.H
--- fltk-1.3.2.orig/FL/fl_draw.H	2012-05-08 18:15:34.000000000 +0200
+++ fltk-1.3.2/FL/fl_draw.H	2013-07-17 19:37:45.785342886 +0200
@@ -751,7 +751,8 @@
 FL_EXPORT unsigned int fl_old_shortcut(const char* s);
 FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h);
 FL_EXPORT void fl_overlay_clear();
-FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE);
+FL_EXPORT void fl_cursor(Fl_Cursor);
+FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg, Fl_Color bg=FL_WHITE);
 FL_EXPORT const char* fl_expand_text(const char* from, char* buf, int maxbuf,
                                      double maxw, int& n, double &width,
                                      int wrap, int draw_symbols = 0);
diff -Nur fltk-1.3.2.orig/FL/Fl.H fltk-1.3.2/FL/Fl.H
--- fltk-1.3.2.orig/FL/Fl.H	2012-10-18 14:56:31.000000000 +0200
+++ fltk-1.3.2/FL/Fl.H	2013-07-17 19:38:09.574341653 +0200
@@ -109,6 +109,9 @@
     \see Fl::event_dispatch(Fl_Event_Dispatch) */
 typedef int (*Fl_Event_Dispatch)(int event, Fl_Window *w);
 
+/** Signature of add_clipboard_notify functions passed as parameters */
+typedef void (*Fl_Clipboard_Notify_Handler)(int source, void *data);
+
 /** @} */ /* group callback_functions */
 
 
@@ -746,6 +749,19 @@
   */
   static void paste(Fl_Widget &receiver, int source /*=0*/); // platform dependent
   /**
+  FLTK will call the registered callback whenever there is a change to the
+  selection buffer or the clipboard. The source argument indicates which
+  of the two has changed. Only changes by other applications are reported.
+  \note Some systems require polling to monitor the clipboard and may
+  therefore have some delay in detecting changes.
+  */
+  static void add_clipboard_notify(Fl_Clipboard_Notify_Handler h, void *data);
+  /**
+  Stop calling the specified callback when there are changes to the selection
+  buffer or the clipboard.
+  */
+  static void remove_clipboard_notify(Fl_Clipboard_Notify_Handler h);
+  /**
     Initiate a Drag And Drop operation. The selection buffer should be
     filled with relevant data before calling this method. FLTK will
     then initiate the system wide drag and drop handling. Dropped data
@@ -792,6 +808,8 @@
   static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my);
   static void screen_xywh(int &X, int &Y, int &W, int &H, int n); 
   static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh);
+  static int screen_num(int x, int y);
+  static int screen_num(int x, int y, int w, int h);
   static void screen_dpi(float &h, float &v, int n=0);
   static void screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my);
   static void screen_work_area(int &X, int &Y, int &W, int &H, int n);
diff -Nur fltk-1.3.2.orig/FL/Fl_Image.H fltk-1.3.2/FL/Fl_Image.H
--- fltk-1.3.2.orig/FL/Fl_Image.H	2012-11-09 17:02:08.000000000 +0100
+++ fltk-1.3.2/FL/Fl_Image.H	2013-07-17 19:37:37.910343301 +0200
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 
 class Fl_Widget;
+class Fl_Pixmap;
 struct Fl_Menu_Item;
 struct Fl_Label;
 
@@ -203,6 +204,7 @@
   */
   Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) :
     Fl_Image(W,H,D), array(bits), alloc_array(0), id_(0), mask_(0) {data((const char **)&array, 1); ld(LD);}
+  Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg=FL_GRAY);
   virtual ~Fl_RGB_Image();
   virtual Fl_Image *copy(int W, int H);
   Fl_Image *copy() { return copy(w(), h()); }
diff -Nur fltk-1.3.2.orig/FL/Fl_Widget.H fltk-1.3.2/FL/Fl_Widget.H
--- fltk-1.3.2.orig/FL/Fl_Widget.H	2012-04-23 22:12:06.000000000 +0200
+++ fltk-1.3.2/FL/Fl_Widget.H	2013-07-17 19:37:07.411344886 +0200
@@ -171,6 +171,7 @@
         GROUP_RELATIVE  = 1<<16,  ///< position this widget relative to the parent group, not to the window
         COPIED_TOOLTIP  = 1<<17,  ///< the widget tooltip is internally copied, its destruction is handled by the widget
         FULLSCREEN      = 1<<18,  ///< a fullscreen window (Fl_Window)
+        SIMPLE_KEYBOARD = 1<<19,  ///< the widget wants simple, consistent keypresses and not advanced input (like character composition and CJK input)
         // (space for more flags)
         USERFLAG3       = 1<<29,  ///< reserved for 3rd party extensions
         USERFLAG2       = 1<<30,  ///< reserved for 3rd party extensions
@@ -776,6 +777,35 @@
    */
   void clear_changed() {flags_ &= ~CHANGED;}
 
+  /** 
+      Returns if the widget sees a simplified keyboard model or not.
+
+      Normally widgets get a full-featured keyboard model that is geared
+      towards text input. This includes support for compose sequences and
+      advanced input methods, commonly used for asian writing system. This
+      system however has downsides in that extra graphic can be presented
+      to the user and that a physical key press doesn't correspond directly
+      to a FLTK event.
+
+      Widgets that need a direct correspondence between actual key events
+      and those seen by the widget can swith to the simplified keyboard
+      model.
+
+     \retval 0 if the widget uses the normal keyboard model
+     \see set_changed(), clear_changed()
+   */
+  unsigned int simple_keyboard() const {return flags_&SIMPLE_KEYBOARD;}
+
+  /** Marks a widget to use the simple keyboard model.
+      \see changed(), clear_changed()
+   */
+  void set_simple_keyboard() {flags_ |= SIMPLE_KEYBOARD;}
+
+  /** Marks a widget to use the normal keyboard model.
+      \see changed(), set_changed()
+   */
+  void set_normal_keyboard() {flags_ &= ~SIMPLE_KEYBOARD;}
+
   /** Gives the widget the keyboard focus.
       Tries to make this widget be the Fl::focus() widget, by first sending 
       it an FL_FOCUS event, and if it returns non-zero, setting 
diff -Nur fltk-1.3.2.orig/FL/Fl_Window.H fltk-1.3.2/FL/Fl_Window.H
--- fltk-1.3.2.orig/FL/Fl_Window.H	2012-11-06 21:46:14.000000000 +0100
+++ fltk-1.3.2/FL/Fl_Window.H	2013-07-17 19:38:17.318341233 +0200
@@ -22,12 +22,17 @@
 #ifndef Fl_Window_H
 #define Fl_Window_H
 
+#ifdef WIN32
+#include <windows.h>
+#endif
+
 #include "Fl_Group.H"
 
 #define FL_WINDOW 0xF0		///< window type id all subclasses have type() >= this
 #define FL_DOUBLE_WINDOW 0xF1   ///< double window type id
 
 class Fl_X;
+class Fl_RGB_Image;
 
 /**
   This widget produces an actual window.  This can either be a main
@@ -49,7 +54,7 @@
 class FL_EXPORT Fl_Window : public Fl_Group {
 
   static char *default_xclass_;
-  // Note: we must use separate statements for each of the following 4 variables,
+  // Note: we must use separate statements for each of the following 8 variables,
   // with the static attribute, otherwise MS VC++ 2008/2010 complains :-(
   // AlbrechtS 04/2012
 #if FLTK_ABI_VERSION < 10301
@@ -68,20 +73,45 @@
   static // when these members are static, ABI compatibility with 1.3.0 is respected
 #endif
   int no_fullscreen_h;
+#if FLTK_ABI_VERSION < 10302
+  static // when these members are static, ABI compatibility with 1.3.0 is respected
+#endif
+  int fullscreen_screen_top;
+#if FLTK_ABI_VERSION < 10302
+  static // when these members are static, ABI compatibility with 1.3.0 is respected
+#endif
+  int fullscreen_screen_bottom;
+#if FLTK_ABI_VERSION < 10302
+  static // when these members are static, ABI compatibility with 1.3.0 is respected
+#endif
+  int fullscreen_screen_left;
+#if FLTK_ABI_VERSION < 10302
+  static // when these members are static, ABI compatibility with 1.3.0 is respected
+#endif
+  int fullscreen_screen_right;
 
   friend class Fl_X;
   Fl_X *i; // points at the system-specific stuff
 
+  struct icon_data {
+    const void *legacy_icon;
+    Fl_RGB_Image **icons;
+    int count;
+#ifdef WIN32
+    HICON big_icon;
+    HICON small_icon;
+#endif
+  };
+
   const char* iconlabel_;
   char* xclass_;
-  const void* icon_;
+  struct icon_data *icon_;
   // size_range stuff:
   int minw, minh, maxw, maxh;
   int dw, dh, aspect;
   uchar size_range_set;
   // cursor stuff
   Fl_Cursor cursor_default;
-  Fl_Color cursor_fg, cursor_bg;
   void size_range_();
   void _Fl_Window(); // constructor innards
   void fullscreen_x(); // platform-specific part of sending a window to full screen
@@ -121,6 +151,8 @@
   */
   int force_position() const { return ((flags() & FORCE_POSITION)?1:0); }
 
+  void free_icons();
+
 public:
 
   /**
@@ -350,6 +382,18 @@
   static const char *default_xclass();
   const char* xclass() const;
   void xclass(const char* c);
+
+  static void default_icon(const Fl_RGB_Image*);
+  static void default_icons(const Fl_RGB_Image*[], int);
+  void icon(const Fl_RGB_Image*);
+  void icons(const Fl_RGB_Image*[], int);
+
+#ifdef WIN32
+  static void default_icons(HICON big_icon, HICON small_icon);
+  void icons(HICON big_icon, HICON small_icon);
+#endif
+
+  /* for legacy compatibility */
   const void* icon() const;
   void icon(const void * ic);
 
@@ -402,13 +446,15 @@
   */
   void show(int argc, char **argv);
   /**
-    Makes the window completely fill the screen, without any window
-    manager border visible.  You must use fullscreen_off() to undo
-    this. 
+    Makes the window completely fill one or more screens, without any
+    window manager border visible.  You must use fullscreen_off() to
+    undo this. 
 
     \note On some platforms, this can result in the keyboard being
     grabbed. The window may also be recreated, meaning hide() and
     show() will be called.
+
+    \see void Fl_Window::fullscreen_screens()
   */
   void fullscreen();
   /**
@@ -425,6 +471,17 @@
   */
   unsigned int fullscreen_active() const { return flags() & FULLSCREEN; }
   /**
+    Sets which screens should be used when this window is in fullscreen
+    mode. The window will be resized to the top of the screen with index
+    \p top, the bottom of the screen with index \p bottom, etc. 
+
+    If this method is never called, or if any argument is < 0, then the
+    window will be resized to fill the screen it is currently on.
+
+    \see void Fl_Window::fullscreen()
+    */
+  void fullscreen_screens(int top, int bottom, int left, int right);
+  /**
     Iconifies the window.  If you call this when shown() is false
     it will show() it as an icon.  If the window is already
     iconified this does nothing.
@@ -466,14 +523,17 @@
     is different.
 
     The type Fl_Cursor is an enumeration defined in <FL/Enumerations.H>.
-    (Under X you can get any XC_cursor value by passing 
-    Fl_Cursor((XC_foo/2)+1)).  The colors only work on X, they are
-    not implemented on WIN32.
 
-    For back compatibility only.
+    \see cursor(const Fl_RGB_Image*, int, int), default_cursor()
   */
-  void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); // platform dependent
-  void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
+  void cursor(Fl_Cursor);
+  void cursor(const Fl_RGB_Image*, int, int);
+  void default_cursor(Fl_Cursor);
+
+  /* for legacy compatibility */
+  void cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE);
+  void default_cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE);
+
   static void default_callback(Fl_Window*, void* v);
   
   /** Returns the window width including any frame added by the window manager.
diff -Nur fltk-1.3.2.orig/FL/mac.H fltk-1.3.2/FL/mac.H
--- fltk-1.3.2.orig/FL/mac.H	2012-11-13 15:45:42.000000000 +0100
+++ fltk-1.3.2/FL/mac.H	2013-07-17 19:38:01.694342066 +0200
@@ -120,7 +120,11 @@
   void collapse(void);
   WindowRef window_ref(void);
   void set_key_window(void);
-  void set_cursor(Fl_Cursor);
+  // OS X doesn't have per window icons
+  static void set_default_icons(const Fl_RGB_Image*[], int) {};
+  void set_icons() {};
+  int set_cursor(Fl_Cursor);
+  int set_cursor(const Fl_RGB_Image*, int, int);
   static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
   static unsigned char *bitmap_from_window_rect(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel);
   static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, int h);
diff -Nur fltk-1.3.2.orig/FL/win32.H fltk-1.3.2/FL/win32.H
--- fltk-1.3.2.orig/FL/win32.H	2012-03-12 12:55:50.000000000 +0100
+++ fltk-1.3.2/FL/win32.H	2013-07-17 19:38:17.318341233 +0200
@@ -73,16 +73,23 @@
   int wait_for_expose;
   HDC private_dc; // used for OpenGL
   HCURSOR cursor;
+  int custom_cursor;
   HDC saved_hdc;  // saves the handle of the DC currently loaded
   // static variables, static functions and member functions
   static Fl_X* first;
   static Fl_X* i(const Fl_Window* w) {return w->i;}
   static int fake_X_wm(const Fl_Window* w,int &X, int &Y,
 		                 int &bt,int &bx,int &by);
+  void make_fullscreen(int X, int Y, int W, int H);
   void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
   void flush() {w->flush();}
   void set_minmax(LPMINMAXINFO minmax);
   void mapraise();
+  static void set_default_icons(const Fl_RGB_Image*[], int);
+  static void set_default_icons(HICON, HICON);
+  void set_icons();
+  int set_cursor(Fl_Cursor);
+  int set_cursor(const Fl_RGB_Image*, int, int);
   static Fl_X* make(Fl_Window*);
 };
 extern FL_EXPORT HCURSOR fl_default_cursor;
diff -Nur fltk-1.3.2.orig/FL/x.H fltk-1.3.2/FL/x.H
--- fltk-1.3.2.orig/FL/x.H	2012-03-23 17:47:53.000000000 +0100
+++ fltk-1.3.2/FL/x.H	2013-07-17 19:38:01.695342062 +0200
@@ -154,6 +154,10 @@
   static Fl_X* i(const Fl_Window* wi) {return wi->i;}
   void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
   void sendxjunk();
+  static void set_default_icons(const Fl_RGB_Image*[], int);
+  void set_icons();
+  int set_cursor(Fl_Cursor);
+  int set_cursor(const Fl_RGB_Image*, int, int);
   static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap);
   static Fl_X* set_xid(Fl_Window*, Window);
   // kludges to get around protection:
diff -Nur fltk-1.3.2.orig/src/CMakeLists.txt fltk-1.3.2/src/CMakeLists.txt
--- fltk-1.3.2.orig/src/CMakeLists.txt	2011-01-12 10:24:03.000000000 +0100
+++ fltk-1.3.2/src/CMakeLists.txt	2013-07-17 19:37:45.788342890 +0200
@@ -239,6 +239,14 @@
    target_link_libraries(fltk ${X11_Xinerama_LIB})
 endif(HAVE_XINERAMA)
 
+if(HAVE_XFIXES)
+   target_link_libraries(fltk ${X11_Xfixes_LIB})
+endif(HAVE_XFIXES)
+
+if(HAVE_XCURSOR)
+   target_link_libraries(fltk ${X11_Xcursor_LIB})
+endif(HAVE_XCURSOR)
+
 if(USE_XFT)
    target_link_libraries(fltk ${X11_Xft_LIB})
 endif(USE_XFT)
diff -Nur fltk-1.3.2.orig/src/Fl_cocoa.mm fltk-1.3.2/src/Fl_cocoa.mm
--- fltk-1.3.2.orig/src/Fl_cocoa.mm	2012-11-30 19:20:36.000000000 +0100
+++ fltk-1.3.2/src/Fl_cocoa.mm	2013-07-17 19:38:17.320341239 +0200
@@ -97,7 +97,6 @@
 CGContextRef fl_gc = 0;
 void *fl_system_menu;                   // this is really a NSMenu*
 Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0;
-void *fl_default_cursor;		// this is really a NSCursor*
 void *fl_capture = 0;			// (NSWindow*) we need this to compensate for a missing(?) mouse capture
 bool fl_show_iconic;                    // true if called from iconize() - shows the next created window in collapsed state
 //int fl_disable_transient_for;           // secret method of removing TRANSIENT_FOR
@@ -663,12 +662,9 @@
     return NO;	// prevent the caption to be redrawn as active on click
 		//  when another modal window is currently the key win
 
-  return !(w->tooltip_window() || w->menu_window());
+  return !w->tooltip_window();
 }
 
-// TODO see if we really need a canBecomeMainWindow ...
-#if 0
-
 - (BOOL)canBecomeMainWindow
 {
   if (Fl::modal_ && (Fl::modal_ != w))
@@ -677,7 +673,6 @@
 
   return !(w->tooltip_window() || w->menu_window());
 }
-#endif
 
 @end
 
@@ -1333,8 +1328,6 @@
 					  dequeue:YES];
     while (ign_event);
     
-    fl_default_cursor = [NSCursor arrowCursor];
-
     // bring the application into foreground without a 'CARB' resource
     Boolean same_psn;
     ProcessSerialNumber cur_psn, front_psn;
@@ -1639,6 +1632,7 @@
 - (void)drawRect:(NSRect)rect;
 - (BOOL)acceptsFirstResponder;
 - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent;
+- (void)resetCursorRects;
 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
 - (void)mouseUp:(NSEvent *)theEvent;
 - (void)rightMouseUp:(NSEvent *)theEvent;
@@ -1696,6 +1690,16 @@
   Fl_Window *first = Fl::first_window();
   return (first == w || !first->modal());
 }
+- (void)resetCursorRects {
+  Fl_Window *w = [(FLWindow*)[self window] getFl_Window];
+  Fl_X *i = Fl_X::i(w);
+  // We have to have at least one cursor rect for invalidateCursorRectsForView
+  // to work, hence the "else" clause.
+  if (i->cursor)
+    [self addCursorRect:[self visibleRect] cursor:(NSCursor*)i->cursor];
+  else
+    [self addCursorRect:[self visibleRect] cursor:[NSCursor arrowCursor]];
+}
 - (void)mouseUp:(NSEvent *)theEvent {
   cocoaMouseHandler(theEvent);
 }
@@ -2069,7 +2073,7 @@
     x->other_xid = 0;
     x->region = 0;
     x->subRegion = 0;
-    x->cursor = fl_default_cursor;
+    x->cursor = NULL;
     x->gc = 0;			// stay 0 for Quickdraw; fill with CGContext for Quartz
     Fl_Window *win = w->window();
     Fl_X *xo = Fl_X::i(win);
@@ -2165,16 +2169,39 @@
     x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows
     x->region = 0;
     x->subRegion = 0;
-    x->cursor = fl_default_cursor;
+    x->cursor = NULL;
     x->xidChildren = 0;
     x->xidNext = 0;
     x->gc = 0;
 	  
     NSRect crect;
     if (w->fullscreen_active()) {
-      int sx, sy, sw, sh;
-      Fl::screen_xywh(sx, sy, sw, sh, w->x(), w->y(), w->w(), w->h());
-      w->resize(sx, sy, sw, sh);
+      int top, bottom, left, right;
+      int sx, sy, sw, sh, X, Y, W, H;
+
+      top = w->fullscreen_screen_top;
+      bottom = w->fullscreen_screen_bottom;
+      left = w->fullscreen_screen_left;
+      right = w->fullscreen_screen_right;
+
+      if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+        top = Fl::screen_num(w->x(), w->y(), w->w(), w->h());
+        bottom = top;
+        left = top;
+        right = top;
+      }
+
+      Fl::screen_xywh(sx, sy, sw, sh, top);
+      Y = sy;
+      Fl::screen_xywh(sx, sy, sw, sh, bottom);
+      H = sy + sh - Y;
+      Fl::screen_xywh(sx, sy, sw, sh, left);
+      X = sx;
+      Fl::screen_xywh(sx, sy, sw, sh, right);
+      W = sx + sw - X;
+
+      w->resize(X, Y, W, H);
+
       winstyle = NSBorderlessWindowMask;
       winlevel = NSStatusWindowLevel;
     }
@@ -2692,6 +2719,10 @@
     Fl_X::relink(w, w->window() );
     w->redraw();
   }
+  if (cursor) {
+    [(NSCursor*)cursor release];
+    cursor = NULL;
+  }
 }
 
 void Fl_X::unmap() {
@@ -2796,68 +2827,106 @@
   return [image autorelease];
 }
 
-static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() )
+int Fl_X::set_cursor(Fl_Cursor c)
 {
-  if (cursor == nil) {
-    CGContextRef c = f();
-    NSImage *image = CGBitmapContextToNSImage(c);
-    fl_delete_offscreen( (Fl_Offscreen)c ); 
-    NSPoint pt = {[image size].width/2, [image size].height/2};
-    cursor = [[NSCursor alloc] initWithImage:image hotSpot:pt];
+  if (cursor) {
+    [(NSCursor*)cursor release];
+    cursor = NULL;
   }
-  return cursor;
-}
 
-void Fl_X::set_cursor(Fl_Cursor c)
-{
-  NSCursor *icrsr;
   switch (c) {
-    case FL_CURSOR_CROSS:  icrsr = [NSCursor crosshairCursor]; break;
-    case FL_CURSOR_WAIT:
-      static NSCursor *watch = nil;
-      watch = PrepareCursor(watch,  &Fl_X::watch_cursor_image);
-      icrsr = watch;
-      break;
-    case FL_CURSOR_INSERT: icrsr = [NSCursor IBeamCursor]; break;
-    case FL_CURSOR_N:      icrsr = [NSCursor resizeUpCursor]; break;
-    case FL_CURSOR_S:      icrsr = [NSCursor resizeDownCursor]; break;
-    case FL_CURSOR_NS:     icrsr = [NSCursor resizeUpDownCursor]; break;
-    case FL_CURSOR_HELP:   
-      static NSCursor *help = nil;
-      help = PrepareCursor(help,  &Fl_X::help_cursor_image);
-      icrsr = help;
-      break;
-    case FL_CURSOR_HAND:   icrsr = [NSCursor pointingHandCursor]; break;
-    case FL_CURSOR_MOVE:   icrsr = [NSCursor openHandCursor]; break;
-    case FL_CURSOR_NE:
-    case FL_CURSOR_SW:
-    case FL_CURSOR_NESW:   
-      static NSCursor *nesw = nil;
-      nesw = PrepareCursor(nesw,  &Fl_X::nesw_cursor_image);
-      icrsr = nesw;
-      break;
-    case FL_CURSOR_E:      icrsr = [NSCursor resizeRightCursor]; break;
-    case FL_CURSOR_W:      icrsr = [NSCursor resizeLeftCursor]; break;
-    case FL_CURSOR_WE:     icrsr = [NSCursor resizeLeftRightCursor]; break;
-    case FL_CURSOR_SE:
-    case FL_CURSOR_NW:
-    case FL_CURSOR_NWSE:   
-      static NSCursor *nwse = nil;
-      nwse = PrepareCursor(nwse,  &Fl_X::nwse_cursor_image);
-      icrsr = nwse;
-      break;
-    case FL_CURSOR_NONE:   
-      static NSCursor *none = nil;
-      none = PrepareCursor(none,  &Fl_X::none_cursor_image);
-      icrsr = none; 
-      break;
-    case FL_CURSOR_ARROW:
-    case FL_CURSOR_DEFAULT:
-    default:			   icrsr = [NSCursor arrowCursor];
-      break;
+  case FL_CURSOR_ARROW:   cursor = [NSCursor arrowCursor]; break;
+  case FL_CURSOR_CROSS:   cursor = [NSCursor crosshairCursor]; break;
+  case FL_CURSOR_INSERT:  cursor = [NSCursor IBeamCursor]; break;
+  case FL_CURSOR_HAND:    cursor = [NSCursor pointingHandCursor]; break;
+  case FL_CURSOR_MOVE:    cursor = [NSCursor openHandCursor]; break;
+  case FL_CURSOR_NS:      cursor = [NSCursor resizeUpDownCursor]; break;
+  case FL_CURSOR_WE:      cursor = [NSCursor resizeLeftRightCursor]; break;
+  case FL_CURSOR_N:       cursor = [NSCursor resizeUpCursor]; break;
+  case FL_CURSOR_E:       cursor = [NSCursor resizeRightCursor]; break;
+  case FL_CURSOR_W:       cursor = [NSCursor resizeLeftCursor]; break;
+  case FL_CURSOR_S:       cursor = [NSCursor resizeDownCursor]; break;
+  default:
+    return 0;
+  }
+
+  [(NSCursor*)cursor retain];
+
+  [(NSWindow*)xid invalidateCursorRectsForView:[(NSWindow*)xid contentView]];
+
+  return 1;
+}
+
+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+  if (cursor) {
+    [(NSCursor*)cursor release];
+    cursor = NULL;
+  }
+
+  if ((hotx < 0) || (hotx >= image->w()))
+    return 0;
+  if ((hoty < 0) || (hoty >= image->h()))
+    return 0;
+
+  // OS X >= 10.6 can create a NSImage from a CGImage, but we need to
+  // support older versions, hence this pesky handling.
+
+  NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
+                              initWithBitmapDataPlanes:NULL
+                              pixelsWide:image->w()
+                              pixelsHigh:image->h()
+                              bitsPerSample:8
+                              samplesPerPixel:image->d()
+                              hasAlpha:!(image->d() & 1)
+                              isPlanar:NO
+                              colorSpaceName:(image->d()<=2) ? NSDeviceWhiteColorSpace : NSDeviceRGBColorSpace
+                              bytesPerRow:(image->w() * image->d())
+                              bitsPerPixel:(image->d()*8)];
+
+  // Alpha needs to be premultiplied for this format
+
+  const uchar *i = (const uchar*)*image->data();
+  unsigned char *o = [bitmap bitmapData];
+  for (int y = 0;y < image->h();y++) {
+    if (image->d() & 1) {
+      for (int x = 0;x < image->w();x++) {
+        unsigned int alpha;
+        if (image->d() == 4) {
+          alpha = i[3];
+          *o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
+          *o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
+        }
+
+        alpha = i[1];
+        *o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
+        *o++ = alpha;
+        i++;
+  }
+    } else {
+      // No alpha, so we can just copy everything directly.
+      int len = image->w() * image->d();
+      memcpy(o, i, len);
+      o += len;
+      i += len;
+    }
+    i += image->ld();
   }
-  [icrsr set];
-  cursor = icrsr;
+
+  NSImage *nsimage = [[NSImage alloc]
+                      initWithSize:NSMakeSize(image->w(), image->h())];
+
+  [nsimage addRepresentation:bitmap];
+
+  cursor = [[NSCursor alloc]
+            initWithImage:nsimage
+            hotSpot:NSMakePoint(hotx, hoty)];
+
+  [(NSWindow*)xid invalidateCursorRectsForView:[(NSWindow*)xid contentView]];
+
+  [bitmap release];
+  [nsimage release];
+
+  return 1;
 }
 
 @interface FLaboutItemTarget : NSObject 
diff -Nur fltk-1.3.2.orig/src/fl_cursor.cxx fltk-1.3.2/src/fl_cursor.cxx
--- fltk-1.3.2.orig/src/fl_cursor.cxx	2012-03-12 12:55:50.000000000 +0100
+++ fltk-1.3.2/src/fl_cursor.cxx	2013-07-17 19:37:45.791342890 +0200
@@ -24,297 +24,165 @@
 
 #include <FL/Fl.H>
 #include <FL/Fl_Window.H>
+#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_RGB_Image.H>
 #include <FL/x.H>
-#if !defined(WIN32) && !defined(__APPLE__)
-#  include <X11/cursorfont.h>
-#endif
 #include <FL/fl_draw.H>
 
+#include "fl_cursor_wait.xpm"
+#include "fl_cursor_help.xpm"
+#include "fl_cursor_nwse.xpm"
+#include "fl_cursor_nesw.xpm"
+#include "fl_cursor_none.xpm"
+
 /**
   Sets the cursor for the current window to the specified shape and colors.
   The cursors are defined in the <FL/Enumerations.H> header file. 
   */
+void fl_cursor(Fl_Cursor c) {
+  if (Fl::first_window()) Fl::first_window()->cursor(c);
+}
+
+/* For back compatibility only. */
 void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
-  if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg);
+  fl_cursor(c);
 }
+
+
 /** 
-    Sets the default window cursor as well as its color.
+    Sets the default window cursor. This is the cursor that will be used
+    after the mouse pointer leaves a widget with a custom cursor set.
 
-    For back compatibility only.
+    \see cursor(const Fl_RGB_Image*, int, int), default_cursor()
 */
-void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
-//  if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW;
-
+void Fl_Window::default_cursor(Fl_Cursor c) {
   cursor_default = c;
-  cursor_fg      = fg;
-  cursor_bg      = bg;
+  cursor(c);
+}
+
+
+void fallback_cursor(Fl_Window *w, Fl_Cursor c) {
+  const char **xpm;
+  int hotx, hoty;
+
+  // The standard arrow is our final fallback, so something is broken
+  // if we get called back here with that as an argument.
+  if (c == FL_CURSOR_ARROW)
+    return;
+
+  switch (c) {
+  case FL_CURSOR_WAIT:
+    xpm = (const char**)fl_cursor_wait_xpm;
+    hotx = 8;
+    hoty = 15;
+    break;
+  case FL_CURSOR_HELP:
+    xpm = (const char**)fl_cursor_help_xpm;
+    hotx = 1;
+    hoty = 3;
+    break;
+  case FL_CURSOR_NWSE:
+    xpm = (const char**)fl_cursor_nwse_xpm;
+    hotx = 7;
+    hoty = 7;
+    break;
+  case FL_CURSOR_NESW:
+    xpm = (const char**)fl_cursor_nesw_xpm;
+    hotx = 7;
+    hoty = 7;
+    break;
+  case FL_CURSOR_NONE:
+    xpm = (const char**)fl_cursor_none_xpm;
+    hotx = 0;
+    hoty = 0;
+    break;
+  default:
+    w->cursor(FL_CURSOR_ARROW);
+    return;
+  }
 
-  cursor(c, fg, bg);
+  Fl_Pixmap pxm(xpm);
+  Fl_RGB_Image image(&pxm);
+
+  w->cursor(&image, hotx, hoty);
 }
 
-#ifdef WIN32
 
-#  ifndef IDC_HAND
-#    define IDC_HAND	MAKEINTRESOURCE(32649)
-#  endif // !IDC_HAND
+void Fl_Window::cursor(Fl_Cursor c) {
+  int ret;
 
-void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) {
-  if (!shown()) return;
   // the cursor must be set for the top level window, not for subwindows
   Fl_Window *w = window(), *toplevel = this;
-  while (w) { toplevel = w; w = w->window(); }
-  if (toplevel != this) { toplevel->cursor(c, c1, c2); return; }
-  // now set the actual cursor
-  if (c == FL_CURSOR_DEFAULT) {
-    c = cursor_default;
-  }
-  if (c > FL_CURSOR_NESW) {
-    i->cursor = 0;
-  } else if (c == FL_CURSOR_DEFAULT) {
-    i->cursor = fl_default_cursor;
-  } else {
-    LPSTR n;
-    switch (c) {
-    case FL_CURSOR_ARROW:	n = IDC_ARROW; break;
-    case FL_CURSOR_CROSS:	n = IDC_CROSS; break;
-    case FL_CURSOR_WAIT:	n = IDC_WAIT; break;
-    case FL_CURSOR_INSERT:	n = IDC_IBEAM; break;
-    case FL_CURSOR_HELP:	n = IDC_HELP; break;
-    case FL_CURSOR_HAND: {
-          OSVERSIONINFO osvi;
-
-          // Get the OS version: Windows 98 and 2000 have a standard
-	  // hand cursor.
-          memset(&osvi, 0, sizeof(OSVERSIONINFO));
-          osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-          GetVersionEx(&osvi);
-
-          if (osvi.dwMajorVersion > 4 ||
-  	      (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 &&
-  	       osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) n = IDC_HAND;
-          else n = IDC_UPARROW;
-	} break;
-    case FL_CURSOR_MOVE:	n = IDC_SIZEALL; break;
-    case FL_CURSOR_N:
-    case FL_CURSOR_S:
-    case FL_CURSOR_NS:		n = IDC_SIZENS; break;
-    case FL_CURSOR_NE:
-    case FL_CURSOR_SW:
-    case FL_CURSOR_NESW:	n = IDC_SIZENESW; break;
-    case FL_CURSOR_E:
-    case FL_CURSOR_W:
-    case FL_CURSOR_WE:		n = IDC_SIZEWE; break;
-    case FL_CURSOR_SE:
-    case FL_CURSOR_NW:
-    case FL_CURSOR_NWSE:	n = IDC_SIZENWSE; break;
-    default:			n = IDC_NO; break;
-    }
-    i->cursor = LoadCursor(NULL, n);
+
+  while (w) {
+    toplevel = w;
+    w = w->window();
   }
-  SetCursor(i->cursor);
-}
 
-#elif defined(__APPLE__)
+  if (toplevel != this) {
+    toplevel->cursor(c);
+    return;
+  }
 
-#ifdef __BIG_ENDIAN__
-# define E(x) x
-#elif defined __LITTLE_ENDIAN__
-// Don't worry. This will be resolved at compile time
-# define E(x) (x>>8)|((x<<8)&0xff00)
-#else
-# error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined"
-#endif
-
-CGContextRef Fl_X::help_cursor_image(void)
-{
-  int w = 20, h = 20;
-  Fl_Offscreen off = Fl_Quartz_Graphics_Driver::create_offscreen_with_alpha(w, h);
-  fl_begin_offscreen(off);
-  CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
-  fl_rectf(0,0,w,h);
-  fl_color(FL_BLACK);
-  fl_font(FL_COURIER_BOLD, 20);
-  fl_draw("?", 1, h-1);
-  fl_end_offscreen();
-  return (CGContextRef)off;
-}
+  if (c == FL_CURSOR_DEFAULT)
+    c = cursor_default;
 
-CGContextRef Fl_X::none_cursor_image(void)
-{
-  int w = 20, h = 20;
-  Fl_Offscreen off = Fl_Quartz_Graphics_Driver::create_offscreen_with_alpha(w, h);
-  fl_begin_offscreen(off);
-  CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
-  fl_rectf(0,0,w,h);
-  fl_end_offscreen();
-  return (CGContextRef)off;
-}
+  if (!i)
+    return;
 
-CGContextRef Fl_X::watch_cursor_image(void)
-{
-  int w, h, r = 5;
-  w = 2*r+6;
-  h = 4*r;
-  Fl_Offscreen off = Fl_Quartz_Graphics_Driver::create_offscreen_with_alpha(w, h);
-  fl_begin_offscreen(off);
-  CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
-  fl_rectf(0,0,w,h);
-  CGContextTranslateCTM( (CGContextRef)off, w/2, h/2);
-  fl_color(FL_WHITE);
-  fl_circle(0, 0, r+1);
-  fl_color(FL_BLACK);
-  fl_rectf(int(-r*0.7), int(-r*1.7), int(1.4*r), int(3.4*r));
-  fl_rectf(r-1, -1, 3, 3);
-  fl_color(FL_WHITE);
-  fl_pie(-r, -r, 2*r, 2*r, 0, 360);
-  fl_color(FL_BLACK);
-  fl_circle(0,0,r);
-  fl_xyline(0, 0, int(-r*.7));
-  fl_xyline(0, 0, 0, int(-r*.7));
-  fl_end_offscreen();
-  return (CGContextRef)off;
-}
+  ret = i->set_cursor(c);
+  if (ret)
+    return;
 
-CGContextRef Fl_X::nesw_cursor_image(void)
-{
-  int c = 7, r = 2*c;
-  int w = r, h = r;
-  Fl_Offscreen off = Fl_Quartz_Graphics_Driver::create_offscreen_with_alpha(w, h);
-  fl_begin_offscreen(off);
-  CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
-  fl_rectf(0,0,w,h);
-  CGContextTranslateCTM( (CGContextRef)off, 0, h);
-  CGContextScaleCTM( (CGContextRef)off, 1, -1);
-  fl_color(FL_BLACK);
-  fl_polygon(0, 0, c, 0, 0, c);
-  fl_polygon(r, r, r, r-c, r-c, r);
-  fl_line_style(FL_SOLID, 2, 0);
-  fl_line(0,1, r,r+1);
-  fl_line_style(FL_SOLID, 0, 0);
-  fl_end_offscreen();
-  return (CGContextRef)off;
+  fallback_cursor(this, c);
 }
 
-CGContextRef Fl_X::nwse_cursor_image(void)
-{
-  int c = 7, r = 2*c;
-  int w = r, h = r;
-  Fl_Offscreen off = Fl_Quartz_Graphics_Driver::create_offscreen_with_alpha(w, h);
-  fl_begin_offscreen(off);
-  CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
-  fl_rectf(0,0,w,h);
-  CGContextTranslateCTM( (CGContextRef)off, 0, h);
-  CGContextScaleCTM( (CGContextRef)off, 1, -1);
-  fl_color(FL_BLACK);
-  fl_polygon(r-1, 0, r-1, c, r-1-c, 0);
-  fl_polygon(-1, r, c-1, r, -1, r-c);
-  fl_line_style(FL_SOLID, 2, 0);
-  fl_line(r-1,1, -1,r+1);
-  fl_line_style(FL_SOLID, 0, 0);
-  fl_end_offscreen();
-  return (CGContextRef)off;
-}
-
-void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
-  if (c == FL_CURSOR_DEFAULT) {
-    c = cursor_default;
-  }
-  if (i) i->set_cursor(c);
-}
+/**
+  Changes the cursor for this window.  This always calls the system, if
+  you are changing the cursor a lot you may want to keep track of how
+  you set it in a static variable and call this only if the new cursor
+  is different.
 
-#else
+  The default cursor will be used if the provided image cannot be used
+  as a cursor.
 
-// I like the MSWindows resize cursors, so I duplicate them here:
+  \see cursor(Fl_Cursor), default_cursor()
+*/
+void Fl_Window::cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+  int ret;
 
-#define CURSORSIZE 16
-#define HOTXY 7
-static struct TableEntry {
-  uchar bits[CURSORSIZE*CURSORSIZE/8];
-  uchar mask[CURSORSIZE*CURSORSIZE/8];
-  Cursor cursor;
-} table[] = {
-  {{	// FL_CURSOR_NS
-   0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
-   0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
-   0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00},
-   {
-   0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
-   0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
-   0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}},
-  {{	// FL_CURSOR_EW
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
-   0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-   {
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
-   0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
-  {{	// FL_CURSOR_NWSE
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
-   0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
-   0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-   {
-   0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
-   0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
-   0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}},
-  {{	// FL_CURSOR_NESW
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e,
-   0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00,
-   0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-   {
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f,
-   0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00,
-   0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}},
-  {{0}, {0}} // FL_CURSOR_NONE & unknown
-};
+  // the cursor must be set for the top level window, not for subwindows
+  Fl_Window *w = window(), *toplevel = this;
 
-void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
-  if (!shown()) return;
-  Cursor xc;
-  int deleteit = 0;
-  if (c == FL_CURSOR_DEFAULT) {
-    c  = cursor_default;
-    fg = cursor_fg;
-    bg = cursor_bg;
+  while (w) {
+    toplevel = w;
+    w = w->window();
   }
 
-  if (!c) {
-    xc = None;
-  } else {
-    if (c >= FL_CURSOR_NS) {
-      TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS);
-      if (!(q->cursor)) {
-	XColor dummy = { 0 };
-	Pixmap p = XCreateBitmapFromData(fl_display,
-	  RootWindow(fl_display, fl_screen), (const char*)(q->bits),
-	  CURSORSIZE, CURSORSIZE);
-	Pixmap m = XCreateBitmapFromData(fl_display,
-	  RootWindow(fl_display, fl_screen), (const char*)(q->mask),
-	  CURSORSIZE, CURSORSIZE);
-	q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy,
-					HOTXY, HOTXY);
-	XFreePixmap(fl_display, m);
-	XFreePixmap(fl_display, p);
-      }
-      xc = q->cursor;
-    } else {
-      xc = XCreateFontCursor(fl_display, (c-1)*2);
-      deleteit = 1;
-    }
-    XColor fgc;
-    uchar r,g,b;
-    Fl::get_color(fg,r,g,b);
-    fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8;
-    XColor bgc;
-    Fl::get_color(bg,r,g,b);
-    bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8;
-    XRecolorCursor(fl_display, xc, &fgc, &bgc);
+  if (toplevel != this) {
+    toplevel->cursor(image, hotx, hoty);
+    return;
   }
-  XDefineCursor(fl_display, fl_xid(this), xc);
-  if (deleteit) XFreeCursor(fl_display, xc);
+
+  if (!i)
+    return;
+
+  ret = i->set_cursor(image, hotx, hoty);
+  if (ret)
+    return;
+
+  cursor(FL_CURSOR_DEFAULT);
 }
 
-#endif
+/* For back compatibility only. */
+void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
+  cursor(c);
+};
+
+void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
+  default_cursor(c);
+};
+
 
 //
 // End of "$Id: fl_cursor.cxx 9278 2012-03-12 11:55:50Z manolo $".
diff -Nur fltk-1.3.2.orig/src/fl_cursor_help.xpm fltk-1.3.2/src/fl_cursor_help.xpm
--- fltk-1.3.2.orig/src/fl_cursor_help.xpm	1970-01-01 01:00:00.000000000 +0100
+++ fltk-1.3.2/src/fl_cursor_help.xpm	2013-07-17 19:37:45.792342890 +0200
@@ -0,0 +1,95 @@
+/* XPM */
+static const char * fl_cursor_help_xpm[] = {
+"16 27 65 1",
+" 	c None",
+".	c #FFFFFF",
+"+	c #E2E2E2",
+"@	c #1C1C1C",
+"#	c #E7E7E7",
+"$	c #000000",
+"%	c #212121",
+"&	c #EAEAEA",
+"*	c #262626",
+"=	c #EDEDED",
+"-	c #2C2C2C",
+";	c #F0F0F0",
+">	c #333333",
+",	c #F1F1F1",
+"'	c #393939",
+")	c #F3F3F3",
+"!	c #404040",
+"~	c #484848",
+"{	c #F4F4F4",
+"]	c #050505",
+"^	c #202020",
+"/	c #707070",
+"(	c #F5F5F5",
+"_	c #040404",
+":	c #E1E1E1",
+"<	c #EEEEEE",
+"[	c #EFEFEF",
+"}	c #FEFEFE",
+"|	c #3D3D3D",
+"1	c #7E7E7E",
+"2	c #696969",
+"3	c #414141",
+"4	c #131313",
+"5	c #080808",
+"6	c #454545",
+"7	c #F2F2F2",
+"8	c #878787",
+"9	c #7D7D7D",
+"0	c #101010",
+"a	c #111111",
+"b	c #FDFDFD",
+"c	c #8A8A8A",
+"d	c #E6E6E6",
+"e	c #7B7B7B",
+"f	c #4C4C4C",
+"g	c #5C5C5C",
+"h	c #9F9F9F",
+"i	c #F9F9F9",
+"j	c #F7F7F7",
+"k	c #B1B1B1",
+"l	c #2E2E2E",
+"m	c #767676",
+"n	c #DCDCDC",
+"o	c #DEDEDE",
+"p	c #C7C7C7",
+"q	c #1B1B1B",
+"r	c #6B6B6B",
+"s	c #575757",
+"t	c #797979",
+"u	c #020202",
+"v	c #010101",
+"w	c #FBFBFB",
+"x	c #D7D7D7",
+"y	c #D8D8D8",
+"z	c #060606",
+"                ",
+".               ",
+".+              ",
+".@#             ",
+".$%&            ",
+".$$*=           ",
+".$$$-;          ",
+".$$$$>,         ",
+".$$$$$')        ",
+".$$$$$$!)       ",
+".$$$$$$$~{      ",
+".$$$$]^^^/(     ",
+".$$$$_:(<<[}    ",
+".$$|1$2<        ",
+".$3,(45[        ",
+".67 78$9,       ",
+".7   {0a( ....  ",
+"b    ,c5[defgh, ",
+"      )ijk_la$m.",
+"         no.p$q.",
+"           .r$s.",
+"          .t$-= ",
+"          7uv+  ",
+"          wxy.  ",
+"          :$z.  ",
+"          :$z.  ",
+"          ....  "};
diff -Nur fltk-1.3.2.orig/src/fl_cursor_nesw.xpm fltk-1.3.2/src/fl_cursor_nesw.xpm
--- fltk-1.3.2.orig/src/fl_cursor_nesw.xpm	1970-01-01 01:00:00.000000000 +0100
+++ fltk-1.3.2/src/fl_cursor_nesw.xpm	2013-07-17 19:37:45.792342890 +0200
@@ -0,0 +1,46 @@
+/* XPM */
+static const char * fl_cursor_nesw_xpm[] = {
+"15 15 28 1",
+" 	c None",
+".	c #FFFFFF",
+"+	c #767676",
+"@	c #000000",
+"#	c #4E4E4E",
+"$	c #0C0C0C",
+"%	c #494949",
+"&	c #4D4D4D",
+"*	c #1B1B1B",
+"=	c #515151",
+"-	c #646464",
+";	c #363636",
+">	c #6A6A6A",
+",	c #545454",
+"'	c #585858",
+")	c #242424",
+"!	c #797979",
+"~	c #2E2E2E",
+"{	c #444444",
+"]	c #3B3B3B",
+"^	c #0A0A0A",
+"/	c #595959",
+"(	c #F7F7F7",
+"_	c #080808",
+":	c #6B6B6B",
+"<	c #FDFDFD",
+"[	c #FCFCFC",
+"}	c #FEFEFE",
+"     ..........",
+"      .+@@@@@@.",
+"       .#@@@@@.",
+"        .$@@@@.",
+"       .%@@@@@.",
+".     .&@@@*@@.",
+"..   .=@@@-.;@.",
+".>. .,@@@'. .).",
+".@!.'@@@#.   ..",
+".@@~@@@{.     .",
+".@@@@@].       ",
+".@@@@^.        ",
+".@@@@@/(       ",
+".______:(      ",
+"<[[[[[[[[}     "};
diff -Nur fltk-1.3.2.orig/src/fl_cursor_none.xpm fltk-1.3.2/src/fl_cursor_none.xpm
--- fltk-1.3.2.orig/src/fl_cursor_none.xpm	1970-01-01 01:00:00.000000000 +0100
+++ fltk-1.3.2/src/fl_cursor_none.xpm	2013-07-17 19:37:45.793342890 +0200
@@ -0,0 +1,19 @@
+/* XPM */
+static const char * fl_cursor_none_xpm[] = {
+"15 15 1 1",
+" 	c None",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               ",
+"               "};
diff -Nur fltk-1.3.2.orig/src/fl_cursor_nwse.xpm fltk-1.3.2/src/fl_cursor_nwse.xpm
--- fltk-1.3.2.orig/src/fl_cursor_nwse.xpm	1970-01-01 01:00:00.000000000 +0100
+++ fltk-1.3.2/src/fl_cursor_nwse.xpm	2013-07-17 19:37:45.793342890 +0200
@@ -0,0 +1,46 @@
+/* XPM */
+static const char * fl_cursor_nwse_xpm[] = {
+"15 15 28 1",
+" 	c None",
+".	c #FFFFFF",
+"+	c #000000",
+"@	c #767676",
+"#	c #4E4E4E",
+"$	c #0C0C0C",
+"%	c #494949",
+"&	c #1B1B1B",
+"*	c #4D4D4D",
+"=	c #363636",
+"-	c #646464",
+";	c #515151",
+">	c #242424",
+",	c #585858",
+"'	c #545454",
+")	c #6A6A6A",
+"!	c #797979",
+"~	c #444444",
+"{	c #2E2E2E",
+"]	c #3B3B3B",
+"^	c #0A0A0A",
+"/	c #F7F7F7",
+"(	c #595959",
+"_	c #6B6B6B",
+":	c #080808",
+"<	c #FEFEFE",
+"[	c #FCFCFC",
+"}	c #FDFDFD",
+"..........     ",
+".++++++@.      ",
+".+++++#.       ",
+".++++$.        ",
+".+++++%.       ",
+".++&+++*.     .",
+".+=.-+++;.   ..",
+".>. .,+++'. .).",
+"..   .#+++,.!+.",
+".     .~+++{++.",
+"       .]+++++.",
+"        .^++++.",
+"       /(+++++.",
+"      /_::::::.",
+"     <[[[[[[[[}"};
diff -Nur fltk-1.3.2.orig/src/fl_cursor_wait.xpm fltk-1.3.2/src/fl_cursor_wait.xpm
--- fltk-1.3.2.orig/src/fl_cursor_wait.xpm	1970-01-01 01:00:00.000000000 +0100
+++ fltk-1.3.2/src/fl_cursor_wait.xpm	2013-07-17 19:37:45.793342890 +0200
@@ -0,0 +1,72 @@
+/* XPM */
+static const char * fl_cursor_wait_xpm[] = {
+"17 32 37 1",
+" 	c None",
+".	c #FFFFFF",
+"+	c #2E2E2E",
+"@	c #202020",
+"#	c #F1F1F1",
+"$	c #2D2D2D",
+"%	c #000000",
+"&	c #EDEDED",
+"*	c #585858",
+"=	c #575757",
+"-	c #FBFBFB",
+";	c #848484",
+">	c #B8B8B8",
+",	c #E5E5E5",
+"'	c #F7F7F7",
+")	c #181818",
+"!	c #F0F0F0",
+"~	c #616161",
+"{	c #B7B7B7",
+"]	c #F5F5F5",
+"^	c #050505",
+"/	c #D4D4D4",
+"(	c #EEEEEE",
+"_	c #595959",
+":	c #7B7B7B",
+"<	c #E9E9E9",
+"[	c #131313",
+"}	c #E3E3E3",
+"|	c #767676",
+"1	c #505050",
+"2	c #F3F3F3",
+"3	c #2A2A2A",
+"4	c #070707",
+"5	c #343434",
+"6	c #939393",
+"7	c #191919",
+"8	c #6A6A6A",
+".................",
+".+@@@@@@@@@@@@@+.",
+".................",
+" #$%%%%%%%%%%%$# ",
+" &*%%%%%%%%%%%=& ",
+" -;%%%%%%%%%%%;- ",
+"  >%%%%%%%%%%%>  ",
+"  ,%%%%%%%%%%%,  ",
+"  ')%%%%%%%%%)'  ",
+"  !~%%%%%%%%%~!  ",
+"   {%%%%%%%%%{   ",
+"   ]^/...../^]   ",
+"   (_:.....:_(   ",
+"    <[}...}[<    ",
+"    !|1...1|!    ",
+"     2[3.3[2     ",
+"     2[%.%[2     ",
+"    !|%%.%%|!    ",
+"    <4%%.%%4<    ",
+"   (_%%%.%%%_(   ",
+"   ]^%%%.%%%^]   ",
+"   {%%%%.%%%%{   ",
+"  !~%%%%.%%%%~!  ",
+"  ')%%%%.%%%%)'  ",
+"  ,%%56{.{65%%,  ",
+"  >%*.......*%>  ",
+" -;7&.......&7;- ",
+" &*8.........8=& ",
+" #$%%%%%%%%%%%$# ",
+".................",
+".+@@@@@@@@@@@@@+.",
+"................."};
diff -Nur fltk-1.3.2.orig/src/Fl.cxx fltk-1.3.2/src/Fl.cxx
--- fltk-1.3.2.orig/src/Fl.cxx	2012-08-16 22:59:36.000000000 +0200
+++ fltk-1.3.2/src/Fl.cxx	2013-07-17 19:38:01.696342059 +0200
@@ -70,6 +70,8 @@
 extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle);
 #endif // WIN32
 
+extern void fl_update_focus(void);
+
 //
 // Globals...
 //
@@ -435,6 +437,69 @@
 #endif
 
 ////////////////////////////////////////////////////////////////
+// Clipboard notifications
+
+struct Clipboard_Notify {
+  Fl_Clipboard_Notify_Handler handler;
+  void *data;
+  struct Clipboard_Notify *next;
+};
+
+static struct Clipboard_Notify *clip_notify_list = NULL;
+
+extern void fl_clipboard_notify_change(); // in Fl_<platform>.cxx
+
+void Fl::add_clipboard_notify(Fl_Clipboard_Notify_Handler h, void *data) {
+  struct Clipboard_Notify *node;
+
+  remove_clipboard_notify(h);
+
+  node = new Clipboard_Notify;
+
+  node->handler = h;
+  node->data = data;
+  node->next = clip_notify_list;
+
+  clip_notify_list = node;
+
+  fl_clipboard_notify_change();
+}
+
+void Fl::remove_clipboard_notify(Fl_Clipboard_Notify_Handler h) {
+  struct Clipboard_Notify *node, **prev;
+
+  node = clip_notify_list;
+  prev = &clip_notify_list;
+  while (node != NULL) {
+    if (node->handler == h) {
+      *prev = node->next;
+      delete node;
+
+      fl_clipboard_notify_change();
+
+      return;
+    }
+
+    prev = &node->next;
+    node = node->next;
+  }
+}
+
+bool fl_clipboard_notify_empty(void) {
+  return clip_notify_list == NULL;
+}
+
+void fl_trigger_clipboard_notify(int source) {
+  struct Clipboard_Notify *node;
+
+  node = clip_notify_list;
+  while (node != NULL) {
+    node->handler(source, node->data);
+    node = node->next;
+  }
+}
+
+////////////////////////////////////////////////////////////////
 // wait/run/check/ready:
 
 void (*Fl::idle)(); // see Fl::add_idle.cxx for the add/remove functions
@@ -876,6 +941,8 @@
       fl_oldfocus = p;
     }
     e_number = old_event;
+    // let the platform code do what it needs
+    fl_update_focus();
   }
 }
 
@@ -1464,6 +1531,8 @@
   if (xclass_) {
     free(xclass_);
   }
+  free_icons();
+  delete icon_;
 }
 
 // FL_SHOW and FL_HIDE are called whenever the visibility of this widget
diff -Nur fltk-1.3.2.orig/src/fl_draw_pixmap.cxx fltk-1.3.2/src/fl_draw_pixmap.cxx
--- fltk-1.3.2.orig/src/fl_draw_pixmap.cxx	2012-04-22 05:09:31.000000000 +0200
+++ fltk-1.3.2/src/fl_draw_pixmap.cxx	2013-07-17 19:37:37.911343302 +0200
@@ -58,99 +58,6 @@
   return 1;
 }
 
-#ifdef U64
-
-// The callback from fl_draw_image to get a row of data passes this:
-struct pixmap_data {
-  int w, h;
-  const uchar*const* data;
-  union {
-    U64 colors[256];
-    U64* byte1[256];
-  };
-};
-
-// callback for 1 byte per pixel:
-static void cb1(void*v, int x, int y, int w, uchar* buf) {
-  pixmap_data& d = *(pixmap_data*)v;
-  const uchar* p = d.data[y]+x;
-  U64* q = (U64*)buf;
-  for (int X=w; X>0; X-=2, p += 2) {
-    if (X>1) {
-#  if WORDS_BIGENDIAN
-      *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]];
-#  else
-      *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]];
-#  endif
-    } else {
-#  if WORDS_BIGENDIAN
-      *q++ = d.colors[p[0]]<<32;
-#  else
-      *q++ = d.colors[p[0]];
-#  endif
-    }
-  }
-}
-
-// callback for 2 bytes per pixel:
-static void cb2(void*v, int x, int y, int w, uchar* buf) {
-  pixmap_data& d = *(pixmap_data*)v;
-  const uchar* p = d.data[y]+2*x;
-  U64* q = (U64*)buf;
-  for (int X=w; X>0; X-=2) {
-    U64* colors = d.byte1[*p++];
-    int index = *p++;
-    if (X>1) {
-      U64* colors1 = d.byte1[*p++];
-      int index1 = *p++;
-#  if WORDS_BIGENDIAN
-      *q++ = (colors[index]<<32) | colors1[index1];
-#  else
-      *q++ = (colors1[index1]<<32) | colors[index];
-#  endif
-    } else {
-#  if WORDS_BIGENDIAN
-      *q++ = colors[index]<<32;
-#  else
-      *q++ = colors[index];
-#  endif
-    }
-  }
-}
-
-#else // U32
-
-// The callback from fl_draw_image to get a row of data passes this:
-struct pixmap_data {
-  int w, h;
-  const uchar*const* data;
-  union {
-    U32 colors[256];
-    U32* byte1[256];
-  };
-};
-
-// callback for 1 byte per pixel:
-static void cb1(void*v, int x, int y, int w, uchar* buf) {
-  pixmap_data& d = *(pixmap_data*)v;
-  const uchar* p = d.data[y]+x;
-  U32* q = (U32*)buf;
-  for (int X=w; X--;) *q++ = d.colors[*p++];
-}
-
-// callback for 2 bytes per pixel:
-static void cb2(void*v, int x, int y, int w, uchar* buf) {
-  pixmap_data& d = *(pixmap_data*)v;
-  const uchar* p = d.data[y]+2*x;
-  U32* q = (U32*)buf;
-  for (int X=w; X--;) {
-    U32* colors = d.byte1[*p++];
-    *q++ = colors[*p++];
-  }
-}
-
-#endif // U64 else U32
-
 uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here
 
 /**
@@ -200,34 +107,33 @@
 }
 #endif
 
-/**
-  Draw XPM image data, with the top-left corner at the given position.
-  \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg)
-  */
-int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
-  pixmap_data d;
-  if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0;
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
+  int w, h;
   const uchar*const* data = (const uchar*const*)(cdata+1);
   int transparent_index = -1;
+
+  if (!fl_measure_pixmap(cdata, w, h))
+    return 0;
+
+  if ((chars_per_pixel < 1) || (chars_per_pixel > 2))
+    return 0;
+
+  uchar colors[1<<(chars_per_pixel*8)][4];
+
 #ifdef WIN32
   uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
   color_count = 0;
   used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar));
 #endif
 
-  if (ncolors < 0) {	// FLTK (non standard) compressed colormap
+  if (ncolors < 0) {
+    // FLTK (non standard) compressed colormap
     ncolors = -ncolors;
     const uchar *p = *data++;
     // if first color is ' ' it is transparent (put it later to make
     // it not be transparent):
     if (*p == ' ') {
-      uchar* c = (uchar*)&d.colors[(int)' '];
-#ifdef U64
-      *(U64*)c = 0;
-#  if WORDS_BIGENDIAN
-      c += 4;
-#  endif
-#endif
+      uchar* c = colors[(int)' '];
       transparent_index = ' ';
       Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
 #ifdef WIN32
@@ -238,13 +144,7 @@
     }
     // read all the rest of the colors:
     for (int i=0; i < ncolors; i++) {
-      uchar* c = (uchar*)&d.colors[*p++];
-#ifdef U64
-      *(U64*)c = 0;
-#  if WORDS_BIGENDIAN
-      c += 4;
-#  endif
-#endif
+      uchar* c = colors[*p++];
 #ifdef WIN32
       used_colors[3*color_count] = *p;
       used_colors[3*color_count+1] = *(p+1);
@@ -254,69 +154,44 @@
       *c++ = *p++;
       *c++ = *p++;
       *c++ = *p++;
-#ifdef __APPLE_QUARTZ__
       *c = 255;
-#else
-      *c = 0;
-#endif
     }
-  } else {	// normal XPM colormap with names
-    if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1));
+  } else {
+    // normal XPM colormap with names
     for (int i=0; i<ncolors; i++) {
       const uchar *p = *data++;
       // the first 1 or 2 characters are the color index:
       int ind = *p++;
       uchar* c;
-      if (chars_per_pixel>1) {
-#ifdef U64
-	U64* colors = d.byte1[ind];
-	if (!colors) colors = d.byte1[ind] = new U64[256];
-#else
-	U32* colors = d.byte1[ind];
-	if (!colors) colors = d.byte1[ind] = new U32[256];
-#endif
-	c = (uchar*)&colors[*p];
-	ind = (ind<<8)|*p++;
-      } else {
-	c = (uchar *)&d.colors[ind];
-      }
+      if (chars_per_pixel>1)
+        ind = (ind<<8)|*p++;
+      c = colors[ind];
       // look for "c word", or last word if none:
       const uchar *previous_word = p;
       for (;;) {
-	while (*p && isspace(*p)) p++;
-	uchar what = *p++;
-	while (*p && !isspace(*p)) p++;
-	while (*p && isspace(*p)) p++;
-	if (!*p) {p = previous_word; break;}
-	if (what == 'c') break;
-	previous_word = p;
-	while (*p && !isspace(*p)) p++;
+        while (*p && isspace(*p)) p++;
+        uchar what = *p++;
+        while (*p && !isspace(*p)) p++;
+        while (*p && isspace(*p)) p++;
+        if (!*p) {p = previous_word; break;}
+        if (what == 'c') break;
+        previous_word = p;
+        while (*p && !isspace(*p)) p++;
       }
-#ifdef U64
-      *(U64*)c = 0;
-#  if WORDS_BIGENDIAN
-      c += 4;
-#  endif
-#endif
-#ifdef __APPLE_QUARTZ__
-      c[3] = 255;
-#endif
       int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]);
+      c[3] = 255;
       if (parse) {
 #ifdef WIN32
-	used_colors[3*color_count] = c[0];
-	used_colors[3*color_count+1] = c[1];
-	used_colors[3*color_count+2] = c[2];
-	color_count++;
+        used_colors[3*color_count] = c[0];
+        used_colors[3*color_count+1] = c[1];
+        used_colors[3*color_count+2] = c[2];
+        color_count++;
 #endif
-	}
-      else {
+      } else {
         // assume "None" or "#transparent" for any errors
-	// "bg" should be transparent...
-	Fl::get_color(bg, c[0], c[1], c[2]);
-#ifdef __APPLE_QUARTZ__
+        // "bg" should be transparent...
+        Fl::get_color(bg, c[0], c[1], c[2]);
         c[3] = 0;
-#endif
 	transparent_index = ind;
 #ifdef WIN32
 	transparent_c = c;
@@ -324,7 +199,6 @@
       }
     }
   }
-  d.data = data;
 #ifdef WIN32
   if (transparent_c) {
     make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
@@ -334,77 +208,76 @@
     make_unused_color(r, g, b);
   }
 #endif
+
+  U32 *q = (U32*)out;
+  for (int Y = 0; Y < h; Y++) {
+    const uchar* p = data[Y];
+    if (chars_per_pixel <= 1) {
+      for (int X = 0; X < w; X++)
+        memcpy(q++, colors[*p++], 4);
+    } else {
+      for (int X = 0; X < w; X++) {
+        int ind = (*p++)<<8;
+        ind |= *p++;
+        memcpy(q++, colors[ind], 4);
+      }
+    }
+  }
   
+  return 1;
+}
+
+/**
+  Draw XPM image data, with the top-left corner at the given position.
+  \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg)
+  */
+int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
+  int w, h;
+
+  if (!fl_measure_pixmap(cdata, w, h))
+    return 0;
+
+  uchar buffer[w*h*4];
+
+  if (!fl_convert_pixmap(cdata, buffer, bg))
+    return 0;
+
+  // FIXME: Hack until fl_draw_image() supports alpha properly
 #ifdef  __APPLE_QUARTZ__
   if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) {
-    U32 *array = new U32[d.w * d.h], *q = array;
-    for (int Y = 0; Y < d.h; Y++) {
-      const uchar* p = data[Y];
-      if (chars_per_pixel <= 1) {
-	for (int X = 0; X < d.w; X++) {
-	  *q++ = d.colors[*p++];
-	}
-      } else {
-	for (int X = 0; X < d.w; X++) {
-	  U32* colors = (U32*)d.byte1[*p++];
-	  *q++ = colors[*p++];
-	}
-      }
-    }
-    Fl_RGB_Image* rgb = new Fl_RGB_Image((uchar*)array, d.w, d.h, 4);
+    Fl_RGB_Image* rgb = new Fl_RGB_Image(buffer, w, h, 4);
     rgb->draw(x, y);
     delete rgb;
-    delete[] array;
-    }
-  else {
+  } else {
 #endif // __APPLE_QUARTZ__
-
   // build the mask bitmap used by Fl_Pixmap:
-  if (fl_mask_bitmap && transparent_index >= 0) {
-    int W = (d.w+7)/8;
-    uchar* bitmap = new uchar[W * d.h];
+  if (fl_mask_bitmap) {
+    int W = (w+7)/8;
+    uchar* bitmap = new uchar[W * h];
     *fl_mask_bitmap = bitmap;
-    for (int Y = 0; Y < d.h; Y++) {
-      const uchar* p = data[Y];
-      if (chars_per_pixel <= 1) {
-	int dw = d.w;
-	for (int X = 0; X < W; X++) {
-	  uchar b = (dw-->0 && *p++ != transparent_index);
-	  if (dw-->0 && *p++ != transparent_index) b |= 2;
-	  if (dw-->0 && *p++ != transparent_index) b |= 4;
-	  if (dw-->0 && *p++ != transparent_index) b |= 8;
-	  if (dw-->0 && *p++ != transparent_index) b |= 16;
-	  if (dw-->0 && *p++ != transparent_index) b |= 32;
-	  if (dw-->0 && *p++ != transparent_index) b |= 64;
-	  if (dw-->0 && *p++ != transparent_index) b |= 128;
+    const uchar *p = &buffer[3];
+    uchar b = 0;
+    for (int Y = 0; Y < h; Y++) {
+      b = 0;
+      for (int X = 0, bit = 1; X < w; X++, p += 4) {
+	if (*p > 127) b |= bit;
+	bit <<= 1;
+	if (bit > 0x80 || X == w-1) {
 	  *bitmap++ = b;
-	}
-      } else {
-        uchar b = 0, bit = 1;
-	for (int X = 0; X < d.w; X++) {
-	  int ind = *p++;
-	  ind = (ind<<8) | (*p++);
-	  if (ind != transparent_index) b |= bit;
-
-          if (bit < 128) bit <<= 1;
-	  else {
-	    *bitmap++ = b;
-	    b = 0;
-	    bit = 1;
+	  bit = 1;
+	  b = 0;
 	  }
 	}
-
-        if (bit > 1) *bitmap++ = b;
       }
-    }
+    
   }
 
-  fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
+  fl_draw_image(buffer, x, y, w, h, 4);
+
 #ifdef __APPLE_QUARTZ__
     }
 #endif
 
-  if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i];
   return 1;
 }
 
diff -Nur fltk-1.3.2.orig/src/Fl_grab.cxx fltk-1.3.2/src/Fl_grab.cxx
--- fltk-1.3.2.orig/src/Fl_grab.cxx	2012-03-23 17:47:53.000000000 +0100
+++ fltk-1.3.2/src/Fl_grab.cxx	2013-07-17 19:37:07.411344886 +0200
@@ -29,6 +29,7 @@
 // override_redirect, it does similar things on WIN32.
 
 extern void fl_fix_focus(); // in Fl.cxx
+void fl_update_focus(void);
 
 #ifdef WIN32
 // We have to keep track of whether we have captured the mouse, since
@@ -80,6 +81,7 @@
 #endif
     }
     grab_ = win;
+    fl_update_focus();
   } else {
     if (grab_) {
 #ifdef WIN32
@@ -98,6 +100,7 @@
       XFlush(fl_display);
 #endif
       grab_ = 0;
+      fl_update_focus();
       fl_fix_focus();
     }
   }
diff -Nur fltk-1.3.2.orig/src/Fl_Image.cxx fltk-1.3.2/src/Fl_Image.cxx
--- fltk-1.3.2.orig/src/Fl_Image.cxx	2012-11-09 17:02:08.000000000 +0100
+++ fltk-1.3.2/src/Fl_Image.cxx	2013-07-17 19:37:37.911343302 +0200
@@ -165,7 +165,22 @@
 //
 size_t Fl_RGB_Image::max_size_ = ~((size_t)0);
 
-/**  The destructor free all memory and server resources that are used by  the image. */
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg);
+
+/** The constructor creates a new RGBA image from the specified Fl_Pixmap. 
+ 
+ The RGBA image is built fully opaque except for the transparent area
+ of the pixmap that is assigned the \par bg color with full transparency */
+Fl_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg):
+  Fl_Image(pxm->w(), pxm->h(), 4), id_(0), mask_(0)
+{
+  array = new uchar[w() * h() * d()];
+  alloc_array = 1;
+  fl_convert_pixmap(pxm->data(), (uchar*)array, bg);
+  data((const char **)&array, 1);
+}
+
+/**  The destructor frees all memory and server resources that are used by the image. */
 Fl_RGB_Image::~Fl_RGB_Image() {
   uncache();
   if (alloc_array) delete[] (uchar *)array;
diff -Nur fltk-1.3.2.orig/src/Fl_win32.cxx fltk-1.3.2/src/Fl_win32.cxx
--- fltk-1.3.2.orig/src/Fl_win32.cxx	2012-06-21 10:52:29.000000000 +0200
+++ fltk-1.3.2/src/Fl_win32.cxx	2013-07-17 19:38:17.322341239 +0200
@@ -942,6 +942,10 @@
     break;
 
   case WM_SETFOCUS:
+    if ((Fl::modal_) && (Fl::modal_ != window)) {
+      SetFocus(fl_xid(Fl::modal_));
+      return 0;
+    }
     Fl::handle(FL_FOCUS, window);
     break;
 
@@ -1333,7 +1337,6 @@
   Y+=yoff;
 
   if (w->fullscreen_active()) {
-    X = Y = 0;
     bx = by = bt = 0;
   }
 
@@ -1387,19 +1390,42 @@
   }
 }
 
-static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) {
+void Fl_X::make_fullscreen(int X, int Y, int W, int H) {
+  int top, bottom, left, right;
   int sx, sy, sw, sh;
-  Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H);
+
+  top = w->fullscreen_screen_top;
+  bottom = w->fullscreen_screen_bottom;
+  left = w->fullscreen_screen_left;
+  right = w->fullscreen_screen_right;
+
+  if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+    top = Fl::screen_num(X, Y, W, H);
+    bottom = top;
+    left = top;
+    right = top;
+  }
+
+  Fl::screen_xywh(sx, sy, sw, sh, top);
+  Y = sy;
+  Fl::screen_xywh(sx, sy, sw, sh, bottom);
+  H = sy + sh - Y;
+  Fl::screen_xywh(sx, sy, sw, sh, left);
+  X = sx;
+  Fl::screen_xywh(sx, sy, sw, sh, right);
+  W = sx + sw - X;
+
   DWORD flags = GetWindowLong(xid, GWL_STYLE);
   flags = flags & ~(WS_THICKFRAME|WS_CAPTION);
   SetWindowLong(xid, GWL_STYLE, flags);
+
   // SWP_NOSENDCHANGING is so that we can override size limits
-  SetWindowPos(xid, HWND_TOP, sx, sy, sw, sh, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
+  SetWindowPos(xid, HWND_TOP, X, Y, W, H, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
 }
 
 void Fl_Window::fullscreen_x() {
   _set_fullscreen();
-  make_fullscreen(this, fl_xid(this), x(), y(), w(), h());
+  i->make_fullscreen(x(), y(), w(), h());
   Fl::handle(FL_FULLSCREEN, this);
 }
 
@@ -1477,7 +1503,6 @@
 
 char fl_show_iconic;	// hack for Fl_Window::iconic()
 // int fl_background_pixel = -1; // color to use for background
-HCURSOR fl_default_cursor;
 UINT fl_wake_msg = 0;
 int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
 
@@ -1526,7 +1551,7 @@
     if (!w->icon())
       w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
     wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
-    wcw.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
+    wcw.hCursor = LoadCursor(NULL, IDC_ARROW);
     //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
     //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
     wcw.hbrBackground = NULL;
@@ -1618,7 +1643,8 @@
   x->setwindow(w);
   x->region = 0;
   x->private_dc = 0;
-  x->cursor = fl_default_cursor;
+  x->cursor = LoadCursor(NULL, IDC_ARROW);
+  x->custom_cursor = 0;
   if (!fl_codepage) fl_get_codepage();
 
   WCHAR *lab = NULL;
@@ -1644,6 +1670,8 @@
   );
   if (lab) free(lab);
 
+  x->set_icons();
+
   if (w->fullscreen_active()) {
   /* We need to make sure that the fullscreen is created on the
      default monitor, ie the desktop where the shortcut is located
@@ -1652,8 +1680,8 @@
      monitor the window was placed on. */
     RECT rect;
     GetWindowRect(x->xid, &rect);
-    make_fullscreen(w, x->xid, rect.left, rect.top, 
-                    rect.right - rect.left, rect.bottom - rect.top);
+    x->make_fullscreen(rect.left, rect.top, 
+                       rect.right - rect.left, rect.bottom - rect.top);
   }
 
   x->next = Fl_X::first;
@@ -1668,6 +1696,11 @@
     Fl::e_number = old_event;
     w->redraw(); // force draw to happen
   }
+
+  // Needs to be done before ShowWindow() to get the correct behaviour
+  // when we get WM_SETFOCUS.
+  if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
+
   // If we've captured the mouse, we dont want to activate any
   // other windows from the code, or we lose the capture.
   ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
@@ -1685,7 +1718,6 @@
     }
   }
 
-  if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
   return x;
 }
 
@@ -1867,6 +1899,285 @@
 }
 
 ////////////////////////////////////////////////////////////////
+
+static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon=true,
+                           int hotx = 0, int hoty = 0) {
+  BITMAPV5HEADER bi;
+  HBITMAP bitmap, mask;
+  DWORD *bits;
+  HICON icon;
+
+  if (!is_icon) {
+  if ((hotx < 0) || (hotx >= image->w()))
+      return NULL;
+  if ((hoty < 0) || (hoty >= image->h()))
+      return NULL;
+  }
+
+  memset(&bi, 0, sizeof(BITMAPV5HEADER));
+
+  bi.bV5Size        = sizeof(BITMAPV5HEADER);
+  bi.bV5Width       = image->w();
+  bi.bV5Height      = -image->h(); // Negative for top-down
+  bi.bV5Planes      = 1;
+  bi.bV5BitCount    = 32;
+  bi.bV5Compression = BI_BITFIELDS;
+  bi.bV5RedMask     = 0x00FF0000;
+  bi.bV5GreenMask   = 0x0000FF00;
+  bi.bV5BlueMask    = 0x000000FF;
+  bi.bV5AlphaMask   = 0xFF000000;
+
+  HDC hdc;
+
+  hdc = GetDC(NULL);
+  bitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+  ReleaseDC(NULL, hdc);
+
+  if (bits == NULL)
+    return NULL;
+
+  const uchar *i = (const uchar*)*image->data();
+  for (int y = 0;y < image->h();y++) {
+    for (int x = 0;x < image->w();x++) {
+      switch (image->d()) {
+      case 1:
+        *bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+        break;
+      case 2:
+        *bits = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+        break;
+      case 3:
+        *bits = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+        break;
+      case 4:
+        *bits = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+        break;
+      }
+      i += image->d();
+      bits++;
+    }
+    i += image->ld();
+  }
+
+  // A mask bitmap is still needed even though it isn't used
+  mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
+  if (mask == NULL) {
+    DeleteObject(bitmap);
+    return NULL;
+  }
+
+  ICONINFO ii;
+
+  ii.fIcon    = is_icon;
+  ii.xHotspot = hotx;
+  ii.yHotspot = hoty;
+  ii.hbmMask  = mask;
+  ii.hbmColor = bitmap;
+
+  icon = CreateIconIndirect(&ii);
+
+  DeleteObject(bitmap);
+  DeleteObject(mask);
+
+  if (icon == NULL)
+    return NULL;
+
+  return icon;
+}
+
+////////////////////////////////////////////////////////////////
+
+static HICON default_big_icon = NULL;
+static HICON default_small_icon = NULL;
+
+const Fl_RGB_Image *find_best_icon(int ideal_width, 
+                                   const Fl_RGB_Image *icons[], int count) {
+  const Fl_RGB_Image *best;
+
+  best = NULL;
+
+  for (int i = 0;i < count;i++) {
+    if (best == NULL)
+      best = icons[i];
+    else {
+      if (best->w() < ideal_width) {
+        if (icons[i]->w() > best->w())
+          best = icons[i];
+      } else {
+        if ((icons[i]->w() >= ideal_width) &&
+            (icons[i]->w() < best->w()))
+          best = icons[i];
+      }
+    }
+  }
+
+  return best;
+}
+
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
+  const Fl_RGB_Image *best_big, *best_small;
+
+  if (default_big_icon != NULL)
+    DestroyIcon(default_big_icon);
+  if (default_small_icon != NULL)
+    DestroyIcon(default_small_icon);
+
+  best_big = find_best_icon(GetSystemMetrics(SM_CXICON), icons, count);
+  best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), icons, count);
+
+  if (best_big != NULL)
+    default_big_icon = image_to_icon(best_big);
+  else
+    default_big_icon = NULL;
+
+  if (best_small != NULL)
+    default_small_icon = image_to_icon(best_small);
+  else
+    default_small_icon = NULL;
+}
+
+void Fl_X::set_default_icons(HICON big_icon, HICON small_icon) {
+  if (default_big_icon != NULL)
+    DestroyIcon(default_big_icon);
+  if (default_small_icon != NULL)
+    DestroyIcon(default_small_icon);
+
+  if (big_icon != NULL)
+    default_big_icon = CopyIcon(big_icon);
+  if (small_icon != NULL)
+    default_small_icon = CopyIcon(small_icon);
+}
+
+void Fl_X::set_icons() {
+  HICON big_icon, small_icon;
+
+  big_icon = NULL;
+  small_icon = NULL;
+
+  if (w->icon_->count) {
+    const Fl_RGB_Image *best_big, *best_small;
+
+    best_big = find_best_icon(GetSystemMetrics(SM_CXICON),
+                              (const Fl_RGB_Image **)w->icon_->icons,
+                              w->icon_->count);
+    best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON),
+                                (const Fl_RGB_Image **)w->icon_->icons,
+                                w->icon_->count);
+
+    if (best_big != NULL)
+      big_icon = image_to_icon(best_big);
+    if (best_small != NULL)
+      small_icon = image_to_icon(best_small);
+  } else {
+    big_icon = default_big_icon;
+    small_icon = default_small_icon;
+  }
+
+  if (big_icon != NULL)
+    SendMessage(xid, WM_SETICON, ICON_BIG, (LPARAM)big_icon);
+  if (small_icon != NULL)
+    SendMessage(xid, WM_SETICON, ICON_SMALL, (LPARAM)small_icon);
+
+  if (w->icon_->count) {
+    if (big_icon != NULL)
+      DestroyIcon(big_icon);
+    if (small_icon != NULL)
+      DestroyIcon(small_icon);
+  }
+}
+
+void Fl_Window::default_icons(HICON big_icon, HICON small_icon) {
+  Fl_X::set_default_icons(big_icon, small_icon);
+}
+
+void Fl_Window::icons(HICON big_icon, HICON small_icon) {
+  free_icons();
+
+  if (big_icon != NULL)
+    icon_->big_icon = CopyIcon(big_icon);
+  if (small_icon != NULL)
+    icon_->small_icon = CopyIcon(small_icon);
+
+  if (i)
+    i->set_icons();
+}
+
+////////////////////////////////////////////////////////////////
+
+#ifndef IDC_HAND
+#  define IDC_HAND  MAKEINTRESOURCE(32649)
+#endif // !IDC_HAND
+
+int Fl_X::set_cursor(Fl_Cursor c) {
+  LPSTR n;
+  HCURSOR new_cursor;
+
+  if (c == FL_CURSOR_NONE)
+    new_cursor = NULL;
+  else {
+    switch (c) {
+    case FL_CURSOR_ARROW:   n = IDC_ARROW; break;
+    case FL_CURSOR_CROSS:   n = IDC_CROSS; break;
+    case FL_CURSOR_WAIT:    n = IDC_WAIT; break;
+    case FL_CURSOR_INSERT:  n = IDC_IBEAM; break;
+    case FL_CURSOR_HAND:    n = IDC_HAND; break;
+    case FL_CURSOR_HELP:    n = IDC_HELP; break;
+    case FL_CURSOR_MOVE:    n = IDC_SIZEALL; break;
+    case FL_CURSOR_N:
+    case FL_CURSOR_S:
+      // FIXME: Should probably have fallbacks for these instead
+    case FL_CURSOR_NS:      n = IDC_SIZENS; break;
+    case FL_CURSOR_NE:
+    case FL_CURSOR_SW:
+      // FIXME: Dito.
+    case FL_CURSOR_NESW:    n = IDC_SIZENESW; break;
+    case FL_CURSOR_E:
+    case FL_CURSOR_W:
+      // FIXME: Dito.
+    case FL_CURSOR_WE:      n = IDC_SIZEWE; break;
+    case FL_CURSOR_SE:
+    case FL_CURSOR_NW:
+      // FIXME: Dito.
+    case FL_CURSOR_NWSE:    n = IDC_SIZENWSE; break;
+    default:
+      return 0;
+    }
+
+    new_cursor = LoadCursor(NULL, n);
+    if (new_cursor == NULL)
+      return 0;
+  }
+
+  if ((cursor != NULL) && custom_cursor)
+    DestroyIcon(cursor);
+
+  cursor = new_cursor;
+  custom_cursor = 0;
+
+  SetCursor(cursor);
+
+  return 1;
+}
+
+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+  HCURSOR new_cursor;
+
+  new_cursor = image_to_icon(image, false, hotx, hoty);
+  if (new_cursor == NULL)
+    return 0;
+
+  if ((cursor != NULL) && custom_cursor)
+    DestroyIcon(cursor);
+
+  cursor = new_cursor;
+  custom_cursor = 1;
+
+  SetCursor(cursor);
+
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
 // Implement the virtual functions for the base Fl_Window class:
 
 // If the box is a filled rectangle, we can make the redisplay *look*
diff -Nur fltk-1.3.2.orig/src/Fl_Window.cxx fltk-1.3.2/src/Fl_Window.cxx
--- fltk-1.3.2.orig/src/Fl_Window.cxx	2012-11-06 21:46:14.000000000 +0100
+++ fltk-1.3.2/src/Fl_Window.cxx	2013-07-17 19:38:01.699342056 +0200
@@ -23,6 +23,7 @@
 #include <config.h>
 #include <FL/Fl.H>
 #include <FL/x.H>
+#include <FL/Fl_RGB_Image.H>
 #include <FL/Fl_Window.H>
 #include <stdlib.h>
 #include "flstring.h"
@@ -45,7 +46,8 @@
   }
   i = 0;
   xclass_ = 0;
-  icon_ = 0;
+  icon_ = new icon_data;
+  memset(icon_, 0, sizeof(*icon_));
   iconlabel_ = 0;
   resizable(0);
   size_range_set = 0;
@@ -62,8 +64,6 @@
 Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l)
 : Fl_Group(X, Y, W, H, l) {
   cursor_default = FL_CURSOR_DEFAULT;
-  cursor_fg      = FL_BLACK;
-  cursor_bg      = FL_WHITE;
 
   _Fl_Window();
   set_flag(FORCE_POSITION);
@@ -73,8 +73,6 @@
 // fix common user error of a missing end() with current(0):
   : Fl_Group((Fl_Group::current(0),0), 0, W, H, l) {
   cursor_default = FL_CURSOR_DEFAULT;
-  cursor_fg      = FL_BLACK;
-  cursor_bg      = FL_WHITE;
 
   _Fl_Window();
   clear_visible();
@@ -268,16 +266,68 @@
   }
 }
 
+void Fl_Window::default_icon(const Fl_RGB_Image *icon) {
+  default_icons(&icon, 1);
+}
+
+void Fl_Window::default_icons(const Fl_RGB_Image **icons, int count) {
+  Fl_X::set_default_icons(icons, count);
+}
+
+void Fl_Window::icon(const Fl_RGB_Image *icon) {
+  icons(&icon, 1);
+}
+
+void Fl_Window::icons(const Fl_RGB_Image **icons, int count) {
+  free_icons();
+
+  if (count > 0) {
+    icon_->icons = new Fl_RGB_Image*[count];
+    icon_->count = count;
+    // FIXME: Fl_RGB_Image lacks const modifiers on methods
+    for (int i = 0;i < count;i++)
+      icon_->icons[i] = (Fl_RGB_Image*)((Fl_RGB_Image*)icons[i])->copy();
+  }
+
+  if (i)
+    i->set_icons();
+}
+
 /** Gets the current icon window target dependent data. */
 const void *Fl_Window::icon() const {
-  return icon_;
+  return icon_->legacy_icon;
 }
 
 /** Sets the current icon window target dependent data. */
 void Fl_Window::icon(const void * ic) {
-  icon_ = ic;
+  free_icons();
+  icon_->legacy_icon = ic;
 }
 
+void Fl_Window::free_icons() {
+  int i;
+
+  icon_->legacy_icon = 0L;
+
+  if (icon_->icons) {
+    for (i = 0;i < icon_->count;i++)
+      delete icon_->icons[i];
+    delete [] icon_->icons;
+    icon_->icons = 0L;
+  }
+
+  icon_->count = 0;
+
+#ifdef WIN32
+  if (icon_->big_icon)
+    DestroyIcon(icon_->big_icon);
+  if (icon_->small_icon)
+    DestroyIcon(icon_->small_icon);
+
+  icon_->big_icon = NULL;
+  icon_->small_icon = NULL;
+#endif
+}
 
 //
 // End of "$Id: Fl_Window.cxx 9706 2012-11-06 20:46:14Z matt $".
diff -Nur fltk-1.3.2.orig/src/Fl_Window_fullscreen.cxx fltk-1.3.2/src/Fl_Window_fullscreen.cxx
--- fltk-1.3.2.orig/src/Fl_Window_fullscreen.cxx	2012-11-06 21:46:14.000000000 +0100
+++ fltk-1.3.2/src/Fl_Window_fullscreen.cxx	2013-07-17 19:38:17.323341239 +0200
@@ -36,6 +36,10 @@
 int Fl_Window::no_fullscreen_y = 0;
 int Fl_Window::no_fullscreen_w = 0;
 int Fl_Window::no_fullscreen_h = 0;
+int Fl_Window::fullscreen_screen_top = -1;
+int Fl_Window::fullscreen_screen_bottom = -1;
+int Fl_Window::fullscreen_screen_left = -1;
+int Fl_Window::fullscreen_screen_right = -1;
 #endif
 
 void Fl_Window::border(int b) {
@@ -95,6 +99,23 @@
   fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h);
 }
 
+void Fl_Window::fullscreen_screens(int top, int bottom, int left, int right) {
+  if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+    fullscreen_screen_top = -1;
+    fullscreen_screen_bottom = -1;
+    fullscreen_screen_left = -1;
+    fullscreen_screen_right = -1;
+  } else {
+    fullscreen_screen_top = top;
+    fullscreen_screen_bottom = bottom;
+    fullscreen_screen_left = left;
+    fullscreen_screen_right = right;
+  }
+
+  if (shown() && (flags() & Fl_Widget::FULLSCREEN))
+    fullscreen_x();
+}
+
 
 //
 // End of "$Id: Fl_Window_fullscreen.cxx 9706 2012-11-06 20:46:14Z matt $".
diff -Nur fltk-1.3.2.orig/src/Fl_x.cxx fltk-1.3.2/src/Fl_x.cxx
--- fltk-1.3.2.orig/src/Fl_x.cxx	2012-10-16 17:35:34.000000000 +0200
+++ fltk-1.3.2/src/Fl_x.cxx	2013-07-17 19:38:17.326341239 +0200
@@ -53,6 +53,17 @@
 static int randrEventBase;                  // base of RandR-defined events
 #endif
 
+#  if HAVE_XFIXES
+#  include <X11/extensions/Xfixes.h>
+static int xfixes_event_base = 0;
+static bool have_xfixes = false;
+#  endif
+
+#  include <X11/cursorfont.h>
+
+#  if HAVE_XCURSOR
+#    include <X11/Xcursor/Xcursor.h>
+#  endif
 static Fl_Xlib_Graphics_Driver fl_xlib_driver;
 static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
 Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display
@@ -298,6 +309,7 @@
 Colormap fl_colormap;
 XIM fl_xim_im = 0;
 XIC fl_xim_ic = 0;
+Window fl_xim_win = 0;
 char fl_is_over_the_spot = 0;
 static XRectangle status_area;
 
@@ -306,6 +318,9 @@
 static Atom fl_MOTIF_WM_HINTS;
 static Atom TARGETS;
 static Atom CLIPBOARD;
+static Atom TIMESTAMP;
+static Atom PRIMARY_TIMESTAMP;
+static Atom CLIPBOARD_TIMESTAMP;
 Atom fl_XdndAware;
 Atom fl_XdndSelection;
 Atom fl_XdndEnter;
@@ -329,7 +344,9 @@
 Atom fl_NET_SUPPORTING_WM_CHECK;
 Atom fl_NET_WM_STATE;
 Atom fl_NET_WM_STATE_FULLSCREEN;
+Atom fl_NET_WM_FULLSCREEN_MONITORS;
 Atom fl_NET_WORKAREA;
+Atom fl_NET_WM_ICON;
 
 /*
   X defines 32-bit-entities to have a format value of max. 32,
@@ -583,6 +600,65 @@
   if(xim_styles) XFree(xim_styles);
 }
 
+void fl_xim_deactivate(void);
+
+void fl_xim_activate(Window xid)
+{
+  if (!fl_xim_im)
+    return;
+
+  // If the focused window has changed, then use the brute force method
+  // of completely recreating the input context.
+  if (fl_xim_win != xid) {
+    fl_xim_deactivate();
+
+    fl_new_ic();
+    fl_xim_win = xid;
+
+    XSetICValues(fl_xim_ic,
+                 XNFocusWindow, fl_xim_win,
+                 XNClientWindow, fl_xim_win,
+                 NULL);
+  }
+
+  fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
+}
+
+void fl_xim_deactivate(void)
+{
+  if (!fl_xim_ic)
+    return;
+
+  XDestroyIC(fl_xim_ic);
+  fl_xim_ic = NULL;
+
+  fl_xim_win = 0;
+}
+
+extern Fl_Window *fl_xfocus;
+
+void fl_update_focus(void)
+{
+  Fl_Widget *focus;
+
+  focus = Fl::grab();
+  if (!focus)
+    focus = Fl::focus();
+  if (!focus)
+    return;
+
+  if (focus->simple_keyboard()) {
+    fl_xim_deactivate();
+  } else {
+    // fl_xfocus should always be set if something has focus, but let's
+    // play it safe
+    if (!fl_xfocus || !fl_xid(fl_xfocus))
+      return;
+
+    fl_xim_activate(fl_xid(fl_xfocus));
+  }
+}
+
 void fl_open_display() {
   if (fl_display) return;
 
@@ -607,6 +683,9 @@
   fl_MOTIF_WM_HINTS     = XInternAtom(d, "_MOTIF_WM_HINTS",     0);
   TARGETS               = XInternAtom(d, "TARGETS",             0);
   CLIPBOARD             = XInternAtom(d, "CLIPBOARD",           0);
+  TIMESTAMP             = XInternAtom(d, "TIMESTAMP",           0);
+  PRIMARY_TIMESTAMP     = XInternAtom(d, "PRIMARY_TIMESTAMP",   0);
+  CLIPBOARD_TIMESTAMP   = XInternAtom(d, "CLIPBOARD_TIMESTAMP", 0);
   fl_XdndAware          = XInternAtom(d, "XdndAware",           0);
   fl_XdndSelection      = XInternAtom(d, "XdndSelection",       0);
   fl_XdndEnter          = XInternAtom(d, "XdndEnter",           0);
@@ -631,7 +710,9 @@
   fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
   fl_NET_WM_STATE       = XInternAtom(d, "_NET_WM_STATE",       0);
   fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
+  fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0);
   fl_NET_WORKAREA       = XInternAtom(d, "_NET_WORKAREA",       0);
+  fl_NET_WM_ICON        = XInternAtom(d, "_NET_WM_ICON",        0);
 
   if (sizeof(Atom) < 4)
     atom_bits = sizeof(Atom) * 8;
@@ -653,6 +734,15 @@
 #if !USE_COLORMAP
   Fl::visual(FL_RGB);
 #endif
+
+#if HAVE_XFIXES
+  int error_base;
+  if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base))
+    have_xfixes = true;
+  else
+    have_xfixes = false;
+#endif
+
 #if USE_XRANDR
   void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY);
   if (!libxrandr_addr)  libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY);
@@ -841,6 +931,102 @@
 }
 
 ////////////////////////////////////////////////////////////////
+// Code for tracking clipboard changes:
+
+static Time primary_timestamp = -1;
+static Time clipboard_timestamp = -1;
+
+extern bool fl_clipboard_notify_empty(void);
+extern void fl_trigger_clipboard_notify(int source);
+
+static void poll_clipboard_owner(void) {
+  Window xid;
+
+#if HAVE_XFIXES
+  // No polling needed with Xfixes
+  if (have_xfixes)
+    return;
+#endif
+
+  // No one is interested, so no point polling
+  if (fl_clipboard_notify_empty())
+    return;
+
+  // We need a window for this to work
+  if (!Fl::first_window())
+    return;
+  xid = fl_xid(Fl::first_window());
+  if (!xid)
+    return;
+
+  // Request an update of the selection time for both the primary and
+  // clipboard selections. Magic continues when we get a SelectionNotify.
+  if (!fl_i_own_selection[0])
+    XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP,
+                      xid, fl_event_time);
+  if (!fl_i_own_selection[1])
+    XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP,
+                      xid, fl_event_time);
+}
+
+static void clipboard_timeout(void *data)
+{
+  // No one is interested, so stop polling
+  if (fl_clipboard_notify_empty())
+    return;
+
+  poll_clipboard_owner();
+
+  Fl::repeat_timeout(0.5, clipboard_timeout);
+}
+
+static void handle_clipboard_timestamp(int clipboard, Time time)
+{
+  Time *timestamp;
+
+  timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp;
+
+#if HAVE_XFIXES
+  if (!have_xfixes)
+#endif
+  {
+    // Initial scan, just store the value
+    if (*timestamp == (Time)-1) {
+      *timestamp = time;
+      return;
+    }
+  }
+
+  // Same selection
+  if (time == *timestamp)
+    return;
+
+  *timestamp = time;
+
+  // Something happened! Let's tell someone!
+  fl_trigger_clipboard_notify(clipboard);
+}
+
+void fl_clipboard_notify_change() {
+  // Reset the timestamps if we've going idle so that you don't
+  // get a bogus immediate trigger next time they're activated.
+  if (fl_clipboard_notify_empty()) {
+    primary_timestamp = -1;
+    clipboard_timestamp = -1;
+  } else {
+#if HAVE_XFIXES
+    if (!have_xfixes)
+#endif
+    {
+      poll_clipboard_owner();
+
+      if (!Fl::has_timeout(clipboard_timeout))
+        Fl::add_timeout(0.5, clipboard_timeout);
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////
 
 const XEvent* fl_xevent; // the current x event
 ulong fl_event_time; // the last timestamp from an x event
@@ -918,10 +1104,9 @@
   XEvent xevent = thisevent;
   fl_xevent = &thisevent;
   Window xid = xevent.xany.window;
-  static Window xim_win = 0;
 
   if (fl_xim_ic && xevent.type == DestroyNotify &&
-        xid != xim_win && !fl_find(xid))
+        xid != fl_xim_win && !fl_find(xid))
   {
     XIM xim_im;
     xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
@@ -936,48 +1121,10 @@
     return 0;
   }
 
-  if (fl_xim_ic && (xevent.type == FocusIn))
-  {
-#define POOR_XIM
-#ifdef POOR_XIM
-        if (xim_win != xid)
-        {
-                xim_win  = xid;
-                XDestroyIC(fl_xim_ic);
-                fl_xim_ic = NULL;
-                fl_new_ic();
-                XSetICValues(fl_xim_ic,
-                                XNFocusWindow, xevent.xclient.window,
-                                XNClientWindow, xid,
-                                NULL);
-        }
-        fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
-#else
-    if (Fl::first_window() && Fl::first_window()->modal()) {
-      Window x  = fl_xid(Fl::first_window());
-      if (x != xim_win) {
-        xim_win  = x;
-        XSetICValues(fl_xim_ic,
-                        XNFocusWindow, xim_win,
-                        XNClientWindow, xim_win,
-                        NULL);
-        fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
-      }
-    } else if (xim_win != xid && xid) {
-      xim_win = xid;
-      XSetICValues(fl_xim_ic,
-                        XNFocusWindow, xevent.xclient.window,
-                        XNClientWindow, xid,
-                        //XNFocusWindow, xim_win,
-                        //XNClientWindow, xim_win,
-                        NULL);
-      fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
-    }
-#endif
+  if (fl_xim_ic) {
+    if (XFilterEvent((XEvent *)&xevent, 0))
+      return 1;
   }
-
-  if ( XFilterEvent((XEvent *)&xevent, 0) )
-      return(1);
   
 #if USE_XRANDR  
   if( XRRUpdateConfiguration_f && xevent.type == randrEventBase + RRScreenChangeNotify) {
@@ -1003,7 +1150,6 @@
     return 0;
 
   case SelectionNotify: {
-    if (!fl_selection_requestor) return 0;
     static unsigned char* buffer = 0;
     if (buffer) {XFree(buffer); buffer = 0;}
     long bytesread = 0;
@@ -1019,6 +1165,19 @@
                              bytesread/4, 65536, 1, 0,
                              &actual, &format, &count, &remaining,
                              &portion)) break; // quit on error
+
+      if ((fl_xevent->xselection.property == PRIMARY_TIMESTAMP) ||
+          (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)) {
+        if (portion && format == 32 && count == 1) {
+          Time t = *(unsigned int*)portion;
+          if (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)
+            handle_clipboard_timestamp(1, t);
+          else
+            handle_clipboard_timestamp(0, t);
+        }
+        return true;
+      }
+
       if (actual == TARGETS || actual == XA_ATOM) {
 	Atom type = XA_STRING;
 	for (unsigned i = 0; i<count; i++) {
@@ -1055,6 +1214,9 @@
       buffer[bytesread] = 0;
       convert_crlf(buffer, bytesread);
     }
+
+    if (!fl_selection_requestor) return 0;
+
     Fl::e_text = buffer ? (char*)buffer : (char *)"";
     Fl::e_length = bytesread;
     int old_event = Fl::e_number;
@@ -1075,6 +1237,7 @@
   case SelectionClear: {
     int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
     fl_i_own_selection[clipboard] = 0;
+    poll_clipboard_owner();
     return 1;}
 
   case SelectionRequest: {
@@ -1287,6 +1450,9 @@
   case FocusIn:
     if (fl_xim_ic) XSetICFocus(fl_xim_ic);
     event = FL_FOCUS;
+    // If the user has toggled from another application to this one,
+    // then it's a good time to check for clipboard changes.
+    poll_clipboard_owner();
     break;
 
   case FocusOut:
@@ -1327,15 +1493,15 @@
         //static XComposeStatus compose;
         len = XLookupString((XKeyEvent*)&(xevent.xkey),
                              buffer, buffer_len, &keysym, 0/*&compose*/);
-        if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets
-          // force it to type a character (not sure if this ever is needed):
-          // if (!len) {buffer[0] = char(keysym); len = 1;}
-          len = fl_utf8encode(XKeysymToUcs(keysym), buffer);
-          if (len < 1) len = 1;
-          // ignore all effects of shift on the keysyms, which makes it a lot
-          // easier to program shortcuts and is Windoze-compatible:
-          keysym = XKeycodeToKeysym(fl_display, keycode, 0);
-        }
+        // XLookupString() is only defined to return Latin-1 (although it
+        // often gives you more). To be safe, use our own lookups based on
+        // keysym.
+        len = fl_utf8encode(XKeysymToUcs(keysym), buffer);
+        if (len < 1)
+          len = 1;
+        // ignore all effects of shift on the keysyms, which makes it a lot
+        // easier to program shortcuts and is Windoze-compatable:
+        keysym = XKeycodeToKeysym(fl_display, keycode, 0);
       }
       // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not
       //      set until set_event_xy() is called later...
@@ -1655,6 +1821,25 @@
     }
   }
 
+#if HAVE_XFIXES
+  switch (xevent.type - xfixes_event_base) {
+  case XFixesSelectionNotify: {
+    // Someone feeding us bogus events?
+    if (!have_xfixes)
+      return true;
+
+    XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent;
+
+    if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0])
+      handle_clipboard_timestamp(0, selection_notify->selection_timestamp);
+    else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1])
+      handle_clipboard_timestamp(1, selection_notify->selection_timestamp);
+
+    return true;
+    }
+  }
+#endif
+
   return Fl::handle(event, window);
 }
 
@@ -1697,22 +1882,30 @@
 #define _NET_WM_STATE_ADD           1  /* add/set property */
 #define _NET_WM_STATE_TOGGLE        2  /* toggle property  */
 
-static void send_wm_state_event(Window wnd, int add, Atom prop) {
+static void send_wm_event(Window wnd, Atom message,
+                          unsigned long d0, unsigned long d1=0,
+                          unsigned long d2=0, unsigned long d3=0,
+                          unsigned long d4=0) {
   XEvent e;
   e.xany.type = ClientMessage;
   e.xany.window = wnd;
-  e.xclient.message_type = fl_NET_WM_STATE;
+  e.xclient.message_type = message;
   e.xclient.format = 32;
-  e.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
-  e.xclient.data.l[1] = prop;
-  e.xclient.data.l[2] = 0;
-  e.xclient.data.l[3] = 0;
-  e.xclient.data.l[4] = 0;
+  e.xclient.data.l[0] = d0;
+  e.xclient.data.l[1] = d1;
+  e.xclient.data.l[2] = d2;
+  e.xclient.data.l[3] = d3;
+  e.xclient.data.l[4] = d4;
   XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
              0, SubstructureNotifyMask | SubstructureRedirectMask,
              &e);
 }
 
+static void send_wm_state_event(Window wnd, int add, Atom prop) {
+  send_wm_event(wnd, fl_NET_WM_STATE,
+                add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, prop);
+}
+
 int Fl_X::ewmh_supported() {
   static int result = -1;
 
@@ -1736,6 +1929,22 @@
 /* Change an existing window to fullscreen */
 void Fl_Window::fullscreen_x() {
   if (Fl_X::ewmh_supported()) {
+    int top, bottom, left, right;
+
+    top = fullscreen_screen_top;
+    bottom = fullscreen_screen_bottom;
+    left = fullscreen_screen_left;
+    right = fullscreen_screen_right;
+
+    if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+      top = Fl::screen_num(x(), y(), w(), h());
+      bottom = top;
+      left = top;
+      right = top;
+    }
+
+    send_wm_event(fl_xid(this), fl_NET_WM_FULLSCREEN_MONITORS,
+                  top, bottom, left, right);
     send_wm_state_event(fl_xid(this), 1, fl_NET_WM_STATE_FULLSCREEN);
   } else {
     _set_fullscreen();
@@ -1822,7 +2031,7 @@
     // force the window to be on-screen.  Usually the X window manager
     // does this, but a few don't, so we do it here for consistency:
     int scr_x, scr_y, scr_w, scr_h;
-    Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y);
+    Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H);
 
     if (win->border()) {
       // ensure border is on screen:
@@ -1851,6 +2060,23 @@
     return;
   }
 
+  // Compute which screen(s) we should be on if we want to go fullscreen
+  int fullscreen_top, fullscreen_bottom, fullscreen_left, fullscreen_right;
+
+  fullscreen_top = win->fullscreen_screen_top;
+  fullscreen_bottom = win->fullscreen_screen_bottom;
+  fullscreen_left = win->fullscreen_screen_left;
+  fullscreen_right = win->fullscreen_screen_right;
+
+  if ((fullscreen_top < 0) || (fullscreen_bottom < 0) ||
+      (fullscreen_left < 0) || (fullscreen_right < 0)) {
+    fullscreen_top = Fl::screen_num(X, Y, W, H);
+    fullscreen_bottom = fullscreen_top;
+    fullscreen_left = fullscreen_top;
+    fullscreen_right = fullscreen_top;
+  }
+
+
   ulong root = win->parent() ?
     fl_xid(win->window()) : RootWindow(fl_display, fl_screen);
 
@@ -1874,9 +2100,17 @@
   // border, and cannot grab without an existing window. Besides, 
   // there is no clear_override(). 
   if (win->flags() & Fl_Widget::FULLSCREEN && !Fl_X::ewmh_supported()) {
+    int sx, sy, sw, sh;
     attr.override_redirect = 1;
     mask |= CWOverrideRedirect;
-    Fl::screen_xywh(X, Y, W, H, X, Y, W, H);
+    Fl::screen_xywh(sx, sy, sw, sh, fullscreen_left);
+    X = sx;
+    Fl::screen_xywh(sx, sy, sw, sh, fullscreen_right);
+    W = sx + sw - X;
+    Fl::screen_xywh(sx, sy, sw, sh, fullscreen_top);
+    Y = sy;
+    Fl::screen_xywh(sx, sy, sw, sh, fullscreen_bottom);
+    H = sy + sh - Y;
   }
 
   if (fl_background_pixel >= 0) {
@@ -1929,6 +2163,12 @@
       while (wp->parent()) wp = wp->window();
       XSetTransientForHint(fl_display, xp->xid, fl_xid(wp));
       if (!wp->visible()) showit = 0; // guess that wm will not show it
+      if (win->modal()) {
+        Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0);
+        Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_MODAL", 0);
+        XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32,
+            PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1);
+      }
     }
 
     // Make sure that borderless windows do not show in the task bar
@@ -1941,6 +2181,13 @@
 
     // If asked for, create fullscreen
     if (win->flags() & Fl_Widget::FULLSCREEN && Fl_X::ewmh_supported()) {
+      unsigned long data[4];
+      data[0] = fullscreen_top;
+      data[1] = fullscreen_bottom;
+      data[2] = fullscreen_left;
+      data[3] = fullscreen_right;
+      XChangeProperty (fl_display, xp->xid, fl_NET_WM_FULLSCREEN_MONITORS, XA_ATOM, 32,
+                       PropModeReplace, (unsigned char*) data, 4);
       XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
                        PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
     }
@@ -1959,12 +2206,14 @@
       fl_show_iconic = 0;
       showit = 0;
     }
-    if (win->icon()) {
-      hints->icon_pixmap = (Pixmap)win->icon();
+    if (win->icon_->legacy_icon) {
+      hints->icon_pixmap = (Pixmap)win->icon_->legacy_icon;
       hints->flags       |= IconPixmapHint;
     }
     XSetWMHints(fl_display, xp->xid, hints);
     XFree(hints);
+
+    xp->set_icons();
   }
 
   // set the window type for menu and tooltip windows to avoid animations (compiz)
@@ -1974,6 +2223,16 @@
     XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1);
   }
 
+#if HAVE_XFIXES
+  // register for clipboard change notifications
+  if (have_xfixes && !win->parent()) {
+    XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY,
+                               XFixesSetSelectionOwnerNotifyMask);
+    XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD,
+                               XFixesSetSelectionOwnerNotifyMask);
+  }
+#endif
+
   XMapWindow(fl_display, xp->xid);
   if (showit) {
     win->set_visible();
@@ -2073,6 +2332,181 @@
 }
 
 ////////////////////////////////////////////////////////////////
+
+static unsigned long *default_net_wm_icons = 0L;
+static size_t default_net_wm_icons_size = 0;
+
+void icons_to_property(const Fl_RGB_Image *icons[], int count,
+                       unsigned long **property, size_t *len) {
+  size_t sz;
+  unsigned long *data;
+
+  sz = 0;
+  for (int i = 0;i < count;i++)
+    sz += 2 + icons[i]->w() * icons[i]->h();
+
+  // FIXME: Might want to sort the icons
+
+  *property = data = new unsigned long[sz];
+  *len = sz;
+
+  for (int i = 0;i < count;i++) {
+    const Fl_RGB_Image *image;
+
+    image = icons[i];
+
+    data[0] = image->w();
+    data[1] = image->h();
+    data += 2;
+
+    const uchar *in = (const uchar*)*image->data();
+    for (int y = 0;y < image->h();y++) {
+      for (int x = 0;x < image->w();x++) {
+        switch (image->d()) {
+        case 1:
+          *data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
+          break;
+        case 2:
+          *data = (in[1]<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
+          break;
+        case 3:
+          *data = ( 0xff<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
+          break;
+        case 4:
+          *data = (in[3]<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
+          break;
+        }
+        in += image->d();
+        data++;
+      }
+      in += image->ld();
+    }
+  }
+}
+
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
+  if (default_net_wm_icons) {
+    delete [] default_net_wm_icons;
+    default_net_wm_icons = 0L;
+    default_net_wm_icons_size = 0;
+  }
+
+  if (count > 0)
+    icons_to_property(icons, count,
+                      &default_net_wm_icons, &default_net_wm_icons_size);
+}
+
+void Fl_X::set_icons() {
+  unsigned long *net_wm_icons;
+  size_t net_wm_icons_size;
+
+  if (w->icon_->count) {
+    icons_to_property((const Fl_RGB_Image **)w->icon_->icons, w->icon_->count,
+                      &net_wm_icons, &net_wm_icons_size);
+  } else {
+    net_wm_icons = default_net_wm_icons;
+    net_wm_icons_size = default_net_wm_icons_size;
+  }
+
+  XChangeProperty (fl_display, xid, fl_NET_WM_ICON, XA_CARDINAL, 32,
+      PropModeReplace, (unsigned char*) net_wm_icons, net_wm_icons_size);
+
+  if (w->icon_->count) {
+    delete [] net_wm_icons;
+    net_wm_icons = 0L;
+    net_wm_icons_size = 0;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl_X::set_cursor(Fl_Cursor c) {
+  unsigned int shape;
+  Cursor xc;
+
+  switch (c) {
+  case FL_CURSOR_ARROW:   shape = XC_left_ptr; break;
+  case FL_CURSOR_CROSS:   shape = XC_tcross; break;
+  case FL_CURSOR_WAIT:    shape = XC_watch; break;
+  case FL_CURSOR_INSERT:  shape = XC_xterm; break;
+  case FL_CURSOR_HAND:    shape = XC_hand2; break;
+  case FL_CURSOR_HELP:    shape = XC_question_arrow; break;
+  case FL_CURSOR_MOVE:    shape = XC_fleur; break;
+  case FL_CURSOR_NS:      shape = XC_sb_v_double_arrow; break;
+  case FL_CURSOR_WE:      shape = XC_sb_h_double_arrow; break;
+  case FL_CURSOR_NE:      shape = XC_top_right_corner; break;
+  case FL_CURSOR_N:       shape = XC_top_side; break;
+  case FL_CURSOR_NW:      shape = XC_top_left_corner; break;
+  case FL_CURSOR_E:       shape = XC_right_side; break;
+  case FL_CURSOR_W:       shape = XC_left_side; break;
+  case FL_CURSOR_SE:      shape = XC_bottom_right_corner; break;
+  case FL_CURSOR_S:       shape = XC_bottom_side; break;
+  case FL_CURSOR_SW:      shape = XC_bottom_left_corner; break;
+  default:
+    return 0;
+  }
+
+  xc = XCreateFontCursor(fl_display, shape);
+  XDefineCursor(fl_display, xid, xc);
+  XFreeCursor(fl_display, xc);
+
+  return 1;
+}
+
+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+#if ! HAVE_XCURSOR
+  return 0;
+#else
+  XcursorImage *cursor;
+  Cursor xc;
+
+  if ((hotx < 0) || (hotx >= image->w()))
+    return 0;
+  if ((hoty < 0) || (hoty >= image->h()))
+    return 0;
+
+  cursor = XcursorImageCreate(image->w(), image->h());
+  if (!cursor)
+    return 0;
+
+  const uchar *i = (const uchar*)*image->data();
+  XcursorPixel *o = cursor->pixels;
+  for (int y = 0;y < image->h();y++) {
+    for (int x = 0;x < image->w();x++) {
+      switch (image->d()) {
+      case 1:
+        *o = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+        break;
+      case 2:
+        *o = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+        break;
+      case 3:
+        *o = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+        break;
+      case 4:
+        *o = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+        break;
+      }
+      i += image->d();
+      o++;
+    }
+    i += image->ld();
+  }
+
+  cursor->xhot = hotx;
+  cursor->yhot = hoty;
+
+  xc = XcursorImageLoadCursor(fl_display, cursor);
+  XDefineCursor(fl_display, xid, xc);
+  XFreeCursor(fl_display, xc);
+
+  XcursorImageDestroy(cursor);
+
+  return 1;
+#endif
+}
+
+////////////////////////////////////////////////////////////////
 
 // returns pointer to the filename, or null if name ends with '/'
 const char *fl_filename_name(const char *name) {
diff -Nur fltk-1.3.2.orig/src/ps_image.cxx fltk-1.3.2/src/ps_image.cxx
--- fltk-1.3.2.orig/src/ps_image.cxx	2011-07-19 06:49:30.000000000 +0200
+++ fltk-1.3.2/src/ps_image.cxx	2013-07-17 19:37:37.912343302 +0200
@@ -185,72 +185,38 @@
 
 extern uchar **fl_mask_bitmap;
 
+struct callback_data {
+  const uchar *data;
+  int D, LD;
+};
 
-void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) {
-  double x = ix, y = iy, w = iw, h = ih;
 
-  if (D<3){ //mono
-    draw_image_mono(data, ix, iy, iw, ih, D, LD);
-    return;
-  }
+static void draw_image_cb(void *data, int x, int y, int w, uchar *buf) {
+  struct callback_data *cb_data;
+  const uchar *curdata;
 
+  cb_data = (struct callback_data*)data;
+  curdata = cb_data->data + x*cb_data->D + y*cb_data->LD;
 
-  int i,j, k;
+  memcpy(buf, curdata, w*cb_data->D);
+}
 
-  fprintf(output,"save\n");
 
-  const char * interpol;
-  if (lang_level_>1){
-    if (interpolate_)
-      interpol="true";
-    else
-      interpol="false";
-    if (mask && lang_level_>2)
-      fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol);
-    else
-      fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol);
-  } else
-    fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih);
+void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) {
+  if (D<3){ //mono
+    draw_image_mono(data, ix, iy, iw, ih, D, LD);
+    return;
+  }
 
+  struct callback_data cb_data;
 
   if (!LD) LD = iw*D;
-  uchar *curmask=mask;
-
-  for (j=0; j<ih;j++){
-    if (mask){
-
-      for (k=0;k<my/ih;k++){
-        for (i=0; i<((mx+7)/8);i++){
-          if (!(i%80)) fprintf(output, "\n");
-          fprintf(output, "%.2x",swap_byte(*curmask));
-          curmask++;
-        }
-        fprintf(output,"\n");
-      }
-    }
-    const uchar *curdata=data+j*LD;
-    for (i=0 ; i<iw ; i++) {
-      uchar r = curdata[0];
-      uchar g =  curdata[1];
-      uchar b =  curdata[2];
-      if (lang_level_<3 && D>3) { //can do  mixing using bg_* colors)
-        unsigned int a2 = curdata[3]; //must be int
-        unsigned int a = 255-a2;
-        r = (a2 * r + bg_r * a)/255;
-        g = (a2 * g + bg_g * a)/255;
-        b = (a2 * b + bg_b * a)/255;
-      }
-      if (!(i%40)) fprintf(output, "\n");
-      fprintf(output, "%.2x%.2x%.2x", r, g, b);
-      curdata +=D;
-    }
-    fprintf(output,"\n");
-
-  }
-
-  fprintf(output," >\nrestore\n" );
 
+  cb_data.data = data;
+  cb_data.D = D;
+  cb_data.LD = LD;
 
+  draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, D);
 }
 
 void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D) {
@@ -325,6 +291,14 @@
 	uchar g =  curdata[1];
 	uchar b =  curdata[2];
 
+        if (lang_level_<3 && D>3) { //can do  mixing using bg_* colors)
+          unsigned int a2 = curdata[3]; //must be int
+          unsigned int a = 255-a2;
+          r = (a2 * r + bg_r * a)/255;
+          g = (a2 * g + bg_g * a)/255;
+          b = (a2 * b + bg_b * a)/255;
+        }
+
 	if (!(i%40)) 	fputs("\n", output);
 	fprintf(output, "%.2x%.2x%.2x", r, g, b);
 
diff -Nur fltk-1.3.2.orig/src/screen_xywh.cxx fltk-1.3.2/src/screen_xywh.cxx
--- fltk-1.3.2.orig/src/screen_xywh.cxx	2012-03-23 17:47:53.000000000 +0100
+++ fltk-1.3.2/src/screen_xywh.cxx	2013-07-17 19:38:09.575341648 +0200
@@ -215,21 +215,6 @@
   return num_screens ? num_screens : 1;
 }
 
-static int find_screen_with_point(int mx, int my) {
-  int screen = 0;
-  if (num_screens < 0) screen_init();
-  
-  for (int i = 0; i < num_screens; i ++) {
-    int sx, sy, sw, sh;
-    Fl::screen_xywh(sx, sy, sw, sh, i);
-    if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) {
-      screen = i;
-      break;
-    }
-  }
-  return screen;
-}
-
 /**
   Gets the bounding box of a screen
   that contains the specified screen position \p mx, \p my
@@ -237,7 +222,7 @@
   \param[in] mx, my the absolute screen position
 */
 void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
-  screen_xywh(X, Y, W, H, find_screen_with_point(mx, my));
+  screen_xywh(X, Y, W, H, screen_num(mx, my));
 }
 
 
@@ -248,7 +233,7 @@
  \param[in] mx, my the absolute screen position
  */
 void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my) {
-  screen_work_area(X, Y, W, H, find_screen_with_point(mx, my));
+  screen_work_area(X, Y, W, H, screen_num(mx, my));
 }
 
 /**
@@ -321,6 +306,38 @@
 #endif // WIN32
 }
 
+/**
+  Gets the screen bounding rect for the screen
+  which intersects the most with the rectangle
+  defined by \p mx, \p my, \p mw, \p mh.
+  \param[out]  X,Y,W,H the corresponding screen bounding box
+  \param[in] mx, my, mw, mh the rectangle to search for intersection with
+  \see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
+  */
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
+  screen_xywh(X, Y, W, H, screen_num(mx, my, mw, mh));
+}
+
+/**
+  Gets the screen number of a screen
+  that contains the specified screen position \p x, \p y
+  \param[in] x, y the absolute screen position
+*/
+int Fl::screen_num(int x, int y) {
+  int screen = 0;
+  if (num_screens < 0) screen_init();
+  
+  for (int i = 0; i < num_screens; i ++) {
+    int sx, sy, sw, sh;
+    Fl::screen_xywh(sx, sy, sw, sh, i);
+    if ((x >= sx) && (x < (sx+sw)) && (y >= sy) && (y < (sy+sh))) {
+      screen = i;
+      break;
+    }
+  }
+  return screen;
+}
+
 static inline float fl_intersection(int x1, int y1, int w1, int h1,
                         int x2, int y2, int w2, int h2) {
   if(x1+w1 < x2 || x2+w2 < x1 || y1+h1 < y2 || y2+h2 < y1)
@@ -333,30 +350,27 @@
 }
 
 /**
-  Gets the screen bounding rect for the screen
+  Gets the screen number for the screen
   which intersects the most with the rectangle
-  defined by \p mx, \p my, \p mw, \p mh.
-  \param[out]  X,Y,W,H the corresponding screen bounding box
-  \param[in] mx, my, mw, mh the rectangle to search for intersection with
-  \see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
+  defined by \p x, \p y, \p w, \p h.
+  \param[in] x, y, w, h the rectangle to search for intersection with
   */
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
+int Fl::screen_num(int x, int y, int w, int h) {
   int best_screen = 0;
   float best_intersection = 0.;
   for(int i = 0; i < Fl::screen_count(); i++) {
     int sx, sy, sw, sh;
     Fl::screen_xywh(sx, sy, sw, sh, i);
-    float sintersection = fl_intersection(mx, my, mw, mh, sx, sy, sw, sh);
+    float sintersection = fl_intersection(x, y, w, h, sx, sy, sw, sh);
     if(sintersection > best_intersection) {
       best_screen = i;
       best_intersection = sintersection;
     }
   }
-  screen_xywh(X, Y, W, H, best_screen);
+  return best_screen;
 }
 
 
-
 /**
  Gets the screen resolution in dots-per-inch for the given screen.
  \param[out]  h, v  horizontal and vertical resolution
diff -Nur fltk-1.3.2.orig/src/xutf8/imKStoUCS.c fltk-1.3.2/src/xutf8/imKStoUCS.c
--- fltk-1.3.2.orig/src/xutf8/imKStoUCS.c	2009-03-13 23:43:43.000000000 +0100
+++ fltk-1.3.2/src/xutf8/imKStoUCS.c	2013-07-17 19:37:07.412344891 +0200
@@ -266,6 +266,12 @@
     0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac                          /* 0x20a8-0x20af */
 };
 
+static unsigned short const keysym_to_unicode_fe50_fe60[] = {
+    0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307, 0x0308, /* 0xfe50-0xfe57 */
+    0x030a, 0x030b, 0x030c, 0x0327, 0x0328, 0x1da5, 0x3099, 0x309a, /* 0xfe58-0xfe5f */
+    0x0323                                                          /* 0xfe60-0xfe67 */
+};
+
 unsigned int
 KeySymToUcs4(KeySym keysym)
 {
@@ -315,6 +321,8 @@
 	return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f];
     else if (keysym > 0x209f && keysym < 0x20ad)
 	return keysym_to_unicode_20a0_20ac[keysym - 0x20a0];
+    else if (keysym > 0xfe4f && keysym < 0xfe61)
+	return keysym_to_unicode_fe50_fe60[keysym - 0xfe50];
     else 
 	return 0;
 }
diff -Nur fltk-1.3.2.orig/test/cursor.cxx fltk-1.3.2/test/cursor.cxx
--- fltk-1.3.2.orig/test/cursor.cxx	2011-07-19 06:49:30.000000000 +0200
+++ fltk-1.3.2/test/cursor.cxx	2013-07-17 19:37:45.796342890 +0200
@@ -23,8 +23,6 @@
 #include <FL/fl_draw.H>
 #include <FL/Fl_Box.H>
 
-Fl_Color fg = FL_BLACK;
-Fl_Color bg = FL_WHITE;
 Fl_Cursor cursor = FL_CURSOR_DEFAULT;
 
 Fl_Hor_Value_Slider *cursor_slider;
@@ -32,7 +30,7 @@
 void choice_cb(Fl_Widget *, void *v) {
   cursor = (Fl_Cursor)(fl_intptr_t)v;
   cursor_slider->value(cursor);
-  fl_cursor(cursor,fg,bg);
+  fl_cursor(cursor);
 }
 
 Fl_Menu_Item choices[] = {
@@ -48,8 +46,6 @@
   {"FL_CURSOR_WE",0,choice_cb,(void*)FL_CURSOR_WE},
   {"FL_CURSOR_NWSE",0,choice_cb,(void*)FL_CURSOR_NWSE},
   {"FL_CURSOR_NESW",0,choice_cb,(void*)FL_CURSOR_NESW},
-  {"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
-#if 0
   {"FL_CURSOR_N",0,choice_cb,(void*)FL_CURSOR_N},
   {"FL_CURSOR_NE",0,choice_cb,(void*)FL_CURSOR_NE},
   {"FL_CURSOR_E",0,choice_cb,(void*)FL_CURSOR_E},
@@ -58,26 +54,14 @@
   {"FL_CURSOR_SW",0,choice_cb,(void*)FL_CURSOR_SW},
   {"FL_CURSOR_W",0,choice_cb,(void*)FL_CURSOR_W},
   {"FL_CURSOR_NW",0,choice_cb,(void*)FL_CURSOR_NW},
-#endif
+  {"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
   {0}
 };
 
 void setcursor(Fl_Widget *o, void *) {
   Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
   cursor = Fl_Cursor((int)slider->value());
-  fl_cursor(cursor,fg,bg);
-}
-
-void setfg(Fl_Widget *o, void *) {
-  Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
-  fg = Fl_Color((int)slider->value());
-  fl_cursor(cursor,fg,bg);
-}
-
-void setbg(Fl_Widget *o, void *) {
-  Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
-  bg = Fl_Color((int)slider->value());
-  fl_cursor(cursor,fg,bg);
+  fl_cursor(cursor);
 }
 
 // draw the label without any ^C or \nnn conversions:
@@ -103,29 +87,11 @@
   slider1.align(FL_ALIGN_LEFT);
   slider1.step(1);
   slider1.precision(0);
-  slider1.bounds(0,100);
+  slider1.bounds(0,255);
   slider1.value(0);
   slider1.callback(setcursor);
   slider1.value(cursor);
 
-  Fl_Hor_Value_Slider slider2(80,220,310,30,"fgcolor:");
-  slider2.align(FL_ALIGN_LEFT);
-  slider2.step(1);
-  slider2.precision(0);
-  slider2.bounds(0,255);
-  slider2.value(0);
-  slider2.callback(setfg);
-  slider2.value(fg);
-
-  Fl_Hor_Value_Slider slider3(80,260,310,30,"bgcolor:");
-  slider3.align(FL_ALIGN_LEFT);
-  slider3.step(1);
-  slider3.precision(0);
-  slider3.bounds(0,255);
-  slider3.value(0);
-  slider3.callback(setbg);
-  slider3.value(bg);
-
 #if 0
   // draw the manual's diagram of cursors...
   window.size(400,800);
diff -Nur fltk-1.3.2.orig/test/fullscreen.cxx fltk-1.3.2/test/fullscreen.cxx
--- fltk-1.3.2.orig/test/fullscreen.cxx	2012-06-14 17:09:46.000000000 +0200
+++ fltk-1.3.2/test/fullscreen.cxx	2013-07-17 19:38:17.327341239 +0200
@@ -127,7 +127,7 @@
   fullscreen_window(int W, int H, const char *t=0);
   int handle (int e);
   Fl_Toggle_Light_Button *b3;
-
+  Fl_Toggle_Light_Button *b4;
 };
 
 fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Window(W, H, t) { 
@@ -170,23 +170,54 @@
 #endif
 }
 
-int px,py,pw,ph;
 Fl_Button *border_button;
 void fullscreen_cb(Fl_Widget *o, void *p) {
   Fl_Window *w = (Fl_Window *)p;
   int d = ((Fl_Button *)o)->value();
   if (d) {
-    px = w->x();
-    py = w->y();
-    pw = w->w();
-    ph = w->h();
+    if (((fullscreen_window*)w)->b4->value()) {
+      int top, bottom, left, right;
+      int top_y, bottom_y, left_x, right_x;
+
+      int sx, sy, sw, sh;
+
+      top = bottom = left = right = 0;
+
+      Fl::screen_xywh(sx, sy, sw, sh, 0);
+      top_y = sy;
+      bottom_y = sy + sh;
+      left_x = sx;
+      right_x = sx + sw;
+
+      for (int i = 1;i < Fl::screen_count();i++) {
+        Fl::screen_xywh(sx, sy, sw, sh, i);
+        if (sy < top_y) {
+          top = i;
+          top_y = sy;
+        }
+        if ((sy + sh) > bottom_y) {
+          bottom = i;
+          bottom_y = sy + sh;
+        }
+        if (sx < left_x) {
+          left = i;
+          left_x = sx;
+        }
+        if ((sx + sw) > right_x) {
+          right = i;
+          right_x = sx + sw;
+        }
+      }
+
+      w->fullscreen_screens(top, bottom, left, right);
+    } else {
+      w->fullscreen_screens(-1, -1, -1, -1);
+    }
     w->fullscreen();
-    w->override();
 #ifndef WIN32 // update our border state in case border was turned off
     border_button->value(w->border());
 #endif
   } else {
-    //w->fullscreen_off(px,py,pw,ph);
     w->fullscreen_off();
   }
 }
@@ -219,7 +250,7 @@
   exit(0);
 }
 
-#define NUMB 7
+#define NUMB 8
 
 int twowindow = 0;
 int initfull = 0;
@@ -284,6 +315,9 @@
   window.b3->callback(fullscreen_cb,w);
   y+=30;
 
+  window.b4 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"All Screens");
+  y+=30;
+
   Fl_Button eb(50,y,window.w()-60,30,"Exit");
   eb.callback(exit_cb);
   y+=30;
