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