imLcLkup.c revision b4ee4795
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 46Public int 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 mb[XLC_PUBLIC(ic->core.im->core.lcd, mb_cur_max)]; 65 ret = _Xlcwctomb(ic->core.im->core.lcd, mb, BRL_UC_ROW | pattern); 66 if(ret > bytes) { 67 if(status) *status = XBufferOverflow; 68 return(ret); 69 } 70 if(keysym) { 71 *keysym = XK_braille_blank | pattern; 72 if(status) *status = XLookupBoth; 73 } else 74 if(status) *status = XLookupChars; 75 memcpy(buffer, mb, ret); 76 } else { /* Composed Event */ 77 ret = strlen(&mb[b[ic->private.local.composed].mb]); 78 if(ret > bytes) { 79 if(status) *status = XBufferOverflow; 80 return(ret); 81 } 82 memcpy(buffer, &mb[b[ic->private.local.composed].mb], ret); 83 if(keysym) *keysym = b[ic->private.local.composed].ks; 84 if (ret > 0) { 85 if (keysym && *keysym != NoSymbol) { 86 if(status) *status = XLookupBoth; 87 } else { 88 if(status) *status = XLookupChars; 89 } 90 } else { 91 if(keysym && *keysym != NoSymbol) { 92 if(status) *status = XLookupKeySym; 93 } else { 94 if(status) *status = XLookupNone; 95 } 96 } 97 } 98 return (ret); 99 } else { /* Throughed Event */ 100 ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL); 101 if(ret > 0) { 102 if (ret > bytes) { 103 if (status) *status = XBufferOverflow; 104 } else if (keysym && *keysym != NoSymbol) { 105 if(status) *status = XLookupBoth; 106 } else { 107 if(status) *status = XLookupChars; 108 } 109 } else { 110 if(keysym && *keysym != NoSymbol) { 111 if(status) *status = XLookupKeySym; 112 } else { 113 if(status) *status = XLookupNone; 114 } 115 } 116 } 117 return (ret); 118} 119 120Public int 121_XimLocalWcLookupString(XIC xic, XKeyEvent *ev, wchar_t *buffer, int wlen, 122 KeySym *keysym, Status *status) 123{ 124 Xic ic = (Xic)xic; 125 int ret; 126 DefTree *b = ic->private.local.base.tree; 127 wchar_t *wc = ic->private.local.base.wc; 128 129 if(ev->type != KeyPress) { 130 if(status) *status = XLookupNone; 131 return(0); 132 } 133 if(ev->keycode == 0) { 134 if (ic->private.local.brl_committed != 0) { /* Braille Event */ 135 unsigned char pattern = ic->private.local.brl_committed; 136 ret = 1; 137 if (ret > wlen) { 138 if(status) *status = XBufferOverflow; 139 return (ret); 140 } 141 *buffer = BRL_UC_ROW | pattern; 142 if(keysym) { 143 *keysym = XK_braille_blank | pattern; 144 if(status) *status = XLookupBoth; 145 } else 146 if(status) *status = XLookupChars; 147 } else { /* Composed Event */ 148 ret = _Xwcslen(&wc[b[ic->private.local.composed].wc]); 149 if(ret > wlen) { 150 if(status) *status = XBufferOverflow; 151 return (ret); 152 } 153 memcpy((char *)buffer, (char *)&wc[b[ic->private.local.composed].wc], 154 ret * sizeof(wchar_t)); 155 if(keysym) *keysym = b[ic->private.local.composed].ks; 156 if (ret > 0) { 157 if (keysym && *keysym != NoSymbol) { 158 if(status) *status = XLookupBoth; 159 } else { 160 if(status) *status = XLookupChars; 161 } 162 } else { 163 if(keysym && *keysym != NoSymbol) { 164 if(status) *status = XLookupKeySym; 165 } else { 166 if(status) *status = XLookupNone; 167 } 168 } 169 } 170 return (ret); 171 } else { /* Throughed Event */ 172 ret = _XimLookupWCText(ic, ev, buffer, wlen, keysym, NULL); 173 if(ret > 0) { 174 if (ret > wlen) { 175 if (status) *status = XBufferOverflow; 176 } else if (keysym && *keysym != NoSymbol) { 177 if(status) *status = XLookupBoth; 178 } else { 179 if(status) *status = XLookupChars; 180 } 181 } else { 182 if(keysym && *keysym != NoSymbol) { 183 if(status) *status = XLookupKeySym; 184 } else { 185 if(status) *status = XLookupNone; 186 } 187 } 188 } 189 return (ret); 190} 191 192Public int 193_XimLocalUtf8LookupString(XIC xic, XKeyEvent *ev, char *buffer, int bytes, 194 KeySym *keysym, Status *status) 195{ 196 Xic ic = (Xic)xic; 197 int ret; 198 DefTree *b = ic->private.local.base.tree; 199 char *utf8 = ic->private.local.base.utf8; 200 201 if(ev->type != KeyPress) { 202 if(status) *status = XLookupNone; 203 return(0); 204 } 205 if(ev->keycode == 0) { 206 if (ic->private.local.brl_committed != 0) { /* Braille Event */ 207 unsigned char pattern = ic->private.local.brl_committed; 208 ret = 3; 209 if (ret > bytes) { 210 if(status) *status = XBufferOverflow; 211 return (ret); 212 } 213 buffer[0] = 0xe0 | ((BRL_UC_ROW >> 12) & 0x0f); 214 buffer[1] = 0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6); 215 buffer[2] = 0x80 | (pattern & 0x3f); 216 } else { /* Composed Event */ 217 ret = strlen(&utf8[b[ic->private.local.composed].utf8]); 218 if(ret > bytes) { 219 if(status) *status = XBufferOverflow; 220 return (ret); 221 } 222 memcpy(buffer, &utf8[b[ic->private.local.composed].utf8], ret); 223 if(keysym) *keysym = b[ic->private.local.composed].ks; 224 if (ret > 0) { 225 if (keysym && *keysym != NoSymbol) { 226 if(status) *status = XLookupBoth; 227 } else { 228 if(status) *status = XLookupChars; 229 } 230 } else { 231 if(keysym && *keysym != NoSymbol) { 232 if(status) *status = XLookupKeySym; 233 } else { 234 if(status) *status = XLookupNone; 235 } 236 } 237 } 238 return (ret); 239 } else { /* Throughed Event */ 240 ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); 241 if(ret > 0) { 242 if (ret > bytes) { 243 if (status) *status = XBufferOverflow; 244 } else if (keysym && *keysym != NoSymbol) { 245 if(status) *status = XLookupBoth; 246 } else { 247 if(status) *status = XLookupChars; 248 } 249 } else { 250 if(keysym && *keysym != NoSymbol) { 251 if(status) *status = XLookupKeySym; 252 } else { 253 if(status) *status = XLookupNone; 254 } 255 } 256 } 257 return (ret); 258} 259 260Private int 261_XimLcctsconvert( 262 XlcConv conv, 263 char *from, 264 int from_len, 265 char *to, 266 int to_len, 267 Status *state) 268{ 269 int from_left; 270 int to_left; 271 int from_savelen; 272 int to_savelen; 273 int from_cnvlen; 274 int to_cnvlen; 275 char *from_buf; 276 char *to_buf; 277 char scratchbuf[BUFSIZ]; 278 Status tmp_state; 279 280 if (!state) 281 state = &tmp_state; 282 283 if (!conv || !from || !from_len) { 284 *state = XLookupNone; 285 return 0; 286 } 287 288 /* Reset the converter. The CompoundText at 'from' starts in 289 initial state. */ 290 _XlcResetConverter(conv); 291 292 from_left = from_len; 293 to_left = BUFSIZ; 294 from_cnvlen = 0; 295 to_cnvlen = 0; 296 for (;;) { 297 from_buf = &from[from_cnvlen]; 298 from_savelen = from_left; 299 to_buf = &scratchbuf[to_cnvlen]; 300 to_savelen = to_left; 301 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 302 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 303 *state = XLookupNone; 304 return 0; 305 } 306 from_cnvlen += (from_savelen - from_left); 307 to_cnvlen += (to_savelen - to_left); 308 if (from_left == 0) { 309 if (!to_cnvlen) { 310 *state = XLookupNone; 311 return 0; 312 } 313 break; 314 } 315 } 316 317 if (!to || !to_len || (to_len < to_cnvlen)) { 318 *state = XBufferOverflow; 319 } else { 320 memcpy(to, scratchbuf, to_cnvlen); 321 *state = XLookupChars; 322 } 323 return to_cnvlen; 324} 325 326Public int 327_XimLcctstombs(XIM xim, char *from, int from_len, 328 char *to, int to_len, Status *state) 329{ 330 return _XimLcctsconvert(((Xim)xim)->private.local.ctom_conv, 331 from, from_len, to, to_len, state); 332} 333 334Public int 335_XimLcctstowcs(XIM xim, char *from, int from_len, 336 wchar_t *to, int to_len, Status *state) 337{ 338 Xim im = (Xim)xim; 339 XlcConv conv = im->private.local.ctow_conv; 340 int from_left; 341 int to_left; 342 int from_savelen; 343 int to_savelen; 344 int from_cnvlen; 345 int to_cnvlen; 346 char *from_buf; 347 wchar_t *to_buf; 348 wchar_t scratchbuf[BUFSIZ]; 349 Status tmp_state; 350 351 if (!state) 352 state = &tmp_state; 353 354 if (!conv || !from || !from_len) { 355 *state = XLookupNone; 356 return 0; 357 } 358 359 /* Reset the converter. The CompoundText at 'from' starts in 360 initial state. */ 361 _XlcResetConverter(conv); 362 363 from_left = from_len; 364 to_left = BUFSIZ; 365 from_cnvlen = 0; 366 to_cnvlen = 0; 367 for (;;) { 368 from_buf = &from[from_cnvlen]; 369 from_savelen = from_left; 370 to_buf = &scratchbuf[to_cnvlen]; 371 to_savelen = to_left; 372 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 373 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 374 *state = XLookupNone; 375 return 0; 376 } 377 from_cnvlen += (from_savelen - from_left); 378 to_cnvlen += (to_savelen - to_left); 379 if (from_left == 0) { 380 if (!to_cnvlen){ 381 *state = XLookupNone; 382 return 0; 383 } 384 break; 385 } 386 } 387 388 if (!to || !to_len || (to_len < to_cnvlen)) { 389 *state = XBufferOverflow; 390 } else { 391 memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); 392 *state = XLookupChars; 393 } 394 return to_cnvlen; 395} 396 397Public int 398_XimLcctstoutf8(XIM xim, char *from, int from_len, 399 char *to, int to_len, Status *state) 400{ 401 return _XimLcctsconvert(((Xim)xim)->private.local.ctoutf8_conv, 402 from, from_len, to, to_len, state); 403} 404