806 lines
16 KiB
C
806 lines
16 KiB
C
/*
|
|
* 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
|
|
*/
|
|
/*
|
|
* 2000
|
|
* Modifier: Ivan Pascal The XFree86 Project
|
|
*/
|
|
|
|
/*
|
|
* The default locale loader.
|
|
* Supports: one byte per char (iso8859 like) locales.
|
|
* How: converts bytes to wide characters in a 1:1 manner.
|
|
* Platforms: all systems.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include "Xlibint.h"
|
|
#include "XlcGeneric.h"
|
|
|
|
#ifndef MB_LEN_MAX
|
|
#define MB_LEN_MAX 6
|
|
#endif
|
|
|
|
#if !defined(Lynx_22) && !defined(X_LOCALE)
|
|
#define STDCVT
|
|
#endif
|
|
|
|
#define GR 0x80
|
|
#define GL 0x7f
|
|
|
|
typedef struct _StateRec *State;
|
|
typedef struct _StateRec {
|
|
CodeSet GL_codeset;
|
|
CodeSet GR_codeset;
|
|
wchar_t wc_mask;
|
|
wchar_t wc_encode_mask;
|
|
Bool (*MBtoWC) (State state, const char *ch, wchar_t *wc);
|
|
Bool (*WCtoMB) (State state, wchar_t wc, char *ch);
|
|
} StateRec;
|
|
|
|
static
|
|
Bool MBtoWCdef(
|
|
State state,
|
|
const char *ch,
|
|
wchar_t *wc)
|
|
{
|
|
wchar_t wc_encoding;
|
|
CodeSet codeset = (*ch & GR) ? state->GR_codeset : state->GL_codeset;
|
|
if (!codeset)
|
|
return False;
|
|
wc_encoding = codeset->wc_encoding;
|
|
*wc = ((wchar_t) *ch & state->wc_mask) | wc_encoding;
|
|
return True;
|
|
}
|
|
|
|
#ifdef STDCVT
|
|
static
|
|
Bool MBtoWCstd(
|
|
State state,
|
|
const char *ch,
|
|
wchar_t *wc)
|
|
{
|
|
return (mbtowc(wc, ch, 1) == 1);
|
|
}
|
|
#endif
|
|
|
|
static
|
|
Bool WCtoMBdef(
|
|
State state,
|
|
wchar_t wc,
|
|
char *ch)
|
|
{
|
|
wchar_t wc_encoding = wc & state->wc_encode_mask;
|
|
CodeSet codeset;
|
|
|
|
codeset = state->GL_codeset;
|
|
if (codeset && (wc_encoding == codeset->wc_encoding)) {
|
|
*ch = wc & state->wc_mask;
|
|
return True;
|
|
}
|
|
codeset = state->GR_codeset;
|
|
if (codeset && (wc_encoding == codeset->wc_encoding)) {
|
|
*ch = (wc & state->wc_mask) | GR;
|
|
return True;
|
|
}
|
|
return False;
|
|
}
|
|
|
|
#ifdef STDCVT
|
|
static
|
|
Bool WCtoMBstd(
|
|
State state,
|
|
wchar_t wc,
|
|
char *ch)
|
|
{
|
|
return (wctomb(ch, wc) == 1);
|
|
}
|
|
#endif
|
|
|
|
static
|
|
XlcCharSet get_charset(
|
|
State state,
|
|
char side)
|
|
{
|
|
CodeSet codeset = side ? state->GR_codeset : state->GL_codeset;
|
|
if (codeset) {
|
|
int i;
|
|
XlcCharSet charset;
|
|
for (i = 0; i < codeset->num_charsets; i++) {
|
|
charset = codeset->charset_list[i];
|
|
if (*charset->ct_sequence != '\0')
|
|
return charset;
|
|
}
|
|
return *(codeset->charset_list);
|
|
}
|
|
return (XlcCharSet) NULL;
|
|
}
|
|
|
|
static int
|
|
def_mbstowcs(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const char *src;
|
|
wchar_t *dst = (wchar_t *) *to;
|
|
State state = (State) conv->state;
|
|
int unconv = 0;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const char *) *from;
|
|
|
|
while (*from_left && *to_left) {
|
|
(*from_left)--;
|
|
if (state->MBtoWC (state, src++, dst)) {
|
|
dst++;
|
|
(*to_left)--;
|
|
} else {
|
|
unconv++;
|
|
}
|
|
}
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return unconv;
|
|
}
|
|
|
|
static int
|
|
def_wcstombs(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const wchar_t *src;
|
|
char *dst = (char *) *to;
|
|
State state = (State) conv->state;
|
|
char ch[MB_LEN_MAX];
|
|
int unconv = 0;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const wchar_t *) *from;
|
|
|
|
while (*from_left && *to_left) {
|
|
(*from_left)--;
|
|
if (state->WCtoMB (state, *src++, ch)) {
|
|
*dst++ = *ch;
|
|
(*to_left)--;
|
|
} else {
|
|
unconv++;
|
|
}
|
|
}
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return unconv;
|
|
}
|
|
|
|
static int
|
|
mbstostr(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const char *src;
|
|
char *dst = (char *) *to;
|
|
CodeSet codeset;
|
|
State state = (State) conv->state;
|
|
char ch;
|
|
int unconv = 0;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const char *) *from;
|
|
|
|
while (*from_left && *to_left) {
|
|
ch = *src++;
|
|
(*from_left)--;
|
|
|
|
codeset = (ch & GR) ? state->GR_codeset : state->GL_codeset;
|
|
if (codeset && codeset->string_encoding) {
|
|
*dst++ = ch;
|
|
(*to_left)--;
|
|
} else {
|
|
unconv++;
|
|
}
|
|
}
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return unconv;
|
|
}
|
|
|
|
static int
|
|
wcstostr(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const wchar_t *src;
|
|
char *dst = (char *) *to;
|
|
CodeSet codeset;
|
|
State state = (State) conv->state;
|
|
char ch[MB_LEN_MAX];
|
|
int unconv = 0;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const wchar_t *) *from;
|
|
|
|
while (*from_left && *to_left) {
|
|
(*from_left)--;
|
|
if (state->WCtoMB (state, *src++, ch)) {
|
|
codeset = (*ch & GR) ? state->GR_codeset : state->GL_codeset;
|
|
if (codeset && codeset->string_encoding) {
|
|
*dst++ = *ch;
|
|
(*to_left)--;
|
|
} else {
|
|
unconv++;
|
|
}
|
|
} else {
|
|
unconv++;
|
|
}
|
|
}
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return unconv;
|
|
}
|
|
|
|
static int
|
|
mbstocs(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const char *src;
|
|
char *dst = (char *) *to;
|
|
int length;
|
|
State state = (State) conv->state;
|
|
char cur_side;
|
|
int unconv = 0;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const char *) *from;
|
|
length = min(*from_left, *to_left);
|
|
|
|
cur_side = *src & GR;
|
|
while (length) {
|
|
if ((char) (*src & GR) != cur_side)
|
|
break;
|
|
*dst++ = *src++;
|
|
length--;
|
|
}
|
|
|
|
if (num_args > 0) {
|
|
XlcCharSet charset = get_charset(state, cur_side);
|
|
if (charset) {
|
|
*((XlcCharSet *) args[0]) = charset;
|
|
} else {
|
|
dst = *to;
|
|
unconv = -1;
|
|
}
|
|
}
|
|
*from_left -= src - (char *) *from;
|
|
*to_left -= dst - (char *) *to;
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return unconv;
|
|
}
|
|
|
|
static int
|
|
wcstocs(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const wchar_t *src;
|
|
char *dst = (char *) *to;
|
|
State state = (State) conv->state;
|
|
char cur_side = 0, ch[MB_LEN_MAX];
|
|
int unconv = 0;
|
|
Bool found = False;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const wchar_t *) *from;
|
|
|
|
while (*from_left) {
|
|
if ((found = state->WCtoMB (state, *src, ch)))
|
|
break;
|
|
unconv++;
|
|
src++;
|
|
(*from_left)--;
|
|
}
|
|
|
|
if (found) {
|
|
cur_side = *ch & GR;
|
|
while (*from_left && *to_left) {
|
|
(*from_left)--;
|
|
if (state->WCtoMB (state, *src++, ch)) {
|
|
if ((char) (*ch & GR) != cur_side) {
|
|
src--;
|
|
(*from_left)++;
|
|
break;
|
|
} else {
|
|
*dst++ = *ch;
|
|
(*to_left)--;
|
|
}
|
|
} else {
|
|
unconv++;
|
|
}
|
|
}
|
|
} else {
|
|
unconv++;
|
|
}
|
|
|
|
if (num_args > 0) {
|
|
XlcCharSet charset = get_charset(state, cur_side);
|
|
if (charset) {
|
|
*((XlcCharSet *) args[0]) = charset;
|
|
} else {
|
|
unconv = -1;
|
|
}
|
|
}
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return unconv;
|
|
}
|
|
|
|
static int
|
|
cstombs(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const char *src;
|
|
char *dst = (char *) *to;
|
|
CodeSet codeset;
|
|
XlcCharSet charset;
|
|
State state = (State) conv->state;
|
|
unsigned char cur_side = 0;
|
|
int i;
|
|
Bool found = False;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const char *) *from;
|
|
|
|
if (num_args > 0) {
|
|
charset = (XlcCharSet) args[0];
|
|
if (charset == NULL)
|
|
return -1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
if ((charset->side == XlcGL) || (charset->side == XlcGLGR)) {
|
|
codeset = state->GL_codeset;
|
|
if (codeset) {
|
|
for (i = 0; i < codeset->num_charsets; i++)
|
|
if (charset == codeset->charset_list[i]) {
|
|
found = True;
|
|
cur_side = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!found && ((charset->side == XlcGR) || (charset->side == XlcGLGR))) {
|
|
codeset = state->GR_codeset;
|
|
if (codeset) {
|
|
for (i = 0; i < codeset->num_charsets; i++)
|
|
if (charset == codeset->charset_list[i]) {
|
|
found = True;
|
|
cur_side = GR;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (found) {
|
|
int length = min(*from_left, *to_left);
|
|
while (length) {
|
|
*dst++ = *src++ | cur_side;
|
|
length--;
|
|
}
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
*from_left -= src - (char *) *from;
|
|
*to_left -= dst - (char *) *to;
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
cstowcs(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const char *src;
|
|
wchar_t *dst = (wchar_t *) *to;
|
|
CodeSet codeset;
|
|
XlcCharSet charset;
|
|
State state = (State) conv->state;
|
|
Bool found = False;
|
|
int i, unconv = 0;
|
|
unsigned char cur_side = 0;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const char *) *from;
|
|
|
|
if (num_args > 0) {
|
|
charset = (XlcCharSet) args[0];
|
|
if (charset == NULL)
|
|
return -1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
if ((charset->side == XlcGL) || (charset->side == XlcGLGR)) {
|
|
codeset = state->GL_codeset;
|
|
if (codeset) {
|
|
for (i = 0; i < codeset->num_charsets; i++)
|
|
if (charset == codeset->charset_list[i]) {
|
|
found = True;
|
|
cur_side = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!found && ((charset->side == XlcGR) || (charset->side == XlcGLGR))) {
|
|
codeset = state->GR_codeset;
|
|
if (codeset) {
|
|
for (i = 0; i < codeset->num_charsets; i++)
|
|
if (charset == codeset->charset_list[i]) {
|
|
found = True;
|
|
cur_side = GR;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (found) {
|
|
char ch;
|
|
while (*from_left && *to_left) {
|
|
ch = *src++ | cur_side;
|
|
(*from_left)--;
|
|
if (state->MBtoWC (state, &ch, dst)) {
|
|
dst++;
|
|
(*to_left)--;
|
|
} else {
|
|
unconv++;
|
|
}
|
|
}
|
|
} else {
|
|
return -1;
|
|
}
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return unconv;
|
|
}
|
|
|
|
static int
|
|
strtombs(
|
|
XlcConv conv,
|
|
XPointer *from,
|
|
int *from_left,
|
|
XPointer *to,
|
|
int *to_left,
|
|
XPointer *args,
|
|
int num_args)
|
|
{
|
|
const char *src;
|
|
char *dst = (char *) *to;
|
|
int length;
|
|
|
|
if (from == NULL || *from == NULL)
|
|
return 0;
|
|
|
|
src = (const char *) *from;
|
|
length = min(*from_left, *to_left);
|
|
while (length) {
|
|
*dst++ = *src++;
|
|
length--;
|
|
}
|
|
|
|
*from_left -= src - (char *) *from;
|
|
*to_left -= dst - (char *) *to;
|
|
*from = (XPointer) src;
|
|
*to = (XPointer) dst;
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
close_converter(
|
|
XlcConv conv)
|
|
{
|
|
|
|
Xfree(conv->state);
|
|
Xfree(conv);
|
|
}
|
|
|
|
static XlcConv
|
|
create_conv(
|
|
XLCd lcd,
|
|
XlcConvMethods methods)
|
|
{
|
|
XlcConv conv;
|
|
State state;
|
|
|
|
conv = Xcalloc(1, sizeof(XlcConvRec));
|
|
if (conv == NULL)
|
|
return (XlcConv) NULL;
|
|
|
|
state = Xmalloc(sizeof(StateRec));
|
|
if (state == NULL) {
|
|
close_converter(conv);
|
|
return (XlcConv) NULL;
|
|
}
|
|
state->GL_codeset = XLC_GENERIC(lcd, initial_state_GL);
|
|
state->GR_codeset = XLC_GENERIC(lcd, initial_state_GR);
|
|
state->wc_mask = (1 << XLC_GENERIC(lcd, wc_shift_bits)) - 1;
|
|
state->wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask);
|
|
|
|
#ifdef STDCVT
|
|
if (XLC_GENERIC(lcd, use_stdc_env) == True)
|
|
state->MBtoWC = &MBtoWCstd;
|
|
else
|
|
#endif
|
|
state->MBtoWC = &MBtoWCdef;
|
|
|
|
#ifdef STDCVT
|
|
if (XLC_GENERIC(lcd, use_stdc_env) == True)
|
|
state->WCtoMB = &WCtoMBstd;
|
|
else
|
|
#endif
|
|
state->WCtoMB = &WCtoMBdef;
|
|
|
|
conv->methods = methods;
|
|
conv->state = (XPointer) state;
|
|
|
|
return conv;
|
|
}
|
|
|
|
static XlcConvMethodsRec mbstowcs_methods = {
|
|
close_converter,
|
|
def_mbstowcs,
|
|
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 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 wcstombs_methods = {
|
|
close_converter,
|
|
def_wcstombs,
|
|
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 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 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);
|
|
}
|
|
|
|
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 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);
|
|
}
|
|
|
|
XLCd
|
|
_XlcDefaultLoader(
|
|
const char *name)
|
|
{
|
|
XLCd lcd;
|
|
|
|
lcd = _XlcCreateLC(name, _XlcGenericMethods);
|
|
if (lcd == NULL)
|
|
return lcd;
|
|
|
|
if (XLC_PUBLIC(lcd, mb_cur_max) != 1){
|
|
_XlcDestroyLC(lcd);
|
|
return (XLCd) NULL;
|
|
}
|
|
|
|
_XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs);
|
|
_XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr);
|
|
_XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
|
|
_XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbstocs);
|
|
|
|
_XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs);
|
|
_XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr);
|
|
_XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
|
|
|
|
_XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs);
|
|
_XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_mbstowcs);
|
|
|
|
_XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
|
|
_XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
|
|
|
|
_XlcAddUtf8Converters(lcd);
|
|
|
|
return lcd;
|
|
}
|