lcPrTxt.c revision 818534a1
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
341ab64890Smrgstatic XPointer *
351ab64890Smrgalloc_list(
361ab64890Smrg    Bool is_wide_char,
371ab64890Smrg    int count,
381ab64890Smrg    int nitems)
391ab64890Smrg{
401ab64890Smrg    if (is_wide_char) {
411ab64890Smrg	wchar_t **wstr_list;
421ab64890Smrg
43818534a1Smrg	wstr_list = Xmalloc(count * sizeof(wchar_t *));
441ab64890Smrg	if (wstr_list == NULL)
451ab64890Smrg	    return (XPointer *) NULL;
461ab64890Smrg
47818534a1Smrg	*wstr_list = Xmalloc(nitems * sizeof(wchar_t));
481ab64890Smrg	if (*wstr_list == NULL) {
491ab64890Smrg	    Xfree(wstr_list);
501ab64890Smrg	    return (XPointer *) NULL;
511ab64890Smrg	}
521ab64890Smrg
531ab64890Smrg	return (XPointer *) wstr_list;
541ab64890Smrg    } else {
551ab64890Smrg	char **str_list;
561ab64890Smrg
57818534a1Smrg	str_list = Xmalloc(count * sizeof(char *));
581ab64890Smrg	if (str_list == NULL)
591ab64890Smrg	    return (XPointer *) NULL;
601ab64890Smrg
61818534a1Smrg	*str_list = Xmalloc(nitems);
621ab64890Smrg	if (*str_list == NULL) {
631ab64890Smrg	    Xfree(str_list);
641ab64890Smrg	    return (XPointer *) NULL;
651ab64890Smrg	}
661ab64890Smrg
671ab64890Smrg	return (XPointer *) str_list;
681ab64890Smrg    }
691ab64890Smrg}
701ab64890Smrg
711ab64890Smrgstatic void
721ab64890Smrgcopy_list(
731ab64890Smrg    Bool is_wide_char,
741ab64890Smrg    XPointer text,
751ab64890Smrg    XPointer *list,
761ab64890Smrg    int count)
771ab64890Smrg{
781ab64890Smrg    int length;
791ab64890Smrg
801ab64890Smrg    if (is_wide_char) {
811ab64890Smrg	wchar_t *wc_text, *wstr, **wstr_list;
8261b2299dSmrg
831ab64890Smrg	wc_text = (wchar_t *) text;
841ab64890Smrg	wstr_list = (wchar_t **) list;
851ab64890Smrg
861ab64890Smrg	for (wstr = *wstr_list; count > 0; count--, wstr_list++) {
871ab64890Smrg	    _Xwcscpy(wstr, wc_text);
881ab64890Smrg	    *wstr_list = wstr;
891ab64890Smrg	    length = _Xwcslen(wstr) + 1;
901ab64890Smrg	    wstr += length;
911ab64890Smrg	    wc_text += length;
921ab64890Smrg	}
931ab64890Smrg    } else {
941ab64890Smrg	char *mb_text, *str, **str_list;
9561b2299dSmrg
961ab64890Smrg	mb_text = (char *) text;
971ab64890Smrg	str_list = (char **) list;
981ab64890Smrg
991ab64890Smrg	for (str = *str_list; count > 0; count--, str_list++) {
1001ab64890Smrg	    strcpy(str, mb_text);
1011ab64890Smrg	    *str_list = str;
1021ab64890Smrg	    length = strlen(str) + 1;
1031ab64890Smrg	    str += length;
1041ab64890Smrg	    mb_text += length;
1051ab64890Smrg	}
1061ab64890Smrg    }
1071ab64890Smrg}
1081ab64890Smrg
1091ab64890Smrgstatic int
1101ab64890Smrg_XTextPropertyToTextList(
1111ab64890Smrg    XLCd lcd,
1121ab64890Smrg    Display *dpy,
1131ab64890Smrg    const XTextProperty *text_prop,
1141ab64890Smrg    const char *to_type,
1151ab64890Smrg    XPointer **list_ret,
1161ab64890Smrg    int *count_ret)
1171ab64890Smrg{
1181ab64890Smrg    XlcConv conv = NULL;
1191ab64890Smrg    const char *from_type;
1201ab64890Smrg    XPointer from, to, buf;
1211ab64890Smrg    char *str_ptr, *last_ptr;
1221ab64890Smrg    Atom encoding;
1231ab64890Smrg    int from_left, to_left, buf_len, ret, len;
1241ab64890Smrg    int unconv_num, nitems = text_prop->nitems;
1251ab64890Smrg    Bool is_wide_char = False, do_strcpy = False;
1261ab64890Smrg
1271ab64890Smrg    if (strcmp(XlcNWideChar, to_type) == 0)
1281ab64890Smrg	is_wide_char = True;
1291ab64890Smrg
1301ab64890Smrg    if (nitems <= 0) {
1311ab64890Smrg	*list_ret = NULL;
1321ab64890Smrg	*count_ret = 0;
1331ab64890Smrg	return Success;
1341ab64890Smrg    }
1351ab64890Smrg
1361ab64890Smrg    if (text_prop->format != 8)
1371ab64890Smrg	return XConverterNotFound;
1381ab64890Smrg
1391ab64890Smrg    encoding = text_prop->encoding;
1401ab64890Smrg    if (encoding == XA_STRING)
1411ab64890Smrg	from_type = XlcNString;
1421ab64890Smrg    else if (encoding == XInternAtom(dpy, "UTF8_STRING", False))
1431ab64890Smrg	from_type = XlcNUtf8String;
1441ab64890Smrg    else if (encoding == XInternAtom(dpy, "COMPOUND_TEXT", False))
1451ab64890Smrg	from_type = XlcNCompoundText;
1461ab64890Smrg    else if (encoding == XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False))
1471ab64890Smrg	from_type = XlcNMultiByte;
1481ab64890Smrg    else
1491ab64890Smrg	return XConverterNotFound;
1501ab64890Smrg
1511ab64890Smrg    if (is_wide_char) {
1521ab64890Smrg	buf_len = (text_prop->nitems + 1) * sizeof(wchar_t);;
1531ab64890Smrg    } else {
1541ab64890Smrg	if (strcmp(to_type, XlcNUtf8String) == 0)
1551ab64890Smrg	    buf_len = text_prop->nitems * 6 + 1;
1561ab64890Smrg	else
1571ab64890Smrg	    buf_len = text_prop->nitems * XLC_PUBLIC(lcd, mb_cur_max) + 1;
1581ab64890Smrg    }
159818534a1Smrg    buf = Xmalloc(buf_len);
1601ab64890Smrg    if (buf == NULL)
1611ab64890Smrg	return XNoMemory;
1621ab64890Smrg    to = buf;
1631ab64890Smrg    to_left = buf_len;
1641ab64890Smrg
1651ab64890Smrg    /* can be XlcNMultiByte to XlcNMultiByte,
1661ab64890Smrg       or XlcNUtf8String to XlcNUtf8String */
1671ab64890Smrg    if (!strcmp(from_type, to_type)) {
1681ab64890Smrg        do_strcpy = True;
1691ab64890Smrg    } else {
1701ab64890Smrg        conv = _XlcOpenConverter(lcd, from_type, lcd, to_type);
1711ab64890Smrg        if (conv == NULL) {
1721ab64890Smrg	    Xfree(buf);
1731ab64890Smrg	    return XConverterNotFound;
1741ab64890Smrg        }
1751ab64890Smrg    }
1761ab64890Smrg
1771ab64890Smrg    last_ptr = str_ptr = (char *) text_prop->value;
1781ab64890Smrg    unconv_num = *count_ret = 0;
1791ab64890Smrg
1801ab64890Smrg    while (1) {
1811ab64890Smrg	if (nitems == 0 || *str_ptr == 0) {
1821ab64890Smrg	    from = (XPointer) last_ptr;
1831ab64890Smrg	    from_left = str_ptr - last_ptr;
1841ab64890Smrg	    last_ptr = str_ptr;
1851ab64890Smrg
1861ab64890Smrg            if (do_strcpy) {
1871ab64890Smrg            	len = min(from_left, to_left);
1881ab64890Smrg                strncpy(to, from, len);
1891ab64890Smrg                from += len;
1901ab64890Smrg                to += len;
1911ab64890Smrg                from_left -= len;
1921ab64890Smrg                to_left -= len;
1931ab64890Smrg                ret = 0;
1941ab64890Smrg            } else {
1951ab64890Smrg	        ret = _XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0);
1961ab64890Smrg            }
1971ab64890Smrg
1981ab64890Smrg	    if (ret < 0)
1991ab64890Smrg		continue;
2001ab64890Smrg
2011ab64890Smrg	    unconv_num += ret;
2021ab64890Smrg	    (*count_ret)++;
2031ab64890Smrg
2041ab64890Smrg	    if (nitems == 0)
2051ab64890Smrg		break;
2061ab64890Smrg 	    last_ptr = ++str_ptr;
2071ab64890Smrg	    if (is_wide_char) {
2081ab64890Smrg		*((wchar_t *)to) = (wchar_t) 0;
2091ab64890Smrg		to += sizeof(wchar_t);
2101ab64890Smrg		to_left -= sizeof(wchar_t);
2111ab64890Smrg	    } else {
2121ab64890Smrg		*((char *)to) = '\0';
2131ab64890Smrg		to++;
2141ab64890Smrg		to_left--;
2151ab64890Smrg	    }
2161ab64890Smrg	    if (! do_strcpy)
2171ab64890Smrg	        _XlcResetConverter(conv);
2181ab64890Smrg	} else
2191ab64890Smrg	    str_ptr++;
2201ab64890Smrg
2211ab64890Smrg	nitems--;
2221ab64890Smrg    }
2231ab64890Smrg
2241ab64890Smrg    if (! do_strcpy)
2251ab64890Smrg        _XlcCloseConverter(conv);
2261ab64890Smrg
2271ab64890Smrg    if (is_wide_char) {
2281ab64890Smrg	*((wchar_t *) to) = (wchar_t) 0;
2291ab64890Smrg	to_left -= sizeof(wchar_t);
2301ab64890Smrg    } else {
2311ab64890Smrg	*((char *) to) = '\0';
2321ab64890Smrg	to_left--;
2331ab64890Smrg    }
2341ab64890Smrg
2351ab64890Smrg    *list_ret = alloc_list(is_wide_char, *count_ret, buf_len - to_left);
2361ab64890Smrg    if (*list_ret)
2371ab64890Smrg	copy_list(is_wide_char, buf, *list_ret, *count_ret);
2381ab64890Smrg
2391ab64890Smrg    Xfree(buf);
2401ab64890Smrg
2411ab64890Smrg    return unconv_num;
2421ab64890Smrg}
2431ab64890Smrg
2441ab64890Smrgint
2451ab64890Smrg_XmbTextPropertyToTextList(
2461ab64890Smrg    XLCd lcd,
2471ab64890Smrg    Display *dpy,
2481ab64890Smrg    const XTextProperty *text_prop,
2491ab64890Smrg    char ***list_ret,
2501ab64890Smrg    int *count_ret)
2511ab64890Smrg{
2521ab64890Smrg    return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNMultiByte,
2531ab64890Smrg				    (XPointer **) list_ret, count_ret);
2541ab64890Smrg}
2551ab64890Smrg
2561ab64890Smrgint
2571ab64890Smrg_XwcTextPropertyToTextList(
2581ab64890Smrg    XLCd lcd,
2591ab64890Smrg    Display *dpy,
2601ab64890Smrg    const XTextProperty *text_prop,
2611ab64890Smrg    wchar_t ***list_ret,
2621ab64890Smrg    int *count_ret)
2631ab64890Smrg{
2641ab64890Smrg    return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNWideChar,
2651ab64890Smrg				    (XPointer **) list_ret, count_ret);
2661ab64890Smrg}
2671ab64890Smrg
2681ab64890Smrgint
2691ab64890Smrg_Xutf8TextPropertyToTextList(
2701ab64890Smrg    XLCd lcd,
2711ab64890Smrg    Display *dpy,
2721ab64890Smrg    const XTextProperty *text_prop,
2731ab64890Smrg    char ***list_ret,
2741ab64890Smrg    int *count_ret)
2751ab64890Smrg{
2761ab64890Smrg    return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNUtf8String,
2771ab64890Smrg				    (XPointer **) list_ret, count_ret);
2781ab64890Smrg}
2791ab64890Smrg
2801ab64890Smrgvoid
2811ab64890Smrg_XwcFreeStringList(
2821ab64890Smrg    XLCd lcd,
2831ab64890Smrg    wchar_t **list)
2841ab64890Smrg{
2851ab64890Smrg    if (list) {
2861ab64890Smrg        if (*list)
2871ab64890Smrg	     Xfree(*list);
2881ab64890Smrg        Xfree(list);
2891ab64890Smrg    }
2901ab64890Smrg}
291