xref: /minix3/external/mit/xorg/tools/xkbcomp/xkbcomp-KeyBind.c (revision 971bb1a5878d19f91739f74fd389e6c5108cb7fa)
1*971bb1a5SLionel Sambuc /*	$NetBSD: xkbcomp-KeyBind.c,v 1.1.1.1 2008/07/29 05:01:23 mrg Exp $	*/
2*971bb1a5SLionel Sambuc 
3*971bb1a5SLionel Sambuc /* $Xorg: KeyBind.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */
4*971bb1a5SLionel Sambuc /*
5*971bb1a5SLionel Sambuc 
6*971bb1a5SLionel Sambuc Copyright 1985, 1987, 1998  The Open Group
7*971bb1a5SLionel Sambuc 
8*971bb1a5SLionel Sambuc Permission to use, copy, modify, distribute, and sell this software and its
9*971bb1a5SLionel Sambuc documentation for any purpose is hereby granted without fee, provided that
10*971bb1a5SLionel Sambuc the above copyright notice appear in all copies and that both that
11*971bb1a5SLionel Sambuc copyright notice and this permission notice appear in supporting
12*971bb1a5SLionel Sambuc documentation.
13*971bb1a5SLionel Sambuc 
14*971bb1a5SLionel Sambuc The above copyright notice and this permission notice shall be included in
15*971bb1a5SLionel Sambuc all copies or substantial portions of the Software.
16*971bb1a5SLionel Sambuc 
17*971bb1a5SLionel Sambuc THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*971bb1a5SLionel Sambuc IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*971bb1a5SLionel Sambuc FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20*971bb1a5SLionel Sambuc OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21*971bb1a5SLionel Sambuc AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22*971bb1a5SLionel Sambuc CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*971bb1a5SLionel Sambuc 
24*971bb1a5SLionel Sambuc Except as contained in this notice, the name of The Open Group shall not be
25*971bb1a5SLionel Sambuc used in advertising or otherwise to promote the sale, use or other dealings
26*971bb1a5SLionel Sambuc in this Software without prior written authorization from The Open Group.
27*971bb1a5SLionel Sambuc 
28*971bb1a5SLionel Sambuc */
29*971bb1a5SLionel Sambuc /* $XFree86: xc/lib/X11/KeyBind.c,v 1.5 2001/12/14 19:54:02 dawes Exp $ */
30*971bb1a5SLionel Sambuc 
31*971bb1a5SLionel Sambuc /* Beware, here be monsters (still under construction... - JG */
32*971bb1a5SLionel Sambuc 
33*971bb1a5SLionel Sambuc #define NEED_EVENTS
34*971bb1a5SLionel Sambuc #include <X11/Xlibint.h>
35*971bb1a5SLionel Sambuc #include <X11/Xutil.h>
36*971bb1a5SLionel Sambuc #define XK_MISCELLANY
37*971bb1a5SLionel Sambuc #define XK_LATIN1
38*971bb1a5SLionel Sambuc #define XK_LATIN2
39*971bb1a5SLionel Sambuc #define XK_LATIN3
40*971bb1a5SLionel Sambuc #define XK_LATIN4
41*971bb1a5SLionel Sambuc #define XK_CYRILLIC
42*971bb1a5SLionel Sambuc #define XK_GREEK
43*971bb1a5SLionel Sambuc #define XK_ARMENIAN
44*971bb1a5SLionel Sambuc #define XK_XKB_KEYS
45*971bb1a5SLionel Sambuc #include <X11/keysymdef.h>
46*971bb1a5SLionel Sambuc #include <stdio.h>
47*971bb1a5SLionel Sambuc 
48*971bb1a5SLionel Sambuc #include "XKBlib.h"
49*971bb1a5SLionel Sambuc 
50*971bb1a5SLionel Sambuc #ifdef USE_OWN_COMPOSE
51*971bb1a5SLionel Sambuc #include "imComp.h"
52*971bb1a5SLionel Sambuc 
53*971bb1a5SLionel Sambuc #endif
54*971bb1a5SLionel Sambuc 
55*971bb1a5SLionel Sambuc #ifdef XKB
56*971bb1a5SLionel Sambuc #define	XKeycodeToKeysym	_XKeycodeToKeysym
57*971bb1a5SLionel Sambuc #define	XKeysymToKeycode	_XKeysymToKeycode
58*971bb1a5SLionel Sambuc #define	XLookupKeysym		_XLookupKeysym
59*971bb1a5SLionel Sambuc #define	XRefreshKeyboardMapping	_XRefreshKeyboardMapping
60*971bb1a5SLionel Sambuc #define	XLookupString		_XLookupString
61*971bb1a5SLionel Sambuc /* XKBBind.c */
62*971bb1a5SLionel Sambuc #else
63*971bb1a5SLionel Sambuc #define	XkbKeysymToModifiers	_XKeysymToModifiers
64*971bb1a5SLionel Sambuc #endif
65*971bb1a5SLionel Sambuc 
66*971bb1a5SLionel Sambuc #define AllMods (ShiftMask|LockMask|ControlMask| \
67*971bb1a5SLionel Sambuc 		 Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
68*971bb1a5SLionel Sambuc 
69*971bb1a5SLionel Sambuc #if 0	/* { */
70*971bb1a5SLionel Sambuc 
71*971bb1a5SLionel Sambuc static void ComputeMaskFromKeytrans();
72*971bb1a5SLionel Sambuc int _XKeyInitialize();
73*971bb1a5SLionel Sambuc 
74*971bb1a5SLionel Sambuc struct _XKeytrans {
75*971bb1a5SLionel Sambuc 	struct _XKeytrans *next;/* next on list */
76*971bb1a5SLionel Sambuc 	char *string;		/* string to return when the time comes */
77*971bb1a5SLionel Sambuc 	int len;		/* length of string (since NULL is legit)*/
78*971bb1a5SLionel Sambuc 	KeySym key;		/* keysym rebound */
79*971bb1a5SLionel Sambuc 	unsigned int state;	/* modifier state */
80*971bb1a5SLionel Sambuc 	KeySym *modifiers;	/* modifier keysyms you want */
81*971bb1a5SLionel Sambuc 	int mlen;		/* length of modifier list */
82*971bb1a5SLionel Sambuc };
83*971bb1a5SLionel Sambuc 
84*971bb1a5SLionel Sambuc static KeySym
85*971bb1a5SLionel Sambuc #if NeedFunctionPrototypes
86*971bb1a5SLionel Sambuc KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col)
87*971bb1a5SLionel Sambuc #else
88*971bb1a5SLionel Sambuc KeyCodetoKeySym(dpy, keycode, col)
89*971bb1a5SLionel Sambuc     register Display *dpy;
90*971bb1a5SLionel Sambuc     KeyCode keycode;
91*971bb1a5SLionel Sambuc     int col;
92*971bb1a5SLionel Sambuc #endif
93*971bb1a5SLionel Sambuc {
94*971bb1a5SLionel Sambuc     register int per = dpy->keysyms_per_keycode;
95*971bb1a5SLionel Sambuc     register KeySym *syms;
96*971bb1a5SLionel Sambuc     KeySym lsym, usym;
97*971bb1a5SLionel Sambuc 
98*971bb1a5SLionel Sambuc     if ((col < 0) || ((col >= per) && (col > 3)) ||
99*971bb1a5SLionel Sambuc 	((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
100*971bb1a5SLionel Sambuc       return NoSymbol;
101*971bb1a5SLionel Sambuc 
102*971bb1a5SLionel Sambuc     syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
103*971bb1a5SLionel Sambuc     if (col < 4) {
104*971bb1a5SLionel Sambuc 	if (col > 1) {
105*971bb1a5SLionel Sambuc 	    while ((per > 2) && (syms[per - 1] == NoSymbol))
106*971bb1a5SLionel Sambuc 		per--;
107*971bb1a5SLionel Sambuc 	    if (per < 3)
108*971bb1a5SLionel Sambuc 		col -= 2;
109*971bb1a5SLionel Sambuc 	}
110*971bb1a5SLionel Sambuc 	if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
111*971bb1a5SLionel Sambuc 	    XConvertCase(syms[col&~1], &lsym, &usym);
112*971bb1a5SLionel Sambuc 	    if (!(col & 1))
113*971bb1a5SLionel Sambuc 		return lsym;
114*971bb1a5SLionel Sambuc 	    else if (usym == lsym)
115*971bb1a5SLionel Sambuc 		return NoSymbol;
116*971bb1a5SLionel Sambuc 	    else
117*971bb1a5SLionel Sambuc 		return usym;
118*971bb1a5SLionel Sambuc 	}
119*971bb1a5SLionel Sambuc     }
120*971bb1a5SLionel Sambuc     return syms[col];
121*971bb1a5SLionel Sambuc }
122*971bb1a5SLionel Sambuc 
123*971bb1a5SLionel Sambuc #if NeedFunctionPrototypes
124*971bb1a5SLionel Sambuc KeySym
125*971bb1a5SLionel Sambuc XKeycodeToKeysym(Display *dpy,
126*971bb1a5SLionel Sambuc #if NeedWidePrototypes
127*971bb1a5SLionel Sambuc 		 unsigned int kc,
128*971bb1a5SLionel Sambuc #else
129*971bb1a5SLionel Sambuc 		 KeyCode kc,
130*971bb1a5SLionel Sambuc #endif
131*971bb1a5SLionel Sambuc 		 int col)
132*971bb1a5SLionel Sambuc #else
133*971bb1a5SLionel Sambuc KeySym
134*971bb1a5SLionel Sambuc XKeycodeToKeysym(dpy, kc, col)
135*971bb1a5SLionel Sambuc     Display *dpy;
136*971bb1a5SLionel Sambuc     KeyCode kc;
137*971bb1a5SLionel Sambuc     int col;
138*971bb1a5SLionel Sambuc #endif
139*971bb1a5SLionel Sambuc {
140*971bb1a5SLionel Sambuc     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
141*971bb1a5SLionel Sambuc 	return NoSymbol;
142*971bb1a5SLionel Sambuc     return KeyCodetoKeySym(dpy, kc, col);
143*971bb1a5SLionel Sambuc }
144*971bb1a5SLionel Sambuc 
145*971bb1a5SLionel Sambuc KeyCode
146*971bb1a5SLionel Sambuc XKeysymToKeycode(dpy, ks)
147*971bb1a5SLionel Sambuc     Display *dpy;
148*971bb1a5SLionel Sambuc     KeySym ks;
149*971bb1a5SLionel Sambuc {
150*971bb1a5SLionel Sambuc     register int i, j;
151*971bb1a5SLionel Sambuc 
152*971bb1a5SLionel Sambuc     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
153*971bb1a5SLionel Sambuc 	return (KeyCode) 0;
154*971bb1a5SLionel Sambuc     for (j = 0; j < dpy->keysyms_per_keycode; j++) {
155*971bb1a5SLionel Sambuc 	for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
156*971bb1a5SLionel Sambuc 	    if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks)
157*971bb1a5SLionel Sambuc 		return i;
158*971bb1a5SLionel Sambuc 	}
159*971bb1a5SLionel Sambuc     }
160*971bb1a5SLionel Sambuc     return 0;
161*971bb1a5SLionel Sambuc }
162*971bb1a5SLionel Sambuc 
163*971bb1a5SLionel Sambuc KeySym
164*971bb1a5SLionel Sambuc XLookupKeysym(event, col)
165*971bb1a5SLionel Sambuc     register XKeyEvent *event;
166*971bb1a5SLionel Sambuc     int col;
167*971bb1a5SLionel Sambuc {
168*971bb1a5SLionel Sambuc     if ((! event->display->keysyms) && (! _XKeyInitialize(event->display)))
169*971bb1a5SLionel Sambuc 	return NoSymbol;
170*971bb1a5SLionel Sambuc     return KeyCodetoKeySym(event->display, event->keycode, col);
171*971bb1a5SLionel Sambuc }
172*971bb1a5SLionel Sambuc 
173*971bb1a5SLionel Sambuc static void
174*971bb1a5SLionel Sambuc ResetModMap(dpy)
175*971bb1a5SLionel Sambuc     Display *dpy;
176*971bb1a5SLionel Sambuc {
177*971bb1a5SLionel Sambuc     register XModifierKeymap *map;
178*971bb1a5SLionel Sambuc     register int i, j, n;
179*971bb1a5SLionel Sambuc     KeySym sym;
180*971bb1a5SLionel Sambuc     register struct _XKeytrans *p;
181*971bb1a5SLionel Sambuc 
182*971bb1a5SLionel Sambuc     map = dpy->modifiermap;
183*971bb1a5SLionel Sambuc     /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock,
184*971bb1a5SLionel Sambuc      * else if any contains Shift_Lock, then interpret as Shift_Lock,
185*971bb1a5SLionel Sambuc      * else ignore Lock altogether.
186*971bb1a5SLionel Sambuc      */
187*971bb1a5SLionel Sambuc     dpy->lock_meaning = NoSymbol;
188*971bb1a5SLionel Sambuc     /* Lock modifiers are in the second row of the matrix */
189*971bb1a5SLionel Sambuc     n = 2 * map->max_keypermod;
190*971bb1a5SLionel Sambuc     for (i = map->max_keypermod; i < n; i++) {
191*971bb1a5SLionel Sambuc 	for (j = 0; j < dpy->keysyms_per_keycode; j++) {
192*971bb1a5SLionel Sambuc 	    sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
193*971bb1a5SLionel Sambuc 	    if (sym == XK_Caps_Lock) {
194*971bb1a5SLionel Sambuc 		dpy->lock_meaning = XK_Caps_Lock;
195*971bb1a5SLionel Sambuc 		break;
196*971bb1a5SLionel Sambuc 	    } else if (sym == XK_Shift_Lock) {
197*971bb1a5SLionel Sambuc 		dpy->lock_meaning = XK_Shift_Lock;
198*971bb1a5SLionel Sambuc 	    }
199*971bb1a5SLionel Sambuc 	    else if (sym == XK_ISO_Lock) {
200*971bb1a5SLionel Sambuc 		dpy->lock_meaning = XK_Caps_Lock;
201*971bb1a5SLionel Sambuc 		break;
202*971bb1a5SLionel Sambuc 	    }
203*971bb1a5SLionel Sambuc 	}
204*971bb1a5SLionel Sambuc     }
205*971bb1a5SLionel Sambuc     /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */
206*971bb1a5SLionel Sambuc     dpy->mode_switch = 0;
207*971bb1a5SLionel Sambuc     dpy->num_lock = 0;
208*971bb1a5SLionel Sambuc     n *= 4;
209*971bb1a5SLionel Sambuc     for (i = 3*map->max_keypermod; i < n; i++) {
210*971bb1a5SLionel Sambuc 	for (j = 0; j < dpy->keysyms_per_keycode; j++) {
211*971bb1a5SLionel Sambuc 	    sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
212*971bb1a5SLionel Sambuc 	    if (sym == XK_Mode_switch)
213*971bb1a5SLionel Sambuc 		dpy->mode_switch |= 1 << (i / map->max_keypermod);
214*971bb1a5SLionel Sambuc 	    if (sym == XK_Num_Lock)
215*971bb1a5SLionel Sambuc 		dpy->num_lock |= 1 << (i / map->max_keypermod);
216*971bb1a5SLionel Sambuc 	}
217*971bb1a5SLionel Sambuc     }
218*971bb1a5SLionel Sambuc     for (p = dpy->key_bindings; p; p = p->next)
219*971bb1a5SLionel Sambuc 	ComputeMaskFromKeytrans(dpy, p);
220*971bb1a5SLionel Sambuc }
221*971bb1a5SLionel Sambuc 
222*971bb1a5SLionel Sambuc static int
223*971bb1a5SLionel Sambuc InitModMap(dpy)
224*971bb1a5SLionel Sambuc     Display *dpy;
225*971bb1a5SLionel Sambuc {
226*971bb1a5SLionel Sambuc     register XModifierKeymap *map;
227*971bb1a5SLionel Sambuc 
228*971bb1a5SLionel Sambuc     if (! (map = XGetModifierMapping(dpy)))
229*971bb1a5SLionel Sambuc 	return 0;
230*971bb1a5SLionel Sambuc     LockDisplay(dpy);
231*971bb1a5SLionel Sambuc     if (dpy->modifiermap)
232*971bb1a5SLionel Sambuc 	XFreeModifiermap(dpy->modifiermap);
233*971bb1a5SLionel Sambuc     dpy->modifiermap = map;
234*971bb1a5SLionel Sambuc     dpy->free_funcs->modifiermap = XFreeModifiermap;
235*971bb1a5SLionel Sambuc     if (dpy->keysyms)
236*971bb1a5SLionel Sambuc 	ResetModMap(dpy);
237*971bb1a5SLionel Sambuc     UnlockDisplay(dpy);
238*971bb1a5SLionel Sambuc     return 1;
239*971bb1a5SLionel Sambuc }
240*971bb1a5SLionel Sambuc 
241*971bb1a5SLionel Sambuc int
242*971bb1a5SLionel Sambuc XRefreshKeyboardMapping(event)
243*971bb1a5SLionel Sambuc     register XMappingEvent *event;
244*971bb1a5SLionel Sambuc {
245*971bb1a5SLionel Sambuc 
246*971bb1a5SLionel Sambuc     if(event->request == MappingKeyboard) {
247*971bb1a5SLionel Sambuc 	/* XXX should really only refresh what is necessary
248*971bb1a5SLionel Sambuc 	 * for now, make initialize test fail
249*971bb1a5SLionel Sambuc 	 */
250*971bb1a5SLionel Sambuc 	LockDisplay(event->display);
251*971bb1a5SLionel Sambuc 	if (event->display->keysyms) {
252*971bb1a5SLionel Sambuc 	     Xfree ((char *)event->display->keysyms);
253*971bb1a5SLionel Sambuc 	     event->display->keysyms = NULL;
254*971bb1a5SLionel Sambuc 	}
255*971bb1a5SLionel Sambuc 	UnlockDisplay(event->display);
256*971bb1a5SLionel Sambuc     }
257*971bb1a5SLionel Sambuc     if(event->request == MappingModifier) {
258*971bb1a5SLionel Sambuc 	LockDisplay(event->display);
259*971bb1a5SLionel Sambuc 	if (event->display->modifiermap) {
260*971bb1a5SLionel Sambuc 	    XFreeModifiermap(event->display->modifiermap);
261*971bb1a5SLionel Sambuc 	    event->display->modifiermap = NULL;
262*971bb1a5SLionel Sambuc 	}
263*971bb1a5SLionel Sambuc 	UnlockDisplay(event->display);
264*971bb1a5SLionel Sambuc 	/* go ahead and get it now, since initialize test may not fail */
265*971bb1a5SLionel Sambuc 	if (event->display->keysyms)
266*971bb1a5SLionel Sambuc 	    (void) InitModMap(event->display);
267*971bb1a5SLionel Sambuc     }
268*971bb1a5SLionel Sambuc     return 1;
269*971bb1a5SLionel Sambuc }
270*971bb1a5SLionel Sambuc 
271*971bb1a5SLionel Sambuc int
272*971bb1a5SLionel Sambuc _XKeyInitialize(dpy)
273*971bb1a5SLionel Sambuc     Display *dpy;
274*971bb1a5SLionel Sambuc {
275*971bb1a5SLionel Sambuc     int per, n;
276*971bb1a5SLionel Sambuc     KeySym *keysyms;
277*971bb1a5SLionel Sambuc 
278*971bb1a5SLionel Sambuc     /*
279*971bb1a5SLionel Sambuc      * lets go get the keysyms from the server.
280*971bb1a5SLionel Sambuc      */
281*971bb1a5SLionel Sambuc     if (!dpy->keysyms) {
282*971bb1a5SLionel Sambuc 	n = dpy->max_keycode - dpy->min_keycode + 1;
283*971bb1a5SLionel Sambuc 	keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode,
284*971bb1a5SLionel Sambuc 				       n, &per);
285*971bb1a5SLionel Sambuc 	/* keysyms may be NULL */
286*971bb1a5SLionel Sambuc 	if (! keysyms) return 0;
287*971bb1a5SLionel Sambuc 
288*971bb1a5SLionel Sambuc 	LockDisplay(dpy);
289*971bb1a5SLionel Sambuc 	if (dpy->keysyms)
290*971bb1a5SLionel Sambuc 	    Xfree ((char *)dpy->keysyms);
291*971bb1a5SLionel Sambuc 	dpy->keysyms = keysyms;
292*971bb1a5SLionel Sambuc 	dpy->keysyms_per_keycode = per;
293*971bb1a5SLionel Sambuc 	if (dpy->modifiermap)
294*971bb1a5SLionel Sambuc 	    ResetModMap(dpy);
295*971bb1a5SLionel Sambuc 	UnlockDisplay(dpy);
296*971bb1a5SLionel Sambuc     }
297*971bb1a5SLionel Sambuc     if (!dpy->modifiermap)
298*971bb1a5SLionel Sambuc         return InitModMap(dpy);
299*971bb1a5SLionel Sambuc     return 1;
300*971bb1a5SLionel Sambuc }
301*971bb1a5SLionel Sambuc 
302*971bb1a5SLionel Sambuc #endif	/* } */
303*971bb1a5SLionel Sambuc 
304*971bb1a5SLionel Sambuc void
XConvertCase(sym,lower,upper)305*971bb1a5SLionel Sambuc XConvertCase(sym, lower, upper)
306*971bb1a5SLionel Sambuc     register KeySym sym;
307*971bb1a5SLionel Sambuc     KeySym *lower;
308*971bb1a5SLionel Sambuc     KeySym *upper;
309*971bb1a5SLionel Sambuc {
310*971bb1a5SLionel Sambuc     *lower = sym;
311*971bb1a5SLionel Sambuc     *upper = sym;
312*971bb1a5SLionel Sambuc     switch(sym >> 8) {
313*971bb1a5SLionel Sambuc     case 0: /* Latin 1 */
314*971bb1a5SLionel Sambuc 	if ((sym >= XK_A) && (sym <= XK_Z))
315*971bb1a5SLionel Sambuc 	    *lower += (XK_a - XK_A);
316*971bb1a5SLionel Sambuc 	else if ((sym >= XK_a) && (sym <= XK_z))
317*971bb1a5SLionel Sambuc 	    *upper -= (XK_a - XK_A);
318*971bb1a5SLionel Sambuc 	else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
319*971bb1a5SLionel Sambuc 	    *lower += (XK_agrave - XK_Agrave);
320*971bb1a5SLionel Sambuc 	else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
321*971bb1a5SLionel Sambuc 	    *upper -= (XK_agrave - XK_Agrave);
322*971bb1a5SLionel Sambuc 	else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
323*971bb1a5SLionel Sambuc 	    *lower += (XK_oslash - XK_Ooblique);
324*971bb1a5SLionel Sambuc 	else if ((sym >= XK_oslash) && (sym <= XK_thorn))
325*971bb1a5SLionel Sambuc 	    *upper -= (XK_oslash - XK_Ooblique);
326*971bb1a5SLionel Sambuc 	break;
327*971bb1a5SLionel Sambuc     case 1: /* Latin 2 */
328*971bb1a5SLionel Sambuc 	/* Assume the KeySym is a legal value (ignore discontinuities) */
329*971bb1a5SLionel Sambuc 	if (sym == XK_Aogonek)
330*971bb1a5SLionel Sambuc 	    *lower = XK_aogonek;
331*971bb1a5SLionel Sambuc 	else if (sym >= XK_Lstroke && sym <= XK_Sacute)
332*971bb1a5SLionel Sambuc 	    *lower += (XK_lstroke - XK_Lstroke);
333*971bb1a5SLionel Sambuc 	else if (sym >= XK_Scaron && sym <= XK_Zacute)
334*971bb1a5SLionel Sambuc 	    *lower += (XK_scaron - XK_Scaron);
335*971bb1a5SLionel Sambuc 	else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
336*971bb1a5SLionel Sambuc 	    *lower += (XK_zcaron - XK_Zcaron);
337*971bb1a5SLionel Sambuc 	else if (sym == XK_aogonek)
338*971bb1a5SLionel Sambuc 	    *upper = XK_Aogonek;
339*971bb1a5SLionel Sambuc 	else if (sym >= XK_lstroke && sym <= XK_sacute)
340*971bb1a5SLionel Sambuc 	    *upper -= (XK_lstroke - XK_Lstroke);
341*971bb1a5SLionel Sambuc 	else if (sym >= XK_scaron && sym <= XK_zacute)
342*971bb1a5SLionel Sambuc 	    *upper -= (XK_scaron - XK_Scaron);
343*971bb1a5SLionel Sambuc 	else if (sym >= XK_zcaron && sym <= XK_zabovedot)
344*971bb1a5SLionel Sambuc 	    *upper -= (XK_zcaron - XK_Zcaron);
345*971bb1a5SLionel Sambuc 	else if (sym >= XK_Racute && sym <= XK_Tcedilla)
346*971bb1a5SLionel Sambuc 	    *lower += (XK_racute - XK_Racute);
347*971bb1a5SLionel Sambuc 	else if (sym >= XK_racute && sym <= XK_tcedilla)
348*971bb1a5SLionel Sambuc 	    *upper -= (XK_racute - XK_Racute);
349*971bb1a5SLionel Sambuc 	break;
350*971bb1a5SLionel Sambuc     case 2: /* Latin 3 */
351*971bb1a5SLionel Sambuc 	/* Assume the KeySym is a legal value (ignore discontinuities) */
352*971bb1a5SLionel Sambuc 	if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
353*971bb1a5SLionel Sambuc 	    *lower += (XK_hstroke - XK_Hstroke);
354*971bb1a5SLionel Sambuc 	else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
355*971bb1a5SLionel Sambuc 	    *lower += (XK_gbreve - XK_Gbreve);
356*971bb1a5SLionel Sambuc 	else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
357*971bb1a5SLionel Sambuc 	    *upper -= (XK_hstroke - XK_Hstroke);
358*971bb1a5SLionel Sambuc 	else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
359*971bb1a5SLionel Sambuc 	    *upper -= (XK_gbreve - XK_Gbreve);
360*971bb1a5SLionel Sambuc 	else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
361*971bb1a5SLionel Sambuc 	    *lower += (XK_cabovedot - XK_Cabovedot);
362*971bb1a5SLionel Sambuc 	else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
363*971bb1a5SLionel Sambuc 	    *upper -= (XK_cabovedot - XK_Cabovedot);
364*971bb1a5SLionel Sambuc 	break;
365*971bb1a5SLionel Sambuc     case 3: /* Latin 4 */
366*971bb1a5SLionel Sambuc 	/* Assume the KeySym is a legal value (ignore discontinuities) */
367*971bb1a5SLionel Sambuc 	if (sym >= XK_Rcedilla && sym <= XK_Tslash)
368*971bb1a5SLionel Sambuc 	    *lower += (XK_rcedilla - XK_Rcedilla);
369*971bb1a5SLionel Sambuc 	else if (sym >= XK_rcedilla && sym <= XK_tslash)
370*971bb1a5SLionel Sambuc 	    *upper -= (XK_rcedilla - XK_Rcedilla);
371*971bb1a5SLionel Sambuc 	else if (sym == XK_ENG)
372*971bb1a5SLionel Sambuc 	    *lower = XK_eng;
373*971bb1a5SLionel Sambuc 	else if (sym == XK_eng)
374*971bb1a5SLionel Sambuc 	    *upper = XK_ENG;
375*971bb1a5SLionel Sambuc 	else if (sym >= XK_Amacron && sym <= XK_Umacron)
376*971bb1a5SLionel Sambuc 	    *lower += (XK_amacron - XK_Amacron);
377*971bb1a5SLionel Sambuc 	else if (sym >= XK_amacron && sym <= XK_umacron)
378*971bb1a5SLionel Sambuc 	    *upper -= (XK_amacron - XK_Amacron);
379*971bb1a5SLionel Sambuc 	break;
380*971bb1a5SLionel Sambuc     case 6: /* Cyrillic */
381*971bb1a5SLionel Sambuc 	/* Assume the KeySym is a legal value (ignore discontinuities) */
382*971bb1a5SLionel Sambuc 	if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
383*971bb1a5SLionel Sambuc 	    *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
384*971bb1a5SLionel Sambuc 	else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
385*971bb1a5SLionel Sambuc 	    *upper += (XK_Serbian_DJE - XK_Serbian_dje);
386*971bb1a5SLionel Sambuc 	else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
387*971bb1a5SLionel Sambuc 	    *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
388*971bb1a5SLionel Sambuc 	else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
389*971bb1a5SLionel Sambuc 	    *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
390*971bb1a5SLionel Sambuc         break;
391*971bb1a5SLionel Sambuc     case 7: /* Greek */
392*971bb1a5SLionel Sambuc 	/* Assume the KeySym is a legal value (ignore discontinuities) */
393*971bb1a5SLionel Sambuc 	if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
394*971bb1a5SLionel Sambuc 	    *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
395*971bb1a5SLionel Sambuc 	else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
396*971bb1a5SLionel Sambuc 		 sym != XK_Greek_iotaaccentdieresis &&
397*971bb1a5SLionel Sambuc 		 sym != XK_Greek_upsilonaccentdieresis)
398*971bb1a5SLionel Sambuc 	    *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
399*971bb1a5SLionel Sambuc 	else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
400*971bb1a5SLionel Sambuc 	    *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
401*971bb1a5SLionel Sambuc 	else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
402*971bb1a5SLionel Sambuc 		 sym != XK_Greek_finalsmallsigma)
403*971bb1a5SLionel Sambuc 	    *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
404*971bb1a5SLionel Sambuc         break;
405*971bb1a5SLionel Sambuc     case 0x14: /* Armenian */
406*971bb1a5SLionel Sambuc 	if (sym >= XK_Armenian_AYB && sym <= XK_Armenian_fe) {
407*971bb1a5SLionel Sambuc 	    *lower = sym | 1;
408*971bb1a5SLionel Sambuc 	    *upper = sym & ~1;
409*971bb1a5SLionel Sambuc 	}
410*971bb1a5SLionel Sambuc         break;
411*971bb1a5SLionel Sambuc     }
412*971bb1a5SLionel Sambuc }
413*971bb1a5SLionel Sambuc 
414*971bb1a5SLionel Sambuc #if __disabled_for_imakeicide__	/* { */
415*971bb1a5SLionel Sambuc 
416*971bb1a5SLionel Sambuc int
417*971bb1a5SLionel Sambuc #if NeedFunctionPrototypes
_XTranslateKey(register Display * dpy,KeyCode keycode,register unsigned int modifiers,unsigned int * modifiers_return,KeySym * keysym_return)418*971bb1a5SLionel Sambuc _XTranslateKey(	register Display *dpy,
419*971bb1a5SLionel Sambuc 		KeyCode keycode,
420*971bb1a5SLionel Sambuc 		register unsigned int modifiers,
421*971bb1a5SLionel Sambuc 		unsigned int *modifiers_return,
422*971bb1a5SLionel Sambuc 		KeySym *keysym_return)
423*971bb1a5SLionel Sambuc #else
424*971bb1a5SLionel Sambuc _XTranslateKey(dpy, keycode, modifiers, modifiers_return, keysym_return)
425*971bb1a5SLionel Sambuc     register Display *dpy;
426*971bb1a5SLionel Sambuc     KeyCode keycode;
427*971bb1a5SLionel Sambuc     register unsigned int modifiers;
428*971bb1a5SLionel Sambuc     unsigned int *modifiers_return;
429*971bb1a5SLionel Sambuc     KeySym *keysym_return;
430*971bb1a5SLionel Sambuc #endif
431*971bb1a5SLionel Sambuc {
432*971bb1a5SLionel Sambuc     int per;
433*971bb1a5SLionel Sambuc     register KeySym *syms;
434*971bb1a5SLionel Sambuc     KeySym sym, lsym, usym;
435*971bb1a5SLionel Sambuc 
436*971bb1a5SLionel Sambuc     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
437*971bb1a5SLionel Sambuc 	return 0;
438*971bb1a5SLionel Sambuc     *modifiers_return = ((ShiftMask|LockMask)
439*971bb1a5SLionel Sambuc 			 | dpy->mode_switch | dpy->num_lock);
440*971bb1a5SLionel Sambuc     if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
441*971bb1a5SLionel Sambuc     {
442*971bb1a5SLionel Sambuc 	*keysym_return = NoSymbol;
443*971bb1a5SLionel Sambuc 	return 1;
444*971bb1a5SLionel Sambuc     }
445*971bb1a5SLionel Sambuc     per = dpy->keysyms_per_keycode;
446*971bb1a5SLionel Sambuc     syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
447*971bb1a5SLionel Sambuc     while ((per > 2) && (syms[per - 1] == NoSymbol))
448*971bb1a5SLionel Sambuc 	per--;
449*971bb1a5SLionel Sambuc     if ((per > 2) && (modifiers & dpy->mode_switch)) {
450*971bb1a5SLionel Sambuc 	syms += 2;
451*971bb1a5SLionel Sambuc 	per -= 2;
452*971bb1a5SLionel Sambuc     }
453*971bb1a5SLionel Sambuc     if ((modifiers & dpy->num_lock) &&
454*971bb1a5SLionel Sambuc 	(per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
455*971bb1a5SLionel Sambuc 	if ((modifiers & ShiftMask) ||
456*971bb1a5SLionel Sambuc 	    ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
457*971bb1a5SLionel Sambuc 	    *keysym_return = syms[0];
458*971bb1a5SLionel Sambuc 	else
459*971bb1a5SLionel Sambuc 	    *keysym_return = syms[1];
460*971bb1a5SLionel Sambuc     } else if (!(modifiers & ShiftMask) &&
461*971bb1a5SLionel Sambuc 	(!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
462*971bb1a5SLionel Sambuc 	if ((per == 1) || (syms[1] == NoSymbol))
463*971bb1a5SLionel Sambuc 	    XConvertCase(syms[0], keysym_return, &usym);
464*971bb1a5SLionel Sambuc 	else
465*971bb1a5SLionel Sambuc 	    *keysym_return = syms[0];
466*971bb1a5SLionel Sambuc     } else if (!(modifiers & LockMask) ||
467*971bb1a5SLionel Sambuc 	       (dpy->lock_meaning != XK_Caps_Lock)) {
468*971bb1a5SLionel Sambuc 	if ((per == 1) || ((usym = syms[1]) == NoSymbol))
469*971bb1a5SLionel Sambuc 	    XConvertCase(syms[0], &lsym, &usym);
470*971bb1a5SLionel Sambuc 	*keysym_return = usym;
471*971bb1a5SLionel Sambuc     } else {
472*971bb1a5SLionel Sambuc 	if ((per == 1) || ((sym = syms[1]) == NoSymbol))
473*971bb1a5SLionel Sambuc 	    sym = syms[0];
474*971bb1a5SLionel Sambuc 	XConvertCase(sym, &lsym, &usym);
475*971bb1a5SLionel Sambuc 	if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
476*971bb1a5SLionel Sambuc 	    ((sym != usym) || (lsym == usym)))
477*971bb1a5SLionel Sambuc 	    XConvertCase(syms[0], &lsym, &usym);
478*971bb1a5SLionel Sambuc 	*keysym_return = usym;
479*971bb1a5SLionel Sambuc     }
480*971bb1a5SLionel Sambuc     if (*keysym_return == XK_VoidSymbol)
481*971bb1a5SLionel Sambuc 	*keysym_return = NoSymbol;
482*971bb1a5SLionel Sambuc     return 1;
483*971bb1a5SLionel Sambuc }
484*971bb1a5SLionel Sambuc 
485*971bb1a5SLionel Sambuc int
_XTranslateKeySym(dpy,symbol,modifiers,buffer,nbytes)486*971bb1a5SLionel Sambuc _XTranslateKeySym(dpy, symbol, modifiers, buffer, nbytes)
487*971bb1a5SLionel Sambuc     Display *dpy;
488*971bb1a5SLionel Sambuc     register KeySym symbol;
489*971bb1a5SLionel Sambuc     unsigned int modifiers;
490*971bb1a5SLionel Sambuc     char *buffer;
491*971bb1a5SLionel Sambuc     int nbytes;
492*971bb1a5SLionel Sambuc {
493*971bb1a5SLionel Sambuc     register struct _XKeytrans *p;
494*971bb1a5SLionel Sambuc     int length;
495*971bb1a5SLionel Sambuc     unsigned long hiBytes;
496*971bb1a5SLionel Sambuc     register unsigned char c;
497*971bb1a5SLionel Sambuc 
498*971bb1a5SLionel Sambuc     if (!symbol)
499*971bb1a5SLionel Sambuc 	return 0;
500*971bb1a5SLionel Sambuc     /* see if symbol rebound, if so, return that string. */
501*971bb1a5SLionel Sambuc     for (p = dpy->key_bindings; p; p = p->next) {
502*971bb1a5SLionel Sambuc 	if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
503*971bb1a5SLionel Sambuc 	    length = p->len;
504*971bb1a5SLionel Sambuc 	    if (length > nbytes) length = nbytes;
505*971bb1a5SLionel Sambuc 	    memcpy (buffer, p->string, length);
506*971bb1a5SLionel Sambuc 	    return length;
507*971bb1a5SLionel Sambuc 	}
508*971bb1a5SLionel Sambuc     }
509*971bb1a5SLionel Sambuc     /* try to convert to Latin-1, handling control */
510*971bb1a5SLionel Sambuc     hiBytes = symbol >> 8;
511*971bb1a5SLionel Sambuc     if (!(nbytes &&
512*971bb1a5SLionel Sambuc 	  ((hiBytes == 0) ||
513*971bb1a5SLionel Sambuc 	   ((hiBytes == 0xFF) &&
514*971bb1a5SLionel Sambuc 	    (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
515*971bb1a5SLionel Sambuc 	     (symbol == XK_Return) ||
516*971bb1a5SLionel Sambuc 	     (symbol == XK_Escape) ||
517*971bb1a5SLionel Sambuc 	     (symbol == XK_KP_Space) ||
518*971bb1a5SLionel Sambuc 	     (symbol == XK_KP_Tab) ||
519*971bb1a5SLionel Sambuc 	     (symbol == XK_KP_Enter) ||
520*971bb1a5SLionel Sambuc 	     ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) ||
521*971bb1a5SLionel Sambuc 	     (symbol == XK_KP_Equal) ||
522*971bb1a5SLionel Sambuc 	     (symbol == XK_Delete))))))
523*971bb1a5SLionel Sambuc 	return 0;
524*971bb1a5SLionel Sambuc 
525*971bb1a5SLionel Sambuc     /* if X keysym, convert to ascii by grabbing low 7 bits */
526*971bb1a5SLionel Sambuc     if (symbol == XK_KP_Space)
527*971bb1a5SLionel Sambuc 	c = XK_space & 0x7F; /* patch encoding botch */
528*971bb1a5SLionel Sambuc     else if (hiBytes == 0xFF)
529*971bb1a5SLionel Sambuc 	c = symbol & 0x7F;
530*971bb1a5SLionel Sambuc     else
531*971bb1a5SLionel Sambuc 	c = symbol & 0xFF;
532*971bb1a5SLionel Sambuc     /* only apply Control key if it makes sense, else ignore it */
533*971bb1a5SLionel Sambuc     if (modifiers & ControlMask) {
534*971bb1a5SLionel Sambuc 	if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
535*971bb1a5SLionel Sambuc 	else if (c == '2') c = '\000';
536*971bb1a5SLionel Sambuc 	else if (c >= '3' && c <= '7') c -= ('3' - '\033');
537*971bb1a5SLionel Sambuc 	else if (c == '8') c = '\177';
538*971bb1a5SLionel Sambuc 	else if (c == '/') c = '_' & 0x1F;
539*971bb1a5SLionel Sambuc     }
540*971bb1a5SLionel Sambuc     buffer[0] = c;
541*971bb1a5SLionel Sambuc     return 1;
542*971bb1a5SLionel Sambuc }
543*971bb1a5SLionel Sambuc 
544*971bb1a5SLionel Sambuc /*ARGSUSED*/
545*971bb1a5SLionel Sambuc int
XLookupString(event,buffer,nbytes,keysym,status)546*971bb1a5SLionel Sambuc XLookupString (event, buffer, nbytes, keysym, status)
547*971bb1a5SLionel Sambuc     register XKeyEvent *event;
548*971bb1a5SLionel Sambuc     char *buffer;	/* buffer */
549*971bb1a5SLionel Sambuc     int nbytes;	/* space in buffer for characters */
550*971bb1a5SLionel Sambuc     KeySym *keysym;
551*971bb1a5SLionel Sambuc     XComposeStatus *status;	/* not implemented */
552*971bb1a5SLionel Sambuc {
553*971bb1a5SLionel Sambuc     unsigned int modifiers;
554*971bb1a5SLionel Sambuc     KeySym symbol;
555*971bb1a5SLionel Sambuc 
556*971bb1a5SLionel Sambuc     if (! _XTranslateKey(event->display, event->keycode, event->state,
557*971bb1a5SLionel Sambuc 		  &modifiers, &symbol))
558*971bb1a5SLionel Sambuc 	return 0;
559*971bb1a5SLionel Sambuc 
560*971bb1a5SLionel Sambuc #ifdef USE_OWN_COMPOSE
561*971bb1a5SLionel Sambuc     if ( status ) {
562*971bb1a5SLionel Sambuc 	static int been_here= 0;
563*971bb1a5SLionel Sambuc 	if ( !been_here ) {
564*971bb1a5SLionel Sambuc 	    XimCompInitTables();
565*971bb1a5SLionel Sambuc 	    been_here = 1;
566*971bb1a5SLionel Sambuc 	}
567*971bb1a5SLionel Sambuc 	if ( !XimCompLegalStatus(status) ) {
568*971bb1a5SLionel Sambuc 	    status->compose_ptr = NULL;
569*971bb1a5SLionel Sambuc 	    status->chars_matched = 0;
570*971bb1a5SLionel Sambuc 	}
571*971bb1a5SLionel Sambuc 	if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
572*971bb1a5SLionel Sambuc 		XimCompIsComposeKey(symbol,event->keycode,status) ) {
573*971bb1a5SLionel Sambuc 	    XimCompRtrn rtrn;
574*971bb1a5SLionel Sambuc 	    switch (XimCompProcessSym(status,symbol,&rtrn)) {
575*971bb1a5SLionel Sambuc 		case XIM_COMP_IGNORE:
576*971bb1a5SLionel Sambuc 		    break;
577*971bb1a5SLionel Sambuc 		case XIM_COMP_IN_PROGRESS:
578*971bb1a5SLionel Sambuc 		    if ( keysym!=NULL )
579*971bb1a5SLionel Sambuc 			*keysym = NoSymbol;
580*971bb1a5SLionel Sambuc 		    return 0;
581*971bb1a5SLionel Sambuc 		case XIM_COMP_FAIL:
582*971bb1a5SLionel Sambuc 		{
583*971bb1a5SLionel Sambuc 		    int n = 0, len= 0;
584*971bb1a5SLionel Sambuc 		    for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
585*971bb1a5SLionel Sambuc 			if ( nbytes-len > 0 ) {
586*971bb1a5SLionel Sambuc 			    len+= _XTranslateKeySym(event->display,rtrn.sym[n],
587*971bb1a5SLionel Sambuc 							event->state,
588*971bb1a5SLionel Sambuc 							buffer+len,nbytes-len);
589*971bb1a5SLionel Sambuc 			}
590*971bb1a5SLionel Sambuc 		    }
591*971bb1a5SLionel Sambuc 		    if ( keysym!=NULL ) {
592*971bb1a5SLionel Sambuc 			if ( n==1 )	*keysym = rtrn.sym[0];
593*971bb1a5SLionel Sambuc 			else		*keysym = NoSymbol;
594*971bb1a5SLionel Sambuc 		    }
595*971bb1a5SLionel Sambuc 		    return len;
596*971bb1a5SLionel Sambuc 		}
597*971bb1a5SLionel Sambuc 		case XIM_COMP_SUCCEED:
598*971bb1a5SLionel Sambuc 		{
599*971bb1a5SLionel Sambuc 		    int len,n = 0;
600*971bb1a5SLionel Sambuc 
601*971bb1a5SLionel Sambuc 		    symbol = rtrn.matchSym;
602*971bb1a5SLionel Sambuc 		    if ( keysym!=NULL )	*keysym = symbol;
603*971bb1a5SLionel Sambuc 		    if ( rtrn.str[0]!='\0' ) {
604*971bb1a5SLionel Sambuc 			strncpy(buffer,rtrn.str,nbytes-1);
605*971bb1a5SLionel Sambuc 			buffer[nbytes-1]= '\0';
606*971bb1a5SLionel Sambuc 			len = strlen(buffer);
607*971bb1a5SLionel Sambuc 		    }
608*971bb1a5SLionel Sambuc 		    else {
609*971bb1a5SLionel Sambuc 			len = _XTranslateKeySym(event->display,symbol,
610*971bb1a5SLionel Sambuc 							event->state,
611*971bb1a5SLionel Sambuc 							buffer,nbytes);
612*971bb1a5SLionel Sambuc 		    }
613*971bb1a5SLionel Sambuc 		    for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
614*971bb1a5SLionel Sambuc 			if ( nbytes-len > 0 ) {
615*971bb1a5SLionel Sambuc 			    len+= _XTranslateKeySym(event->display,rtrn.sym[n],
616*971bb1a5SLionel Sambuc 							event->state,
617*971bb1a5SLionel Sambuc 							buffer+len,nbytes-len);
618*971bb1a5SLionel Sambuc 			}
619*971bb1a5SLionel Sambuc 		    }
620*971bb1a5SLionel Sambuc 		    return len;
621*971bb1a5SLionel Sambuc 		}
622*971bb1a5SLionel Sambuc 	    }
623*971bb1a5SLionel Sambuc 	}
624*971bb1a5SLionel Sambuc     }
625*971bb1a5SLionel Sambuc #endif
626*971bb1a5SLionel Sambuc 
627*971bb1a5SLionel Sambuc     if (keysym)
628*971bb1a5SLionel Sambuc 	*keysym = symbol;
629*971bb1a5SLionel Sambuc     /* arguable whether to use (event->state & ~modifiers) here */
630*971bb1a5SLionel Sambuc     return _XTranslateKeySym(event->display, symbol, event->state,
631*971bb1a5SLionel Sambuc 			     buffer, nbytes);
632*971bb1a5SLionel Sambuc }
633*971bb1a5SLionel Sambuc 
634*971bb1a5SLionel Sambuc static void
_XFreeKeyBindings(dpy)635*971bb1a5SLionel Sambuc _XFreeKeyBindings (dpy)
636*971bb1a5SLionel Sambuc     Display *dpy;
637*971bb1a5SLionel Sambuc {
638*971bb1a5SLionel Sambuc     register struct _XKeytrans *p, *np;
639*971bb1a5SLionel Sambuc 
640*971bb1a5SLionel Sambuc     for (p = dpy->key_bindings; p; p = np) {
641*971bb1a5SLionel Sambuc 	np = p->next;
642*971bb1a5SLionel Sambuc 	Xfree(p->string);
643*971bb1a5SLionel Sambuc 	Xfree((char *)p->modifiers);
644*971bb1a5SLionel Sambuc 	Xfree((char *)p);
645*971bb1a5SLionel Sambuc     }
646*971bb1a5SLionel Sambuc }
647*971bb1a5SLionel Sambuc 
648*971bb1a5SLionel Sambuc int
649*971bb1a5SLionel Sambuc #if NeedFunctionPrototypes
XRebindKeysym(Display * dpy,KeySym keysym,KeySym * mlist,int nm,_Xconst unsigned char * str,int nbytes)650*971bb1a5SLionel Sambuc XRebindKeysym (
651*971bb1a5SLionel Sambuc     Display *dpy,
652*971bb1a5SLionel Sambuc     KeySym keysym,
653*971bb1a5SLionel Sambuc     KeySym *mlist,
654*971bb1a5SLionel Sambuc     int nm,		/* number of modifiers in mlist */
655*971bb1a5SLionel Sambuc     _Xconst unsigned char *str,
656*971bb1a5SLionel Sambuc     int nbytes)
657*971bb1a5SLionel Sambuc #else
658*971bb1a5SLionel Sambuc XRebindKeysym (dpy, keysym, mlist, nm, str, nbytes)
659*971bb1a5SLionel Sambuc     Display *dpy;
660*971bb1a5SLionel Sambuc     KeySym keysym;
661*971bb1a5SLionel Sambuc     KeySym *mlist;
662*971bb1a5SLionel Sambuc     int nm;		/* number of modifiers in mlist */
663*971bb1a5SLionel Sambuc     unsigned char *str;
664*971bb1a5SLionel Sambuc     int nbytes;
665*971bb1a5SLionel Sambuc #endif
666*971bb1a5SLionel Sambuc {
667*971bb1a5SLionel Sambuc     register struct _XKeytrans *tmp, *p;
668*971bb1a5SLionel Sambuc     int nb;
669*971bb1a5SLionel Sambuc 
670*971bb1a5SLionel Sambuc     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
671*971bb1a5SLionel Sambuc 	return 0;
672*971bb1a5SLionel Sambuc     LockDisplay(dpy);
673*971bb1a5SLionel Sambuc     tmp = dpy->key_bindings;
674*971bb1a5SLionel Sambuc     nb = sizeof(KeySym) * nm;
675*971bb1a5SLionel Sambuc 
676*971bb1a5SLionel Sambuc     if ((! (p = (struct _XKeytrans *) Xmalloc( sizeof(struct _XKeytrans)))) ||
677*971bb1a5SLionel Sambuc 	((! (p->string = (char *) Xmalloc( (unsigned) nbytes))) &&
678*971bb1a5SLionel Sambuc 	 (nbytes > 0)) ||
679*971bb1a5SLionel Sambuc 	((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb))) &&
680*971bb1a5SLionel Sambuc 	 (nb > 0))) {
681*971bb1a5SLionel Sambuc 	if (p) {
682*971bb1a5SLionel Sambuc 	    if (p->string) Xfree(p->string);
683*971bb1a5SLionel Sambuc 	    if (p->modifiers) Xfree((char *) p->modifiers);
684*971bb1a5SLionel Sambuc 	    Xfree((char *) p);
685*971bb1a5SLionel Sambuc 	}
686*971bb1a5SLionel Sambuc 	UnlockDisplay(dpy);
687*971bb1a5SLionel Sambuc 	return 0;
688*971bb1a5SLionel Sambuc     }
689*971bb1a5SLionel Sambuc 
690*971bb1a5SLionel Sambuc     dpy->key_bindings = p;
691*971bb1a5SLionel Sambuc     dpy->free_funcs->key_bindings = _XFreeKeyBindings;
692*971bb1a5SLionel Sambuc     p->next = tmp;	/* chain onto list */
693*971bb1a5SLionel Sambuc     memcpy (p->string, (char *) str, nbytes);
694*971bb1a5SLionel Sambuc     p->len = nbytes;
695*971bb1a5SLionel Sambuc     memcpy ((char *) p->modifiers, (char *) mlist, nb);
696*971bb1a5SLionel Sambuc     p->key = keysym;
697*971bb1a5SLionel Sambuc     p->mlen = nm;
698*971bb1a5SLionel Sambuc     ComputeMaskFromKeytrans(dpy, p);
699*971bb1a5SLionel Sambuc     UnlockDisplay(dpy);
700*971bb1a5SLionel Sambuc     return 0;
701*971bb1a5SLionel Sambuc }
702*971bb1a5SLionel Sambuc 
703*971bb1a5SLionel Sambuc unsigned
_XKeysymToModifiers(dpy,ks)704*971bb1a5SLionel Sambuc _XKeysymToModifiers(dpy,ks)
705*971bb1a5SLionel Sambuc     Display *dpy;
706*971bb1a5SLionel Sambuc     KeySym ks;
707*971bb1a5SLionel Sambuc {
708*971bb1a5SLionel Sambuc     CARD8 code,mods;
709*971bb1a5SLionel Sambuc     register KeySym *kmax;
710*971bb1a5SLionel Sambuc     register KeySym *k;
711*971bb1a5SLionel Sambuc     register XModifierKeymap *m;
712*971bb1a5SLionel Sambuc 
713*971bb1a5SLionel Sambuc     if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
714*971bb1a5SLionel Sambuc 	return 0;
715*971bb1a5SLionel Sambuc     kmax = dpy->keysyms +
716*971bb1a5SLionel Sambuc 	   (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
717*971bb1a5SLionel Sambuc     k = dpy->keysyms;
718*971bb1a5SLionel Sambuc     m = dpy->modifiermap;
719*971bb1a5SLionel Sambuc     mods= 0;
720*971bb1a5SLionel Sambuc     while (k<kmax) {
721*971bb1a5SLionel Sambuc 	if (*k == ks ) {
722*971bb1a5SLionel Sambuc 	    register int j = m->max_keypermod<<3;
723*971bb1a5SLionel Sambuc 
724*971bb1a5SLionel Sambuc 	    code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode);
725*971bb1a5SLionel Sambuc 
726*971bb1a5SLionel Sambuc 	    while (--j >= 0) {
727*971bb1a5SLionel Sambuc 		if (code == m->modifiermap[j])
728*971bb1a5SLionel Sambuc 		    mods|= (1<<(j/m->max_keypermod));
729*971bb1a5SLionel Sambuc 	    }
730*971bb1a5SLionel Sambuc 	}
731*971bb1a5SLionel Sambuc 	k++;
732*971bb1a5SLionel Sambuc     }
733*971bb1a5SLionel Sambuc     return mods;
734*971bb1a5SLionel Sambuc }
735*971bb1a5SLionel Sambuc 
736*971bb1a5SLionel Sambuc /*
737*971bb1a5SLionel Sambuc  * given a list of modifiers, computes the mask necessary for later matching.
738*971bb1a5SLionel Sambuc  * This routine must lookup the key in the Keymap and then search to see
739*971bb1a5SLionel Sambuc  * what modifier it is bound to, if any.  Sets the AnyModifier bit if it
740*971bb1a5SLionel Sambuc  * can't map some keysym to a modifier.
741*971bb1a5SLionel Sambuc  */
742*971bb1a5SLionel Sambuc static void
ComputeMaskFromKeytrans(dpy,p)743*971bb1a5SLionel Sambuc ComputeMaskFromKeytrans(dpy, p)
744*971bb1a5SLionel Sambuc     Display *dpy;
745*971bb1a5SLionel Sambuc     register struct _XKeytrans *p;
746*971bb1a5SLionel Sambuc {
747*971bb1a5SLionel Sambuc     register int i;
748*971bb1a5SLionel Sambuc 
749*971bb1a5SLionel Sambuc     p->state = AnyModifier;
750*971bb1a5SLionel Sambuc     for (i = 0; i < p->mlen; i++) {
751*971bb1a5SLionel Sambuc 	p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]);
752*971bb1a5SLionel Sambuc     }
753*971bb1a5SLionel Sambuc     p->state &= AllMods;
754*971bb1a5SLionel Sambuc }
755*971bb1a5SLionel Sambuc 
756*971bb1a5SLionel Sambuc #endif	/* __disabled_for_imakeicide__ } */
757