1/*
2
3Copyright 1988, 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include <X11/Xmu/Lookup.h>
31
32#define XK_LATIN1
33#define XK_PUBLISHING
34#include <X11/keysymdef.h>
35
36/* bit (1<<i) means character is in codeset i */
37static unsigned short _Xconst latin1[128] =
38  {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
39   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
40   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
41   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
42   0x10ee, 0x0000, 0x1000, 0x1084, 0x102e, 0x1000, 0x1080, 0x108e, /* 10 */
43   0x108e, 0x1080, 0x0000, 0x1080, 0x1080, 0x10ee, 0x1000, 0x1008,
44   0x108e, 0x1080, 0x1084, 0x1084, 0x108e, 0x1004, 0x1000, 0x1084, /* 11 */
45   0x100e, 0x1000, 0x0000, 0x1080, 0x1000, 0x1084, 0x1000, 0x0000,
46   0x0004, 0x000e, 0x000e, 0x0008, 0x000e, 0x0008, 0x0008, 0x0006, /* 12 */
47   0x0004, 0x000e, 0x0004, 0x000e, 0x0004, 0x000e, 0x000e, 0x0004,
48   0x0000, 0x0004, 0x0004, 0x0006, 0x000e, 0x0008, 0x000e, 0x000e, /* 13 */
49   0x0008, 0x0004, 0x000e, 0x000c, 0x000e, 0x0002, 0x0000, 0x000e,
50   0x0004, 0x000e, 0x000e, 0x0008, 0x000e, 0x0008, 0x0008, 0x0006, /* 14 */
51   0x0004, 0x000e, 0x0004, 0x000e, 0x0004, 0x000e, 0x000e, 0x0004,
52   0x0000, 0x0004, 0x0004, 0x0006, 0x000e, 0x0008, 0x000e, 0x000e, /* 15 */
53   0x0008, 0x0004, 0x000e, 0x000c, 0x000e, 0x0002, 0x0000, 0x0000};
54
55/* bit (1<<i) means character is in codeset i */
56static unsigned short _Xconst latin2[128] =
57  {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
58   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
59   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
60   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
61   0x0000, 0x0008, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10 */
62   0x0000, 0x0008, 0x0004, 0x0000, 0x0000, 0x0000, 0x0008, 0x0004,
63   0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, /* 11 */
64   0x0000, 0x0008, 0x0004, 0x0000, 0x0000, 0x0000, 0x0008, 0x0004,
65   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
66   0x0008, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
67   0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 13 */
68   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
69   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 14 */
70   0x0008, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
71   0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 15 */
72   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c};
73
74/* maps Cyrillic keysyms to 8859-5 */
75static unsigned char _Xconst cyrillic[128] =
76   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80    0x00, 0xf2, 0xf3, 0xf1, 0xf4, 0xf5, 0xf6, 0xf7, /* 10 */
81    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff,
82    0xf0, 0xa2, 0xa3, 0xa1, 0xa4, 0xa5, 0xa6, 0xa7, /* 11 */
83    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf,
84    0xee, 0xd0, 0xd1, 0xe6, 0xd4, 0xd5, 0xe4, 0xd3, /* 12 */
85    0xe5, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
86    0xdf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xd6, 0xd2, /* 13 */
87    0xec, 0xeb, 0xd7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
88    0xce, 0xb0, 0xb1, 0xc6, 0xb4, 0xb5, 0xc4, 0xb3, /* 14 */
89    0xc5, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
90    0xbf, 0xcf, 0xc0, 0xc1, 0xc2, 0xc3, 0xb6, 0xb2, /* 15 */
91    0xcc, 0xcb, 0xb7, 0xc8, 0xcd, 0xc9, 0xc7, 0xca};
92
93/* maps Greek keysyms to 8859-7 */
94static unsigned char _Xconst greek[128] =
95   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99    0x00, 0xb6, 0xb8, 0xb9, 0xba, 0xda, 0x00, 0xbc, /* 10 */
100    0xbe, 0xdb, 0x00, 0xbf, 0x00, 0x00, 0xb5, 0xaf,
101    0x00, 0xdc, 0xdd, 0xde, 0xdf, 0xfa, 0xc0, 0xfc, /* 11 */
102    0xfd, 0xfb, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00,
103    0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 12 */
104    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
105    0xd0, 0xd1, 0xd3, 0x00, 0xd4, 0xd5, 0xd6, 0xd7, /* 13 */
106    0xd8, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107    0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 14 */
108    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
109    0xf0, 0xf1, 0xf3, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7, /* 15 */
110    0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
111
112#define sLatin1		(unsigned long)0
113#define sLatin2		(unsigned long)1
114#define sLatin3		(unsigned long)2
115#define sLatin4		(unsigned long)3
116#define sKana		(unsigned long)4
117#define sX0201		(unsigned long)0x01000004
118#define sArabic		(unsigned long)5
119#define sCyrillic	(unsigned long)6
120#define sGreek		(unsigned long)7
121#define sAPL		(unsigned long)11
122#define sHebrew		(unsigned long)12
123
124int
125XmuLookupString(register XKeyEvent *event, unsigned char *buffer, int nbytes,
126		KeySym *keysym, XComposeStatus *status,
127		unsigned long keysymSet)
128{
129    int count;
130    KeySym symbol;
131    unsigned long kset;
132
133    kset = keysymSet & 0xffffff;
134    count = XLookupString(event, (char *)buffer, nbytes, &symbol, status);
135    if (keysym) *keysym = symbol;
136    if ((nbytes == 0) || (symbol == NoSymbol)) {
137	/* nothing */
138    } else if ((count == 0) && ((symbol >> 8) == kset)) {
139	count = 1;
140	switch (keysymSet) {
141	case sKana:
142	    buffer[0] = (symbol & 0xff);
143	    if (buffer[0] == 0x7e)
144		count = 0;
145	    break;
146	case sCyrillic:
147	    buffer[0] = cyrillic[symbol & 0x7f];
148	    break;
149	case sGreek:
150	    buffer[0] = greek[symbol & 0x7f];
151	    if (!buffer[0])
152		count = 0;
153	    break;
154	default:
155	    buffer[0] = (symbol & 0xff);
156	    break;
157	}
158    } else if ((keysymSet != 0) && (count == 1) &&
159	       (((unsigned char *)buffer)[0] == symbol) &&
160	       (symbol & 0x80) &&
161	       !(latin1[symbol & 0x7f] & (1 << kset))) {
162	if ((keysymSet == sHebrew) && (symbol == XK_multiply))
163	    buffer[0] = 0xaa;
164	else if ((keysymSet == sHebrew) && (symbol == XK_division))
165	    buffer[0] = 0xba;
166	else if ((keysymSet == sCyrillic) && (symbol == XK_section))
167	    buffer[0] = 0xfd;
168	else if ((keysymSet == sX0201) && (symbol == XK_yen))
169	    buffer[0] = 0x5c;
170	else
171	    count = 0;
172    } else if (count != 0) {
173	if ((keysymSet == sX0201) &&
174	    ((symbol == XK_backslash) || (symbol == XK_asciitilde)))
175	    count = 0;
176    } else if (((symbol >> 8) == sLatin2) &&
177	       (symbol & 0x80) && (latin2[symbol & 0x7f] & (1 << kset))) {
178	buffer[0] = (symbol & 0xff);
179	count = 1;
180    } else if ((keysymSet == sGreek) &&
181	       ((symbol == XK_leftsinglequotemark) ||
182		(symbol == XK_rightsinglequotemark))) {
183	buffer[0] = symbol - (XK_leftsinglequotemark - 0xa1);
184	count = 1;
185    }
186    return count;
187}
188
189/* produces ISO 8859-1 encoding plus ASCII control */
190int
191XmuLookupLatin1(register XKeyEvent *event, unsigned char *buffer, int nbytes,
192		KeySym *keysym, XComposeStatus *status)
193{
194    return XLookupString(event, (char *)buffer, nbytes, keysym, status);
195}
196
197/* produces ISO 8859-2 encoding plus ASCII control */
198int
199XmuLookupLatin2(register XKeyEvent *event, unsigned char *buffer, int nbytes,
200		KeySym *keysym, XComposeStatus *status)
201{
202    return XmuLookupString(event, buffer, nbytes, keysym, status, sLatin2);
203}
204
205/* produces ISO 8859-3 encoding plus ASCII control */
206int
207XmuLookupLatin3(register XKeyEvent *event, unsigned char *buffer, int nbytes,
208		KeySym *keysym, XComposeStatus *status)
209{
210    return XmuLookupString(event, buffer, nbytes, keysym, status, sLatin3);
211}
212
213/* produces ISO 8859-4 encoding plus ASCII control */
214int
215XmuLookupLatin4(register XKeyEvent *event, unsigned char *buffer, int nbytes,
216		KeySym *keysym, XComposeStatus *status)
217{
218    return XmuLookupString(event, buffer, nbytes, keysym, status, sLatin4);
219}
220
221/* produces ISO 8859-1 GL plus Katakana plus ASCII control */
222int
223XmuLookupKana(register XKeyEvent *event, unsigned char *buffer, int nbytes,
224	      KeySym *keysym, XComposeStatus *status)
225{
226    return XmuLookupString(event, buffer, nbytes, keysym, status, sKana);
227}
228
229/* produces JIS X0201-1976 (8-bit) */
230int
231XmuLookupJISX0201(register XKeyEvent *event, unsigned char *buffer, int nbytes,
232		  KeySym *keysym, XComposeStatus *status)
233{
234    return XmuLookupString(event, buffer, nbytes, keysym, status, sX0201);
235}
236
237/* produces ISO 8859-6 encoding plus ASCII control */
238int
239XmuLookupArabic(register XKeyEvent *event, unsigned char *buffer, int nbytes,
240		KeySym *keysym, XComposeStatus *status)
241{
242    return XmuLookupString(event, buffer, nbytes, keysym, status, sArabic);
243}
244
245/* produces ISO/IEC 8859-5 encoding plus ASCII control */
246int
247XmuLookupCyrillic(register XKeyEvent *event, unsigned char *buffer, int nbytes,
248		  KeySym *keysym, XComposeStatus *status)
249{
250    return XmuLookupString(event, buffer, nbytes, keysym, status, sCyrillic);
251}
252
253/* produces ISO 8859-7 encoding plus ASCII control */
254int
255XmuLookupGreek(register XKeyEvent *event, unsigned char *buffer, int nbytes,
256	       KeySym *keysym, XComposeStatus *status)
257{
258    return XmuLookupString(event, buffer, nbytes, keysym, status, sGreek);
259}
260
261/* XXX this character set needs work */
262
263int
264XmuLookupAPL(register XKeyEvent *event, unsigned char *buffer, int nbytes,
265	     KeySym *keysym, XComposeStatus *status)
266{
267    return XmuLookupString(event, buffer, nbytes, keysym, status, sAPL);
268}
269
270/* produces ISO 8859-8 encoding plus ASCII control */
271int
272XmuLookupHebrew(register XKeyEvent *event, unsigned char *buffer, int nbytes,
273		KeySym *keysym, XComposeStatus *status)
274{
275    return XmuLookupString(event, buffer, nbytes, keysym, status, sHebrew);
276}
277