]> source.dussan.org Git - tigervnc.git/commitdiff
Update extensions to cleanly apply against FLTK 1.3.0, and fix several bugs (includin...
authorDRC <dcommander@users.sourceforge.net>
Thu, 23 Jun 2011 08:28:18 +0000 (08:28 +0000)
committerDRC <dcommander@users.sourceforge.net>
Thu, 23 Jun 2011 08:28:18 +0000 (08:28 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4519 3789f03b-4d11-0410-bbf8-ca57d06f2519

fltk/README
fltk/extensions.patch
fltk/fltk-1.3.x-r8772.tar.bz2 [deleted file]

index a424523abd24337af264deb8a98af611461054b9..ccf6c7294bd1d637e71cf55e30311aaf10628660 100644 (file)
@@ -1,3 +1,3 @@
-This directory contains a snapshot of FLTK with the associated extra patches
-that we rely on so that people can easily build a version that gives a full
-features vncviewer.
+This directory contains a unified patch which, when applied to the FLTK 1.3.0
+source tree, will enable extensions to the FLTK code which are necessary to
+build a fully-functional version of the FLTK-based TigerVNC Viewer.
index 6eebe84b9c9e87987cb5eb961852152c9b718f3b..1cb5c74783f950118be15196ecca55ca400d7e3d 100644 (file)
-diff -up fltk-1.3.x-r8732/src/Fl_win32.cxx.hwheel fltk-1.3.x-r8732/src/Fl_win32.cxx
---- fltk-1.3.x-r8732/src/Fl_win32.cxx.hwheel   2011-05-21 23:55:59.000000000 +0200
-+++ fltk-1.3.x-r8732/src/Fl_win32.cxx  2011-05-24 13:37:31.109341034 +0200
-@@ -1125,12 +1286,28 @@ static LRESULT CALLBACK WndProc(HWND hWn
-   case WM_MOUSEWHEEL: {
-     static int delta = 0; // running total of all motion
-     delta += (SHORT)(HIWORD(wParam));
-+    Fl::e_dx = 0;
-     Fl::e_dy = -delta / WHEEL_DELTA;
-     delta += Fl::e_dy * WHEEL_DELTA;
-     if (Fl::e_dy) Fl::handle(FL_MOUSEWHEEL, window);
-     return 0;
-   }
-+// This is only defined on Vista and upwards...
-+#ifndef WM_MOUSEHWHEEL
-+#define WM_MOUSEHWHEEL 0x020E
-+#endif
-+
-+  case WM_MOUSEHWHEEL: {
-+    static int delta = 0; // running total of all motion
-+    delta += (SHORT)(HIWORD(wParam));
-+    Fl::e_dy = 0;
-+    Fl::e_dx = delta / WHEEL_DELTA;
-+    delta -= Fl::e_dx * WHEEL_DELTA;
-+    if (Fl::e_dx) Fl::handle(FL_MOUSEWHEEL, window);
-+    return 0;
-+  }
-+
-   case WM_GETMINMAXINFO:
-     Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam);
-     break;
-diff -up fltk-1.3.x-r8732/src/Fl_x.cxx.hwheel fltk-1.3.x-r8732/src/Fl_x.cxx
---- fltk-1.3.x-r8732/src/Fl_x.cxx.hwheel       2011-05-23 21:40:23.000000000 +0200
-+++ fltk-1.3.x-r8732/src/Fl_x.cxx      2011-05-24 13:36:49.635113914 +0200
-@@ -1441,12 +1608,19 @@ int fl_handle(const XEvent& thisevent)
-   case ButtonPress:
-     Fl::e_keysym = FL_Button + xevent.xbutton.button;
-     set_event_xy();
-+    Fl::e_dx = Fl::e_dy = 0;
-     if (xevent.xbutton.button == Button4) {
-       Fl::e_dy = -1; // Up
-       event = FL_MOUSEWHEEL;
-     } else if (xevent.xbutton.button == Button5) {
-       Fl::e_dy = +1; // Down
-       event = FL_MOUSEWHEEL;
-+    } else if (xevent.xbutton.button == 6) {
-+      Fl::e_dx = -1; // Left
-+      event = FL_MOUSEWHEEL;
-+    } else if (xevent.xbutton.button == 7) {
-+      Fl::e_dx = +1; // Right
-+      event = FL_MOUSEWHEEL;
-     } else {
-       Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1));
-       event = FL_PUSH;
---- fltk-1.3.x-r8744/src/screen_xywh.cxx.fullscreen    2011-05-26 15:48:00.000000000 +0200
-+++ fltk-1.3.x-r8744/src/screen_xywh.cxx       2011-06-01 14:00:08.256046579 +0200
-@@ -202,81 +202,21 @@ int Fl::screen_count() {
-   \param[in] mx, my the absolute screen position
- */
- void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
--  if (num_screens < 0) screen_init();
--
--#ifdef WIN32
--  if (num_screens > 0) {
--    int i;
--
--    for (i = 0; i < num_screens; i ++) {
--      if (mx >= screens[i].left && mx < screens[i].right &&
--        my >= screens[i].top && my < screens[i].bottom) {
--      X = screens[i].left;
--      Y = screens[i].top;
--      W = screens[i].right - screens[i].left;
--      H = screens[i].bottom - screens[i].top;
--      return;
--      }
--    }
--  }
--  // if all else fails:
--  X = Fl::x();
--  Y = Fl::y();
--  W = Fl::w();
--  H = Fl::h();
--#elif defined(__APPLE__)
--  if (num_screens > 0) {
--    int i;
-+  int screen = 0;
-+  int i;
--    for (i = 0; i < num_screens; i ++) {
--      if (mx >= screens[i].x &&
--        mx < (screens[i].x + screens[i].width) &&
--        my >= screens[i].y &&
--        my < (screens[i].y + screens[i].height)) {
--      X = screens[i].x;
--      Y = screens[i].y;
--      W = screens[i].width;
--      H = screens[i].height;
--      return;
--      }
--    }
--  }
--  // if all else fails:
--  X = Fl::x();
--  Y = Fl::y();
--  W = Fl::w();
--  H = Fl::h();
--#elif HAVE_XINERAMA
--  if (num_screens > 0 && screens) { // screens == NULL if !XineramaIsActive(fl_display)
--    int i;
-+  if (num_screens < 0) screen_init();
--    for (i = 0; i < num_screens; i ++) {
--      if (mx >= screens[i].x_org &&
--        mx < (screens[i].x_org + screens[i].width) &&
--        my >= screens[i].y_org &&
--        my < (screens[i].y_org + screens[i].height)) {
--      X = screens[i].x_org;
--      Y = screens[i].y_org;
--      W = screens[i].width;
--      H = screens[i].height;
--      return;
--      }
-+  for (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;
-     }
-   }
--  // if all else fails:
--  X = Fl::x();
--  Y = Fl::y();
--  W = Fl::w();
--  H = Fl::h();
--#else
--  (void)mx;
--  (void)my;
--  X = 0;
--  Y = 0;
--  W = DisplayWidth(fl_display, fl_screen);
--  H = DisplayHeight(fl_display, fl_screen);
--#endif // WIN32
-+  screen_xywh(X, Y, W, H, screen);
- }
- /**
-@@ -288,47 +228,51 @@ void Fl::screen_xywh(int &X, int &Y, int
- void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
-   if (num_screens < 0) screen_init();
-+  if ((n < 0) || (n >= num_screens))
-+    n = 0;
-+
- #ifdef WIN32
--  if (num_screens > 0 && n >= 0 && n < num_screens) {
-+  if (num_screens > 0) {
-     X = screens[n].left;
-     Y = screens[n].top;
-     W = screens[n].right - screens[n].left;
-     H = screens[n].bottom - screens[n].top;
-   } else {
--    X = Fl::x();
--    Y = Fl::y();
--    W = Fl::w();
--    H = Fl::h();
-+    /* Fallback if something is broken... */
-+    X = 0;
-+    Y = 0;
-+    W = GetSystemMetrics(SM_CXSCREEN);
-+    H = GetSystemMetrics(SM_CYSCREEN);
-   }
- #elif defined(__APPLE__)
--  if (num_screens > 0 && n >= 0 && n < num_screens) {
-+  if (num_screens > 0) {
-     X = screens[n].x;
-     Y = screens[n].y;
-     W = screens[n].width;
-     H = screens[n].height;
-   } else {
-+    /* Fallback if something is broken... */
-     X = Fl::x();
-     Y = Fl::y();
-     W = Fl::w();
-     H = Fl::h();
-   }
--#elif HAVE_XINERAMA
--  if (num_screens > 0 && n >= 0 && n < num_screens && screens) {
-+#else
-+#if HAVE_XINERAMA
-+  if (num_screens > 0) {
-     X = screens[n].x_org;
-     Y = screens[n].y_org;
-     W = screens[n].width;
-     H = screens[n].height;
--  } else {
--    X = Fl::x();
--    Y = Fl::y();
--    W = Fl::w();
--    H = Fl::h();
-+  } else
-+#endif // HAVE_XINERAMA
-+  {
-+    /* Fallback if something is broken (or no Xinerama)... */
-+    X = 0;
-+    Y = 0;
-+    W = DisplayWidth(fl_display, fl_screen);
-+    H = DisplayHeight(fl_display, fl_screen);
-   }
--#else
--  X = 0;
--  Y = 0;
--  W = DisplayWidth(fl_display, fl_screen);
--  H = DisplayHeight(fl_display, fl_screen);
- #endif // WIN32
- }
-diff -up fltk-1.3.x-r8659/FL/Fl_Widget.H.kbd-x11 fltk-1.3.x-r8659/FL/Fl_Widget.H
---- fltk-1.3.x-r8659/FL/Fl_Widget.H.kbd-x11    2011-04-24 19:09:41.000000000 +0200
-+++ fltk-1.3.x-r8659/FL/Fl_Widget.H    2011-05-13 13:51:26.307888360 +0200
-@@ -179,6 +179,7 @@ protected:
-         NO_OVERLAY      = 1<<15,  ///< window not using a hardware overlay plane (Fl_Menu_Window)
-         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
-+        SIMPLE_KEYBOARD = 1<<18,  ///< 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
-@@ -784,6 +785,35 @@ public:
-    */
-   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()
+*** fltk-1.3.0/CMakeLists.txt  2011-01-06 04:24:58.000000000 -0600
+--- fltk/CMakeLists.txt        2011-06-22 23:01:51.000000000 -0500
+***************
+*** 62,65 ****
+--- 62,66 ----
+     set(HAVE_DIRENT_H 1)
+     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Cocoa")
++    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Carbon")
+  endif(APPLE)
+  
+*** fltk-1.3.0/FL/Enumerations.H       2011-05-21 16:55:59.000000000 -0500
+--- fltk/FL/Enumerations.H     2011-06-22 22:35:32.000000000 -0500
+***************
+*** 293,297 ****
+        following FL_PASTE event.
+     */
+!   FL_DND_RELEASE     = 23
+  };
+  
+--- 293,302 ----
+        following FL_PASTE event.
+     */
+!   FL_DND_RELEASE     = 23,
+! 
+!   /** The fullscreen state of the window has changed
+!    */
+!   FL_FULLSCREEN         = 24
+! 
+  };
+  
+***************
+*** 875,907 ****
+  /** 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.
+  
+      \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. */
+  };
+  /*@}*/               // group: Cursors  
+--- 880,913 ----
+  /** The following constants define the mouse cursors that are available in FLTK.
+  
+!     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   = 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  
+*** fltk-1.3.0/FL/Fl.H 2011-05-23 13:01:29.000000000 -0500
+--- fltk/FL/Fl.H       2011-06-22 22:35:31.000000000 -0500
+***************
+*** 109,112 ****
+--- 109,115 ----
+  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 */
+  
+***************
+*** 745,748 ****
+--- 748,764 ----
+    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.
 +   */
-+  void set_simple_keyboard() {flags_ |= SIMPLE_KEYBOARD;}
-+
-+  /** Marks a widget to use the normal keyboard model.
-+      \see changed(), set_changed()
++   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.
 +   */
