aboutsummaryrefslogtreecommitdiff
path: root/libXt/src/TMkey.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-09-12 11:27:51 +0200
committermarha <marha@users.sourceforge.net>2011-09-12 11:27:51 +0200
commitdafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 (patch)
treebdf833cc6a4fc9035411779e10dd9e8478201885 /libXt/src/TMkey.c
parent0b40f5f4b54453a77f4b09c431f8efc6875da61f (diff)
downloadvcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.gz
vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.bz2
vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.zip
Synchronised line endinge with release branch
Diffstat (limited to 'libXt/src/TMkey.c')
-rw-r--r--libXt/src/TMkey.c1454
1 files changed, 727 insertions, 727 deletions
diff --git a/libXt/src/TMkey.c b/libXt/src/TMkey.c
index c56e257ff..e59bccae2 100644
--- a/libXt/src/TMkey.c
+++ b/libXt/src/TMkey.c
@@ -1,727 +1,727 @@
-/*LINTLIBRARY*/
-
-/***********************************************************
-Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
-
-Copyright 1987, 1988, 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-#define XK_MISCELLANY
-#define XK_LATIN1
-#define XK_LATIN2
-#define XK_LATIN3
-#define XK_LATIN4
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "IntrinsicI.h"
-#include <X11/keysymdef.h>
-#ifdef XKB
-#include <X11/XKBlib.h>
-#endif
-
-#define FLUSHKEYCACHE(ctx) \
- bzero((char *)&ctx->keycache, sizeof(TMKeyCache))
-
-/*
- * The following array reorders the modifier bits so that the most common ones
- * (used by a translator) are in the top-most bits with respect to the size of
- * the keycache. The array currently just reverses the bits as a good guess.
- * This might be more trouble than it is worth, but it seems to help.
- */
-
-#define FM(i) i >> (8 - TMKEYCACHELOG2)
-static const unsigned char modmix[256] = {
-FM(0x0f), FM(0x8f), FM(0x4f), FM(0xcf), FM(0x2f), FM(0xaf), FM(0x6f), FM(0xef),
-FM(0x1f), FM(0x9f), FM(0x5f), FM(0xdf), FM(0x3f), FM(0xbf), FM(0x7f), FM(0xff),
-FM(0x07), FM(0x87), FM(0x47), FM(0xc7), FM(0x27), FM(0xa7), FM(0x67), FM(0xe7),
-FM(0x17), FM(0x97), FM(0x57), FM(0xd7), FM(0x37), FM(0xb7), FM(0x77), FM(0xf7),
-FM(0x0b), FM(0x8b), FM(0x4b), FM(0xcb), FM(0x2b), FM(0xab), FM(0x6b), FM(0xeb),
-FM(0x1b), FM(0x9b), FM(0x5b), FM(0xdb), FM(0x3b), FM(0xbb), FM(0x7b), FM(0xfb),
-FM(0x03), FM(0x83), FM(0x43), FM(0xc3), FM(0x23), FM(0xa3), FM(0x63), FM(0xe3),
-FM(0x13), FM(0x93), FM(0x53), FM(0xd3), FM(0x33), FM(0xb3), FM(0x73), FM(0xf3),
-FM(0x0d), FM(0x8d), FM(0x4d), FM(0xcd), FM(0x2d), FM(0xad), FM(0x6d), FM(0xed),
-FM(0x1d), FM(0x9d), FM(0x5d), FM(0xdd), FM(0x3d), FM(0xbd), FM(0x7d), FM(0xfd),
-FM(0x05), FM(0x85), FM(0x45), FM(0xc5), FM(0x25), FM(0xa5), FM(0x65), FM(0xe5),
-FM(0x15), FM(0x95), FM(0x55), FM(0xd5), FM(0x35), FM(0xb5), FM(0x75), FM(0xf5),
-FM(0x09), FM(0x89), FM(0x49), FM(0xc9), FM(0x29), FM(0xa9), FM(0x69), FM(0xe9),
-FM(0x19), FM(0x99), FM(0x59), FM(0xd9), FM(0x39), FM(0xb9), FM(0x79), FM(0xf9),
-FM(0x01), FM(0x81), FM(0x41), FM(0xc1), FM(0x21), FM(0xa1), FM(0x61), FM(0xe1),
-FM(0x11), FM(0x91), FM(0x51), FM(0xd1), FM(0x31), FM(0xb1), FM(0x71), FM(0xf1),
-FM(0x00), FM(0x8e), FM(0x4e), FM(0xce), FM(0x2e), FM(0xae), FM(0x6e), FM(0xee),
-FM(0x1e), FM(0x9e), FM(0x5e), FM(0xde), FM(0x3e), FM(0xbe), FM(0x7e), FM(0xfe),
-FM(0x08), FM(0x88), FM(0x48), FM(0xc8), FM(0x28), FM(0xa8), FM(0x68), FM(0xe8),
-FM(0x18), FM(0x98), FM(0x58), FM(0xd8), FM(0x38), FM(0xb8), FM(0x78), FM(0xf8),
-FM(0x04), FM(0x84), FM(0x44), FM(0xc4), FM(0x24), FM(0xa4), FM(0x64), FM(0xe4),
-FM(0x14), FM(0x94), FM(0x54), FM(0xd4), FM(0x34), FM(0xb4), FM(0x74), FM(0xf4),
-FM(0x0c), FM(0x8c), FM(0x4c), FM(0xcc), FM(0x2c), FM(0xac), FM(0x6c), FM(0xec),
-FM(0x1c), FM(0x9c), FM(0x5c), FM(0xdc), FM(0x3c), FM(0xbc), FM(0x7c), FM(0xfc),
-FM(0x02), FM(0x82), FM(0x42), FM(0xc2), FM(0x22), FM(0xa2), FM(0x62), FM(0xe2),
-FM(0x12), FM(0x92), FM(0x52), FM(0xd2), FM(0x32), FM(0xb2), FM(0x72), FM(0xf2),
-FM(0x0a), FM(0x8a), FM(0x4a), FM(0xca), FM(0x2a), FM(0xaa), FM(0x6a), FM(0xea),
-FM(0x1a), FM(0x9a), FM(0x5a), FM(0xda), FM(0x3a), FM(0xba), FM(0x7a), FM(0xfa),
-FM(0x06), FM(0x86), FM(0x46), FM(0xc6), FM(0x26), FM(0xa6), FM(0x66), FM(0xe6),
-FM(0x16), FM(0x96), FM(0x56), FM(0xd6), FM(0x36), FM(0xb6), FM(0x76), FM(0xf6),
-FM(0x0e), FM(0x8e), FM(0x4e), FM(0xce), FM(0x2e), FM(0xae), FM(0x6e), FM(0xee),
-FM(0x1e), FM(0x9e), FM(0x5e), FM(0xde), FM(0x3e), FM(0xbe), FM(0x7e), FM(0xfe)
-};
-#undef FM
-
-#define MOD_RETURN(ctx, key) (ctx)->keycache.modifiers_return[key]
-
-#define TRANSLATE(ctx,pd,dpy,key,mod,mod_ret,sym_ret) \
-{ \
- int _i_ = (((key) - (pd)->min_keycode + modmix[(mod) & 0xff]) & \
- (TMKEYCACHESIZE-1)); \
- if ((key) == 0) { /* Xlib XIM composed input */ \
- mod_ret = 0; \
- sym_ret = 0; \
- } else if ( /* not Xlib XIM composed input */ \
- (ctx)->keycache.keycode[_i_] == (key) && \
- (ctx)->keycache.modifiers[_i_] == (mod)) { \
- mod_ret = MOD_RETURN(ctx, key); \
- sym_ret = (ctx)->keycache.keysym[_i_]; \
- } else { \
- XtTranslateKeycode(dpy, key, mod, &mod_ret, &sym_ret); \
- (ctx)->keycache.keycode[_i_] = key; \
- (ctx)->keycache.modifiers[_i_] = (unsigned char)(mod); \
- (ctx)->keycache.keysym[_i_] = sym_ret; \
- MOD_RETURN(ctx, key) = (unsigned char)mod_ret; \
- } \
-}
-
-#define UPDATE_CACHE(ctx, pd, key, mod, mod_ret, sym_ret) \
-{ \
- int _i_ = (((key) - (pd)->min_keycode + modmix[(mod) & 0xff]) & \
- (TMKEYCACHESIZE-1)); \
- (ctx)->keycache.keycode[_i_] = key; \
- (ctx)->keycache.modifiers[_i_] = (unsigned char)(mod); \
- (ctx)->keycache.keysym[_i_] = sym_ret; \
- MOD_RETURN(ctx, key) = (unsigned char)mod_ret; \
-}
-
-/* usual number of expected keycodes in XtKeysymToKeycodeList */
-#define KEYCODE_ARRAY_SIZE 10
-
-Boolean _XtComputeLateBindings(
- Display *dpy,
- LateBindingsPtr lateModifiers,
- Modifiers *computed,
- Modifiers *computedMask)
-{
- int i,j,ref;
- ModToKeysymTable* temp;
- XtPerDisplay perDisplay;
- Boolean found;
- KeySym tempKeysym = NoSymbol;
-
- perDisplay = _XtGetPerDisplay(dpy);
- if (perDisplay == NULL) {
- XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
- "displayError","invalidDisplay",XtCXtToolkitError,
- "Can't find display structure",
- (String *)NULL, (Cardinal *)NULL);
- return FALSE;
- }
- _InitializeKeysymTables(dpy, perDisplay);
- for (ref=0; lateModifiers[ref].keysym; ref++) {
- found = FALSE;
- for (i=0;i<8;i++) {
- temp = &(perDisplay->modsToKeysyms[i]);
- for (j=0;j<temp->count;j++){
- if (perDisplay->modKeysyms[temp->idx+j] ==
- lateModifiers[ref].keysym) {
- *computedMask = *computedMask | temp->mask;
- if (!lateModifiers[ref].knot)
- *computed |= temp->mask;
- tempKeysym = lateModifiers[ref].keysym;
- found = TRUE; break;
- }
- }
- if (found) break;
- }
- if (!found && !lateModifiers[ref].knot)
- if (!lateModifiers[ref].pair && (tempKeysym == NoSymbol))
- return FALSE;
- /* if you didn't find the modifier and the modifier must be
- asserted then return FALSE. If you didn't find the modifier
- and the modifier must be off, then it is OK . Don't
- return FALSE if this is the first member of a pair or if
- it is the second member of a pair when the first member
- was bound to a modifier */
- if (!lateModifiers[ref].pair) tempKeysym = NoSymbol;
- }
- return TRUE;
-}
-
-void _XtAllocTMContext(
- XtPerDisplay pd)
-{
- TMKeyContext ctx;
- ctx = (TMKeyContext)_XtHeapAlloc(&pd->heap,
- sizeof(TMKeyContextRec));
- ctx->event = NULL;
- ctx->serial = 0;
- ctx->keysym = NoSymbol;
- ctx->modifiers = 0;
- FLUSHKEYCACHE(ctx);
- pd->tm_context = ctx;
-}
-
-static unsigned int num_bits(unsigned long mask)
-{
- register unsigned long y;
-
- y = (mask >> 1) &033333333333;
- y = mask - y - ((y >>1) & 033333333333);
- return ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
-}
-
-Boolean _XtMatchUsingDontCareMods(
- TMTypeMatch typeMatch,
- TMModifierMatch modMatch,
- TMEventPtr eventSeq)
-{
- Modifiers modifiers_return;
- KeySym keysym_return;
- Modifiers useful_mods;
- int i, num_modbits;
- Modifiers computed = 0;
- Modifiers computedMask = 0;
- Boolean resolved = TRUE;
- Display *dpy = eventSeq->xev->xany.display;
- XtPerDisplay pd;
- TMKeyContext tm_context;
-
- if (modMatch->lateModifiers != NULL)
- resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers,
- &computed, &computedMask);
- if (!resolved) return FALSE;
- computed |= modMatch->modifiers;
- computedMask |= modMatch->modifierMask; /* gives do-care mask */
-
- if ( (computed & computedMask) ==
- (eventSeq->event.modifiers & computedMask) ) {
-
- pd = _XtGetPerDisplay(dpy);
- tm_context = pd->tm_context;
- TRANSLATE(tm_context, pd, dpy, (KeyCode)eventSeq->event.eventCode,
- (unsigned)0, modifiers_return, keysym_return);
-
- if ((keysym_return & typeMatch->eventCodeMask) == typeMatch->eventCode ) {
- tm_context->event = eventSeq->xev;
- tm_context->serial = eventSeq->xev->xany.serial;
- tm_context->keysym = keysym_return;
- tm_context->modifiers = (Modifiers)0;
- return TRUE;
- }
- useful_mods = ~computedMask & modifiers_return;
- if (useful_mods == 0) return FALSE;
-
- switch (num_modbits = num_bits(useful_mods)) {
- case 1:
- case 8:
- /*
- * one modbit should never happen, in fact the implementation
- * of XtTranslateKey and XmTranslateKey guarantee that it
- * won't, so don't care if the loop is set up for the case
- * when one modbit is set.
- * The performance implications of all eight modbits being
- * set is horrendous. This isn't a problem with Xt/Xaw based
- * applications. We can only hope that Motif's virtual
- * modifiers won't result in all eight modbits being set.
- */
- for (i = useful_mods; i > 0; i--) {
- TRANSLATE(tm_context, pd, dpy, eventSeq->event.eventCode,
- (Modifiers)i, modifiers_return, keysym_return);
- if (keysym_return ==
- (typeMatch->eventCode & typeMatch->eventCodeMask)) {
- tm_context->event = eventSeq->xev;
- tm_context->serial = eventSeq->xev->xany.serial;
- tm_context->keysym = keysym_return;
- tm_context->modifiers = (Modifiers)i;
- return TRUE;
- }
- }
- break;
- default: /* (2..7) */
- {
- /*
- * Only translate using combinations of the useful modifiers.
- * to minimize the chance of invalidating the cache.
- */
- static char pows[] = { 0, 1, 3, 7, 15, 31, 63, 127 };
- Modifiers tmod, mod_masks[8];
- int j;
- for (tmod = 1, i = 0; tmod <= (Mod5Mask<<1); tmod <<= 1)
- if (tmod & useful_mods) mod_masks[i++] = tmod;
- for (j = (int) pows[num_modbits]; j > 0; j--) {
- tmod = 0;
- for (i = 0; i < num_modbits; i++)
- if (j & (1<<i)) tmod |= mod_masks[i];
- TRANSLATE(tm_context, pd, dpy, eventSeq->event.eventCode,
- tmod, modifiers_return, keysym_return);
- if (keysym_return ==
- (typeMatch->eventCode & typeMatch->eventCodeMask)) {
- tm_context->event = eventSeq->xev;
- tm_context->serial = eventSeq->xev->xany.serial;
- tm_context->keysym = keysym_return;
- tm_context->modifiers = (Modifiers)i;
- return TRUE;
- }
- }
- }
- break;
- } /* switch (num_modbits) */
- }
- return FALSE;
-}
-
-void XtConvertCase(
- Display *dpy,
- KeySym keysym,
- KeySym *lower_return,
- KeySym *upper_return)
-{
- XtPerDisplay pd;
- CaseConverterPtr ptr;
- DPY_TO_APPCON(dpy);
-
- LOCK_APP(app);
- pd = _XtGetPerDisplay(dpy);
-
- *lower_return = *upper_return = keysym;
- for (ptr=pd->case_cvt; ptr; ptr = ptr->next)
- if (ptr->start <= keysym && keysym <= ptr->stop) {
- (*ptr->proc)(dpy, keysym, lower_return, upper_return);
- return;
- }
- XConvertCase(keysym, lower_return, upper_return);
- UNLOCK_APP(app);
-}
-
-Boolean _XtMatchUsingStandardMods (
- TMTypeMatch typeMatch,
- TMModifierMatch modMatch,
- TMEventPtr eventSeq)
-{
- Modifiers modifiers_return;
- KeySym keysym_return;
- Modifiers computed= 0;
- Modifiers computedMask = 0;
- Boolean resolved = TRUE;
- Display *dpy = eventSeq->xev->xany.display;
- XtPerDisplay pd = _XtGetPerDisplay(dpy);
- TMKeyContext tm_context = pd->tm_context;
- Modifiers translateModifiers;
-
- /* To maximize cache utilization, we mask off nonstandard modifiers
- before cache lookup. For a given key translator, standard modifiers
- are constant per KeyCode. If a key translator uses no standard
- modifiers this implementation will never reference the cache.
- */
-
- modifiers_return = MOD_RETURN(tm_context, eventSeq->event.eventCode);
- if (!modifiers_return) {
- XtTranslateKeycode(dpy, (KeyCode)eventSeq->event.eventCode,
- eventSeq->event.modifiers, &modifiers_return,
- &keysym_return);
- translateModifiers = eventSeq->event.modifiers & modifiers_return;
- UPDATE_CACHE(tm_context, pd, eventSeq->event.eventCode,
- translateModifiers, modifiers_return, keysym_return);
- } else {
- translateModifiers = eventSeq->event.modifiers & modifiers_return;
- TRANSLATE(tm_context, pd, dpy, (KeyCode)eventSeq->event.eventCode,
- translateModifiers, modifiers_return, keysym_return);
- }
-
- if ((typeMatch->eventCode & typeMatch->eventCodeMask) ==
- (keysym_return & typeMatch->eventCodeMask)) {
- if (modMatch->lateModifiers != NULL)
- resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers,
- &computed, &computedMask);
- if (!resolved) return FALSE;
- computed |= modMatch->modifiers;
- computedMask |= modMatch->modifierMask;
-
- if ((computed & computedMask) ==
- (eventSeq->event.modifiers & ~modifiers_return & computedMask)) {
- tm_context->event = eventSeq->xev;
- tm_context->serial = eventSeq->xev->xany.serial;
- tm_context->keysym = keysym_return;
- tm_context->modifiers = translateModifiers;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-
-void _XtBuildKeysymTables(
- Display *dpy,
- register XtPerDisplay pd)
-{
- ModToKeysymTable *table;
- int maxCount,i,j,k,tempCount,idx;
- KeySym keysym,tempKeysym;
- XModifierKeymap* modKeymap;
- KeyCode keycode;
-#define KeysymTableSize 16
-
- FLUSHKEYCACHE(pd->tm_context);
- if (pd->keysyms)
- XFree( (char *)pd->keysyms );
- pd->keysyms_serial = NextRequest(dpy);
- pd->keysyms = XGetKeyboardMapping(dpy, pd->min_keycode,
- pd->max_keycode-pd->min_keycode+1,
- &pd->keysyms_per_keycode);
- if (pd->modKeysyms)
- XtFree((char *)pd->modKeysyms);
- if (pd->modsToKeysyms)
- XtFree((char *)pd->modsToKeysyms);
- pd->modKeysyms = (KeySym*)__XtMalloc((Cardinal)KeysymTableSize*sizeof(KeySym));
- maxCount = KeysymTableSize;
- tempCount = 0;
-
- table = (ModToKeysymTable*)__XtMalloc((Cardinal)8*sizeof(ModToKeysymTable));
- pd->modsToKeysyms = table;
-
- table[0].mask = ShiftMask;
- table[1].mask = LockMask;
- table[2].mask = ControlMask;
- table[3].mask = Mod1Mask;
- table[4].mask = Mod2Mask;
- table[5].mask = Mod3Mask;
- table[6].mask = Mod4Mask;
- table[7].mask = Mod5Mask;
- tempKeysym = 0;
-
- modKeymap = XGetModifierMapping(dpy);
- for (i=0;i<32;i++)
- pd->isModifier[i] = 0;
- pd->mode_switch = 0;
- pd->num_lock = 0;
- for (i=0;i<8;i++) {
- table[i].idx = tempCount;
- table[i].count = 0;
- for (j=0;j<modKeymap->max_keypermod;j++) {
- keycode = modKeymap->modifiermap[i*modKeymap->max_keypermod+j];
- if (keycode != 0) {
- pd->isModifier[keycode>>3] |= 1 << (keycode & 7);
- for (k=0; k<pd->keysyms_per_keycode;k++) {
- idx = ((keycode-pd->min_keycode)*
- pd->keysyms_per_keycode)+k;
- keysym = pd->keysyms[idx];
- if ((keysym == XK_Mode_switch) && (i > 2))
- pd->mode_switch |= 1 << i;
- if ((keysym == XK_Num_Lock) && (i > 2))
- pd->num_lock |= 1 << i;
- if (keysym != 0 && keysym != tempKeysym ){
- if (tempCount==maxCount) {
- maxCount += KeysymTableSize;
- pd->modKeysyms = (KeySym*)XtRealloc(
- (char*)pd->modKeysyms,
- (unsigned) (maxCount*sizeof(KeySym)) );
- }
- pd->modKeysyms[tempCount++] = keysym;
- table[i].count++;
- tempKeysym = keysym;
- }
- }
- }
- }
- }
- pd->lock_meaning = NoSymbol;
- for (i = 0; i < table[1].count; i++) {
- keysym = pd->modKeysyms[table[1].idx + i];
- if (keysym == XK_Caps_Lock) {
- pd->lock_meaning = XK_Caps_Lock;
- break;
- } else if (keysym == XK_Shift_Lock) {
- pd->lock_meaning = XK_Shift_Lock;
- }
- }
- XFreeModifiermap(modKeymap);
-}
-
-void XtTranslateKeycode (
- Display *dpy,
- _XtKeyCode keycode,
- Modifiers modifiers,
- Modifiers *modifiers_return,
- KeySym *keysym_return)
-{
- XtPerDisplay pd;
- DPY_TO_APPCON(dpy);
-
- LOCK_APP(app);
- pd = _XtGetPerDisplay(dpy);
- _InitializeKeysymTables(dpy, pd);
- (*pd->defaultKeycodeTranslator)(
- dpy,keycode,modifiers,modifiers_return,keysym_return);
- UNLOCK_APP(app);
-}
-
-/* This code should match XTranslateKey (internal, sigh) in Xlib */
-void XtTranslateKey(
- register Display *dpy,
- _XtKeyCode keycode,
- Modifiers modifiers,
- Modifiers *modifiers_return,
- KeySym *keysym_return)
-{
-#ifndef XKB
- XtPerDisplay pd;
- int per;
- register KeySym *syms;
- KeySym sym, lsym, usym;
- DPY_TO_APPCON(dpy);
-
- LOCK_APP(app);
- pd = _XtGetPerDisplay(dpy);
- *modifiers_return = (ShiftMask|LockMask) | pd->mode_switch | pd->num_lock;
- if (((int)keycode < pd->min_keycode) || ((int)keycode > pd->max_keycode)) {
- *keysym_return = NoSymbol;
- UNLOCK_APP(app);
- return;
- }
- per = pd->keysyms_per_keycode;
- syms = &pd->keysyms[(keycode - pd->min_keycode) * per];
- while ((per > 2) && (syms[per - 1] == NoSymbol))
- per--;
- if ((per > 2) && (modifiers & pd->mode_switch)) {
- syms += 2;
- per -= 2;
- }
- if ((modifiers & pd->num_lock) &&
- (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
- if ((modifiers & ShiftMask) ||
- ((modifiers & LockMask) && (pd->lock_meaning == XK_Shift_Lock)))
- *keysym_return = syms[0];
- else
- *keysym_return = syms[1];
- } else if (!(modifiers & ShiftMask) &&
- (!(modifiers & LockMask) || (pd->lock_meaning == NoSymbol))) {
- if ((per == 1) || (syms[1] == NoSymbol))
- XtConvertCase(dpy, syms[0], keysym_return, &usym);
- else
- *keysym_return = syms[0];
- } else if (!(modifiers & LockMask) ||
- (pd->lock_meaning != XK_Caps_Lock)) {
- if ((per == 1) || ((usym = syms[1]) == NoSymbol))
- XtConvertCase(dpy, syms[0], &lsym, &usym);
- *keysym_return = usym;
- } else {
- if ((per == 1) || ((sym = syms[1]) == NoSymbol))
- sym = syms[0];
- XtConvertCase(dpy, sym, &lsym, &usym);
- if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
- ((sym != usym) || (lsym == usym)))
- XtConvertCase(dpy, syms[0], &lsym, &usym);
- *keysym_return = usym;
- }
-
- if (*keysym_return == XK_VoidSymbol)
- *keysym_return = NoSymbol;
- UNLOCK_APP(app);
-#else
- XkbLookupKeySym(dpy, keycode, modifiers, modifiers_return, keysym_return);
-#endif
-}
-
-void XtSetKeyTranslator(
- Display *dpy,
- XtKeyProc translator)
-{
- XtPerDisplay pd;
- DPY_TO_APPCON(dpy);
-
- LOCK_APP(app);
- pd = _XtGetPerDisplay(dpy);
-
- pd->defaultKeycodeTranslator = translator;
- FLUSHKEYCACHE(pd->tm_context);
- /* XXX should now redo grabs */
- UNLOCK_APP(app);
-}
-
-void XtRegisterCaseConverter(
- Display *dpy,
- XtCaseProc proc,
- KeySym start,
- KeySym stop)
-{
- XtPerDisplay pd;
- CaseConverterPtr ptr, prev;
- DPY_TO_APPCON(dpy);
-
- LOCK_APP(app);
- pd = _XtGetPerDisplay(dpy);
-
- ptr = (CaseConverterPtr) __XtMalloc(sizeof(CaseConverterRec));
- ptr->start = start;
- ptr->stop = stop;
- ptr->proc = proc;
- ptr->next = pd->case_cvt;
- pd->case_cvt = ptr;
-
- /* Remove obsolete case converters from the list */
- prev = ptr;
- for (ptr=ptr->next; ptr; ptr=prev->next) {
- if (start <= ptr->start && stop >= ptr->stop) {
- prev->next = ptr->next;
- XtFree((char *)ptr);
- }
- else prev = ptr;
- }
- FLUSHKEYCACHE(pd->tm_context);
- /* XXX should now redo grabs */
- UNLOCK_APP(app);
-}
-
-KeySym *XtGetKeysymTable(
- Display *dpy,
- KeyCode *min_keycode_return,
- int *keysyms_per_keycode_return)
-{
- XtPerDisplay pd;
- KeySym* retval;
- DPY_TO_APPCON(dpy);
-
- LOCK_APP(app);
- pd = _XtGetPerDisplay(dpy);
- _InitializeKeysymTables(dpy, pd);
- *min_keycode_return = pd->min_keycode; /* %%% */
- *keysyms_per_keycode_return = pd->keysyms_per_keycode;
- retval = pd->keysyms;
- UNLOCK_APP(app);
- return retval;
-}
-
-void XtKeysymToKeycodeList(
- Display *dpy,
- KeySym keysym,
- KeyCode **keycodes_return,
- Cardinal *keycount_return)
-{
- XtPerDisplay pd;
- unsigned keycode;
- int per, match;
- register KeySym *syms;
- register int i, j;
- KeySym lsym, usym;
- unsigned maxcodes = 0;
- unsigned ncodes = 0;
- KeyCode *keycodes, *codeP = NULL;
- DPY_TO_APPCON(dpy);
-
- LOCK_APP(app);
- pd = _XtGetPerDisplay(dpy);
- _InitializeKeysymTables(dpy, pd);
- keycodes = NULL;
- per = pd->keysyms_per_keycode;
- for (syms = pd->keysyms, keycode = (unsigned) pd->min_keycode;
- (int)keycode <= pd->max_keycode;
- syms += per, keycode++) {
- match = 0;
- for (j = 0; j < per; j++) {
- if (syms[j] == keysym) {
- match = 1;
- break;
- }
- }
- if (!match)
- for (i = 1; i < 5; i += 2) {
- if ((per == i) || ((per > i) && (syms[i] == NoSymbol))) {
- XtConvertCase(dpy, syms[i-1], &lsym, &usym);
- if ((lsym == keysym) || (usym == keysym)) {
- match = 1;
- break;
- }
- }
- }
- if (match) {
- if (ncodes == maxcodes) {
- KeyCode *old = keycodes;
- maxcodes += KEYCODE_ARRAY_SIZE;
- keycodes = (KeyCode*)__XtMalloc(maxcodes*sizeof(KeyCode));
- if (ncodes) {
- (void) memmove((char *)keycodes, (char *)old,
- ncodes*sizeof(KeyCode) );
- XtFree((char *)old);
- }
- codeP = &keycodes[ncodes];
- }
- *codeP++ = (KeyCode) keycode;
- ncodes++;
- }
- }
- *keycodes_return = keycodes;
- *keycount_return = ncodes;
- UNLOCK_APP(app);
-}
+/*LINTLIBRARY*/
+
+/***********************************************************
+Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+
+Copyright 1987, 1988, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#define XK_LATIN2
+#define XK_LATIN3
+#define XK_LATIN4
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "IntrinsicI.h"
+#include <X11/keysymdef.h>
+#ifdef XKB
+#include <X11/XKBlib.h>
+#endif
+
+#define FLUSHKEYCACHE(ctx) \
+ bzero((char *)&ctx->keycache, sizeof(TMKeyCache))
+
+/*
+ * The following array reorders the modifier bits so that the most common ones
+ * (used by a translator) are in the top-most bits with respect to the size of
+ * the keycache. The array currently just reverses the bits as a good guess.
+ * This might be more trouble than it is worth, but it seems to help.
+ */
+
+#define FM(i) i >> (8 - TMKEYCACHELOG2)
+static const unsigned char modmix[256] = {
+FM(0x0f), FM(0x8f), FM(0x4f), FM(0xcf), FM(0x2f), FM(0xaf), FM(0x6f), FM(0xef),
+FM(0x1f), FM(0x9f), FM(0x5f), FM(0xdf), FM(0x3f), FM(0xbf), FM(0x7f), FM(0xff),
+FM(0x07), FM(0x87), FM(0x47), FM(0xc7), FM(0x27), FM(0xa7), FM(0x67), FM(0xe7),
+FM(0x17), FM(0x97), FM(0x57), FM(0xd7), FM(0x37), FM(0xb7), FM(0x77), FM(0xf7),
+FM(0x0b), FM(0x8b), FM(0x4b), FM(0xcb), FM(0x2b), FM(0xab), FM(0x6b), FM(0xeb),
+FM(0x1b), FM(0x9b), FM(0x5b), FM(0xdb), FM(0x3b), FM(0xbb), FM(0x7b), FM(0xfb),
+FM(0x03), FM(0x83), FM(0x43), FM(0xc3), FM(0x23), FM(0xa3), FM(0x63), FM(0xe3),
+FM(0x13), FM(0x93), FM(0x53), FM(0xd3), FM(0x33), FM(0xb3), FM(0x73), FM(0xf3),
+FM(0x0d), FM(0x8d), FM(0x4d), FM(0xcd), FM(0x2d), FM(0xad), FM(0x6d), FM(0xed),
+FM(0x1d), FM(0x9d), FM(0x5d), FM(0xdd), FM(0x3d), FM(0xbd), FM(0x7d), FM(0xfd),
+FM(0x05), FM(0x85), FM(0x45), FM(0xc5), FM(0x25), FM(0xa5), FM(0x65), FM(0xe5),
+FM(0x15), FM(0x95), FM(0x55), FM(0xd5), FM(0x35), FM(0xb5), FM(0x75), FM(0xf5),
+FM(0x09), FM(0x89), FM(0x49), FM(0xc9), FM(0x29), FM(0xa9), FM(0x69), FM(0xe9),
+FM(0x19), FM(0x99), FM(0x59), FM(0xd9), FM(0x39), FM(0xb9), FM(0x79), FM(0xf9),
+FM(0x01), FM(0x81), FM(0x41), FM(0xc1), FM(0x21), FM(0xa1), FM(0x61), FM(0xe1),
+FM(0x11), FM(0x91), FM(0x51), FM(0xd1), FM(0x31), FM(0xb1), FM(0x71), FM(0xf1),
+FM(0x00), FM(0x8e), FM(0x4e), FM(0xce), FM(0x2e), FM(0xae), FM(0x6e), FM(0xee),
+FM(0x1e), FM(0x9e), FM(0x5e), FM(0xde), FM(0x3e), FM(0xbe), FM(0x7e), FM(0xfe),
+FM(0x08), FM(0x88), FM(0x48), FM(0xc8), FM(0x28), FM(0xa8), FM(0x68), FM(0xe8),
+FM(0x18), FM(0x98), FM(0x58), FM(0xd8), FM(0x38), FM(0xb8), FM(0x78), FM(0xf8),
+FM(0x04), FM(0x84), FM(0x44), FM(0xc4), FM(0x24), FM(0xa4), FM(0x64), FM(0xe4),
+FM(0x14), FM(0x94), FM(0x54), FM(0xd4), FM(0x34), FM(0xb4), FM(0x74), FM(0xf4),
+FM(0x0c), FM(0x8c), FM(0x4c), FM(0xcc), FM(0x2c), FM(0xac), FM(0x6c), FM(0xec),
+FM(0x1c), FM(0x9c), FM(0x5c), FM(0xdc), FM(0x3c), FM(0xbc), FM(0x7c), FM(0xfc),
+FM(0x02), FM(0x82), FM(0x42), FM(0xc2), FM(0x22), FM(0xa2), FM(0x62), FM(0xe2),
+FM(0x12), FM(0x92), FM(0x52), FM(0xd2), FM(0x32), FM(0xb2), FM(0x72), FM(0xf2),
+FM(0x0a), FM(0x8a), FM(0x4a), FM(0xca), FM(0x2a), FM(0xaa), FM(0x6a), FM(0xea),
+FM(0x1a), FM(0x9a), FM(0x5a), FM(0xda), FM(0x3a), FM(0xba), FM(0x7a), FM(0xfa),
+FM(0x06), FM(0x86), FM(0x46), FM(0xc6), FM(0x26), FM(0xa6), FM(0x66), FM(0xe6),
+FM(0x16), FM(0x96), FM(0x56), FM(0xd6), FM(0x36), FM(0xb6), FM(0x76), FM(0xf6),
+FM(0x0e), FM(0x8e), FM(0x4e), FM(0xce), FM(0x2e), FM(0xae), FM(0x6e), FM(0xee),
+FM(0x1e), FM(0x9e), FM(0x5e), FM(0xde), FM(0x3e), FM(0xbe), FM(0x7e), FM(0xfe)
+};
+#undef FM
+
+#define MOD_RETURN(ctx, key) (ctx)->keycache.modifiers_return[key]
+
+#define TRANSLATE(ctx,pd,dpy,key,mod,mod_ret,sym_ret) \
+{ \
+ int _i_ = (((key) - (pd)->min_keycode + modmix[(mod) & 0xff]) & \
+ (TMKEYCACHESIZE-1)); \
+ if ((key) == 0) { /* Xlib XIM composed input */ \
+ mod_ret = 0; \
+ sym_ret = 0; \
+ } else if ( /* not Xlib XIM composed input */ \
+ (ctx)->keycache.keycode[_i_] == (key) && \
+ (ctx)->keycache.modifiers[_i_] == (mod)) { \
+ mod_ret = MOD_RETURN(ctx, key); \
+ sym_ret = (ctx)->keycache.keysym[_i_]; \
+ } else { \
+ XtTranslateKeycode(dpy, key, mod, &mod_ret, &sym_ret); \
+ (ctx)->keycache.keycode[_i_] = key; \
+ (ctx)->keycache.modifiers[_i_] = (unsigned char)(mod); \
+ (ctx)->keycache.keysym[_i_] = sym_ret; \
+ MOD_RETURN(ctx, key) = (unsigned char)mod_ret; \
+ } \
+}
+
+#define UPDATE_CACHE(ctx, pd, key, mod, mod_ret, sym_ret) \
+{ \
+ int _i_ = (((key) - (pd)->min_keycode + modmix[(mod) & 0xff]) & \
+ (TMKEYCACHESIZE-1)); \
+ (ctx)->keycache.keycode[_i_] = key; \
+ (ctx)->keycache.modifiers[_i_] = (unsigned char)(mod); \
+ (ctx)->keycache.keysym[_i_] = sym_ret; \
+ MOD_RETURN(ctx, key) = (unsigned char)mod_ret; \
+}
+
+/* usual number of expected keycodes in XtKeysymToKeycodeList */
+#define KEYCODE_ARRAY_SIZE 10
+
+Boolean _XtComputeLateBindings(
+ Display *dpy,
+ LateBindingsPtr lateModifiers,
+ Modifiers *computed,
+ Modifiers *computedMask)
+{
+ int i,j,ref;
+ ModToKeysymTable* temp;
+ XtPerDisplay perDisplay;
+ Boolean found;
+ KeySym tempKeysym = NoSymbol;
+
+ perDisplay = _XtGetPerDisplay(dpy);
+ if (perDisplay == NULL) {
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ "displayError","invalidDisplay",XtCXtToolkitError,
+ "Can't find display structure",
+ (String *)NULL, (Cardinal *)NULL);
+ return FALSE;
+ }
+ _InitializeKeysymTables(dpy, perDisplay);
+ for (ref=0; lateModifiers[ref].keysym; ref++) {
+ found = FALSE;
+ for (i=0;i<8;i++) {
+ temp = &(perDisplay->modsToKeysyms[i]);
+ for (j=0;j<temp->count;j++){
+ if (perDisplay->modKeysyms[temp->idx+j] ==
+ lateModifiers[ref].keysym) {
+ *computedMask = *computedMask | temp->mask;
+ if (!lateModifiers[ref].knot)
+ *computed |= temp->mask;
+ tempKeysym = lateModifiers[ref].keysym;
+ found = TRUE; break;
+ }
+ }
+ if (found) break;
+ }
+ if (!found && !lateModifiers[ref].knot)
+ if (!lateModifiers[ref].pair && (tempKeysym == NoSymbol))
+ return FALSE;
+ /* if you didn't find the modifier and the modifier must be
+ asserted then return FALSE. If you didn't find the modifier
+ and the modifier must be off, then it is OK . Don't
+ return FALSE if this is the first member of a pair or if
+ it is the second member of a pair when the first member
+ was bound to a modifier */
+ if (!lateModifiers[ref].pair) tempKeysym = NoSymbol;
+ }
+ return TRUE;
+}
+
+void _XtAllocTMContext(
+ XtPerDisplay pd)
+{
+ TMKeyContext ctx;
+ ctx = (TMKeyContext)_XtHeapAlloc(&pd->heap,
+ sizeof(TMKeyContextRec));
+ ctx->event = NULL;
+ ctx->serial = 0;
+ ctx->keysym = NoSymbol;
+ ctx->modifiers = 0;
+ FLUSHKEYCACHE(ctx);
+ pd->tm_context = ctx;
+}
+
+static unsigned int num_bits(unsigned long mask)
+{
+ register unsigned long y;
+
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
+}
+
+Boolean _XtMatchUsingDontCareMods(
+ TMTypeMatch typeMatch,
+ TMModifierMatch modMatch,
+ TMEventPtr eventSeq)
+{
+ Modifiers modifiers_return;
+ KeySym keysym_return;
+ Modifiers useful_mods;
+ int i, num_modbits;
+ Modifiers computed = 0;
+ Modifiers computedMask = 0;
+ Boolean resolved = TRUE;
+ Display *dpy = eventSeq->xev->xany.display;
+ XtPerDisplay pd;
+ TMKeyContext tm_context;
+
+ if (modMatch->lateModifiers != NULL)
+ resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers,
+ &computed, &computedMask);
+ if (!resolved) return FALSE;
+ computed |= modMatch->modifiers;
+ computedMask |= modMatch->modifierMask; /* gives do-care mask */
+
+ if ( (computed & computedMask) ==
+ (eventSeq->event.modifiers & computedMask) ) {
+
+ pd = _XtGetPerDisplay(dpy);
+ tm_context = pd->tm_context;
+ TRANSLATE(tm_context, pd, dpy, (KeyCode)eventSeq->event.eventCode,
+ (unsigned)0, modifiers_return, keysym_return);
+
+ if ((keysym_return & typeMatch->eventCodeMask) == typeMatch->eventCode ) {
+ tm_context->event = eventSeq->xev;
+ tm_context->serial = eventSeq->xev->xany.serial;
+ tm_context->keysym = keysym_return;
+ tm_context->modifiers = (Modifiers)0;
+ return TRUE;
+ }
+ useful_mods = ~computedMask & modifiers_return;
+ if (useful_mods == 0) return FALSE;
+
+ switch (num_modbits = num_bits(useful_mods)) {
+ case 1:
+ case 8:
+ /*
+ * one modbit should never happen, in fact the implementation
+ * of XtTranslateKey and XmTranslateKey guarantee that it
+ * won't, so don't care if the loop is set up for the case
+ * when one modbit is set.
+ * The performance implications of all eight modbits being
+ * set is horrendous. This isn't a problem with Xt/Xaw based
+ * applications. We can only hope that Motif's virtual
+ * modifiers won't result in all eight modbits being set.
+ */
+ for (i = useful_mods; i > 0; i--) {
+ TRANSLATE(tm_context, pd, dpy, eventSeq->event.eventCode,
+ (Modifiers)i, modifiers_return, keysym_return);
+ if (keysym_return ==
+ (typeMatch->eventCode & typeMatch->eventCodeMask)) {
+ tm_context->event = eventSeq->xev;
+ tm_context->serial = eventSeq->xev->xany.serial;
+ tm_context->keysym = keysym_return;
+ tm_context->modifiers = (Modifiers)i;
+ return TRUE;
+ }
+ }
+ break;
+ default: /* (2..7) */
+ {
+ /*
+ * Only translate using combinations of the useful modifiers.
+ * to minimize the chance of invalidating the cache.
+ */
+ static char pows[] = { 0, 1, 3, 7, 15, 31, 63, 127 };
+ Modifiers tmod, mod_masks[8];
+ int j;
+ for (tmod = 1, i = 0; tmod <= (Mod5Mask<<1); tmod <<= 1)
+ if (tmod & useful_mods) mod_masks[i++] = tmod;
+ for (j = (int) pows[num_modbits]; j > 0; j--) {
+ tmod = 0;
+ for (i = 0; i < num_modbits; i++)
+ if (j & (1<<i)) tmod |= mod_masks[i];
+ TRANSLATE(tm_context, pd, dpy, eventSeq->event.eventCode,
+ tmod, modifiers_return, keysym_return);
+ if (keysym_return ==
+ (typeMatch->eventCode & typeMatch->eventCodeMask)) {
+ tm_context->event = eventSeq->xev;
+ tm_context->serial = eventSeq->xev->xany.serial;
+ tm_context->keysym = keysym_return;
+ tm_context->modifiers = (Modifiers)i;
+ return TRUE;
+ }
+ }
+ }
+ break;
+ } /* switch (num_modbits) */
+ }
+ return FALSE;
+}
+
+void XtConvertCase(
+ Display *dpy,
+ KeySym keysym,
+ KeySym *lower_return,
+ KeySym *upper_return)
+{
+ XtPerDisplay pd;
+ CaseConverterPtr ptr;
+ DPY_TO_APPCON(dpy);
+
+ LOCK_APP(app);
+ pd = _XtGetPerDisplay(dpy);
+
+ *lower_return = *upper_return = keysym;
+ for (ptr=pd->case_cvt; ptr; ptr = ptr->next)
+ if (ptr->start <= keysym && keysym <= ptr->stop) {
+ (*ptr->proc)(dpy, keysym, lower_return, upper_return);
+ return;
+ }
+ XConvertCase(keysym, lower_return, upper_return);
+ UNLOCK_APP(app);
+}
+
+Boolean _XtMatchUsingStandardMods (
+ TMTypeMatch typeMatch,
+ TMModifierMatch modMatch,
+ TMEventPtr eventSeq)
+{
+ Modifiers modifiers_return;
+ KeySym keysym_return;
+ Modifiers computed= 0;
+ Modifiers computedMask = 0;
+ Boolean resolved = TRUE;
+ Display *dpy = eventSeq->xev->xany.display;
+ XtPerDisplay pd = _XtGetPerDisplay(dpy);
+ TMKeyContext tm_context = pd->tm_context;
+ Modifiers translateModifiers;
+
+ /* To maximize cache utilization, we mask off nonstandard modifiers
+ before cache lookup. For a given key translator, standard modifiers
+ are constant per KeyCode. If a key translator uses no standard
+ modifiers this implementation will never reference the cache.
+ */
+
+ modifiers_return = MOD_RETURN(tm_context, eventSeq->event.eventCode);
+ if (!modifiers_return) {
+ XtTranslateKeycode(dpy, (KeyCode)eventSeq->event.eventCode,
+ eventSeq->event.modifiers, &modifiers_return,
+ &keysym_return);
+ translateModifiers = eventSeq->event.modifiers & modifiers_return;
+ UPDATE_CACHE(tm_context, pd, eventSeq->event.eventCode,
+ translateModifiers, modifiers_return, keysym_return);
+ } else {
+ translateModifiers = eventSeq->event.modifiers & modifiers_return;
+ TRANSLATE(tm_context, pd, dpy, (KeyCode)eventSeq->event.eventCode,
+ translateModifiers, modifiers_return, keysym_return);
+ }
+
+ if ((typeMatch->eventCode & typeMatch->eventCodeMask) ==
+ (keysym_return & typeMatch->eventCodeMask)) {
+ if (modMatch->lateModifiers != NULL)
+ resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers,
+ &computed, &computedMask);
+ if (!resolved) return FALSE;
+ computed |= modMatch->modifiers;
+ computedMask |= modMatch->modifierMask;
+
+ if ((computed & computedMask) ==
+ (eventSeq->event.modifiers & ~modifiers_return & computedMask)) {
+ tm_context->event = eventSeq->xev;
+ tm_context->serial = eventSeq->xev->xany.serial;
+ tm_context->keysym = keysym_return;
+ tm_context->modifiers = translateModifiers;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void _XtBuildKeysymTables(
+ Display *dpy,
+ register XtPerDisplay pd)
+{
+ ModToKeysymTable *table;
+ int maxCount,i,j,k,tempCount,idx;
+ KeySym keysym,tempKeysym;
+ XModifierKeymap* modKeymap;
+ KeyCode keycode;
+#define KeysymTableSize 16
+
+ FLUSHKEYCACHE(pd->tm_context);
+ if (pd->keysyms)
+ XFree( (char *)pd->keysyms );
+ pd->keysyms_serial = NextRequest(dpy);
+ pd->keysyms = XGetKeyboardMapping(dpy, pd->min_keycode,
+ pd->max_keycode-pd->min_keycode+1,
+ &pd->keysyms_per_keycode);
+ if (pd->modKeysyms)
+ XtFree((char *)pd->modKeysyms);
+ if (pd->modsToKeysyms)
+ XtFree((char *)pd->modsToKeysyms);
+ pd->modKeysyms = (KeySym*)__XtMalloc((Cardinal)KeysymTableSize*sizeof(KeySym));
+ maxCount = KeysymTableSize;
+ tempCount = 0;
+
+ table = (ModToKeysymTable*)__XtMalloc((Cardinal)8*sizeof(ModToKeysymTable));
+ pd->modsToKeysyms = table;
+
+ table[0].mask = ShiftMask;
+ table[1].mask = LockMask;
+ table[2].mask = ControlMask;
+ table[3].mask = Mod1Mask;
+ table[4].mask = Mod2Mask;
+ table[5].mask = Mod3Mask;
+ table[6].mask = Mod4Mask;
+ table[7].mask = Mod5Mask;
+ tempKeysym = 0;
+
+ modKeymap = XGetModifierMapping(dpy);
+ for (i=0;i<32;i++)
+ pd->isModifier[i] = 0;
+ pd->mode_switch = 0;
+ pd->num_lock = 0;
+ for (i=0;i<8;i++) {
+ table[i].idx = tempCount;
+ table[i].count = 0;
+ for (j=0;j<modKeymap->max_keypermod;j++) {
+ keycode = modKeymap->modifiermap[i*modKeymap->max_keypermod+j];
+ if (keycode != 0) {
+ pd->isModifier[keycode>>3] |= 1 << (keycode & 7);
+ for (k=0; k<pd->keysyms_per_keycode;k++) {
+ idx = ((keycode-pd->min_keycode)*
+ pd->keysyms_per_keycode)+k;
+ keysym = pd->keysyms[idx];
+ if ((keysym == XK_Mode_switch) && (i > 2))
+ pd->mode_switch |= 1 << i;
+ if ((keysym == XK_Num_Lock) && (i > 2))
+ pd->num_lock |= 1 << i;
+ if (keysym != 0 && keysym != tempKeysym ){
+ if (tempCount==maxCount) {
+ maxCount += KeysymTableSize;
+ pd->modKeysyms = (KeySym*)XtRealloc(
+ (char*)pd->modKeysyms,
+ (unsigned) (maxCount*sizeof(KeySym)) );
+ }
+ pd->modKeysyms[tempCount++] = keysym;
+ table[i].count++;
+ tempKeysym = keysym;
+ }
+ }
+ }
+ }
+ }
+ pd->lock_meaning = NoSymbol;
+ for (i = 0; i < table[1].count; i++) {
+ keysym = pd->modKeysyms[table[1].idx + i];
+ if (keysym == XK_Caps_Lock) {
+ pd->lock_meaning = XK_Caps_Lock;
+ break;
+ } else if (keysym == XK_Shift_Lock) {
+ pd->lock_meaning = XK_Shift_Lock;
+ }
+ }
+ XFreeModifiermap(modKeymap);
+}
+
+void XtTranslateKeycode (
+ Display *dpy,
+ _XtKeyCode keycode,
+ Modifiers modifiers,
+ Modifiers *modifiers_return,
+ KeySym *keysym_return)
+{
+ XtPerDisplay pd;
+ DPY_TO_APPCON(dpy);
+
+ LOCK_APP(app);
+ pd = _XtGetPerDisplay(dpy);
+ _InitializeKeysymTables(dpy, pd);
+ (*pd->defaultKeycodeTranslator)(
+ dpy,keycode,modifiers,modifiers_return,keysym_return);
+ UNLOCK_APP(app);
+}
+
+/* This code should match XTranslateKey (internal, sigh) in Xlib */
+void XtTranslateKey(
+ register Display *dpy,
+ _XtKeyCode keycode,
+ Modifiers modifiers,
+ Modifiers *modifiers_return,
+ KeySym *keysym_return)
+{
+#ifndef XKB
+ XtPerDisplay pd;
+ int per;
+ register KeySym *syms;
+ KeySym sym, lsym, usym;
+ DPY_TO_APPCON(dpy);
+
+ LOCK_APP(app);
+ pd = _XtGetPerDisplay(dpy);
+ *modifiers_return = (ShiftMask|LockMask) | pd->mode_switch | pd->num_lock;
+ if (((int)keycode < pd->min_keycode) || ((int)keycode > pd->max_keycode)) {
+ *keysym_return = NoSymbol;
+ UNLOCK_APP(app);
+ return;
+ }
+ per = pd->keysyms_per_keycode;
+ syms = &pd->keysyms[(keycode - pd->min_keycode) * per];
+ while ((per > 2) && (syms[per - 1] == NoSymbol))
+ per--;
+ if ((per > 2) && (modifiers & pd->mode_switch)) {
+ syms += 2;
+ per -= 2;
+ }
+ if ((modifiers & pd->num_lock) &&
+ (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
+ if ((modifiers & ShiftMask) ||
+ ((modifiers & LockMask) && (pd->lock_meaning == XK_Shift_Lock)))
+ *keysym_return = syms[0];
+ else
+ *keysym_return = syms[1];
+ } else if (!(modifiers & ShiftMask) &&
+ (!(modifiers & LockMask) || (pd->lock_meaning == NoSymbol))) {
+ if ((per == 1) || (syms[1] == NoSymbol))
+ XtConvertCase(dpy, syms[0], keysym_return, &usym);
+ else
+ *keysym_return = syms[0];
+ } else if (!(modifiers & LockMask) ||
+ (pd->lock_meaning != XK_Caps_Lock)) {
+ if ((per == 1) || ((usym = syms[1]) == NoSymbol))
+ XtConvertCase(dpy, syms[0], &lsym, &usym);
+ *keysym_return = usym;
+ } else {
+ if ((per == 1) || ((sym = syms[1]) == NoSymbol))
+ sym = syms[0];
+ XtConvertCase(dpy, sym, &lsym, &usym);
+ if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
+ ((sym != usym) || (lsym == usym)))
+ XtConvertCase(dpy, syms[0], &lsym, &usym);
+ *keysym_return = usym;
+ }
+
+ if (*keysym_return == XK_VoidSymbol)
+ *keysym_return = NoSymbol;
+ UNLOCK_APP(app);
+#else
+ XkbLookupKeySym(dpy, keycode, modifiers, modifiers_return, keysym_return);
+#endif
+}
+
+void XtSetKeyTranslator(
+ Display *dpy,
+ XtKeyProc translator)
+{
+ XtPerDisplay pd;
+ DPY_TO_APPCON(dpy);
+
+ LOCK_APP(app);
+ pd = _XtGetPerDisplay(dpy);
+
+ pd->defaultKeycodeTranslator = translator;
+ FLUSHKEYCACHE(pd->tm_context);
+ /* XXX should now redo grabs */
+ UNLOCK_APP(app);
+}
+
+void XtRegisterCaseConverter(
+ Display *dpy,
+ XtCaseProc proc,
+ KeySym start,
+ KeySym stop)
+{
+ XtPerDisplay pd;
+ CaseConverterPtr ptr, prev;
+ DPY_TO_APPCON(dpy);
+
+ LOCK_APP(app);
+ pd = _XtGetPerDisplay(dpy);
+
+ ptr = (CaseConverterPtr) __XtMalloc(sizeof(CaseConverterRec));
+ ptr->start = start;
+ ptr->stop = stop;
+ ptr->proc = proc;
+ ptr->next = pd->case_cvt;
+ pd->case_cvt = ptr;
+
+ /* Remove obsolete case converters from the list */
+ prev = ptr;
+ for (ptr=ptr->next; ptr; ptr=prev->next) {
+ if (start <= ptr->start && stop >= ptr->stop) {
+ prev->next = ptr->next;
+ XtFree((char *)ptr);
+ }
+ else prev = ptr;
+ }
+ FLUSHKEYCACHE(pd->tm_context);
+ /* XXX should now redo grabs */
+ UNLOCK_APP(app);
+}
+
+KeySym *XtGetKeysymTable(
+ Display *dpy,
+ KeyCode *min_keycode_return,
+ int *keysyms_per_keycode_return)
+{
+ XtPerDisplay pd;
+ KeySym* retval;
+ DPY_TO_APPCON(dpy);
+
+ LOCK_APP(app);
+ pd = _XtGetPerDisplay(dpy);
+ _InitializeKeysymTables(dpy, pd);
+ *min_keycode_return = pd->min_keycode; /* %%% */
+ *keysyms_per_keycode_return = pd->keysyms_per_keycode;
+ retval = pd->keysyms;
+ UNLOCK_APP(app);
+ return retval;
+}
+
+void XtKeysymToKeycodeList(
+ Display *dpy,
+ KeySym keysym,
+ KeyCode **keycodes_return,
+ Cardinal *keycount_return)
+{
+ XtPerDisplay pd;
+ unsigned keycode;
+ int per, match;
+ register KeySym *syms;
+ register int i, j;
+ KeySym lsym, usym;
+ unsigned maxcodes = 0;
+ unsigned ncodes = 0;
+ KeyCode *keycodes, *codeP = NULL;
+ DPY_TO_APPCON(dpy);
+
+ LOCK_APP(app);
+ pd = _XtGetPerDisplay(dpy);
+ _InitializeKeysymTables(dpy, pd);
+ keycodes = NULL;
+ per = pd->keysyms_per_keycode;
+ for (syms = pd->keysyms, keycode = (unsigned) pd->min_keycode;
+ (int)keycode <= pd->max_keycode;
+ syms += per, keycode++) {
+ match = 0;
+ for (j = 0; j < per; j++) {
+ if (syms[j] == keysym) {
+ match = 1;
+ break;
+ }
+ }
+ if (!match)
+ for (i = 1; i < 5; i += 2) {
+ if ((per == i) || ((per > i) && (syms[i] == NoSymbol))) {
+ XtConvertCase(dpy, syms[i-1], &lsym, &usym);
+ if ((lsym == keysym) || (usym == keysym)) {
+ match = 1;
+ break;
+ }
+ }
+ }
+ if (match) {
+ if (ncodes == maxcodes) {
+ KeyCode *old = keycodes;
+ maxcodes += KEYCODE_ARRAY_SIZE;
+ keycodes = (KeyCode*)__XtMalloc(maxcodes*sizeof(KeyCode));
+ if (ncodes) {
+ (void) memmove((char *)keycodes, (char *)old,
+ ncodes*sizeof(KeyCode) );
+ XtFree((char *)old);
+ }
+ codeP = &keycodes[ncodes];
+ }
+ *codeP++ = (KeyCode) keycode;
+ ncodes++;
+ }
+ }
+ *keycodes_return = keycodes;
+ *keycount_return = ncodes;
+ UNLOCK_APP(app);
+}