11ab64890Smrg/*
21ab64890Smrg * Copyright 1992, 1993 by TOSHIBA Corp.
31ab64890Smrg *
41ab64890Smrg * Permission to use, copy, modify, and distribute this software and its
51ab64890Smrg * documentation for any purpose and without fee is hereby granted, provided
61ab64890Smrg * that the above copyright notice appear in all copies and that both that
71ab64890Smrg * copyright notice and this permission notice appear in supporting
81ab64890Smrg * documentation, and that the name of TOSHIBA not be used in advertising
91ab64890Smrg * or publicity pertaining to distribution of the software without specific,
101ab64890Smrg * written prior permission. TOSHIBA make no representations about the
111ab64890Smrg * suitability of this software for any purpose.  It is provided "as is"
121ab64890Smrg * without express or implied warranty.
131ab64890Smrg *
141ab64890Smrg * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
151ab64890Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
161ab64890Smrg * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
171ab64890Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
181ab64890Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
191ab64890Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
201ab64890Smrg * SOFTWARE.
211ab64890Smrg *
221ab64890Smrg * Author: Katsuhisa Yano	TOSHIBA Corp.
231ab64890Smrg *			   	mopi@osa.ilab.toshiba.co.jp
241ab64890Smrg */
251ab64890Smrg
261ab64890Smrg#ifdef HAVE_CONFIG_H
271ab64890Smrg#include <config.h>
281ab64890Smrg#endif
291ab64890Smrg#include "Xlibint.h"
301ab64890Smrg#include "XlcPubI.h"
311ab64890Smrg#include <X11/Xutil.h>
321ab64890Smrg#include <X11/Xatom.h>
331ab64890Smrg#include <stdio.h>
341ab64890Smrg
351ab64890Smrgstatic int
361ab64890Smrgget_buf_size(
371ab64890Smrg    Bool is_wide_char,
381ab64890Smrg    XPointer list,
391ab64890Smrg    int count)
401ab64890Smrg{
411ab64890Smrg    int length = 0;
421ab64890Smrg    char **mb_list;
431ab64890Smrg    wchar_t **wc_list;
441ab64890Smrg
451ab64890Smrg    if (list == NULL)
461ab64890Smrg	return 0;
471ab64890Smrg
481ab64890Smrg    if (is_wide_char) {
491ab64890Smrg	wc_list = (wchar_t **) list;
501ab64890Smrg	for ( ; count-- > 0; wc_list++) {
511ab64890Smrg	    if (*wc_list)
521ab64890Smrg		length += _Xwcslen(*wc_list) + 1;
531ab64890Smrg	}
541ab64890Smrg	length *= 5;	/* XXX */
551ab64890Smrg    } else {
561ab64890Smrg	mb_list = (char **) list;
571ab64890Smrg	for ( ; count-- > 0; mb_list++) {
581ab64890Smrg	    if (*mb_list)
599c019ec5Smaya		length = (int) ((size_t) length + (strlen(*mb_list) + 1));
601ab64890Smrg	}
611ab64890Smrg	length *= 3;	/* XXX */
621ab64890Smrg    }
631ab64890Smrg    length = (length / BUFSIZ + 1) * BUFSIZ;	/* XXX */
641ab64890Smrg
651ab64890Smrg    return length;
661ab64890Smrg}
671ab64890Smrg
681ab64890Smrgstatic int
691ab64890Smrg_XTextListToTextProperty(
701ab64890Smrg    XLCd lcd,
711ab64890Smrg    Display *dpy,
721ab64890Smrg    const char *from_type,
731ab64890Smrg    XPointer list,
741ab64890Smrg    int count,
751ab64890Smrg    XICCEncodingStyle style,
761ab64890Smrg    XTextProperty *text_prop)
771ab64890Smrg{
781ab64890Smrg    Atom encoding;
791ab64890Smrg    XlcConv conv;
801ab64890Smrg    const char *to_type;
811ab64890Smrg    char **mb_list = NULL;
821ab64890Smrg    wchar_t **wc_list = NULL;
831ab64890Smrg    XPointer from;
841ab64890Smrg    char *to, *buf, *value;
851ab64890Smrg    int from_left, to_left, buf_len, nitems, unconv_num = 0, ret, i;
861ab64890Smrg    Bool is_wide_char = False;
871ab64890Smrg
881ab64890Smrg    if (strcmp(XlcNWideChar, from_type) == 0)
891ab64890Smrg	is_wide_char = True;
901ab64890Smrg
911ab64890Smrg    buf_len = get_buf_size(is_wide_char, list, count);
92818534a1Smrg    if ((buf = Xmalloc(buf_len)) == NULL)
931ab64890Smrg	return XNoMemory;
9461b2299dSmrg
951ab64890Smrg    switch (style) {
961ab64890Smrg	case XStringStyle:
971ab64890Smrg	case XStdICCTextStyle:
981ab64890Smrg	    encoding = XA_STRING;
991ab64890Smrg	    to_type = XlcNString;
1001ab64890Smrg	    break;
1011ab64890Smrg	case XUTF8StringStyle:
1021ab64890Smrg	    encoding = XInternAtom(dpy, "UTF8_STRING", False);
1031ab64890Smrg	    to_type = XlcNUtf8String;
1041ab64890Smrg	    break;
1051ab64890Smrg	case XCompoundTextStyle:
1061ab64890Smrg	    encoding = XInternAtom(dpy, "COMPOUND_TEXT", False);
1071ab64890Smrg	    to_type = XlcNCompoundText;
1081ab64890Smrg	    break;
1091ab64890Smrg	case XTextStyle:
1101ab64890Smrg	    encoding = XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False);
1111ab64890Smrg	    to_type = XlcNMultiByte;
1121ab64890Smrg	    if (is_wide_char == False) {
1131ab64890Smrg		nitems = 0;
1141ab64890Smrg		mb_list = (char **) list;
1151ab64890Smrg		to = buf;
1161ab64890Smrg		for (i = 0; i < count && buf_len > 0; i++) {
11761b2299dSmrg		    if (*mb_list)
1181ab64890Smrg			strcpy(to, *mb_list);
1191ab64890Smrg		    else
1201ab64890Smrg			*to = '\0';
1219c019ec5Smaya		    from_left = (int) (*mb_list ? strlen(*mb_list) : 0) + 1;
1221ab64890Smrg		    nitems += from_left;
1231ab64890Smrg		    to += from_left;
1241ab64890Smrg		    mb_list++;
1251ab64890Smrg		}
1261ab64890Smrg		unconv_num = 0;
1271ab64890Smrg		goto done;
1281ab64890Smrg	    }
1291ab64890Smrg	    break;
1301ab64890Smrg	default:
1311ab64890Smrg	    Xfree(buf);
1321ab64890Smrg	    return XConverterNotFound;
1331ab64890Smrg    }
1341ab64890Smrg
1351ab64890Smrg    if (count < 1) {
1361ab64890Smrg	nitems = 0;
1371ab64890Smrg	goto done;
1381ab64890Smrg    }
1391ab64890Smrg
1401ab64890Smrgretry:
1411ab64890Smrg    conv = _XlcOpenConverter(lcd, from_type, lcd, to_type);
1421ab64890Smrg    if (conv == NULL) {
1431ab64890Smrg	Xfree(buf);
1441ab64890Smrg	return XConverterNotFound;
1451ab64890Smrg    }
1461ab64890Smrg
1471ab64890Smrg    if (is_wide_char)
1481ab64890Smrg	wc_list = (wchar_t **) list;
1491ab64890Smrg    else
1501ab64890Smrg	mb_list = (char **) list;
1511ab64890Smrg
1521ab64890Smrg    to = buf;
1531ab64890Smrg    to_left = buf_len;
1541ab64890Smrg
1551ab64890Smrg    unconv_num = 0;
1561ab64890Smrg
1571ab64890Smrg    for (i = 1; to_left > 0; i++) {
1581ab64890Smrg	if (is_wide_char) {
1591ab64890Smrg	    from = (XPointer) *wc_list;
1601ab64890Smrg	    from_left = _Xwcslen(*wc_list);
1611ab64890Smrg	    wc_list++;
1621ab64890Smrg	} else {
1631ab64890Smrg	    from = (XPointer) *mb_list;
1649c019ec5Smaya	    from_left = (int) (*mb_list ? strlen(*mb_list) : 0);
1651ab64890Smrg	    mb_list++;
1661ab64890Smrg	}
1671ab64890Smrg
1681ab64890Smrg	ret = _XlcConvert(conv, &from, &from_left, (XPointer *) &to, &to_left,
1691ab64890Smrg			  NULL, 0);
1701ab64890Smrg
1711ab64890Smrg	if (ret < 0)
1721ab64890Smrg	    continue;
1731ab64890Smrg
1741ab64890Smrg	if (ret > 0 && style == XStdICCTextStyle && encoding == XA_STRING) {
1751ab64890Smrg	    _XlcCloseConverter(conv);
1761ab64890Smrg	    encoding = XInternAtom(dpy, "COMPOUND_TEXT", False);
1771ab64890Smrg	    to_type = XlcNCompoundText;
1781ab64890Smrg	    goto retry;
1791ab64890Smrg	}
1801ab64890Smrg
1811ab64890Smrg	unconv_num += ret;
1821ab64890Smrg	*to++ = '\0';
1831ab64890Smrg	to_left--;
1841ab64890Smrg
1851ab64890Smrg	if (i >= count)
1861ab64890Smrg	    break;
1871ab64890Smrg
1881ab64890Smrg	_XlcResetConverter(conv);
1891ab64890Smrg    }
1901ab64890Smrg
1911ab64890Smrg    _XlcCloseConverter(conv);
1921ab64890Smrg
1939c019ec5Smaya    nitems = (int) (to - buf);
1941ab64890Smrgdone:
1951ab64890Smrg    if (nitems <= 0)
1961ab64890Smrg	nitems = 1;
197818534a1Smrg    value = Xmalloc(nitems);
1981ab64890Smrg    if (value == NULL) {
1991ab64890Smrg	Xfree(buf);
2001ab64890Smrg	return XNoMemory;
2011ab64890Smrg    }
2021ab64890Smrg    if (nitems == 1)
2031ab64890Smrg	*value = 0;
2041ab64890Smrg    else
2059c019ec5Smaya    	memcpy(value, buf, (size_t) nitems);
2061ab64890Smrg    nitems--;
2071ab64890Smrg    Xfree(buf);
2081ab64890Smrg
2091ab64890Smrg    text_prop->value = (unsigned char *) value;
2101ab64890Smrg    text_prop->encoding = encoding;
2111ab64890Smrg    text_prop->format = 8;
2129c019ec5Smaya    text_prop->nitems = (unsigned long) nitems;
2131ab64890Smrg
2141ab64890Smrg    return unconv_num;
2151ab64890Smrg}
2161ab64890Smrg
2171ab64890Smrgint
2181ab64890Smrg_XmbTextListToTextProperty(
2191ab64890Smrg    XLCd lcd,
2201ab64890Smrg    Display *dpy,
2211ab64890Smrg    char **list,
2221ab64890Smrg    int count,
2231ab64890Smrg    XICCEncodingStyle style,
2241ab64890Smrg    XTextProperty *text_prop)
2251ab64890Smrg{
2261ab64890Smrg    return _XTextListToTextProperty(lcd, dpy, XlcNMultiByte, (XPointer) list,
2271ab64890Smrg				    count, style, text_prop);
2281ab64890Smrg}
2291ab64890Smrg
2301ab64890Smrgint
2311ab64890Smrg_XwcTextListToTextProperty(
2321ab64890Smrg    XLCd lcd,
2331ab64890Smrg    Display *dpy,
2341ab64890Smrg    wchar_t **list,
2351ab64890Smrg    int count,
2361ab64890Smrg    XICCEncodingStyle style,
2371ab64890Smrg    XTextProperty *text_prop)
2381ab64890Smrg{
2391ab64890Smrg    return _XTextListToTextProperty(lcd, dpy, XlcNWideChar, (XPointer) list,
2401ab64890Smrg				    count, style, text_prop);
2411ab64890Smrg}
2421ab64890Smrg
2431ab64890Smrgint
2441ab64890Smrg_Xutf8TextListToTextProperty(
2451ab64890Smrg    XLCd lcd,
2461ab64890Smrg    Display *dpy,
2471ab64890Smrg    char **list,
2481ab64890Smrg    int count,
2491ab64890Smrg    XICCEncodingStyle style,
2501ab64890Smrg    XTextProperty *text_prop)
2511ab64890Smrg{
2521ab64890Smrg    return _XTextListToTextProperty(lcd, dpy, XlcNUtf8String, (XPointer) list,
2531ab64890Smrg				    count, style, text_prop);
2541ab64890Smrg}
255