-+  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 -up fltk-1.3.x-r8659/src/Fl.cxx.kbd-x11 fltk-1.3.x-r8659/src/Fl.cxx
---- fltk-1.3.x-r8659/src/Fl.cxx.kbd-x11        2011-04-11 22:10:02.000000000 +0200
-+++ fltk-1.3.x-r8659/src/Fl.cxx        2011-05-13 13:51:26.308888510 +0200
-@@ -63,6 +63,8 @@ void fl_cleanup_dc_list(void);
- extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle);
- #endif // WIN32
-+extern void fl_update_focus(void);
-+
- //
- // Globals...
- //
-@@ -864,6 +866,8 @@ void Fl::focus(Fl_Widget *o) {
-       fl_oldfocus = p;
-     }
-     e_number = old_event;
-+    // let the platform code do what it needs
-+    fl_update_focus();
-   }
- }
-diff -up fltk-1.3.x-r8659/src/Fl_grab.cxx.kbd-x11 fltk-1.3.x-r8659/src/Fl_grab.cxx
---- fltk-1.3.x-r8659/src/Fl_grab.cxx.kbd-x11   2010-12-18 23:31:01.000000000 +0100
-+++ fltk-1.3.x-r8659/src/Fl_grab.cxx   2011-05-13 13:51:26.309888660 +0200
-@@ -38,6 +38,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
-@@ -79,6 +80,7 @@ void Fl::grab(Fl_Window* win) {
- #endif
-     }
-     grab_ = win;
-+    fl_update_focus();
-   } else {
-     if (grab_) {
- #ifdef WIN32
-@@ -94,6 +96,7 @@ void Fl::grab(Fl_Window* win) {
-       XFlush(fl_display);
- #endif
-       grab_ = 0;
-+      fl_update_focus();
-       fl_fix_focus();
-     }
-   }
-diff -up fltk-1.3.x-r8659/src/Fl_x.cxx.kbd-x11 fltk-1.3.x-r8659/src/Fl_x.cxx
---- fltk-1.3.x-r8659/src/Fl_x.cxx.kbd-x11      2011-04-27 10:47:00.000000000 +0200
-+++ fltk-1.3.x-r8659/src/Fl_x.cxx      2011-05-13 13:54:28.813284014 +0200
-@@ -300,6 +300,7 @@ XVisualInfo *fl_visual;
- 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;
-@@ -581,6 +582,65 @@ void fl_init_xim() {
-   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;
-@@ -864,10 +924,9 @@ int fl_handle(const XEvent& thisevent)
-   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);
-@@ -882,48 +941,10 @@ int fl_handle(const XEvent& thisevent)
-     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 ( XFilterEvent((XEvent *)&xevent, 0) )
--      return(1);
-+  if (fl_xim_ic) {
-+    if (XFilterEvent((XEvent *)&xevent, 0))
-+      return 1;
-+  }
-   switch (xevent.type) {
-@@ -1248,15 +1269,15 @@ int fl_handle(const XEvent& thisevent)
-         //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...
-diff -up fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c.kbd-x11 fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c
---- fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c.kbd-x11     2009-03-13 23:43:43.000000000 +0100
-+++ fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c     2011-05-13 13:51:26.311888960 +0200
-@@ -266,6 +266,12 @@ static unsigned short const keysym_to_un
-     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 @@ KeySymToUcs4(KeySym keysym)
-       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 -up fltk-1.3.x-r8617/src/Fl_win32.cxx.kbd-win32 fltk-1.3.x-r8617/src/Fl_win32.cxx
---- fltk-1.3.x-r8617/src/Fl_win32.cxx.kbd-win32        2011-04-18 22:47:32.000000000 +0200
-+++ fltk-1.3.x-r8617/src/Fl_win32.cxx  2011-05-13 13:43:12.131708663 +0200
-@@ -98,6 +98,8 @@ FL_EXPORT Fl_Graphics_Driver *fl_graphic
- Fl_Surface_Device* Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_gdi_display; // the current target surface of graphics operations
- Fl_Display_Device *Fl_Display_Device::_display = &fl_gdi_display; // the platform display
-+bool use_simple_keyboard = false;
-+
- // dynamic wsock dll handling api:
- #if defined(__CYGWIN__) && !defined(SOCKET)
- # define SOCKET int
-@@ -131,6 +133,8 @@ static HMODULE get_wsock_mod() {
-  * size and link dependencies.
-  */
- static HMODULE s_imm_module = 0;
-+typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
-+static flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
- typedef HIMC (WINAPI* flTypeImmGetContext)(HWND);
- static flTypeImmGetContext flImmGetContext = 0;
- typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
-@@ -146,6 +150,7 @@ static HMODULE get_imm_module() {
-     if (!s_imm_module)
-       Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
-         "Please check your input method manager library accessibility.");
-+    flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx");
-     flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
-     flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
-     flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
-@@ -424,7 +429,12 @@ int fl_wait(double time_to_wait) {
-         }
-       }
--      TranslateMessage(&fl_msg);
-+      // Don't bother with key to character translation as we do
-+      // it manually for simpley keyboard widgets. In fact, calling
-+      // TranslateMessage() just makes it more difficult as it sets
-+      // a bunch of internal state.
-+      if (!use_simple_keyboard)
-+        TranslateMessage(&fl_msg);
-       DispatchMessageW(&fl_msg);
-       have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
-     }
-@@ -649,6 +659,49 @@ void fl_get_codepage()
-   }
- }
-+void fl_update_focus(void)
-+{
-+  Fl_Widget *focus;
-+  Fl_Window *win;
-+
-+  get_imm_module();
-+
-+  focus = Fl::grab();
-+  if (!focus)
-+    focus = Fl::focus();
-+  if (!focus)
-+    return;
-+
-+  // Grabs are special in that events are sent to the first
-+  // available window
-+  if (focus == Fl::grab())
-+    win = Fl::first_window();
-+  else {
-+    win = focus->as_window();
-+    if (!win)
-+      win = focus->window();
-+  }
-+
-+  if (!win) {
-+    Fl::warning("Cannot find window for widget receiving focus");
-+    return;
-+  }
-+
-+  // No Win32 window created yet
-+  if (!Fl_X::i(win) || !fl_xid(win))
-+    return;
-+
-+  if (focus->simple_keyboard()) {
-+    use_simple_keyboard = true;
-+    if (flImmGetContext(fl_xid(win)) != 0)
-+      flImmAssociateContextEx(fl_xid(win), 0, 0);
-+  } else {
-+    use_simple_keyboard = false;
-+    if (flImmGetContext(fl_xid(win)) == 0)
-+      flImmAssociateContextEx(fl_xid(win), 0, IACE_DEFAULT);
-+  }
-+}
-+
- HWND fl_capture;
- static int mouse_event(Fl_Window *window, int what, int button,
-@@ -778,6 +831,27 @@ static int ms2fltk(int vk, int extended)
-   return extended ? extendedlut[vk] : vklut[vk];
- }
-+static xchar msdead2fltk(xchar in)
-+{
-+  switch (in) {
-+  case 0x0060:      // GRAVE ACCENT
-+    return 0x0300;  // COMBINING GRAVE ACCENT
-+  case 0x00b4:      // ACUTE ACCENT
-+    return 0x0301;  // COMBINING ACUTE ACCENT
-+  case 0x005e:      // CIRCUMFLEX ACCENT
-+    return 0x0302;  // COMBINING CIRCUMFLEX ACCENT
-+  case 0x007e:      // TILDE
-+    return 0x0303;  // COMBINING TILDE
-+  case 0x00a8:      // DIAERESIS
-+    return 0x0308;  // COMBINING DIAERESIS
-+  // FIXME: Windows dead key behaviour isn't documented and I don't have
-+  //        any more keyboards to test with...
-+  }
-+
-+  // hope that Windows gave us something proper to begin with
-+  return in;
-+}
-+
- #if USE_COLORMAP
- extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx
- #endif
-@@ -839,6 +913,8 @@ static LRESULT CALLBACK WndProc(HWND hWn
-   //fl_msg.pt = ???
-   //fl_msg.lPrivate = ???
-+  MSG fl_orig_msg = fl_msg;
-+
-   Fl_Window *window = fl_find(hWnd);
-   if (window) switch (uMsg) {
-@@ -1018,23 +1094,82 @@ static LRESULT CALLBACK WndProc(HWND hWn
-     if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
-     Fl::e_state = state;
-     static char buffer[1024];
--    if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
-+    if (use_simple_keyboard) {
-+      BYTE keystate[256];
-+      WCHAR wbuf[8];
-+      int ret;
-+
-+      // I'm not sure if we ever get WM_CHAR (& friends) without an initial
-+      // WM_KEYDOWN (& friends), but if we do then we should not send such
-+      // side band events to simple keyboard widgets.
-+      if ((fl_orig_msg.message != WM_KEYDOWN) &&
-+          (fl_orig_msg.message != WM_SYSKEYDOWN) &&
-+          (fl_orig_msg.message != WM_KEYUP) &&
-+          (fl_orig_msg.message != WM_SYSKEYUP))
-+        break;
-+
-+      GetKeyboardState(keystate);
-+
-+      // Pressing Ctrl wreaks havoc with the symbol lookup, so turn that off.
-+      // But AltGr shows up as Ctrl+Alt in Windows, so keep Ctrl if Alt is
-+      // active.
-+      if (!(keystate[VK_MENU] & (1<<31)))
-+        keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
-+
-+      // We cannot inspect or modify Windows' internal state of the keyboard
-+      // so we have to try to infer information from ToUnicode() and wedge
-+      // things into a known state.
-+      for (int i = 0;i < 2;i++) {
-+        ret = ToUnicode(fl_orig_msg.wParam, 0, keystate, wbuf,
-+                        sizeof(wbuf)/sizeof(wbuf[0]), 0);
-+
-+        // No symbol for this key (or unexpected length)
-+        if ((ret == 0) || (ret < -1)) {
-+          buffer[0] = 0;
-+          Fl::e_length = 0;
-+          break;
-+        }
-+
-+        // A dead key. Convert this to a Unicode combining character so
-+        // that the application can tell the difference between dead and
-+        // normal keys.
-+        if (ret == -1) {
-+          xchar u = (xchar) msdead2fltk(wbuf[0]);
-+          Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
-+          buffer[Fl::e_length] = 0;
-+          break;
-+        }
-+
-+        // If we have two characters (or more) from ToUnicode(), that's
-+        // an invalid sequence. One character chould mean a proper symbol,
-+        // or it could mean a composed one. In both cases we need to call
-+        // ToUnicode() again to get something sane.
-+        if (i == 0)
-+          continue;
-+
-+        // We should now have something sane. Give whatever we have to the
-+        // application.
-+        Fl::e_length = fl_utf8fromwc(buffer, 1024, wbuf, ret);
-+        buffer[Fl::e_length] = 0;
-+      }
-+    } else if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
-       xchar u = (xchar) wParam;
- //    Fl::e_length = fl_unicode2utf(&u, 1, buffer);
-       Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
-       buffer[Fl::e_length] = 0;
-+    } else {
-+      buffer[0] = 0;
-+      Fl::e_length = 0;
-+    }
--
--    } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
--      if (state & FL_NUM_LOCK) {
--        // Convert to regular keypress...
--      buffer[0] = Fl::e_keysym-FL_KP;
--      Fl::e_length = 1;
--      } else {
--        // Convert to special keypress...
--      buffer[0] = 0;
--      Fl::e_length = 0;
-+    // The keypad area is a bit odd in that we need to change the keysym
-+    // to properly indicate what the user meant, unlike other keys where
-+    // we normally change the text and keep keysym stable.
-+    if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
-+      // The initial mapping tables give us a keysym that corresponds to
-+      // numlock being on, so we only do something when it is off.
-+      if (!(state & FL_NUM_LOCK)) {
-       switch (Fl::e_keysym) {
-         case FL_KP + '0' :
-           Fl::e_keysym = FL_Insert;
-@@ -1066,30 +1201,10 @@ static LRESULT CALLBACK WndProc(HWND hWn
-         case FL_KP + '.' :
-           Fl::e_keysym = FL_Delete;
-           break;
--        case FL_KP + '/' :
--        case FL_KP + '*' :
--        case FL_KP + '-' :
--        case FL_KP + '+' :
--          buffer[0] = Fl::e_keysym-FL_KP;
--          Fl::e_length = 1;
--          break;
-       }
-       }
--    } else if ((lParam & (1<<31))==0) {
--#ifdef FLTK_PREVIEW_DEAD_KEYS
--      if ((lParam & (1<<24))==0) { // clear if dead key (always?)
--        xchar u = (xchar) wParam;
--        Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
--        buffer[Fl::e_length] = 0;
--      } else { // set if "extended key" (never printable?)
--        buffer[0] = 0;
--        Fl::e_length = 0;
--      }
--#else
--      buffer[0] = 0;
--      Fl::e_length = 0;
--#endif
-     }
-+
-     Fl::e_text = buffer;
-     if (lParam & (1<<31)) { // key up events.
-       if (Fl::handle(FL_KEYUP, window)) return 0;
-diff -up fltk-1.3.x-r8695/configure.in.kbd-osx fltk-1.3.x-r8695/configure.in
---- fltk-1.3.x-r8695/configure.in.kbd-osx      2011-03-06 17:54:58.000000000 +0100
-+++ fltk-1.3.x-r8695/configure.in      2011-05-20 12:16:49.545510571 +0200
-@@ -874,6 +874,8 @@ case $uname_GUI in
-     Darwin*)
-         # MacOS X uses Cocoa for graphics.
-         LIBS="$LIBS -framework Cocoa"
-+        # And some Carbon for keyboard handling
-+        LIBS="$LIBS -framework Carbon"
-       if test x$have_pthread = xyes; then
-           AC_DEFINE(HAVE_PTHREAD)
-diff -up fltk-1.3.x-r8695/src/Fl_cocoa.mm.kbd-osx fltk-1.3.x-r8695/src/Fl_cocoa.mm
---- fltk-1.3.x-r8695/src/Fl_cocoa.mm.kbd-osx   2011-05-15 14:34:31.000000000 +0200
-+++ fltk-1.3.x-r8695/src/Fl_cocoa.mm   2011-05-20 12:21:01.376320373 +0200
-@@ -61,6 +61,7 @@ extern "C" {
- #include <stdarg.h>
- #import <Cocoa/Cocoa.h>
-+#import <Carbon/Carbon.h>
- #ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h
- #if defined(__LP64__) && __LP64__
-@@ -124,6 +125,8 @@ static Fl_Window* send_motion;
- extern Fl_Window* fl_xmousewin;
- #endif
-+bool use_simple_keyboard = false;
-+
- enum { FLTKTimerEvent = 1, FLTKDataReadyEvent };
-@@ -140,6 +143,39 @@ void fl_set_status(int x, int y, int w, 
- {
- }
-+// Undocumented voodoo. Taken from Mozilla.
-+#define ENABLE_ROMAN_KYBDS_ONLY -23
-+
-+void fl_update_focus(void)
-+{
-+  Fl_Widget *focus;
-+
-+  focus = Fl::grab();
-+  if (!focus)
-+    focus = Fl::focus();
-+  if (!focus)
-+    return;
-+
-+  if (focus->simple_keyboard())
-+    use_simple_keyboard = true;
-+  else
-+    use_simple_keyboard = false;
-+
-+  // Force a "Roman" or "ASCII" keyboard, which both the Mozilla and
-+  // Safari people seem to think implies turning off advanced IME stuff
-+  // (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput
-+  // in Safari/Webcore). Should be good enough for us then...
-+#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
-+  CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
-+  TSMSetDocumentProperty(TSMGetActiveDocument(),
-+                         kTSMDocumentEnabledInputSourcesPropertyTag,
-+                         sizeof(CFArrayRef), &inputSources);
-+  CFRelease(inputSources);
-+#else
-+  KeyScript(use_simple_keyboard ? ENABLE_ROMAN_KYBDS_ONLY : smKeyEnableKybds);
-+#endif  
-+}
-+
- /*
-  * Mac keyboard lookup table
-  * See also the inverse converter vktab in Fl_get_key_mac.cxx
-@@ -842,6 +878,25 @@ static void cocoaMouseHandler(NSEvent *t
- }
- @end
-+static const char* cocoaDead2FLTK(const char *in)
-+{
-+  if (strcmp(in, "\140") == 0)      // GRAVE ACCENT
-+    return "\314\200";              // COMBINING GRAVE ACCENT
-+  if (strcmp(in, "\302\264") == 0)  // ACUTE ACCENT
-+    return "\314\201";              // COMBINING ACUTE ACCENT
-+  if (strcmp(in, "\136") == 0)      // CIRCUMFLEX ACCENT
-+    return "\314\202";              // COMBINING CIRCUMFLEX ACCENT
-+  if (strcmp(in, "\176") == 0)      // TILDE
-+    return "\314\203";              // COMBINING TILDE
-+  if (strcmp(in, "\302\250") == 0)  // DIAERESIS
-+    return "\314\210";              // COMBINING DIAERESIS
-+  // FIXME: OS X dead key behaviour isn't documented and I don't have
-+  //        any more keyboards to test with...
-+
-+  // hope that OS X gave us something proper to begin with
-+  return in;
-+}
-+
- /*
- Handle cocoa keyboard events
- Events during a character composition sequence:
-@@ -1701,8 +1756,13 @@ static void  q_set_window_title(NSWindow
-       break;
-     }
-   }
-+  // Don't send cmd-<key> to interpretKeyEvents because it beeps.
-   if (!no_text_key && !(Fl::e_state & FL_META) ) {
--    // Don't send cmd-<key> to interpretKeyEvents because it beeps.
-+    // The simple keyboard model will ignore insertText, so we need to grab
-+    // the symbol directly from the event. Note that we still use setMarkedText.
-+    if (use_simple_keyboard)
-+      [FLView prepareEtext:[theEvent charactersIgnoringModifiers]];
-+
-     // Then we can let the OS have a stab at it and see if it thinks it
-     // should result in some text
-     NSText *edit = [[theEvent window]  fieldEditor:YES forObject:nil];
-@@ -1879,21 +1939,30 @@ static void  q_set_window_title(NSWindow
-   //NSLog(@"insertText: received=%@",received);
-   if (!in_key_event) fl_lock_function();
-+
-+  // Simple keyboard widgets do not want these side channel inputs.
-+  if (use_simple_keyboard)
-+    goto end;
-+
-   [FLView prepareEtext:received];
-+
-   // We can get called outside of key events (e.g. from the character
--  // palette). Transform such actions to FL_PASTE events.
-+  // palette). We need to fake our own key event at that point.
-   if (!in_key_event) {
-     Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
--    Fl::handle(FL_PASTE, target);
-+    Fl::e_keysym = Fl::e_original_keysym = 0;
-+    Fl::handle(FL_KEYDOWN, target);
-     // for some reason, the window does not redraw until the next mouse move or button push
-     // sending a 'redraw()' or 'awake()' does not solve the issue!
-     Fl::flush();
-   }
-+
-+end:
-   if (!in_key_event) fl_unlock_function();
- }
- - (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection  {
--  NSString *received;
-+  NSString *received, *current, *aggregate;
-   if (newSelection.location == 0) {
-     [self unmarkText];
-     return;
-@@ -1904,11 +1973,47 @@ static void  q_set_window_title(NSWindow
-     received = (NSString*)aString;
-   }
-   //NSLog(@"setMarkedText: %@ %d %d",received,newSelection.location,newSelection.length);
-+
-+  fl_lock_function();
-+
-+  // Simple keyboard widgets generally do not want these side channel
-+  // inputs, but we have no other way of getting dead keys so we make
-+  // an exception in that case.
-+  if (use_simple_keyboard) {
-+    if (in_key_event && (Fl::e_length == 0)) {
-+      [FLView prepareEtext:received];
-+
-+      Fl::e_text = (char*)cocoaDead2FLTK(Fl::e_text);
-+      Fl::e_length = strlen(Fl::e_text);
-+    }
-+    goto end;
-+  }
-+
-   // This code creates the OS X behaviour of seeing dead keys as things
-   // are being composed.
-+  //
-+  // Note: The concatenation thing is because of how OS X deals with
-+  //       invalid sequences. At that point it will spit out one call
-+  //       to insertText with the now aborted sequence, and one new
-+  //       call to setMarkedText with the new sequence. Since we want
-+  //       both to be visible, we need to concatenate.
-   next_compose_length = newSelection.location;
--  [FLView prepareEtext:received];
--  //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", received, Fl::e_length, next_compose_length);
-+  current = [NSString stringWithUTF8String:Fl::e_text];
-+  aggregate = [current stringByAppendingString:received];
-+
-+  [FLView prepareEtext:aggregate];
-+  //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", aggregate, Fl::e_length, next_compose_length);
-+
-+  // We can get called outside of key events (e.g. from the character
-+  // palette). We need to fake our own key event at that point.
-+  if (!in_key_event) {
-+    Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
-+    Fl::e_keysym = Fl::e_original_keysym = 0;
-+    Fl::handle(FL_KEYDOWN, target);
-+  }
-+
-+end:
-+  fl_unlock_function();
- }
- - (void)unmarkText {
-diff -up fltk-1.3.x-r8659/FL/Fl.H.orig fltk-1.3.x-r8659/FL/Fl.H
---- fltk-1.3.x-r8659/FL/Fl.H.orig      2011-05-17 16:25:56.671744548 +0200
-+++ fltk-1.3.x-r8659/FL/Fl.H   2011-05-17 16:26:05.709101536 +0200
-@@ -108,6 +108,9 @@ typedef int (*Fl_Args_Handler)(int argc,
-     \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 */
-@@ -744,6 +747,19 @@ public:
-   */
-   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
-diff -up fltk-1.3.x-r8659/src/Fl.cxx.orig fltk-1.3.x-r8659/src/Fl.cxx
---- fltk-1.3.x-r8659/src/Fl.cxx.orig   2011-05-18 15:20:26.667291459 +0200
-+++ fltk-1.3.x-r8659/src/Fl.cxx        2011-05-18 16:31:15.522026086 +0200
-@@ -430,6 +430,69 @@ static char in_idle;
- #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
-diff -up fltk-1.3.x-r8659/src/Fl_x.cxx.orig fltk-1.3.x-r8659/src/Fl_x.cxx
---- fltk-1.3.x-r8659/src/Fl_x.cxx.orig 2011-05-17 16:37:11.092011814 +0200
-+++ fltk-1.3.x-r8659/src/Fl_x.cxx      2011-05-18 13:51:06.135475325 +0200
-@@ -309,6 +309,9 @@ static Atom WM_PROTOCOLS;
- 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;
-@@ -678,6 +681,9 @@ void fl_open_display(Display* d) {
-   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);
-@@ -861,6 +881,86 @@ void Fl::copy(const char *stuff, int len
- }
- ////////////////////////////////////////////////////////////////
-+// 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;
-+
-+  // 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;
-+
-+  // 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 {
-+    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
-@@ -976,7 +1102,6 @@ int fl_handle(const XEvent& thisevent)
-     return 0;
-   case SelectionNotify: {
--    if (!fl_selection_requestor) return 0;
-     static unsigned char* buffer = 0;
-     if (buffer) {XFree(buffer); buffer = 0;}
-     long bytesread = 0;
-@@ -992,6 +1117,19 @@ int fl_handle(const XEvent& thisevent)
-                              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++) {
-@@ -1029,6 +1167,9 @@ int fl_handle(const XEvent& thisevent)
-       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;
-@@ -1049,6 +1190,7 @@ int fl_handle(const XEvent& thisevent)
-   case SelectionClear: {
-     int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
-     fl_i_own_selection[clipboard] = 0;
-+    poll_clipboard_owner();
-     return 1;}
-   case SelectionRequest: {
-@@ -1248,6 +1390,9 @@ int fl_handle(const XEvent& thisevent)
-   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:
-diff -up fltk-1.3.x-r8659/configh.in.clp-xfixes fltk-1.3.x-r8659/configh.in
---- fltk-1.3.x-r8659/configh.in.clp-xfixes     2011-03-06 17:54:58.000000000 +0100
-+++ fltk-1.3.x-r8659/configh.in        2011-05-19 16:55:27.986364764 +0200
-@@ -117,6 +117,14 @@
- #define USE_XDBE HAVE_XDBE
- /*
-+ * HAVE_XFIXES:
-+ *
-+ * Do we have the X fixes extension?
-+ */
-+
-+#define HAVE_XFIXES 0
-+
-+/*
-  * __APPLE_QUARTZ__:
-  *
-  * All Apple implementations are now based on Quartz and Cocoa,
-diff -up fltk-1.3.x-r8659/configure.in.clp-xfixes fltk-1.3.x-r8659/configure.in
---- fltk-1.3.x-r8659/configure.in.clp-xfixes   2011-05-19 16:55:27.976363265 +0200
-+++ fltk-1.3.x-r8659/configure.in      2011-05-19 16:55:27.987364914 +0200
-@@ -1008,6 +1008,16 @@ case $uname_GUI in
-               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 overlay visuals...
-       AC_PATH_PROG(XPROP, xprop)
-       AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay,
-diff -up fltk-1.3.x-r8659/src/Fl_x.cxx.clp-xfixes fltk-1.3.x-r8659/src/Fl_x.cxx
---- fltk-1.3.x-r8659/src/Fl_x.cxx.clp-xfixes   2011-05-19 16:55:27.984364466 +0200
-+++ fltk-1.3.x-r8659/src/Fl_x.cxx      2011-05-19 16:58:06.156112039 +0200
-@@ -53,6 +53,10 @@
- #  include <X11/Xlib.h>
- #  include <X11/keysym.h>
-+#  ifdef HAVE_XFIXES
-+#  include <X11/extensions/Xfixes.h>
-+#  endif
-+
- static Fl_Xlib_Graphics_Driver fl_xlib_driver;
- static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
- FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_xlib_driver; // the current target device of graphics operations
-@@ -303,6 +307,8 @@ XIC fl_xim_ic = 0;
- Window fl_xim_win = 0;
- char fl_is_over_the_spot = 0;
- static XRectangle status_area;
-+static bool have_xfixes = false;
-+static int xfixes_event_base = 0;
- static Atom WM_DELETE_WINDOW;
- static Atom WM_PROTOCOLS;
-@@ -726,6 +732,14 @@ void fl_open_display(Display* d) {
- #if !USE_COLORMAP
-   Fl::visual(FL_RGB);
- #endif
-+
-+#ifdef HAVE_XFIXES
-+  int error_base;
-+  if (XFixesQueryExtension(d, &xfixes_event_base, &error_base))
-+    have_xfixes = true;
-+  else
-+    have_xfixes = false;
-+#endif
- }
- void fl_close_display() {
-@@ -878,6 +892,10 @@ extern void fl_trigger_clipboard_notify(
- static void poll_clipboard_owner(void) {
-   Window xid;
-+  // No polling needed with Xfixes
-+  if (have_xfixes)
-+    return;
-+
-   // No one is interested, so no point polling
-   if (fl_clipboard_notify_empty())
-     return;
-@@ -916,10 +934,12 @@ static void handle_clipboard_timestamp(i
-   timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp;
--  // Initial scan, just store the value
--  if (*timestamp == (Time)-1) {
--    *timestamp = time;
--    return;
-+  if (!have_xfixes) {
-+    // Initial scan, just store the value
-+    if (*timestamp == (Time)-1) {
-+      *timestamp = time;
-+      return;
-+    }
-   }
-   // Same selection
-@@ -939,10 +959,12 @@ void fl_clipboard_notify_change() {
-     primary_timestamp = -1;
-     clipboard_timestamp = -1;
-   } else {
--    poll_clipboard_owner();
-+    if (!have_xfixes) {
-+      poll_clipboard_owner();
--    if (!Fl::has_timeout(clipboard_timeout))
--      Fl::add_timeout(0.5, clipboard_timeout);
-+      if (!Fl::has_timeout(clipboard_timeout))
-+        Fl::add_timeout(0.5, clipboard_timeout);
-+    }
-   }
- }
-@@ -1638,6 +1660,25 @@ int fl_handle(const XEvent& thisevent)
-     }
-   }
-+#ifdef 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);
- }
-@@ -1871,6 +1912,16 @@ void Fl_X::make_xid(Fl_Window* win, XVis
-     XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1);
-   }
-+#ifdef 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();
-diff -up fltk-1.3.x-r8659/src/Fl.cxx.orig fltk-1.3.x-r8659/src/Fl.cxx
---- fltk-1.3.x-r8659/src/Fl.cxx.orig   2011-05-18 17:39:15.639513675 +0200
-+++ fltk-1.3.x-r8659/src/Fl.cxx        2011-05-19 13:47:56.082954290 +0200
-@@ -1412,7 +1412,9 @@ int Fl::handle_(int e, Fl_Window* window
- ////////////////////////////////////////////////////////////////
- // hide() destroys the X window, it does not do unmap!
--#if !defined(WIN32) && USE_XFT
-+#if defined(WIN32)
-+extern void fl_update_clipboard(void);
-+#elif USE_XFT
- extern void fl_destroy_xft_draw(Window);
- #endif
-@@ -1459,14 +1461,8 @@ void Fl_Window::hide() {
- #if defined(WIN32)
-   // this little trick keeps the current clipboard alive, even if we are about
-   // to destroy the window that owns the selection.
--  if (GetClipboardOwner()==ip->xid) {
--    Fl_Window *w1 = Fl::first_window();
--    if (w1 && OpenClipboard(fl_xid(w1))) {
--      EmptyClipboard();
--      SetClipboardData(CF_TEXT, NULL);
--      CloseClipboard();
--    }
--  }
-+  if (GetClipboardOwner()==ip->xid)
-+    fl_update_clipboard();
-   // Send a message to myself so that I'll get out of the event loop...
-   PostMessage(ip->xid, WM_APP, 0, 0);
-   if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
-diff -up fltk-1.3.x-r8659/src/Fl_win32.cxx.orig fltk-1.3.x-r8659/src/Fl_win32.cxx
---- fltk-1.3.x-r8659/src/Fl_win32.cxx.orig     2011-05-19 13:48:59.655499725 +0200
-+++ fltk-1.3.x-r8659/src/Fl_win32.cxx  2011-05-19 13:49:31.147228227 +0200
-@@ -552,6 +552,36 @@ public:
-   const char* GetValue() const { return(out); }
- };
-+void fl_update_clipboard(void) {
-+  HWND hwnd = fl_xid(Fl::first_window());
-+
-+  if (!hwnd)
-+    return;
-+
-+  if (!OpenClipboard(hwnd))
-+    return;
-+
-+  EmptyClipboard();
-+
-+  int utf16_len = fl_utf8toUtf16(fl_selection_buffer[1],
-+                                 fl_selection_length[1], 0, 0);
-+
-+  HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
-+  LPVOID memLock = GlobalLock(hMem);
-+
-+  fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1],
-+                 (unsigned short*) memLock, utf16_len + 1);
-+
-+  GlobalUnlock(hMem);
-+  SetClipboardData(CF_UNICODETEXT, hMem);
-+
-+  CloseClipboard();
-+
-+  // In case Windows managed to lob of a WM_DESTROYCLIPBOARD during
-+  // the above.
-+  fl_i_own_selection[1] = 1;
-+}
-+
- // call this when you create a selection:
- void Fl::copy(const char *stuff, int len, int clipboard) {
-   if (!stuff || len<0) return;
-@@ -569,25 +599,9 @@ void Fl::copy(const char *stuff, int len
-   memcpy(fl_selection_buffer[clipboard], stuff, len);
-   fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
-   fl_selection_length[clipboard] = len;
--  if (clipboard) {
--    // set up for "delayed rendering":
--    if (OpenClipboard(NULL)) {
--      // if the system clipboard works, use it
--      int utf16_len = fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], 0, 0);
--      EmptyClipboard();
--      HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
--      LPVOID memLock = GlobalLock(hMem);
--      fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], (unsigned short*) memLock, utf16_len + 1);
--      GlobalUnlock(hMem);
--      SetClipboardData(CF_UNICODETEXT, hMem);
--      CloseClipboard();
--      GlobalFree(hMem);
--      fl_i_own_selection[clipboard] = 0;
--    } else {
--      // only if it fails, instruct paste() to use the internal buffers
--      fl_i_own_selection[clipboard] = 1;
--    }
--  }
-+  fl_i_own_selection[clipboard] = 1;
-+  if (clipboard)
-+    fl_update_clipboard();
- }
- // Call this when a "paste" operation happens:
-@@ -1282,34 +1296,6 @@ static LRESULT CALLBACK WndProc(HWND hWn
-     fl_i_own_selection[1] = 0;
-     return 1;
--  case WM_RENDERALLFORMATS:
--    fl_i_own_selection[1] = 0;
--    // Windoze seems unhappy unless I do these two steps. Documentation
--    // seems to vary on whether opening the clipboard is necessary or
--    // is in fact wrong:
--    CloseClipboard();
--    OpenClipboard(NULL);
--    // fall through...
--  case WM_RENDERFORMAT: {
--    HANDLE h;
--
--//  int l = fl_utf_nb_char((unsigned char*)fl_selection_buffer[1], fl_selection_length[1]);
--    int l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], NULL, 0); // Pass NULL buffer to query length required
--    h = GlobalAlloc(GHND, (l+1) * sizeof(unsigned short));
--    if (h) {
--      unsigned short *g = (unsigned short*) GlobalLock(h);
--//    fl_utf2unicode((unsigned char *)fl_selection_buffer[1], fl_selection_length[1], (xchar*)g);
--      l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], g, (l+1));
--      g[l] = 0;
--      GlobalUnlock(h);
--      SetClipboardData(CF_UNICODETEXT, h);
--    }
--
--    // Windoze also seems unhappy if I don't do this. Documentation very
--    // unclear on what is correct:
--    if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard();
--    return 1;}
--
-   default:
-     if (Fl::handle(0,0)) return 0;
-     break;
-diff -up fltk-1.3.x-r8659/src/Fl.cxx.win32-fix fltk-1.3.x-r8659/src/Fl.cxx
---- fltk-1.3.x-r8659/src/Fl.cxx.win32-fix      2011-05-19 13:47:56.082954290 +0200
-+++ fltk-1.3.x-r8659/src/Fl.cxx        2011-05-19 13:47:35.540869893 +0200
-@@ -1413,6 +1413,7 @@ int Fl::handle_(int e, Fl_Window* window
- // hide() destroys the X window, it does not do unmap!
- #if defined(WIN32)
-+extern void fl_clipboard_notify_untarget(HWND wnd);
- extern void fl_update_clipboard(void);
- #elif USE_XFT
- extern void fl_destroy_xft_draw(Window);
-@@ -1463,6 +1464,8 @@ void Fl_Window::hide() {
-   // to destroy the window that owns the selection.
-   if (GetClipboardOwner()==ip->xid)
-     fl_update_clipboard();
-+  // Make sure we unlink this window from the clipboard chain
-+  fl_clipboard_notify_untarget(ip->xid);
-   // Send a message to myself so that I'll get out of the event loop...
-   PostMessage(ip->xid, WM_APP, 0, 0);
-   if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
-diff -up fltk-1.3.x-r8659/src/Fl_win32.cxx.win32-fix fltk-1.3.x-r8659/src/Fl_win32.cxx
---- fltk-1.3.x-r8659/src/Fl_win32.cxx.win32-fix        2011-05-19 13:49:31.147228227 +0200
-+++ fltk-1.3.x-r8659/src/Fl_win32.cxx  2011-05-19 13:47:42.548922155 +0200
-@@ -654,6 +654,38 @@ void Fl::paste(Fl_Widget &receiver, int 
-   }
- }
-+static HWND clipboard_wnd = 0;
-+static HWND next_clipboard_wnd = 0;
-+
-+static bool initial_clipboard = true;
-+
-+void fl_clipboard_notify_change() {
-+  // No need to do anything here...
-+}
-+
-+void fl_clipboard_notify_target(HWND wnd) {
-+  if (clipboard_wnd)
-+    return;
-+
-+  // We get one fake WM_DRAWCLIPBOARD immediately, which we therefore
-+  // need to ignore.
-+  initial_clipboard = true;
-+
-+  clipboard_wnd = wnd;
-+  next_clipboard_wnd = SetClipboardViewer(wnd);
-+}
-+
-+void fl_clipboard_notify_untarget(HWND wnd) {
-+  if (wnd != clipboard_wnd)
-+    return;
-+
-+  ChangeClipboardChain(wnd, next_clipboard_wnd);
-+  clipboard_wnd = next_clipboard_wnd = 0;
-+
-+  if (Fl::first_window())
-+    fl_clipboard_notify_target(fl_xid(Fl::first_window()));
-+}
-+
- ////////////////////////////////////////////////////////////////
- char fl_is_ime = 0;
- void fl_get_codepage()
-@@ -1296,6 +1328,27 @@ static LRESULT CALLBACK WndProc(HWND hWn
-     fl_i_own_selection[1] = 0;
-     return 1;
-+  case WM_CHANGECBCHAIN:
-+    if ((hWnd == clipboard_wnd) &&
-+        (next_clipboard_wnd == (HWND)wParam)) {
-+      next_clipboard_wnd = (HWND)lParam;
-+      return 0;
-+    }
-+    break;
-+
-+  case WM_DRAWCLIPBOARD:
-+    // When the clipboard moves between two FLTK windows,
-+    // fl_i_own_selection will temporarily be false as we are
-+    // processing this message. Hence the need to use fl_find().
-+    if (!initial_clipboard && !fl_find(GetClipboardOwner()))
-+      fl_trigger_clipboard_notify(1);
-+    initial_clipboard = false;
-+
-+    if (next_clipboard_wnd)
-+      SendMessage(next_clipboard_wnd, WM_DRAWCLIPBOARD, wParam, lParam);
-+
-+    return 0;
-+
-   default:
-     if (Fl::handle(0,0)) return 0;
-     break;
-@@ -1652,6 +1705,8 @@ Fl_X* Fl_X::make(Fl_Window* w) {
-   x->next = Fl_X::first;
-   Fl_X::first = x;
-+  fl_clipboard_notify_target(x->xid);
-+
-   x->wait_for_expose = 1;
-   if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;}
-   if (showit) {
-diff -up fltk-1.3.x-r8659/src/Fl_cocoa.mm.orig fltk-1.3.x-r8659/src/Fl_cocoa.mm
---- fltk-1.3.x-r8659/src/Fl_cocoa.mm.orig      2011-05-19 14:22:48.558149919 +0200
-+++ fltk-1.3.x-r8659/src/Fl_cocoa.mm   2011-05-19 14:23:49.938366416 +0200
-@@ -1282,9 +1282,13 @@ extern "C" {
- }
- @end
-+static void clipboard_check(void);
-+
- @implementation FLApplication
- + (void)sendEvent:(NSEvent *)theEvent
- {
-+  // update clipboard status
-+  clipboard_check();
-   NSEventType type = [theEvent type];  
-   if (type == NSLeftMouseDown) {
-     fl_lock_function();
-@@ -2647,6 +2651,27 @@ void Fl::paste(Fl_Widget &receiver, int 
-   receiver.handle(FL_PASTE);
- }
-+extern void fl_trigger_clipboard_notify(int source);
-+
-+void fl_clipboard_notify_change() {
-+  // No need to do anything here...
-+}
-+
-+static void clipboard_check(void)
-+{
-+  PasteboardSyncFlags flags;
-+
-+  allocatePasteboard();
-+  flags = PasteboardSynchronize(myPasteboard);
-+
-+  if (!(flags & kPasteboardModified))
-+    return;
-+  if (flags & kPasteboardClientIsOwner)
-+    return;
-+
-+  fl_trigger_clipboard_notify(1);
-+}
-+
- void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
- {
-   // check, if this timer slot exists already
-diff -bur fltk-1.3.x-r8732.org/documentation/src/enumerations.dox fltk-1.3.x-r8732/documentation/src/enumerations.dox
---- fltk-1.3.x-r8732.org/documentation/src/enumerations.dox    2011-05-11 17:49:30.000000000 +0200
-+++ fltk-1.3.x-r8732/documentation/src/enumerations.dox        2011-05-26 10:15:39.258959203 +0200
-@@ -57,6 +57,7 @@
- \li FL_DND_LEAVE - The mouse pointer left a widget still dragging
-     data. 
- \li FL_DND_RELEASE - Dragged data is about to be dropped. 
-+\li FL_FULLSCREEN - The fullscreen state of the window has changed.
- \section enumerations_when Callback "When" Conditions
-diff -bur fltk-1.3.x-r8732.org/documentation/src/events.dox fltk-1.3.x-r8732/documentation/src/events.dox
---- fltk-1.3.x-r8732.org/documentation/src/events.dox  2011-05-11 17:49:30.000000000 +0200
-+++ fltk-1.3.x-r8732/documentation/src/events.dox      2011-05-26 10:15:39.259959029 +0200
-@@ -300,6 +300,13 @@
- the widget. If the widget returns 1, it will receive the data in
- the immediately following \p FL_PASTE event.
-+\subsection events_fl_fullscreen FL_FULLSCREEN
-+
-+The application window has been changed from normal to fullscreen, or
-+from fullscreen to normal. If you are using a X window manager which
-+supports Extended Window Manager Hints, this event will not be
-+delivered until the change has actually happened. 
-+
- \section events_event_xxx Fl::event_*() methods
-diff -bur fltk-1.3.x-r8732.org/FL/Enumerations.H fltk-1.3.x-r8732/FL/Enumerations.H
---- fltk-1.3.x-r8732.org/FL/Enumerations.H     2011-05-21 23:55:59.000000000 +0200
-+++ fltk-1.3.x-r8732/FL/Enumerations.H 2011-05-26 10:15:39.256959549 +0200
-@@ -292,7 +292,12 @@
-       If the widget returns 1, it will receive the data in the immediately 
-       following FL_PASTE event.
++   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
+*** fltk-1.3.0/FL/Fl_Image.H   2011-01-30 03:24:40.000000000 -0600
+--- fltk/FL/Fl_Image.H 2011-06-22 22:35:32.000000000 -0500
+***************
+*** 35,38 ****
+--- 35,39 ----
+  
+  class Fl_Widget;
++ class Fl_Pixmap;
+  struct Fl_Menu_Item;
+  struct Fl_Label;
+***************
+*** 197,200 ****
+--- 198,202 ----
+    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);
+*** fltk-1.3.0/FL/Fl_Widget.H  2011-04-24 12:09:41.000000000 -0500
+--- fltk/FL/Fl_Widget.H        2011-06-22 22:41:26.000000000 -0500
+***************
+*** 109,112 ****
+--- 109,113 ----
+  class FL_EXPORT Fl_Widget {
+    friend class Fl_Group;
++   friend class Fl_X;
+  
+    Fl_Group* parent_;
+***************
+*** 180,183 ****
+--- 181,186 ----
+          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
++         SIMPLE_KEYBOARD = 1<<18,  ///< the widget wants simple, consistent keypresses and not advanced input (like character composition and CJK input)
++         FULLSCREEN      = 1<<19,  ///< a fullscreen window (Fl_Window)
+          // (space for more flags)
+          USERFLAG3       = 1<<29,  ///< reserved for 3rd party extensions
+***************
+*** 785,788 ****
+--- 788,820 ----
+    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 
+***************
+*** 853,856 ****
+--- 885,891 ----
+    /* Internal use only. */
+    static int test_shortcut(const char*, const bool require_alt = false);
++   /* Internal use only. */
++   void _set_fullscreen() {flags_ |= FULLSCREEN;}
++   void _clear_fullscreen() {flags_ &= ~FULLSCREEN;}
+  
+    /** Checks if w is a child of this widget.
+*** fltk-1.3.0/FL/Fl_Window.H  2011-04-15 16:38:05.000000000 -0500
+--- fltk/FL/Fl_Window.H        2011-06-22 22:35:32.000000000 -0500
+***************
+*** 38,41 ****
+--- 38,42 ----
+  
+  class Fl_X;
++ class Fl_RGB_Image;
+  
+  /**
+***************
+*** 70,76 ****
+    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
+--- 71,77 ----
+    int dw, dh, aspect;
+    uchar size_range_set;
++   int no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h;
+    // cursor stuff
+    Fl_Cursor cursor_default;
+    void size_range_();
+    void _Fl_Window(); // constructor innards
+***************
+*** 385,392 ****
+      Makes the window completely fill the screen, without any window
+      manager border visible.  You must use fullscreen_off() to undo
+!     this. This may not work with all window managers.
+    */
+    void fullscreen();
+    /**
+      Turns off any side effects of fullscreen() and does 
+      resize(x,y,w,h).
+--- 386,401 ----
+      Makes the window completely fill the screen, 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.
     */
--  FL_DND_RELEASE      = 23
-+  FL_DND_RELEASE      = 23,
-+
-+  /** The fullscreen state of the window has changed
+    void fullscreen();
+    /**
++     Turns off any side effects of fullscreen()
 +   */
-+  FL_FULLSCREEN         = 24
-+
- };
- /** \name When Conditions */
-diff -bur fltk-1.3.x-r8732.org/FL/Fl_Widget.H fltk-1.3.x-r8732/FL/Fl_Widget.H
---- fltk-1.3.x-r8732.org/FL/Fl_Widget.H        2011-05-26 10:15:26.146232604 +0200
-+++ fltk-1.3.x-r8732/FL/Fl_Widget.H    2011-05-26 10:15:53.701455256 +0200
-@@ -180,6 +180,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
-         SIMPLE_KEYBOARD = 1<<18,  ///< the widget wants simple, consistent keypresses and not advanced input (like character composition and CJK input)
-+        FULLSCREEN      = 1<<19,  ///< a fullscreen window (Fl_Window)
-         // (space for more flags)
-         USERFLAG3       = 1<<29,  ///< reserved for 3rd party extensions
-         USERFLAG2       = 1<<30,  ///< reserved for 3rd party extensions
-@@ -882,6 +883,9 @@
-   static unsigned int label_shortcut(const char *t);
-   /* Internal use only. */
-   static int test_shortcut(const char*, const bool require_alt = false);
-+  /* Internal use only. */
-+  void _set_fullscreen() {flags_ |= FULLSCREEN;}
-+  void _clear_fullscreen() {flags_ &= ~FULLSCREEN;}
-   /** Checks if w is a child of this widget.
-       \param[in] w potential child widget
-Endast i fltk-1.3.x-r8732/FL: Fl_Widget.H.orig
-diff -bur fltk-1.3.x-r8732.org/FL/Fl_Window.H fltk-1.3.x-r8732/FL/Fl_Window.H
---- fltk-1.3.x-r8732.org/FL/Fl_Window.H        2011-04-15 23:38:05.000000000 +0200
-+++ fltk-1.3.x-r8732/FL/Fl_Window.H    2011-05-26 10:15:39.258959203 +0200
-@@ -69,6 +69,7 @@
-   int minw, minh, maxw, maxh;
-   int dw, dh, aspect;
-   uchar size_range_set;
-+  int no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h;
-   // cursor stuff
-   Fl_Cursor cursor_default;
-   Fl_Color cursor_fg, cursor_bg;
-@@ -384,15 +385,27 @@
-   /**
-     Makes the window completely fill the screen, without any window
-     manager border visible.  You must use fullscreen_off() to undo
--    this. This may not work with all window managers.
-+    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.
-   */
-   void fullscreen();
-   /**
-+    Turns off any side effects of fullscreen()
-+  */
-+  void fullscreen_off();
-+  /**
-     Turns off any side effects of fullscreen() and does 
-     resize(x,y,w,h).
-   */
-   void fullscreen_off(int,int,int,int);
-   /**
-+    Returns non zero if FULLSCREEN flag is set, 0 otherwise. 
++   void fullscreen_off();
++   /**
+      Turns off any side effects of fullscreen() and does 
+      resize(x,y,w,h).
+***************
+*** 394,397 ****
+--- 403,410 ----
+    void fullscreen_off(int,int,int,int);
+    /**
++     Returns non zero if FULLSCREEN flag is set, 0 otherwise. 
++   */
++   unsigned int fullscreen_active() const { return flags() & FULLSCREEN; }
++   /**
+      Iconifies the window.  If you call this when shown() is false
+      it will show() it as an icon.  If the window is already
+***************
+*** 435,446 ****
+  
+      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.
+    */
+!   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);
+    static void default_callback(Fl_Window*, void* v);
+    
+--- 448,462 ----
+  
+      The type Fl_Cursor is an enumeration defined in <FL/Enumerations.H>.
+  
+!     \see cursor(const Fl_RGB_Image*, int, int), default_cursor()
+    */
+!   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) { cursor(c); };
+!   void default_cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE) { default_cursor(c); };
+! 
+    static void default_callback(Fl_Window*, void* v);
+    
+*** fltk-1.3.0/FL/fl_draw.H    2011-06-02 03:06:09.000000000 -0500
+--- fltk/FL/fl_draw.H  2011-06-22 22:35:32.000000000 -0500
+***************
+*** 758,762 ****
+  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 const char* fl_expand_text(const char* from, char* buf, int maxbuf,
+                                       double maxw, int& n, double &width,
+--- 758,763 ----
+  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_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,
+*** fltk-1.3.0/FL/mac.H        2011-05-12 06:50:43.000000000 -0500
+--- fltk/FL/mac.H      2011-06-22 22:35:32.000000000 -0500
+***************
+*** 142,146 ****
+    WindowRef window_ref(void);
+    void set_key_window(void);
+!   void set_cursor(Fl_Cursor);
+    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);
+--- 142,147 ----
+    WindowRef window_ref(void);
+    void set_key_window(void);
+!   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);
+*** fltk-1.3.0/FL/names.h      2010-11-28 15:06:39.000000000 -0600
+--- fltk/FL/names.h    2011-06-22 22:35:32.000000000 -0500
+***************
+*** 76,79 ****
+--- 76,80 ----
+    "FL_DND_LEAVE",
+    "FL_DND_RELEASE",
++   "FL_FULLSCREEN"
+  };
+  
+*** fltk-1.3.0/FL/win32.H      2011-05-23 13:32:47.000000000 -0500
+--- fltk/FL/win32.H    2011-06-22 22:35:32.000000000 -0500
+***************
+*** 93,96 ****
+--- 93,98 ----
+    void set_minmax(LPMINMAXINFO minmax);
+    void mapraise();
++   int set_cursor(Fl_Cursor);
++   int set_cursor(const Fl_RGB_Image*, int, int);
+    static Fl_X* make(Fl_Window*);
+  };
+*** fltk-1.3.0/FL/x.H  2011-05-21 05:05:19.000000000 -0500
+--- fltk/FL/x.H        2011-06-22 22:35:32.000000000 -0500
+***************
+*** 164,167 ****
+--- 164,169 ----
+    void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
+    void sendxjunk();
++   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);
+*** fltk-1.3.0/configh.in      2011-06-09 11:21:40.000000000 -0500
+--- fltk/configh.in    2011-06-22 22:35:32.000000000 -0500
+***************
+*** 118,121 ****
+--- 118,137 ----
+  
+  /*
++  * HAVE_XFIXES:
++  *
++  * Do we have the X fixes extension?
 +  */
