~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/X11/KeyBind.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

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