Rex Dieter 23b064
diff -ur fltk-1.3.2.org/FL/Fl_Window.H fltk-1.3.2/FL/Fl_Window.H
Rex Dieter 23b064
--- fltk-1.3.2.org/FL/Fl_Window.H	2013-01-16 10:49:40.904228200 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/FL/Fl_Window.H	2013-01-16 10:49:55.554353925 +0100
Adam Tkac 5e945f
@@ -22,6 +22,10 @@
Adam Tkac 5e945f
 #ifndef Fl_Window_H
Adam Tkac 5e945f
 #define Fl_Window_H
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+#ifdef WIN32
Adam Tkac 5e945f
+#include <windows.h>
Adam Tkac 5e945f
+#endif
Adam Tkac 5e945f
+
Adam Tkac 5e945f
 #include "Fl_Group.H"
Adam Tkac 5e945f
 
Adam Tkac 5e945f
 #define FL_WINDOW 0xF0		///< window type id all subclasses have type() >= this
Adam Tkac 5e945f
@@ -73,9 +77,19 @@
Adam Tkac 5e945f
   friend class Fl_X;
Adam Tkac 5e945f
   Fl_X *i; // points at the system-specific stuff
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+  struct icon_data {
Adam Tkac 5e945f
+    const void *legacy_icon;
Adam Tkac 5e945f
+    Fl_RGB_Image **icons;
Adam Tkac 5e945f
+    int count;
Adam Tkac 5e945f
+#ifdef WIN32
Adam Tkac 5e945f
+    HICON big_icon;
Adam Tkac 5e945f
+    HICON small_icon;
Adam Tkac 5e945f
+#endif
Adam Tkac 5e945f
+  };
Adam Tkac 5e945f
+
Adam Tkac 5e945f
   const char* iconlabel_;
Adam Tkac 5e945f
   char* xclass_;
Adam Tkac 5e945f
-  const void* icon_;
Adam Tkac 5e945f
+  struct icon_data *icon_;
Adam Tkac 5e945f
   // size_range stuff:
Adam Tkac 5e945f
   int minw, minh, maxw, maxh;
Adam Tkac 5e945f
   int dw, dh, aspect;
Adam Tkac 5e945f
@@ -121,6 +135,8 @@
Adam Tkac 5e945f
   */
Adam Tkac 5e945f
   int force_position() const { return ((flags() & FORCE_POSITION)?1:0); }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+  void free_icons();
Adam Tkac 5e945f
+
Adam Tkac 5e945f
 public:
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   /**
Rex Dieter 23b064
@@ -350,6 +366,18 @@
Adam Tkac 5e945f
   static const char *default_xclass();
Adam Tkac 5e945f
   const char* xclass() const;
Adam Tkac 5e945f
   void xclass(const char* c);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  static void default_icon(const Fl_RGB_Image*);
Adam Tkac 5e945f
+  static void default_icons(const Fl_RGB_Image*[], int);
Adam Tkac 5e945f
+  void icon(const Fl_RGB_Image*);
Adam Tkac 5e945f
+  void icons(const Fl_RGB_Image*[], int);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+#ifdef WIN32
Adam Tkac 5e945f
+  static void default_icons(HICON big_icon, HICON small_icon);
Adam Tkac 5e945f
+  void icons(HICON big_icon, HICON small_icon);
Adam Tkac 5e945f
+#endif
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  /* for legacy compatibility */
Adam Tkac 5e945f
   const void* icon() const;
Adam Tkac 5e945f
   void icon(const void * ic);
Adam Tkac 5e945f
 
Rex Dieter 23b064
diff -ur fltk-1.3.2.org/FL/mac.H fltk-1.3.2/FL/mac.H
Rex Dieter 23b064
--- fltk-1.3.2.org/FL/mac.H	2013-01-16 10:49:40.904228200 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/FL/mac.H	2013-01-16 10:49:55.554353925 +0100
Adam Tkac 5e945f
@@ -120,6 +120,9 @@
Adam Tkac 5e945f
   void collapse(void);
Adam Tkac 5e945f
   WindowRef window_ref(void);
Adam Tkac 5e945f
   void set_key_window(void);
Adam Tkac 5e945f
+  // OS X doesn't have per window icons
Adam Tkac 5e945f
+  static void set_default_icons(const Fl_RGB_Image*[], int) {};
Adam Tkac 5e945f
+  void set_icons() {};
Adam Tkac 5e945f
   int set_cursor(Fl_Cursor);