-+  unsigned int fullscreen_active() const { return flags() & FULLSCREEN; }
-+  /**
-     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.
-diff -bur fltk-1.3.x-r8732.org/FL/names.h fltk-1.3.x-r8732/FL/names.h
---- fltk-1.3.x-r8732.org/FL/names.h    2010-11-28 22:06:39.000000000 +0100
-+++ fltk-1.3.x-r8732/FL/names.h        2011-05-26 10:15:39.257959376 +0200
-@@ -75,6 +75,7 @@
-   "FL_DND_DRAG",
-   "FL_DND_LEAVE",
-   "FL_DND_RELEASE",
-+  "FL_FULLSCREEN"
- };
- /**
-diff -bur fltk-1.3.x-r8732.org/src/Fl_cocoa.mm fltk-1.3.x-r8732/src/Fl_cocoa.mm
---- fltk-1.3.x-r8732.org/src/Fl_cocoa.mm       2011-05-26 10:15:26.168228790 +0200
-+++ fltk-1.3.x-r8732/src/Fl_cocoa.mm   2011-05-26 10:15:39.255959723 +0200
-@@ -649,6 +649,10 @@
- {
-   containsGLsubwindow = contains;
- }
-+- (BOOL)canBecomeKeyWindow
-+{
-+  return YES;
-+}
- @end
- @interface FLApplication : NSObject
-@@ -1087,6 +1091,10 @@
-   fl_lock_function();
-   FLWindow *nsw = (FLWindow*)[notif object];
-   Fl_Window *window = [nsw getFl_Window];
-+  /* Fullscreen windows obscure all other windows so we need to return
-+     to a "normal" level when the user switches to another window */
-+  if (window->fullscreen_active())
-+    [nsw setLevel:NSNormalWindowLevel];
-   Fl::handle( FL_UNFOCUS, window);
-   fl_unlock_function();
- }
-@@ -1095,6 +1103,9 @@
-   fl_lock_function();
-   FLWindow *nsw = (FLWindow*)[notif object];
-   Fl_Window *w = [nsw getFl_Window];
-+  /* Restore previous fullscreen level */
-+  if (w->fullscreen_active())
-+    [nsw setLevel:NSStatusWindowLevel];
-   if ( w->border() || (!w->modal() && !w->tooltip_window()) ) Fl::handle( FL_FOCUS, w);
-   fl_unlock_function();
- }
-@@ -2087,6 +2098,22 @@
- @end
-+void fullscreen_x(Fl_Window *w) {
-+  w->_set_fullscreen();
-+  /* On OS X < 10.6, it is necessary to recreate the window. This is done
-+     with hide+show. */
-+  w->hide();
-+  w->show();
-+  Fl::handle(FL_FULLSCREEN, w);
-+}
-+
-+void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
-+  w->_clear_fullscreen();
-+  w->hide();
-+  w->resize(X, Y, W, H);
-+  w->show();
-+  Fl::handle(FL_FULLSCREEN, w);
-+}
- /*
-  * go ahead, create that (sub)window
-@@ -2210,6 +2237,13 @@
-     x->gc = 0;
-         
-     NSRect srect = [[NSScreen mainScreen] frame];
-+    if (w->flags() & Fl_Widget::FULLSCREEN) {
-+      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);
-+      winstyle = NSBorderlessWindowMask;
-+      winlevel = NSStatusWindowLevel;
-+    }
-     NSRect crect;
-     crect.origin.x = w->x(); 
-     crect.origin.y = srect.size.height - (w->y() + w->h());
-Endast i fltk-1.3.x-r8732/src: Fl_cocoa.mm.orig
-diff -bur fltk-1.3.x-r8732.org/src/Fl_grab.cxx fltk-1.3.x-r8732/src/Fl_grab.cxx
---- fltk-1.3.x-r8732.org/src/Fl_grab.cxx       2011-05-26 10:15:26.147232431 +0200
-+++ fltk-1.3.x-r8732/src/Fl_grab.cxx   2011-05-26 10:15:39.250960589 +0200
-@@ -51,7 +51,19 @@
- extern void *fl_capture;
- #endif
-+#if !(defined(WIN32) || defined(__APPLE__))
-+extern int ewmh_supported(); // from Fl_x.cxx
-+#endif
-+
- void Fl::grab(Fl_Window* win) {
-+    Fl_Window *fullscreen_win = NULL;
-+    for (Fl_Window *W = Fl::first_window(); W; W = Fl::next_window(W)) {
-+      if (W->fullscreen_active()) {
-+        fullscreen_win = W;
-+        break;
-+      }
-+    }
-+
-   if (win) {
-     if (!grab_) {
- #ifdef WIN32
-@@ -61,8 +73,9 @@
-       fl_capture = Fl_X::i(first_window())->xid;
-       Fl_X::i(first_window())->set_key_window();
- #else
-+      Window xid = fullscreen_win ? fl_xid(fullscreen_win) : fl_xid(first_window());
-       XGrabPointer(fl_display,
--                 fl_xid(first_window()),
-+                 xid,
-                  1,
-                  ButtonPressMask|ButtonReleaseMask|
-                  ButtonMotionMask|PointerMotionMask,
-@@ -72,7 +85,7 @@
-                  0,
-                  fl_event_time);
-       XGrabKeyboard(fl_display,
--                  fl_xid(first_window()),
-+                  xid,
-                   1,
-                   GrabModeAsync,
-                   GrabModeAsync, 
-@@ -89,7 +102,10 @@
- #elif defined(__APPLE__)
-       fl_capture = 0;
- #else
-+      // We must keep the grab in the non-EWMH fullscreen case
-+      if (!fullscreen_win || ewmh_supported()) {
-       XUngrabKeyboard(fl_display, fl_event_time);
-+      }
-       XUngrabPointer(fl_display, fl_event_time);
-       // this flush is done in case the picked menu item goes into
-       // an infinite loop, so we don't leave the X server locked up:
-Endast i fltk-1.3.x-r8732/src: Fl_grab.cxx.orig
-diff -bur fltk-1.3.x-r8732.org/src/Fl_win32.cxx fltk-1.3.x-r8732/src/Fl_win32.cxx
---- fltk-1.3.x-r8732.org/src/Fl_win32.cxx      2011-05-26 10:15:26.165229310 +0200
-+++ fltk-1.3.x-r8732/src/Fl_win32.cxx  2011-05-26 10:15:39.252960243 +0200
-@@ -1490,6 +1490,11 @@
-   X+=xoff;
-   Y+=yoff;
-+  if (w->flags() & Fl_Widget::FULLSCREEN) {
-+    X = Y = 0;
-+    bx = by = bt = 0;
-+  }
-+
-   return ret;
- }
-@@ -1540,6 +1545,58 @@
-   }
- }
-+static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) {
-+  int sx, sy, sw, sh;
-+  Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H);
-+  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);
-+}
-+
-+void fullscreen_x(Fl_Window *w) {
-+  w->_set_fullscreen();
-+  make_fullscreen(w, fl_xid(w), w->x(), w->y(), w->w(), w->h());
-+  Fl::handle(FL_FULLSCREEN, w);
-+}
-+
-+void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
-+  w->_clear_fullscreen();
-+  DWORD style = GetWindowLong(fl_xid(w), GWL_STYLE);
-+  // Remove the xid temporarily so that Fl_X::fake_X_wm() behaves like it
-+  // does in Fl_X::make().
-+  HWND xid = fl_xid(w);
-+  Fl_X::i(w)->xid = NULL;
-+  int x, y, bt, bx, by;
-+  switch (Fl_X::fake_X_wm(w, x, y, bt, bx, by)) {
-+  case 0: 
-+    break;
-+  case 1: 
-+    style |= WS_CAPTION; 
-+    break;
-+  case 2: 
-+    if (w->border()) {
-+      style |= WS_THICKFRAME | WS_CAPTION; 
-+    }
-+    break;
-+  }
-+  Fl_X::i(w)->xid = xid;
-+  // Adjust for decorations (but not if that puts the decorations
-+  // outside the screen)
-+  if ((X != w->x()) || (Y != w->y())) {
-+    X -= bx;
-+    Y -= by+bt;
-+  }
-+  W += bx*2;
-+  H += by*2+bt;
-+  SetWindowLong(fl_xid(w), GWL_STYLE, style);
-+  SetWindowPos(fl_xid(w), 0, X, Y, W, H,
-+               SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
-+  Fl::handle(FL_FULLSCREEN, w);
-+}
-+
-+
- ////////////////////////////////////////////////////////////////
- /*
-@@ -1669,18 +1726,26 @@ Fl_X* Fl_X::make(Fl_Window* w) {
-     int xwm = xp , ywm = yp , bt, bx, by;
-     switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) {
-       // No border (used for menus)
--      case 0: style |= WS_POPUP;
--              styleEx |= WS_EX_TOOLWINDOW;
-+      case 0:
-+        style |= WS_POPUP;
-+        styleEx |= WS_EX_TOOLWINDOW;
-             break;
-       // Thin border and title bar
--      case 1: style |= WS_DLGFRAME | WS_CAPTION; break;
-+      case 1:
-+        style |= WS_DLGFRAME | WS_CAPTION;
-+        if (!w->modal())
-+          style |= WS_SYSMENU | WS_MINIMIZEBOX;
-+        break;
-       // Thick, resizable border and title bar, with maximize button
--      case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break;
-+      case 2:
-+        style |= WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_CAPTION;
-+        if (!w->modal())
-+          style |= WS_MINIMIZEBOX;
-+        break;
-     }
-     if (by+bt) {
--      if (!w->modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX;
-       wp += 2*bx;
-       hp += 2*by+bt;
-     }
-@@ -1736,6 +1801,18 @@
-   );
-   if (lab) free(lab);
-+  if (w->flags() & Fl_Widget::FULLSCREEN) {
-+  /* We need to make sure that the fullscreen is created on the
-+     default monitor, ie the desktop where the shortcut is located
-+     etc. This requires that CreateWindow is called with CW_USEDEFAULT
-+     for x and y. We can then use GetWindowRect to determine which
-+     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->next = Fl_X::first;
-   Fl_X::first = x;
-@@ -1753,7 +1830,7 @@
-   // 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 :
--           (Fl::grab() || (style & WS_POPUP)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
-+           (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
-   // Register all windows for potential drag'n'drop operations
-   fl_OleInitialize();
-Endast i fltk-1.3.x-r8732/src: Fl_win32.cxx.orig
-diff -bur fltk-1.3.x-r8732.org/src/Fl_Window.cxx fltk-1.3.x-r8732/src/Fl_Window.cxx
---- fltk-1.3.x-r8732.org/src/Fl_Window.cxx     2011-02-25 09:44:47.000000000 +0100
-+++ fltk-1.3.x-r8732/src/Fl_Window.cxx 2011-05-26 10:15:39.250960589 +0200
-@@ -59,6 +59,10 @@
-   resizable(0);
-   size_range_set = 0;
-   minw = maxw = minh = maxh = 0;
-+  no_fullscreen_x = 0;
-+  no_fullscreen_y = 0;
-+  no_fullscreen_w = w();
-+  no_fullscreen_h = h();
-   callback((Fl_Callback*)default_callback);
- }
-diff -bur fltk-1.3.x-r8732.org/src/Fl_Window_fullscreen.cxx fltk-1.3.x-r8732/src/Fl_Window_fullscreen.cxx
---- fltk-1.3.x-r8732.org/src/Fl_Window_fullscreen.cxx  2011-03-12 22:36:21.000000000 +0100
-+++ fltk-1.3.x-r8732/src/Fl_Window_fullscreen.cxx      2011-05-26 10:15:39.249960763 +0200
-@@ -60,39 +60,48 @@
- #endif
- }
-+void fullscreen_x(Fl_Window *w);
-+void fullscreen_off_x();
-+void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H);
-+
-+/* Note: The previous implementation toggled border(). With this new
-+   implementation this is not necessary. Additionally, if we do that,
-+   the application may lose focus when switching out of fullscreen
-+   mode with some window managers. Besides, the API does not say that
-+   the FLTK border state should be toggled; it only says that the
-+   borders should not be *visible*. 
-+*/
- void Fl_Window::fullscreen() {
--#ifndef WIN32
--  //this would clobber the fake wm, since it relies on the border flags to
--  //determine its thickness
--  border(0);
--#endif
--#if defined(__APPLE__) || defined(WIN32) || defined(USE_X11)
--  int sx, sy, sw, sh;
--  Fl::screen_xywh(sx, sy, sw, sh, x(), y(), w(), h());
--  // if we are on the main screen, we will leave the system menu bar unobstructed
--  if (Fl::x()>=sx && Fl::y()>=sy && Fl::x()+Fl::w()<=sx+sw && Fl::y()+Fl::h()<=sy+sh) {
--    sx = Fl::x(); sy = Fl::y(); 
--    sw = Fl::w(); sh = Fl::h();
-+  if (shown() && !(flags() & Fl_Widget::FULLSCREEN)) {
-+    no_fullscreen_x = x();
-+    no_fullscreen_y = y();
-+    no_fullscreen_w = w();
-+    no_fullscreen_h = h();
-+    fullscreen_x(this);
-+  } else {
-+    set_flag(FULLSCREEN);
-   }
--  if (x()==sx) x(sx+1); // make sure that we actually execute the resize
--#if defined(USE_X11)
--  resize(0, 0, w(), h()); // work around some quirks in X11
--#endif
--  resize(sx, sy, sw, sh);
--#else
--  if (!x()) x(1); // make sure that we actually execute the resize
--  resize(0,0,Fl::w(),Fl::h());
--#endif
- }
- void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
--  // this order produces less blinking on IRIX:
--  resize(X,Y,W,H);
--#ifndef WIN32
--  border(1);
--#endif
-+  if (shown() && (flags() & Fl_Widget::FULLSCREEN)) {
-+    fullscreen_off_x(this, X, Y, W, H);
-+  } else {
-+    clear_flag(FULLSCREEN);
-+  }
-+  no_fullscreen_x = no_fullscreen_y = no_fullscreen_w = no_fullscreen_h = 0;
- }
-+void Fl_Window::fullscreen_off() {
-+  if (!no_fullscreen_x && !no_fullscreen_y) {
-+    // Window was initially created fullscreen - default to current monitor
-+    no_fullscreen_x = x();
-+    no_fullscreen_y = y();
-+  }
-+  fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h);
-+}
-+
-+
- //
- // End of "$Id: Fl_Window_fullscreen.cxx 8515 2011-03-12 21:36:21Z manolo $".
- //
-Endast i fltk-1.3.x-r8732/src: Fl_Window_fullscreen.cxx.orig
-diff -bur fltk-1.3.x-r8732.org/src/Fl_x.cxx fltk-1.3.x-r8732/src/Fl_x.cxx
---- fltk-1.3.x-r8732.org/src/Fl_x.cxx  2011-05-26 10:15:26.159230350 +0200
-+++ fltk-1.3.x-r8732/src/Fl_x.cxx      2011-05-26 10:15:39.253960069 +0200
-@@ -338,6 +338,9 @@
- Atom fl_XaTextUriList;
- Atom fl_NET_WM_NAME;                  // utf8 aware window label
- Atom fl_NET_WM_ICON_NAME;             // utf8 aware window icon name
-+Atom fl_NET_SUPPORTING_WM_CHECK;
-+Atom fl_NET_WM_STATE;
-+Atom fl_NET_WM_STATE_FULLSCREEN;
- /*
-   X defines 32-bit-entities to have a format value of max. 32,
-@@ -711,6 +714,9 @@
-   fl_XaTextUriList      = XInternAtom(d, "text/uri-list",       0);
-   fl_NET_WM_NAME        = XInternAtom(d, "_NET_WM_NAME",        0);
-   fl_NET_WM_ICON_NAME   = XInternAtom(d, "_NET_WM_ICON_NAME",   0);
-+  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);
-   if (sizeof(Atom) < 4)
-     atom_bits = sizeof(Atom) * 8;
-@@ -862,6 +868,31 @@
-   XSendEvent(fl_display, window, 0, 0, &e);
- }
-+
-+/* 
-+   Get window property value (32 bit format) 
-+   Returns zero on success, -1 on error
-+*/
-+static int get_xwinprop(Window wnd, Atom prop, long max_length,
-+                        unsigned long *nitems, unsigned long **data) {
-+  Atom actual;
-+  int format;
-+  unsigned long bytes_after;
-+  
-+  if (Success != XGetWindowProperty(fl_display, wnd, prop, 0, max_length, 
-+                                    False, AnyPropertyType, &actual, &format, 
-+                                    nitems, &bytes_after, (unsigned char**)data)) {
-+    return -1;
-+  }
-+
-+  if (actual == None || format != 32) {
-+    return -1;
-+  }
-+
-+  return 0;
-+}
-+
-+
- ////////////////////////////////////////////////////////////////
- // Code for copying to clipboard and DnD out of the program:
-@@ -1631,6 +1662,31 @@
-     in_a_window = true;
-     break;
-+  case PropertyNotify:
-+    if (xevent.xproperty.atom == fl_NET_WM_STATE) {
-+      int fullscreen_state = 0;
-+      if (xevent.xproperty.state != PropertyDelete) {
-+        unsigned long nitems;
-+        unsigned long *words = 0;
-+        if (0 == get_xwinprop(xid, fl_NET_WM_STATE, 64, &nitems, &words) ) { 
-+          for (unsigned long item = 0; item < nitems; item++) {
-+            if (words[item] == fl_NET_WM_STATE_FULLSCREEN) {
-+              fullscreen_state = 1;
-+            }
-+          }
-+        }
-+      }
-+      if (window->fullscreen_active() && !fullscreen_state) {
-+        window->_clear_fullscreen();
-+        event = FL_FULLSCREEN;
-+      }
-+      if (!window->fullscreen_active() && fullscreen_state) {
-+        window->_set_fullscreen();
-+        event = FL_FULLSCREEN;
-+      }
-+    }
-+    break;
-+
-   case MotionNotify:
-     set_event_xy();
- #  if CONSOLIDATE_MOTION
-@@ -1789,6 +1845,75 @@
- ////////////////////////////////////////////////////////////////
-+#define _NET_WM_STATE_REMOVE        0  /* remove/unset property */
-+#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) {
-+  XEvent e;
-+  e.xany.type = ClientMessage;
-+  e.xany.window = wnd;
-+  e.xclient.message_type = fl_NET_WM_STATE;
-+  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;
-+  XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
-+             0, SubstructureNotifyMask | SubstructureRedirectMask,
-+             &e);
-+}
-+
-+int ewmh_supported() {
-+  static int result = -1;
-+
-+  if (result == -1) {
-+    result = 0;
-+    unsigned long nitems;
-+    unsigned long *words = 0;
-+    if (0 == get_xwinprop(XRootWindow(fl_display, fl_screen), fl_NET_SUPPORTING_WM_CHECK, 64,
-+                          &nitems, &words) && nitems == 1) {
-+      Window child = words[0];
-+      if (0 == get_xwinprop(child, fl_NET_SUPPORTING_WM_CHECK, 64,
-+                           &nitems, &words) && nitems == 1) {
-+        result = (child == words[0]);
-+      }
-+    }
-+  }
-+
-+  return result;
-+}
-+
-+/* Change an existing window to fullscreen */
-+void fullscreen_x(Fl_Window *w) {
-+  if (ewmh_supported()) {
-+    send_wm_state_event(fl_xid(w), 1, fl_NET_WM_STATE_FULLSCREEN);
-+  } else {
-+    w->_set_fullscreen();
-+    w->hide();
-+    w->show();
-+    /* We want to grab the window, not a widget, so we cannot use Fl::grab */
-+    XGrabKeyboard(fl_display, fl_xid(w), 1, GrabModeAsync, GrabModeAsync, fl_event_time);
-+    Fl::handle(FL_FULLSCREEN, w);
-+  }
-+}
-+
-+void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
-+  if (ewmh_supported()) {
-+    send_wm_state_event(fl_xid(w), 0, fl_NET_WM_STATE_FULLSCREEN);
-+  } else {
-+    w->_clear_fullscreen();
-+    /* The grab will be lost when the window is destroyed */
-+    w->hide();
-+    w->resize(X,Y,W,H);
-+    w->show();
-+    Fl::handle(FL_FULLSCREEN, w);
-+  }
-+}
-+
-+////////////////////////////////////////////////////////////////
-+
- // A subclass of Fl_Window may call this to associate an X window it
- // creates with the Fl_Window:
-@@ -1824,6 +1949,7 @@
- |KeyPressMask|KeyReleaseMask|KeymapStateMask|FocusChangeMask
- |ButtonPressMask|ButtonReleaseMask
- |EnterWindowMask|LeaveWindowMask
-+|PropertyChangeMask
- |PointerMotionMask;
- void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
-@@ -1895,6 +2021,16 @@
-     attr.save_under = 1; mask |= CWSaveUnder;
-     if (!win->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;}
-   }
-+  // For the non-EWMH fullscreen case, we cannot use the code above,
-+  // since we do not want save_under, do not want to turn off the
-+  // border, and cannot grab without an existing window. Besides, 
-+  // there is no clear_override(). 
-+  if (win->flags() & Fl_Widget::FULLSCREEN && !ewmh_supported()) {
-+    attr.override_redirect = 1;
-+    mask |= CWOverrideRedirect;
-+    Fl::screen_xywh(X, Y, W, H, X, Y, W, H);
-+  }
-+
-   if (fl_background_pixel >= 0) {
-     attr.background_pixel = fl_background_pixel;
-     fl_background_pixel = -1;
-@@ -1954,6 +2090,12 @@
-           PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1);
-     }
-+    // If asked for, create fullscreen
-+    if (win->flags() & Fl_Widget::FULLSCREEN && ewmh_supported()) {
-+      XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
-+                       PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
-+    }
-+
-     // Make it receptive to DnD:
-     long version = 4;
-     XChangeProperty(fl_display, xp->xid, fl_XdndAware,
-@@ -2001,6 +2143,12 @@
-     Fl::e_number = old_event;
-     win->redraw();
-   }
-+
-+  // non-EWMH fullscreen case, need grab
-+  if (win->flags() & Fl_Widget::FULLSCREEN && !ewmh_supported()) {
-+    XGrabKeyboard(fl_display, xp->xid, 1, GrabModeAsync, GrabModeAsync, fl_event_time);
-+  }
-+
- }
- ////////////////////////////////////////////////////////////////
-Endast i fltk-1.3.x-r8732/src: Fl_x.cxx.orig
-diff -bur fltk-1.3.x-r8732.org/test/fullscreen.cxx fltk-1.3.x-r8732/test/fullscreen.cxx
---- fltk-1.3.x-r8732.org/test/fullscreen.cxx   2010-12-15 13:11:16.000000000 +0100
-+++ fltk-1.3.x-r8732/test/fullscreen.cxx       2011-05-26 10:15:39.258959203 +0200
-@@ -60,8 +60,11 @@
- #include <FL/Fl.H>
- #include <FL/Fl_Single_Window.H>
- #include <FL/Fl_Hor_Slider.H>
-+#include <FL/Fl_Input.H>
-+#include <FL/Fl_Menu_Button.H>
- #include <FL/Fl_Toggle_Light_Button.H>
- #include <FL/math.h>
-+#include <FL/fl_ask.H>
- #include <stdio.h>
- #if HAVE_GL
-@@ -124,6 +127,28 @@
- #endif
-+class fullscreen_window : public Fl_Single_Window {
-+
-+  public:
-+  fullscreen_window(int W, int H, const char *t=0);
-+  int handle (int e);
-+  Fl_Toggle_Light_Button *b3;
-+
-+};
-+
-+fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Window(W, H, t) { 
-+
-+}
-+
-+int fullscreen_window::handle(int e) {
-+  if (e == FL_FULLSCREEN) {
-+    printf("Recieved FL_FULLSCREEN event\n");
-+    b3->value(fullscreen_active());
-+  }
-+  if (Fl_Single_Window::handle(e)) return 1;
-+  return 0;
-+}
-+
- void sides_cb(Fl_Widget *o, void *p) {
-   shape_window *sw = (shape_window *)p;
-   sw->sides = int(((Fl_Slider *)o)->value());
-@@ -161,13 +186,14 @@
-     py = w->y();
-     pw = w->w();
-     ph = w->h();
--#ifndef WIN32//necessary because fullscreen removes border
--      border_button->value(0);
--      border_button->do_callback();
--#endif
-     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(px,py,pw,ph);
-+    w->fullscreen_off();
-   }
- }
-@@ -177,7 +203,7 @@
-   exit(0);
- }
--#define NUMB 5
-+#define NUMB 6
- int twowindow = 0;
- int initfull = 0;
-@@ -193,7 +219,7 @@
-   if (Fl::args(argc,argv,i,arg) < argc)
-     Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
--  Fl_Single_Window window(300,300+30*NUMB); window.end();
-+  fullscreen_window window(300,300+30*NUMB); window.end();
-   shape_window sw(10,10,window.w()-20,window.h()-30*NUMB-20);
- #if HAVE_GL
-@@ -228,21 +254,24 @@
-   b1.callback(double_cb,&sw);
-   y+=30;
-+  Fl_Input i1(50,y,window.w()-60,30, "Input");
-+  y+=30;
-+
-   Fl_Toggle_Light_Button b2(50,y,window.w()-60,30,"Border");
-   b2.callback(border_cb,w);
-   b2.set();
-   border_button = &b2;
-   y+=30;
--  Fl_Toggle_Light_Button b3(50,y,window.w()-60,30,"FullScreen");
--  b3.callback(fullscreen_cb,w);
-+  window.b3 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"FullScreen");
-+  window.b3->callback(fullscreen_cb,w);
-   y+=30;
-   Fl_Button eb(50,y,window.w()-60,30,"Exit");
-   eb.callback(exit_cb);
-   y+=30;
--  if (initfull) {b3.set(); b3.do_callback();}
-+  if (initfull) {window.b3->set(); window.b3->do_callback();}
-   window.end();
-   window.show(argc,argv);
-Index: fltk-1.3.x-r8772/src/Fl_Image.cxx
-===================================================================
---- fltk-1.3.x-r8772/src/Fl_Image.cxx  (revision 8771)
-+++ fltk-1.3.x-r8772/src/Fl_Image.cxx  (working copy)
-@@ -172,6 +172,19 @@
- //
- // RGB image class...
- //
-+
-+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. */
-+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 free all memory and server resources that are used by  the image. */
- Fl_RGB_Image::~Fl_RGB_Image() {
-   uncache();
-Index: fltk-1.3.x-r8772/FL/Fl_Image.H
-===================================================================
---- fltk-1.3.x-r8772/FL/Fl_Image.H     (revision 8771)
-+++ fltk-1.3.x-r8772/FL/Fl_Image.H     (working copy)
-@@ -34,6 +34,7 @@
- #  include "Enumerations.H"
- class Fl_Widget;
-+class Fl_Pixmap;
- struct Fl_Menu_Item;
- struct Fl_Label;
-@@ -196,6 +197,7 @@
- /**  The constructor creates a new image from the specified data. */
-   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()); }
-Index: fltk-1.3.x-r8772/src/fl_draw_pixmap.cxx
-===================================================================
---- fltk-1.3.x-r8772/src/fl_draw_pixmap.cxx    (revision 8771)
-+++ fltk-1.3.x-r8772/src/fl_draw_pixmap.cxx    (working copy)
-@@ -67,99 +67,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
- /**
-@@ -209,34 +116,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;
-   uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
-+
-+  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
-   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;
-       transparent_c = c;
-@@ -245,13 +151,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);
-@@ -261,75 +161,49 @@
-       *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;
--      transparent_c = c;
-+        transparent_index = ind;
-+        transparent_c = c;
-       }
-     }
-   }
--  d.data = data;
- #ifdef WIN32
-   if (transparent_c) {
-     make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
-@@ -339,88 +213,85 @@
-     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)
++ 
++ #define HAVE_XFIXES 0
++ 
++ /*
++  * HAVE_XCURSOR:
++  *
++  * Do we have the X cursor library?
 +  */
