_fallcCT.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* lcCT.c 1.1 - Fujitsu source for CDEnext 95/11/06 20:32:33 */
  24. /* $XConsortium: _fallcCT.c /main/1 1996/04/08 15:15:33 cde-fuj $ */
  25. /*
  26. * Copyright 1992, 1993 by TOSHIBA Corp.
  27. *
  28. * Permission to use, copy, modify, and distribute this software and its
  29. * documentation for any purpose and without fee is hereby granted, provided
  30. * that the above copyright notice appear in all copies and that both that
  31. * copyright notice and this permission notice appear in supporting
  32. * documentation, and that the name of TOSHIBA not be used in advertising
  33. * or publicity pertaining to distribution of the software without specific,
  34. * written prior permission. TOSHIBA make no representations about the
  35. * suitability of this software for any purpose. It is provided "as is"
  36. * without express or implied warranty.
  37. *
  38. * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  39. * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  40. * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  41. * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  42. * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  43. * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  44. * SOFTWARE.
  45. *
  46. * Author: Katsuhisa Yano TOSHIBA Corp.
  47. * mopi@osa.ilab.toshiba.co.jp
  48. */
  49. #include "_fallibint.h"
  50. #include "_fallcPubI.h"
  51. #include <X11/Xos.h>
  52. #include <stdio.h>
  53. typedef struct _StateRec {
  54. XlcCharSet charset;
  55. XlcCharSet GL_charset;
  56. XlcCharSet GR_charset;
  57. XlcCharSet ext_seg_charset;
  58. int ext_seg_left;
  59. } StateRec, *State;
  60. typedef struct _CTDataRec {
  61. char *name;
  62. char *encoding; /* Compound Text encoding */
  63. } CTDataRec, *CTData;
  64. typedef struct _CTInfoRec {
  65. XlcCharSet charset;
  66. int encoding_len;
  67. char *encoding; /* Compound Text encoding */
  68. int ext_segment_len;
  69. char *ext_segment; /* extended segment */
  70. struct _CTInfoRec *next;
  71. } CTInfoRec, *CTInfo;
  72. static CTDataRec default_ct_data[] =
  73. {
  74. { "ISO8859-1:GL", "\033(B" },
  75. { "ISO8859-1:GR", "\033-A" },
  76. { "ISO8859-2:GR", "\033-B" },
  77. { "ISO8859-3:GR", "\033-C" },
  78. { "ISO8859-4:GR", "\033-D" },
  79. { "ISO8859-7:GR", "\033-F" },
  80. { "ISO8859-6:GR", "\033-G" },
  81. { "ISO8859-8:GR", "\033-H" },
  82. { "ISO8859-5:GR", "\033-L" },
  83. { "ISO8859-9:GR", "\033-M" },
  84. { "JISX0201.1976-0:GL", "\033(J" },
  85. { "JISX0201.1976-0:GR", "\033)I" },
  86. { "GB2312.1980-0:GL", "\033$(A" },
  87. { "GB2312.1980-0:GR", "\033$)A" },
  88. { "JISX0208.1983-0:GL", "\033$(B" },
  89. { "JISX0208.1983-0:GR", "\033$)B" },
  90. { "KSC5601.1987-0:GL", "\033$(C" },
  91. { "KSC5601.1987-0:GR", "\033$)C" },
  92. } ;
  93. #define XctC0 0x0000
  94. #define XctHT 0x0009
  95. #define XctNL 0x000a
  96. #define XctESC 0x001b
  97. #define XctGL 0x0020
  98. #define XctC1 0x0080
  99. #define XctCSI 0x009b
  100. #define XctGR 0x00a0
  101. #define XctCntrlFunc 0x0023
  102. #define XctMB 0x0024
  103. #define XctOtherCoding 0x0025
  104. #define XctGL94 0x0028
  105. #define XctGR94 0x0029
  106. #define XctGR96 0x002d
  107. #define XctNonStandard 0x002f
  108. #define XctIgnoreExt 0x0030
  109. #define XctNotIgnoreExt 0x0031
  110. #define XctLeftToRight 0x0031
  111. #define XctRightToLeft 0x0032
  112. #define XctDirection 0x005d
  113. #define XctDirectionEnd 0x005d
  114. #define XctGL94MB 0x2428
  115. #define XctGR94MB 0x2429
  116. #define XctExtSeg 0x252f
  117. #define XctOtherSeg 0x2f00
  118. #define XctESCSeq 0x1b00
  119. #define XctCSISeq 0x9b00
  120. #define SKIP_I(str) while (*(str) >= 0x20 && *(str) <= 0x2f) (str)++;
  121. #define SKIP_P(str) while (*(str) >= 0x30 && *(str) <= 0x3f) (str)++;
  122. typedef struct {
  123. XlcSide side;
  124. int char_size;
  125. int set_size;
  126. int ext_seg_length;
  127. int version;
  128. CTInfo ct_info;
  129. } CTParseRec, *CTParse;
  130. static CTInfo ct_list = NULL;
  131. static CTInfo
  132. _XlcGetCTInfoFromEncoding(char *encoding, int length)
  133. {
  134. CTInfo ct_info;
  135. for (ct_info = ct_list; ct_info; ct_info = ct_info->next) {
  136. if (length >= ct_info->encoding_len) {
  137. if (ct_info->ext_segment) {
  138. if (!strncmp(ct_info->encoding, encoding, 4) &&
  139. !strncmp(ct_info->ext_segment, encoding + 6,
  140. ct_info->ext_segment_len))
  141. return ct_info;
  142. } else if (!strncmp(ct_info->encoding, encoding,
  143. ct_info->encoding_len)) {
  144. return ct_info;
  145. }
  146. }
  147. }
  148. return (CTInfo) NULL;
  149. }
  150. static unsigned int
  151. _XlcParseCT(CTParse parse, char **text, int *length)
  152. {
  153. unsigned int ret = 0;
  154. unsigned char ch;
  155. unsigned char *str = (unsigned char *) *text;
  156. bzero((char *) parse, sizeof(CTParseRec));
  157. switch (ch = *str++) {
  158. case XctESC:
  159. if (*str == XctOtherCoding && *(str + 1) == XctNonStandard
  160. && *(str + 2) >= 0x30 && *(str + 2) <= 0x3f && *length >= 6) {
  161. /* non-standard encodings */
  162. parse->side = XlcGLGR;
  163. parse->set_size = 0;
  164. str += 2;
  165. if (*str <= 0x34) {
  166. parse->char_size = *str - 0x30;
  167. if (parse->char_size == 0) parse->char_size = 1;
  168. ret = XctExtSeg;
  169. parse->ct_info = _XlcGetCTInfoFromEncoding(*text, *length);
  170. } else
  171. ret = XctOtherSeg;
  172. str++;
  173. parse->ext_seg_length = (*str - 128) * 128 + *(str + 1) - 128;
  174. str += 2;
  175. *length -= (char *) str - *text;
  176. *text = (char *) str;
  177. return ret;
  178. } else if (*str == XctCntrlFunc && *length >= 4 &&
  179. *(str + 1) >= 0x20 && *(str + 1) <= 0x2f &&
  180. (*(str + 2) == XctIgnoreExt ||
  181. *(str + 2) == XctNotIgnoreExt)) {
  182. /* ignore extension or not */
  183. str++;
  184. parse->version = *str++ - 0x20;
  185. ret = *str++;
  186. *length -= (char *) str - *text;
  187. *text = (char *) str;
  188. return ret;
  189. }
  190. if (*str == XctMB) { /* multiple-byte sets */
  191. parse->char_size = 2;
  192. str++;
  193. } else
  194. parse->char_size = 1;
  195. switch (*str) {
  196. case XctGL94:
  197. parse->side = XlcGL;
  198. parse->set_size = 94;
  199. ret = (parse->char_size == 1) ? XctGL94 : XctGL94MB;
  200. break;
  201. case XctGR94:
  202. parse->side = XlcGR;
  203. parse->set_size = 94;
  204. ret = (parse->char_size == 1) ? XctGR94 : XctGR94MB;
  205. break;
  206. case XctGR96:
  207. if (parse->char_size == 1) {
  208. parse->side = XlcGR;
  209. parse->set_size = 96;
  210. ret = XctGR96;
  211. }
  212. break;
  213. }
  214. if (ret) {
  215. str++;
  216. if (*str >= 0x24 && *str <= 0x2f) { /* non-standard */
  217. ret = 0;
  218. str++;
  219. }
  220. }
  221. SKIP_I(str)
  222. if (ret && *str < 0x40) /* non-standard */
  223. ret = 0;
  224. if (*str < 0x30 || *str > 0x7e || (char *) str - *text >= *length)
  225. break;
  226. if (ret == 0)
  227. ret = XctESCSeq;
  228. else {
  229. if (parse->char_size == 2) {
  230. if (*str >= 0x70)
  231. parse->char_size = 4;
  232. else if (*str >= 0x60)
  233. parse->char_size = 3;
  234. }
  235. parse->ct_info = _XlcGetCTInfoFromEncoding(*text, *length);
  236. }
  237. str++;
  238. *length -= (char *) str - *text;
  239. *text = (char *) str;
  240. return ret;
  241. case XctCSI:
  242. /* direction */
  243. if (*str == XctLeftToRight && *(str + 1) == XctDirection) {
  244. ret = XctLeftToRight;
  245. str += 2;
  246. *length -= (char *) str - *text;
  247. *text = (char *) str;
  248. return ret;
  249. } else if (*str == XctRightToLeft && *(str + 1) == XctDirection) {
  250. ret = XctRightToLeft;
  251. str += 2;
  252. *length -= (char *) str - *text;
  253. *text = (char *) str;
  254. return ret;
  255. } else if (*str == XctDirectionEnd) {
  256. ret = XctDirectionEnd;
  257. str++;
  258. *length -= (char *) str - *text;
  259. *text = (char *) str;
  260. return ret;
  261. }
  262. SKIP_P(str)
  263. SKIP_I(str)
  264. if (*str < 0x40 && *str > 0x7e)
  265. break;
  266. ret = XctCSISeq;
  267. str++;
  268. *length -= (char *) str - *text;
  269. *text = (char *) str;
  270. return ret;
  271. }
  272. if (ch & 0x80) {
  273. if (ch < 0xa0)
  274. ret = XctC1;
  275. else
  276. ret = XctGR;
  277. } else {
  278. if (ch == XctHT || ch == XctNL)
  279. ret = ch;
  280. else if (ch < 0x20)
  281. ret = XctC0;
  282. else
  283. ret = XctGL;
  284. }
  285. return ret;
  286. }
  287. XlcCharSet
  288. _fallcAddCT(char *name, char *encoding)
  289. {
  290. CTInfo ct_info;
  291. XlcCharSet charset;
  292. CTParseRec parse;
  293. char *ct_ptr = encoding;
  294. int length;
  295. unsigned int type;
  296. length = strlen(encoding);
  297. switch (type = _XlcParseCT(&parse, &ct_ptr, &length)) {
  298. case XctExtSeg:
  299. case XctGL94:
  300. case XctGL94MB:
  301. case XctGR94:
  302. case XctGR94MB:
  303. case XctGR96:
  304. if (parse.ct_info) /* existed */
  305. return parse.ct_info->charset;
  306. break;
  307. default:
  308. return (XlcCharSet) NULL;
  309. }
  310. charset = _fallcCreateDefaultCharSet(name, encoding);
  311. if (charset == NULL)
  312. return (XlcCharSet) NULL;
  313. _fallcAddCharSet(charset);
  314. ct_info = (CTInfo) Xmalloc(sizeof(CTInfoRec));
  315. if (ct_info == NULL)
  316. return (XlcCharSet) NULL;
  317. ct_info->charset = charset;
  318. ct_info->encoding = charset->ct_sequence;
  319. ct_info->encoding_len = strlen(ct_info->encoding);
  320. if (type == XctExtSeg) {
  321. ct_info->ext_segment = ct_info->encoding + 6;
  322. ct_info->ext_segment_len = strlen(ct_info->ext_segment);
  323. } else {
  324. ct_info->ext_segment = NULL;
  325. ct_info->ext_segment_len = 0;
  326. }
  327. ct_info->next = ct_list;
  328. ct_list = ct_info;
  329. return charset;
  330. }
  331. static CTInfo
  332. _XlcGetCTInfoFromCharSet(XlcCharSet charset)
  333. {
  334. CTInfo ct_info;
  335. for (ct_info = ct_list; ct_info; ct_info = ct_info->next)
  336. if (ct_info->charset == charset)
  337. return ct_info;
  338. return (CTInfo) NULL;
  339. }
  340. Bool
  341. _fallcParseCharSet(XlcCharSet charset)
  342. {
  343. CTParseRec parse;
  344. char *ptr, buf[BUFSIZ];
  345. unsigned int type;
  346. int length;
  347. if (charset->ct_sequence == NULL)
  348. return False;
  349. ptr = charset->ct_sequence;
  350. length = strlen(ptr);
  351. type = _XlcParseCT(&parse, &ptr, &length);
  352. if (charset->name) {
  353. charset->xrm_name = falrmStringToQuark(charset->name);
  354. snprintf(buf, sizeof(buf), "%s", charset->name);
  355. if (ptr = strchr(buf, ':'))
  356. *ptr = '\0';
  357. charset->xrm_encoding_name = falrmStringToQuark(buf);
  358. charset->encoding_name = falrmQuarkToString(charset->xrm_encoding_name);
  359. } else {
  360. charset->xrm_name = 0;
  361. charset->encoding_name = NULL;
  362. charset->xrm_encoding_name = 0;
  363. }
  364. charset->side = parse.side;
  365. charset->char_size = parse.char_size;
  366. charset->set_size = parse.set_size;
  367. return True;
  368. }
  369. static void init_converter();
  370. Bool
  371. _fallcInitCTInfo(void)
  372. {
  373. XlcCharSet charset;
  374. CTData ct_data;
  375. int num;
  376. if (ct_list == NULL) {
  377. num = sizeof(default_ct_data) / sizeof(CTDataRec);
  378. for (ct_data = default_ct_data; num-- > 0; ct_data++) {
  379. charset = _fallcAddCT(ct_data->name, ct_data->encoding);
  380. if (charset == NULL)
  381. continue;
  382. }
  383. init_converter();
  384. }
  385. return True;
  386. }
  387. static int
  388. _XlcCheckCTSequence(State state, char **ctext, int *ctext_len)
  389. {
  390. XlcCharSet charset;
  391. CTParseRec parse;
  392. CTInfo ct_info;
  393. int length;
  394. _XlcParseCT(&parse, ctext, ctext_len);
  395. ct_info = parse.ct_info;
  396. if (parse.ext_seg_length > 0) { /* XctExtSeg or XctOtherSeg */
  397. if (ct_info) {
  398. length = ct_info->ext_segment_len;
  399. *ctext += length;
  400. *ctext_len -= length;
  401. state->ext_seg_left = parse.ext_seg_length - length;
  402. state->ext_seg_charset = ct_info->charset;
  403. } else {
  404. state->ext_seg_left = parse.ext_seg_length;
  405. state->ext_seg_charset = NULL;
  406. }
  407. } else if (ct_info) {
  408. if (charset = ct_info->charset) {
  409. if (charset->side == XlcGL)
  410. state->GL_charset = charset;
  411. else if (charset->side == XlcGR)
  412. state->GR_charset = charset;
  413. }
  414. }
  415. return 0;
  416. }
  417. static void
  418. init_state(XlcConv conv)
  419. {
  420. State state = (State) conv->state;
  421. static XlcCharSet GL_charset = NULL;
  422. static XlcCharSet GR_charset = NULL;
  423. if (GL_charset == NULL) {
  424. GL_charset = _fallcGetCharSet("ISO8859-1:GL");
  425. GR_charset = _fallcGetCharSet("ISO8859-1:GR");
  426. }
  427. state->GL_charset = state->charset = GL_charset;
  428. state->GR_charset = GR_charset;
  429. state->ext_seg_charset = NULL;
  430. state->ext_seg_left = 0;
  431. }
  432. static int
  433. cttocs(
  434. XlcConv conv,
  435. XPointer *from,
  436. int *from_left,
  437. XPointer *to,
  438. int *to_left,
  439. XPointer *args,
  440. int num_args)
  441. {
  442. State state = (State) conv->state;
  443. unsigned char ch;
  444. int length;
  445. XlcCharSet charset = NULL;
  446. char *ctptr, *bufptr;
  447. int ctext_len, buf_len;
  448. ctptr = *((char **) from);
  449. bufptr = *((char **) to);
  450. ctext_len = *from_left;
  451. buf_len = *to_left;
  452. while (ctext_len > 0 && buf_len > 0) {
  453. if (state->ext_seg_left > 0) {
  454. length = min(state->ext_seg_left, ctext_len);
  455. length = min(length, buf_len);
  456. ctext_len -= length;
  457. state->ext_seg_left -= length;
  458. if (state->ext_seg_charset) {
  459. charset = state->ext_seg_charset;
  460. buf_len -= length;
  461. if (charset->side == XlcGL) {
  462. while (length-- > 0)
  463. *bufptr++ = *ctptr++ & 0x7f;
  464. } else if (charset->side == XlcGR) {
  465. while (length-- > 0)
  466. *bufptr++ = *ctptr++ | 0x80;
  467. } else {
  468. while (length-- > 0)
  469. *bufptr++ = *ctptr++;
  470. }
  471. if (state->ext_seg_left < 1)
  472. state->ext_seg_charset = NULL;
  473. }
  474. break;
  475. }
  476. ch = *((unsigned char *) ctptr);
  477. if (ch == 0x1b || ch == 0x9b) {
  478. length = _XlcCheckCTSequence(state, &ctptr, &ctext_len);
  479. if (length < 0)
  480. return -1;
  481. if (state->ext_seg_left > 0 && charset)
  482. break;
  483. } else {
  484. if (charset) {
  485. if (charset != (ch & 0x80 ? state->GR_charset :
  486. state->GL_charset))
  487. break;
  488. } else
  489. charset = ch & 0x80 ? state->GR_charset : state->GL_charset;
  490. if ((ch < 0x20 && ch != '\0' && ch != '\n' && ch != '\t') ||
  491. (ch >= 0x80 && ch < 0xa0))
  492. return -1;
  493. *bufptr++ = *ctptr++;
  494. ctext_len--;
  495. buf_len--;
  496. }
  497. }
  498. if (charset)
  499. state->charset = charset;
  500. if (num_args > 0)
  501. *((XlcCharSet *) args[0]) = state->charset;
  502. *from_left -= ctptr - *((char **) from);
  503. *from = (XPointer) ctptr;
  504. *to_left -= bufptr - *((char **) to);
  505. *to = (XPointer) bufptr;
  506. return 0;
  507. }
  508. static int
  509. cstoct(
  510. XlcConv conv,
  511. XPointer *from,
  512. int *from_left,
  513. XPointer *to,
  514. int *to_left,
  515. XPointer *args,
  516. int num_args)
  517. {
  518. State state = (State) conv->state;
  519. XlcSide side;
  520. unsigned char min_ch, max_ch, ch;
  521. int length;
  522. CTInfo ct_info;
  523. XlcCharSet charset;
  524. char *csptr, *ctptr;
  525. int csstr_len, ct_len;
  526. if (num_args < 1)
  527. return -1;
  528. csptr = *((char **) from);
  529. ctptr = *((char **) to);
  530. csstr_len = *from_left;
  531. ct_len = *to_left;
  532. charset = (XlcCharSet) args[0];
  533. ct_info = _XlcGetCTInfoFromCharSet(charset);
  534. if (ct_info == NULL)
  535. return -1;
  536. side = charset->side;
  537. if (ct_info->ext_segment) {
  538. if (charset != state->ext_seg_charset && state->ext_seg_left < 1) {
  539. length = ct_info->encoding_len;
  540. if (ct_len < length)
  541. return -1;
  542. strcpy(ctptr, ct_info->encoding);
  543. ctptr[4] = ((ct_info->ext_segment_len + csstr_len) / 128) | 0x80;
  544. ctptr[5] = ((ct_info->ext_segment_len + csstr_len) % 128) | 0x80;
  545. ctptr += length;
  546. ct_len -= length;
  547. state->ext_seg_left = csstr_len;
  548. }
  549. length = min(state->ext_seg_left, csstr_len);
  550. state->ext_seg_left -= length;
  551. if (side == XlcGL) {
  552. while (length-- > 0)
  553. *ctptr++ = *csptr++ & 0x7f;
  554. } else if (side == XlcGR) {
  555. while (length-- > 0)
  556. *ctptr++ = *csptr++ | 0x80;
  557. } else {
  558. while (length-- > 0)
  559. *ctptr++ = *csptr++;
  560. }
  561. state->ext_seg_charset = (state->ext_seg_left > 0) ? charset : NULL;
  562. } else {
  563. if ((side == XlcGR && charset != state->GR_charset) ||
  564. (side == XlcGL && charset != state->GL_charset)) {
  565. ct_len -= ct_info->encoding_len;
  566. if (ct_len < 0)
  567. return -1;
  568. strcpy(ctptr, ct_info->encoding);
  569. ctptr += ct_info->encoding_len;
  570. }
  571. min_ch = 0x20;
  572. max_ch = 0x7f;
  573. if (charset->set_size == 94) {
  574. max_ch--;
  575. if (charset->char_size > 1 || side == XlcGR)
  576. min_ch++;
  577. }
  578. while (csstr_len > 0 && ct_len > 0) {
  579. ch = *((unsigned char *) csptr++) & 0x7f;
  580. if (ch < min_ch || ch > max_ch)
  581. if (ch != 0x00 && ch != 0x09 && ch != 0x0a && ch != 0x1b)
  582. continue; /* XXX */
  583. if (side == XlcGL)
  584. *ctptr++ = ch & 0x7f;
  585. else if (side == XlcGR)
  586. *ctptr++ = ch | 0x80;
  587. else
  588. *ctptr++ = ch;
  589. csstr_len--;
  590. ct_len--;
  591. }
  592. if (side == XlcGR)
  593. state->GR_charset = charset;
  594. else if (side == XlcGL)
  595. state->GL_charset = charset;
  596. }
  597. *from_left -= csptr - *((char **) from);
  598. *from = (XPointer) csptr;
  599. *to_left -= ctptr - *((char **) to);
  600. *to = (XPointer) ctptr;
  601. return 0;
  602. }
  603. static int
  604. strtocs(
  605. XlcConv conv,
  606. XPointer *from,
  607. int *from_left,
  608. XPointer *to,
  609. int *to_left,
  610. XPointer *args,
  611. int num_args)
  612. {
  613. State state = (State) conv->state;
  614. char *src, *dst;
  615. unsigned char side;
  616. int length;
  617. src = (char *) *from;
  618. dst = (char *) *to;
  619. length = min(*from_left, *to_left);
  620. side = *((unsigned char *) src) & 0x80;
  621. while (side == (*((unsigned char *) src) & 0x80) && length-- > 0)
  622. *dst++ = *src++;
  623. *from_left -= src - (char *) *from;
  624. *from = (XPointer) src;
  625. *to_left -= dst - (char *) *to;
  626. *to = (XPointer) dst;
  627. if (num_args > 0)
  628. *((XlcCharSet *)args[0]) = side ? state->GR_charset : state->GL_charset;
  629. return 0;
  630. }
  631. static int
  632. cstostr(
  633. XlcConv conv,
  634. XPointer *from,
  635. int *from_left,
  636. XPointer *to,
  637. int *to_left,
  638. XPointer *args,
  639. int num_args)
  640. {
  641. State state = (State) conv->state;
  642. char *csptr, *string_ptr;
  643. int csstr_len, str_len;
  644. unsigned char ch;
  645. int unconv_num = 0;
  646. if (num_args < 1 || (state->GL_charset != (XlcCharSet) args[0] &&
  647. state->GR_charset != (XlcCharSet) args[0]))
  648. return -1;
  649. csptr = *((char **) from);
  650. string_ptr = *((char **) to);
  651. csstr_len = *from_left;
  652. str_len = *to_left;
  653. while (csstr_len-- > 0 && str_len > 0) {
  654. ch = *((unsigned char *) csptr++);
  655. if ((ch < 0x20 && ch != 0x00 && ch != 0x09 && ch != 0x0a) ||
  656. ch == 0x7f || ((ch & 0x80) && ch < 0xa0)) {
  657. unconv_num++;
  658. continue;
  659. }
  660. *((unsigned char *) string_ptr++) = ch;
  661. str_len--;
  662. }
  663. *from_left -= csptr - *((char **) from);
  664. *from = (XPointer) csptr;
  665. *to_left -= string_ptr - *((char **) to);
  666. *to = (XPointer) string_ptr;
  667. return unconv_num;
  668. }
  669. static void
  670. close_converter(XlcConv conv)
  671. {
  672. if (conv->state)
  673. Xfree((char *) conv->state);
  674. Xfree((char *) conv);
  675. }
  676. static XlcConv
  677. create_conv(XlcConvMethods methods)
  678. {
  679. XlcConv conv;
  680. conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
  681. if (conv == NULL)
  682. return (XlcConv) NULL;
  683. conv->state = (XPointer) Xmalloc(sizeof(StateRec));
  684. if (conv->state == NULL) {
  685. close_converter(conv);
  686. return (XlcConv) NULL;
  687. }
  688. conv->methods = methods;
  689. init_state(conv);
  690. return conv;
  691. }
  692. static XlcConvMethodsRec cttocs_methods = {
  693. close_converter,
  694. cttocs,
  695. init_state
  696. } ;
  697. static XlcConv
  698. open_cttocs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  699. {
  700. return create_conv(&cttocs_methods);
  701. }
  702. static XlcConvMethodsRec cstoct_methods = {
  703. close_converter,
  704. cstoct,
  705. init_state
  706. } ;
  707. static XlcConv
  708. open_cstoct(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  709. {
  710. return create_conv(&cstoct_methods);
  711. }
  712. static XlcConvMethodsRec strtocs_methods = {
  713. close_converter,
  714. strtocs,
  715. init_state
  716. } ;
  717. static XlcConv
  718. open_strtocs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  719. {
  720. return create_conv(&strtocs_methods);
  721. }
  722. static XlcConvMethodsRec cstostr_methods = {
  723. close_converter,
  724. cstostr,
  725. init_state
  726. } ;
  727. static XlcConv
  728. open_cstostr(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  729. {
  730. return create_conv(&cstostr_methods);
  731. }
  732. static void
  733. init_converter(void)
  734. {
  735. _fallcSetConverter((XLCd) NULL, XlcNCompoundText, (XLCd) NULL, XlcNCharSet,
  736. open_cttocs);
  737. _fallcSetConverter((XLCd) NULL, XlcNString, (XLCd) NULL, XlcNCharSet,
  738. open_strtocs);
  739. _fallcSetConverter((XLCd) NULL, XlcNCharSet, (XLCd) NULL, XlcNCompoundText,
  740. open_cstoct);
  741. _fallcSetConverter((XLCd) NULL, XlcNCharSet, (XLCd) NULL, XlcNString,
  742. open_cstostr);
  743. }