Adam Tkac 5e945f
   int set_cursor(const Fl_RGB_Image*, int, int);
Adam Tkac 5e945f
   static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
Rex Dieter 23b064
diff -ur fltk-1.3.2.org/FL/win32.H fltk-1.3.2/FL/win32.H
Rex Dieter 23b064
--- fltk-1.3.2.org/FL/win32.H	2013-01-16 10:49:40.904228200 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/FL/win32.H	2013-01-16 10:49:55.555355617 +0100
Adam Tkac 5e945f
@@ -84,6 +84,9 @@
Adam Tkac 5e945f
   void flush() {w->flush();}
Adam Tkac 5e945f
   void set_minmax(LPMINMAXINFO minmax);
Adam Tkac 5e945f
   void mapraise();
Adam Tkac 5e945f
+  static void set_default_icons(const Fl_RGB_Image*[], int);
Adam Tkac 5e945f
+  static void set_default_icons(HICON, HICON);
Adam Tkac 5e945f
+  void set_icons();
Adam Tkac 5e945f
   int set_cursor(Fl_Cursor);
Adam Tkac 5e945f
   int set_cursor(const Fl_RGB_Image*, int, int);
Adam Tkac 5e945f
   static Fl_X* make(Fl_Window*);
Rex Dieter 23b064
diff -ur fltk-1.3.2.org/FL/x.H fltk-1.3.2/FL/x.H
Rex Dieter 23b064
--- fltk-1.3.2.org/FL/x.H	2013-01-16 10:49:40.904228200 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/FL/x.H	2013-01-16 10:49:55.555355617 +0100
Adam Tkac 5e945f
@@ -154,6 +154,8 @@
Adam Tkac 5e945f
   static Fl_X* i(const Fl_Window* wi) {return wi->i;}
Adam Tkac 5e945f
   void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
Adam Tkac 5e945f
   void sendxjunk();
Adam Tkac 5e945f
+  static void set_default_icons(const Fl_RGB_Image*[], int);
Adam Tkac 5e945f
+  void set_icons();
Adam Tkac 5e945f
   int set_cursor(Fl_Cursor);
Adam Tkac 5e945f
   int set_cursor(const Fl_RGB_Image*, int, int);
Adam Tkac 5e945f
   static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap);
Rex Dieter 23b064
diff -ur fltk-1.3.2.org/src/Fl.cxx fltk-1.3.2/src/Fl.cxx
Rex Dieter 23b064
--- fltk-1.3.2.org/src/Fl.cxx	2013-01-16 10:49:40.895228113 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/src/Fl.cxx	2013-01-16 10:49:55.556137979 +0100
Adam Tkac 5e945f
@@ -1530,6 +1530,8 @@
Adam Tkac 5e945f
   if (xclass_) {
Adam Tkac 5e945f
     free(xclass_);
Adam Tkac 5e945f
   }
Adam Tkac 5e945f
+  free_icons();
Adam Tkac 5e945f
+  delete icon_;
Adam Tkac 5e945f
 }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
 // FL_SHOW and FL_HIDE are called whenever the visibility of this widget
Rex Dieter 23b064
diff -ur fltk-1.3.2.org/src/Fl_win32.cxx fltk-1.3.2/src/Fl_win32.cxx
Rex Dieter 23b064
--- fltk-1.3.2.org/src/Fl_win32.cxx	2013-01-16 10:49:40.911227539 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/src/Fl_win32.cxx	2013-01-16 10:49:55.556137979 +0100
Adam Tkac 5e945f
@@ -1804,6 +1804,8 @@
Adam Tkac 5e945f
   );