-+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_graphics_driver->class_name() == Fl_Quartz_Graphics_Driver::class_id ) {
--    bool transparent = (transparent_index>=0);
--    transparent = true;
--    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++];
--      }
--      }
--    }
-     CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
--    CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L);
--    CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w,
--                                 lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast,
--                                 src, 0L, false, kCGRenderingIntentDefault);
-+    CGDataProviderRef src = CGDataProviderCreateWithData( 0L, buffer, w * h * 4, 0L);
-+    CGImageRef img = CGImageCreate(w, h, 8, 4*8, 4*w,
-+                                   lut, kCGImageAlphaLast,
-+                                   src, 0L, false, kCGRenderingIntentDefault);
-     CGColorSpaceRelease(lut);
-     CGDataProviderRelease(src);
--    CGRect rect = { { x, y} , { d.w, d.h } };
--    Fl_X::q_begin_image(rect, 0, 0, d.w, d.h);
-+    CGRect rect = { { x, y }, { w, h } };
-+    Fl_X::q_begin_image(rect, 0, 0, w, h);
-     CGContextDrawImage(fl_gc, rect, img);
-     Fl_X::q_end_image();
-     CGImageRelease(img);
--    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;
--        *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;
--        }
--      }
--
--        if (bit > 1) *bitmap++ = b;
-+    const uchar *p = &buffer[3];
-+    for (int Y = 0; Y < h; Y++) {
-+      int dw = w;
-+      for (int X = 0; X < W; X++) {
-+        uchar b = 0;
-+        for (int bit = 0x01;bit <= 0x80;bit<<=1) {
-+          if (dw-- < 0)
-+            break;
-+          if (*p > 127)
-+            b |= bit;
-+          p += 4;
-+        }
-+        *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 -up fltk-1.3.x-r8772/configh.in.cursor fltk-1.3.x-r8772/configh.in
---- fltk-1.3.x-r8772/configh.in.cursor 2011-06-08 18:23:14.000000000 +0200
-+++ fltk-1.3.x-r8772/configh.in        2011-06-08 18:24:34.373649514 +0200
-@@ -125,6 +125,14 @@
- #define HAVE_XFIXES 0
- /*
-+ * HAVE_XCURSOR:
-+ *
-+ * Do we have the X cursor library?
++ 
++ #define HAVE_XCURSOR 0
++ 
++ /*
+   * __APPLE_QUARTZ__:
+   *
+*** fltk-1.3.0/configure.in    2011-03-06 10:54:58.000000000 -0600
+--- fltk/configure.in  2011-06-22 22:35:32.000000000 -0500
+***************
+*** 875,878 ****
+--- 875,880 ----
+          # MacOS X uses Cocoa for graphics.
+          LIBS="$LIBS -framework Cocoa"
++         # And some Carbon for keyboard handling
++         LIBS="$LIBS -framework Carbon"
+  
+       if test x$have_pthread = xyes; then
+***************
+*** 1007,1010 ****
+--- 1009,1032 ----
+       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)
+*** fltk-1.3.0/documentation/src/enumerations.dox      2011-05-11 10:49:30.000000000 -0500
+--- fltk/documentation/src/enumerations.dox    2011-06-22 22:35:32.000000000 -0500
+***************
+*** 58,61 ****
+--- 58,62 ----
+      data. 
+  \li FL_DND_RELEASE - Dragged data is about to be dropped. 
++ \li FL_FULLSCREEN - The fullscreen state of the window has changed.
+  
+  
+*** fltk-1.3.0/documentation/src/events.dox    2011-05-11 10:49:30.000000000 -0500
+--- fltk/documentation/src/events.dox  2011-06-22 22:35:32.000000000 -0500
+***************
+*** 301,304 ****
+--- 301,311 ----
+  the immediately following \p FL_PASTE event.
+  
++ \subsection events_fl_fullscreen FL_FULLSCREEN
++ 
++ The application window has been changed from normal to fullscreen, or
++ from fullscreen to normal. If you are using a X window manager which
++ supports Extended Window Manager Hints, this event will not be
++ delivered until the change has actually happened. 
++ 
+  
+  \section events_event_xxx Fl::event_*() methods
+*** fltk-1.3.0/src/Fl.cxx      2011-05-23 11:49:02.000000000 -0500
+--- fltk-1.3.0.new/src/Fl.cxx  2011-06-22 22:35:32.000000000 -0500
+***************
+*** 80,83 ****
+--- 80,85 ----
+  #endif // WIN32
+  
++ extern void fl_update_focus(void);
++ 
+  //
+  // Globals...
+***************
+*** 445,448 ****
+--- 447,513 ----
+  
+  ////////////////////////////////////////////////////////////////
++ // 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:
+  
+***************
+*** 881,884 ****
+--- 946,951 ----
+      }
+      e_number = old_event;
++     // let the platform code do what it needs
++     fl_update_focus();
+    }
+  }
+***************
+*** 1362,1366 ****
+  // hide() destroys the X window, it does not do unmap!
+  
+! #if !defined(WIN32) && USE_XFT
+  extern void fl_destroy_xft_draw(Window);
+  #endif
+--- 1429,1436 ----
+  // hide() destroys the X window, it does not do unmap!
+  
+! #if defined(WIN32)
+! extern void fl_clipboard_notify_untarget(HWND wnd);
+! extern void fl_update_clipboard(void);
+! #elif USE_XFT
+  extern void fl_destroy_xft_draw(Window);
+  #endif
+***************
+*** 1409,1420 ****
+    // this little trick keeps the current clipboard alive, even if we are about
+    // to destroy the window that owns the selection.
+!   if (GetClipboardOwner()==ip->xid) {
+!     Fl_Window *w1 = Fl::first_window();
+!     if (w1 && OpenClipboard(fl_xid(w1))) {
+!       EmptyClipboard();
+!       SetClipboardData(CF_TEXT, NULL);
+!       CloseClipboard();
+!     }
+!   }
+    // Send a message to myself so that I'll get out of the event loop...
+    PostMessage(ip->xid, WM_APP, 0, 0);
+--- 1479,1486 ----
+    // this little trick keeps the current clipboard alive, even if we are about
+    // to destroy the window that owns the selection.
+!   if (GetClipboardOwner()==ip->xid)
+!     fl_update_clipboard();
+!   // Make sure we unlink this window from the clipboard chain
+!   fl_clipboard_notify_untarget(ip->xid);
+    // Send a message to myself so that I'll get out of the event loop...
+    PostMessage(ip->xid, WM_APP, 0, 0);
+*** fltk-1.3.0/src/Fl_Image.cxx        2011-04-20 09:01:04.000000000 -0500
+--- fltk-1.3.0.new/src/Fl_Image.cxx    2011-06-22 22:35:32.000000000 -0500
+***************
+*** 173,176 ****
+--- 173,189 ----
+  // RGB image class...
+  //
++ 
++ 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. */
++ 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 free all memory and server resources that are used by  the image. */
+  Fl_RGB_Image::~Fl_RGB_Image() {
+*** fltk-1.3.0/src/Fl_Window.cxx       2011-02-25 02:44:47.000000000 -0600
+--- fltk-1.3.0.new/src/Fl_Window.cxx   2011-06-22 22:35:32.000000000 -0500
+***************
+*** 60,63 ****
+--- 60,67 ----
+    size_range_set = 0;
+    minw = maxw = minh = maxh = 0;
++   no_fullscreen_x = 0;
++   no_fullscreen_y = 0;
++   no_fullscreen_w = w();
++   no_fullscreen_h = h();
+    callback((Fl_Callback*)default_callback);
+  }
+***************
+*** 66,71 ****
+  : Fl_Group(X, Y, W, H, l) {
+    cursor_default = FL_CURSOR_DEFAULT;
+-   cursor_fg      = FL_BLACK;
+-   cursor_bg      = FL_WHITE;
+  
+    _Fl_Window();
+--- 70,73 ----
+***************
+*** 77,82 ****
+    : 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();
+--- 79,82 ----
+*** fltk-1.3.0/src/Fl_Window_fullscreen.cxx    2011-03-12 15:36:21.000000000 -0600
+--- fltk-1.3.0.new/src/Fl_Window_fullscreen.cxx        2011-06-22 22:35:32.000000000 -0500
+***************
+*** 61,97 ****
+  }
+  
+  void Fl_Window::fullscreen() {
+! #ifndef WIN32
+!   //this would clobber the fake wm, since it relies on the border flags to
+!   //determine its thickness
+!   border(0);
+! #endif
+! #if defined(__APPLE__) || defined(WIN32) || defined(USE_X11)
+!   int sx, sy, sw, sh;
+!   Fl::screen_xywh(sx, sy, sw, sh, x(), y(), w(), h());
+!   // if we are on the main screen, we will leave the system menu bar unobstructed
+!   if (Fl::x()>=sx && Fl::y()>=sy && Fl::x()+Fl::w()<=sx+sw && Fl::y()+Fl::h()<=sy+sh) {
+!     sx = Fl::x(); sy = Fl::y(); 
+!     sw = Fl::w(); sh = Fl::h();
+    }
+-   if (x()==sx) x(sx+1); // make sure that we actually execute the resize
+- #if defined(USE_X11)
+-   resize(0, 0, w(), h()); // work around some quirks in X11
+- #endif
+-   resize(sx, sy, sw, sh);
+- #else
+-   if (!x()) x(1); // make sure that we actually execute the resize
+-   resize(0,0,Fl::w(),Fl::h());
+- #endif
+  }
+  
+  void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
+!   // this order produces less blinking on IRIX:
+!   resize(X,Y,W,H);
+! #ifndef WIN32
+!   border(1);
+! #endif
+  }
+  
+  //
+  // End of "$Id: Fl_Window_fullscreen.cxx 8515 2011-03-12 21:36:21Z manolo $".
+--- 61,106 ----
+  }
+  
++ void fullscreen_x(Fl_Window *w);
++ void fullscreen_off_x();
++ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H);
++ 
++ /* Note: The previous implementation toggled border(). With this new
++    implementation this is not necessary. Additionally, if we do that,
++    the application may lose focus when switching out of fullscreen
++    mode with some window managers. Besides, the API does not say that
++    the FLTK border state should be toggled; it only says that the
++    borders should not be *visible*. 
 + */
