lcPrTxt.c revision 61b2299d
1/* $Xorg: lcPrTxt.c,v 1.3 2000/08/17 19:45:18 cpqbld Exp $ */ 2/* 3 * Copyright 1992, 1993 by TOSHIBA Corp. 4 * 5 * Permission to use, copy, modify, and distribute this software and its 6 * documentation for any purpose and without fee is hereby granted, provided 7 * that the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of TOSHIBA not be used in advertising 10 * or publicity pertaining to distribution of the software without specific, 11 * written prior permission. TOSHIBA make no representations about the 12 * suitability of this software for any purpose. It is provided "as is" 13 * without express or implied warranty. 14 * 15 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 17 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 21 * SOFTWARE. 22 * 23 * Author: Katsuhisa Yano TOSHIBA Corp. 24 * mopi@osa.ilab.toshiba.co.jp 25 */ 26/* $XFree86: xc/lib/X11/lcPrTxt.c,v 1.9 2003/04/03 22:34:02 dawes Exp $ */ 27 28#ifdef HAVE_CONFIG_H 29#include <config.h> 30#endif 31#include "Xlibint.h" 32#include "XlcPubI.h" 33#include <X11/Xutil.h> 34#include <X11/Xatom.h> 35 36static XPointer * 37alloc_list( 38 Bool is_wide_char, 39 int count, 40 int nitems) 41{ 42 if (is_wide_char) { 43 wchar_t **wstr_list; 44 45 wstr_list = (wchar_t **) Xmalloc(count * sizeof(wchar_t *)); 46 if (wstr_list == NULL) 47 return (XPointer *) NULL; 48 49 *wstr_list = (wchar_t *) Xmalloc(nitems * sizeof(wchar_t)); 50 if (*wstr_list == NULL) { 51 Xfree(wstr_list); 52 return (XPointer *) NULL; 53 } 54 55 return (XPointer *) wstr_list; 56 } else { 57 char **str_list; 58 59 str_list = (char **) Xmalloc(count * sizeof(char *)); 60 if (str_list == NULL) 61 return (XPointer *) NULL; 62 63 *str_list = (char *) Xmalloc(nitems); 64 if (*str_list == NULL) { 65 Xfree(str_list); 66 return (XPointer *) NULL; 67 } 68 69 return (XPointer *) str_list; 70 } 71} 72 73static void 74copy_list( 75 Bool is_wide_char, 76 XPointer text, 77 XPointer *list, 78 int count) 79{ 80 int length; 81 82 if (is_wide_char) { 83 wchar_t *wc_text, *wstr, **wstr_list; 84 85 wc_text = (wchar_t *) text; 86 wstr_list = (wchar_t **) list; 87 88 for (wstr = *wstr_list; count > 0; count--, wstr_list++) { 89 _Xwcscpy(wstr, wc_text); 90 *wstr_list = wstr; 91 length = _Xwcslen(wstr) + 1; 92 wstr += length; 93 wc_text += length; 94 } 95 } else { 96 char *mb_text, *str, **str_list; 97 98 mb_text = (char *) text; 99 str_list = (char **) list; 100 101 for (str = *str_list; count > 0; count--, str_list++) { 102 strcpy(str, mb_text); 103 *str_list = str; 104 length = strlen(str) + 1; 105 str += length; 106 mb_text += length; 107 } 108 } 109} 110 111static int 112_XTextPropertyToTextList( 113 XLCd lcd, 114 Display *dpy, 115 const XTextProperty *text_prop, 116 const char *to_type, 117 XPointer **list_ret, 118 int *count_ret) 119{ 120 XlcConv conv = NULL; 121 const char *from_type; 122 XPointer from, to, buf; 123 char *str_ptr, *last_ptr; 124 Atom encoding; 125 int from_left, to_left, buf_len, ret, len; 126 int unconv_num, nitems = text_prop->nitems; 127 Bool is_wide_char = False, do_strcpy = False; 128 129 if (strcmp(XlcNWideChar, to_type) == 0) 130 is_wide_char = True; 131 132 if (nitems <= 0) { 133 *list_ret = NULL; 134 *count_ret = 0; 135 return Success; 136 } 137 138 if (text_prop->format != 8) 139 return XConverterNotFound; 140 141 encoding = text_prop->encoding; 142 if (encoding == XA_STRING) 143 from_type = XlcNString; 144 else if (encoding == XInternAtom(dpy, "UTF8_STRING", False)) 145 from_type = XlcNUtf8String; 146 else if (encoding == XInternAtom(dpy, "COMPOUND_TEXT", False)) 147 from_type = XlcNCompoundText; 148 else if (encoding == XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False)) 149 from_type = XlcNMultiByte; 150 else 151 return XConverterNotFound; 152 153 if (is_wide_char) { 154 buf_len = (text_prop->nitems + 1) * sizeof(wchar_t);; 155 } else { 156 if (strcmp(to_type, XlcNUtf8String) == 0) 157 buf_len = text_prop->nitems * 6 + 1; 158 else 159 buf_len = text_prop->nitems * XLC_PUBLIC(lcd, mb_cur_max) + 1; 160 } 161 buf = (XPointer) Xmalloc(buf_len); 162 if (buf == NULL) 163 return XNoMemory; 164 to = buf; 165 to_left = buf_len; 166 167 /* can be XlcNMultiByte to XlcNMultiByte, 168 or XlcNUtf8String to XlcNUtf8String */ 169 if (!strcmp(from_type, to_type)) { 170 do_strcpy = True; 171 } else { 172 conv = _XlcOpenConverter(lcd, from_type, lcd, to_type); 173 if (conv == NULL) { 174 Xfree(buf); 175 return XConverterNotFound; 176 } 177 } 178 179 last_ptr = str_ptr = (char *) text_prop->value; 180 unconv_num = *count_ret = 0; 181 182 while (1) { 183 if (nitems == 0 || *str_ptr == 0) { 184 from = (XPointer) last_ptr; 185 from_left = str_ptr - last_ptr; 186 last_ptr = str_ptr; 187 188 if (do_strcpy) { 189 len = min(from_left, to_left); 190 strncpy(to, from, len); 191 from += len; 192 to += len; 193 from_left -= len; 194 to_left -= len; 195 ret = 0; 196 } else { 197 ret = _XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0); 198 } 199 200 if (ret < 0) 201 continue; 202 203 unconv_num += ret; 204 (*count_ret)++; 205 206 if (nitems == 0) 207 break; 208 last_ptr = ++str_ptr; 209 if (is_wide_char) { 210 *((wchar_t *)to) = (wchar_t) 0; 211 to += sizeof(wchar_t); 212 to_left -= sizeof(wchar_t); 213 } else { 214 *((char *)to) = '\0'; 215 to++; 216 to_left--; 217 } 218 if (! do_strcpy) 219 _XlcResetConverter(conv); 220 } else 221 str_ptr++; 222 223 nitems--; 224 } 225 226 if (! do_strcpy) 227 _XlcCloseConverter(conv); 228 229 if (is_wide_char) { 230 *((wchar_t *) to) = (wchar_t) 0; 231 to_left -= sizeof(wchar_t); 232 } else { 233 *((char *) to) = '\0'; 234 to_left--; 235 } 236 237 *list_ret = alloc_list(is_wide_char, *count_ret, buf_len - to_left); 238 if (*list_ret) 239 copy_list(is_wide_char, buf, *list_ret, *count_ret); 240 241 Xfree(buf); 242 243 return unconv_num; 244} 245 246int 247_XmbTextPropertyToTextList( 248 XLCd lcd, 249 Display *dpy, 250 const XTextProperty *text_prop, 251 char ***list_ret, 252 int *count_ret) 253{ 254 return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNMultiByte, 255 (XPointer **) list_ret, count_ret); 256} 257 258int 259_XwcTextPropertyToTextList( 260 XLCd lcd, 261 Display *dpy, 262 const XTextProperty *text_prop, 263 wchar_t ***list_ret, 264 int *count_ret) 265{ 266 return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNWideChar, 267 (XPointer **) list_ret, count_ret); 268} 269 270int 271_Xutf8TextPropertyToTextList( 272 XLCd lcd, 273 Display *dpy, 274 const XTextProperty *text_prop, 275 char ***list_ret, 276 int *count_ret) 277{ 278 return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNUtf8String, 279 (XPointer **) list_ret, count_ret); 280} 281 282void 283_XwcFreeStringList( 284 XLCd lcd, 285 wchar_t **list) 286{ 287 if (list) { 288 if (*list) 289 Xfree(*list); 290 Xfree(list); 291 } 292} 293