Adam Tkac 5e945f
   if (lab) free(lab);
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+  x->set_icons();
Adam Tkac 5e945f
+
Adam Tkac 5e945f
   if (w->fullscreen_active()) {
Adam Tkac 5e945f
   /* We need to make sure that the fullscreen is created on the
Adam Tkac 5e945f
      default monitor, ie the desktop where the shortcut is located
Adam Tkac 5e945f
@@ -2034,71 +2036,19 @@
Adam Tkac 5e945f
 
Adam Tkac 5e945f
 ////////////////////////////////////////////////////////////////
Adam Tkac 5e945f
 
Adam Tkac 5e945f
-#ifndef IDC_HAND
Adam Tkac 5e945f
-#  define IDC_HAND  MAKEINTRESOURCE(32649)
Adam Tkac 5e945f
-#endif // !IDC_HAND
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-int Fl_X::set_cursor(Fl_Cursor c) {
Adam Tkac 5e945f
-  LPSTR n;
Adam Tkac 5e945f
-  HCURSOR new_cursor;
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-  if (c == FL_CURSOR_NONE)
Adam Tkac 5e945f
-    new_cursor = NULL;
Adam Tkac 5e945f
-  else {
Adam Tkac 5e945f
-    switch (c) {
Adam Tkac 5e945f
-    case FL_CURSOR_ARROW:   n = IDC_ARROW; break;
Adam Tkac 5e945f
-    case FL_CURSOR_CROSS:   n = IDC_CROSS; break;
Adam Tkac 5e945f
-    case FL_CURSOR_WAIT:    n = IDC_WAIT; break;
Adam Tkac 5e945f
-    case FL_CURSOR_INSERT:  n = IDC_IBEAM; break;
Adam Tkac 5e945f
-    case FL_CURSOR_HAND:    n = IDC_HAND; break;
Adam Tkac 5e945f
-    case FL_CURSOR_HELP:    n = IDC_HELP; break;
Adam Tkac 5e945f
-    case FL_CURSOR_MOVE:    n = IDC_SIZEALL; break;
Adam Tkac 5e945f
-    case FL_CURSOR_N:
Adam Tkac 5e945f
-    case FL_CURSOR_S:
Adam Tkac 5e945f
-      // FIXME: Should probably have fallbacks for these instead
Adam Tkac 5e945f
-    case FL_CURSOR_NS:      n = IDC_SIZENS; break;
Adam Tkac 5e945f
-    case FL_CURSOR_NE:
Adam Tkac 5e945f
-    case FL_CURSOR_SW:
Adam Tkac 5e945f
-      // FIXME: Dito.
Adam Tkac 5e945f
-    case FL_CURSOR_NESW:    n = IDC_SIZENESW; break;
Adam Tkac 5e945f
-    case FL_CURSOR_E:
Adam Tkac 5e945f
-    case FL_CURSOR_W:
Adam Tkac 5e945f
-      // FIXME: Dito.
Adam Tkac 5e945f
-    case FL_CURSOR_WE:      n = IDC_SIZEWE; break;
Adam Tkac 5e945f
-    case FL_CURSOR_SE:
Adam Tkac 5e945f
-    case FL_CURSOR_NW:
Adam Tkac 5e945f
-      // FIXME: Dito.
Adam Tkac 5e945f
-    case FL_CURSOR_NWSE:    n = IDC_SIZENWSE; break;
Adam Tkac 5e945f
-    default:
Adam Tkac 5e945f
-      return 0;
Adam Tkac 5e945f
-    }
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-    new_cursor = LoadCursor(NULL, n);
Adam Tkac 5e945f
-    if (new_cursor == NULL)
Adam Tkac 5e945f
-      return 0;
Adam Tkac 5e945f
-  }
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-  if ((cursor != NULL) && custom_cursor)
Adam Tkac 5e945f
-    DestroyIcon(cursor);
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-  cursor = new_cursor;
Adam Tkac 5e945f
-  custom_cursor = 0;
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-  SetCursor(cursor);
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-  return 1;
Adam Tkac 5e945f
-}
Adam Tkac 5e945f
-
Adam Tkac 5e945f
-int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
Adam Tkac 5e945f
+static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon=true,
Adam Tkac 5e945f
+                           int hotx = 0, int hoty = 0) {
Adam Tkac 5e945f
   BITMAPV5HEADER bi;
Adam Tkac 5e945f
   HBITMAP bitmap, mask;
Adam Tkac 5e945f
   DWORD *bits;
Adam Tkac 5e945f
-  HCURSOR new_cursor;
Adam Tkac 5e945f
+  HICON icon;
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+  if (!is_icon) {
Adam Tkac 5e945f
   if ((hotx < 0) || (hotx >= image->w()))
Adam Tkac 5e945f
-    return 0;
Adam Tkac 5e945f
+      return NULL;
Adam Tkac 5e945f
   if ((hoty < 0) || (hoty >= image->h()))
Adam Tkac 5e945f
-    return 0;
Adam Tkac 5e945f
+      return NULL;
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   memset(&bi, 0, sizeof(BITMAPV5HEADER));
Adam Tkac 5e945f
 
Adam Tkac 5e945f
@@ -2120,7 +2070,7 @@
Adam Tkac 5e945f
   ReleaseDC(NULL, hdc);
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   if (bits == NULL)
Adam Tkac 5e945f
-    return 0;
Adam Tkac 5e945f
+    return NULL;
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   const uchar *i = (const uchar*)*image->data();
Adam Tkac 5e945f
   for (int y = 0;y < image->h();y++) {
Adam Tkac 5e945f
@@ -2149,22 +2099,206 @@
Adam Tkac 5e945f
   mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
Adam Tkac 5e945f
   if (mask == NULL) {
Adam Tkac 5e945f
     DeleteObject(bitmap);
Adam Tkac 5e945f
-    return 0;
Adam Tkac 5e945f
+    return NULL;
Adam Tkac 5e945f
   }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   ICONINFO ii;
Adam Tkac 5e945f
 
Adam Tkac 5e945f
-  ii.fIcon    = FALSE;
Adam Tkac 5e945f
+  ii.fIcon    = is_icon;
Adam Tkac 5e945f
   ii.xHotspot = hotx;
Adam Tkac 5e945f
   ii.yHotspot = hoty;
Adam Tkac 5e945f
   ii.hbmMask  = mask;
Adam Tkac 5e945f
   ii.hbmColor = bitmap;
Adam Tkac 5e945f
 
Adam Tkac 5e945f
-  new_cursor = CreateIconIndirect(&ii);
Adam Tkac 5e945f
+  icon = CreateIconIndirect(&ii);
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   DeleteObject(bitmap);
Adam Tkac 5e945f
   DeleteObject(mask);
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+  if (icon == NULL)
Adam Tkac 5e945f
+    return NULL;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  return icon;
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+////////////////////////////////////////////////////////////////
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+static HICON default_big_icon = NULL;
Adam Tkac 5e945f
+static HICON default_small_icon = NULL;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+const Fl_RGB_Image *find_best_icon(int ideal_width, 
Adam Tkac 5e945f
+                                   const Fl_RGB_Image *icons[], int count) {
Adam Tkac 5e945f
+  const Fl_RGB_Image *best;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  best = NULL;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  for (int i = 0;i < count;i++) {
Adam Tkac 5e945f
+    if (best == NULL)
Adam Tkac 5e945f
+      best = icons[i];
Adam Tkac 5e945f
+    else {
Adam Tkac 5e945f
+      if (best->w() < ideal_width) {
Adam Tkac 5e945f
+        if (icons[i]->w() > best->w())
Adam Tkac 5e945f
+          best = icons[i];
Adam Tkac 5e945f
+      } else {
Adam Tkac 5e945f
+        if ((icons[i]->w() >= ideal_width) &&
Adam Tkac 5e945f
+            (icons[i]->w() < best->w()))
Adam Tkac 5e945f
+          best = icons[i];
Adam Tkac 5e945f
+      }
Adam Tkac 5e945f
+    }
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  return best;
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
Adam Tkac 5e945f
+  const Fl_RGB_Image *best_big, *best_small;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (default_big_icon != NULL)
Adam Tkac 5e945f
+    DestroyIcon(default_big_icon);
Adam Tkac 5e945f
+  if (default_small_icon != NULL)
Adam Tkac 5e945f
+    DestroyIcon(default_small_icon);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  best_big = find_best_icon(GetSystemMetrics(SM_CXICON), icons, count);
Adam Tkac 5e945f
+  best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), icons, count);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (best_big != NULL)
Adam Tkac 5e945f
+    default_big_icon = image_to_icon(best_big);
Adam Tkac 5e945f
+  else
Adam Tkac 5e945f
+    default_big_icon = NULL;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (best_small != NULL)
Adam Tkac 5e945f
+    default_small_icon = image_to_icon(best_small);
Adam Tkac 5e945f
+  else
Adam Tkac 5e945f
+    default_small_icon = NULL;
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_X::set_default_icons(HICON big_icon, HICON small_icon) {
Adam Tkac 5e945f
+  if (default_big_icon != NULL)
Adam Tkac 5e945f
+    DestroyIcon(default_big_icon);
Adam Tkac 5e945f
+  if (default_small_icon != NULL)
Adam Tkac 5e945f
+    DestroyIcon(default_small_icon);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (big_icon != NULL)
Adam Tkac 5e945f
+    default_big_icon = CopyIcon(big_icon);
Adam Tkac 5e945f
+  if (small_icon != NULL)
Adam Tkac 5e945f
+    default_small_icon = CopyIcon(small_icon);
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_X::set_icons() {
Adam Tkac 5e945f
+  HICON big_icon, small_icon;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  big_icon = NULL;
Adam Tkac 5e945f
+  small_icon = NULL;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (w->icon_->count) {
Adam Tkac 5e945f
+    const Fl_RGB_Image *best_big, *best_small;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+    best_big = find_best_icon(GetSystemMetrics(SM_CXICON),
Adam Tkac 5e945f
+                              (const Fl_RGB_Image **)w->icon_->icons,
Adam Tkac 5e945f
+                              w->icon_->count);
Adam Tkac 5e945f
+    best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON),
Adam Tkac 5e945f
+                                (const Fl_RGB_Image **)w->icon_->icons,
Adam Tkac 5e945f
+                                w->icon_->count);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+    if (best_big != NULL)
Adam Tkac 5e945f
+      big_icon = image_to_icon(best_big);
Adam Tkac 5e945f
+    if (best_small != NULL)
Adam Tkac 5e945f
+      small_icon = image_to_icon(best_small);
Adam Tkac 5e945f
+  } else {
Adam Tkac 5e945f
+    big_icon = default_big_icon;
Adam Tkac 5e945f
+    small_icon = default_small_icon;
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (big_icon != NULL)
Adam Tkac 5e945f
+    SendMessage(xid, WM_SETICON, ICON_BIG, (LPARAM)big_icon);
Adam Tkac 5e945f
+  if (small_icon != NULL)
Adam Tkac 5e945f
+    SendMessage(xid, WM_SETICON, ICON_SMALL, (LPARAM)small_icon);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (w->icon_->count) {
Adam Tkac 5e945f
+    if (big_icon != NULL)
Adam Tkac 5e945f
+      DestroyIcon(big_icon);
Adam Tkac 5e945f
+    if (small_icon != NULL)
Adam Tkac 5e945f
+      DestroyIcon(small_icon);
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_Window::default_icons(HICON big_icon, HICON small_icon) {
Adam Tkac 5e945f
+  Fl_X::set_default_icons(big_icon, small_icon);
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_Window::icons(HICON big_icon, HICON small_icon) {
Adam Tkac 5e945f
+  free_icons();
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (big_icon != NULL)
Adam Tkac 5e945f
+    icon_->big_icon = CopyIcon(big_icon);
Adam Tkac 5e945f
+  if (small_icon != NULL)
Adam Tkac 5e945f
+    icon_->small_icon = CopyIcon(small_icon);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (i)
Adam Tkac 5e945f
+    i->set_icons();
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+////////////////////////////////////////////////////////////////
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+#ifndef IDC_HAND
Adam Tkac 5e945f
+#  define IDC_HAND  MAKEINTRESOURCE(32649)
Adam Tkac 5e945f
+#endif // !IDC_HAND
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+int Fl_X::set_cursor(Fl_Cursor c) {
Adam Tkac 5e945f
+  LPSTR n;
Adam Tkac 5e945f
+  HCURSOR new_cursor;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (c == FL_CURSOR_NONE)
Adam Tkac 5e945f
+    new_cursor = NULL;
Adam Tkac 5e945f
+  else {
Adam Tkac 5e945f
+    switch (c) {
Adam Tkac 5e945f
+    case FL_CURSOR_ARROW:   n = IDC_ARROW; break;
Adam Tkac 5e945f
+    case FL_CURSOR_CROSS:   n = IDC_CROSS; break;
Adam Tkac 5e945f
+    case FL_CURSOR_WAIT:    n = IDC_WAIT; break;
Adam Tkac 5e945f
+    case FL_CURSOR_INSERT:  n = IDC_IBEAM; break;
Adam Tkac 5e945f
+    case FL_CURSOR_HAND:    n = IDC_HAND; break;
Adam Tkac 5e945f
+    case FL_CURSOR_HELP:    n = IDC_HELP; break;
Adam Tkac 5e945f
+    case FL_CURSOR_MOVE:    n = IDC_SIZEALL; break;
Adam Tkac 5e945f
+    case FL_CURSOR_N:
Adam Tkac 5e945f
+    case FL_CURSOR_S:
Adam Tkac 5e945f
+      // FIXME: Should probably have fallbacks for these instead
Adam Tkac 5e945f
+    case FL_CURSOR_NS:      n = IDC_SIZENS; break;
Adam Tkac 5e945f
+    case FL_CURSOR_NE:
Adam Tkac 5e945f
+    case FL_CURSOR_SW:
Adam Tkac 5e945f
+      // FIXME: Dito.
Adam Tkac 5e945f
+    case FL_CURSOR_NESW:    n = IDC_SIZENESW; break;
Adam Tkac 5e945f
+    case FL_CURSOR_E:
Adam Tkac 5e945f
+    case FL_CURSOR_W:
Adam Tkac 5e945f
+      // FIXME: Dito.
Adam Tkac 5e945f
+    case FL_CURSOR_WE:      n = IDC_SIZEWE; break;
Adam Tkac 5e945f
+    case FL_CURSOR_SE:
Adam Tkac 5e945f
+    case FL_CURSOR_NW:
Adam Tkac 5e945f
+      // FIXME: Dito.
Adam Tkac 5e945f
+    case FL_CURSOR_NWSE:    n = IDC_SIZENWSE; break;
Adam Tkac 5e945f
+    default:
Adam Tkac 5e945f
+      return 0;
Adam Tkac 5e945f
+    }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+    new_cursor = LoadCursor(NULL, n);
Adam Tkac 5e945f
+    if (new_cursor == NULL)
Adam Tkac 5e945f
+      return 0;
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if ((cursor != NULL) && custom_cursor)
Adam Tkac 5e945f
+    DestroyIcon(cursor);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  cursor = new_cursor;
Adam Tkac 5e945f
+  custom_cursor = 0;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  SetCursor(cursor);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  return 1;
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
Adam Tkac 5e945f
+  HCURSOR new_cursor;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  new_cursor = image_to_icon(image, false, hotx, hoty);
Adam Tkac 5e945f
   if (new_cursor == NULL)
Adam Tkac 5e945f
     return 0;
Adam Tkac 5e945f
 
Rex Dieter 23b064
diff -ur fltk-1.3.2.org/src/Fl_Window.cxx fltk-1.3.2/src/Fl_Window.cxx
Rex Dieter 23b064
--- fltk-1.3.2.org/src/Fl_Window.cxx	2013-01-16 10:49:40.908130903 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/src/Fl_Window.cxx	2013-01-16 10:49:55.557353865 +0100
Adam Tkac 5e945f
@@ -23,6 +23,7 @@
Adam Tkac 5e945f
 #include <config.h>
Adam Tkac 5e945f
 #include <fl fl.h="">
Adam Tkac 5e945f
 #include <fl x.h="">
Adam Tkac 5e945f
+#include <fl fl_rgb_image.h="">
Adam Tkac 5e945f
 #include <fl fl_window.h="">
Adam Tkac 5e945f
 #include <stdlib.h>
Adam Tkac 5e945f
 #include "flstring.h"
Adam Tkac 5e945f
@@ -45,7 +46,8 @@
Adam Tkac 5e945f
   }
Adam Tkac 5e945f
   i = 0;
Adam Tkac 5e945f
   xclass_ = 0;
Adam Tkac 5e945f
-  icon_ = 0;
Adam Tkac 5e945f
+  icon_ = new icon_data;
Adam Tkac 5e945f
+  memset(icon_, 0, sizeof(*icon_));
Adam Tkac 5e945f
   iconlabel_ = 0;
Adam Tkac 5e945f
   resizable(0);
Adam Tkac 5e945f
   size_range_set = 0;
Adam Tkac 5e945f
@@ -264,16 +266,68 @@
Adam Tkac 5e945f
   }
Adam Tkac 5e945f
 }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+void Fl_Window::default_icon(const Fl_RGB_Image *icon) {
Adam Tkac 5e945f
+  default_icons(&icon, 1);
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_Window::default_icons(const Fl_RGB_Image **icons, int count) {
Adam Tkac 5e945f
+  Fl_X::set_default_icons(icons, count);
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_Window::icon(const Fl_RGB_Image *icon) {
Adam Tkac 5e945f
+  icons(&icon, 1);
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_Window::icons(const Fl_RGB_Image **icons, int count) {
Adam Tkac 5e945f
+  free_icons();
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (count > 0) {
Adam Tkac 5e945f
+    icon_->icons = new Fl_RGB_Image*[count];
Adam Tkac 5e945f
+    icon_->count = count;
Adam Tkac 5e945f
+    // FIXME: Fl_RGB_Image lacks const modifiers on methods
Adam Tkac 5e945f
+    for (int i = 0;i < count;i++)
Adam Tkac 5e945f
+      icon_->icons[i] = (Fl_RGB_Image*)((Fl_RGB_Image*)icons[i])->copy();
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (i)
Adam Tkac 5e945f
+    i->set_icons();
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
 /** Gets the current icon window target dependent data. */
Adam Tkac 5e945f
 const void *Fl_Window::icon() const {
Adam Tkac 5e945f
-  return icon_;
Adam Tkac 5e945f
+  return icon_->legacy_icon;
Adam Tkac 5e945f
 }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
 /** Sets the current icon window target dependent data. */
Adam Tkac 5e945f
 void Fl_Window::icon(const void * ic) {
Adam Tkac 5e945f
-  icon_ = ic;
Adam Tkac 5e945f
+  free_icons();
Adam Tkac 5e945f
+  icon_->legacy_icon = ic;
Adam Tkac 5e945f
 }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+void Fl_Window::free_icons() {
Adam Tkac 5e945f
+  int i;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  icon_->legacy_icon = 0L;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (icon_->icons) {
Adam Tkac 5e945f
+    for (i = 0;i < icon_->count;i++)
Adam Tkac 5e945f
+      delete icon_->icons[i];
Adam Tkac 5e945f
+    delete [] icon_->icons;
Adam Tkac 5e945f
+    icon_->icons = 0L;
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  icon_->count = 0;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+#ifdef WIN32
Adam Tkac 5e945f
+  if (icon_->big_icon)
Adam Tkac 5e945f
+    DestroyIcon(icon_->big_icon);
Adam Tkac 5e945f
+  if (icon_->small_icon)
Adam Tkac 5e945f
+    DestroyIcon(icon_->small_icon);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  icon_->big_icon = NULL;
Adam Tkac 5e945f
+  icon_->small_icon = NULL;
Adam Tkac 5e945f
+#endif
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
 
Adam Tkac 5e945f
 //
Rex Dieter 23b064
 // End of "$Id: Fl_Window.cxx 9706 2012-11-06 20:46:14Z matt $".
Rex Dieter 23b064
diff -ur fltk-1.3.2.org/src/Fl_x.cxx fltk-1.3.2/src/Fl_x.cxx
Rex Dieter 23b064
--- fltk-1.3.2.org/src/Fl_x.cxx	2013-01-16 10:49:40.912227213 +0100
Rex Dieter 23b064
+++ fltk-1.3.2/src/Fl_x.cxx	2013-01-16 10:49:55.558137113 +0100
Rex Dieter 23b064
@@ -345,6 +345,7 @@
Adam Tkac 5e945f
 Atom fl_NET_WM_STATE;
Adam Tkac 5e945f
 Atom fl_NET_WM_STATE_FULLSCREEN;
Adam Tkac 5e945f
 Atom fl_NET_WORKAREA;
Adam Tkac 5e945f
+Atom fl_NET_WM_ICON;
Adam Tkac 5e945f
 
Adam Tkac 5e945f
 /*
Adam Tkac 5e945f
   X defines 32-bit-entities to have a format value of max. 32,
Rex Dieter 23b064
@@ -709,6 +710,7 @@
Adam Tkac 5e945f
   fl_NET_WM_STATE       = XInternAtom(d, "_NET_WM_STATE",       0);
Adam Tkac 5e945f
   fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
Adam Tkac 5e945f
   fl_NET_WORKAREA       = XInternAtom(d, "_NET_WORKAREA",       0);
Adam Tkac 5e945f
+  fl_NET_WM_ICON        = XInternAtom(d, "_NET_WM_ICON",        0);
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   if (sizeof(Atom) < 4)
Adam Tkac 5e945f
     atom_bits = sizeof(Atom) * 8;
Rex Dieter 23b064
@@ -2138,12 +2140,14 @@
Adam Tkac 5e945f
       fl_show_iconic = 0;
Adam Tkac 5e945f
       showit = 0;
Adam Tkac 5e945f
     }
Adam Tkac 5e945f
-    if (win->icon()) {
Adam Tkac 5e945f
-      hints->icon_pixmap = (Pixmap)win->icon();
Adam Tkac 5e945f
+    if (win->icon_->legacy_icon) {
Adam Tkac 5e945f
+      hints->icon_pixmap = (Pixmap)win->icon_->legacy_icon;
Adam Tkac 5e945f
       hints->flags       |= IconPixmapHint;
Adam Tkac 5e945f
     }
Adam Tkac 5e945f
     XSetWMHints(fl_display, xp->xid, hints);
Adam Tkac 5e945f
     XFree(hints);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+    xp->set_icons();
Adam Tkac 5e945f
   }
Adam Tkac 5e945f
 
Adam Tkac 5e945f
   // set the window type for menu and tooltip windows to avoid animations (compiz)
Rex Dieter 23b064
@@ -2263,6 +2267,93 @@
Adam Tkac 5e945f
 
Adam Tkac 5e945f
 ////////////////////////////////////////////////////////////////
Adam Tkac 5e945f
 
Adam Tkac 5e945f
+static unsigned long *default_net_wm_icons = 0L;
Adam Tkac 5e945f
+static size_t default_net_wm_icons_size = 0;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void icons_to_property(const Fl_RGB_Image *icons[], int count,
Adam Tkac 5e945f
+                       unsigned long **property, size_t *len) {
Adam Tkac 5e945f
+  size_t sz;
Adam Tkac 5e945f
+  unsigned long *data;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  sz = 0;
Adam Tkac 5e945f
+  for (int i = 0;i < count;i++)
Adam Tkac 5e945f
+    sz += 2 + icons[i]->w() * icons[i]->h();
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  // FIXME: Might want to sort the icons
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  *property = data = new unsigned long[sz];
Adam Tkac 5e945f
+  *len = sz;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  for (int i = 0;i < count;i++) {
Adam Tkac 5e945f
+    const Fl_RGB_Image *image;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+    image = icons[i];
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+    data[0] = image->w();
Adam Tkac 5e945f
+    data[1] = image->h();
Adam Tkac 5e945f
+    data += 2;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+    const uchar *in = (const uchar*)*image->data();
Adam Tkac 5e945f
+    for (int y = 0;y < image->h();y++) {
Adam Tkac 5e945f
+      for (int x = 0;x < image->w();x++) {
Adam Tkac 5e945f
+        switch (image->d()) {
Adam Tkac 5e945f
+        case 1:
Adam Tkac 5e945f
+          *data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
Adam Tkac 5e945f
+          break;
Adam Tkac 5e945f
+        case 2:
Adam Tkac 5e945f
+          *data = (in[1]<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
Adam Tkac 5e945f
+          break;
Adam Tkac 5e945f
+        case 3:
Adam Tkac 5e945f
+          *data = ( 0xff<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
Adam Tkac 5e945f
+          break;
Adam Tkac 5e945f
+        case 4:
Adam Tkac 5e945f
+          *data = (in[3]<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
Adam Tkac 5e945f
+          break;
Adam Tkac 5e945f
+        }
Adam Tkac 5e945f
+        in += image->d();
Adam Tkac 5e945f
+        data++;
Adam Tkac 5e945f
+      }
Adam Tkac 5e945f
+      in += image->ld();
Adam Tkac 5e945f
+    }
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
Adam Tkac 5e945f
+  if (default_net_wm_icons) {
Adam Tkac 5e945f
+    delete [] default_net_wm_icons;
Adam Tkac 5e945f
+    default_net_wm_icons = 0L;
Adam Tkac 5e945f
+    default_net_wm_icons_size = 0;
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (count > 0)
Adam Tkac 5e945f
+    icons_to_property(icons, count,
Adam Tkac 5e945f
+                      &default_net_wm_icons, &default_net_wm_icons_size);
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+void Fl_X::set_icons() {
Adam Tkac 5e945f
+  unsigned long *net_wm_icons;
Adam Tkac 5e945f
+  size_t net_wm_icons_size;
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (w->icon_->count) {
Adam Tkac 5e945f
+    icons_to_property((const Fl_RGB_Image **)w->icon_->icons, w->icon_->count,
Adam Tkac 5e945f
+                      &net_wm_icons, &net_wm_icons_size);
Adam Tkac 5e945f
+  } else {
Adam Tkac 5e945f
+    net_wm_icons = default_net_wm_icons;
Adam Tkac 5e945f
+    net_wm_icons_size = default_net_wm_icons_size;
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  XChangeProperty (fl_display, xid, fl_NET_WM_ICON, XA_CARDINAL, 32,
Adam Tkac 5e945f
+      PropModeReplace, (unsigned char*) net_wm_icons, net_wm_icons_size);
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+  if (w->icon_->count) {
Adam Tkac 5e945f
+    delete [] net_wm_icons;
Adam Tkac 5e945f
+    net_wm_icons = 0L;
Adam Tkac 5e945f
+    net_wm_icons_size = 0;
Adam Tkac 5e945f
+  }
Adam Tkac 5e945f
+}
Adam Tkac 5e945f
+
Adam Tkac 5e945f
+////////////////////////////////////////////////////////////////
Adam Tkac 5e945f
+
Adam Tkac 5e945f
 int Fl_X::set_cursor(Fl_Cursor c) {
Adam Tkac 5e945f
   unsigned int shape;
Adam Tkac 5e945f
   Cursor xc;