home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xlc_CT.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  23KB  |  943 lines

  1. /* $TOG: lcCT.c /main/17 1998/06/18 13:17:06 kaleb $ */
  2. /*
  3.  * Copyright 1992, 1993 by TOSHIBA Corp.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose and without fee is hereby granted, provided
  7.  * that the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of TOSHIBA not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission. TOSHIBA make no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as is"
  13.  * without express or implied warranty.
  14.  *
  15.  * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17.  * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  *
  23.  * Author: Katsuhisa Yano    TOSHIBA Corp.
  24.  *                   mopi@osa.ilab.toshiba.co.jp
  25.  */
  26. /*
  27.  * Copyright 1995 by FUJITSU LIMITED
  28.  * This is source code modified by FUJITSU LIMITED under the Joint
  29.  * Development Agreement for the CDE/Motif PST.
  30.  *
  31.  * Modifier: Takanori Tateno   FUJITSU LIMITED
  32.  *
  33.  */
  34. /* $XFree86: xc/lib/X11/lcCT.c,v 3.5.2.4 1998/10/21 06:40:39 dawes Exp $ */
  35.  
  36. #include "Xlib_private.h"
  37. #include "XlcPubI.h"
  38. #include <X11/Xos.h>
  39. #include <stdio.h>
  40.  
  41. typedef struct _StateRec {
  42.     XlcCharSet charset;
  43.     XlcCharSet GL_charset;
  44.     XlcCharSet GR_charset;
  45.     XlcCharSet ext_seg_charset;
  46.     int ext_seg_left;
  47. } StateRec, *State;
  48.  
  49. typedef struct _CTDataRec {
  50.     char *name;
  51.     char *encoding;        /* Compound Text encoding */
  52. } CTDataRec, *CTData;
  53.  
  54. typedef struct _CTInfoRec {
  55.     XlcCharSet charset;
  56.     int encoding_len;
  57.     char *encoding;        /* Compound Text encoding */
  58.     int ext_segment_len;
  59.     char *ext_segment;        /* extended segment */
  60.     struct _CTInfoRec *next;
  61. } CTInfoRec, *CTInfo;
  62.  
  63. static CTDataRec default_ct_data[] =
  64. {
  65.     { "ISO8859-1:GL", "\033(B" },
  66.     { "ISO8859-1:GR", "\033-A" },
  67.     { "ISO8859-2:GR", "\033-B" },
  68.     { "ISO8859-3:GR", "\033-C" },
  69.     { "ISO8859-4:GR", "\033-D" },
  70.     { "ISO8859-7:GR", "\033-F" },
  71.     { "ISO8859-6:GR", "\033-G" },
  72.     { "ISO8859-8:GR", "\033-H" },
  73.     { "ISO8859-5:GR", "\033-L" },
  74.     { "ISO8859-9:GR", "\033-M" },
  75.     { "ISO8859-10:GR", "\033-V" },
  76.     { "JISX0201.1976-0:GL", "\033(J" },
  77.     { "JISX0201.1976-0:GR", "\033)I" },
  78.  
  79.     { "GB2312.1980-0:GL", "\033$(A" },
  80.     { "GB2312.1980-0:GR", "\033$)A" },
  81.     { "JISX0208.1983-0:GL", "\033$(B" },
  82.     { "JISX0208.1983-0:GR", "\033$)B" },
  83.     { "KSC5601.1987-0:GL", "\033$(C" },
  84.     { "KSC5601.1987-0:GR", "\033$)C" },
  85. #ifdef notdef
  86.     { "JISX0212.1990-0:GL", "\033$(D" },
  87.     { "JISX0212.1990-0:GR", "\033$)D" },
  88.     { "CNS11643.1986-1:GL", "\033$(G" },
  89.     { "CNS11643.1986-1:GR", "\033$)G" },
  90.     { "CNS11643.1986-2:GL", "\033$(H" },
  91.     { "CNS11643.1986-2:GR", "\033$)H" },
  92. #endif
  93.     { "TIS620.2533-1:GR", "\033-T"},
  94.     { "ISO10646-1", "\033%B"},
  95.     /* Non-Standard Character Set Encodings */
  96.     { "KOI8-R:GR", "\033%/1\200\210koi8-r\002"},
  97.     { "ISO8859-15:GR", "\033%/1\200\213iso8859-15\002"},
  98. } ; 
  99.  
  100. #define XctC0        0x0000
  101. #define XctHT        0x0009
  102. #define XctNL        0x000a
  103. #define XctESC        0x001b
  104. #define XctGL        0x0020
  105. #define XctC1        0x0080
  106. #define XctCSI        0x009b
  107. #define XctGR        0x00a0
  108.  
  109. #define XctCntrlFunc    0x0023
  110. #define XctMB        0x0024
  111. #define XctOtherCoding    0x0025
  112. #define XctGL94        0x0028
  113. #define XctGR94        0x0029
  114. #define XctGR96        0x002d
  115. #define XctNonStandard    0x002f
  116. #define XctIgnoreExt    0x0030
  117. #define XctNotIgnoreExt    0x0031
  118. #define XctLeftToRight    0x0031
  119. #define XctRightToLeft    0x0032
  120. #define XctDirection    0x005d
  121. #define XctDirectionEnd    0x005d
  122.  
  123. #define XctGL94MB    0x2428
  124. #define XctGR94MB    0x2429
  125. #define XctExtSeg    0x252f
  126. #define XctOtherSeg    0x2f00
  127.  
  128. #define XctESCSeq    0x1b00
  129. #define XctCSISeq    0x9b00
  130.  
  131. #define SKIP_I(str)    while (*(str) >= 0x20 && *(str) <=  0x2f) (str)++;
  132. #define SKIP_P(str)    while (*(str) >= 0x30 && *(str) <=  0x3f) (str)++;
  133.  
  134. typedef struct {
  135.     XlcSide side;
  136.     int char_size;
  137.     int set_size;
  138.     int ext_seg_length;
  139.     int version;
  140.     CTInfo ct_info;
  141. } CTParseRec, *CTParse;
  142.  
  143. CTDataRec *default_ct_data_list()
  144. {
  145.     return(default_ct_data);
  146. }
  147.  
  148. size_t default_ct_data_list_num()
  149. {
  150.     size_t num = sizeof(default_ct_data) / sizeof(CTDataRec);
  151.     return(num);
  152. }
  153.  
  154. static CTInfo ct_list = NULL;
  155.  
  156. static CTInfo
  157. _XlcGetCTInfoFromEncoding(encoding, length)
  158.     register char *encoding;
  159.     register int length;
  160. {
  161.     DBUG_ENTER("_XlcGetCTInfoFromEncoding")
  162.     register CTInfo ct_info;
  163.  
  164.     for (ct_info = ct_list; ct_info; ct_info = ct_info->next) {
  165.     if (length >= ct_info->encoding_len) {
  166.         if (ct_info->ext_segment) {
  167.         if (!strncmp(ct_info->encoding, encoding, 4) &&
  168.             !strncmp(ct_info->ext_segment, encoding + 6,
  169.                  ct_info->ext_segment_len))
  170.             DBUG_RETURN(ct_info);
  171.         } else if (!strncmp(ct_info->encoding, encoding,
  172.                 ct_info->encoding_len)) {
  173.         DBUG_RETURN(ct_info);
  174.         }
  175.     }
  176.     }
  177.  
  178.     DBUG_RETURN((CTInfo) NULL);
  179. }
  180.  
  181. static unsigned int
  182. _XlcParseCT(parse, text, length)
  183.     register CTParse parse;
  184.     char **text;
  185.     int *length;
  186. {
  187.     DBUG_ENTER("_XlcParseCT")
  188.     unsigned int ret = 0;
  189.     unsigned char ch;
  190.     register unsigned char *str = (unsigned char *) *text;
  191.  
  192.     bzero((char *) parse, sizeof(CTParseRec));
  193.  
  194.     switch (ch = *str++) {
  195.     case XctESC:
  196.         if (*str == XctOtherCoding && *(str + 1) == XctNonStandard
  197.         && *(str + 2) >= 0x30 && *(str + 2) <= 0x3f && *length >= 6) {
  198.  
  199.         /* non-standard encodings */
  200.         parse->side = XlcGLGR;
  201.         parse->set_size = 0;
  202.         str += 2;
  203.         if (*str <= 0x34) {
  204.             parse->char_size = *str - 0x30;
  205.             if (parse->char_size == 0) parse->char_size = 1;
  206.             ret = XctExtSeg;
  207.             parse->ct_info = _XlcGetCTInfoFromEncoding(*text, *length);
  208.         } else
  209.             ret = XctOtherSeg;
  210.         str++;
  211.         parse->ext_seg_length = (*str - 128) * 128 + *(str + 1) - 128;
  212.         str += 2;
  213.  
  214.         goto done;
  215.         } else if (*str == XctCntrlFunc && *length >= 4 &&
  216.                *(str + 1) >= 0x20 && *(str + 1) <= 0x2f &&
  217.                (*(str + 2) == XctIgnoreExt ||
  218.             *(str + 2) == XctNotIgnoreExt)) {
  219.         
  220.         /* ignore extension or not */
  221.         str++;
  222.         parse->version = *str++ - 0x20;
  223.         ret = *str++;
  224.  
  225.         goto done;
  226.         }
  227.         
  228.         if (*str == XctMB) {    /* multiple-byte sets */
  229.         parse->char_size = 2;
  230.         str++;
  231.         } else
  232.         parse->char_size = 1;
  233.     
  234.         switch (*str) {
  235.         case XctGL94:
  236.             parse->side = XlcGL;
  237.             parse->set_size = 94;
  238.             ret = (parse->char_size == 1) ? XctGL94 : XctGL94MB;
  239.             break;
  240.         case XctGR94:
  241.             parse->side = XlcGR;
  242.             parse->set_size = 94;
  243.             ret = (parse->char_size == 1) ? XctGR94 : XctGR94MB;
  244.             break;
  245.         case XctGR96:
  246.             if (parse->char_size == 1) {
  247.             parse->side = XlcGR;
  248.             parse->set_size = 96;
  249.             ret = XctGR96;
  250.             }
  251.             break;
  252.         }
  253.         if (ret) {
  254.         str++;
  255.         if (*str >= 0x24 && *str <= 0x2f) {    /* non-standard */
  256.             ret = 0;
  257.             str++;
  258.         }
  259.         }
  260.  
  261.         SKIP_I(str)
  262.  
  263.         if (ret && *str < 0x40)            /* non-standard */
  264.         ret = 0;
  265.  
  266.         if (*str < 0x30 || *str > 0x7e || (char *) str - *text >= *length)
  267.         break;
  268.         
  269.         if (ret == 0)
  270.         ret = XctESCSeq;
  271.         else {
  272.         if (parse->char_size == 2) {
  273.             if (*str >= 0x70)
  274.             parse->char_size = 4;
  275.             else if (*str >= 0x60)
  276.             parse->char_size = 3;
  277.         }
  278.         parse->ct_info = _XlcGetCTInfoFromEncoding(*text, *length);
  279.         }
  280.         str++;
  281.         goto done;
  282.     case XctCSI:
  283.         /* direction */
  284.         if (*str == XctLeftToRight && *(str + 1) == XctDirection) {
  285.         ret = XctLeftToRight;
  286.         str += 2;
  287.         goto done;
  288.         } else if (*str == XctRightToLeft && *(str + 1) == XctDirection) {
  289.         ret = XctRightToLeft;
  290.         str += 2;
  291.         goto done;
  292.         } else if (*str == XctDirectionEnd) {
  293.         ret = XctDirectionEnd;
  294.         str++;
  295.         goto done;
  296.         }
  297.  
  298.         SKIP_P(str)
  299.         SKIP_I(str)
  300.  
  301.         if (*str < 0x40 && *str > 0x7e)
  302.         break;
  303.  
  304.         ret = XctCSISeq;
  305.         str++;
  306.         goto done;
  307.     }
  308.  
  309.     if (ch & 0x80) {
  310.     if (ch < 0xa0)
  311.         ret = XctC1;
  312.     else
  313.         ret = XctGR;
  314.     } else {
  315.     if (ch == XctHT || ch == XctNL)
  316.         ret = ch;
  317.     else if (ch < 0x20)
  318.         ret = XctC0;
  319.     else
  320.         ret = XctGL;
  321.     }
  322.  
  323.     DBUG_RETURN(ret);
  324.  
  325. done:
  326.     *length -= (char *) str - *text;
  327.     *text = (char *) str;
  328.  
  329.     DBUG_RETURN(ret);
  330. }
  331.  
  332. XlcCharSet
  333. _XlcAddCT(name, encoding)
  334.     _Xconst char *name;
  335.     char *encoding;
  336. {
  337.     DBUG_ENTER("_XlcAddCT")
  338.     CTInfo ct_info;
  339.     XlcCharSet charset;
  340.     CTParseRec parse;
  341.     char *ct_ptr = encoding;
  342.     int length;
  343.     unsigned int type;
  344.  
  345.     length = strlen(encoding);
  346.  
  347.     switch (type = _XlcParseCT(&parse, &ct_ptr, &length)) {
  348.     case XctExtSeg:
  349.     case XctGL94:
  350.     case XctGL94MB:
  351.     case XctGR94:
  352.     case XctGR94MB:
  353.     case XctGR96:
  354.         if (parse.ct_info) {    /* existed */
  355.         charset = parse.ct_info->charset;
  356.         DBUG_RETURN(charset);
  357.         }
  358.         break;
  359.     default:
  360.         DBUG_RETURN((XlcCharSet) NULL);
  361.     }
  362.  
  363.     charset = _XlcCreateDefaultCharSet(name, encoding);
  364.     if (charset == NULL)
  365.     DBUG_RETURN((XlcCharSet) NULL);
  366.     _XlcAddCharSet(charset);
  367.  
  368.     ct_info = (CTInfo) Xmalloc(sizeof(CTInfoRec));
  369.     if (ct_info == NULL)
  370.     DBUG_RETURN((XlcCharSet) NULL);
  371.     
  372.     ct_info->charset = charset;
  373.     ct_info->encoding = charset->ct_sequence;
  374.     ct_info->encoding_len = strlen(ct_info->encoding);
  375.     if (type == XctExtSeg) {
  376.     ct_info->ext_segment = ct_info->encoding + 6;
  377.     ct_info->ext_segment_len = strlen(ct_info->ext_segment);
  378.     } else {
  379.     ct_info->ext_segment = NULL;
  380.     ct_info->ext_segment_len = 0;
  381.     }
  382.     ct_info->next = ct_list;
  383.     ct_list = ct_info;
  384.  
  385.     DBUG_RETURN(charset);
  386. }
  387.  
  388. static CTInfo
  389. _XlcGetCTInfoFromCharSet(charset)
  390.     register XlcCharSet charset;
  391. {
  392.     DBUG_ENTER("_XlcGetCTInfoFromCharSet")
  393.     register CTInfo ct_info;
  394.  
  395.     for (ct_info = ct_list; ct_info; ct_info = ct_info->next)
  396.     if (ct_info->charset == charset)
  397.         DBUG_RETURN(ct_info);
  398.  
  399.     DBUG_RETURN((CTInfo) NULL);
  400. }
  401.  
  402. Bool
  403. _XlcParseCharSet(charset)
  404.     XlcCharSet charset;
  405. {
  406.     DBUG_ENTER("_XlcParseCharSet")
  407.     CTParseRec parse;
  408.     char *ptr, *bufp, buf[BUFSIZ];
  409.     int length;
  410.  
  411.     if (charset->ct_sequence == NULL)
  412.     DBUG_RETURN(False);
  413.  
  414.     if (charset->name && strlen(charset->name) >= sizeof(buf))
  415.     DBUG_RETURN(False);
  416.  
  417.     ptr = charset->ct_sequence;
  418.     length = strlen(ptr);
  419.  
  420.     (void) _XlcParseCT(&parse, &ptr, &length);
  421.     
  422.     if (charset->name) {
  423.     charset->xrm_name = XrmStringToQuark(charset->name);
  424.  
  425.     if ((length = strlen (charset->name)) < sizeof buf) bufp = buf;
  426.     else bufp = Xmalloc (length + 1);
  427.  
  428.     if (bufp == NULL)
  429.         DBUG_RETURN(False);
  430.     strcpy(bufp, charset->name);
  431.     if (ptr = strchr(bufp, ':'))
  432.         *ptr = '\0';
  433.     charset->xrm_encoding_name = XrmStringToQuark(bufp);
  434.     if (bufp != buf) Xfree (bufp);
  435.     charset->encoding_name = XrmQuarkToString(charset->xrm_encoding_name);
  436.     } else {
  437.     charset->xrm_name = 0;
  438.     charset->encoding_name = NULL;
  439.     charset->xrm_encoding_name = 0;
  440.     }
  441.  
  442.     charset->side = parse.side;
  443.     charset->char_size = parse.char_size;
  444.     charset->set_size = parse.set_size;
  445.  
  446.     DBUG_RETURN(True);
  447. }
  448.  
  449. static void init_converter();
  450.  
  451. Bool
  452. _XlcInitCTInfo()
  453. {
  454.     DBUG_ENTER("_XlcInitCTInfo")
  455.     register XlcCharSet charset;
  456.     register CTData ct_data;
  457.     register int num;
  458.  
  459.     if (ct_list == NULL) {
  460.     num = sizeof(default_ct_data) / sizeof(CTDataRec);
  461.     for (ct_data = default_ct_data; num-- > 0; ct_data++) {
  462.         charset = _XlcAddCT(ct_data->name, ct_data->encoding);
  463.         if (charset == NULL)
  464.         continue;
  465.     }
  466.     init_converter();
  467.     }
  468.  
  469.     DBUG_RETURN(True);
  470. }
  471.  
  472.  
  473. static int
  474. _XlcCheckCTSequence(state, ctext, ctext_len)
  475.     State state;
  476.     char **ctext;
  477.     int *ctext_len;
  478. {
  479.     DBUG_ENTER("_XlcCheckCTSequence")
  480.     XlcCharSet charset;
  481.     CTParseRec parse;
  482.     CTInfo ct_info;
  483.     int length;
  484.  
  485.     _XlcParseCT(&parse, ctext, ctext_len);
  486.  
  487.     ct_info = parse.ct_info;
  488.     if (parse.ext_seg_length > 0) {    /* XctExtSeg or XctOtherSeg */
  489.     if (ct_info) {
  490.         length = ct_info->ext_segment_len;
  491.         *ctext += length;
  492.         *ctext_len -= length;
  493.         state->ext_seg_left = parse.ext_seg_length - length;
  494.         state->ext_seg_charset = ct_info->charset;
  495.     } else {
  496.         state->ext_seg_left = parse.ext_seg_length;
  497.         state->ext_seg_charset = NULL;
  498.     }
  499.     } else if (ct_info) {
  500.     if (charset = ct_info->charset) {
  501.         if (charset->side == XlcGL)
  502.         state->GL_charset = charset;
  503.         else if (charset->side == XlcGR)
  504.         state->GR_charset = charset;
  505.     }
  506.     }
  507.  
  508.     DBUG_RETURN(0);
  509. }
  510.  
  511.  
  512. static void
  513. init_state(conv)
  514.     XlcConv conv;
  515. {
  516.     DBUG_ENTER("init_state")
  517.     State state = (State) conv->state;
  518.     static XlcCharSet GL_charset = NULL;
  519.     static XlcCharSet GR_charset = NULL;
  520.  
  521.     if (GL_charset == NULL) {
  522.     GL_charset = _XlcGetCharSet("ISO8859-1:GL");
  523.     GR_charset = _XlcGetCharSet("ISO8859-1:GR");
  524.     }
  525.  
  526.     state->GL_charset = state->charset = GL_charset;
  527.     state->GR_charset = GR_charset;
  528.     state->ext_seg_charset = NULL;
  529.     state->ext_seg_left = 0;
  530.     DBUG_VOID_RETURN;
  531. }
  532.  
  533. static int
  534. cttocs(conv, from, from_left, to, to_left, args, num_args)
  535.     XlcConv conv;
  536.     XPointer *from;
  537.     int *from_left;
  538.     XPointer *to;
  539.     int *to_left;
  540.     XPointer *args;
  541.     int num_args;
  542. {
  543.     DBUG_ENTER("cttocs")
  544.     register State state = (State) conv->state;
  545.     register unsigned char ch;
  546.     int length;
  547.     XlcCharSet charset = NULL;
  548.     char *ctptr, *bufptr;
  549.     int ctext_len, buf_len;
  550.  
  551.     ctptr = *((char **) from);
  552.     bufptr = *((char **) to);
  553.     ctext_len = *from_left;
  554.     buf_len = *to_left;
  555.  
  556.     while (ctext_len > 0 && buf_len > 0) {
  557.     if (state->ext_seg_left > 0) {
  558.         length = min(state->ext_seg_left, ctext_len);
  559.         length = min(length, buf_len);
  560.  
  561.         ctext_len -= length;
  562.         state->ext_seg_left -= length;
  563.  
  564.         if (state->ext_seg_charset) {
  565.         charset = state->ext_seg_charset;
  566.         buf_len -= length;
  567.         if (charset->side == XlcGL) {
  568.             while (length-- > 0)
  569.             *bufptr++ = *ctptr++ & 0x7f;
  570.         } else if (charset->side == XlcGR) {
  571.             while (length-- > 0)
  572.             *bufptr++ = *ctptr++ | 0x80;
  573.         } else {
  574.             while (length-- > 0)
  575.             *bufptr++ = *ctptr++;
  576.         }
  577.  
  578.         if (state->ext_seg_left < 1)
  579.             state->ext_seg_charset = NULL;
  580.         }
  581.         break;
  582.     }
  583.     ch = *((unsigned char *) ctptr);
  584.     if (ch == 0x1b || ch == 0x9b) {
  585.         length = _XlcCheckCTSequence(state, &ctptr, &ctext_len);
  586.         if (length < 0)
  587.         DBUG_RETURN(-1);
  588.         if (state->ext_seg_left > 0 && charset)
  589.         break;
  590.     } else {
  591.         if (charset) {
  592.         if (charset != (ch & 0x80 ? state->GR_charset :
  593.                 state->GL_charset))
  594.             break;
  595.         } else
  596.         charset = ch & 0x80 ? state->GR_charset : state->GL_charset;
  597.  
  598.         if ((ch < 0x20 && ch != '\0' && ch != '\n' && ch != '\t') ||
  599.             (ch >= 0x80 && ch < 0xa0))
  600.         DBUG_RETURN(-1);
  601.  
  602.         *bufptr++ = *ctptr++;
  603.         ctext_len--;
  604.         buf_len--;
  605.     }
  606.     }
  607.  
  608.     if (charset)
  609.     state->charset = charset;
  610.     if (num_args > 0)
  611.     *((XlcCharSet *) args[0]) = state->charset;
  612.  
  613.     *from_left -= ctptr - *((char **) from);
  614.     *from = (XPointer) ctptr;
  615.  
  616.     *to_left -= bufptr - *((char **) to);
  617.     *to = (XPointer) bufptr;
  618.  
  619.     DBUG_RETURN(0);
  620. }
  621.  
  622. static int
  623. cstoct(conv, from, from_left, to, to_left, args, num_args)
  624.     XlcConv conv;
  625.     XPointer *from;
  626.     int *from_left;
  627.     XPointer *to;
  628.     int *to_left;
  629.     XPointer *args;
  630.     int num_args;
  631. {
  632.     DBUG_ENTER("cstoct")
  633.     State state = (State) conv->state;
  634.     XlcSide side;
  635.     unsigned char min_ch, max_ch;
  636.     register unsigned char ch;
  637.     int length;
  638.     CTInfo ct_info;
  639.     XlcCharSet charset;
  640.     char *csptr, *ctptr;
  641.     int csstr_len, ct_len;
  642.  
  643.     if (num_args < 1)
  644.     return -1;
  645.     
  646.     csptr = *((char **) from);
  647.     ctptr = *((char **) to);
  648.     csstr_len = *from_left;
  649.     ct_len = *to_left;
  650.     
  651.     charset = (XlcCharSet) args[0];
  652.  
  653.     ct_info = _XlcGetCTInfoFromCharSet(charset);
  654.     if (ct_info == NULL)
  655.     DBUG_RETURN(-1);
  656.  
  657.     side = charset->side;
  658.  
  659.     if (ct_info->ext_segment) {
  660.     if (charset != state->ext_seg_charset && state->ext_seg_left < 1) {
  661.         length = ct_info->encoding_len;
  662.         if (ct_len < length)
  663.         DBUG_RETURN(-1);
  664.         strcpy(ctptr, ct_info->encoding);
  665.         ctptr[4] = ((ct_info->ext_segment_len + csstr_len) / 128) | 0x80;
  666.         ctptr[5] = ((ct_info->ext_segment_len + csstr_len) % 128) | 0x80;
  667.         ctptr += length;
  668.         ct_len -= length;
  669.         state->ext_seg_left = csstr_len;
  670.     }
  671.     length = min(state->ext_seg_left, csstr_len);
  672.     state->ext_seg_left -= length;
  673.  
  674.     if (side == XlcGL) {
  675.         while (length-- > 0)
  676.         *ctptr++ = *csptr++ & 0x7f;
  677.     } else if (side == XlcGR) {
  678.         while (length-- > 0)
  679.         *ctptr++ = *csptr++ | 0x80;
  680.     } else {
  681.         while (length-- > 0)
  682.         *ctptr++ = *csptr++;
  683.     }
  684.     state->ext_seg_charset = (state->ext_seg_left > 0) ? charset : NULL;
  685.     } else {
  686.     if ((side == XlcGR && charset != state->GR_charset) ||
  687.         (side == XlcGL && charset != state->GL_charset)) {
  688.  
  689.         ct_len -= ct_info->encoding_len;
  690.         if (ct_len < 0)
  691.         DBUG_RETURN(-1);
  692.         strcpy(ctptr, ct_info->encoding);
  693.         ctptr += ct_info->encoding_len;
  694.     }
  695.  
  696.     min_ch = 0x20;
  697.     max_ch = 0x7f;
  698.  
  699.     if (charset->set_size == 94) {
  700.         max_ch--;
  701.         if (charset->char_size > 1 || side == XlcGR)
  702.         min_ch++;
  703.     }
  704.  
  705.     while (csstr_len > 0 && ct_len > 0) {
  706.         ch = *((unsigned char *) csptr++) & 0x7f;
  707.         if (ch < min_ch || ch > max_ch)
  708.         if (ch != 0x00 && ch != 0x09 && ch != 0x0a && ch != 0x1b)
  709.             continue;    /* XXX */
  710.         if (side == XlcGL)
  711.         *ctptr++ = ch & 0x7f;
  712.         else if (side == XlcGR)
  713.         *ctptr++ = ch | 0x80;
  714.         else
  715.         *ctptr++ = ch;
  716.         csstr_len--;
  717.         ct_len--;
  718.     }
  719.     if (side == XlcGR)
  720.         state->GR_charset = charset;
  721.     else if (side == XlcGL)
  722.         state->GL_charset = charset;
  723.     }
  724.  
  725.     *from_left -= csptr - *((char **) from);
  726.     *from = (XPointer) csptr;
  727.  
  728.     *to_left -= ctptr - *((char **) to);
  729.     *to = (XPointer) ctptr;
  730.  
  731.     DBUG_RETURN(0);
  732. }
  733.  
  734. static int
  735. strtocs(conv, from, from_left, to, to_left, args, num_args)
  736.     XlcConv conv;
  737.     XPointer *from;
  738.     int *from_left;
  739.     XPointer *to;
  740.     int *to_left;
  741.     XPointer *args;
  742.     int num_args;
  743. {
  744.     DBUG_ENTER("strtocs")
  745.     State state = (State) conv->state;
  746.     register char *src, *dst;
  747.     unsigned char side;
  748.     register int length;
  749.  
  750.     src = (char *) *from;
  751.     dst = (char *) *to;
  752.  
  753.     length = min(*from_left, *to_left);
  754.     side = *((unsigned char *) src) & 0x80;
  755.  
  756.     while (side == (*((unsigned char *) src) & 0x80) && length-- > 0)
  757.     *dst++ = *src++;
  758.     
  759.     *from_left -= src - (char *) *from;
  760.     *from = (XPointer) src;
  761.     *to_left -= dst - (char *) *to;
  762.     *to = (XPointer) dst;
  763.  
  764.     if (num_args > 0)
  765.     *((XlcCharSet *)args[0]) = side ? state->GR_charset : state->GL_charset;
  766.  
  767.     DBUG_RETURN(0);
  768. }
  769.  
  770. static int
  771. cstostr(conv, from, from_left, to, to_left, args, num_args)
  772.     XlcConv conv;
  773.     XPointer *from;
  774.     int *from_left;
  775.     XPointer *to;
  776.     int *to_left;
  777.     XPointer *args;
  778.     int num_args;
  779. {
  780.     DBUG_ENTER("cstostr")
  781.     State state = (State) conv->state;
  782.     char *csptr, *string_ptr;
  783.     int csstr_len, str_len;
  784.     unsigned char ch;
  785.     int unconv_num = 0;
  786.  
  787.     if (num_args < 1 || (state->GL_charset != (XlcCharSet) args[0] &&
  788.     state->GR_charset != (XlcCharSet) args[0]))
  789.     DBUG_RETURN(-1);
  790.     
  791.     csptr = *((char **) from);
  792.     string_ptr = *((char **) to);
  793.     csstr_len = *from_left;
  794.     str_len = *to_left;
  795.  
  796.     while (csstr_len-- > 0 && str_len > 0) {
  797.     ch = *((unsigned char *) csptr++);
  798.     if ((ch < 0x20 && ch != 0x00 && ch != 0x09 && ch != 0x0a) ||
  799.         ch == 0x7f || ((ch & 0x80) && ch < 0xa0)) {
  800.         unconv_num++;
  801.         continue;
  802.     }
  803.     *((unsigned char *) string_ptr++) = ch;
  804.     str_len--;
  805.     }
  806.  
  807.     *from_left -= csptr - *((char **) from);
  808.     *from = (XPointer) csptr;
  809.  
  810.     *to_left -= string_ptr - *((char **) to);
  811.     *to = (XPointer) string_ptr;
  812.  
  813.     DBUG_RETURN(unconv_num);
  814. }
  815.  
  816.  
  817. static void
  818. close_converter(conv)
  819.     XlcConv conv;
  820. {
  821.     DBUG_ENTER("close_converter")
  822.     if (conv->state)
  823.     Xfree((char *) conv->state);
  824.  
  825.     Xfree((char *) conv);
  826.     DBUG_VOID_RETURN;
  827. }
  828.  
  829. static XlcConv
  830. create_conv(methods)
  831.     XlcConvMethods methods;
  832. {
  833.     DBUG_ENTER("create_conv")
  834.     register XlcConv conv;
  835.  
  836.     conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
  837.     if (conv == NULL)
  838.     DBUG_RETURN((XlcConv) NULL);
  839.  
  840.     conv->state = (XPointer) Xmalloc(sizeof(StateRec));
  841.     if (conv->state == NULL)
  842.     goto err;
  843.     
  844.     conv->methods = methods;
  845.  
  846.     init_state(conv);
  847.  
  848.     DBUG_RETURN(conv);
  849.  
  850. err:
  851.     close_converter(conv);
  852.  
  853.     DBUG_RETURN((XlcConv) NULL);
  854. }
  855.  
  856. static XlcConvMethodsRec cttocs_methods = {
  857.     close_converter,
  858.     cttocs,
  859.     init_state
  860. } ;
  861.  
  862. static XlcConv
  863. open_cttocs(from_lcd, from_type, to_lcd, to_type)
  864.     XLCd from_lcd;
  865.     char *from_type;
  866.     XLCd to_lcd;
  867.     char *to_type;
  868. {
  869.     DBUG_ENTER("open_cttocs")
  870.     XlcConv result = create_conv(&cttocs_methods);
  871.     DBUG_RETURN(result);
  872. }
  873.  
  874. static XlcConvMethodsRec cstoct_methods = {
  875.     close_converter,
  876.     cstoct,
  877.     init_state
  878. } ;
  879.  
  880. static XlcConv
  881. open_cstoct(from_lcd, from_type, to_lcd, to_type)
  882.     XLCd from_lcd;
  883.     char *from_type;
  884.     XLCd to_lcd;
  885.     char *to_type;
  886. {
  887.     DBUG_ENTER("open_cstoct")
  888.     XlcConv result = create_conv(&cstoct_methods);
  889.     DBUG_RETURN(result);
  890. }
  891.  
  892. static XlcConvMethodsRec strtocs_methods = {
  893.     close_converter,
  894.     strtocs,
  895.     init_state
  896. } ;
  897.  
  898. static XlcConv
  899. open_strtocs(from_lcd, from_type, to_lcd, to_type)
  900.     XLCd from_lcd;
  901.     char *from_type;
  902.     XLCd to_lcd;
  903.     char *to_type;
  904. {
  905.     DBUG_ENTER("open_strtocs")
  906.     XlcConv result = create_conv(&strtocs_methods);
  907.     DBUG_RETURN(result);
  908. }
  909.  
  910. static XlcConvMethodsRec cstostr_methods = {
  911.     close_converter,
  912.     cstostr,
  913.     init_state
  914. } ;
  915.  
  916. static XlcConv
  917. open_cstostr(from_lcd, from_type, to_lcd, to_type)
  918.     XLCd from_lcd;
  919.     char *from_type;
  920.     XLCd to_lcd;
  921.     char *to_type;
  922. {
  923.     DBUG_ENTER("open_cstostr")
  924.     XlcConv result = create_conv(&cstostr_methods);
  925.     DBUG_RETURN(result);
  926. }
  927.  
  928. static void
  929. init_converter()
  930. {
  931.     DBUG_ENTER("init_converter")
  932.     _XlcSetConverter((XLCd) NULL, XlcNCompoundText, (XLCd) NULL, XlcNCharSet,
  933.              open_cttocs);
  934.     _XlcSetConverter((XLCd) NULL, XlcNString, (XLCd) NULL, XlcNCharSet,
  935.              open_strtocs);
  936.  
  937.     _XlcSetConverter((XLCd) NULL, XlcNCharSet, (XLCd) NULL, XlcNCompoundText,
  938.              open_cstoct);
  939.     _XlcSetConverter((XLCd) NULL, XlcNCharSet, (XLCd) NULL, XlcNString,
  940.              open_cstostr);
  941.     DBUG_VOID_RETURN;
  942. }
  943.