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