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