PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/fltk/src/xutf8/utf8Input.c

http://luafltk.googlecode.com/
C | 410 lines | 345 code | 32 blank | 33 comment | 133 complexity | 0ef30b385315954b615751f932fa77e5 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-3.0, 0BSD
  1. /* "$Id: $"
  2. *
  3. * Author: Jean-Marc Lienher ( http://oksid.ch )
  4. * Copyright 2000-2003 by O'ksi'D.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Library General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  19. * USA.
  20. *
  21. * Please report all bugs and problems on the following page:
  22. *
  23. * http://www.fltk.org/str.php
  24. */
  25. #if !defined(WIN32) && !defined(__APPLE__)
  26. #include "config.h"
  27. #include "../../FL/Xutf8.h"
  28. #include <X11/X.h>
  29. #include <X11/Xlib.h>
  30. #include <X11/Xutil.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #if HAVE_LIBC_ICONV
  34. #include <iconv.h>
  35. #endif
  36. /*
  37. I haven't found much doc on the web about EUC encodings, so I've used
  38. GNU libiconv source code as a reference.
  39. http://clisp.cons.org/~haible/packages-libiconv.html
  40. */
  41. #define RET_ILSEQ -1
  42. #define RET_TOOFEW(x) (-10 - x)
  43. #define RET_TOOSMALL -2
  44. #define conv_t void*
  45. #define ucs4_t unsigned int
  46. typedef struct {
  47. unsigned short indx;
  48. unsigned short used;
  49. } Summary16;
  50. #include "lcUniConv/big5.h"
  51. #include "lcUniConv/gb2312.h"
  52. #include "lcUniConv/jisx0201.h"
  53. #include "lcUniConv/jisx0208.h"
  54. #include "lcUniConv/jisx0212.h"
  55. #include "lcUniConv/ksc5601.h"
  56. int
  57. XConvertEucTwToUtf8(char* buffer_return, int len) {
  58. /* FIXME */
  59. #if HAVE_LIBC_ICONV
  60. iconv_t cd;
  61. int cdl;
  62. #else
  63. int i = 0;
  64. #endif
  65. int l = 0;
  66. char *buf, *b;
  67. if (len < 1) return 0;
  68. b = buf = (char*) malloc((unsigned)len);
  69. memcpy(buf, buffer_return, (unsigned) len);
  70. #if HAVE_LIBC_ICONV
  71. l = cdl = len;
  72. cd = iconv_open("EUC-TW", "UTF-8");
  73. iconv(cd, &b, &len, &buffer_return, &cdl);
  74. iconv_close(cd);
  75. l -= cdl;
  76. #else
  77. while (i < len) {
  78. unsigned int ucs;
  79. unsigned char c;
  80. c = (unsigned char) buf[i];
  81. if (c < 0x80) {
  82. ucs = c;
  83. i++;
  84. } else if (c >= 0xa1 && c < 0xff && len - i > 1 ) {
  85. unsigned char b[2];
  86. b[0] = (unsigned char) c - 0x80;
  87. b[1] = (unsigned char) buf[i + 1] - 0x80;
  88. ucs = ' '; i += 2;
  89. } else if (c == 0x8e && len - i > 3) {
  90. unsigned char b[2];
  91. unsigned char c1 = buf[i + 1];
  92. unsigned char c2 = buf[i + 2];
  93. unsigned char c3 = buf[i + 3];
  94. b[0] = (unsigned char) buf[i + 2] - 0x80;
  95. b[1] = (unsigned char) buf[i + 3] - 0x80;
  96. if (c1 >= 0xa1 && c1 <= 0xb0) {
  97. if (c2 >= 0xa1 && c2 < 0xff && c3 >= 0xa1 && c3 < 0xff) {
  98. ucs = ' '; i += 4;
  99. } else {
  100. ucs = '?'; i++;
  101. }
  102. } else {
  103. ucs = '?'; i++;
  104. }
  105. } else {
  106. ucs = '?';
  107. i++;
  108. }
  109. l += XConvertUcsToUtf8(ucs, buffer_return + l);
  110. }
  111. #endif
  112. free(buf);
  113. return l;
  114. }
  115. int
  116. XConvertEucKrToUtf8(char* buffer_return, int len) {
  117. int i = 0, l = 0;
  118. char *buf;
  119. if (len < 1) return 0;
  120. buf = (char*) malloc((unsigned)len);
  121. memcpy(buf, buffer_return, (unsigned)len);
  122. while (i < len) {
  123. unsigned int ucs;
  124. unsigned char c, c1;
  125. c = (unsigned char) buf[i];
  126. if (c < 0x80) {
  127. ucs = c;
  128. i++;
  129. } else if (c >= 0xA1 && c < 0xFF && len - i > 1) {
  130. c1 = (unsigned char) buf[i + 1];
  131. if (c1 >= 0xa1 && c1 < 0xff) {
  132. unsigned char b[2];
  133. b[0] = c - 0x80;
  134. b[1] = c1 - 0x80;
  135. if (ksc5601_mbtowc(NULL, &ucs, b, 2) < 1) {
  136. ucs = '?';
  137. }
  138. } else {
  139. ucs = '?';
  140. }
  141. i += 2;
  142. } else {
  143. ucs = '?';
  144. i++;
  145. }
  146. l += XConvertUcsToUtf8(ucs, buffer_return + l);
  147. }
  148. free(buf);
  149. return l;
  150. }
  151. int
  152. XConvertBig5ToUtf8(char* buffer_return, int len) {
  153. int i = 0, l = 0;
  154. char *buf;
  155. if (len < 1) return 0;
  156. buf = (char*) malloc((unsigned)len);
  157. memcpy(buf, buffer_return, (unsigned)len);
  158. if (len == 1) {
  159. l += XConvertUcsToUtf8((unsigned int)buf[i], buffer_return + l);
  160. }
  161. while (i + 1 < len) {
  162. unsigned int ucs;
  163. unsigned char b[2];
  164. b[0] = (unsigned char) buf[i];
  165. b[1] = (unsigned char) buf[i + 1];
  166. if (big5_mbtowc(NULL, &ucs, b, 2) == 2) {
  167. i += 2;
  168. } else {
  169. ucs = '?';
  170. i++;
  171. }
  172. l += XConvertUcsToUtf8(ucs, buffer_return + l);
  173. }
  174. free(buf);
  175. return l;
  176. }
  177. int
  178. XConvertGb2312ToUtf8(char* buffer_return, int len) {
  179. int i = 0, l = 0;
  180. char *buf;
  181. if (len < 1) return 0;
  182. buf = (char*) malloc((unsigned)len);
  183. memcpy(buf, buffer_return, (unsigned)len);
  184. if (len == 1) {
  185. l += XConvertUcsToUtf8((unsigned int)buf[i], buffer_return + l);
  186. }
  187. while (i + 1 < len) {
  188. unsigned int ucs;
  189. unsigned char b[2];
  190. b[0] = (unsigned char) buf[i];
  191. b[1] = (unsigned char) buf[i + 1];
  192. if (gb2312_mbtowc(NULL, &ucs, b, 2) == 2) {
  193. i += 2;
  194. } else {
  195. ucs = '?';
  196. i++;
  197. }
  198. l += XConvertUcsToUtf8(ucs, buffer_return + l);
  199. }
  200. free(buf);
  201. return l;
  202. }
  203. int
  204. XConvertEucCnToUtf8(char* buffer_return, int len) {
  205. int i = 0, l = 0;
  206. char *buf;
  207. if (len < 1) return 0;
  208. buf = (char*) malloc((unsigned)len);
  209. memcpy(buf, buffer_return, (unsigned)len);
  210. while (i < len) {
  211. unsigned int ucs;
  212. unsigned char c, c1;
  213. c = (unsigned char) buf[i];
  214. if (c < 0x80) {
  215. ucs = c;
  216. i++;
  217. } else if (c >= 0xA1 && c < 0xFF && len - i > 1) {
  218. c1 = (unsigned char) buf[i + 1];
  219. if (c1 >= 0xa1 && c1 < 0xff) {
  220. unsigned char b[2];
  221. b[0] = (unsigned char) c;
  222. b[1] = (unsigned char) c1;
  223. if (gb2312_mbtowc(NULL, &ucs, b, 2) < 1) {
  224. ucs = '?';
  225. }
  226. } else {
  227. ucs = '?';
  228. }
  229. i += 2;
  230. } else {
  231. ucs = '?';
  232. i++;
  233. }
  234. l += XConvertUcsToUtf8(ucs, buffer_return + l);
  235. }
  236. free(buf);
  237. return l;
  238. }
  239. int
  240. XConvertEucJpToUtf8(char* buffer_return, int len) {
  241. int i = 0, l = 0;
  242. char *buf;
  243. if (len < 1) return 0;
  244. buf = (char*) malloc((unsigned)len);
  245. memcpy(buf, buffer_return, (unsigned)len);
  246. while (i < len) {
  247. unsigned int ucs;
  248. unsigned char c, c1;
  249. c = (unsigned char) buf[i];
  250. if (c < 0x80) {
  251. ucs = c;
  252. i++;
  253. } else if (c >= 0xA1 && c < 0xFF && len - i > 1) {
  254. c1 = (unsigned char) buf[i + 1];
  255. if (c < 0xF5 && c1 >= 0xa1) {
  256. unsigned char b[2];
  257. b[0] = c - 0x80;
  258. b[1] = c1 - 0x80;
  259. if (jisx0208_mbtowc(NULL, &ucs, b, 2) < 1) {
  260. ucs = '?';
  261. }
  262. } else if (c1 >= 0xA1 && c1 < 0xFF) {
  263. ucs = 0xE000 + 94 * (c - 0xF5) + (c1 - 0xA1);
  264. } else {
  265. ucs = '?';
  266. }
  267. i += 2;
  268. } else if (c == 0x8E && len - i > 1) {
  269. c1 = (unsigned char) buf[i + 1];
  270. if (c1 >= 0xa1 && c1 <= 0xe0) {
  271. if (jisx0201_mbtowc(NULL, &ucs, &c1, 1) != 1) {
  272. ucs = '?';
  273. }
  274. } else {
  275. ucs = '?';
  276. }
  277. i += 2;
  278. } else if (c == 0x8F && len - i > 2) {
  279. c = (unsigned char) buf[i + 1];
  280. c1 = (unsigned char) buf[i + 2];
  281. if (c >= 0xa1 && c < 0xff) {
  282. if (c < 0xf5 && c1 >= 0xa1 && c1 < 0xff) {
  283. unsigned char b[2];
  284. b[0] = c - 0x80;
  285. b[1] = c1 - 0x80;
  286. if (jisx0212_mbtowc(NULL, &ucs, b, 2) < 1) {
  287. ucs = '?';
  288. }
  289. } else {
  290. ucs = '?';
  291. }
  292. } else {
  293. if (c1 >= 0xa1 && c1 < 0xff) {
  294. ucs = 0xe3ac + 94 * (c - 0xF5) + (c1 - 0xA1);
  295. } else {
  296. ucs = '?';
  297. }
  298. }
  299. i += 3;
  300. } else {
  301. ucs = '?';
  302. i++;
  303. }
  304. l += XConvertUcsToUtf8(ucs, buffer_return + l);
  305. }
  306. free(buf);
  307. return l;
  308. }
  309. int
  310. XConvertEucToUtf8(const char* locale,
  311. char* buffer_return,
  312. int len,
  313. int bytes_buffer) {
  314. if (!locale/* || strstr(locale, "UTF") || strstr(locale, "utf")*/) {
  315. return len;
  316. }
  317. if (strstr(locale, "ja")) {
  318. return XConvertEucJpToUtf8(buffer_return, len);
  319. } else if (strstr(locale, "Big5") || strstr(locale, "big5")) { /* BIG5 */
  320. return XConvertBig5ToUtf8(buffer_return, len);
  321. } else if (strstr(locale, "zh") || strstr(locale, "chinese-")) {
  322. if (strstr(locale, "TW") || strstr(locale, "chinese-t")) {
  323. if (strstr(locale, "EUC") || strstr(locale, "euc") || strstr(locale, "chinese-t")) {
  324. return XConvertEucTwToUtf8(buffer_return, len);
  325. }
  326. return XConvertBig5ToUtf8(buffer_return, len);
  327. }
  328. if (strstr(locale, "EUC") || strstr(locale, "euc")) {
  329. return XConvertEucCnToUtf8(buffer_return, len);
  330. }
  331. return XConvertGb2312ToUtf8(buffer_return, len);
  332. } else if (strstr(locale, "ko")) {
  333. return XConvertEucKrToUtf8(buffer_return, len);
  334. }
  335. return len;
  336. }
  337. int
  338. XUtf8LookupString(XIC ic,
  339. XKeyPressedEvent* event,
  340. char* buffer_return,
  341. int bytes_buffer,
  342. KeySym* keysym,
  343. Status* status_return) {
  344. long ucs = -1;
  345. int len;
  346. len = XmbLookupString(ic, event, buffer_return, bytes_buffer / 5,
  347. keysym, status_return);
  348. if (*status_return == XBufferOverflow) {
  349. return len * 5;
  350. }
  351. if (*keysym > 0 && *keysym < 0x100 && len == 1) {
  352. if (*keysym < 0x80) {
  353. ucs = (unsigned char)buffer_return[0];
  354. } else {
  355. ucs = *keysym;
  356. }
  357. } else if (((*keysym >= 0x100 && *keysym <= 0xf000) ||
  358. (*keysym & 0xff000000U) == 0x01000000))
  359. {
  360. ucs = XKeysymToUcs(*keysym);
  361. } else {
  362. ucs = -2;
  363. }
  364. if (ucs > 0) {
  365. len = XConvertUcsToUtf8((unsigned)ucs, (char *)buffer_return);
  366. } else if (len > 0) {
  367. XIM im;
  368. if (!ic) return 0;
  369. im = XIMOfIC(ic);
  370. if (!im) return 0;
  371. len = XConvertEucToUtf8(XLocaleOfIM(im), buffer_return, len, bytes_buffer);
  372. }
  373. return len;
  374. }
  375. #endif /* X11 only */
  376. /*
  377. * End of "$Id$".
  378. */