Home | History | Annotate | Line # | Download | only in xlibi18n
      1 /*
      2  * Copyright 1992, 1993 by TOSHIBA Corp.
      3  *
      4  * Permission to use, copy, modify, and distribute this software and its
      5  * documentation for any purpose and without fee is hereby granted, provided
      6  * that the above copyright notice appear in all copies and that both that
      7  * copyright notice and this permission notice appear in supporting
      8  * documentation, and that the name of TOSHIBA not be used in advertising
      9  * or publicity pertaining to distribution of the software without specific,
     10  * written prior permission. TOSHIBA make no representations about the
     11  * suitability of this software for any purpose.  It is provided "as is"
     12  * without express or implied warranty.
     13  *
     14  * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     15  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
     16  * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     17  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     18  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     19  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     20  * SOFTWARE.
     21  *
     22  * Author: Katsuhisa Yano	TOSHIBA Corp.
     23  *			   	mopi (at) osa.ilab.toshiba.co.jp
     24  */
     25 
     26 #ifdef HAVE_CONFIG_H
     27 #include <config.h>
     28 #endif
     29 #include "Xlibint.h"
     30 #include "XlcPubI.h"
     31 #include <X11/Xutil.h>
     32 #include <X11/Xatom.h>
     33 #include <stdio.h>
     34 
     35 static int
     36 get_buf_size(
     37     Bool is_wide_char,
     38     XPointer list,
     39     int count)
     40 {
     41     int length = 0;
     42     char **mb_list;
     43     wchar_t **wc_list;
     44 
     45     if (list == NULL)
     46 	return 0;
     47 
     48     if (is_wide_char) {
     49 	wc_list = (wchar_t **) list;
     50 	for ( ; count-- > 0; wc_list++) {
     51 	    if (*wc_list)
     52 		length += _Xwcslen(*wc_list) + 1;
     53 	}
     54 	length *= 5;	/* XXX */
     55     } else {
     56 	mb_list = (char **) list;
     57 	for ( ; count-- > 0; mb_list++) {
     58 	    if (*mb_list)
     59 		length = (int) ((size_t) length + (strlen(*mb_list) + 1));
     60 	}
     61 	length *= 3;	/* XXX */
     62     }
     63     length = (length / BUFSIZ + 1) * BUFSIZ;	/* XXX */
     64 
     65     return length;
     66 }
     67 
     68 static int
     69 _XTextListToTextProperty(
     70     XLCd lcd,
     71     Display *dpy,
     72     const char *from_type,
     73     XPointer list,
     74     int count,
     75     XICCEncodingStyle style,
     76     XTextProperty *text_prop)
     77 {
     78     Atom encoding;
     79     XlcConv conv;
     80     const char *to_type;
     81     char **mb_list = NULL;
     82     wchar_t **wc_list = NULL;
     83     XPointer from;
     84     char *to, *buf, *value;
     85     int from_left, to_left, buf_len, nitems, unconv_num = 0, ret, i;
     86     Bool is_wide_char = False;
     87 
     88     if (strcmp(XlcNWideChar, from_type) == 0)
     89 	is_wide_char = True;
     90 
     91     buf_len = get_buf_size(is_wide_char, list, count);
     92     if ((buf = Xmalloc(buf_len)) == NULL)
     93 	return XNoMemory;
     94 
     95     switch (style) {
     96 	case XStringStyle:
     97 	case XStdICCTextStyle:
     98 	    encoding = XA_STRING;
     99 	    to_type = XlcNString;
    100 	    break;
    101 	case XUTF8StringStyle:
    102 	    encoding = XInternAtom(dpy, "UTF8_STRING", False);
    103 	    to_type = XlcNUtf8String;
    104 	    break;
    105 	case XCompoundTextStyle:
    106 	    encoding = XInternAtom(dpy, "COMPOUND_TEXT", False);
    107 	    to_type = XlcNCompoundText;
    108 	    break;
    109 	case XTextStyle:
    110 	    encoding = XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False);
    111 	    to_type = XlcNMultiByte;
    112 	    if (is_wide_char == False) {
    113 		nitems = 0;
    114 		mb_list = (char **) list;
    115 		to = buf;
    116 		for (i = 0; i < count && buf_len > 0; i++) {
    117 		    if (*mb_list)
    118 			strcpy(to, *mb_list);
    119 		    else
    120 			*to = '\0';
    121 		    from_left = (int) (*mb_list ? strlen(*mb_list) : 0) + 1;
    122 		    nitems += from_left;
    123 		    to += from_left;
    124 		    mb_list++;
    125 		}
    126 		unconv_num = 0;
    127 		goto done;
    128 	    }
    129 	    break;
    130 	default:
    131 	    Xfree(buf);
    132 	    return XConverterNotFound;
    133     }
    134 
    135     if (count < 1) {
    136 	nitems = 0;
    137 	goto done;
    138     }
    139 
    140 retry:
    141     conv = _XlcOpenConverter(lcd, from_type, lcd, to_type);
    142     if (conv == NULL) {
    143 	Xfree(buf);
    144 	return XConverterNotFound;
    145     }
    146 
    147     if (is_wide_char)
    148 	wc_list = (wchar_t **) list;
    149     else
    150 	mb_list = (char **) list;
    151 
    152     to = buf;
    153     to_left = buf_len;
    154 
    155     unconv_num = 0;
    156 
    157     for (i = 1; to_left > 0; i++) {
    158 	if (is_wide_char) {
    159 	    from = (XPointer) *wc_list;
    160 	    from_left = _Xwcslen(*wc_list);
    161 	    wc_list++;
    162 	} else {
    163 	    from = (XPointer) *mb_list;
    164 	    from_left = (int) (*mb_list ? strlen(*mb_list) : 0);
    165 	    mb_list++;
    166 	}
    167 
    168 	ret = _XlcConvert(conv, &from, &from_left, (XPointer *) &to, &to_left,
    169 			  NULL, 0);
    170 
    171 	if (ret < 0)
    172 	    continue;
    173 
    174 	if (ret > 0 && style == XStdICCTextStyle && encoding == XA_STRING) {
    175 	    _XlcCloseConverter(conv);
    176 	    encoding = XInternAtom(dpy, "COMPOUND_TEXT", False);
    177 	    to_type = XlcNCompoundText;
    178 	    goto retry;
    179 	}
    180 
    181 	unconv_num += ret;
    182 	*to++ = '\0';
    183 	to_left--;
    184 
    185 	if (i >= count)
    186 	    break;
    187 
    188 	_XlcResetConverter(conv);
    189     }
    190 
    191     _XlcCloseConverter(conv);
    192 
    193     nitems = (int) (to - buf);
    194 done:
    195     if (nitems <= 0)
    196 	nitems = 1;
    197     value = Xmalloc(nitems);
    198     if (value == NULL) {
    199 	Xfree(buf);
    200 	return XNoMemory;
    201     }
    202     if (nitems == 1)
    203 	*value = 0;
    204     else
    205     	memcpy(value, buf, (size_t) nitems);
    206     nitems--;
    207     Xfree(buf);
    208 
    209     text_prop->value = (unsigned char *) value;
    210     text_prop->encoding = encoding;
    211     text_prop->format = 8;
    212     text_prop->nitems = (unsigned long) nitems;
    213 
    214     return unconv_num;
    215 }
    216 
    217 int
    218 _XmbTextListToTextProperty(
    219     XLCd lcd,
    220     Display *dpy,
    221     char **list,
    222     int count,
    223     XICCEncodingStyle style,
    224     XTextProperty *text_prop)
    225 {
    226     return _XTextListToTextProperty(lcd, dpy, XlcNMultiByte, (XPointer) list,
    227 				    count, style, text_prop);
    228 }
    229 
    230 int
    231 _XwcTextListToTextProperty(
    232     XLCd lcd,
    233     Display *dpy,
    234     wchar_t **list,
    235     int count,
    236     XICCEncodingStyle style,
    237     XTextProperty *text_prop)
    238 {
    239     return _XTextListToTextProperty(lcd, dpy, XlcNWideChar, (XPointer) list,
    240 				    count, style, text_prop);
    241 }
    242 
    243 int
    244 _Xutf8TextListToTextProperty(
    245     XLCd lcd,
    246     Display *dpy,
    247     char **list,
    248     int count,
    249     XICCEncodingStyle style,
    250     XTextProperty *text_prop)
    251 {
    252     return _XTextListToTextProperty(lcd, dpy, XlcNUtf8String, (XPointer) list,
    253 				    count, style, text_prop);
    254 }
    255