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