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