From c350873c7c977efe5210484f04160be45f84ba7e Mon Sep 17 00:00:00 2001
From: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Date: Fri, 21 Jul 2017 12:31:09 +0200
Subject: Convert nx-X11/lib/ build flow from imake to autotools.

---
 nx-X11/lib/modules/lc/gen/Makefile.am |   27 +
 nx-X11/lib/modules/lc/gen/lcGenConv.c | 3112 +++++++++++++++++++++++++++++++++
 2 files changed, 3139 insertions(+)
 create mode 100644 nx-X11/lib/modules/lc/gen/Makefile.am
 create mode 100644 nx-X11/lib/modules/lc/gen/lcGenConv.c

(limited to 'nx-X11/lib/modules/lc/gen')

diff --git a/nx-X11/lib/modules/lc/gen/Makefile.am b/nx-X11/lib/modules/lc/gen/Makefile.am
new file mode 100644
index 000000000..6106cfd4b
--- /dev/null
+++ b/nx-X11/lib/modules/lc/gen/Makefile.am
@@ -0,0 +1,27 @@
+NULL =
+
+noinst_LTLIBRARIES = libxlibi18n.la
+
+AM_CPPFLAGS =					\
+	-I$(top_srcdir)/include			\
+	-I$(top_srcdir)/include/X11		\
+	-I$(top_builddir)/include		\
+	-I$(top_builddir)/include/X11		\
+	-I$(top_srcdir)/src/xcms		\
+	-I$(top_srcdir)/src/xkb			\
+	-I$(top_srcdir)/src/xlibi18n		\
+	-I$(top_srcdir)/../exports/include	\
+	-D_GNU_SOURCE				\
+	$(NULL)
+
+AM_CFLAGS =					\
+	$(X11_CFLAGS)				\
+	$(BIGFONT_CFLAGS)			\
+	$(CWARNFLAGS)				\
+	$(NULL)
+
+xlibi18n_la_SOURCES =				\
+	lcGenConv.c				\
+	$(NULL)
+
+libxlibi18n_la_SOURCES = $(xlibi18n_la_SOURCES)
diff --git a/nx-X11/lib/modules/lc/gen/lcGenConv.c b/nx-X11/lib/modules/lc/gen/lcGenConv.c
new file mode 100644
index 000000000..799f49a30
--- /dev/null
+++ b/nx-X11/lib/modules/lc/gen/lcGenConv.c
@@ -0,0 +1,3112 @@
+/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Katsuhisa Yano	TOSHIBA Corp.
+ *			   	mopi@osa.ilab.toshiba.co.jp
+ */
+/*
+ *  (c) Copyright 1995 FUJITSU LIMITED
+ *  This is source code modified by FUJITSU LIMITED under the Joint
+ *  Development Agreement for the CDE/Motif PST.
+ *
+ *   Modifier: Masayoshi Shimamura      FUJITSU LIMITED
+ *
+ */
+/*
+ *  2000
+ *  Modifier: Ivan Pascal      The XFree86 Project
+ */
+
+/*
+ * A generic locale loader for all kinds of ISO-2022 based codesets.
+ * Supports: all locales.
+ * How: Provides generic converters for ISO-2022 based codesets. Extensible as
+ *      far as ISO-2022 is extensible: codesets can be given by name in the
+ *      stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff).
+ *      In every chunk between escape sequences, the number of bytes per
+ *      character (char_size) is constant.
+ * Platforms: all systems.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "XlcGeneric.h"
+#include <stdio.h>
+
+#if !defined(X_LOCALE)
+#define STDCVT
+#endif
+
+typedef struct _CTDataRec {
+    const char *name;
+    const char *encoding; /* Compound Text encoding */
+} CTDataRec, *CTData;
+
+static CTDataRec directionality_data[] =
+{
+    { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" },
+    { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" },
+    { "END_OF_STRING", "\233]" },
+};
+
+typedef struct _StateRec {
+    XLCd lcd;
+    /* CT state */
+    XlcCharSet charset;		/* charset of current state */
+    XlcCharSet GL_charset;	/* charset of initial state in GL */
+    XlcCharSet GR_charset;	/* charset of initial state in GR */
+    /* MB shift state */
+    CodeSet  GL_codeset;
+    CodeSet  GR_codeset;
+} StateRec, *State;
+
+#define GR      0x80    /* begins right-side (non-ascii) region */
+#define GL      0x7f    /* ends left-side (ascii) region        */
+#define ESC	0x1b
+#define CSI	0x9b
+#define STX	0x02
+
+#define isrightside(c)   ((c) & GR)
+#define isleftside(c)  (!isrightside(c))
+
+/* Forward declarations for local routines. */
+static int mbstocts (XlcConv conv, XPointer *from, int *from_left,
+		     XPointer *to, int *to_left, XPointer *args, int num_args);
+static int ctstombs (XlcConv conv, XPointer *from, int *from_left,
+		     XPointer *to, int *to_left, XPointer *args, int num_args);
+static int cstombs (XlcConv conv, XPointer *from, int *from_left,
+		    XPointer *to, int *to_left, XPointer *args, int num_args);
+
+/* ------------------------------------------------------------------------- */
+/*				Misc                                         */
+/* ------------------------------------------------------------------------- */
+
+static int
+compare(
+    const char *src,
+    const char *encoding,
+    int length)
+{
+    const char *start = src;
+
+    while (length-- > 0) {
+	if (*src++ != *encoding++)
+	    return 0;
+	if (*encoding == '\0')
+	    return src - start;
+    }
+
+    return 0;
+}
+
+static unsigned long
+conv_to_dest(
+    Conversion conv,
+    unsigned long code)
+{
+    int i;
+    int conv_num = conv->conv_num;
+    FontScope convlist = conv->convlist;
+
+    for (i = 0; i < conv_num; i++) {
+  	if (convlist[i].start <= code && code <= convlist[i].end) {
+	    switch (convlist[i].shift_direction) {
+	    case '+':
+	        return(code + convlist[i].shift);
+	    case '-':
+		return(code - convlist[i].shift);
+            default:
+		return(code);
+	    }
+	}
+    }
+
+    return(code);
+}
+
+static unsigned long
+conv_to_source(
+    Conversion conv,
+    unsigned long code)
+{
+    int i;
+    int conv_num;
+    FontScope convlist;
+    unsigned long start_p;
+    unsigned long start_m;
+    unsigned long end_p;
+    unsigned long end_m;
+
+    if (!conv)
+	return(code);
+
+    conv_num = conv->conv_num;
+    convlist = conv->convlist;
+
+    for (i = 0; i < conv_num; i++) {
+        switch (convlist[i].shift_direction) {
+	case '+':
+            start_p = convlist[i].start + convlist[i].shift;
+            end_p = convlist[i].end + convlist[i].shift;
+	    if (start_p <= code && code <= end_p)
+		return(code - convlist[i].shift);
+            break;
+	case '-':
+            start_m = convlist[i].start - convlist[i].shift;
+            end_m = convlist[i].end - convlist[i].shift;
+	    if (start_m <= code && code <= end_m)
+		return(code + convlist[i].shift);
+            break;
+        default:
+	    continue;
+	}
+    }
+
+    return(code);
+}
+
+static unsigned long
+mb_to_gi(
+    unsigned long mb,
+    CodeSet codeset)
+{
+    int i;
+    unsigned long mb_tmp, mask = 0;
+
+    if (codeset->mbconv) {
+	mb_tmp = conv_to_dest(codeset->mbconv, mb);
+	if (mb_tmp != mb)
+	    return(mb_tmp);
+    }
+
+    if (codeset->side == XlcC0 || codeset->side == XlcGL ||
+	codeset->side == XlcC1 || codeset->side == XlcGR) {
+
+        for (i = 0; i < codeset->length; i++)
+	    mask = (mask << 8) | GL;
+	mb = mb & mask;
+    }
+
+    return(mb);
+}
+
+static unsigned long
+gi_to_mb(
+    unsigned long glyph_index,
+    CodeSet codeset)
+{
+    int i;
+    unsigned long mask = 0;
+
+    if (codeset->side == XlcC1 || codeset->side == XlcGR) {
+        for (i = 0; i < codeset->length; i++)
+	    mask = (mask << 8) | GR;
+	glyph_index = glyph_index | mask;
+    }
+
+    if (codeset->mbconv)
+        return( conv_to_source(codeset->mbconv, glyph_index) );
+
+    return(glyph_index);
+}
+
+static Bool
+gi_to_wc(
+    XLCd lcd,
+    unsigned long glyph_index,
+    CodeSet codeset,
+    wchar_t *wc)
+{
+    unsigned char mask = 0;
+    unsigned long wc_encoding = codeset->wc_encoding;
+    int length = codeset->length;
+    unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
+
+    mask = (1 << wc_shift_bits) - 1 ;
+
+    for (*wc = 0, length--; length >= 0; length--)
+	*wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask);
+
+    *wc = *wc | wc_encoding;
+
+    return(True);
+}
+
+static Bool
+wc_to_gi(
+    XLCd lcd,
+    wchar_t wc,
+    unsigned long *glyph_index,
+    CodeSet *codeset)
+{
+    int i;
+    unsigned char mask = 0;
+    unsigned long wc_encoding;
+    unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask);
+    unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
+    int codeset_num = XLC_GENERIC(lcd, codeset_num);
+    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+
+    wc_encoding = wc & wc_encode_mask;
+    for (*codeset = NULL, i = 0; i < codeset_num; i++) {
+	if (wc_encoding == codeset_list[i]->wc_encoding) {
+	    *codeset = codeset_list[i];
+	    break;
+        }
+    }
+    if (*codeset == NULL)
+	return(False);
+
+    mask = (1 << wc_shift_bits) - 1 ;
+
+    wc = wc & ~wc_encode_mask;
+    for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--)
+	*glyph_index = (*glyph_index << 8) |
+		      ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask );
+
+    return(True);
+}
+
+static CodeSet
+mb_parse_codeset(
+    State state,
+    int num,
+    const char **inbufptr,
+    int *from_left)
+{
+    int len;
+    int from_len = (*from_left) + 1;
+    const char *src = (*inbufptr) - 1;
+    ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list);
+    ParseInfo parse_info;
+    CodeSet codeset;
+
+    for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) {
+       len = compare(src, parse_info->encoding, from_len);
+       if (len > 0) {
+           codeset = parse_info->codeset;
+           if (parse_info->type == E_LSL)
+               state->GL_codeset = codeset;
+           else if (parse_info->type == E_LSR)
+               state->GR_codeset = codeset;
+           --len;
+           *inbufptr += len;
+           *from_left -= len;
+           return codeset;
+       }
+    }
+    return (CodeSet) NULL;
+}
+
+static CodeSet
+byteM_parse_codeset(
+    XLCd lcd,
+    const char *inbufptr)
+{
+    unsigned char ch;
+    CodeSet codeset;
+    ByteInfoList byteM;
+    ByteInfoListRec byteM_rec;
+    ByteInfo byteinfo;
+    ByteInfoRec byteinfo_rec;
+    Bool hit = False;
+    int i, j, k;
+
+    int codeset_num               = XLC_GENERIC(lcd, codeset_num);
+    CodeSet *codeset_list         = XLC_GENERIC(lcd, codeset_list);
+
+    for (i = 0; i < codeset_num; i++) {
+        codeset = codeset_list[i];
+        byteM = codeset->byteM;
+        if (codeset->side != XlcNONE || byteM == NULL)
+	    continue;
+
+        for (j = 0; j < codeset->length; j++) {
+	    ch = *((const unsigned char *)(inbufptr + j));
+	    byteM_rec = byteM[j];
+	    byteinfo = byteM_rec.byteinfo;
+
+	    for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) {
+	        byteinfo_rec = byteinfo[k];
+	        if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) {
+	            hit = True;
+		    break;
+                }
+            }
+
+            if (!hit)
+		break;
+        }
+
+        if (hit)
+	    return(codeset);
+    }
+
+    return(NULL);
+}
+
+#define GLGR_parse_codeset(ch) \
+     (isrightside(ch) ? (state->GR_codeset) : \
+                        (state->GL_codeset) )
+
+static XlcCharSet
+gi_parse_charset(
+    unsigned long glyph_index,
+    CodeSet codeset)
+{
+    int i;
+    XlcCharSet *charset_list = codeset->charset_list;
+    int num_charsets = codeset->num_charsets;
+    ExtdSegment ctextseg = codeset->ctextseg;
+    XlcCharSet charset = NULL;
+    int area_num;
+    FontScope area;
+
+    /* lockup ct sequence */
+    for (i = 0; i < num_charsets; i++) {
+	charset = charset_list[i];
+        if (*charset->ct_sequence != '\0')
+	    break;
+    }
+    if (i >= num_charsets)
+	return(NULL);
+
+    if (charset->source != CSsrcStd)
+        return (charset);
+
+    if (!ctextseg)
+        return(charset);
+
+    area = ctextseg->area;
+    area_num = ctextseg->area_num;
+
+    for (i = 0; i < area_num; i++) {
+
+        if (area[i].start <= glyph_index && glyph_index <= area[i].end) {
+
+	    charset = ctextseg->charset;
+
+            if (*charset->ct_sequence == '\0')
+                return(NULL);
+
+	    break;
+	}
+    }
+
+    return(charset);
+}
+
+static Bool
+ct_parse_csi(
+    const char *inbufptr,
+    int *ctr_seq_len)
+{
+    int i;
+    int num = sizeof(directionality_data) / sizeof(directionality_data[0]);
+
+    for (i = 0; i < num; i++) {
+	if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) )
+	    continue;
+
+	if ( strncmp(inbufptr, directionality_data[i].encoding,
+						*ctr_seq_len) == 0)
+            return(True);
+    }
+
+    return(False);
+}
+
+static int
+cmp_esc_sequence(
+    const char *inbufptr,
+    XlcCharSet charset)
+{
+    int seq_len, name_len, total_len;
+    unsigned char byte_m, byte_l;
+    const char *ct_sequence =  charset->ct_sequence;
+    const char *encoding_name = charset->encoding_name;
+
+    /* check esc sequence */
+    if ( !(seq_len = strlen(ct_sequence) ) )
+	return(0);
+    if ( strncmp(inbufptr, ct_sequence, seq_len) != 0)
+	return(0);
+
+    /* Standard Character Set Encoding ? */
+    if (charset->source == CSsrcStd)
+        return(seq_len);
+
+    /*
+     *   Non-Standard Character Set Encoding
+     *
+     * +--- ---+-----+-----+-----+----   ----+-----+-----+-------   ------+
+     * | ctseq |  M  |  L  |     encoding name     | STX |     contents   |
+     * +--- ---+-----+-----+-----+----   ----+-----+-----+-------   ------+
+     *  4bytes  1byte 1byte     variable length     1byte  variable length
+     * 	                   |                                              |
+     * 	                   +----------------------------------------------+
+     * 	                     rest length  = ((M - 128) * 128) + (L - 128)
+     */
+
+    /* get length of encoding name */
+    inbufptr += seq_len;
+    byte_m = *inbufptr++;
+    byte_l = *inbufptr++;
+    name_len = strlen(encoding_name);
+
+    if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len)
+	return(0);
+
+    if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 )
+	return(0);
+
+    /* check STX (Start of Text) */
+    inbufptr = inbufptr + name_len;
+    if ( *inbufptr != STX )
+	return(0);
+
+    total_len = seq_len + name_len + 3;
+    return(total_len);
+}
+
+static Bool
+ct_parse_charset(
+    XLCd lcd,
+    const char *inbufptr,
+    XlcCharSet *charset,
+    int *ctr_seq_len)
+{
+    int i, j;
+    ExtdSegment ctextseg;
+    int num_charsets;
+    XlcCharSet *charset_list;
+    CodeSet codeset;
+    int codeset_num       = XLC_GENERIC(lcd, codeset_num);
+    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+    int segment_conv_num  = XLC_GENERIC(lcd, segment_conv_num);
+    SegConv segment_conv  = XLC_GENERIC(lcd, segment_conv);
+
+    /* get charset from XLC_XLOCALE by escape sequence */
+
+    for (i = 0; i < codeset_num; i++) {
+	codeset = codeset_list[i];
+
+	num_charsets = codeset->num_charsets;
+	charset_list = codeset->charset_list;
+	ctextseg     = codeset->ctextseg;
+
+	for (j = 0; j < num_charsets; j++) {
+	    *charset = charset_list[j];
+            if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+		return(True);
+	}
+
+	if (ctextseg) {
+	    *charset = ctextseg->charset;
+            if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+		return(True);
+	}
+    }
+
+    /* get charset from XLC_SEGMENTCONVERSION by escape sequence */
+
+    if (!segment_conv)
+	return(False);
+
+    for (i = 0; i < segment_conv_num; i++) {
+	*charset = segment_conv[i].source;
+        if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+	    return(True);
+	*charset = segment_conv[i].dest;
+        if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+	    return(True);
+    }
+
+    return(False);
+}
+
+static Bool
+segment_conversion(
+    XLCd lcd,
+    XlcCharSet *charset,
+    unsigned long *glyph_index)
+{
+    int i;
+    int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num);
+    SegConv segment_conv = XLC_GENERIC(lcd, segment_conv);
+    FontScopeRec range;
+    ConversionRec conv_rec;
+
+    if (!segment_conv)
+	return(True);
+
+    for (i = 0; i < segment_conv_num; i++) {
+	if (segment_conv[i].source == *charset)
+	    break;
+    }
+
+    if (i >= segment_conv_num)
+	return(True);
+
+    range = segment_conv[i].range;
+    if (*glyph_index < range.start || range.end < *glyph_index)
+	return(True);
+
+    *charset = segment_conv[i].dest;
+    conv_rec.conv_num = segment_conv[i].conv_num;
+    conv_rec.convlist = segment_conv[i].conv;
+    *glyph_index = conv_to_dest(&conv_rec, *glyph_index);
+
+    return(True);
+}
+
+static CodeSet
+_XlcGetCodeSetFromName(
+    XLCd lcd,
+    const char *name)
+{
+    int i, j;
+    XlcCharSet charset;
+    int num_charsets;
+    XlcCharSet *charset_list;
+    CodeSet codeset;
+
+    int codeset_num       = XLC_GENERIC(lcd, codeset_num);
+    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+
+    for (i = 0; i < codeset_num; i++) {
+        codeset = codeset_list[i];
+
+        num_charsets = codeset->num_charsets;
+        charset_list = codeset->charset_list;
+
+        for (j = 0; j < num_charsets; j++) {
+            charset = charset_list[j];
+
+            if (!strlen(charset->name))
+                continue;
+            if ( strcmp(charset->name, name) == 0)
+                return(codeset);
+        }
+    }
+
+    return(NULL);
+}
+
+static Bool
+_XlcGetCodeSetFromCharSet(
+    XLCd lcd,
+    XlcCharSet charset,
+    CodeSet *codeset,
+    unsigned long *glyph_index)
+{
+    int j, num;
+    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+    XlcCharSet *charset_list;
+    int codeset_num, num_charsets;
+    Conversion ctconv;
+    unsigned long glyph_index_tmp = 0;
+    ExtdSegment ctextseg;
+
+    codeset_num = XLC_GENERIC(lcd, codeset_num);
+
+    for (num = 0 ; num < codeset_num; num++) {
+        *codeset = codeset_list[num];
+        ctconv = (*codeset)->ctconv;
+	ctextseg = (*codeset)->ctextseg;
+
+        num_charsets = (*codeset)->num_charsets;
+        charset_list = (*codeset)->charset_list;
+
+        glyph_index_tmp = conv_to_source(ctconv, *glyph_index);
+
+        if (charset->source == CSsrcStd) {
+
+            /* Standard Character Set Encoding */
+	    if (glyph_index_tmp == *glyph_index) {
+                for (j = 0; j < num_charsets; j++) {
+                    if (charset_list[j] == charset) {
+                        goto end_loop;
+                    }
+                }
+            }
+
+	} else {
+
+            /* Non-Standard Character Set Encoding */
+            for (j = 0; j < num_charsets; j++) {
+                if (charset_list[j] == charset) {
+                    goto end_loop;
+                }
+            }
+
+            if (glyph_index_tmp != *glyph_index) {
+		if (ctextseg && ctextseg->charset == charset) {
+		    goto end_loop;
+                }
+            }
+
+	}
+
+    }
+
+end_loop:
+    if (num < codeset_num) {
+	*glyph_index = glyph_index_tmp;
+	return(True);
+    }
+
+    return(False);
+}
+
+#define check_string_encoding(codeset)	(codeset->string_encoding)
+
+static void
+output_ulong_value(
+    char *outbufptr,
+    unsigned long code,
+    int length,
+    XlcSide side)
+{
+    int i;
+
+    for (i = (length - 1) * 8; i >= 0; i -= 8) {
+	*outbufptr = ( code >> i) & 0xff;
+
+	if (side == XlcC0 || side == XlcGL) {
+	    *outbufptr = *outbufptr & GL;
+	} else if (side == XlcC1 || side == XlcGR) {
+	    *outbufptr = *outbufptr | GR;
+	}
+
+	outbufptr++;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+/*				Init                                          */
+/* -------------------------------------------------------------------------- */
+
+static XlcCharSet default_GL_charset = 0;
+static XlcCharSet default_GR_charset = 0;
+
+static void
+init_state(
+    XlcConv conv)
+{
+    State state = (State) conv->state;
+
+    /* for CT */
+    state->charset = NULL;
+    state->GL_charset = default_GL_charset;
+    state->GR_charset = default_GR_charset;
+
+    /* for MB shift state */
+    state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL);
+    state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR);
+}
+
+/* -------------------------------------------------------------------------- */
+/*				Convert                                       */
+/* -------------------------------------------------------------------------- */
+
+static int
+mbstowcs_org(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    unsigned char ch;
+    unsigned long mb = 0;
+    wchar_t wc;
+
+    int length = 0, len_left = 0;
+    int unconv_num = 0;
+    int num;
+
+    CodeSet codeset = NULL;
+
+    const char *inbufptr;
+    wchar_t *outbufptr = (wchar_t *) *to;
+    int from_size = *from_left;
+
+    unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
+
+    if (from == NULL || *from == NULL) {
+	_XlcResetConverter(conv);
+        return( 0 );
+    }
+
+    inbufptr = *from;
+
+    while (*from_left && *to_left) {
+
+	ch = *inbufptr++;
+	(*from_left)--;
+
+	/* null ? */
+	if (!ch) {
+            if (outbufptr) {*outbufptr++ = L'\0';}
+	    (*to_left)--;
+
+	    /* error check */
+            if (len_left) {
+	        unconv_num += (length - len_left);
+		len_left = 0;
+            }
+
+	    continue;
+	}
+
+	/* same mb char data */
+        if (len_left)
+	    goto output_one_wc;
+
+        /* next mb char data for single shift ? */
+	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
+	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
+            if (codeset != NULL) {
+		length = len_left = codeset->length;
+		mb = 0;
+		continue;
+	    }
+        }
+
+	/* next mb char data for byteM ? */
+	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+	    goto next_mb_char;
+
+	/* next mb char data for GL or GR side ? */
+	if ((codeset = GLGR_parse_codeset(ch)))
+	    goto next_mb_char;
+
+        /* can't find codeset for the ch */
+        unconv_num++;
+        continue;
+
+next_mb_char:
+        length = len_left = codeset->length;
+	mb = 0;
+
+output_one_wc:
+	mb = (mb << 8) | ch;  /* 1 byte left shift */
+	len_left--;
+
+        /* last of one mb char data */
+        if (!len_left) {
+            gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc);
+            if (outbufptr) {*outbufptr++ = wc;}
+	    (*to_left)--;
+        }
+
+    } /* end of while */
+
+    /* error check on last char */
+    if (len_left) {
+	inbufptr -= (length - len_left);
+	(*from_left) += (length - len_left);
+	unconv_num += (length - len_left);
+    }
+
+    *from = (XPointer) ((const char *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+stdc_mbstowcs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    const char *src = *((const char **) from);
+    wchar_t *dst = *((wchar_t **) to);
+    int src_left = *from_left;
+    int dst_left = *to_left;
+    int length, unconv_num = 0;
+
+    while (src_left > 0 && dst_left > 0) {
+	length = mbtowc(dst, src, src_left);
+
+	if (length > 0) {
+	    src += length;
+	    src_left -= length;
+	    if (dst)
+	        dst++;
+	    dst_left--;
+	} else if (length < 0) {
+	    src++;
+	    src_left--;
+	    unconv_num++;
+        } else {
+            /* null ? */
+            src++;
+            src_left--;
+            if (dst)
+                *dst++ = L'\0';
+            dst_left--;
+        }
+    }
+
+    *from = (XPointer) src;
+    if (dst)
+	*to = (XPointer) dst;
+    *from_left = src_left;
+    *to_left = dst_left;
+
+    return unconv_num;
+}
+
+static int
+wcstombs_org(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    char *encoding;
+    unsigned long mb, glyph_index;
+    wchar_t wc;
+
+    int length;
+    int unconv_num = 0;
+
+    CodeSet codeset;
+
+    const wchar_t *inbufptr = (const wchar_t *) *from;
+    char *outbufptr = *to;
+    int from_size = *from_left;
+
+    const char *default_string = XLC_PUBLIC(lcd, default_string);
+    int defstr_len = strlen(default_string);
+
+
+    while (*from_left && *to_left) {
+
+        wc = *inbufptr++;
+        (*from_left)--;
+
+        /* null ? */
+        if (!wc) {
+            if (outbufptr) {*outbufptr++ = '\0';}
+            (*to_left)--;
+
+            continue;
+        }
+
+        /* convert */
+	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+
+	    /* output default_string of XDefaultString() */
+            if (*to_left < defstr_len)
+		break;
+	    if (outbufptr) {
+                strncpy((char *)outbufptr, default_string, defstr_len);
+                outbufptr += defstr_len;
+            }
+	    (*to_left) -= defstr_len;
+
+            unconv_num++;
+
+        } else {
+            mb = gi_to_mb(glyph_index, codeset);
+	    if (codeset->parse_info) {
+                Bool need_shift = False;
+                switch (codeset->parse_info->type) {
+                    case E_LSL :
+                        if (codeset != state->GL_codeset) {
+                            need_shift = True;
+                            state->GL_codeset = codeset;
+                        }
+                        break;
+                    case E_LSR :
+                        if (codeset != state->GR_codeset) {
+                            need_shift = True;
+                            state->GR_codeset = codeset;
+                        }
+                        break;
+                    /* case E_SS */
+                    default:
+                        need_shift = True;
+                }
+
+		/* output shift sequence */
+                if (need_shift) {
+		    encoding = codeset->parse_info->encoding;
+                    length = strlen(encoding);
+                    if (*to_left < length)
+		        break;
+	            if (outbufptr) {
+                        strncpy((char *)outbufptr, encoding, length);
+	                outbufptr += length;
+                    }
+	            (*to_left) -= length;
+                }
+            }
+
+            /* output characters */
+	    length = codeset->length;
+            if (*to_left < length)
+		break;
+
+	    if (outbufptr) {
+		output_ulong_value(outbufptr, mb, length, XlcNONE);
+	        outbufptr += length;
+	    }
+
+	    (*to_left) -= length;
+        }
+
+    } /* end of while */
+
+    *from = (XPointer) ((const wchar_t *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+stdc_wcstombs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    const wchar_t *src = *((const wchar_t **) from);
+    char *dst = *((char **) to);
+    int src_left = *from_left;
+    int dst_left = *to_left;
+    int length, unconv_num = 0;
+
+    while (src_left > 0 && dst_left >= MB_CUR_MAX) {
+	length = wctomb(dst, *src);		/* XXX */
+
+        if (length > 0) {
+	    src++;
+	    src_left--;
+	    if (dst)
+		dst += length;
+	    dst_left -= length;
+	} else if (length < 0) {
+	    src++;
+	    src_left--;
+	    unconv_num++;
+	}
+    }
+
+    *from = (XPointer) src;
+    if (dst)
+      *to = (XPointer) dst;
+    *from_left = src_left;
+    *to_left = dst_left;
+
+    return unconv_num;
+}
+
+static int
+wcstocts(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    unsigned long glyph_index;
+    wchar_t wc;
+
+    int total_len, seq_len, name_len;
+    int unconv_num = 0;
+    Bool first_flag = True, standard_flag;
+    XlcSide side;
+
+    CodeSet codeset;
+    XlcCharSet charset, old_charset = NULL;
+    const char *ct_sequence;
+
+    const wchar_t *inbufptr = (const wchar_t *) *from;
+    char *outbufptr = *to;
+    int from_size = *from_left;
+    char *ext_seg_len = NULL;
+
+    while (*from_left && *to_left) {
+
+        wc = *inbufptr++;
+        (*from_left)--;
+
+        /* null ? */
+        if (!wc) {
+            if (outbufptr) {*outbufptr++ = '\0';}
+            (*to_left)--;
+
+            continue;
+        }
+
+        /* convert */
+	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+            unconv_num++;
+	    continue;
+        }
+
+        /* parse charset */
+        if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
+            unconv_num++;
+	    continue;
+        }
+
+        /* Standard Character Set Encoding ? */
+	standard_flag = charset->source == CSsrcStd ? True : False;
+
+        /*
+         *   Non-Standard Character Set Encoding
+         *
+         * +-----+-----+-----+-----+-----+-----+-----+----   ----+-----+-----+
+         * |     esc sequence      |  M  |  L  |     encoding name     | STX |
+         * +-----+-----+-----+-----+-----+-----+-----+----   ----+-----+-----+
+         *           4bytes         1byte 1byte     variable length     1byte
+         * 	                   |                                         |
+         * 	                   +-----------------------------------------+
+         * 	                     name length  = ((M - 128) * 128) + (L - 128)
+         */
+
+        /* make encoding data */
+	ct_sequence = charset->ct_sequence;
+	side = charset->side;
+        seq_len = strlen(ct_sequence);
+	if (standard_flag) {
+            name_len = 0;
+	    total_len = seq_len;
+	} else {
+            name_len = strlen(charset->encoding_name) + 1;
+	    total_len = seq_len + name_len + 2;
+	}
+
+        /* output escape sequence of CT */
+	if ( (charset != old_charset) &&
+	    !(first_flag && charset->string_encoding) ){
+
+            if ( (ext_seg_len != NULL) && outbufptr) {
+                int i = (outbufptr - ext_seg_len) - 2;
+                *ext_seg_len++ = i / 128 + 128;
+                *ext_seg_len   = i % 128 + 128;
+                ext_seg_len = NULL;
+            }
+
+	    if (*to_left < total_len + 1) {
+                unconv_num++;
+	        break;
+	    }
+
+	    if (outbufptr) {
+	        strcpy((char *)outbufptr, ct_sequence);
+		outbufptr += seq_len;
+
+                if (!standard_flag) {
+                    const char *i = charset->encoding_name;
+                    ext_seg_len = outbufptr;
+                    outbufptr += 2;
+	            for (; *i ; i++)
+                        *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ?
+                                       *i - 'A' + 'a' : *i;
+		    *outbufptr++ = STX;
+                }
+	    }
+
+	    (*to_left) -= total_len;
+
+	    first_flag = False;
+	    old_charset = charset;
+	}
+
+        /* output glyph index */
+	if (codeset->ctconv)
+            glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
+        if (*to_left < charset->char_size) {
+            unconv_num++;
+	    break;
+        }
+
+	if (outbufptr) {
+	   output_ulong_value(outbufptr, glyph_index, charset->char_size, side);
+	   outbufptr += charset->char_size;
+	}
+
+	(*to_left) -= charset->char_size;
+
+    } /* end of while */
+
+    if ( (ext_seg_len != NULL) && outbufptr) {
+        int i = (outbufptr - ext_seg_len) - 2;
+        *ext_seg_len++ = i / 128 + 128;
+        *ext_seg_len   = i % 128 + 128;
+    }
+
+    *from = (XPointer) ((const wchar_t *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+stdc_wcstocts(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left) * MB_CUR_MAX;
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = stdc_wcstombs(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = buf_ptr1 - buf_ptr2;
+
+    unconv_num2 = mbstocts(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+static int
+ctstowcs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    unsigned char ch;
+    unsigned long glyph_index = 0;
+    wchar_t wc;
+
+    int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0;
+    int unconv_num = 0;
+
+    CodeSet codeset = NULL;
+    XlcCharSet charset_tmp;
+
+    const char *inbufptr;
+    wchar_t *outbufptr = (wchar_t *) *to;
+    int from_size = *from_left;
+
+    _XlcResetConverter(conv); /* ??? */
+
+    if (from == NULL || *from == NULL) {
+	_XlcResetConverter(conv);
+        return( 0 );
+    }
+    inbufptr = *from;
+
+    while (*from_left && *to_left) {
+
+	ch = *inbufptr++;
+	(*from_left)--;
+
+	/* null ? */
+	if (!ch) {
+            if (outbufptr) {*outbufptr++ = L'\0';}
+	    (*to_left)--;
+
+	    /* error check */
+            if (gi_len_left) {
+	        unconv_num += (gi_len - gi_len_left);
+		gi_len_left = 0;
+            }
+
+	    continue;
+	}
+
+	/* same glyph_index data */
+        if (gi_len_left)
+	    goto output_one_wc;
+
+        /* control sequence ? */
+        if (ch == CSI) {
+            if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) )
+	        goto skip_the_seg;
+
+	    if (*from_left + 1 < ctr_seq_len) {
+		inbufptr--;
+		(*from_left)++;
+		unconv_num += *from_left;
+		break;
+	    }
+
+            /* skip the control sequence */
+	    inbufptr += (ctr_seq_len - 1);
+	    *from_left -= (ctr_seq_len - 1);
+
+            continue;
+	}
+
+        /* escape sequence ? */
+        if (ch == ESC) {
+	    if ( !ct_parse_charset(lcd,
+			inbufptr - 1, &state->charset, &ctr_seq_len) )
+		goto skip_the_seg;
+
+	    if (state->charset->side == XlcC0 ||
+		state->charset->side == XlcGL)
+	      {
+		state->GL_charset = state->charset;
+	      }
+	    else if (state->charset->side == XlcC1 ||
+		     state->charset->side == XlcGR)
+	      {
+		state->GR_charset = state->charset;
+	      }
+	    else if (state->charset->side == XlcGLGR)
+	      {
+		state->GL_charset = state->charset;
+		state->GR_charset = state->charset;
+	      }
+
+	    if (*from_left + 1 < ctr_seq_len) {
+		inbufptr--;
+		(*from_left)++;
+		unconv_num += *from_left;
+		break;
+	    }
+
+            /* skip the escape sequence */
+	    inbufptr += (ctr_seq_len - 1);
+	    *from_left -= (ctr_seq_len - 1);
+
+            continue;
+        }
+
+ 	/* check current state */
+	if (isleftside(ch))
+	  state->charset = state->GL_charset;
+	else
+	  state->charset = state->GR_charset;
+
+	gi_len = gi_len_left = state->charset->char_size;
+	glyph_index = 0;
+
+output_one_wc:
+        if (state->charset->side == XlcC1 || state->charset->side == XlcGR)
+            glyph_index = (glyph_index << 8) | (ch & GL);
+        else
+            glyph_index = (glyph_index << 8) | ch;
+
+	gi_len_left--;
+
+        /* last of one glyph_index data */
+        if (!gi_len_left) {
+
+	    /* segment conversion */
+	    charset_tmp = state->charset;
+	    segment_conversion(lcd, &charset_tmp, &glyph_index);
+
+            /* get codeset */
+            if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
+						&codeset, &glyph_index) ) {
+		unconv_num += gi_len;
+		continue;
+            }
+
+            /* convert glyph index to wicd char */
+            gi_to_wc(lcd, glyph_index, codeset, &wc);
+            if (outbufptr) {*outbufptr++ = wc;}
+	    (*to_left)--;
+        }
+
+        continue;
+
+skip_the_seg:
+	/* skip until next escape or control sequence */
+        while ( *from_left ) {
+	    ch = *inbufptr++;
+	    (*from_left)--;
+	    unconv_num++;
+
+            if (ch == ESC || ch == CSI) {
+		inbufptr--;
+		(*from_left)++;
+		unconv_num--;
+		break;
+	    }
+        }
+
+        if ( !(*from_left) )
+	    break;
+
+    } /* end of while */
+
+    /* error check on last char */
+    if (gi_len_left) {
+	inbufptr -= (gi_len - gi_len_left);
+	(*from_left) += (gi_len - gi_len_left);
+	unconv_num += (gi_len - gi_len_left);
+    }
+
+    *from = (XPointer) ((const char *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+cstowcs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    unsigned char ch;
+    unsigned long glyph_index = 0;
+    wchar_t wc;
+    int gi_len_left = 0, gi_len = 0;
+
+    int unconv_num = 0;
+
+    CodeSet codeset = NULL;
+    XlcCharSet charset, charset_tmp;
+
+    const char *inbufptr;
+    wchar_t *outbufptr = (wchar_t *) *to;
+    int from_size = *from_left;
+
+    if (from == NULL || *from == NULL) {
+        return( 0 );
+    }
+
+    inbufptr = *from;
+
+    charset = (XlcCharSet) args[0];
+
+    while (*from_left && *to_left) {
+
+        if (!gi_len_left) {
+            gi_len_left = gi_len = charset->char_size;
+            glyph_index = 0;
+        }
+
+	ch = *inbufptr++;
+	(*from_left)--;
+
+	/* null ? */
+	if (!ch) {
+            if (outbufptr) {*outbufptr++ = L'\0';}
+	    (*to_left)--;
+
+	    /* error check */
+            if (gi_len_left) {
+	        unconv_num += (gi_len - gi_len_left);
+		gi_len_left = 0;
+            }
+	    continue;
+	}
+
+        if (charset->side == XlcC1 || charset->side == XlcGR)
+            glyph_index = (glyph_index << 8) | (ch & GL);
+        else
+            glyph_index = (glyph_index << 8) | ch;
+
+	gi_len_left--;
+
+        /* last of one glyph_index data */
+        if (!gi_len_left) {
+
+	    /* segment conversion */
+	    charset_tmp = charset;
+	    segment_conversion(lcd, &charset_tmp, &glyph_index);
+
+            /* get codeset */
+            if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
+						&codeset, &glyph_index) ) {
+		unconv_num += gi_len;
+		continue;
+            }
+
+            /* convert glyph index to wicd char */
+            gi_to_wc(lcd, glyph_index, codeset, &wc);
+            if (outbufptr) {*outbufptr++ = wc;}
+	    (*to_left)--;
+        }
+
+    } /* end of while */
+
+    /* error check on last char */
+    if (gi_len_left) {
+	inbufptr -= (gi_len - gi_len_left);
+	(*from_left) += (gi_len - gi_len_left);
+	unconv_num += (gi_len - gi_len_left);
+    }
+
+    *from = (XPointer) ((const char *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+stdc_ctstowcs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left) * MB_CUR_MAX;
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = ctstombs(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = buf_ptr1 - buf_ptr2;
+
+    unconv_num2 = stdc_mbstowcs(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+static int
+stdc_cstowcs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left) * MB_CUR_MAX;
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = cstombs(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = buf_ptr1 - buf_ptr2;
+
+    unconv_num2 = stdc_mbstowcs(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+static int
+mbstocts(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left);
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = mbstowcs_org(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
+
+    unconv_num2 += wcstocts(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+static int
+mbstostr(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    unsigned char ch;
+    unsigned long mb = 0;
+
+    int length = 0, len_left = 0;
+    int unconv_num = 0;
+    int num;
+
+    CodeSet codeset = NULL;
+
+    const char *inbufptr;
+    char *outbufptr = *to;
+    int from_size = *from_left;
+
+    unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
+
+    if (from == NULL || *from == NULL) {
+	_XlcResetConverter(conv);
+        return( 0 );
+    }
+
+    inbufptr = *from;
+
+    while (*from_left && *to_left) {
+
+	ch = *inbufptr++;
+	(*from_left)--;
+
+	/* null ? */
+	if (!ch) {
+            if (outbufptr) {*outbufptr++ = '\0';}
+	    (*to_left)--;
+
+            /* error check */
+            if (len_left) {
+                unconv_num += (length - len_left);
+                len_left = 0;
+            }
+
+	    continue;
+	}
+
+        /* same mb char data */
+        if (len_left)
+            goto output_one_mb;
+
+        /* next mb char data for single shift ? */
+	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
+	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
+            if (codeset != NULL) {
+		length = len_left = codeset->length;
+		mb = 0;
+		continue;
+	    }
+        }
+
+	/* next char data : byteM ? */
+	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+	    goto next_mb_char;
+
+	/* next char data : GL or GR side ? */
+	if ((codeset = GLGR_parse_codeset(ch)))
+	    goto next_mb_char;
+
+        /* can't find codeset for the ch */
+        unconv_num++;
+        continue;
+
+next_mb_char:
+        length = len_left = codeset->length;
+        mb = 0;
+
+output_one_mb:
+        mb = (mb << 8) | ch;  /* 1 byte left shift */
+        len_left--;
+
+        /* last of one mb char data */
+        if (!len_left) {
+            if (check_string_encoding(codeset)) {
+                if (outbufptr) {*outbufptr++ = mb & 0xff;}
+		(*to_left)--;
+            } else {
+	        unconv_num++;
+            }
+        }
+
+    } /* end of while */
+
+    /* error check on last char */
+    if (len_left) {
+        inbufptr -= (length - len_left);
+        (*from_left) += (length - len_left);
+        unconv_num += (length - len_left);
+    }
+
+    *from = (XPointer) ((const char *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+mbtocs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    unsigned char ch;
+    unsigned long mb = 0;
+    unsigned long glyph_index;
+
+    int length = 0, len_left = 0, char_len;
+    int unconv_num = 0;
+    int num;
+    XlcSide side;
+
+    CodeSet codeset = NULL;
+    XlcCharSet charset = NULL;
+
+    const char *inbufptr;
+    char *outbufptr = *to;
+    int from_size = *from_left;
+
+    unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
+
+    if (from == NULL || *from == NULL) {
+	_XlcResetConverter(conv);
+        return( 0 );
+    }
+
+    inbufptr = *from;
+
+    while (*from_left && *to_left) {
+
+	ch = *inbufptr++;
+	(*from_left)--;
+
+	/* null ? */
+	if (!ch) {
+            unconv_num = 1;
+            if (len_left)
+	        unconv_num += (length - len_left);
+	    break;
+	}
+
+	/* same mb char data */
+        if (len_left)
+	    goto output;
+
+        /* next mb char data for single shift ? */
+	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
+	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
+            if (codeset != NULL) {
+		length = len_left = codeset->length;
+		mb = 0;
+		continue;
+	    }
+        }
+
+	/* next mb char data for byteM ? */
+	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+	    goto next_mb_char;
+
+	/* next mb char data for GL or GR side ? */
+	if ((codeset = GLGR_parse_codeset(ch)))
+	    goto next_mb_char;
+
+        /* can't find codeset for the ch */
+        unconv_num = 1;
+        break;
+
+next_mb_char:
+        length = len_left = codeset->length;
+	mb = 0;
+
+output:
+	mb = (mb << 8) | ch;  /* 1 byte left shift */
+	len_left--;
+
+        /* last of one mb char data */
+        if (!len_left) {
+            glyph_index = mb_to_gi(mb, codeset);
+            if (!(charset = gi_parse_charset(glyph_index, codeset))) {
+                unconv_num = length;
+                break;
+            }
+            char_len = charset->char_size;
+	    side = charset->side;
+
+            /* output glyph index */
+            if (codeset->ctconv)
+                glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
+            if (*to_left < char_len) {
+                unconv_num = length;
+                break;
+            }
+
+	    if (outbufptr) {
+	        output_ulong_value(outbufptr, glyph_index, char_len, side);
+	        outbufptr += char_len;
+	    }
+
+            (*to_left) -= char_len;
+
+            break;
+        }
+
+    } /* end of while */
+
+    /* error end */
+    if (unconv_num) {
+        *from = (XPointer) ((const char *) *from + from_size);
+        *from_left = 0;
+        *to = (XPointer) outbufptr;
+	return -1;
+    }
+
+    /* normal end */
+    *from = (XPointer) inbufptr;
+    *to = (XPointer) outbufptr;
+
+    if (num_args > 0)
+        *((XlcCharSet *) args[0]) = charset;
+
+    return 0;
+}
+
+static int
+mbstocs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    int ret;
+    XlcCharSet charset_old, charset = NULL;
+    XPointer tmp_args[1];
+
+    const char *inbufptr;
+    int	in_left;
+    char *outbufptr;
+    int	out_left;
+    tmp_args[0] = (XPointer) &charset;
+
+    ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
+    charset_old = charset;
+
+    while ( ret == 0 && *from_left && *to_left) {
+	inbufptr = *from;
+	in_left = *from_left;
+	outbufptr = *to;
+	out_left = *to_left;
+        ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
+        if (charset_old != charset) {
+           *from = (XPointer) inbufptr;
+           *from_left = in_left;
+           *to = (XPointer) outbufptr;
+           *to_left = out_left;
+           break;
+        }
+    }
+
+    if (num_args > 0)
+        *((XlcCharSet *) args[0]) = charset_old;
+
+    /* error end */
+    if (ret != 0)
+	return( -1 );
+
+    return(0);
+}
+
+static int
+wcstostr(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    char *encoding;
+    unsigned long mb, glyph_index;
+    wchar_t wc;
+
+    int length;
+    int unconv_num = 0;
+
+    CodeSet codeset;
+
+    const wchar_t *inbufptr = (const wchar_t *) *from;
+    char *outbufptr = *to;
+    int from_size = *from_left;
+
+    const char *default_string = XLC_PUBLIC(lcd, default_string);
+    int defstr_len = strlen(default_string);
+
+    while (*from_left && *to_left) {
+
+        wc = *inbufptr++;
+        (*from_left)--;
+
+        /* null ? */
+        if (!wc) {
+            if (outbufptr) {*outbufptr++ = '\0';}
+            (*to_left)--;
+
+            continue;
+        }
+
+        /* convert */
+	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+
+	    /* output default_string of XDefaultString() */
+            if (*to_left < defstr_len)
+		break;
+	    if (outbufptr) {
+                strncpy((char *)outbufptr, default_string, defstr_len);
+	        outbufptr += defstr_len;
+            }
+	    (*to_left) -= defstr_len;
+
+            unconv_num++;
+
+        } else {
+            mb = gi_to_mb(glyph_index, codeset);
+
+	    if (check_string_encoding(codeset)) {
+	        if (codeset->parse_info) {
+                    Bool need_shift = False;
+                    switch (codeset->parse_info->type) {
+                        case E_LSL :
+                            if (codeset != state->GL_codeset) {
+                                need_shift = True;
+                                state->GL_codeset = codeset;
+                            }
+                            break;
+                        case E_LSR :
+                            if (codeset != state->GR_codeset) {
+                                need_shift = True;
+                                state->GR_codeset = codeset;
+                            }
+                            break;
+                        /* case E_SS */
+                        default:
+                            need_shift = True;
+                    }
+
+		    /* output shift sequence */
+                    if (need_shift) {
+		        encoding = codeset->parse_info->encoding;
+                        length = strlen(encoding);
+                        if (*to_left < length)
+		            break;
+
+	                if (outbufptr) {
+                            strncpy((char *)outbufptr, encoding, length);
+	                    outbufptr += length;
+                        }
+	                (*to_left) -= length;
+                    }
+                }
+
+                /* output characters */
+	        length = codeset->length;
+                if (*to_left < length)
+		    break;
+
+	        if (outbufptr) {
+	            output_ulong_value(outbufptr, mb, length, XlcNONE);
+	            outbufptr += length;
+	        }
+
+	        (*to_left) -= length;
+            } else {
+		unconv_num++;
+            }
+        }
+
+    } /* end of while */
+
+    *from = (XPointer) ((const wchar_t *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+stdc_wcstostr(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left) * MB_CUR_MAX;
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = stdc_wcstombs(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = buf_ptr1 - buf_ptr2;
+
+    unconv_num2 = mbstostr(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+static int
+wctocs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    wchar_t wc;
+    unsigned long glyph_index;
+
+    int char_len;
+    int unconv_num = 0;
+    XlcSide side;
+
+    CodeSet codeset;
+    XlcCharSet charset = NULL;
+
+    const wchar_t *inbufptr = (const wchar_t *) *from;
+    char *outbufptr = *to;
+    int from_size = *from_left;
+
+    if (*from_left && *to_left) {
+
+        wc = *inbufptr++;
+        (*from_left)--;
+
+        /* null ? */
+        if (!wc) {
+            unconv_num = 1;
+            goto end;
+        }
+
+        /* convert */
+	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+            unconv_num = 1;
+	    goto end;
+        }
+
+        if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
+            unconv_num = 1;
+	    goto end;
+        }
+	char_len = charset->char_size;
+	side = charset->side;
+
+        /* output glyph index */
+	if (codeset->ctconv)
+            glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
+        if (*to_left < char_len) {
+            unconv_num++;
+	    goto end;
+        }
+
+        if (outbufptr) {
+            output_ulong_value(outbufptr, glyph_index, char_len, side);
+            outbufptr += char_len;
+        }
+
+	(*to_left) -= char_len;
+
+    }
+
+end:
+
+     /* error end */
+    if (unconv_num) {
+        *from = (XPointer) ((const wchar_t *) *from + from_size);
+        *from_left = 0;
+        *to = (XPointer) outbufptr;
+        return -1;
+    }
+
+    /* normal end */
+    *from = (XPointer) inbufptr;
+    *to = (XPointer) outbufptr;
+
+    if (num_args > 0)
+        *((XlcCharSet *) args[0]) = charset;
+
+    return 0;
+}
+
+static int
+stdc_wctocs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    const wchar_t *src = *((const wchar_t **) from);
+    wchar_t wch;
+    XPointer tmp_from, save_from = *from;
+    char tmp[32];
+    int length, ret, src_left = *from_left;
+    int from_size = *from_left;
+
+    if (src_left > 0 && *to_left > 0) {
+	if ((wch = *src)) {
+	    length = wctomb(tmp, wch);
+	} else {
+	    goto end;
+	}
+
+	if (length < 0)
+	    goto end;
+
+	tmp_from = (XPointer) tmp;
+	ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args);
+	if (ret < 0)
+	    goto end;
+
+	src++;
+	src_left--;
+    }
+
+end:
+     /* error end */
+    if (save_from == (XPointer) src) {
+        *from = (XPointer) ((const wchar_t *) *from + from_size);
+        *from_left = 0;
+	return -1;
+    }
+
+    /* normal end */
+    *from = (XPointer) src;
+    *from_left = src_left;
+
+    return 0;
+}
+
+static int
+wcstocs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    int ret;
+    XlcCharSet charset_old, charset = NULL;
+    XPointer tmp_args[1];
+
+    const wchar_t *inbufptr;
+    int	in_left;
+    XPointer outbufptr;
+    int	out_left;
+    tmp_args[0] = (XPointer) &charset;
+
+    ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+    charset_old = charset;
+
+    while ( ret == 0 && *from_left && *to_left) {
+	inbufptr = (const wchar_t *) *from;
+	in_left = *from_left;
+	outbufptr = *to;
+	out_left = *to_left;
+        ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+        if (charset_old != charset) {
+           *from = (XPointer) inbufptr;
+           *from_left = in_left;
+           *to = (XPointer) outbufptr;
+           *to_left = out_left;
+           break;
+        }
+    }
+
+    if (num_args > 0)
+        *((XlcCharSet *) args[0]) = charset_old;
+
+    /* error end */
+    if (ret != 0)
+	return( -1 );
+
+    return(0);
+}
+
+#ifdef STDCVT
+
+static int
+stdc_wcstocs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    int ret;
+    XlcCharSet charset_old, charset = NULL;
+    XPointer tmp_args[1];
+
+    const wchar_t *inbufptr;
+    int	in_left;
+    XPointer outbufptr;
+    int	out_left;
+    tmp_args[0] = (XPointer) &charset;
+
+    ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+    charset_old = charset;
+
+    while ( ret == 0 && *from_left && *to_left ) {
+	inbufptr = (const wchar_t *) *from;
+	in_left = *from_left;
+	outbufptr = *to;
+	out_left = *to_left;
+        ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+        if (charset_old != charset) {
+           *from = (XPointer) inbufptr;
+           *from_left = in_left;
+           *to = (XPointer) outbufptr;
+           *to_left = out_left;
+           break;
+        }
+    }
+
+    if (num_args > 0)
+        *((XlcCharSet *) args[0]) = charset_old;
+
+    /* error end */
+    if (ret != 0)
+	return( -1 );
+
+    return(0);
+}
+
+#endif
+
+static int
+ctstombs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left);
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = ctstowcs(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
+
+    unconv_num2 += wcstombs_org(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+static int
+cstombs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left);
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = cstowcs(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
+
+    unconv_num2 += wcstombs_org(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+static int
+strtombs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    char *encoding;
+    unsigned long mb, glyph_index;
+    unsigned char ch;
+
+    int length;
+    int unconv_num = 0;
+
+    CodeSet codeset;
+
+    const char *inbufptr = *from;
+    char *outbufptr = *to;
+    int from_size = *from_left;
+
+    while (*from_left && *to_left) {
+
+        ch = *inbufptr++;
+        (*from_left)--;
+
+        /* null ? */
+        if (!ch) {
+            if (outbufptr) {*outbufptr++ = '\0';}
+            (*to_left)--;
+
+            continue;
+        }
+
+        /* convert */
+        if (isleftside(ch)) {
+	    glyph_index = ch;
+	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
+	} else {
+	    glyph_index = ch & GL;
+	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
+	}
+
+        if (!codeset) {
+	    unconv_num++;
+	    continue;
+        }
+
+        mb = gi_to_mb(glyph_index, codeset);
+	if (codeset->parse_info) {
+            Bool need_shift = False;
+            switch (codeset->parse_info->type) {
+                case E_LSL :
+                    if (codeset != state->GL_codeset) {
+                        need_shift = True;
+                        state->GL_codeset = codeset;
+                    }
+                    break;
+                case E_LSR :
+                    if (codeset != state->GR_codeset) {
+                        need_shift = True;
+                        state->GR_codeset = codeset;
+                    }
+                    break;
+                /* case E_SS */
+                default:
+                    need_shift = True;
+            }
+
+	    /* output shift sequence */
+            if (need_shift) {
+                encoding = codeset->parse_info->encoding;
+                length = strlen(encoding);
+                if (*to_left < length)
+		    break;
+	        if (outbufptr) {
+                    strncpy((char *)outbufptr, encoding, length);
+	            outbufptr += length;
+                }
+	        (*to_left) -= length;
+	    }
+        }
+
+        /* output characters */
+	length = codeset->length;
+        if (*to_left < length)
+	    break;
+
+        if (outbufptr) {
+            output_ulong_value(outbufptr, mb, length, XlcNONE);
+            outbufptr += length;
+        }
+
+	(*to_left) -= length;
+
+    } /* end of while */
+
+    *from = (XPointer) ((const char *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+strtowcs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    State state = (State) conv->state;
+    XLCd lcd = state->lcd;
+
+    unsigned char ch;
+    unsigned long glyph_index;
+    wchar_t wc;
+
+    int unconv_num = 0;
+    CodeSet codeset;
+
+    const char *inbufptr = *from;
+    wchar_t *outbufptr = (wchar_t *)*to;
+    int from_size = *from_left;
+
+    while (*from_left && *to_left) {
+
+        ch = *inbufptr++;
+        (*from_left)--;
+
+        /* null ? */
+        if (!ch) {
+            if (outbufptr) {*outbufptr++ = L'\0';}
+            (*to_left)--;
+
+            continue;
+        }
+
+        /* convert */
+        if (isleftside(ch)) {
+	    glyph_index = ch;
+	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
+	} else {
+	    glyph_index = ch & GL;
+	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
+	}
+
+        if (!codeset) {
+	    unconv_num++;
+	    continue;
+        }
+
+        gi_to_wc(lcd, glyph_index, codeset, &wc);
+	if (outbufptr) {*outbufptr++ = wc;}
+	(*to_left)--;
+
+    } /* end of while */
+
+    *from = (XPointer) ((const char *) *from + from_size);
+    *from_left = 0;
+    *to = (XPointer) outbufptr;
+
+    return unconv_num;
+}
+
+static int
+stdc_strtowcs(
+    XlcConv conv,
+    XPointer *from,
+    int *from_left,
+    XPointer *to,
+    int *to_left,
+    XPointer *args,
+    int num_args)
+{
+    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+    char *buf_ptr1 = buf;
+    int buf_left1 = (*from_left) * MB_CUR_MAX;
+    char *buf_ptr2 = buf_ptr1;
+    int buf_left2;
+    int unconv_num1 = 0, unconv_num2 = 0;
+
+    unconv_num1 = strtombs(conv,
+		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+    if (unconv_num1 < 0)
+        goto ret;
+
+    buf_left2 = buf_ptr1 - buf_ptr2;
+
+    unconv_num2 = stdc_mbstowcs(conv,
+		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
+    if (unconv_num2 < 0)
+        goto ret;
+
+ret:
+    Xfree(buf);
+
+    return (unconv_num1 + unconv_num2);
+}
+
+/* -------------------------------------------------------------------------- */
+/*				Close                                         */
+/* -------------------------------------------------------------------------- */
+
+static void
+close_converter(
+    XlcConv conv)
+{
+    Xfree(conv->state);
+    Xfree(conv->methods);
+    Xfree(conv);
+}
+
+/* -------------------------------------------------------------------------- */
+/*				Open                                          */
+/* -------------------------------------------------------------------------- */
+
+static XlcConv
+create_conv(
+    XLCd lcd,
+    XlcConvMethods methods)
+{
+    XlcConv conv;
+    State state;
+
+    conv = Xcalloc(1, sizeof(XlcConvRec));
+    if (conv == NULL)
+	return (XlcConv) NULL;
+
+    conv->methods = Xmalloc(sizeof(XlcConvMethodsRec));
+    if (conv->methods == NULL)
+	goto err;
+    *conv->methods = *methods;
+    conv->methods->reset = init_state;
+
+    conv->state = Xcalloc(1, sizeof(StateRec));
+    if (conv->state == NULL)
+	goto err;
+
+    state = (State) conv->state;
+    state->lcd = lcd;
+
+    _XlcResetConverter(conv);
+
+    return conv;
+
+err:
+    close_converter(conv);
+
+    return (XlcConv) NULL;
+}
+
+static XlcConvMethodsRec mbstocts_methods = {
+    close_converter,
+    mbstocts,
+    NULL
+};
+
+static XlcConv
+open_mbstocts(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &mbstocts_methods);
+}
+
+static XlcConvMethodsRec mbstostr_methods = {
+    close_converter,
+    mbstostr,
+    NULL
+};
+
+static XlcConv
+open_mbstostr(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &mbstostr_methods);
+}
+
+static XlcConvMethodsRec mbstocs_methods = {
+    close_converter,
+    mbstocs,
+    NULL
+};
+
+static XlcConv
+open_mbstocs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &mbstocs_methods);
+}
+
+static XlcConvMethodsRec mbtocs_methods = {
+    close_converter,
+    mbtocs,
+    NULL
+};
+
+static XlcConv
+open_mbtocs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &mbtocs_methods);
+}
+
+static XlcConvMethodsRec ctstombs_methods = {
+    close_converter,
+    ctstombs,
+    NULL
+};
+
+static XlcConv
+open_ctstombs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &ctstombs_methods);
+}
+
+static XlcConvMethodsRec cstombs_methods = {
+    close_converter,
+    cstombs,
+    NULL
+};
+
+static XlcConv
+open_cstombs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &cstombs_methods);
+}
+
+static XlcConvMethodsRec strtombs_methods = {
+    close_converter,
+    strtombs,
+    NULL
+};
+
+static XlcConv
+open_strtombs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &strtombs_methods);
+}
+
+#ifdef STDCVT
+
+static XlcConvMethodsRec stdc_mbstowcs_methods = {
+    close_converter,
+    stdc_mbstowcs,
+    NULL
+};
+
+static XlcConv
+open_stdc_mbstowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_mbstowcs_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstombs_methods = {
+    close_converter,
+    stdc_wcstombs,
+    NULL
+};
+
+static XlcConv
+open_stdc_wcstombs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_wcstombs_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstocts_methods = {
+    close_converter,
+    stdc_wcstocts,
+    NULL
+};
+
+static XlcConv
+open_stdc_wcstocts(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_wcstocts_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstostr_methods = {
+    close_converter,
+    stdc_wcstostr,
+    NULL
+};
+
+static XlcConv
+open_stdc_wcstostr(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_wcstostr_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstocs_methods = {
+    close_converter,
+    stdc_wcstocs,
+    NULL
+};
+
+static XlcConv
+open_stdc_wcstocs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_wcstocs_methods);
+}
+
+static XlcConvMethodsRec stdc_wctocs_methods = {
+    close_converter,
+    stdc_wctocs,
+    NULL
+};
+
+static XlcConv
+open_stdc_wctocs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_wctocs_methods);
+}
+
+static XlcConvMethodsRec stdc_ctstowcs_methods = {
+    close_converter,
+    stdc_ctstowcs,
+    NULL
+};
+
+static XlcConv
+open_stdc_ctstowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_ctstowcs_methods);
+}
+
+static XlcConvMethodsRec stdc_cstowcs_methods = {
+    close_converter,
+    stdc_cstowcs,
+    NULL
+};
+
+static XlcConv
+open_stdc_cstowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_cstowcs_methods);
+}
+
+static XlcConvMethodsRec stdc_strtowcs_methods = {
+    close_converter,
+    stdc_strtowcs,
+    NULL
+};
+
+static XlcConv
+open_stdc_strtowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &stdc_strtowcs_methods);
+}
+
+#endif /* STDCVT */
+
+static XlcConvMethodsRec mbstowcs_methods = {
+    close_converter,
+    mbstowcs_org,
+    NULL
+};
+
+static XlcConv
+open_mbstowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &mbstowcs_methods);
+}
+
+static XlcConvMethodsRec wcstombs_methods = {
+    close_converter,
+    wcstombs_org,
+    NULL
+};
+
+static XlcConv
+open_wcstombs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &wcstombs_methods);
+}
+
+static XlcConvMethodsRec wcstocts_methods = {
+    close_converter,
+    wcstocts,
+    NULL
+};
+
+static XlcConv
+open_wcstocts(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &wcstocts_methods);
+}
+
+static XlcConvMethodsRec wcstostr_methods = {
+    close_converter,
+    wcstostr,
+    NULL
+};
+
+static XlcConv
+open_wcstostr(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &wcstostr_methods);
+}
+
+static XlcConvMethodsRec wcstocs_methods = {
+    close_converter,
+    wcstocs,
+    NULL
+};
+
+static XlcConv
+open_wcstocs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &wcstocs_methods);
+}
+
+static XlcConvMethodsRec wctocs_methods = {
+    close_converter,
+    wctocs,
+    NULL
+};
+
+static XlcConv
+open_wctocs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &wctocs_methods);
+}
+
+static XlcConvMethodsRec ctstowcs_methods = {
+    close_converter,
+    ctstowcs,
+    NULL
+};
+
+static XlcConv
+open_ctstowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &ctstowcs_methods);
+}
+
+static XlcConvMethodsRec cstowcs_methods = {
+    close_converter,
+    cstowcs,
+    NULL
+};
+
+static XlcConv
+open_cstowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &cstowcs_methods);
+}
+
+static XlcConvMethodsRec strtowcs_methods = {
+    close_converter,
+    strtowcs,
+    NULL
+};
+
+static XlcConv
+open_strtowcs(
+    XLCd from_lcd,
+    const char *from_type,
+    XLCd to_lcd,
+    const char *to_type)
+{
+    return create_conv(from_lcd, &strtowcs_methods);
+}
+
+/* -------------------------------------------------------------------------- */
+/*				Loader                                        */
+/* -------------------------------------------------------------------------- */
+
+XLCd
+_XlcGenericLoader(
+    const char *name)
+{
+    XLCd lcd;
+#ifdef STDCVT
+    XLCdGenericPart *gen;
+#endif
+
+    lcd = _XlcCreateLC(name, _XlcGenericMethods);
+
+    if (lcd == NULL)
+	return lcd;
+
+    default_GL_charset = _XlcGetCharSet("ISO8859-1:GL");
+    default_GR_charset = _XlcGetCharSet("ISO8859-1:GR");
+
+    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
+    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString,       open_mbstostr);
+    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet,      open_mbstocs);
+    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar,         open_mbtocs);
+    _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
+    _XlcSetConverter(lcd, XlcNString,    lcd, XlcNMultiByte,    open_strtombs);
+    _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNMultiByte,    open_cstombs);
+
+#ifdef STDCVT
+     gen = XLC_GENERIC_PART(lcd);
+
+     if (gen->use_stdc_env != True) {
+#endif
+        _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar,     open_mbstowcs);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNMultiByte,    open_wcstombs);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCompoundText, open_wcstocts);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNString,       open_wcstostr);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCharSet,      open_wcstocs);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNChar,         open_wctocs);
+        _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar,  open_ctstowcs);
+        _XlcSetConverter(lcd, XlcNString,    lcd, XlcNWideChar,     open_strtowcs);
+        _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNWideChar,     open_cstowcs);
+#ifdef STDCVT
+    }
+#endif
+
+#ifdef STDCVT
+    if (gen->use_stdc_env == True) {
+        _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar,     open_stdc_mbstowcs);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNMultiByte,    open_stdc_wcstombs);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCompoundText, open_stdc_wcstocts);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNString,       open_stdc_wcstostr);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCharSet,      open_stdc_wcstocs);
+        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNChar,         open_stdc_wctocs);
+        _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar,  open_stdc_ctstowcs);
+        _XlcSetConverter(lcd, XlcNString,    lcd, XlcNWideChar,     open_stdc_strtowcs);
+        _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNWideChar,     open_stdc_cstowcs);
+    }
+#endif
+
+    _XlcAddUtf8Converters(lcd);
+
+    return lcd;
+}
-- 
cgit v1.2.3