-+
-+#define HAVE_XCURSOR 0
-+
-+/*
-  * __APPLE_QUARTZ__:
-  *
-  * All Apple implementations are now based on Quartz and Cocoa,
-diff -up fltk-1.3.x-r8772/configure.in.cursor fltk-1.3.x-r8772/configure.in
---- fltk-1.3.x-r8772/configure.in.cursor       2011-06-08 18:23:14.000000000 +0200
-+++ fltk-1.3.x-r8772/configure.in      2011-06-08 18:25:06.681678402 +0200
-@@ -1018,6 +1018,16 @@ case $uname_GUI in
-               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 -up fltk-1.3.x-r8772/FL/Enumerations.H.cursor fltk-1.3.x-r8772/FL/Enumerations.H
---- fltk-1.3.x-r8772/FL/Enumerations.H.cursor  2011-06-08 18:23:14.285141149 +0200
-+++ fltk-1.3.x-r8772/FL/Enumerations.H 2011-06-08 18:23:14.308143306 +0200
-@@ -879,35 +879,36 @@ inline Fl_Color fl_color_cube(int r, int
- /** 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_DEFAULT = 0,    /**< the default cursor, usually an arrow. */
-+  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 -up fltk-1.3.x-r8772/FL/fl_draw.H.cursor fltk-1.3.x-r8772/FL/fl_draw.H
---- fltk-1.3.x-r8772/FL/fl_draw.H.cursor       2011-06-02 10:06:09.000000000 +0200
-+++ fltk-1.3.x-r8772/FL/fl_draw.H      2011-06-08 18:23:14.320144432 +0200
-@@ -757,7 +757,8 @@ FL_EXPORT const char* fl_shortcut_label(
- 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 -up fltk-1.3.x-r8772/FL/Fl_Window.H.cursor fltk-1.3.x-r8772/FL/Fl_Window.H
---- fltk-1.3.x-r8772/FL/Fl_Window.H.cursor     2011-06-08 18:23:14.287141337 +0200
-+++ fltk-1.3.x-r8772/FL/Fl_Window.H    2011-06-08 18:23:50.721557098 +0200
-@@ -37,6 +37,7 @@
- #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
-@@ -72,7 +73,6 @@ class FL_EXPORT Fl_Window : public Fl_Gr
-   int no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h;
-   // cursor stuff
-   Fl_Cursor cursor_default;
--  Fl_Color cursor_fg, cursor_bg;
-   void size_range_();
-   void _Fl_Window(); // constructor innards
-@@ -447,14 +447,17 @@ public:
-     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) { cursor(c); };
-+  void default_cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE) { default_cursor(c); };
-+
-   static void default_callback(Fl_Window*, void* v);
-   
-   /** Returns the window width including any frame added by the window manager.
-diff -up fltk-1.3.x-r8772/FL/mac.H.cursor fltk-1.3.x-r8772/FL/mac.H
---- fltk-1.3.x-r8772/FL/mac.H.cursor   2011-05-12 13:50:43.000000000 +0200
-+++ fltk-1.3.x-r8772/FL/mac.H  2011-06-08 18:23:14.330145367 +0200
-@@ -141,7 +141,8 @@ public:
-   void collapse(void);
-   WindowRef window_ref(void);
-   void set_key_window(void);
--  void set_cursor(Fl_Cursor);
-+  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 -up fltk-1.3.x-r8772/FL/win32.H.cursor fltk-1.3.x-r8772/FL/win32.H
---- fltk-1.3.x-r8772/FL/win32.H.cursor 2011-05-23 20:32:47.000000000 +0200
-+++ fltk-1.3.x-r8772/FL/win32.H        2011-06-08 18:23:14.331145463 +0200
-@@ -92,6 +92,8 @@ public:
-   void flush() {w->flush();}
-   void set_minmax(LPMINMAXINFO minmax);
-   void mapraise();
-+  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 -up fltk-1.3.x-r8772/FL/x.H.cursor fltk-1.3.x-r8772/FL/x.H
---- fltk-1.3.x-r8772/FL/x.H.cursor     2011-05-21 12:05:19.000000000 +0200
-+++ fltk-1.3.x-r8772/FL/x.H    2011-06-08 18:23:14.331145463 +0200
-@@ -163,6 +163,8 @@ public:
-   static Fl_X* i(const Fl_Window* wi) {return wi->i;}
-   void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
-   void sendxjunk();
-+  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 -up fltk-1.3.x-r8772/src/Fl_cocoa.mm.cursor fltk-1.3.x-r8772/src/Fl_cocoa.mm
---- fltk-1.3.x-r8772/src/Fl_cocoa.mm.cursor    2011-06-08 18:23:14.290141618 +0200
-+++ fltk-1.3.x-r8772/src/Fl_cocoa.mm   2011-06-08 18:23:14.334145743 +0200
-@@ -108,7 +108,6 @@ int fl_screen;
- 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
-@@ -1355,8 +1354,6 @@ void fl_open_display() {
-                                         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;
-@@ -1656,6 +1653,7 @@ static void  q_set_window_title(NSWindow
- - (void)drawRect:(NSRect)rect;
- - (BOOL)acceptsFirstResponder;
- - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent;
-+- (void)resetCursorRects;
- - (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
- - (void)mouseUp:(NSEvent *)theEvent;
- - (void)rightMouseUp:(NSEvent *)theEvent;
-@@ -1713,6 +1711,16 @@ static void  q_set_window_title(NSWindow
-   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);
- }
-@@ -2130,7 +2138,7 @@ void Fl_X::make(Fl_Window* w)
-     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);
-@@ -2232,7 +2240,7 @@ void Fl_X::make(Fl_Window* w)
-     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;
-@@ -2838,6 +2846,10 @@ void Fl_X::destroy() {
-     [[(NSWindow *)xid contentView] release];
-     [(NSWindow *)xid close];
-   }
-+  if (cursor) {
-+    [(NSCursor*)cursor release];
-+    cursor = NULL;
-+  }
- }
- void Fl_X::map() {
-@@ -2953,68 +2965,106 @@ static NSImage *CGBitmapContextToNSImage
-   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 -up fltk-1.3.x-r8772/src/fl_cursor.cxx.cursor fltk-1.3.x-r8772/src/fl_cursor.cxx
---- fltk-1.3.x-r8772/src/fl_cursor.cxx.cursor  2010-12-18 23:31:01.000000000 +0100
-+++ fltk-1.3.x-r8772/src/fl_cursor.cxx 2011-06-08 18:23:14.335145836 +0200
-@@ -33,300 +33,155 @@
- #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_Window::fullscreen() {
+!   if (shown() && !(flags() & Fl_Widget::FULLSCREEN)) {
+!     no_fullscreen_x = x();
+!     no_fullscreen_y = y();
+!     no_fullscreen_w = w();
+!     no_fullscreen_h = h();
+!     fullscreen_x(this);
+!   } else {
+!     set_flag(FULLSCREEN);
+    }
+  }
+  
+  void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
+!   if (shown() && (flags() & Fl_Widget::FULLSCREEN)) {
+!     fullscreen_off_x(this, X, Y, W, H);
+!   } else {
+!     clear_flag(FULLSCREEN);
+!   }
+!   no_fullscreen_x = no_fullscreen_y = no_fullscreen_w = no_fullscreen_h = 0;
+! }
+! 
+! void Fl_Window::fullscreen_off() {
+!   if (!no_fullscreen_x && !no_fullscreen_y) {
+!     // Window was initially created fullscreen - default to current monitor
+!     no_fullscreen_x = x();
+!     no_fullscreen_y = y();
+!   }
+!   fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h);
+  }
+  
++ 
+  //
+  // End of "$Id: Fl_Window_fullscreen.cxx 8515 2011-03-12 21:36:21Z manolo $".
+*** fltk-1.3.0/src/Fl_cocoa.mm 2011-06-16 07:35:32.000000000 -0500
+--- fltk-1.3.0.new/src/Fl_cocoa.mm     2011-06-22 22:35:32.000000000 -0500
+***************
+*** 62,65 ****
+--- 62,66 ----
+  
+  #import <Cocoa/Cocoa.h>
++ #import <Carbon/Carbon.h>
+  
+  #ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h
+***************
+*** 108,112 ****
+  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
+--- 109,112 ----
+***************
+*** 125,128 ****
+--- 125,130 ----
+  #endif
+  
++ bool use_simple_keyboard = false;
++ 
+  enum { FLTKTimerEvent = 1, FLTKDataReadyEvent };
+  
+***************
+*** 141,144 ****
+--- 143,179 ----
+  }
+  
++ // Undocumented voodoo. Taken from Mozilla.
++ #define ENABLE_ROMAN_KYBDS_ONLY -23
++ 
++ void fl_update_focus(void)
++ {
++   Fl_Widget *focus;
++ 
++   focus = Fl::grab();
++   if (!focus)
++     focus = Fl::focus();
++   if (!focus)
++     return;
++ 
++   if (focus->simple_keyboard())
++     use_simple_keyboard = true;
++   else
++     use_simple_keyboard = false;
++ 
++   // Force a "Roman" or "ASCII" keyboard, which both the Mozilla and
++   // Safari people seem to think implies turning off advanced IME stuff
++   // (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput
++   // in Safari/Webcore). Should be good enough for us then...
++ #if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
++   CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
++   TSMSetDocumentProperty(TSMGetActiveDocument(),
++                          kTSMDocumentEnabledInputSourcesPropertyTag,
++                          sizeof(CFArrayRef), &inputSources);
++   CFRelease(inputSources);
++ #else
++   KeyScript(use_simple_keyboard ? ENABLE_ROMAN_KYBDS_ONLY : smKeyEnableKybds);
++ #endif  
++ }
++ 
+  /*
+   * Mac keyboard lookup table
+***************
+*** 615,618 ****
+--- 650,657 ----
+    containsGLsubwindow = contains;
+  }
++ - (BOOL)canBecomeKeyWindow
++ {
++   return YES;
++ }
+  @end
+  
+***************
+*** 844,847 ****
+--- 883,905 ----
+  @end
+  
++ static const char* cocoaDead2FLTK(const char *in)
++ {
++   if (strcmp(in, "\140") == 0)      // GRAVE ACCENT
++     return "\314\200";              // COMBINING GRAVE ACCENT
++   if (strcmp(in, "\302\264") == 0)  // ACUTE ACCENT
++     return "\314\201";              // COMBINING ACUTE ACCENT
++   if (strcmp(in, "\136") == 0)      // CIRCUMFLEX ACCENT
++     return "\314\202";              // COMBINING CIRCUMFLEX ACCENT
++   if (strcmp(in, "\176") == 0)      // TILDE
++     return "\314\203";              // COMBINING TILDE
++   if (strcmp(in, "\302\250") == 0)  // DIAERESIS
++     return "\314\210";              // COMBINING DIAERESIS
++   // FIXME: OS X dead key behaviour isn't documented and I don't have
++   //        any more keyboards to test with...
++ 
++   // hope that OS X gave us something proper to begin with
++   return in;
++ }
++ 
+  /*
+  Handle cocoa keyboard events
+***************
+*** 1034,1037 ****
+--- 1092,1099 ----
+    FLWindow *nsw = (FLWindow*)[notif object];
+    Fl_Window *window = [nsw getFl_Window];
++   /* Fullscreen windows obscure all other windows so we need to return
++      to a "normal" level when the user switches to another window */
++   if (window->fullscreen_active())
++     [nsw setLevel:NSNormalWindowLevel];
+    Fl::handle( FL_UNFOCUS, window);
+    fl_unlock_function();
+***************
+*** 1042,1045 ****
+--- 1104,1110 ----
+    FLWindow *nsw = (FLWindow*)[notif object];
+    Fl_Window *w = [nsw getFl_Window];
++   /* Restore previous fullscreen level */
++   if (w->fullscreen_active())
++     [nsw setLevel:NSStatusWindowLevel];
+    if ( w->border() || (!w->modal() && !w->tooltip_window()) ) Fl::handle( FL_FOCUS, w);
+    fl_unlock_function();
+***************
+*** 1229,1235 ****
+--- 1294,1304 ----
+  @end
+  
++ static void clipboard_check(void);
++ 
+  @implementation FLApplication
+  + (void)sendEvent:(NSEvent *)theEvent
+  {
++   // update clipboard status
++   clipboard_check();
+    NSEventType type = [theEvent type];  
+    if (type == NSLeftMouseDown) {
+***************
+*** 1286,1291 ****
+      while (ign_event);
+      
+-     fl_default_cursor = [NSCursor arrowCursor];
+- 
+      // bring the application into foreground without a 'CARB' resource
+      Boolean same_psn;
+--- 1355,1358 ----
+***************
+*** 1587,1590 ****
+--- 1654,1658 ----
+  - (BOOL)acceptsFirstResponder;
+  - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent;
++ - (void)resetCursorRects;
+  - (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
+  - (void)mouseUp:(NSEvent *)theEvent;
+***************
+*** 1644,1647 ****
+--- 1712,1725 ----
+    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);
+***************
+*** 1703,1708 ****
+      }
+    }
+    if (!no_text_key && !(Fl::e_state & FL_META) ) {
+!     // Don't send cmd-<key> to interpretKeyEvents because it beeps.
+      // Then we can let the OS have a stab at it and see if it thinks it
+      // should result in some text
+--- 1781,1791 ----
+      }
+    }
++   // Don't send cmd-<key> to interpretKeyEvents because it beeps.
+    if (!no_text_key && !(Fl::e_state & FL_META) ) {
+!     // The simple keyboard model will ignore insertText, so we need to grab
+!     // the symbol directly from the event. Note that we still use setMarkedText.
+!     if (use_simple_keyboard)
+!       [FLView prepareEtext:[theEvent charactersIgnoringModifiers]];
+! 
+      // Then we can let the OS have a stab at it and see if it thinks it
+      // should result in some text
+***************
+*** 1883,1901 ****
+  
+    if (!in_key_event) fl_lock_function();
+    [FLView prepareEtext:received];
+    // We can get called outside of key events (e.g. from the character
+!   // palette). Transform such actions to FL_PASTE events.
+    if (!in_key_event) {
+      Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+!     Fl::handle(FL_PASTE, target);
+      // for some reason, the window does not redraw until the next mouse move or button push
+      // sending a 'redraw()' or 'awake()' does not solve the issue!
+      Fl::flush();
+    }
+    if (!in_key_event) fl_unlock_function();
+  }
+  
+  - (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection  {
+!   NSString *received;
+    if (newSelection.location == 0) {
+      [self unmarkText];
+--- 1966,1993 ----
+  
+    if (!in_key_event) fl_lock_function();
++ 
++   // Simple keyboard widgets do not want these side channel inputs.
++   if (use_simple_keyboard)
++     goto end;
++ 
+    [FLView prepareEtext:received];
++ 
+    // We can get called outside of key events (e.g. from the character
+!   // palette). We need to fake our own key event at that point.
+    if (!in_key_event) {
+      Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+!     Fl::e_keysym = Fl::e_original_keysym = 0;
+!     Fl::handle(FL_KEYDOWN, target);
+      // for some reason, the window does not redraw until the next mouse move or button push
+      // sending a 'redraw()' or 'awake()' does not solve the issue!
+      Fl::flush();
+    }
++ 
++ end:
+    if (!in_key_event) fl_unlock_function();
+  }
+  
+  - (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection  {
+!   NSString *received, *current, *aggregate;
+    if (newSelection.location == 0) {
+      [self unmarkText];
+***************
+*** 1908,1916 ****
+    }
+    //NSLog(@"setMarkedText: %@ %d %d",received,newSelection.location,newSelection.length);
+    // This code creates the OS X behaviour of seeing dead keys as things
+    // are being composed.
+    next_compose_length = newSelection.location;
+!   [FLView prepareEtext:received];
+!   //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", received, Fl::e_length, next_compose_length);
+  }
+  
+--- 2000,2044 ----
+    }
+    //NSLog(@"setMarkedText: %@ %d %d",received,newSelection.location,newSelection.length);
++ 
++   fl_lock_function();
++ 
++   // Simple keyboard widgets generally do not want these side channel
++   // inputs, but we have no other way of getting dead keys so we make
++   // an exception in that case.
++   if (use_simple_keyboard) {
++     if (in_key_event && (Fl::e_length == 0)) {
++       [FLView prepareEtext:received];
++ 
++       Fl::e_text = (char*)cocoaDead2FLTK(Fl::e_text);
++       Fl::e_length = strlen(Fl::e_text);
++     }
++     goto end;
++   }
++ 
+    // This code creates the OS X behaviour of seeing dead keys as things
+    // are being composed.
++   //
++   // Note: The concatenation thing is because of how OS X deals with
++   //       invalid sequences. At that point it will spit out one call
++   //       to insertText with the now aborted sequence, and one new
++   //       call to setMarkedText with the new sequence. Since we want
++   //       both to be visible, we need to concatenate.
+    next_compose_length = newSelection.location;
+!   current = [NSString stringWithUTF8String:Fl::e_text];
+!   aggregate = [current stringByAppendingString:received];
+! 
+!   [FLView prepareEtext:aggregate];
+!   //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", aggregate, Fl::e_length, next_compose_length);
+! 
+!   // We can get called outside of key events (e.g. from the character
+!   // palette). We need to fake our own key event at that point.
+!   if (!in_key_event) {
+!     Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+!     Fl::e_keysym = Fl::e_original_keysym = 0;
+!     Fl::handle(FL_KEYDOWN, target);
+!   }
+! 
+! end:
+!   fl_unlock_function();
+  }
+  
+***************
+*** 1982,1985 ****
+--- 2110,2129 ----
+  @end
+  
++ void fullscreen_x(Fl_Window *w) {
++   w->_set_fullscreen();
++   /* On OS X < 10.6, it is necessary to recreate the window. This is done
++      with hide+show. */
++   w->hide();
++   w->show();
++   Fl::handle(FL_FULLSCREEN, w);
++ }
++ 
++ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
++   w->_clear_fullscreen();
++   w->hide();
++   w->resize(X, Y, W, H);
++   w->show();
++   Fl::handle(FL_FULLSCREEN, w);
++ }
+  
+  /*
+***************
+*** 1997,2001 ****
+      x->region = 0;
+      x->subRegion = 0;
+!     x->cursor = fl_default_cursor;
+      x->gc = 0;                       // stay 0 for Quickdraw; fill with CGContext for Quartz
+      Fl_Window *win = w->window();
+--- 2141,2145 ----
+      x->region = 0;
+      x->subRegion = 0;
+!     x->cursor = NULL;
+      x->gc = 0;                       // stay 0 for Quickdraw; fill with CGContext for Quartz
+      Fl_Window *win = w->window();
+***************
+*** 2099,2103 ****
+      x->region = 0;
+      x->subRegion = 0;
+!     x->cursor = fl_default_cursor;
+      x->xidChildren = 0;
+      x->xidNext = 0;
+--- 2243,2247 ----
+      x->region = 0;
+      x->subRegion = 0;
+!     x->cursor = NULL;
+      x->xidChildren = 0;
+      x->xidNext = 0;
+***************
+*** 2105,2108 ****
+--- 2249,2259 ----
+         
+      NSRect srect = [[NSScreen mainScreen] frame];
++     if (w->flags() & Fl_Widget::FULLSCREEN) {
++       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);
++       winstyle = NSBorderlessWindowMask;
++       winlevel = NSStatusWindowLevel;
++     }
+      NSRect crect;
+      crect.origin.x = w->x(); 
+***************
+*** 2553,2556 ****
+--- 2704,2728 ----
+  }
+  
++ extern void fl_trigger_clipboard_notify(int source);
++ 
++ void fl_clipboard_notify_change() {
++   // No need to do anything here...
++ }
++ 
++ static void clipboard_check(void)
++ {
++   PasteboardSyncFlags flags;
++ 
++   allocatePasteboard();
++   flags = PasteboardSynchronize(myPasteboard);
++ 
++   if (!(flags & kPasteboardModified))
++     return;
++   if (flags & kPasteboardClientIsOwner)
++     return;
++ 
++   fl_trigger_clipboard_notify(1);
++ }
++ 
+  void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
+  {
+***************
+*** 2677,2680 ****
+--- 2849,2856 ----
+      [(NSWindow *)xid close];
+    }
++   if (cursor) {
++     [(NSCursor*)cursor release];
++     cursor = NULL;
++   }
+  }
+  
+***************
+*** 2792,2857 ****
+  }
+  
+! static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() )
+  {
+!   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];
+    }
+-   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;
+    }
+!   [icrsr set];
+!   cursor = icrsr;
+  }
+  
+--- 2968,3071 ----
+  }
+  
+! int Fl_X::set_cursor(Fl_Cursor c)
+  {
+!   if (cursor) {
+!     [(NSCursor*)cursor release];
+!     cursor = NULL;
+    }
+  
+    switch (c) {
+!   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();
+    }
+! 
+!   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;
+  }
+  
+*** fltk-1.3.0/src/Fl_grab.cxx 2010-12-18 16:31:01.000000000 -0600
+--- fltk-1.3.0.new/src/Fl_grab.cxx     2011-06-22 22:35:32.000000000 -0500
+***************
+*** 39,42 ****
+--- 39,43 ----
+  
+  extern void fl_fix_focus(); // in Fl.cxx
++ void fl_update_focus(void);
+  
+  #ifdef WIN32
+***************
+*** 51,55 ****
+--- 52,68 ----
+  #endif
+  
++ #if !(defined(WIN32) || defined(__APPLE__))
++ extern int ewmh_supported(); // from Fl_x.cxx
++ #endif
++ 
+  void Fl::grab(Fl_Window* win) {
++     Fl_Window *fullscreen_win = NULL;
++     for (Fl_Window *W = Fl::first_window(); W; W = Fl::next_window(W)) {
++       if (W->fullscreen_active()) {
++         fullscreen_win = W;
++         break;
++       }
++     }
++ 
+    if (win) {
+      if (!grab_) {
+***************
+*** 61,66 ****
+        Fl_X::i(first_window())->set_key_window();
+  #else
+        XGrabPointer(fl_display,
+!                 fl_xid(first_window()),
+                  1,
+                  ButtonPressMask|ButtonReleaseMask|
+--- 74,80 ----
+        Fl_X::i(first_window())->set_key_window();
+  #else
++       Window xid = fullscreen_win ? fl_xid(fullscreen_win) : fl_xid(first_window());
+        XGrabPointer(fl_display,
+!                 xid,
+                  1,
+                  ButtonPressMask|ButtonReleaseMask|
+***************
+*** 72,76 ****
+                  fl_event_time);
+        XGrabKeyboard(fl_display,
+!                  fl_xid(first_window()),
+                   1,
+                   GrabModeAsync,
+--- 86,90 ----
+                  fl_event_time);
+        XGrabKeyboard(fl_display,
+!                  xid,
+                   1,
+                   GrabModeAsync,
+***************
+*** 80,83 ****
+--- 94,98 ----
+      }
+      grab_ = win;
++     fl_update_focus();
+    } else {
+      if (grab_) {
+***************
+*** 88,92 ****
+--- 103,110 ----
+        fl_capture = 0;
+  #else
++       // We must keep the grab in the non-EWMH fullscreen case
++       if (!fullscreen_win || ewmh_supported()) {
+        XUngrabKeyboard(fl_display, fl_event_time);
++       }
+        XUngrabPointer(fl_display, fl_event_time);
+        // this flush is done in case the picked menu item goes into
+***************
+*** 95,98 ****
+--- 113,117 ----
+  #endif
+        grab_ = 0;
++       fl_update_focus();
+        fl_fix_focus();
+      }
+*** fltk-1.3.0/src/Fl_win32.cxx        2011-05-30 07:33:51.000000000 -0500
+--- fltk-1.3.0.new/src/Fl_win32.cxx    2011-06-22 22:35:32.000000000 -0500
+***************
+*** 99,102 ****
+--- 99,104 ----
+  Fl_Display_Device *Fl_Display_Device::_display = &fl_gdi_display; // the platform display
+  
++ bool use_simple_keyboard = false;
++ 
+  // dynamic wsock dll handling api:
+  #if defined(__CYGWIN__) && !defined(SOCKET)
+***************
+*** 132,135 ****
+--- 134,139 ----
    */
