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 (at) 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 #include <stdio.h> 34 35 static int 36 get_buf_size( 37 Bool is_wide_char, 38 XPointer list, 39 int count) 40 { 41 int length = 0; 42 char **mb_list; 43 wchar_t **wc_list; 44 45 if (list == NULL) 46 return 0; 47 48 if (is_wide_char) { 49 wc_list = (wchar_t **) list; 50 for ( ; count-- > 0; wc_list++) { 51 if (*wc_list) 52 length += _Xwcslen(*wc_list) + 1; 53 } 54 length *= 5; /* XXX */ 55 } else { 56 mb_list = (char **) list; 57 for ( ; count-- > 0; mb_list++) { 58 if (*mb_list) 59 length = (int) ((size_t) length + (strlen(*mb_list) + 1)); 60 } 61 length *= 3; /* XXX */ 62 } 63 length = (length / BUFSIZ + 1) * BUFSIZ; /* XXX */ 64 65 return length; 66 } 67 68 static int 69 _XTextListToTextProperty( 70 XLCd lcd, 71 Display *dpy, 72 const char *from_type, 73 XPointer list, 74 int count, 75 XICCEncodingStyle style, 76 XTextProperty *text_prop) 77 { 78 Atom encoding; 79 XlcConv conv; 80 const char *to_type; 81 char **mb_list = NULL; 82 wchar_t **wc_list = NULL; 83 XPointer from; 84 char *to, *buf, *value; 85 int from_left, to_left, buf_len, nitems, unconv_num = 0, ret, i; 86 Bool is_wide_char = False; 87 88 if (strcmp(XlcNWideChar, from_type) == 0) 89 is_wide_char = True; 90 91 buf_len = get_buf_size(is_wide_char, list, count); 92 if ((buf = Xmalloc(buf_len)) == NULL) 93 return XNoMemory; 94 95 switch (style) { 96 case XStringStyle: 97 case XStdICCTextStyle: 98 encoding = XA_STRING; 99 to_type = XlcNString; 100 break; 101 case XUTF8StringStyle: 102 encoding = XInternAtom(dpy, "UTF8_STRING", False); 103 to_type = XlcNUtf8String; 104 break; 105 case XCompoundTextStyle: 106 encoding = XInternAtom(dpy, "COMPOUND_TEXT", False); 107 to_type = XlcNCompoundText; 108 break; 109 case XTextStyle: 110 encoding = XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False); 111 to_type = XlcNMultiByte; 112 if (is_wide_char == False) { 113 nitems = 0; 114 mb_list = (char **) list; 115 to = buf; 116 for (i = 0; i < count && buf_len > 0; i++) { 117 if (*mb_list) 118 strcpy(to, *mb_list); 119 else 120 *to = '\0'; 121 from_left = (int) (*mb_list ? strlen(*mb_list) : 0) + 1; 122 nitems += from_left; 123 to += from_left; 124 mb_list++; 125 } 126 unconv_num = 0; 127 goto done; 128 } 129 break; 130 default: 131 Xfree(buf); 132 return XConverterNotFound; 133 } 134 135 if (count < 1) { 136 nitems = 0; 137 goto done; 138 } 139 140 retry: 141 conv = _XlcOpenConverter(lcd, from_type, lcd, to_type); 142 if (conv == NULL) { 143 Xfree(buf); 144 return XConverterNotFound; 145 } 146 147 if (is_wide_char) 148 wc_list = (wchar_t **) list; 149 else 150 mb_list = (char **) list; 151 152 to = buf; 153 to_left = buf_len; 154 155 unconv_num = 0; 156 157 for (i = 1; to_left > 0; i++) { 158 if (is_wide_char) { 159 from = (XPointer) *wc_list; 160 from_left = _Xwcslen(*wc_list); 161 wc_list++; 162 } else { 163 from = (XPointer) *mb_list; 164 from_left = (int) (*mb_list ? strlen(*mb_list) : 0); 165 mb_list++; 166 } 167 168 ret = _XlcConvert(conv, &from, &from_left, (XPointer *) &to, &to_left, 169 NULL, 0); 170 171 if (ret < 0) 172 continue; 173 174 if (ret > 0 && style == XStdICCTextStyle && encoding == XA_STRING) { 175 _XlcCloseConverter(conv); 176 encoding = XInternAtom(dpy, "COMPOUND_TEXT", False); 177 to_type = XlcNCompoundText; 178 goto retry; 179 } 180 181 unconv_num += ret; 182 *to++ = '\0'; 183 to_left--; 184 185 if (i >= count) 186 break; 187 188 _XlcResetConverter(conv); 189 } 190 191 _XlcCloseConverter(conv); 192 193 nitems = (int) (to - buf); 194 done: 195 if (nitems <= 0) 196 nitems = 1; 197 value = Xmalloc(nitems); 198 if (value == NULL) { 199 Xfree(buf); 200 return XNoMemory; 201 } 202 if (nitems == 1) 203 *value = 0; 204 else 205 memcpy(value, buf, (size_t) nitems); 206 nitems--; 207 Xfree(buf); 208 209 text_prop->value = (unsigned char *) value; 210 text_prop->encoding = encoding; 211 text_prop->format = 8; 212 text_prop->nitems = (unsigned long) nitems; 213 214 return unconv_num; 215 } 216 217 int 218 _XmbTextListToTextProperty( 219 XLCd lcd, 220 Display *dpy, 221 char **list, 222 int count, 223 XICCEncodingStyle style, 224 XTextProperty *text_prop) 225 { 226 return _XTextListToTextProperty(lcd, dpy, XlcNMultiByte, (XPointer) list, 227 count, style, text_prop); 228 } 229 230 int 231 _XwcTextListToTextProperty( 232 XLCd lcd, 233 Display *dpy, 234 wchar_t **list, 235 int count, 236 XICCEncodingStyle style, 237 XTextProperty *text_prop) 238 { 239 return _XTextListToTextProperty(lcd, dpy, XlcNWideChar, (XPointer) list, 240 count, style, text_prop); 241 } 242 243 int 244 _Xutf8TextListToTextProperty( 245 XLCd lcd, 246 Display *dpy, 247 char **list, 248 int count, 249 XICCEncodingStyle style, 250 XTextProperty *text_prop) 251 { 252 return _XTextListToTextProperty(lcd, dpy, XlcNUtf8String, (XPointer) list, 253 count, style, text_prop); 254 } 255