Include a stripped-down version of FLTK in tree and add a USE_INCLUDED_FLTK option to build against it.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4603 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/fltk/src/Fl_File_Icon.cxx b/common/fltk/src/Fl_File_Icon.cxx
new file mode 100644
index 0000000..98069dd
--- /dev/null
+++ b/common/fltk/src/Fl_File_Icon.cxx
@@ -0,0 +1,492 @@
+//
+// "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $"
+//
+// Fl_File_Icon routines.
+//
+// KDE icon code donated by Maarten De Boer.
+//
+// Copyright 1999-2010 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_File_Icon::Fl_File_Icon()       - Create a new file icon.
+//   Fl_File_Icon::~Fl_File_Icon()      - Remove a file icon.
+//   Fl_File_Icon::add()               - Add data to an icon.
+//   Fl_File_Icon::find()              - Find an icon based upon a given file.
+//   Fl_File_Icon::draw()              - Draw an icon.
+//   Fl_File_Icon::label()             - Set the widgets label to an icon.
+//   Fl_File_Icon::labeltype()         - Draw the icon label.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <FL/fl_utf8.h>
+#include "flstring.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
+#  include <io.h>
+#  define F_OK	0
+#else
+#  include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+#include <FL/Fl_File_Icon.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <FL/filename.H>
+
+
+//
+// Define missing POSIX/XPG4 macros as needed...
+//
+
+#ifndef S_ISDIR
+#  define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#  define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#  define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#  define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#endif /* !S_ISDIR */
+
+
+//
+// Icon cache...
+//
+
+Fl_File_Icon	*Fl_File_Icon::first_ = (Fl_File_Icon *)0;
+
+
+/**
+  Creates a new Fl_File_Icon with the specified information.
+  \param[in] p filename pattern
+  \param[in] t file type
+  \param[in] nd number of data values
+  \param[in] d data values
+*/
+Fl_File_Icon::Fl_File_Icon(const char *p,	/* I - Filename pattern */
+                	   int        t,	/* I - File type */
+			   int        nd,	/* I - Number of data values */
+			   short      *d)	/* I - Data values */
+{
+  // Initialize the pattern and type...
+  pattern_ = p;
+  type_    = t;
+
+  // Copy icon data as needed...
+  if (nd)
+  {
+    num_data_   = nd;
+    alloc_data_ = nd + 1;
+    data_       = (short *)calloc(sizeof(short), nd + 1);
+    memcpy(data_, d, nd * sizeof(short));
+  }
+  else
+  {
+    num_data_   = 0;
+    alloc_data_ = 0;
+  }
+
+  // And add the icon to the list of icons...
+  next_  = first_;
+  first_ = this;
+}
+
+
+/**
+  The destructor destroys the icon and frees all memory that has been
+  allocated for it.
+*/
+Fl_File_Icon::~Fl_File_Icon() {
+  Fl_File_Icon	*current,	// Current icon in list
+		*prev;		// Previous icon in list
+
+
+  // Find the icon in the list...
+  for (current = first_, prev = (Fl_File_Icon *)0;
+       current != this && current != (Fl_File_Icon *)0;
+       prev = current, current = current->next_);
+
+  // Remove the icon from the list as needed...
+  if (current)
+  {
+    if (prev)
+      prev->next_ = current->next_;
+    else
+      first_ = current->next_;
+  }
+
+  // Free any memory used...
+  if (alloc_data_)
+    free(data_);
+}
+
+
+/**
+  Adds a keyword value to the icon array, returning a pointer to it.
+  \param[in] d data value
+*/
+short *				// O - Pointer to new data value
+Fl_File_Icon::add(short d)	// I - Data to add
+{
+  short	*dptr;			// Pointer to new data value
+
+
+  // Allocate/reallocate memory as needed
+  if ((num_data_ + 1) >= alloc_data_)
+  {
+    alloc_data_ += 128;
+
+    if (alloc_data_ == 128)
+      dptr = (short *)malloc(sizeof(short) * alloc_data_);
+    else
+      dptr = (short *)realloc(data_, sizeof(short) * alloc_data_);
+
+    if (dptr == NULL)
+      return (NULL);
+
+    data_ = dptr;
+  }
+
+  // Store the new data value and return
+  data_[num_data_++] = d;
+  data_[num_data_]   = END;
+
+  return (data_ + num_data_ - 1);
+}
+
+
+/**
+  Finds an icon that matches the given filename and file type.
+  \param[in] filename name of file
+  \param[in] filetype enumerated file type
+  \return matching file icon or NULL
+*/
+Fl_File_Icon *				// O - Matching file icon or NULL
+Fl_File_Icon::find(const char *filename,// I - Name of file */
+                   int        filetype)	// I - Enumerated file type
+{
+  Fl_File_Icon	*current;		// Current file in list
+#ifndef WIN32
+  struct stat	fileinfo;		// Information on file
+#endif // !WIN32
+  const char	*name;			// Base name of filename
+
+
+  // Get file information if needed...
+  if (filetype == ANY)
+  {
+#ifdef WIN32
+    if (filename[strlen(filename) - 1] == '/')
+      filetype = DIRECTORY;
+    else if (fl_filename_isdir(filename))
+      filetype = DIRECTORY;
+    else
+      filetype = PLAIN;
+#else
+    if (!fl_stat(filename, &fileinfo))
+    {
+      if (S_ISDIR(fileinfo.st_mode))
+        filetype = DIRECTORY;
+#  ifdef S_IFIFO
+      else if (S_ISFIFO(fileinfo.st_mode))
+        filetype = FIFO;
+#  endif // S_IFIFO
+#  if defined(S_ICHR) && defined(S_IBLK)
+      else if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode))
+        filetype = DEVICE;
+#  endif // S_ICHR && S_IBLK
+#  ifdef S_ILNK
+      else if (S_ISLNK(fileinfo.st_mode))
+        filetype = LINK;
+#  endif // S_ILNK
+      else
+        filetype = PLAIN;
+    }
+    else
+      filetype = PLAIN;
+#endif // WIN32
+  }
+
+  // Look at the base name in the filename
+  name = fl_filename_name(filename);
+
+  // Loop through the available file types and return any match that
+  // is found...
+  for (current = first_; current != (Fl_File_Icon *)0; current = current->next_)
+    if ((current->type_ == filetype || current->type_ == ANY) &&
+        (fl_filename_match(filename, current->pattern_) ||
+	 fl_filename_match(name, current->pattern_)))
+      break;
+
+  // Return the match (if any)...
+  return (current);
+}
+
+/**
+  Draws an icon in the indicated area.
+  \param[in] x, y, w, h position and size
+  \param[in] ic icon color
+  \param[in] active status, default is active [non-zero]
+*/
+void
+Fl_File_Icon::draw(int      x,		// I - Upper-lefthand X
+        	   int      y,		// I - Upper-lefthand Y
+		   int      w,		// I - Width of bounding box
+		   int      h,		// I - Height of bounding box
+        	   Fl_Color ic,		// I - Icon color...
+        	   int      active)	// I - Active or inactive?
+{
+  Fl_Color	c,		// Current color
+		oc;		// Outline color
+  short		*d,		// Pointer to data
+		*dend;		// End of data...
+  short		*prim;		// Pointer to start of primitive...
+  double	scale;		// Scale of icon
+
+
+  // Don't try to draw a NULL array!
+  if (num_data_ == 0)
+    return;
+
+  // Setup the transform matrix as needed...
+  scale = w < h ? w : h;
+
+  fl_push_matrix();
+  fl_translate((float)x + 0.5 * ((float)w - scale),
+               (float)y + 0.5 * ((float)h + scale));
+  fl_scale(scale, -scale);
+
+  // Loop through the array until we see an unmatched END...
+  d    = data_;
+  dend = data_ + num_data_;
+  prim = NULL;
+  c    = ic;
+
+  if (active)
+    fl_color(c);
+  else
+    fl_color(fl_inactive(c));
+
+  while (d < dend)
+    switch (*d)
+    {
+      case END :
+          if (prim)
+            switch (*prim)
+	    {
+	      case LINE :
+		  fl_end_line();
+		  break;
+
+	      case CLOSEDLINE :
+		  fl_end_loop();
+		  break;
+
+	      case POLYGON :
+		  fl_end_complex_polygon();
+		  break;
+
+	      case OUTLINEPOLYGON :
+		  fl_end_complex_polygon();
+
+        	  oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | 
+	                	  ((unsigned short *)prim)[2]);
+                  if (active)
+		  {
+                    if (oc == FL_ICON_COLOR)
+		      fl_color(ic);
+		    else
+		      fl_color(oc);
+		  }
+		  else
+		  {
+                    if (oc == FL_ICON_COLOR)
+		      fl_color(fl_inactive(ic));
+		    else
+		      fl_color(fl_inactive(oc));
+		  }
+
+		  fl_begin_loop();
+
+		  prim += 3;
+		  while (*prim == VERTEX)
+		  {
+		    fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001);
+		    prim += 3;
+		  }
+
+        	  fl_end_loop();
+		  fl_color(c);
+		  break;
+	    }
+
+          prim = NULL;
+	  d ++;
+	  break;
+
+      case COLOR :
+          c = (Fl_Color)((((unsigned short *)d)[1] << 16) | 
+	                   ((unsigned short *)d)[2]);
+
+          if (c == FL_ICON_COLOR)
+	    c = ic;
+
+          if (!active)
+	    c = fl_inactive(c);
+
+          fl_color(c);
+	  d += 3;
+	  break;
+
+      case LINE :
+          prim = d;
+	  d ++;
+	  fl_begin_line();
+	  break;
+
+      case CLOSEDLINE :
+          prim = d;
+	  d ++;
+	  fl_begin_loop();
+	  break;
+
+      case POLYGON :
+          prim = d;
+	  d ++;
+	  fl_begin_complex_polygon();
+	  break;
+
+      case OUTLINEPOLYGON :
+          prim = d;
+	  d += 3;
+	  fl_begin_complex_polygon();
+	  break;
+
+      case VERTEX :
+          if (prim)
+	    fl_vertex(d[1] * 0.0001, d[2] * 0.0001);
+	  d += 3;
+	  break;
+
+      default : // Ignore invalid data...
+          d ++;
+    }
+
+  // If we still have an open primitive, close it...
+  if (prim)
+    switch (*prim)
+    {
+      case LINE :
+	  fl_end_line();
+	  break;
+
+      case CLOSEDLINE :
+	  fl_end_loop();
+	  break;
+
+      case POLYGON :
+	  fl_end_polygon();
+	  break;
+
+      case OUTLINEPOLYGON :
+	  fl_end_polygon();
+
+          oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | 
+	                  ((unsigned short *)prim)[2]);
+          if (active)
+	  {
+            if (oc == FL_ICON_COLOR)
+	      fl_color(ic);
+	    else
+	      fl_color(oc);
+	  }
+	  else
+	  {
+            if (oc == FL_ICON_COLOR)
+	      fl_color(fl_inactive(ic));
+	    else
+	      fl_color(fl_inactive(oc));
+	  }
+
+	  fl_begin_loop();
+
+	  prim += 3;
+	  while (*prim == VERTEX)
+	  {
+	    fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001);
+	    prim += 3;
+	  }
+
+          fl_end_loop();
+	  fl_color(c);
+	  break;
+    }
+
+  // Restore the transform matrix
+  fl_pop_matrix();
+}
+
+/**
+  Applies the icon to the widget, registering the Fl_File_Icon
+  label type as needed.
+  \param[in] w widget for which this icon will become the label
+*/
+void Fl_File_Icon::label(Fl_Widget *w)	// I - Widget to label
+{
+  Fl::set_labeltype(_FL_ICON_LABEL, labeltype, 0);
+  w->label(_FL_ICON_LABEL, (const char*)this);
+}
+
+
+/**
+  Draw the icon label.
+  \param[in] o label data
+  \param[in] x, y, w, h position and size of label
+  \param[in] a label alignment [not used]
+*/
+void
+Fl_File_Icon::labeltype(const Fl_Label *o,	// I - Label data
+                	int            x,	// I - X position of label
+			int            y,	// I - Y position of label
+			int            w,	// I - Width of label
+			int            h,	// I - Height of label
+			Fl_Align       a)	// I - Label alignment (not used)
+{
+  Fl_File_Icon *icon;			// Pointer to icon data
+
+
+  (void)a;
+
+  icon = (Fl_File_Icon *)(o->value);
+  if (icon) icon->draw(x, y, w, h, (Fl_Color)(o->color));
+}
+
+
+//
+// End of "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $".
+//