-+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);
-+}
-+
--  cursor(c, fg, bg);
-+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;
-+  }
-+
-+  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
--
--extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h);
--
--
--CGContextRef Fl_X::help_cursor_image(void)
--{
--  int w = 20, h = 20;
--  Fl_Offscreen off = fl_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_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_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_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_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;
--}
-+/**
-+  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.
--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);
--}
-+  The default cursor will be used if the provided image cannot be used
-+  as a cursor.
--#else
-+  \see cursor(Fl_Cursor), default_cursor()
-+*/
-+void Fl_Window::cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
-+  int ret;
--// I like the MSWindows resize cursors, so I duplicate them here:
-+  // the cursor must be set for the top level window, not for subwindows
-+  Fl_Window *w = window(), *toplevel = this;
--#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
--};
--
--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);
--}
--#endif
-+  if (!i)
-+    return;
-+
-+  ret = i->set_cursor(image, hotx, hoty);
-+  if (ret)
-+    return;
-+
-+  cursor(FL_CURSOR_DEFAULT);
-+}
- //
- // End of "$Id: fl_cursor.cxx 8055 2010-12-18 22:31:01Z manolo $".
-diff -up fltk-1.3.x-r8772/src/fl_cursor_help.xpm.cursor fltk-1.3.x-r8772/src/fl_cursor_help.xpm
---- fltk-1.3.x-r8772/src/fl_cursor_help.xpm.cursor     2011-06-08 18:23:14.336145931 +0200
-+++ fltk-1.3.x-r8772/src/fl_cursor_help.xpm    2011-06-08 18:23:14.336145931 +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 -up fltk-1.3.x-r8772/src/fl_cursor_nesw.xpm.cursor fltk-1.3.x-r8772/src/fl_cursor_nesw.xpm
---- fltk-1.3.x-r8772/src/fl_cursor_nesw.xpm.cursor     2011-06-08 18:23:14.336145931 +0200
-+++ fltk-1.3.x-r8772/src/fl_cursor_nesw.xpm    2011-06-08 18:23:14.336145931 +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 -up fltk-1.3.x-r8772/src/fl_cursor_none.xpm.cursor fltk-1.3.x-r8772/src/fl_cursor_none.xpm
---- fltk-1.3.x-r8772/src/fl_cursor_none.xpm.cursor     2011-06-08 18:23:14.337146025 +0200
-+++ fltk-1.3.x-r8772/src/fl_cursor_none.xpm    2011-06-08 18:23:14.337146025 +0200
-@@ -0,0 +1,19 @@
-+/* XPM */
-+static const char * fl_cursor_none_xpm[] = {
-+"15 15 1 1",
-+"     c None",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               ",
-+"               "};
-diff -up fltk-1.3.x-r8772/src/fl_cursor_nwse.xpm.cursor fltk-1.3.x-r8772/src/fl_cursor_nwse.xpm
---- fltk-1.3.x-r8772/src/fl_cursor_nwse.xpm.cursor     2011-06-08 18:23:14.337146025 +0200
-+++ fltk-1.3.x-r8772/src/fl_cursor_nwse.xpm    2011-06-08 18:23:14.337146025 +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 -up fltk-1.3.x-r8772/src/fl_cursor_wait.xpm.cursor fltk-1.3.x-r8772/src/fl_cursor_wait.xpm
---- fltk-1.3.x-r8772/src/fl_cursor_wait.xpm.cursor     2011-06-08 18:23:14.338146118 +0200
-+++ fltk-1.3.x-r8772/src/fl_cursor_wait.xpm    2011-06-08 18:23:14.338146118 +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 -up fltk-1.3.x-r8772/src/Fl_win32.cxx.cursor fltk-1.3.x-r8772/src/Fl_win32.cxx
---- fltk-1.3.x-r8772/src/Fl_win32.cxx.cursor   2011-06-08 18:23:14.292141805 +0200
-+++ fltk-1.3.x-r8772/src/Fl_win32.cxx  2011-06-08 18:23:14.339146212 +0200
-@@ -1635,7 +1635,6 @@ void fl_fix_focus(); // in Fl.cxx
- 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
-@@ -1683,7 +1682,7 @@ Fl_X* Fl_X::make(Fl_Window* w) {
-     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;
-@@ -1775,7 +1774,7 @@ Fl_X* Fl_X::make(Fl_Window* w) {
-   x->setwindow(w);
-   x->region = 0;
-   x->private_dc = 0;
--  x->cursor = fl_default_cursor;
-+  x->cursor = LoadCursor(NULL, IDC_ARROW);
-   if (!fl_codepage) fl_get_codepage();
-   WCHAR *lab = NULL;
-@@ -2026,6 +2025,129 @@ void Fl_Window::label(const char *name,c
- }
- ////////////////////////////////////////////////////////////////
-+
-+#ifndef IDC_HAND
-+#  define IDC_HAND  MAKEINTRESOURCE(32649)
-+#endif // !IDC_HAND
-+
-+int Fl_X::set_cursor(Fl_Cursor c) {
-+  LPSTR n;
-+
-+  if (c == FL_CURSOR_NONE)
-+    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;
-+    }
-+
-+    cursor = LoadCursor(NULL, n);
-+    if (cursor == NULL)
-+      return 0;
-+  }
-+
-+  SetCursor(cursor);
-+
-+  return 1;
-+}
-+
-+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
-+  BITMAPV5HEADER bi;
-+  HBITMAP bitmap, mask;
-+  DWORD *bits;
-+
-+  if ((hotx < 0) || (hotx >= image->w()))
-+    return 0;
-+  if ((hoty < 0) || (hoty >= image->h()))
-+    return 0;
-+
-+  memset(&bi, 0, sizeof(BITMAPV5HEADER));
-+
-+  bi.bV5Size        = sizeof(BITMAPV5HEADER);
-+  bi.bV5Width       = image->w();
-+  bi.bV5Height      = image->h();
-+  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);
-+
-+  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);
-+
-+  ICONINFO ii;
-+
-+  ii.fIcon    = FALSE;
-+  ii.xHotspot = hotx;
-+  ii.yHotspot = hoty;
-+  ii.hbmMask  = mask;
-+  ii.hbmColor = bitmap;
-+
-+  cursor = CreateIconIndirect(&ii);
-+
-+  DeleteObject(bitmap);
-+  DeleteObject(mask);
-+
-+  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 -up fltk-1.3.x-r8772/src/Fl_Window.cxx.cursor fltk-1.3.x-r8772/src/Fl_Window.cxx
---- fltk-1.3.x-r8772/src/Fl_Window.cxx.cursor  2011-06-08 18:23:14.293141899 +0200
-+++ fltk-1.3.x-r8772/src/Fl_Window.cxx 2011-06-08 18:23:14.340146306 +0200
-@@ -69,8 +69,6 @@ void Fl_Window::_Fl_Window() {
- 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);
-@@ -80,8 +78,6 @@ Fl_Window::Fl_Window(int W, int H, const
- // 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();
-diff -up fltk-1.3.x-r8772/src/Fl_x.cxx.cursor fltk-1.3.x-r8772/src/Fl_x.cxx
---- fltk-1.3.x-r8772/src/Fl_x.cxx.cursor       2011-06-08 18:23:14.296142181 +0200
-+++ fltk-1.3.x-r8772/src/Fl_x.cxx      2011-06-08 18:27:42.302267800 +0200
-@@ -52,6 +52,11 @@
- #  include <X11/Xlocale.h>
- #  include <X11/Xlib.h>
- #  include <X11/keysym.h>
-+#  include <X11/cursorfont.h>
-+
-+#  if HAVE_XCURSOR
-+#    include <X11/Xcursor/Xcursor.h>
-+#  endif
- #  ifdef HAVE_XFIXES
- #  include <X11/extensions/Xfixes.h>
-@@ -2215,6 +2220,94 @@ void Fl_Window::size_range_() {
- ////////////////////////////////////////////////////////////////
-+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) {
-   const char *p,*q;
-diff -up fltk-1.3.x-r8772/test/cursor.cxx.cursor fltk-1.3.x-r8772/test/cursor.cxx
---- fltk-1.3.x-r8772/test/cursor.cxx.cursor    2010-12-08 15:00:35.000000000 +0100
-+++ fltk-1.3.x-r8772/test/cursor.cxx   2011-06-08 18:23:14.343146587 +0200
-@@ -32,8 +32,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;
-@@ -41,7 +39,7 @@ Fl_Hor_Value_Slider *cursor_slider;
- 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[] = {
-@@ -57,8 +55,6 @@ Fl_Menu_Item choices[] = {
-   {"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},
-@@ -67,26 +63,14 @@ Fl_Menu_Item choices[] = {
-   {"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:
-@@ -112,29 +96,11 @@ int main(int argc, char **argv) {
-   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);
+  static HMODULE s_imm_module = 0;
++ typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
++ static flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
+  typedef HIMC (WINAPI* flTypeImmGetContext)(HWND);
+  static flTypeImmGetContext flImmGetContext = 0;
+***************
+*** 147,150 ****
+--- 151,155 ----
+        Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
+          "Please check your input method manager library accessibility.");
++     flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx");
+      flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
+      flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
+***************
+*** 425,429 ****
+        }
+  
+!       TranslateMessage(&fl_msg);
+        DispatchMessageW(&fl_msg);
+        have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
+--- 430,439 ----
+        }
+  
+!       // Don't bother with key to character translation as we do
+!       // it manually for simpley keyboard widgets. In fact, calling
+!       // TranslateMessage() just makes it more difficult as it sets
+!       // a bunch of internal state.
+!       if (!use_simple_keyboard)
+!         TranslateMessage(&fl_msg);
+        DispatchMessageW(&fl_msg);
+        have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
+***************
+*** 543,546 ****
+--- 553,586 ----
+  };
+  
++ void fl_update_clipboard(void) {
++   HWND hwnd = fl_xid(Fl::first_window());
++ 
++   if (!hwnd)
++     return;
++ 
++   if (!OpenClipboard(hwnd))
++     return;
++ 
++   EmptyClipboard();
++ 
++   int utf16_len = fl_utf8toUtf16(fl_selection_buffer[1],
++                                  fl_selection_length[1], 0, 0);
++ 
++   HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
++   LPVOID memLock = GlobalLock(hMem);
++ 
++   fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1],
++                  (unsigned short*) memLock, utf16_len + 1);
++ 
++   GlobalUnlock(hMem);
++   SetClipboardData(CF_UNICODETEXT, hMem);
++ 
++   CloseClipboard();
++ 
++   // In case Windows managed to lob of a WM_DESTROYCLIPBOARD during
++   // the above.
++   fl_i_own_selection[1] = 1;
++ }
++ 
+  // call this when you create a selection:
+  void Fl::copy(const char *stuff, int len, int clipboard) {
+***************
+*** 560,582 ****
+    fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
+    fl_selection_length[clipboard] = len;
+!   if (clipboard) {
+!     // set up for "delayed rendering":
+!     if (OpenClipboard(NULL)) {
+!       // if the system clipboard works, use it
+!       int utf16_len = fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], 0, 0);
+!       EmptyClipboard();
+!       HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
+!       LPVOID memLock = GlobalLock(hMem);
+!       fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], (unsigned short*) memLock, utf16_len + 1);
+!       GlobalUnlock(hMem);
+!       SetClipboardData(CF_UNICODETEXT, hMem);
+!       CloseClipboard();
+!       GlobalFree(hMem);
+!       fl_i_own_selection[clipboard] = 0;
+!     } else {
+!       // only if it fails, instruct paste() to use the internal buffers
+!       fl_i_own_selection[clipboard] = 1;
+!     }
+!   }
+  }
+  
+--- 600,606 ----
+    fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
+    fl_selection_length[clipboard] = len;
+!   fl_i_own_selection[clipboard] = 1;
+!   if (clipboard)
+!     fl_update_clipboard();
+  }
+  
+***************
+*** 631,634 ****
+--- 655,690 ----
+  }
+  
++ static HWND clipboard_wnd = 0;
++ static HWND next_clipboard_wnd = 0;
++ 
++ static bool initial_clipboard = true;
++ 
++ void fl_clipboard_notify_change() {
++   // No need to do anything here...
++ }
++ 
++ void fl_clipboard_notify_target(HWND wnd) {
++   if (clipboard_wnd)
++     return;
++ 
++   // We get one fake WM_DRAWCLIPBOARD immediately, which we therefore
++   // need to ignore.
++   initial_clipboard = true;
++ 
++   clipboard_wnd = wnd;
++   next_clipboard_wnd = SetClipboardViewer(wnd);
++ }
++ 
++ void fl_clipboard_notify_untarget(HWND wnd) {
++   if (wnd != clipboard_wnd)
++     return;
++ 
++   ChangeClipboardChain(wnd, next_clipboard_wnd);
++   clipboard_wnd = next_clipboard_wnd = 0;
++ 
++   if (Fl::first_window())
++     fl_clipboard_notify_target(fl_xid(Fl::first_window()));
++ }
++ 
+  ////////////////////////////////////////////////////////////////
+  char fl_is_ime = 0;
+***************
+*** 650,653 ****
+--- 706,752 ----
+  }
+  
++ void fl_update_focus(void)
++ {
++   Fl_Widget *focus;
++   Fl_Window *win;
++ 
++   get_imm_module();
++ 
++   focus = Fl::grab();
++   if (!focus)
++     focus = Fl::focus();
++   if (!focus)
++     return;
++ 
++   // Grabs are special in that events are sent to the first
++   // available window
++   if (focus == Fl::grab())
++     win = Fl::first_window();
++   else {
++     win = focus->as_window();
++     if (!win)
++       win = focus->window();
++   }
++ 
++   if (!win) {
++     Fl::warning("Cannot find window for widget receiving focus");
++     return;
++   }
++ 
++   // No Win32 window created yet
++   if (!Fl_X::i(win) || !fl_xid(win))
++     return;
++ 
++   if (focus->simple_keyboard()) {
++     use_simple_keyboard = true;
++     if (flImmGetContext(fl_xid(win)) != 0)
++       flImmAssociateContextEx(fl_xid(win), 0, 0);
++   } else {
++     use_simple_keyboard = false;
++     if (flImmGetContext(fl_xid(win)) == 0)
++       flImmAssociateContextEx(fl_xid(win), 0, IACE_DEFAULT);
++   }
++ }
++ 
+  HWND fl_capture;
+  
+***************
+*** 797,800 ****
+--- 896,920 ----
+  }
+  
++ static xchar msdead2fltk(xchar in)
++ {
++   switch (in) {
++   case 0x0060:      // GRAVE ACCENT
++     return 0x0300;  // COMBINING GRAVE ACCENT
++   case 0x00b4:      // ACUTE ACCENT
++     return 0x0301;  // COMBINING ACUTE ACCENT
++   case 0x005e:      // CIRCUMFLEX ACCENT
++     return 0x0302;  // COMBINING CIRCUMFLEX ACCENT
++   case 0x007e:      // TILDE
++     return 0x0303;  // COMBINING TILDE
++   case 0x00a8:      // DIAERESIS
++     return 0x0308;  // COMBINING DIAERESIS
++   // FIXME: Windows dead key behaviour isn't documented and I don't have
++   //        any more keyboards to test with...
++   }
++ 
++   // hope that Windows gave us something proper to begin with
++   return in;
++ }
++ 
+  #if USE_COLORMAP
+  extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx
+***************
+*** 858,861 ****
+--- 978,983 ----
+    //fl_msg.lPrivate = ???
+  
++   MSG fl_orig_msg = fl_msg;
++ 
+    Fl_Window *window = fl_find(hWnd);
+  
+***************
+*** 1037,1057 ****
+      Fl::e_state = state;
+      static char buffer[1024];
+-     if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
+  
+        xchar u = (xchar) wParam;
+  //    Fl::e_length = fl_unicode2utf(&u, 1, buffer);
+        Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
+        buffer[Fl::e_length] = 0;
+  
+! 
+!     } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
+!       if (state & FL_NUM_LOCK) {
+!         // Convert to regular keypress...
+!      buffer[0] = Fl::e_keysym-FL_KP;
+!      Fl::e_length = 1;
+!       } else {
+!         // Convert to special keypress...
+!      buffer[0] = 0;
+!      Fl::e_length = 0;
+       switch (Fl::e_keysym) {
+         case FL_KP + '0' :
+--- 1159,1238 ----
+      Fl::e_state = state;
+      static char buffer[1024];
+  
++     if (use_simple_keyboard) {
++       BYTE keystate[256];
++       WCHAR wbuf[8];
++       int ret;
++ 
++       // I'm not sure if we ever get WM_CHAR (& friends) without an initial
++       // WM_KEYDOWN (& friends), but if we do then we should not send such
++       // side band events to simple keyboard widgets.
++       if ((fl_orig_msg.message != WM_KEYDOWN) &&
++           (fl_orig_msg.message != WM_SYSKEYDOWN) &&
++           (fl_orig_msg.message != WM_KEYUP) &&
++           (fl_orig_msg.message != WM_SYSKEYUP))
++         break;
++ 
++       GetKeyboardState(keystate);
++ 
++       // Pressing Ctrl wreaks havoc with the symbol lookup, so turn that off.
++       // But AltGr shows up as Ctrl+Alt in Windows, so keep Ctrl if Alt is
++       // active.
++       if (!(keystate[VK_MENU] & (1<<31)))
++         keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
++ 
++       // We cannot inspect or modify Windows' internal state of the keyboard
++       // so we have to try to infer information from ToUnicode() and wedge
++       // things into a known state.
++       for (int i = 0;i < 2;i++) {
++         ret = ToUnicode(fl_orig_msg.wParam, 0, keystate, wbuf,
++                         sizeof(wbuf)/sizeof(wbuf[0]), 0);
++ 
++         // No symbol for this key (or unexpected length)
++         if ((ret == 0) || (ret < -1)) {
++           buffer[0] = 0;
++           Fl::e_length = 0;
++           break;
++         }
++ 
++         // A dead key. Convert this to a Unicode combining character so
++         // that the application can tell the difference between dead and
++         // normal keys.
++         if (ret == -1) {
++           xchar u = (xchar) msdead2fltk(wbuf[0]);
++           Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
++           buffer[Fl::e_length] = 0;
++           break;
++         }
++ 
++         // If we have two characters (or more) from ToUnicode(), that's
++         // an invalid sequence. One character chould mean a proper symbol,
++         // or it could mean a composed one. In both cases we need to call
++         // ToUnicode() again to get something sane.
++         if (i == 0)
++           continue;
++ 
++         // We should now have something sane. Give whatever we have to the
++         // application.
++         Fl::e_length = fl_utf8fromwc(buffer, 1024, wbuf, ret);
++         buffer[Fl::e_length] = 0;
++       }
++     } else if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
+        xchar u = (xchar) wParam;
+  //    Fl::e_length = fl_unicode2utf(&u, 1, buffer);
+        Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
+        buffer[Fl::e_length] = 0;
++     } else {
++       buffer[0] = 0;
++       Fl::e_length = 0;
++     }
+  
+!     // The keypad area is a bit odd in that we need to change the keysym
+!     // to properly indicate what the user meant, unlike other keys where
+!     // we normally change the text and keep keysym stable.
+!     if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
+!       // The initial mapping tables give us a keysym that corresponds to
+!       // numlock being on, so we only do something when it is off.
+!       if (!(state & FL_NUM_LOCK)) {
+       switch (Fl::e_keysym) {
+         case FL_KP + '0' :
+***************
+*** 1085,1112 ****
+           Fl::e_keysym = FL_Delete;
+           break;
+-        case FL_KP + '/' :
+-        case FL_KP + '*' :
+-        case FL_KP + '-' :
+-        case FL_KP + '+' :
+-          buffer[0] = Fl::e_keysym-FL_KP;
+-          Fl::e_length = 1;
+-          break;
+       }
+        }
+-     } else if ((lParam & (1<<31))==0) {
+- #ifdef FLTK_PREVIEW_DEAD_KEYS
+-       if ((lParam & (1<<24))==0) { // clear if dead key (always?)
+-         xchar u = (xchar) wParam;
+-         Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
+-         buffer[Fl::e_length] = 0;
+-       } else { // set if "extended key" (never printable?)
+-         buffer[0] = 0;
+-         Fl::e_length = 0;
+-       }
+- #else
+-       buffer[0] = 0;
+-       Fl::e_length = 0;
+- #endif
+      }
+      Fl::e_text = buffer;
+      if (lParam & (1<<31)) { // key up events.
+--- 1266,1273 ----
+           Fl::e_keysym = FL_Delete;
+           break;
+       }
+        }
+      }
++ 
+      Fl::e_text = buffer;
+      if (lParam & (1<<31)) { // key up events.
+***************
+*** 1126,1129 ****
+--- 1287,1291 ----
+      static int delta = 0; // running total of all motion
+      delta += (SHORT)(HIWORD(wParam));
++     Fl::e_dx = 0;
+      Fl::e_dy = -delta / WHEEL_DELTA;
+      delta += Fl::e_dy * WHEEL_DELTA;
+***************
+*** 1132,1135 ****
+--- 1294,1312 ----
+    }
+  
++ // This is only defined on Vista and upwards...
++ #ifndef WM_MOUSEHWHEEL
++ #define WM_MOUSEHWHEEL 0x020E
++ #endif
++ 
++   case WM_MOUSEHWHEEL: {
++     static int delta = 0; // running total of all motion
++     delta += (SHORT)(HIWORD(wParam));
++     Fl::e_dy = 0;
++     Fl::e_dx = delta / WHEEL_DELTA;
++     delta -= Fl::e_dx * WHEEL_DELTA;
++     if (Fl::e_dx) Fl::handle(FL_MOUSEWHEEL, window);
++     return 0;
++   }
++ 
+    case WM_GETMINMAXINFO:
+      Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam);
+***************
+*** 1186,1216 ****
+      return 1;
+  
+!   case WM_RENDERALLFORMATS:
+!     fl_i_own_selection[1] = 0;
+!     // Windoze seems unhappy unless I do these two steps. Documentation
+!     // seems to vary on whether opening the clipboard is necessary or
+!     // is in fact wrong:
+!     CloseClipboard();
+!     OpenClipboard(NULL);
+!     // fall through...
+!   case WM_RENDERFORMAT: {
+!     HANDLE h;
+! 
+! //  int l = fl_utf_nb_char((unsigned char*)fl_selection_buffer[1], fl_selection_length[1]);
+!     int l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], NULL, 0); // Pass NULL buffer to query length required
+!     h = GlobalAlloc(GHND, (l+1) * sizeof(unsigned short));
+!     if (h) {
+!       unsigned short *g = (unsigned short*) GlobalLock(h);
+! //    fl_utf2unicode((unsigned char *)fl_selection_buffer[1], fl_selection_length[1], (xchar*)g);
+!       l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], g, (l+1));
+!       g[l] = 0;
+!       GlobalUnlock(h);
+!       SetClipboardData(CF_UNICODETEXT, h);
+      }
+  
+!     // Windoze also seems unhappy if I don't do this. Documentation very
+!     // unclear on what is correct:
+!     if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard();
+!     return 1;}
+  
+    default:
+--- 1363,1386 ----
+      return 1;
+  
+!   case WM_CHANGECBCHAIN:
+!     if ((hWnd == clipboard_wnd) &&
+!         (next_clipboard_wnd == (HWND)wParam)) {
+!       next_clipboard_wnd = (HWND)lParam;
+!       return 0;
+      }
++     break;
++ 
++   case WM_DRAWCLIPBOARD:
++     // When the clipboard moves between two FLTK windows,
++     // fl_i_own_selection will temporarily be false as we are
++     // processing this message. Hence the need to use fl_find().
++     if (!initial_clipboard && !fl_find(GetClipboardOwner()))
++       fl_trigger_clipboard_notify(1);
++     initial_clipboard = false;
+  
+!     if (next_clipboard_wnd)
+!       SendMessage(next_clipboard_wnd, WM_DRAWCLIPBOARD, wParam, lParam);
+! 
+!     return 0;
+  
+    default:
+***************
+*** 1321,1324 ****
+--- 1491,1499 ----
+    Y+=yoff;
+  
++   if (w->flags() & Fl_Widget::FULLSCREEN) {
++     X = Y = 0;
++     bx = by = bt = 0;
++   }
++ 
+    return ret;
+  }
+***************
+*** 1371,1374 ****
+--- 1546,1601 ----
+  }
+  
++ static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) {
++   int sx, sy, sw, sh;
++   Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H);
++   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);
++ }
++ 
++ void fullscreen_x(Fl_Window *w) {
++   w->_set_fullscreen();
++   make_fullscreen(w, fl_xid(w), w->x(), w->y(), w->w(), w->h());
++   Fl::handle(FL_FULLSCREEN, w);
++ }
++ 
++ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
++   w->_clear_fullscreen();
++   DWORD style = GetWindowLong(fl_xid(w), GWL_STYLE);
++   // Remove the xid temporarily so that Fl_X::fake_X_wm() behaves like it
++   // does in Fl_X::make().
++   HWND xid = fl_xid(w);
++   Fl_X::i(w)->xid = NULL;
++   int x, y, bt, bx, by;
++   switch (Fl_X::fake_X_wm(w, x, y, bt, bx, by)) {
++   case 0: 
++     break;
++   case 1: 
++     style |= WS_CAPTION; 
++     break;
++   case 2: 
++     if (w->border()) {
++       style |= WS_THICKFRAME | WS_CAPTION; 
++     }
++     break;
++   }
++   Fl_X::i(w)->xid = xid;
++   // Adjust for decorations (but not if that puts the decorations
++   // outside the screen)
++   if ((X != w->x()) || (Y != w->y())) {
++     X -= bx;
++     Y -= by+bt;
++   }
++   W += bx*2;
++   H += by*2+bt;
++   SetWindowLong(fl_xid(w), GWL_STYLE, style);
++   SetWindowPos(fl_xid(w), 0, X, Y, W, H,
++                SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
++   Fl::handle(FL_FULLSCREEN, w);
++ }
++ 
++ 
+  ////////////////////////////////////////////////////////////////
+  
+***************
+*** 1409,1413 ****
+  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
+--- 1636,1639 ----
+***************
+*** 1457,1461 ****
+        w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
+      wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
+!     wcw.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
+      //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
+      //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
+--- 1683,1687 ----
+        w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
+      wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
+!     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));
+***************
+*** 1500,1515 ****
+      switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) {
+        // No border (used for menus)
+!       case 0: style |= WS_POPUP;
+!               styleEx |= WS_EX_TOOLWINDOW;
+             break;
+  
+        // Thin border and title bar
+!       case 1: style |= WS_DLGFRAME | WS_CAPTION; break;
+  
+        // Thick, resizable border and title bar, with maximize button
+!       case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break;
+      }
+      if (by+bt) {
+-       if (!w->modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX;
+        wp += 2*bx;
+        hp += 2*by+bt;
+--- 1726,1749 ----
+      switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) {
+        // No border (used for menus)
+!       case 0:
+!         style |= WS_POPUP;
+!         styleEx |= WS_EX_TOOLWINDOW;
+             break;
+  
+        // Thin border and title bar
+!       case 1:
+!         style |= WS_DLGFRAME | WS_CAPTION;
+!         if (!w->modal())
+!           style |= WS_SYSMENU | WS_MINIMIZEBOX;
+!         break;
+  
+        // Thick, resizable border and title bar, with maximize button
+!       case 2:
+!         style |= WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_CAPTION;
+!         if (!w->modal())
+!           style |= WS_MINIMIZEBOX;
+!         break;
+      }
+      if (by+bt) {
+        wp += 2*bx;
+        hp += 2*by+bt;
+***************
+*** 1541,1545 ****
+    x->region = 0;
+    x->private_dc = 0;
+!   x->cursor = fl_default_cursor;
+    if (!fl_codepage) fl_get_codepage();
+  
+--- 1775,1779 ----
+    x->region = 0;
+    x->private_dc = 0;
+!   x->cursor = LoadCursor(NULL, IDC_ARROW);
+    if (!fl_codepage) fl_get_codepage();
+  
+***************
+*** 1567,1573 ****
+--- 1801,1821 ----
+    if (lab) free(lab);
+  
++   if (w->flags() & Fl_Widget::FULLSCREEN) {
++   /* We need to make sure that the fullscreen is created on the
++      default monitor, ie the desktop where the shortcut is located
++      etc. This requires that CreateWindow is called with CW_USEDEFAULT
++      for x and y. We can then use GetWindowRect to determine which
++      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->next = Fl_X::first;
+    Fl_X::first = x;
+  
++   fl_clipboard_notify_target(x->xid);
++ 
+    x->wait_for_expose = 1;
+    if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;}
+***************
+*** 1582,1586 ****
+    // other windows from the code, or we lose the capture.
+    ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
+!           (Fl::grab() || (style & WS_POPUP)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
+  
+    // Register all windows for potential drag'n'drop operations
+--- 1830,1834 ----
+    // other windows from the code, or we lose the capture.
+    ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
+!           (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
+  
+    // Register all windows for potential drag'n'drop operations
+***************
+*** 1778,1781 ****
+--- 2026,2152 ----
+  
+  ////////////////////////////////////////////////////////////////
++ 
++ #ifndef IDC_HAND
++ #  define IDC_HAND  MAKEINTRESOURCE(32649)
++ #endif // !IDC_HAND
++ 
++ int Fl_X::set_cursor(Fl_Cursor c) {
++   LPSTR n;
++ 
++   if (c == FL_CURSOR_NONE)
++     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;
++     }
++ 
++     cursor = LoadCursor(NULL, n);
++     if (cursor == NULL)
++       return 0;
++   }
++ 
++   SetCursor(cursor);
++ 
++   return 1;
++ }
++ 
++ int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
++   BITMAPV5HEADER bi;
++   HBITMAP bitmap, mask;
++   DWORD *bits;
++ 
++   if ((hotx < 0) || (hotx >= image->w()))
++     return 0;
++   if ((hoty < 0) || (hoty >= image->h()))
++     return 0;
++ 
++   memset(&bi, 0, sizeof(BITMAPV5HEADER));
++ 
++   bi.bV5Size        = sizeof(BITMAPV5HEADER);
++   bi.bV5Width       = image->w();
++   bi.bV5Height      = image->h();
++   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);
++ 
++   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);
++ 
++   ICONINFO ii;
++ 
++   ii.fIcon    = FALSE;
++   ii.xHotspot = hotx;
++   ii.yHotspot = hoty;
++   ii.hbmMask  = mask;
++   ii.hbmColor = bitmap;
++ 
++   cursor = CreateIconIndirect(&ii);
++ 
++   DeleteObject(bitmap);
++   DeleteObject(mask);
++ 
++   SetCursor(cursor);
++ 
++   return 1;
++ }
++ 
++ ////////////////////////////////////////////////////////////////
+  // Implement the virtual functions for the base Fl_Window class:
+  
+*** fltk-1.3.0/src/Fl_x.cxx    2011-05-30 11:47:48.000000000 -0500
+--- fltk-1.3.0.new/src/Fl_x.cxx        2011-06-22 22:35:32.000000000 -0500
+***************
+*** 53,56 ****
+--- 53,65 ----
+  #  include <X11/Xlib.h>
+  #  include <X11/keysym.h>
++ #  include <X11/cursorfont.h>
++ 
++ #  if HAVE_XCURSOR
++ #    include <X11/Xcursor/Xcursor.h>
++ #  endif
++ 
++ #  ifdef HAVE_XFIXES
++ #  include <X11/extensions/Xfixes.h>
++ #  endif
+  
+  static Fl_Xlib_Graphics_Driver fl_xlib_driver;
+***************
+*** 301,306 ****
+--- 310,318 ----
+  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;
++ static bool have_xfixes = false;
++ static int xfixes_event_base = 0;
+  
+  static Atom WM_DELETE_WINDOW;
+***************
+*** 309,312 ****
+--- 321,327 ----
+  static Atom TARGETS;
+  static Atom CLIPBOARD;
++ static Atom TIMESTAMP;
++ static Atom PRIMARY_TIMESTAMP;
++ static Atom CLIPBOARD_TIMESTAMP;
+  Atom fl_XdndAware;
+  Atom fl_XdndSelection;
+***************
+*** 329,332 ****
+--- 344,350 ----
+  Atom fl_NET_WM_NAME;                 // utf8 aware window label
+  Atom fl_NET_WM_ICON_NAME;            // utf8 aware window icon name
++ Atom fl_NET_SUPPORTING_WM_CHECK;
++ Atom fl_NET_WM_STATE;
++ Atom fl_NET_WM_STATE_FULLSCREEN;
+  
+  /*
+***************
+*** 582,585 ****
+--- 600,662 ----
+  }
+  
++ 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;
+***************
+*** 605,608 ****
+--- 682,688 ----
+    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);
+***************
+*** 626,629 ****
+--- 706,712 ----
+    fl_NET_WM_NAME        = XInternAtom(d, "_NET_WM_NAME",        0);
+    fl_NET_WM_ICON_NAME   = XInternAtom(d, "_NET_WM_ICON_NAME",   0);
++   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);
+  
+    if (sizeof(Atom) < 4)
+***************
+*** 647,650 ****
+--- 730,741 ----
+    Fl::visual(FL_RGB);
+  #endif
++ 
++ #ifdef HAVE_XFIXES
++   int error_base;
++   if (XFixesQueryExtension(d, &xfixes_event_base, &error_base))
++     have_xfixes = true;
++   else
++     have_xfixes = false;
++ #endif
+  }
+  
+***************
+*** 769,772 ****
+--- 860,888 ----
+  }
+  
++ 
++ /* 
++    Get window property value (32 bit format) 
++    Returns zero on success, -1 on error
++ */
++ static int get_xwinprop(Window wnd, Atom prop, long max_length,
++                         unsigned long *nitems, unsigned long **data) {
++   Atom actual;
++   int format;
++   unsigned long bytes_after;
++   
++   if (Success != XGetWindowProperty(fl_display, wnd, prop, 0, max_length, 
++                                     False, AnyPropertyType, &actual, &format, 
++                                     nitems, &bytes_after, (unsigned char**)data)) {
++     return -1;
++   }
++ 
++   if (actual == None || format != 32) {
++     return -1;
++   }
++ 
++   return 0;
++ }
++ 
++ 
+  ////////////////////////////////////////////////////////////////
+  // Code for copying to clipboard and DnD out of the program:
+***************
+*** 788,791 ****
+--- 904,995 ----
+  
+  ////////////////////////////////////////////////////////////////
++ // 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;
++ 
++   // No polling needed with Xfixes
++   if (have_xfixes)
++     return;
++ 
++   // 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) {
++     // 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) {
++       poll_clipboard_owner();
++ 
++       if (!Fl::has_timeout(clipboard_timeout))
++         Fl::add_timeout(0.5, clipboard_timeout);
++     }
++   }
++ }
++ 
++ ////////////////////////////////////////////////////////////////
+  
+  const XEvent* fl_xevent; // the current x event
+***************
+*** 865,872 ****
+    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))
+    {
+      XIM xim_im;
+--- 1069,1075 ----
+    fl_xevent = &thisevent;
+    Window xid = xevent.xany.window;
+  
+    if (fl_xim_ic && xevent.type == DestroyNotify &&
+!         xid != fl_xim_win && !fl_find(xid))
+    {
+      XIM xim_im;
+***************
+*** 883,929 ****
+    }
+  
+!   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 ( XFilterEvent((XEvent *)&xevent, 0) )
+-       return(1);
+- 
+    switch (xevent.type) {
+  
+--- 1086,1094 ----
+    }
+  
+!   if (fl_xim_ic) {
+!     if (XFilterEvent((XEvent *)&xevent, 0))
+!       return 1;
+    }
+  
+    switch (xevent.type) {
+  
+***************
+*** 937,941 ****
+  
+    case SelectionNotify: {
+-     if (!fl_selection_requestor) return 0;
+      static unsigned char* buffer = 0;
+      if (buffer) {XFree(buffer); buffer = 0;}
+--- 1102,1105 ----
+***************
+*** 953,956 ****
+--- 1117,1133 ----
+                               &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;
+***************
+*** 989,992 ****
+--- 1166,1172 ----
+        convert_crlf(buffer, bytesread);
+      }
++ 
++     if (!fl_selection_requestor) return 0;
++ 
+      Fl::e_text = buffer ? (char*)buffer : (char *)"";
+      Fl::e_length = bytesread;
+***************
+*** 1009,1012 ****
+--- 1189,1193 ----
+      int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
+      fl_i_own_selection[clipboard] = 0;
++     poll_clipboard_owner();
+      return 1;}
+  
+***************
+*** 1221,1224 ****
+--- 1402,1408 ----
+      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;
+  
+***************
+*** 1261,1273 ****
+          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);
+!         }
+        }
+        // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not
+--- 1445,1457 ----
+          len = XLookupString((XKeyEvent*)&(xevent.xkey),
+                               buffer, buffer_len, &keysym, 0/*&compose*/);
+!         // 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
+***************
+*** 1441,1444 ****
+--- 1625,1629 ----
+      Fl::e_keysym = FL_Button + xevent.xbutton.button;
+      set_event_xy();
++     Fl::e_dx = Fl::e_dy = 0;
+      if (xevent.xbutton.button == Button4) {
+        Fl::e_dy = -1; // Up
+***************
+*** 1447,1450 ****
+--- 1632,1641 ----
+        Fl::e_dy = +1; // Down
+        event = FL_MOUSEWHEEL;
++     } else if (xevent.xbutton.button == 6) {
++       Fl::e_dx = -1; // Left
++       event = FL_MOUSEWHEEL;
++     } else if (xevent.xbutton.button == 7) {
++       Fl::e_dx = +1; // Right
++       event = FL_MOUSEWHEEL;
+      } else {
+        Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1));
+***************
+*** 1457,1460 ****
+--- 1648,1676 ----
+      break;
+  
++   case PropertyNotify:
++     if (xevent.xproperty.atom == fl_NET_WM_STATE) {
++       int fullscreen_state = 0;
++       if (xevent.xproperty.state != PropertyDelete) {
++         unsigned long nitems;
++         unsigned long *words = 0;
++         if (0 == get_xwinprop(xid, fl_NET_WM_STATE, 64, &nitems, &words) ) { 
++           for (unsigned long item = 0; item < nitems; item++) {
++             if (words[item] == fl_NET_WM_STATE_FULLSCREEN) {
++               fullscreen_state = 1;
++             }
++           }
++         }
++       }
++       if (window->fullscreen_active() && !fullscreen_state) {
++         window->_clear_fullscreen();
++         event = FL_FULLSCREEN;
++       }
++       if (!window->fullscreen_active() && fullscreen_state) {
++         window->_set_fullscreen();
++         event = FL_FULLSCREEN;
++       }
++     }
++     break;
++ 
+    case MotionNotify:
+      set_event_xy();
+***************
+*** 1557,1560 ****
+--- 1773,1795 ----
+    }
+  
++ #ifdef 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);
+  }
+***************
+*** 1596,1599 ****
+--- 1831,1903 ----
+  ////////////////////////////////////////////////////////////////
+  
++ #define _NET_WM_STATE_REMOVE        0  /* remove/unset property */
++ #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) {
++   XEvent e;
++   e.xany.type = ClientMessage;
++   e.xany.window = wnd;
++   e.xclient.message_type = fl_NET_WM_STATE;
++   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;
++   XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
++              0, SubstructureNotifyMask | SubstructureRedirectMask,
++              &e);
++ }
++ 
++ int ewmh_supported() {
++   static int result = -1;
++ 
++   if (result == -1) {
++     result = 0;
++     unsigned long nitems;
++     unsigned long *words = 0;
++     if (0 == get_xwinprop(XRootWindow(fl_display, fl_screen), fl_NET_SUPPORTING_WM_CHECK, 64,
++                           &nitems, &words) && nitems == 1) {
++       Window child = words[0];
++       if (0 == get_xwinprop(child, fl_NET_SUPPORTING_WM_CHECK, 64,
++                            &nitems, &words) && nitems == 1) {
++         result = (child == words[0]);
++       }
++     }
++   }
++ 
++   return result;
++ }
++ 
++ /* Change an existing window to fullscreen */
++ void fullscreen_x(Fl_Window *w) {
++   if (ewmh_supported()) {
++     send_wm_state_event(fl_xid(w), 1, fl_NET_WM_STATE_FULLSCREEN);
++   } else {
++     w->_set_fullscreen();
++     w->hide();
++     w->show();
++     /* We want to grab the window, not a widget, so we cannot use Fl::grab */
++     XGrabKeyboard(fl_display, fl_xid(w), 1, GrabModeAsync, GrabModeAsync, fl_event_time);
++     Fl::handle(FL_FULLSCREEN, w);
++   }
++ }
++ 
++ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
++   if (ewmh_supported()) {
++     send_wm_state_event(fl_xid(w), 0, fl_NET_WM_STATE_FULLSCREEN);
++   } else {
++     w->_clear_fullscreen();
++     /* The grab will be lost when the window is destroyed */
++     w->hide();
++     w->resize(X,Y,W,H);
++     w->show();
++     Fl::handle(FL_FULLSCREEN, w);
++   }
++ }
++ 
++ ////////////////////////////////////////////////////////////////
++ 
+  // A subclass of Fl_Window may call this to associate an X window it
+  // creates with the Fl_Window:
+***************
+*** 1631,1634 ****
+--- 1935,1939 ----
+  |ButtonPressMask|ButtonReleaseMask
+  |EnterWindowMask|LeaveWindowMask
++ |PropertyChangeMask
+  |PointerMotionMask;
+  
+***************
+*** 1702,1705 ****
+--- 2007,2020 ----
+      if (!win->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;}
+    }
++   // For the non-EWMH fullscreen case, we cannot use the code above,
++   // since we do not want save_under, do not want to turn off the
++   // border, and cannot grab without an existing window. Besides, 
++   // there is no clear_override(). 
++   if (win->flags() & Fl_Widget::FULLSCREEN && !ewmh_supported()) {
++     attr.override_redirect = 1;
++     mask |= CWOverrideRedirect;
++     Fl::screen_xywh(X, Y, W, H, X, Y, W, H);
++   }
++ 
+    if (fl_background_pixel >= 0) {
+      attr.background_pixel = fl_background_pixel;
+***************
+*** 1761,1764 ****
+--- 2076,2085 ----
+      }
+  
++     // If asked for, create fullscreen
++     if (win->flags() & Fl_Widget::FULLSCREEN && ewmh_supported()) {
++       XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
++                        PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
++     }
++ 
+      // Make it receptive to DnD:
+      long version = 4;
+***************
+*** 1790,1793 ****
+--- 2111,2124 ----
+    }
+  
++ #ifdef 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) {
+***************
+*** 1798,1801 ****
+--- 2129,2138 ----
+      win->redraw();
+    }
++ 
++   // non-EWMH fullscreen case, need grab
++   if (win->flags() & Fl_Widget::FULLSCREEN && !ewmh_supported()) {
++     XGrabKeyboard(fl_display, xp->xid, 1, GrabModeAsync, GrabModeAsync, fl_event_time);
++   }
++ 
+  }
+  
+***************
+*** 1884,1887 ****
+--- 2221,2312 ----
+  ////////////////////////////////////////////////////////////////
+  
++ 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) {
+*** fltk-1.3.0/src/fl_cursor.cxx       2010-12-18 16:31:01.000000000 -0600
+--- fltk-1.3.0.new/src/fl_cursor.cxx   2011-06-22 22:35:32.000000000 -0500
+***************
+*** 34,331 ****
+  #include <FL/Fl.H>
+  #include <FL/Fl_Window.H>
+  #include <FL/x.H>
+- #if !defined(WIN32) && !defined(__APPLE__)
+- #  include <X11/cursorfont.h>
+- #endif
+  #include <FL/fl_draw.H>
+  
+  /**
+    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, Fl_Color fg, Fl_Color bg) {
+!   if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg);
+  }
+  /** 
+!     Sets the default window cursor as well as its color.
+  
+!     For back compatibility only.
+  */
+! void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
+! //  if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW;
+! 
+    cursor_default = c;
+!   cursor_fg      = fg;
+!   cursor_bg      = bg;
+  
+!   cursor(c, fg, bg);
+  }
+  
+- #ifdef WIN32
+  
+! #  ifndef IDC_HAND
+! #    define IDC_HAND MAKEINTRESOURCE(32649)
+! #  endif // !IDC_HAND
+  
+- 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);
+    }
+-   SetCursor(i->cursor);
+- }
+  
+! #elif defined(__APPLE__)
+  
+! #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
+! 
+! extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h);
+! 
+! 
+! CGContextRef Fl_X::help_cursor_image(void)
+! {
+!   int w = 20, h = 20;
+!   Fl_Offscreen off = fl_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;
+! }
+  
+! CGContextRef Fl_X::none_cursor_image(void)
+! {
+!   int w = 20, h = 20;
+!   Fl_Offscreen off = fl_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;
+! }
+  
+! CGContextRef Fl_X::watch_cursor_image(void)
+! {
+!   int w, h, r = 5;
+!   w = 2*r+6;
+!   h = 4*r;
+!   Fl_Offscreen off = fl_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;
+! }
+  
+! CGContextRef Fl_X::nesw_cursor_image(void)
+! {
+!   int c = 7, r = 2*c;
+!   int w = r, h = r;
+!   Fl_Offscreen off = fl_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;
+  }
+  
+! CGContextRef Fl_X::nwse_cursor_image(void)
+! {
+!   int c = 7, r = 2*c;
+!   int w = r, h = r;
+!   Fl_Offscreen off = fl_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);
+! }
+  
+! #else
+  
+! // I like the MSWindows resize cursors, so I duplicate them here:
+  
+! #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
+! };
+! 
+! 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;
+    }
+  
+!   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);
+    }
+-   XDefineCursor(fl_display, fl_xid(this), xc);
+-   if (deleteit) XFreeCursor(fl_display, xc);
+- }
+  
+! #endif
+  
+  //
+--- 34,186 ----
+  #include <FL/Fl.H>
+  #include <FL/Fl_Window.H>
++ #include <FL/Fl_Pixmap.H>
++ #include <FL/Fl_RGB_Image.H>
+  #include <FL/x.H>
+  #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) {
+!   fl_cursor(c);
+  }
++ 
++ 
+  /** 
+!     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.
+  
+!     \see cursor(const Fl_RGB_Image*, int, int), default_cursor()
+  */
+! void Fl_Window::default_cursor(Fl_Cursor c) {
+    cursor_default = c;
+!   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;
+!   }
+! 
+!   Fl_Pixmap pxm(xpm);
+!   Fl_RGB_Image image(&pxm);
+! 
+!   w->cursor(&image, hotx, hoty);
+  }
+  
+  
+! void Fl_Window::cursor(Fl_Cursor c) {
+!   int ret;
+  
+    // 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);
+!     return;
+!   }
+  
+!   if (c == FL_CURSOR_DEFAULT)
+!     c = cursor_default;
+  
+!   if (!i)
+!     return;
+  
+!   ret = i->set_cursor(c);
+!   if (ret)
+!     return;
+  
+!   fallback_cursor(this, 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.
+  
+!   The default cursor will be used if the provided image cannot be used
+!   as a cursor.
+  
+!   \see cursor(Fl_Cursor), default_cursor()
+! */
+! void Fl_Window::cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+!   int ret;
+  
+!   // 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(image, hotx, hoty);
+!     return;
+    }
+  
+!   if (!i)
+!     return;
+! 
+!   ret = i->set_cursor(image, hotx, hoty);
+!   if (ret)
+!     return;
+! 
+!   cursor(FL_CURSOR_DEFAULT);
+! }
+  
+  //
+*** fltk-1.3.0/src/fl_draw_pixmap.cxx  2011-02-02 12:39:34.000000000 -0600
+--- fltk-1.3.0.new/src/fl_draw_pixmap.cxx      2011-06-22 22:46:30.000000000 -0500
+***************
+*** 68,164 ****
+  }
+  
+- #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
+  
+--- 68,71 ----
+***************
+*** 210,223 ****
+  #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;
+    const uchar*const* data = (const uchar*const*)(cdata+1);
+    int transparent_index = -1;
+    uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
+  #ifdef WIN32
+    color_count = 0;
+--- 117,134 ----
+  #endif
+  
+! 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;
+    uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
++ 
++   if (!fl_measure_pixmap(cdata, w, h))
++     return 0;
++ 
++   if ((chars_per_pixel < 1) || (chars_per_pixel > 2))
++     return 0;
++ 
++   uchar (*colors)[4] = new uchar [1<<(chars_per_pixel*8)][4];
++ 
+  #ifdef WIN32
+    color_count = 0;
+***************
+*** 225,229 ****
+  #endif
+  
+!   if (ncolors < 0) { // FLTK (non standard) compressed colormap
+      ncolors = -ncolors;
+      const uchar *p = *data++;
+--- 136,141 ----
+  #endif
+  
+!   if (ncolors < 0) {
+!     // FLTK (non standard) compressed colormap
+      ncolors = -ncolors;
+      const uchar *p = *data++;
+***************
+*** 231,241 ****
+      // it not be transparent):
+      if (*p == ' ') {
+!       uchar* c = (uchar*)&d.colors[(int)' '];
+! #ifdef U64
+!       *(U64*)c = 0;
+! #  if WORDS_BIGENDIAN
+!       c += 4;
+! #  endif
+! #endif
+        transparent_index = ' ';
+        Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
+--- 143,147 ----
+      // it not be transparent):
+      if (*p == ' ') {
+!       uchar* c = colors[(int)' '];
+        transparent_index = ' ';
+        Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
+***************
+*** 246,256 ****
+      // 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
+  #ifdef WIN32
+        used_colors[3*color_count] = *p;
+--- 152,156 ----
+      // read all the rest of the colors:
+      for (int i=0; i < ncolors; i++) {
+!       uchar* c = colors[*p++];
+  #ifdef WIN32
+        used_colors[3*color_count] = *p;
+***************
+*** 262,273 ****
+        *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));
+      for (int i=0; i<ncolors; i++) {
+        const uchar *p = *data++;
+--- 162,169 ----
+        *c++ = *p++;
+        *c++ = *p++;
+        *c = 255;
+      }
+!   } else {
+!     // normal XPM colormap with names
+      for (int i=0; i<ncolors; i++) {
+        const uchar *p = *data++;
+***************
+*** 275,334 ****
+        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];
+!       }
+        // 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++;
+        }
+- #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]);
+        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++;
+  #endif
+!      }
+!       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__
+          c[3] = 0;
+! #endif
+!      transparent_index = ind;
+!      transparent_c = c;
+        }
+      }
+    }
+-   d.data = data;
+  #ifdef WIN32
+    if (transparent_c) {
+--- 171,208 ----
+        int ind = *p++;
+        uchar* c;
+!       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++;
+        }
+        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++;
+  #endif
+!       } else {
+          // assume "None" or "#transparent" for any errors
+!         // "bg" should be transparent...
+!         Fl::get_color(bg, c[0], c[1], c[2]);
+          c[3] = 0;
+!         transparent_index = ind;
+!         transparent_c = c;
+        }
+      }
+    }
+  #ifdef WIN32
+    if (transparent_c) {
+***************
+*** 340,425 ****
+    }
+  #endif
+    
+  #ifdef  __APPLE_QUARTZ__
+    if (fl_graphics_driver->class_name() == Fl_Quartz_Graphics_Driver::class_id ) {
+-     bool transparent = (transparent_index>=0);
+-     transparent = true;
+-     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++];
+-      }
+-       }
+-     }
+      CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+!     CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L);
+!     CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w,
+!                                 lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast,
+!                                 src, 0L, false, kCGRenderingIntentDefault);
+      CGColorSpaceRelease(lut);
+      CGDataProviderRelease(src);
+!     CGRect rect = { { x, y} , { d.w, d.h } };
+!     Fl_X::q_begin_image(rect, 0, 0, d.w, d.h);
+      CGContextDrawImage(fl_gc, rect, img);
+      Fl_X::q_end_image();
+      CGImageRelease(img);
+!     delete[] array;
+!     }
+!   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];
+      *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;
+!        *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;
+!        }
+!      }
+! 
+!         if (bit > 1) *bitmap++ = b;
+        }
+      }
+    }
+  
+!   fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
+  #ifdef __APPLE_QUARTZ__
+      }
+  #endif
+  
+!   if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i];
+    return 1;
+  }
+--- 214,300 ----
+    }
+  #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);
++       }
++     }
++   }
+    
++   delete [] colors;
++   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 = new uchar[w*h*4];
++ 
++   if (!fl_convert_pixmap(cdata, buffer, bg)) {
++     delete buffer;
++     return 0;
++   }
++ 
++   // FIXME: Hack until fl_draw_image() supports alpha properly
+  #ifdef  __APPLE_QUARTZ__
+    if (fl_graphics_driver->class_name() == Fl_Quartz_Graphics_Driver::class_id ) {
+      CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+!     CGDataProviderRef src = CGDataProviderCreateWithData( 0L, buffer, w * h * 4, 0L);
+!     CGImageRef img = CGImageCreate(w, h, 8, 4*8, 4*w,
+!                                    lut, kCGImageAlphaLast,
+!                                    src, 0L, false, kCGRenderingIntentDefault);
+      CGColorSpaceRelease(lut);
+      CGDataProviderRelease(src);
+!     CGRect rect = { { x, y }, { w, h } };
+!     Fl_X::q_begin_image(rect, 0, 0, w, h);
+      CGContextDrawImage(fl_gc, rect, img);
+      Fl_X::q_end_image();
+      CGImageRelease(img);
+!   } else {
+  #endif // __APPLE_QUARTZ__
+    // build the mask bitmap used by Fl_Pixmap:
+!   if (fl_mask_bitmap) {
+!     int W = (w+7)/8;
+!     uchar* bitmap = new uchar[W * h];
+      *fl_mask_bitmap = bitmap;
+!     const uchar *p = &buffer[3];
+!     for (int Y = 0; Y < h; Y++) {
+!       int dw = w;
+!       for (int X = 0; X < W; X++) {
+!         uchar b = 0;
+!         for (int bit = 0x01;bit <= 0x80;bit<<=1) {
+!           if (dw-- < 0)
+!             break;
+!           if (*p > 127)
+!             b |= bit;
+!           p += 4;
+!         }
+!         *bitmap++ = b;
+        }
+      }
+    }
+  
+!   fl_draw_image(buffer, x, y, w, h, 4);
+! 
+  #ifdef __APPLE_QUARTZ__
+      }
+  #endif
+  
+!   delete buffer;
+    return 1;
+  }
+*** fltk-1.3.0/src/xutf8/imKStoUCS.c   2009-03-13 17:43:43.000000000 -0500
+--- fltk-1.3.0.new/src/xutf8/imKStoUCS.c       2011-06-22 22:35:31.000000000 -0500
+***************
+*** 267,270 ****
+--- 267,276 ----
+  };
+  
++ 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)
+***************
+*** 316,319 ****
+--- 322,327 ----
+      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;
+*** fltk-1.3.0/test/cursor.cxx 2010-12-08 08:00:35.000000000 -0600
+--- fltk-1.3.0.new/test/cursor.cxx     2011-06-22 22:35:32.000000000 -0500
+***************
+*** 33,38 ****
+  #include <FL/Fl_Box.H>
+  
+- Fl_Color fg = FL_BLACK;
+- Fl_Color bg = FL_WHITE;
+  Fl_Cursor cursor = FL_CURSOR_DEFAULT;
+  
+--- 33,36 ----
+***************
+*** 42,46 ****
+    cursor = (Fl_Cursor)(fl_intptr_t)v;
+    cursor_slider->value(cursor);
+!   fl_cursor(cursor,fg,bg);
+  }
+  
+--- 40,44 ----
+    cursor = (Fl_Cursor)(fl_intptr_t)v;
+    cursor_slider->value(cursor);
+!   fl_cursor(cursor);
+  }
+  
+***************
+*** 58,63 ****
+    {"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},
+--- 56,59 ----
+***************
+*** 68,72 ****
+    {"FL_CURSOR_W",0,choice_cb,(void*)FL_CURSOR_W},
+    {"FL_CURSOR_NW",0,choice_cb,(void*)FL_CURSOR_NW},
+! #endif
+    {0}
+  };
+--- 64,68 ----
+    {"FL_CURSOR_W",0,choice_cb,(void*)FL_CURSOR_W},
+    {"FL_CURSOR_NW",0,choice_cb,(void*)FL_CURSOR_NW},
+!   {"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
+    {0}
+  };
+***************
+*** 75,91 ****
+    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);
+  }
+  
+--- 71,75 ----
+    Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
+    cursor = Fl_Cursor((int)slider->value());
+!   fl_cursor(cursor);
+  }
+  
+***************
+*** 113,139 ****
+    slider1.step(1);
+    slider1.precision(0);
+!   slider1.bounds(0,100);
+    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...
+--- 97,105 ----
+    slider1.step(1);
+    slider1.precision(0);
+!   slider1.bounds(0,255);
+    slider1.value(0);
+    slider1.callback(setcursor);
+    slider1.value(cursor);
+  
+  #if 0
+    // draw the manual's diagram of cursors...
+*** fltk-1.3.0/test/fullscreen.cxx     2010-12-15 06:11:16.000000000 -0600
+--- fltk-1.3.0.new/test/fullscreen.cxx 2011-06-22 22:35:32.000000000 -0500
+***************
+*** 61,66 ****
+--- 61,69 ----
+  #include <FL/Fl_Single_Window.H>
+  #include <FL/Fl_Hor_Slider.H>
++ #include <FL/Fl_Input.H>
++ #include <FL/Fl_Menu_Button.H>
+  #include <FL/Fl_Toggle_Light_Button.H>
+  #include <FL/math.h>
++ #include <FL/fl_ask.H>
+  #include <stdio.h>
+  
+***************
+*** 125,128 ****
+--- 128,153 ----
+  #endif
+  
++ class fullscreen_window : public Fl_Single_Window {
++ 
++   public:
++   fullscreen_window(int W, int H, const char *t=0);
++   int handle (int e);
++   Fl_Toggle_Light_Button *b3;
++ 
++ };
++ 
++ fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Window(W, H, t) { 
++ 
++ }
++ 
++ int fullscreen_window::handle(int e) {
++   if (e == FL_FULLSCREEN) {
++     printf("Recieved FL_FULLSCREEN event\n");
++     b3->value(fullscreen_active());
++   }
++   if (Fl_Single_Window::handle(e)) return 1;
++   return 0;
++ }
++ 
+  void sides_cb(Fl_Widget *o, void *p) {
+    shape_window *sw = (shape_window *)p;
+***************
+*** 162,172 ****
+      pw = w->w();
+      ph = w->h();
+- #ifndef WIN32//necessary because fullscreen removes border
+-      border_button->value(0);
+-      border_button->do_callback();
+- #endif
+      w->fullscreen();
+    } else {
+!     w->fullscreen_off(px,py,pw,ph);
+    }
+  }
+--- 187,198 ----
+      pw = w->w();
+      ph = w->h();
+      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();
+    }
+  }
+***************
+*** 178,182 ****
+  }
+  
+! #define NUMB 5
+  
+  int twowindow = 0;
+--- 204,208 ----
+  }
+  
+! #define NUMB 6
+  
+  int twowindow = 0;
+***************
+*** 194,198 ****
+      Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
+  
+!   Fl_Single_Window window(300,300+30*NUMB); window.end();
+  
+    shape_window sw(10,10,window.w()-20,window.h()-30*NUMB-20);
+--- 220,224 ----
+      Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
+  
+!   fullscreen_window window(300,300+30*NUMB); window.end();
+  
+    shape_window sw(10,10,window.w()-20,window.h()-30*NUMB-20);
+***************
+*** 229,232 ****
+--- 255,261 ----
+    y+=30;
+  
++   Fl_Input i1(50,y,window.w()-60,30, "Input");
++   y+=30;
++ 
+    Fl_Toggle_Light_Button b2(50,y,window.w()-60,30,"Border");
+    b2.callback(border_cb,w);
+***************
+*** 235,240 ****
+    y+=30;
+  
+!   Fl_Toggle_Light_Button b3(50,y,window.w()-60,30,"FullScreen");
+!   b3.callback(fullscreen_cb,w);
+    y+=30;
+  
+--- 264,269 ----
+    y+=30;
+  
+!   window.b3 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"FullScreen");
+!   window.b3->callback(fullscreen_cb,w);
+    y+=30;
+  
+***************
+*** 243,247 ****
+    y+=30;
+  
+!   if (initfull) {b3.set(); b3.do_callback();}
+  
+    window.end();
+--- 272,276 ----
+    y+=30;
+  
+!   if (initfull) {window.b3->set(); window.b3->do_callback();}
+  
+    window.end();
diff --git a/fltk/fltk-1.3.x-r8772.tar.bz2 b/fltk/fltk-1.3.x-r8772.tar.bz2
deleted file mode 100644 (file)
index 66c3f03..0000000
Binary files a/fltk/fltk-1.3.x-r8772.tar.bz2 and /dev/null differ