imLcLkup.c revision 0efe039a
1/****************************************************************** 2 3 Copyright 1992 by Fuji Xerox Co., Ltd. 4 Copyright 1992, 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, 11FUJITSU LIMITED not be used in advertising or publicity pertaining 12to distribution of the software without specific, written prior 13permission. Fuji Xerox, FUJITSU LIMITED make no representations 14about the suitability of this software for any purpose. 15It is provided "as is" without express or implied warranty. 16 17FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH 18REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 19MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX, 20FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA 22OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 23TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 24PERFORMANCE OF THIS SOFTWARE. 25 26 Author: Kazunori Nishihara Fuji Xerox 27 Takashi Fujiwara FUJITSU LIMITED 28 fujiwara@a80.tech.yk.fujitsu.co.jp 29 30******************************************************************/ 31 32#ifdef HAVE_CONFIG_H 33#include <config.h> 34#endif 35#include <stdio.h> 36#include <X11/Xatom.h> 37#include <X11/Xos.h> 38#include <X11/Xlib.h> 39#include <X11/keysym.h> 40#include <X11/Xutil.h> 41#include "Xlibint.h" 42#include "Xlcint.h" 43#include "XlcPubI.h" 44#include "Ximint.h" 45 46int 47_XimLocalMbLookupString(XIC xic, XKeyEvent *ev, char *buffer, int bytes, 48 KeySym *keysym, Status *status) 49{ 50 Xic ic = (Xic)xic; 51 int ret; 52 DefTree *b = ic->private.local.base.tree; 53 char *mb = ic->private.local.base.mb; 54 55 if(ev->type != KeyPress) { 56 if(status) *status = XLookupNone; 57 return(0); 58 } 59 if(ev->keycode == 0 && 60 ( (ic->private.local.composed != 0) 61 ||(ic->private.local.brl_committed != 0))) { 62 if (ic->private.local.brl_committed != 0) { /* Braille Event */ 63 unsigned char pattern = ic->private.local.brl_committed; 64 char mb2[XLC_PUBLIC(ic->core.im->core.lcd, mb_cur_max)]; 65 ret = _Xlcwctomb(ic->core.im->core.lcd, mb2, BRL_UC_ROW | pattern); 66 if(ret > bytes) { 67 if(status) *status = XBufferOverflow; 68 return(ret); 69 } 70 if(keysym) *keysym = XK_braille_blank | pattern; 71 if(ret > 0) { 72 if (keysym) { 73 if(status) *status = XLookupBoth; 74 } else { 75 if(status) *status = XLookupChars; 76 } 77 memcpy(buffer, mb2, ret); 78 } else { 79 if(keysym) { 80 if(status) *status = XLookupKeySym; 81 } else { 82 if(status) *status = XLookupNone; 83 } 84 } 85 } else { /* Composed Event */ 86 ret = strlen(&mb[b[ic->private.local.composed].mb]); 87 if(ret > bytes) { 88 if(status) *status = XBufferOverflow; 89 return(ret); 90 } 91 memcpy(buffer, &mb[b[ic->private.local.composed].mb], ret); 92 if(keysym) *keysym = b[ic->private.local.composed].ks; 93 if (ret > 0) { 94 if (keysym && *keysym != NoSymbol) { 95 if(status) *status = XLookupBoth; 96 } else { 97 if(status) *status = XLookupChars; 98 } 99 } else { 100 if(keysym && *keysym != NoSymbol) { 101 if(status) *status = XLookupKeySym; 102 } else { 103 if(status) *status = XLookupNone; 104 } 105 } 106 } 107 return (ret); 108 } else { /* Throughed Event */ 109 ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL); 110 if(ret > 0) { 111 if (ret > bytes) { 112 if (status) *status = XBufferOverflow; 113 } else if (keysym && *keysym != NoSymbol) { 114 if(status) *status = XLookupBoth; 115 } else { 116 if(status) *status = XLookupChars; 117 } 118 } else { 119 if(keysym && *keysym != NoSymbol) { 120 if(status) *status = XLookupKeySym; 121 } else { 122 if(status) *status = XLookupNone; 123 } 124 } 125 } 126 return (ret); 127} 128 129int 130_XimLocalWcLookupString(XIC xic, XKeyEvent *ev, wchar_t *buffer, int wlen, 131 KeySym *keysym, Status *status) 132{ 133 Xic ic = (Xic)xic; 134 int ret; 135 DefTree *b = ic->private.local.base.tree; 136 wchar_t *wc = ic->private.local.base.wc; 137 138 if(ev->type != KeyPress) { 139 if(status) *status = XLookupNone; 140 return(0); 141 } 142 if(ev->keycode == 0) { 143 if (ic->private.local.brl_committed != 0) { /* Braille Event */ 144 unsigned char pattern = ic->private.local.brl_committed; 145 ret = 1; 146 if (ret > wlen) { 147 if(status) *status = XBufferOverflow; 148 return (ret); 149 } 150 *buffer = BRL_UC_ROW | pattern; 151 if(keysym) { 152 *keysym = XK_braille_blank | pattern; 153 if(status) *status = XLookupBoth; 154 } else 155 if(status) *status = XLookupChars; 156 } else { /* Composed Event */ 157 ret = _Xwcslen(&wc[b[ic->private.local.composed].wc]); 158 if(ret > wlen) { 159 if(status) *status = XBufferOverflow; 160 return (ret); 161 } 162 memcpy((char *)buffer, (char *)&wc[b[ic->private.local.composed].wc], 163 ret * sizeof(wchar_t)); 164 if(keysym) *keysym = b[ic->private.local.composed].ks; 165 if (ret > 0) { 166 if (keysym && *keysym != NoSymbol) { 167 if(status) *status = XLookupBoth; 168 } else { 169 if(status) *status = XLookupChars; 170 } 171 } else { 172 if(keysym && *keysym != NoSymbol) { 173 if(status) *status = XLookupKeySym; 174 } else { 175 if(status) *status = XLookupNone; 176 } 177 } 178 } 179 return (ret); 180 } else { /* Throughed Event */ 181 ret = _XimLookupWCText(ic, ev, buffer, wlen, keysym, NULL); 182 if(ret > 0) { 183 if (ret > wlen) { 184 if (status) *status = XBufferOverflow; 185 } else if (keysym && *keysym != NoSymbol) { 186 if(status) *status = XLookupBoth; 187 } else { 188 if(status) *status = XLookupChars; 189 } 190 } else { 191 if(keysym && *keysym != NoSymbol) { 192 if(status) *status = XLookupKeySym; 193 } else { 194 if(status) *status = XLookupNone; 195 } 196 } 197 } 198 return (ret); 199} 200 201int 202_XimLocalUtf8LookupString(XIC xic, XKeyEvent *ev, char *buffer, int bytes, 203 KeySym *keysym, Status *status) 204{ 205 Xic ic = (Xic)xic; 206 int ret; 207 DefTree *b = ic->private.local.base.tree; 208 char *utf8 = ic->private.local.base.utf8; 209 210 if(ev->type != KeyPress) { 211 if(status) *status = XLookupNone; 212 return(0); 213 } 214 if(ev->keycode == 0) { 215 if (ic->private.local.brl_committed != 0) { /* Braille Event */ 216 unsigned char pattern = ic->private.local.brl_committed; 217 ret = 3; 218 if (ret > bytes) { 219 if(status) *status = XBufferOverflow; 220 return (ret); 221 } 222 buffer[0] = 0xe0 | ((BRL_UC_ROW >> 12) & 0x0f); 223 buffer[1] = 0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6); 224 buffer[2] = 0x80 | (pattern & 0x3f); 225 if(keysym) { 226 *keysym = XK_braille_blank | pattern; 227 if(status) *status = XLookupBoth; 228 } else 229 if(status) *status = XLookupChars; 230 } else { /* Composed Event */ 231 ret = strlen(&utf8[b[ic->private.local.composed].utf8]); 232 if(ret > bytes) { 233 if(status) *status = XBufferOverflow; 234 return (ret); 235 } 236 memcpy(buffer, &utf8[b[ic->private.local.composed].utf8], ret); 237 if(keysym) *keysym = b[ic->private.local.composed].ks; 238 if (ret > 0) { 239 if (keysym && *keysym != NoSymbol) { 240 if(status) *status = XLookupBoth; 241 } else { 242 if(status) *status = XLookupChars; 243 } 244 } else { 245 if(keysym && *keysym != NoSymbol) { 246 if(status) *status = XLookupKeySym; 247 } else { 248 if(status) *status = XLookupNone; 249 } 250 } 251 } 252 return (ret); 253 } else { /* Throughed Event */ 254 ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); 255 if(ret > 0) { 256 if (ret > bytes) { 257 if (status) *status = XBufferOverflow; 258 } else if (keysym && *keysym != NoSymbol) { 259 if(status) *status = XLookupBoth; 260 } else { 261 if(status) *status = XLookupChars; 262 } 263 } else { 264 if(keysym && *keysym != NoSymbol) { 265 if(status) *status = XLookupKeySym; 266 } else { 267 if(status) *status = XLookupNone; 268 } 269 } 270 } 271 return (ret); 272} 273 274static int 275_XimLcctsconvert( 276 XlcConv conv, 277 char *from, 278 int from_len, 279 char *to, 280 int to_len, 281 Status *state) 282{ 283 int from_left; 284 int to_left; 285 int from_savelen; 286 int to_savelen; 287 int from_cnvlen; 288 int to_cnvlen; 289 char *from_buf; 290 char *to_buf; 291 char scratchbuf[BUFSIZ]; 292 Status tmp_state; 293 294 if (!state) 295 state = &tmp_state; 296 297 if (!conv || !from || !from_len) { 298 *state = XLookupNone; 299 return 0; 300 } 301 302 /* Reset the converter. The CompoundText at 'from' starts in 303 initial state. */ 304 _XlcResetConverter(conv); 305 306 from_left = from_len; 307 to_left = BUFSIZ; 308 from_cnvlen = 0; 309 to_cnvlen = 0; 310 for (;;) { 311 from_buf = &from[from_cnvlen]; 312 from_savelen = from_left; 313 to_buf = &scratchbuf[to_cnvlen]; 314 to_savelen = to_left; 315 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 316 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 317 *state = XLookupNone; 318 return 0; 319 } 320 from_cnvlen += (from_savelen - from_left); 321 to_cnvlen += (to_savelen - to_left); 322 if (from_left == 0) { 323 if (!to_cnvlen) { 324 *state = XLookupNone; 325 return 0; 326 } 327 break; 328 } 329 } 330 331 if (!to || !to_len || (to_len < to_cnvlen)) { 332 *state = XBufferOverflow; 333 } else { 334 memcpy(to, scratchbuf, to_cnvlen); 335 *state = XLookupChars; 336 } 337 return to_cnvlen; 338} 339 340int 341_XimLcctstombs(XIM xim, char *from, int from_len, 342 char *to, int to_len, Status *state) 343{ 344 return _XimLcctsconvert(((Xim)xim)->private.local.ctom_conv, 345 from, from_len, to, to_len, state); 346} 347 348int 349_XimLcctstowcs(XIM xim, char *from, int from_len, 350 wchar_t *to, int to_len, Status *state) 351{ 352 Xim im = (Xim)xim; 353 XlcConv conv = im->private.local.ctow_conv; 354 int from_left; 355 int to_left; 356 int from_savelen; 357 int to_savelen; 358 int from_cnvlen; 359 int to_cnvlen; 360 char *from_buf; 361 wchar_t *to_buf; 362 wchar_t scratchbuf[BUFSIZ]; 363 Status tmp_state; 364 365 if (!state) 366 state = &tmp_state; 367 368 if (!conv || !from || !from_len) { 369 *state = XLookupNone; 370 return 0; 371 } 372 373 /* Reset the converter. The CompoundText at 'from' starts in 374 initial state. */ 375 _XlcResetConverter(conv); 376 377 from_left = from_len; 378 to_left = BUFSIZ; 379 from_cnvlen = 0; 380 to_cnvlen = 0; 381 for (;;) { 382 from_buf = &from[from_cnvlen]; 383 from_savelen = from_left; 384 to_buf = &scratchbuf[to_cnvlen]; 385 to_savelen = to_left; 386 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 387 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 388 *state = XLookupNone; 389 return 0; 390 } 391 from_cnvlen += (from_savelen - from_left); 392 to_cnvlen += (to_savelen - to_left); 393 if (from_left == 0) { 394 if (!to_cnvlen){ 395 *state = XLookupNone; 396 return 0; 397 } 398 break; 399 } 400 } 401 402 if (!to || !to_len || (to_len < to_cnvlen)) { 403 *state = XBufferOverflow; 404 } else { 405 memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); 406 *state = XLookupChars; 407 } 408 return to_cnvlen; 409} 410 411int 412_XimLcctstoutf8(XIM xim, char *from, int from_len, 413 char *to, int to_len, Status *state) 414{ 415 return _XimLcctsconvert(((Xim)xim)->private.local.ctoutf8_conv, 416 from, from_len, to, to_len, state); 417} 418