Home | History | Annotate | Line # | Download | only in ximcp
      1 /******************************************************************
      2 
      3               Copyright 1992 by Fuji Xerox Co., Ltd.
      4               Copyright 1992, 1994  by FUJITSU LIMITED
      5 
      6 Permission to use, copy, modify, distribute, and sell this software
      7 and its documentation for any purpose is hereby granted without fee,
      8 provided that the above copyright notice appear in all copies and
      9 that both that copyright notice and this permission notice appear
     10 in supporting documentation, and that the name of Fuji Xerox,
     11 FUJITSU LIMITED not be used in advertising or publicity pertaining
     12 to distribution of the software without specific, written prior
     13 permission.  Fuji Xerox, FUJITSU LIMITED  make no representations
     14 about the suitability of this software for any purpose.
     15 It is provided "as is" without express or implied warranty.
     16 
     17 FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH
     18 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
     19 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX,
     20 FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     21 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
     22 OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     23 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     24 PERFORMANCE OF THIS SOFTWARE.
     25 
     26   Author: Kazunori Nishihara   Fuji Xerox
     27           Takashi Fujiwara     FUJITSU LIMITED
     28                                fujiwara (at) 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 
     46 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 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 
    129 int
    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 
    201 int
    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] = (char)(0xe0 | ((BRL_UC_ROW >> 12) & 0x0f));
    223 	    buffer[1] = (char)(0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6));
    224 	    buffer[2] = (char)(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 
    274 static 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 
    340 int
    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 
    348 int
    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 
    411 int
    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