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/xutf8/utf8Utils.c b/common/fltk/src/xutf8/utf8Utils.c
new file mode 100644
index 0000000..6c177a7
--- /dev/null
+++ b/common/fltk/src/xutf8/utf8Utils.c
@@ -0,0 +1,238 @@
+/* "$Id: $"
+ *
+ * Author: Jean-Marc Lienher ( http://oksid.ch )
+ * Copyright 2000-2003 by O'ksi'D.
+ *
+ * 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
+ */
+
+/*
+ * Unicode to UTF-8 conversion functions.
+ */
+
+#if !defined(WIN32) && !defined(__APPLE__)
+
+#include "../../FL/Xutf8.h"
+
+/*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/
+
+/* 
+ * Converts the first char of the UTF-8 string to an Unicode value 
+ * Returns the byte length of the converted UTF-8 char 
+ * Returns -1 if the UTF-8 string is not valid 
+ */
+int
+XConvertUtf8ToUcs(const unsigned char     *buf,
+		  int                     len,
+		  unsigned int         	  *ucs) {
+
+  if (buf[0] & 0x80) {
+    if (buf[0] & 0x40) {
+      if (buf[0] & 0x20) {
+	if (buf[0] & 0x10) {
+	  if (buf[0] & 0x08) {
+	    if (buf[0] & 0x04) {
+	      if (buf[0] & 0x02) {
+		/* bad UTF-8 string */
+	      } else {
+		/* 0x04000000 - 0x7FFFFFFF */
+	      }	
+	    } else if (len > 4 
+		       && (buf[1] & 0xC0) == 0x80
+		       && (buf[2] & 0xC0) == 0x80
+		       && (buf[3] & 0xC0) == 0x80
+		       && (buf[4] & 0xC0) == 0x80) {
+	      /* 0x00200000 - 0x03FFFFFF */
+	      *ucs =  ((buf[0] & ~0xF8) << 24) +
+		      ((buf[1] & ~0x80) << 18) +
+		      ((buf[2] & ~0x80) << 12) +
+		      ((buf[3] & ~0x80) << 6) +
+		       (buf[4] & ~0x80);
+	      if (*ucs > 0x001FFFFF && *ucs < 0x01000000) return 5;
+	    }
+	  } else if (len > 3 
+		     && (buf[1] & 0xC0) == 0x80
+		     && (buf[2] & 0xC0) == 0x80
+		     && (buf[3] & 0xC0) == 0x80) {
+	    /* 0x00010000 - 0x001FFFFF */
+	    *ucs =  ((buf[0] & ~0xF0) << 18) +
+		    ((buf[1] & ~0x80) << 12) +
+		    ((buf[2] & ~0x80) << 6) +
+		     (buf[3] & ~0x80);
+	    if (*ucs > 0x0000FFFF) return 4;
+	  }
+	} else if (len > 2
+	           && (buf[1] & 0xC0) == 0x80 
+		   && (buf[2] & 0xC0) == 0x80) {
+	  /* 0x00000800 - 0x0000FFFF */
+	  *ucs =  ((buf[0] & ~0xE0) << 12) +
+		  ((buf[1] & ~0x80) << 6) +
+		   (buf[2] & ~0x80);
+	  if (*ucs > 0x000007FF) return 3;
+	}	
+      } else if (len > 1 && (buf[1] & 0xC0) == 0x80) {
+	/* 0x00000080 - 0x000007FF */
+	*ucs = ((buf[0] & ~0xC0) << 6) +
+		(buf[1] & ~0x80);
+	if (*ucs > 0x0000007F) return 2;
+      }
+    }
+  } else if (len > 0) {
+    /* 0x00000000 - 0x0000007F */
+    *ucs = buf[0];
+    return 1;
+  } 
+
+  *ucs = (unsigned int) '?'; /* bad utf-8 string */
+  return -1;
+}
+
+/* 
+ * Converts an Unicode value to an UTF-8 string 
+ * NOTE : the buffer (buf) must be at least 5 bytes long !!!  
+ */
+int 
+XConvertUcsToUtf8(unsigned int 	ucs, 
+		  char 		*buf) {
+
+  if (ucs < 0x000080) {
+    buf[0] = ucs;
+    return 1;
+  } else if (ucs < 0x000800) {
+    buf[0] = 0xC0 | (ucs >> 6);
+    buf[1] = 0x80 | (ucs & 0x3F);
+    return 2;
+  } else if (ucs < 0x010000) { 
+    buf[0] = 0xE0 | (ucs >> 12);
+    buf[1] = 0x80 | ((ucs >> 6) & 0x3F);
+    buf[2] = 0x80 | (ucs & 0x3F);
+    return 3;
+  } else if (ucs < 0x00200000) {
+    buf[0] = 0xF0 | (ucs >> 18);
+    buf[1] = 0x80 | ((ucs >> 12) & 0x3F);
+    buf[2] = 0x80 | ((ucs >> 6) & 0x3F);
+    buf[3] = 0x80 | (ucs & 0x3F);
+    return 4;
+  } else if (ucs < 0x01000000) {
+    buf[0] = 0xF8 | (ucs >> 24);
+    buf[1] = 0x80 | ((ucs >> 18) & 0x3F);
+    buf[2] = 0x80 | ((ucs >> 12) & 0x3F);
+    buf[3] = 0x80 | ((ucs >> 6) & 0x3F);
+    buf[4] = 0x80 | (ucs & 0x3F);
+    return 5;
+  }
+  buf[0] = '?';
+  return -1;
+}
+
+/* 
+ * returns the byte length of the first UTF-8 char 
+ * (returns -1 if not valid) 
+ */
+int
+XUtf8CharByteLen(const unsigned char     *buf,
+		 int                     len) {
+  unsigned int ucs;
+  return XConvertUtf8ToUcs(buf, len, &ucs);
+}
+
+/*
+ * returns the quantity of Unicode chars in the UTF-8 string 
+ */
+int 
+XCountUtf8Char(const unsigned char 	*buf, 
+	       int 			len) {
+
+  int i = 0;
+  int nbc = 0;
+  while (i < len) {
+    int cl = XUtf8CharByteLen(buf + i, len - i);
+    if (cl < 1) cl = 1;
+    nbc++;
+    i += cl;
+  }
+  return nbc;
+}
+
+/* 
+ * Same as XConvertUtf8ToUcs but no sanity check is done.
+ */
+int
+XFastConvertUtf8ToUcs(const unsigned char     *buf,
+		      int                     len,
+		      unsigned int            *ucs) {
+
+  if (buf[0] & 0x80) {
+    if (buf[0] & 0x40) {
+      if (buf[0] & 0x20) {
+	if (buf[0] & 0x10) {
+	  if (buf[0] & 0x08) {
+	    if (buf[0] & 0x04) {
+	      if (buf[0] & 0x02) {
+		/* bad UTF-8 string */
+	      } else {
+		/* 0x04000000 - 0x7FFFFFFF */
+	      }	
+	    } else if (len > 4) {
+	      /* 0x00200000 - 0x03FFFFFF */
+	      *ucs =  ((buf[0] & ~0xF8) << 24) +
+		      ((buf[1] & ~0x80) << 18) +
+		      ((buf[2] & ~0x80) << 12) +
+		      ((buf[3] & ~0x80) << 6) +
+		       (buf[4] & ~0x80);
+	      return 5;
+	    }
+	  } else if (len > 3) {
+	    /* 0x00010000 - 0x001FFFFF */
+	    *ucs =  ((buf[0] & ~0xF0) << 18) +
+		    ((buf[1] & ~0x80) << 12) +
+		    ((buf[2] & ~0x80) << 6) +
+		     (buf[3] & ~0x80);
+	    return 4;
+	  }
+	} else if (len > 2) {
+	  /* 0x00000800 - 0x0000FFFF */
+	  *ucs =  ((buf[0] & ~0xE0) << 12) +
+		  ((buf[1] & ~0x80) << 6) +
+		   (buf[2] & ~0x80);
+	  return 3;
+	}	
+      } else if (len > 1) {
+	/* 0x00000080 - 0x000007FF */
+	*ucs = ((buf[0] & ~0xC0) << 6) +
+		(buf[1] & ~0x80);
+	return 2;
+      }
+    }
+  } else if (len > 0) {
+    /* 0x00000000 - 0x0000007F */
+    *ucs = buf[0];
+    return 1;
+  } 
+
+  *ucs = (unsigned int) '?'; /* bad utf-8 string */
+  return -1;
+}
+
+#endif /* X11 only */
+
+/*
+ * End of "$Id: $".
+ */