imConv.c revision 3b4ba46c
1/****************************************************************** 2 3 Copyright 1991, 1992 by Fuji Xerox Co.,Ltd. 4 Copyright 1993, 1994 by FUJITSU LIMITED 5 6Permission to use, copy, modify, distribute, and sell this software 7and its documentation for any purpose is hereby granted without fee, 8provided that the above copyright notice appear in all copies and 9that both that copyright notice and this permission notice appear 10in supporting documentation, and that the name of Fuji Xerox Co.,Ltd. 11, and that the name of FUJITSU LIMITED not be used in advertising or 12publicity pertaining to distribution of the software without specific, 13 written prior permission. 14Fuji Xerox Co.,Ltd. , and FUJITSU LIMITED makes no representations about 15the suitability of this software for any purpose. 16It is provided "as is" without express or implied warranty. 17 18FUJI XEROX CO.,LTD. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH 19REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 20MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX CO.,LTD. 21AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT 22OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 23LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 24NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 25THE USE OR PERFORMANCE OF THIS SOFTWARE. 26 27 Author: Kazunori Nishihara, Fuji Xerox Co.,Ltd. 28 kaz@ssdev.ksp.fujixerox.co.jp 29 Modifier: Takashi Fujiwara FUJITSU LIMITED 30 fujiwara@a80.tech.yk.fujitsu.co.jp 31 32******************************************************************/ 33/* 2000 Modifier: Ivan Pascal The XFree86 Project. 34 */ 35 36#ifdef HAVE_CONFIG_H 37#include <config.h> 38#endif 39#include <stdio.h> 40#include "Xlibint.h" 41#include "Xlcint.h" 42#include "Ximint.h" 43#include "XlcPubI.h" 44 45#ifdef XKB 46/* 47 * rather than just call _XLookupString (i.e. the pre-XKB XLookupString) 48 * do this because with XKB the event may have some funky modifiers that 49 * _XLookupString doesn't grok. 50 */ 51#include "XKBlib.h" 52#define XLOOKUPSTRING lookup_string 53#else 54#define XLOOKUPSTRING XLookupString 55#endif 56 57typedef unsigned int ucs4_t; 58 59typedef int (*ucstocsConvProc)( 60 XPointer, 61 unsigned char *, 62 ucs4_t, 63 int 64); 65 66struct SubstRec { 67 const char encoding_name[8]; 68 const char charset_name[12]; 69}; 70 71static const struct SubstRec SubstTable[] = { 72 {"STRING", "ISO8859-1"}, 73 {"TIS620", "TIS620-0"}, 74 {"UTF-8", "ISO10646-1"} 75}; 76#define num_substitute (sizeof SubstTable / sizeof SubstTable[0]) 77 78/* 79 * Given the name of a charset, returns the pointer to convertors 80 * from UCS char to specified charset char. 81 * This converter is needed for _XimGetCharCode subroutine. 82 */ 83XPointer 84_XimGetLocaleCode ( 85 _Xconst char* encoding_name) 86{ 87 XPointer cvt = _Utf8GetConvByName(encoding_name); 88 if (!cvt && encoding_name) { 89 int i; 90 for (i = 0; i < num_substitute; i++) 91 if (!strcmp(encoding_name, SubstTable[i].encoding_name)) 92 return _Utf8GetConvByName(SubstTable[i].charset_name); 93 } 94 return cvt; 95} 96 97/* 98 * Returns the locale dependent representation of a keysym. 99 * The locale's encoding is passed in form of pointer to UCS converter. 100 * The resulting multi-byte sequence is placed starting at buf (a buffer 101 * with nbytes bytes, nbytes should be >= 8) and is NUL terminated. 102 * Returns the length of the resulting multi-byte sequence, excluding the 103 * terminating NUL byte. Return 0 if the keysym is not representable in the 104 * locale 105 */ 106/*ARGSUSED*/ 107int 108_XimGetCharCode ( 109 XPointer ucs_conv, 110 KeySym keysym, 111 unsigned char* buf, 112 int nbytes) 113{ 114 int count = 0; 115 ucstocsConvProc cvt = (ucstocsConvProc) ucs_conv; 116 ucs4_t ucs4; 117 118 if (keysym < 0x80) { 119 buf[0] = (char) keysym; 120 count = 1; 121 } else if (cvt) { 122 ucs4 = KeySymToUcs4(keysym); 123 if (ucs4) 124 count = (*cvt)((XPointer)NULL, buf, ucs4, nbytes); 125 } 126 127 if (count < 0) 128 count = 0; 129 if (count>nbytes) 130 return nbytes; 131 if (count<nbytes) 132 buf[count]= '\0'; 133 return count; 134} 135 136#ifdef XKB 137static int lookup_string( 138 XKeyEvent* event, 139 char* buffer, 140 int nbytes, 141 KeySym* keysym, 142 XComposeStatus* status) 143{ 144 int ret; 145 unsigned ctrls = XkbGetXlibControls (event->display); 146 XkbSetXlibControls (event->display, 147 XkbLC_ForceLatin1Lookup, XkbLC_ForceLatin1Lookup); 148 ret = XLookupString(event, (char *)buffer, nbytes, keysym, status); 149 XkbSetXlibControls (event->display, 150 XkbLC_ForceLatin1Lookup, ctrls); 151 return ret; 152} 153#endif 154 155#define BUF_SIZE (20) 156 157int 158_XimLookupMBText( 159 Xic ic, 160 XKeyEvent* event, 161 char* buffer, 162 int nbytes, 163 KeySym* keysym, 164 XComposeStatus* status) 165{ 166 int count; 167 KeySym symbol; 168 Status dummy; 169 Xim im = (Xim)ic->core.im; 170 XimCommonPrivateRec* private = &im->private.common; 171 unsigned char look[BUF_SIZE]; 172 ucs4_t ucs4; 173 174 /* force a latin-1 lookup for compatibility */ 175 count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status); 176 if (keysym != NULL) *keysym = symbol; 177 if ((nbytes == 0) || (symbol == NoSymbol)) return count; 178 179 if (count > 1) { 180 if ((unsigned)count >= sizeof(look)) 181 return 0; 182 memcpy(look, (char *)buffer,count); 183 look[count] = '\0'; 184 if ((count = im->methods->ctstombs(ic->core.im, 185 (char*) look, count, 186 buffer, nbytes, &dummy)) < 0) { 187 count = 0; 188 } 189 } else if ((count == 0) || 190 (count == 1 && (symbol > 0x7f && symbol < 0xff00))) { 191 192 XPointer from = (XPointer) &ucs4; 193 XPointer to = (XPointer) look; 194 int from_len = 1; 195 int to_len = BUF_SIZE; 196 XPointer args[1]; 197 XlcCharSet charset; 198 args[0] = (XPointer) &charset; 199 ucs4 = (ucs4_t) KeySymToUcs4(symbol); 200 if (!ucs4) 201 return 0; 202 203 if (_XlcConvert(private->ucstoc_conv, 204 &from, &from_len, &to, &to_len, 205 args, 1 ) != 0) { 206 count = 0; 207 } else { 208 from = (XPointer) look; 209 to = (XPointer) buffer; 210 from_len = BUF_SIZE - to_len; 211 to_len = nbytes; 212 args[0] = (XPointer) charset; 213 if (_XlcConvert(private->cstomb_conv, 214 &from, &from_len, &to, &to_len, 215 args, 1 ) != 0) { 216 count = 0; 217 } else { 218 count = nbytes - to_len; 219 } 220 } 221 } 222 /* FIXME: 223 * we should make sure that if the character is a Latin1 character 224 * and it's on the right side, and we're in a non-Latin1 locale 225 * that this is a valid Latin1 character for this locale. 226 */ 227 return count; 228} 229 230int 231_XimLookupWCText( 232 Xic ic, 233 XKeyEvent* event, 234 wchar_t* buffer, 235 int nbytes, 236 KeySym* keysym, 237 XComposeStatus* status) 238{ 239 int count; 240 KeySym symbol; 241 Status dummy; 242 Xim im = (Xim)ic->core.im; 243 XimCommonPrivateRec* private = &im->private.common; 244 unsigned char look[BUF_SIZE]; 245 ucs4_t ucs4; 246 247 /* force a latin-1 lookup for compatibility */ 248 count = XLOOKUPSTRING(event, (char *)look, nbytes, &symbol, status); 249 if (keysym != NULL) *keysym = symbol; 250 if ((nbytes == 0) || (symbol == NoSymbol)) return count; 251 252 if (count > 1) { 253 if ((count = im->methods->ctstowcs(ic->core.im, 254 (char*) look, count, 255 buffer, nbytes, &dummy)) < 0) { 256 count = 0; 257 } 258 } else if ((count == 0) || 259 (count == 1 && (symbol > 0x7f && symbol < 0xff00))) { 260 261 XPointer from = (XPointer) &ucs4; 262 XPointer to = (XPointer) look; 263 int from_len = 1; 264 int to_len = BUF_SIZE; 265 XPointer args[1]; 266 XlcCharSet charset; 267 args[0] = (XPointer) &charset; 268 ucs4 = (ucs4_t) KeySymToUcs4(symbol); 269 if (!ucs4) 270 return 0; 271 272 if (_XlcConvert(private->ucstoc_conv, 273 &from, &from_len, &to, &to_len, 274 args, 1 ) != 0) { 275 count = 0; 276 } else { 277 from = (XPointer) look; 278 to = (XPointer) buffer; 279 from_len = BUF_SIZE - to_len; 280 to_len = nbytes; 281 args[0] = (XPointer) charset; 282 283 if (_XlcConvert(private->cstowc_conv, 284 &from, &from_len, &to, &to_len, 285 args, 1 ) != 0) { 286 count = 0; 287 } else { 288 count = nbytes - to_len; 289 } 290 } 291 } else 292 /* FIXME: 293 * we should make sure that if the character is a Latin1 character 294 * and it's on the right side, and we're in a non-Latin1 locale 295 * that this is a valid Latin1 character for this locale. 296 */ 297 buffer[0] = look[0]; 298 299 return count; 300} 301 302int 303_XimLookupUTF8Text( 304 Xic ic, 305 XKeyEvent* event, 306 char* buffer, 307 int nbytes, 308 KeySym* keysym, 309 XComposeStatus* status) 310{ 311 int count; 312 KeySym symbol; 313 Status dummy; 314 Xim im = (Xim)ic->core.im; 315 XimCommonPrivateRec* private = &im->private.common; 316 unsigned char look[BUF_SIZE]; 317 ucs4_t ucs4; 318 319 /* force a latin-1 lookup for compatibility */ 320 count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status); 321 if (keysym != NULL) *keysym = symbol; 322 if ((nbytes == 0) || (symbol == NoSymbol)) return count; 323 324 if (count > 1) { 325 if ((unsigned)count >= sizeof(look)) 326 return 0; 327 memcpy(look, (char *)buffer,count); 328 look[count] = '\0'; 329 if ((count = im->methods->ctstoutf8(ic->core.im, 330 (char*) look, count, 331 buffer, nbytes, &dummy)) < 0) { 332 count = 0; 333 } 334 } else if ((count == 0) || 335 (count == 1 && (symbol > 0x7f && symbol < 0xff00))) { 336 337 XPointer from = (XPointer) &ucs4; 338 int from_len = 1; 339 XPointer to = (XPointer) buffer; 340 int to_len = nbytes; 341 342 ucs4 = (ucs4_t) KeySymToUcs4(symbol); 343 if (!ucs4) 344 return 0; 345 346 if (_XlcConvert(private->ucstoutf8_conv, 347 &from, &from_len, &to, &to_len, 348 NULL, 0) != 0) { 349 count = 0; 350 } else { 351 count = nbytes - to_len; 352 } 353 } 354 /* FIXME: 355 * we should make sure that if the character is a Latin1 character 356 * and it's on the right side, and we're in a non-Latin1 locale 357 * that this is a valid Latin1 character for this locale. 358 */ 359 return count; 360} 361