lcConv.c revision 1ab64890
11ab64890Smrg/* $Xorg: lcConv.c,v 1.4 2000/08/17 19:45:17 cpqbld Exp $ */ 21ab64890Smrg/* 31ab64890Smrg * Copyright 1992, 1993 by TOSHIBA Corp. 41ab64890Smrg * 51ab64890Smrg * Permission to use, copy, modify, and distribute this software and its 61ab64890Smrg * documentation for any purpose and without fee is hereby granted, provided 71ab64890Smrg * that the above copyright notice appear in all copies and that both that 81ab64890Smrg * copyright notice and this permission notice appear in supporting 91ab64890Smrg * documentation, and that the name of TOSHIBA not be used in advertising 101ab64890Smrg * or publicity pertaining to distribution of the software without specific, 111ab64890Smrg * written prior permission. TOSHIBA make no representations about the 121ab64890Smrg * suitability of this software for any purpose. It is provided "as is" 131ab64890Smrg * without express or implied warranty. 141ab64890Smrg * 151ab64890Smrg * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 161ab64890Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 171ab64890Smrg * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 181ab64890Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 191ab64890Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 201ab64890Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 211ab64890Smrg * SOFTWARE. 221ab64890Smrg * 231ab64890Smrg * Author: Katsuhisa Yano TOSHIBA Corp. 241ab64890Smrg * mopi@osa.ilab.toshiba.co.jp 251ab64890Smrg */ 261ab64890Smrg/* $XFree86: xc/lib/X11/lcConv.c,v 1.5 2000/12/04 18:49:26 dawes Exp $ */ 271ab64890Smrg 281ab64890Smrg#ifdef HAVE_CONFIG_H 291ab64890Smrg#include <config.h> 301ab64890Smrg#endif 311ab64890Smrg#include "Xlibint.h" 321ab64890Smrg#include "XlcPubI.h" 331ab64890Smrg#include <stdio.h> 341ab64890Smrg 351ab64890Smrgtypedef struct _XlcConverterListRec { 361ab64890Smrg XLCd from_lcd; 371ab64890Smrg const char *from; 381ab64890Smrg XrmQuark from_type; 391ab64890Smrg XLCd to_lcd; 401ab64890Smrg const char *to; 411ab64890Smrg XrmQuark to_type; 421ab64890Smrg XlcOpenConverterProc converter; 431ab64890Smrg struct _XlcConverterListRec *next; 441ab64890Smrg} XlcConverterListRec, *XlcConverterList; 451ab64890Smrg 461ab64890Smrgstatic XlcConverterList conv_list = NULL; 471ab64890Smrg 481ab64890Smrgstatic void 491ab64890Smrgclose_converter( 501ab64890Smrg XlcConv conv) 511ab64890Smrg{ 521ab64890Smrg (*conv->methods->close)(conv); 531ab64890Smrg} 541ab64890Smrg 551ab64890Smrgstatic XlcConv 561ab64890Smrgget_converter( 571ab64890Smrg XLCd from_lcd, 581ab64890Smrg XrmQuark from_type, 591ab64890Smrg XLCd to_lcd, 601ab64890Smrg XrmQuark to_type) 611ab64890Smrg{ 621ab64890Smrg XlcConverterList list, prev = NULL; 631ab64890Smrg 641ab64890Smrg for (list = conv_list; list; list = list->next) { 651ab64890Smrg if (list->from_lcd == from_lcd && list->to_lcd == to_lcd 661ab64890Smrg && list->from_type == from_type && list->to_type == to_type) { 671ab64890Smrg 681ab64890Smrg if (prev && prev != conv_list) { /* XXX */ 691ab64890Smrg prev->next = list->next; 701ab64890Smrg list->next = conv_list; 711ab64890Smrg conv_list = list; 721ab64890Smrg } 731ab64890Smrg 741ab64890Smrg return (*list->converter)(from_lcd, list->from, to_lcd, list->to); 751ab64890Smrg } 761ab64890Smrg 771ab64890Smrg prev = list; 781ab64890Smrg } 791ab64890Smrg 801ab64890Smrg return (XlcConv) NULL; 811ab64890Smrg} 821ab64890Smrg 831ab64890SmrgBool 841ab64890Smrg_XlcSetConverter( 851ab64890Smrg XLCd from_lcd, 861ab64890Smrg const char *from, 871ab64890Smrg XLCd to_lcd, 881ab64890Smrg const char *to, 891ab64890Smrg XlcOpenConverterProc converter) 901ab64890Smrg{ 911ab64890Smrg XlcConverterList list; 921ab64890Smrg XrmQuark from_type, to_type; 931ab64890Smrg 941ab64890Smrg from_type = XrmStringToQuark(from); 951ab64890Smrg to_type = XrmStringToQuark(to); 961ab64890Smrg 971ab64890Smrg for (list = conv_list; list; list = list->next) { 981ab64890Smrg if (list->from_lcd == from_lcd && list->to_lcd == to_lcd 991ab64890Smrg && list->from_type == from_type && list->to_type == to_type) { 1001ab64890Smrg 1011ab64890Smrg list->converter = converter; 1021ab64890Smrg return True; 1031ab64890Smrg } 1041ab64890Smrg } 1051ab64890Smrg 1061ab64890Smrg list = (XlcConverterList) Xmalloc(sizeof(XlcConverterListRec)); 1071ab64890Smrg if (list == NULL) 1081ab64890Smrg return False; 1091ab64890Smrg 1101ab64890Smrg list->from_lcd = from_lcd; 1111ab64890Smrg list->from = from; 1121ab64890Smrg list->from_type = from_type; 1131ab64890Smrg list->to_lcd = to_lcd; 1141ab64890Smrg list->to = to; 1151ab64890Smrg list->to_type = to_type; 1161ab64890Smrg list->converter = converter; 1171ab64890Smrg list->next = conv_list; 1181ab64890Smrg conv_list = list; 1191ab64890Smrg 1201ab64890Smrg return True; 1211ab64890Smrg} 1221ab64890Smrg 1231ab64890Smrgtypedef struct _ConvRec { 1241ab64890Smrg XlcConv from_conv; 1251ab64890Smrg XlcConv to_conv; 1261ab64890Smrg} ConvRec, *Conv; 1271ab64890Smrg 1281ab64890Smrgstatic int 1291ab64890Smrgindirect_convert( 1301ab64890Smrg XlcConv lc_conv, 1311ab64890Smrg XPointer *from, 1321ab64890Smrg int *from_left, 1331ab64890Smrg XPointer *to, 1341ab64890Smrg int *to_left, 1351ab64890Smrg XPointer *args, 1361ab64890Smrg int num_args) 1371ab64890Smrg{ 1381ab64890Smrg Conv conv = (Conv) lc_conv->state; 1391ab64890Smrg XlcConv from_conv = conv->from_conv; 1401ab64890Smrg XlcConv to_conv = conv->to_conv; 1411ab64890Smrg XlcCharSet charset; 1421ab64890Smrg char buf[BUFSIZ], *cs; 1431ab64890Smrg XPointer tmp_args[1]; 1441ab64890Smrg int cs_left, ret, length, unconv_num = 0; 1451ab64890Smrg 1461ab64890Smrg if (from == NULL || *from == NULL) { 1471ab64890Smrg if (from_conv->methods->reset) 1481ab64890Smrg (*from_conv->methods->reset)(from_conv); 1491ab64890Smrg 1501ab64890Smrg if (to_conv->methods->reset) 1511ab64890Smrg (*to_conv->methods->reset)(to_conv); 1521ab64890Smrg 1531ab64890Smrg return 0; 1541ab64890Smrg } 1551ab64890Smrg 1561ab64890Smrg while (*from_left > 0) { 1571ab64890Smrg cs = buf; 1581ab64890Smrg cs_left = BUFSIZ; 1591ab64890Smrg tmp_args[0] = (XPointer) &charset; 1601ab64890Smrg 1611ab64890Smrg ret = (*from_conv->methods->convert)(from_conv, from, from_left, &cs, 1621ab64890Smrg &cs_left, tmp_args, 1); 1631ab64890Smrg if (ret < 0) 1641ab64890Smrg break; 1651ab64890Smrg 1661ab64890Smrg unconv_num += ret; 1671ab64890Smrg 1681ab64890Smrg length = cs - buf; 1691ab64890Smrg if (length > 0) { 1701ab64890Smrg cs_left = length; 1711ab64890Smrg cs = buf; 1721ab64890Smrg 1731ab64890Smrg tmp_args[0] = (XPointer) charset; 1741ab64890Smrg 1751ab64890Smrg ret = (*to_conv->methods->convert)(to_conv, &cs, &cs_left, to, to_left, 1761ab64890Smrg tmp_args, 1); 1771ab64890Smrg if (ret < 0) { 1781ab64890Smrg unconv_num += length / (charset->char_size > 0 ? charset->char_size : 1); 1791ab64890Smrg continue; 1801ab64890Smrg } 1811ab64890Smrg 1821ab64890Smrg unconv_num += ret; 1831ab64890Smrg 1841ab64890Smrg if (*to_left < 1) 1851ab64890Smrg break; 1861ab64890Smrg } 1871ab64890Smrg } 1881ab64890Smrg 1891ab64890Smrg return unconv_num; 1901ab64890Smrg} 1911ab64890Smrg 1921ab64890Smrgstatic void 1931ab64890Smrgclose_indirect_converter( 1941ab64890Smrg XlcConv lc_conv) 1951ab64890Smrg{ 1961ab64890Smrg Conv conv = (Conv) lc_conv->state; 1971ab64890Smrg 1981ab64890Smrg if (conv) { 1991ab64890Smrg if (conv->from_conv) 2001ab64890Smrg close_converter(conv->from_conv); 2011ab64890Smrg if (conv->to_conv) 2021ab64890Smrg close_converter(conv->to_conv); 2031ab64890Smrg 2041ab64890Smrg Xfree((char *) conv); 2051ab64890Smrg } 2061ab64890Smrg 2071ab64890Smrg Xfree((char *) lc_conv); 2081ab64890Smrg} 2091ab64890Smrg 2101ab64890Smrgstatic void 2111ab64890Smrgreset_indirect_converter( 2121ab64890Smrg XlcConv lc_conv) 2131ab64890Smrg{ 2141ab64890Smrg Conv conv = (Conv) lc_conv->state; 2151ab64890Smrg 2161ab64890Smrg if (conv) { 2171ab64890Smrg if (conv->from_conv && conv->from_conv->methods->reset) 2181ab64890Smrg (*conv->from_conv->methods->reset)(conv->from_conv); 2191ab64890Smrg if (conv->to_conv && conv->to_conv->methods->reset) 2201ab64890Smrg (*conv->to_conv->methods->reset)(conv->to_conv); 2211ab64890Smrg } 2221ab64890Smrg} 2231ab64890Smrg 2241ab64890Smrgstatic XlcConvMethodsRec conv_methods = { 2251ab64890Smrg close_indirect_converter, 2261ab64890Smrg indirect_convert, 2271ab64890Smrg reset_indirect_converter 2281ab64890Smrg} ; 2291ab64890Smrg 2301ab64890Smrgstatic XlcConv 2311ab64890Smrgopen_indirect_converter( 2321ab64890Smrg XLCd from_lcd, 2331ab64890Smrg const char *from, 2341ab64890Smrg XLCd to_lcd, 2351ab64890Smrg const char *to) 2361ab64890Smrg{ 2371ab64890Smrg XlcConv lc_conv, from_conv, to_conv; 2381ab64890Smrg Conv conv; 2391ab64890Smrg XrmQuark from_type, to_type; 2401ab64890Smrg static XrmQuark QChar, QCharSet, QCTCharSet = (XrmQuark) 0; 2411ab64890Smrg 2421ab64890Smrg if (QCTCharSet == (XrmQuark) 0) { 2431ab64890Smrg QCTCharSet = XrmStringToQuark(XlcNCTCharSet); 2441ab64890Smrg QCharSet = XrmStringToQuark(XlcNCharSet); 2451ab64890Smrg QChar = XrmStringToQuark(XlcNChar); 2461ab64890Smrg } 2471ab64890Smrg 2481ab64890Smrg from_type = XrmStringToQuark(from); 2491ab64890Smrg to_type = XrmStringToQuark(to); 2501ab64890Smrg 2511ab64890Smrg if (from_type == QCharSet || from_type == QChar || to_type == QCharSet || 2521ab64890Smrg to_type == QChar) 2531ab64890Smrg return (XlcConv) NULL; 2541ab64890Smrg 2551ab64890Smrg lc_conv = (XlcConv) Xmalloc(sizeof(XlcConvRec)); 2561ab64890Smrg if (lc_conv == NULL) 2571ab64890Smrg return (XlcConv) NULL; 2581ab64890Smrg 2591ab64890Smrg lc_conv->methods = &conv_methods; 2601ab64890Smrg 2611ab64890Smrg lc_conv->state = (XPointer) Xcalloc(1, sizeof(ConvRec)); 2621ab64890Smrg if (lc_conv->state == NULL) 2631ab64890Smrg goto err; 2641ab64890Smrg 2651ab64890Smrg conv = (Conv) lc_conv->state; 2661ab64890Smrg 2671ab64890Smrg from_conv = get_converter(from_lcd, from_type, from_lcd, QCTCharSet); 2681ab64890Smrg if (from_conv == NULL) 2691ab64890Smrg from_conv = get_converter(from_lcd, from_type, from_lcd, QCharSet); 2701ab64890Smrg if (from_conv == NULL) 2711ab64890Smrg from_conv = get_converter((XLCd)NULL, from_type, (XLCd)NULL, QCharSet); 2721ab64890Smrg if (from_conv == NULL) 2731ab64890Smrg from_conv = get_converter(from_lcd, from_type, from_lcd, QChar); 2741ab64890Smrg if (from_conv == NULL) 2751ab64890Smrg goto err; 2761ab64890Smrg conv->from_conv = from_conv; 2771ab64890Smrg 2781ab64890Smrg to_conv = get_converter(to_lcd, QCTCharSet, to_lcd, to_type); 2791ab64890Smrg if (to_conv == NULL) 2801ab64890Smrg to_conv = get_converter(to_lcd, QCharSet, to_lcd, to_type); 2811ab64890Smrg if (to_conv == NULL) 2821ab64890Smrg to_conv = get_converter((XLCd) NULL, QCharSet, (XLCd) NULL, to_type); 2831ab64890Smrg if (to_conv == NULL) 2841ab64890Smrg goto err; 2851ab64890Smrg conv->to_conv = to_conv; 2861ab64890Smrg 2871ab64890Smrg return lc_conv; 2881ab64890Smrg 2891ab64890Smrgerr: 2901ab64890Smrg close_indirect_converter(lc_conv); 2911ab64890Smrg 2921ab64890Smrg return (XlcConv) NULL; 2931ab64890Smrg} 2941ab64890Smrg 2951ab64890SmrgXlcConv 2961ab64890Smrg_XlcOpenConverter( 2971ab64890Smrg XLCd from_lcd, 2981ab64890Smrg const char *from, 2991ab64890Smrg XLCd to_lcd, 3001ab64890Smrg const char *to) 3011ab64890Smrg{ 3021ab64890Smrg XlcConv conv; 3031ab64890Smrg XrmQuark from_type, to_type; 3041ab64890Smrg 3051ab64890Smrg from_type = XrmStringToQuark(from); 3061ab64890Smrg to_type = XrmStringToQuark(to); 3071ab64890Smrg 3081ab64890Smrg if ((conv = get_converter(from_lcd, from_type, to_lcd, to_type))) 3091ab64890Smrg return conv; 3101ab64890Smrg 3111ab64890Smrg return open_indirect_converter(from_lcd, from, to_lcd, to); 3121ab64890Smrg} 3131ab64890Smrg 3141ab64890Smrgvoid 3151ab64890Smrg_XlcCloseConverter( 3161ab64890Smrg XlcConv conv) 3171ab64890Smrg{ 3181ab64890Smrg close_converter(conv); 3191ab64890Smrg} 3201ab64890Smrg 3211ab64890Smrgint 3221ab64890Smrg_XlcConvert( 3231ab64890Smrg XlcConv conv, 3241ab64890Smrg XPointer *from, 3251ab64890Smrg int *from_left, 3261ab64890Smrg XPointer *to, 3271ab64890Smrg int *to_left, 3281ab64890Smrg XPointer *args, 3291ab64890Smrg int num_args) 3301ab64890Smrg{ 3311ab64890Smrg return (*conv->methods->convert)(conv, from, from_left, to, to_left, args, 3321ab64890Smrg num_args); 3331ab64890Smrg} 3341ab64890Smrg 3351ab64890Smrgvoid 3361ab64890Smrg_XlcResetConverter( 3371ab64890Smrg XlcConv conv) 3381ab64890Smrg{ 3391ab64890Smrg if (conv->methods->reset) 3401ab64890Smrg (*conv->methods->reset)(conv); 3411ab64890Smrg} 342