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: $".
+ */