upload tizen2.0 source
[framework/uifw/xorg/lib/libx11.git] / src / imConv.c
1 /******************************************************************
2
3               Copyright 1991, 1992 by Fuji Xerox Co.,Ltd.
4               Copyright 1993, 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 Co.,Ltd.
11 , and that the name of FUJITSU LIMITED not be used in advertising or
12 publicity pertaining to distribution of the software without specific,
13  written prior permission.
14 Fuji Xerox Co.,Ltd. , and FUJITSU LIMITED makes no representations about
15 the suitability of this software for any purpose.
16 It is provided "as is" without express or implied warranty.
17
18 FUJI XEROX CO.,LTD. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH
19 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
20 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX CO.,LTD.
21 AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT
22 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
23 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
24 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
25 THE USE OR PERFORMANCE OF THIS SOFTWARE.
26
27   Auther:   Kazunori Nishihara, Fuji Xerox Co.,Ltd.
28                                 kaz@ssdev.ksp.fujixerox.co.jp
29   Modifier: Takashi Fujiwara    FUJITSU LIMITED
30                                 fujiwara@a80.tech.yk.fujitsu.co.jp
31
32 ******************************************************************/
33 /* 2000 Modifier: Ivan Pascal   The XFree86 Project.
34  */
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39 #include <stdio.h>
40 #include "Xlibint.h"
41 #include "Xlcint.h"
42 #include "Ximint.h"
43 #include "XlcPubI.h"
44
45 #ifdef XKB
46 /*
47  * rather than just call _XLookupString (i.e. the pre-XKB XLookupString)
48  * do this because with XKB the event may have some funky modifiers that
49  * _XLookupString doesn't grok.
50  */
51 #include "XKBlib.h"
52 #define XLOOKUPSTRING lookup_string
53 #else
54 #define XLOOKUPSTRING XLookupString
55 #endif
56
57 typedef unsigned int ucs4_t;
58
59 typedef int (*ucstocsConvProc)(
60     XPointer,
61     unsigned char *,
62     ucs4_t,
63     int
64 );
65
66 struct SubstRec {
67     const char encoding_name[8];
68     const char charset_name[12];
69 };
70
71 static const struct SubstRec SubstTable[] = {
72     {"STRING", "ISO8859-1"},
73     {"TIS620", "TIS620-0"},
74     {"UTF-8",  "ISO10646-1"}
75 };
76 #define num_substitute (sizeof SubstTable / sizeof SubstTable[0])
77
78 /*
79  * Given the name of a charset, returns the pointer to convertors
80  * from UCS char to specified charset char.
81  * This converter is needed for _XimGetCharCode subroutine.
82  */
83 XPointer
84 _XimGetLocaleCode (
85     _Xconst char*       encoding_name)
86 {
87     XPointer cvt = _Utf8GetConvByName(encoding_name);
88     if (!cvt && encoding_name) {
89        int i;
90        for (i = 0; i < num_substitute; i++)
91            if (!strcmp(encoding_name, SubstTable[i].encoding_name))
92                return _Utf8GetConvByName(SubstTable[i].charset_name);
93     }
94     return cvt;
95 }
96
97 /*
98  * Returns the locale dependent representation of a keysym.
99  * The locale's encoding is passed in form of pointer to UCS convertor.
100  * The resulting multi-byte sequence is placed starting at buf (a buffer
101  * with nbytes bytes, nbytes should be >= 8) and is NUL terminated.
102  * Returns the length of the resulting multi-byte sequence, excluding the
103  * terminating NUL byte. Return 0 if the keysym is not representable in the
104  * locale
105  */
106 /*ARGSUSED*/
107 int
108 _XimGetCharCode (
109     XPointer            ucs_conv,
110     KeySym              keysym,
111     unsigned char*      buf,
112     int                 nbytes)
113 {
114     int count = 0;
115     ucstocsConvProc cvt = (ucstocsConvProc) ucs_conv;
116     ucs4_t ucs4;
117
118     if (keysym < 0x80) {
119         buf[0] = (char) keysym;
120         count = 1;
121     } else if (cvt) {
122         ucs4 = KeySymToUcs4(keysym);
123         if (ucs4)
124             count = (*cvt)((XPointer)NULL, buf, ucs4, nbytes);
125     }
126
127     if (count < 0)
128         count = 0;
129     if (count>nbytes)
130         return nbytes;
131     if (count<nbytes)
132         buf[count]= '\0';
133     return count;
134 }
135
136 #ifdef XKB
137 static int lookup_string(
138     XKeyEvent*          event,
139     char*               buffer,
140     int                 nbytes,
141     KeySym*             keysym,
142     XComposeStatus*     status)
143 {
144     int ret;
145     unsigned ctrls = XkbGetXlibControls (event->display);
146     XkbSetXlibControls (event->display,
147                         XkbLC_ForceLatin1Lookup, XkbLC_ForceLatin1Lookup);
148     ret = XLookupString(event, (char *)buffer, nbytes, keysym, status);
149     XkbSetXlibControls (event->display,
150                         XkbLC_ForceLatin1Lookup, ctrls);
151     return ret;
152 }
153 #endif
154
155 #define BUF_SIZE (20)
156
157 int
158 _XimLookupMBText(
159     Xic                  ic,
160     XKeyEvent*          event,
161     char*               buffer,
162     int                 nbytes,
163     KeySym*             keysym,
164     XComposeStatus*     status)
165 {
166     int count;
167     KeySym symbol;
168     Status      dummy;
169     Xim im = (Xim)ic->core.im;
170     XimCommonPrivateRec* private = &im->private.common;
171     unsigned char look[BUF_SIZE];
172     ucs4_t ucs4;
173
174     /* force a latin-1 lookup for compatibility */
175     count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status);
176     if (keysym != NULL) *keysym = symbol;
177     if ((nbytes == 0) || (symbol == NoSymbol)) return count;
178
179     if (count > 1) {
180         memcpy(look, (char *)buffer,count);
181         look[count] = '\0';
182         if ((count = im->methods->ctstombs(ic->core.im,
183                                 (char*) look, count,
184                                 buffer, nbytes, &dummy)) < 0) {
185             count = 0;
186         }
187     } else if ((count == 0) ||
188                (count == 1 && (symbol > 0x7f && symbol < 0xff00))) {
189
190         XPointer from = (XPointer) &ucs4;
191         XPointer to =   (XPointer) look;
192         int from_len = 1;
193         int to_len = BUF_SIZE;
194         XPointer args[1];
195         XlcCharSet charset;
196         args[0] = (XPointer) &charset;
197         ucs4 = (ucs4_t) KeySymToUcs4(symbol);
198         if (!ucs4)
199             return 0;
200
201         if (_XlcConvert(private->ucstoc_conv,
202                         &from, &from_len, &to, &to_len,
203                         args, 1 ) != 0) {
204             count = 0;
205         } else {
206             from = (XPointer) look;
207             to =   (XPointer) buffer;
208             from_len = BUF_SIZE - to_len;
209             to_len = nbytes;
210             args[0] = (XPointer) charset;
211             if (_XlcConvert(private->cstomb_conv,
212                             &from, &from_len, &to, &to_len,
213                             args, 1 ) != 0) {
214                 count = 0;
215             } else {
216                 count = nbytes - to_len;
217             }
218         }
219     }
220     /* FIXME:
221      * we should make sure that if the character is a Latin1 character
222      * and it's on the right side, and we're in a non-Latin1 locale
223      * that this is a valid Latin1 character for this locale.
224      */
225     return count;
226 }
227
228 int
229 _XimLookupWCText(
230     Xic                  ic,
231     XKeyEvent*          event,
232     wchar_t*            buffer,
233     int                 nbytes,
234     KeySym*             keysym,
235     XComposeStatus*     status)
236 {
237     int count;
238     KeySym symbol;
239     Status      dummy;
240     Xim im = (Xim)ic->core.im;
241     XimCommonPrivateRec* private = &im->private.common;
242     unsigned char look[BUF_SIZE];
243     ucs4_t ucs4;
244
245     /* force a latin-1 lookup for compatibility */
246     count = XLOOKUPSTRING(event, (char *)look, nbytes, &symbol, status);
247     if (keysym != NULL) *keysym = symbol;
248     if ((nbytes == 0) || (symbol == NoSymbol)) return count;
249
250     if (count > 1) {
251         if ((count = im->methods->ctstowcs(ic->core.im,
252                                 (char*) look, count,
253                                 buffer, nbytes, &dummy)) < 0) {
254             count = 0;
255         }
256     } else if ((count == 0) ||
257                (count == 1 && (symbol > 0x7f && symbol < 0xff00))) {
258
259         XPointer from = (XPointer) &ucs4;
260         XPointer to =   (XPointer) look;
261         int from_len = 1;
262         int to_len = BUF_SIZE;
263         XPointer args[1];
264         XlcCharSet charset;
265         args[0] = (XPointer) &charset;
266         ucs4 = (ucs4_t) KeySymToUcs4(symbol);
267         if (!ucs4)
268             return 0;
269
270         if (_XlcConvert(private->ucstoc_conv,
271                         &from, &from_len, &to, &to_len,
272                         args, 1 ) != 0) {
273             count = 0;
274         } else {
275             from = (XPointer) look;
276             to =   (XPointer) buffer;
277             from_len = BUF_SIZE - to_len;
278             to_len = nbytes;
279             args[0] = (XPointer) charset;
280
281             if (_XlcConvert(private->cstowc_conv,
282                             &from, &from_len, &to, &to_len,
283                             args, 1 ) != 0) {
284                 count = 0;
285             } else {
286                 count = nbytes - to_len;
287             }
288         }
289     } else
290         /* FIXME:
291          * we should make sure that if the character is a Latin1 character
292          * and it's on the right side, and we're in a non-Latin1 locale
293          * that this is a valid Latin1 character for this locale.
294          */
295         buffer[0] = look[0];
296
297     return count;
298 }
299
300 int
301 _XimLookupUTF8Text(
302     Xic                  ic,
303     XKeyEvent*          event,
304     char*               buffer,
305     int                 nbytes,
306     KeySym*             keysym,
307     XComposeStatus*     status)
308 {
309     int count;
310     KeySym symbol;
311     Status      dummy;
312     Xim im = (Xim)ic->core.im;
313     XimCommonPrivateRec* private = &im->private.common;
314     unsigned char look[BUF_SIZE];
315     ucs4_t ucs4;
316
317     /* force a latin-1 lookup for compatibility */
318     count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status);
319     if (keysym != NULL) *keysym = symbol;
320     if ((nbytes == 0) || (symbol == NoSymbol)) return count;
321
322     if (count > 1) {
323         memcpy(look, (char *)buffer,count);
324         look[count] = '\0';
325         if ((count = im->methods->ctstoutf8(ic->core.im,
326                                 (char*) look, count,
327                                 buffer, nbytes, &dummy)) < 0) {
328             count = 0;
329         }
330     } else if ((count == 0) ||
331                (count == 1 && (symbol > 0x7f && symbol < 0xff00))) {
332
333         XPointer from = (XPointer) &ucs4;
334         int from_len = 1;
335         XPointer to = (XPointer) buffer;
336         int to_len = nbytes;
337
338         ucs4 = (ucs4_t) KeySymToUcs4(symbol);
339         if (!ucs4)
340             return 0;
341
342         if (_XlcConvert(private->ucstoutf8_conv,
343                         &from, &from_len, &to, &to_len,
344                         NULL, 0) != 0) {
345             count = 0;
346         } else {
347             count = nbytes - to_len;
348         }
349     }
350     /* FIXME:
351      * we should make sure that if the character is a Latin1 character
352      * and it's on the right side, and we're in a non-Latin1 locale
353      * that this is a valid Latin1 character for this locale.
354      */
355     return count;
356 }