123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881 |
- /************************************************************
- Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
- 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 Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS 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.
- ********************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #elif defined(HAVE_CONFIG_H)
- #include <config.h>
- #endif
- #include <stdio.h>
- #include <X11/X.h>
- #include <X11/Xproto.h>
- #include "misc.h"
- #include "inputstr.h"
- #include <X11/keysym.h>
- #define XKBSRV_NEED_FILE_FUNCS
- #include <xkbsrv.h>
- /***====================================================================***/
- #define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
- #define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
- int
- XkbKeyTypesForCoreSymbols(XkbDescPtr xkb,
- int map_width,
- KeySym * core_syms,
- unsigned int protected,
- int *types_inout, KeySym * xkb_syms_rtrn)
- {
- register int i;
- unsigned int empty;
- int nSyms[XkbNumKbdGroups];
- int nGroups, tmp, groupsWidth;
- BOOL replicated = FALSE;
- /* Section 12.2 of the protocol describes this process in more detail */
- /* Step 1: find the # of symbols in the core mapping per group */
- groupsWidth = 2;
- for (i = 0; i < XkbNumKbdGroups; i++) {
- if ((protected & (1 << i)) && (types_inout[i] < xkb->map->num_types)) {
- nSyms[i] = xkb->map->types[types_inout[i]].num_levels;
- if (nSyms[i] > groupsWidth)
- groupsWidth = nSyms[i];
- }
- else {
- types_inout[i] = XkbTwoLevelIndex; /* don't really know, yet */
- nSyms[i] = 2;
- }
- }
- if (nSyms[XkbGroup1Index] < 2)
- nSyms[XkbGroup1Index] = 2;
- if (nSyms[XkbGroup2Index] < 2)
- nSyms[XkbGroup2Index] = 2;
- /* Step 2: Copy the symbols from the core ordering to XKB ordering */
- /* symbols in the core are in the order: */
- /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, 0)] = CORE_SYM(0);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, 1)] = CORE_SYM(1);
- for (i = 2; i < nSyms[XkbGroup1Index]; i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, i)] = CORE_SYM(2 + i);
- }
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, 0)] = CORE_SYM(2);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, 1)] = CORE_SYM(3);
- tmp = 2 + (nSyms[XkbGroup1Index] - 2); /* offset to extra group2 syms */
- for (i = 2; i < nSyms[XkbGroup2Index]; i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, i)] = CORE_SYM(tmp + i);
- }
- /* Special case: if only the first group is explicit, and the symbols
- * replicate across all groups, then we have a Section 12.4 replication */
- if ((protected & ~XkbExplicitKeyType1Mask) == 0) {
- int j, width = nSyms[XkbGroup1Index];
- replicated = TRUE;
- /* Check ABAB in ABABCDECDEABCDE */
- if ((width > 0 && CORE_SYM(0) != CORE_SYM(2)) ||
- (width > 1 && CORE_SYM(1) != CORE_SYM(3)))
- replicated = FALSE;
- /* Check CDECDE in ABABCDECDEABCDE */
- for (i = 2; i < width && replicated; i++) {
- if (CORE_SYM(2 + i) != CORE_SYM(i + width))
- replicated = FALSE;
- }
- /* Check ABCDE in ABABCDECDEABCDE */
- for (j = 2; replicated &&
- j < XkbNumKbdGroups && map_width >= width * (j + 1); j++) {
- for (i = 0; i < width && replicated; i++) {
- if (CORE_SYM(((i < 2) ? i : 2 + i)) != CORE_SYM(i + width * j))
- replicated = FALSE;
- }
- }
- }
- if (replicated) {
- nSyms[XkbGroup2Index] = 0;
- nSyms[XkbGroup3Index] = 0;
- nSyms[XkbGroup4Index] = 0;
- nGroups = 1;
- }
- else {
- tmp = nSyms[XkbGroup1Index] + nSyms[XkbGroup2Index];
- if ((tmp >= map_width) &&
- ((protected & (XkbExplicitKeyType3Mask | XkbExplicitKeyType4Mask))
- == 0)) {
- nSyms[XkbGroup3Index] = 0;
- nSyms[XkbGroup4Index] = 0;
- nGroups = 2;
- }
- else {
- nGroups = 3;
- for (i = 0; i < nSyms[XkbGroup3Index]; i++, tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index, i)] = CORE_SYM(tmp);
- }
- if ((tmp < map_width) || (protected & XkbExplicitKeyType4Mask)) {
- nGroups = 4;
- for (i = 0; i < nSyms[XkbGroup4Index]; i++, tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index, i)] =
- CORE_SYM(tmp);
- }
- }
- else {
- nSyms[XkbGroup4Index] = 0;
- }
- }
- }
- /* steps 3&4: alphanumeric expansion, assign canonical types */
- empty = 0;
- for (i = 0; i < nGroups; i++) {
- KeySym *syms;
- syms = &xkb_syms_rtrn[XKB_OFFSET(i, 0)];
- if ((nSyms[i] > 1) && (syms[1] == NoSymbol) && (syms[0] != NoSymbol)) {
- KeySym upper, lower;
- XkbConvertCase(syms[0], &lower, &upper);
- if (upper != lower) {
- xkb_syms_rtrn[XKB_OFFSET(i, 0)] = lower;
- xkb_syms_rtrn[XKB_OFFSET(i, 1)] = upper;
- if ((protected & (1 << i)) == 0)
- types_inout[i] = XkbAlphabeticIndex;
- }
- else if ((protected & (1 << i)) == 0) {
- types_inout[i] = XkbOneLevelIndex;
- /* nSyms[i]= 1; */
- }
- }
- if (((protected & (1 << i)) == 0) &&
- (types_inout[i] == XkbTwoLevelIndex)) {
- if (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))
- types_inout[i] = XkbKeypadIndex;
- else {
- KeySym upper, lower;
- XkbConvertCase(syms[0], &lower, &upper);
- if ((syms[0] == lower) && (syms[1] == upper))
- types_inout[i] = XkbAlphabeticIndex;
- }
- }
- if (syms[0] == NoSymbol) {
- register int n;
- Bool found;
- for (n = 1, found = FALSE; (!found) && (n < nSyms[i]); n++) {
- found = (syms[n] != NoSymbol);
- }
- if (!found)
- empty |= (1 << i);
- }
- }
- /* step 5: squoosh out empty groups */
- if (empty) {
- for (i = nGroups - 1; i >= 0; i--) {
- if (((empty & (1 << i)) == 0) || (protected & (1 << i)))
- break;
- nGroups--;
- }
- }
- if (nGroups < 1)
- return 0;
- /* step 6: replicate group 1 into group two, if necessary */
- if ((nGroups > 1) &&
- ((empty & (XkbGroup1Mask | XkbGroup2Mask)) == XkbGroup2Mask)) {
- if ((protected & (XkbExplicitKeyType1Mask | XkbExplicitKeyType2Mask)) ==
- 0) {
- nSyms[XkbGroup2Index] = nSyms[XkbGroup1Index];
- types_inout[XkbGroup2Index] = types_inout[XkbGroup1Index];
- memcpy((char *) &xkb_syms_rtrn[2], (char *) xkb_syms_rtrn,
- 2 * sizeof(KeySym));
- }
- else if (types_inout[XkbGroup1Index] == types_inout[XkbGroup2Index]) {
- memcpy((char *) &xkb_syms_rtrn[nSyms[XkbGroup1Index]],
- (char *) xkb_syms_rtrn,
- nSyms[XkbGroup1Index] * sizeof(KeySym));
- }
- }
- /* step 7: check for all groups identical or all width 1
- *
- * Special feature: if group 1 has an explicit type and all other groups
- * have canonical types with same symbols, we assume it's info lost from
- * the core replication.
- */
- if (nGroups > 1) {
- Bool sameType, allOneLevel, canonical = TRUE;
- allOneLevel = (xkb->map->types[types_inout[0]].num_levels == 1);
- for (i = 1, sameType = TRUE; (allOneLevel || sameType) && (i < nGroups);
- i++) {
- sameType = (sameType &&
- (types_inout[i] == types_inout[XkbGroup1Index]));
- if (allOneLevel)
- allOneLevel = (xkb->map->types[types_inout[i]].num_levels == 1);
- if (types_inout[i] > XkbLastRequiredType)
- canonical = FALSE;
- }
- if (((sameType) || canonical) &&
- (!(protected &
- (XkbExplicitKeyTypesMask & ~XkbExplicitKeyType1Mask)))) {
- register int s;
- Bool identical;
- for (i = 1, identical = TRUE; identical && (i < nGroups); i++) {
- KeySym *syms;
- if (nSyms[i] != nSyms[XkbGroup1Index])
- identical = FALSE;
- syms = &xkb_syms_rtrn[XKB_OFFSET(i, 0)];
- for (s = 0; identical && (s < nSyms[i]); s++) {
- if (syms[s] != xkb_syms_rtrn[s])
- identical = FALSE;
- }
- }
- if (identical)
- nGroups = 1;
- }
- if (allOneLevel && (nGroups > 1)) {
- KeySym *syms;
- syms = &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
- nSyms[XkbGroup1Index] = 1;
- for (i = 1; i < nGroups; i++) {
- xkb_syms_rtrn[i] = syms[0];
- syms += nSyms[i];
- nSyms[i] = 1;
- }
- }
- }
- return nGroups;
- }
- static XkbSymInterpretPtr
- _XkbFindMatchingInterp(XkbDescPtr xkb,
- KeySym sym, unsigned int real_mods, unsigned int level)
- {
- register unsigned i;
- XkbSymInterpretPtr interp, rtrn;
- CARD8 mods;
- rtrn = NULL;
- interp = xkb->compat->sym_interpret;
- for (i = 0; i < xkb->compat->num_si; i++, interp++) {
- if ((interp->sym == NoSymbol) || (sym == interp->sym)) {
- int match;
- if ((level == 0) || ((interp->match & XkbSI_LevelOneOnly) == 0))
- mods = real_mods;
- else
- mods = 0;
- switch (interp->match & XkbSI_OpMask) {
- case XkbSI_NoneOf:
- match = ((interp->mods & mods) == 0);
- break;
- case XkbSI_AnyOfOrNone:
- match = ((mods == 0) || ((interp->mods & mods) != 0));
- break;
- case XkbSI_AnyOf:
- match = ((interp->mods & mods) != 0);
- break;
- case XkbSI_AllOf:
- match = ((interp->mods & mods) == interp->mods);
- break;
- case XkbSI_Exactly:
- match = (interp->mods == mods);
- break;
- default:
- match = 0;
- break;
- }
- if (match) {
- if (interp->sym != NoSymbol) {
- return interp;
- }
- else if (rtrn == NULL) {
- rtrn = interp;
- }
- }
- }
- }
- return rtrn;
- }
- static void
- _XkbAddKeyChange(KeyCode *pFirst, unsigned char *pNum, KeyCode newKey)
- {
- KeyCode last;
- last = (*pFirst) + (*pNum);
- if (newKey < *pFirst) {
- *pFirst = newKey;
- *pNum = (last - newKey) + 1;
- }
- else if (newKey > last) {
- *pNum = (last - *pFirst) + 1;
- }
- return;
- }
- static void
- _XkbSetActionKeyMods(XkbDescPtr xkb, XkbAction *act, unsigned mods)
- {
- unsigned tmp;
- switch (act->type) {
- case XkbSA_SetMods:
- case XkbSA_LatchMods:
- case XkbSA_LockMods:
- if (act->mods.flags & XkbSA_UseModMapMods)
- act->mods.real_mods = act->mods.mask = mods;
- if ((tmp = XkbModActionVMods(&act->mods)) != 0) {
- XkbVirtualModsToReal(xkb, tmp, &tmp);
- act->mods.mask |= tmp;
- }
- break;
- case XkbSA_ISOLock:
- if (act->iso.flags & XkbSA_UseModMapMods)
- act->iso.real_mods = act->iso.mask = mods;
- if ((tmp = XkbModActionVMods(&act->iso)) != 0) {
- XkbVirtualModsToReal(xkb, tmp, &tmp);
- act->iso.mask |= tmp;
- }
- break;
- }
- return;
- }
- #define IBUF_SIZE 8
- Bool
- XkbApplyCompatMapToKey(XkbDescPtr xkb, KeyCode key, XkbChangesPtr changes)
- {
- KeySym *syms;
- unsigned char explicit, mods;
- XkbSymInterpretPtr *interps, ibuf[IBUF_SIZE];
- int n, nSyms, found;
- unsigned changed, tmp;
- if ((!xkb) || (!xkb->map) || (!xkb->map->key_sym_map) ||
- (!xkb->compat) || (!xkb->compat->sym_interpret) ||
- (key < xkb->min_key_code) || (key > xkb->max_key_code)) {
- return FALSE;
- }
- if (((!xkb->server) || (!xkb->server->key_acts)) &&
- (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 0) != Success)) {
- return FALSE;
- }
- changed = 0; /* keeps track of what has changed in _this_ call */
- explicit = xkb->server->explicit[key];
- if (explicit & XkbExplicitInterpretMask) /* nothing to do */
- return TRUE;
- mods = (xkb->map->modmap ? xkb->map->modmap[key] : 0);
- nSyms = XkbKeyNumSyms(xkb, key);
- syms = XkbKeySymsPtr(xkb, key);
- if (nSyms > IBUF_SIZE) {
- interps = calloc(nSyms, sizeof(XkbSymInterpretPtr));
- if (interps == NULL) {
- interps = ibuf;
- nSyms = IBUF_SIZE;
- }
- }
- else {
- interps = ibuf;
- }
- found = 0;
- for (n = 0; n < nSyms; n++) {
- unsigned level = (n % XkbKeyGroupsWidth(xkb, key));
- interps[n] = NULL;
- if (syms[n] != NoSymbol) {
- interps[n] = _XkbFindMatchingInterp(xkb, syms[n], mods, level);
- if (interps[n] && interps[n]->act.type != XkbSA_NoAction)
- found++;
- else
- interps[n] = NULL;
- }
- }
- /* 1/28/96 (ef) -- XXX! WORKING HERE */
- if (!found) {
- if (xkb->server->key_acts[key] != 0) {
- xkb->server->key_acts[key] = 0;
- changed |= XkbKeyActionsMask;
- }
- }
- else {
- XkbAction *pActs;
- unsigned int new_vmodmask;
- changed |= XkbKeyActionsMask;
- pActs = XkbResizeKeyActions(xkb, key, nSyms);
- if (!pActs) {
- if (nSyms > IBUF_SIZE)
- free(interps);
- return FALSE;
- }
- new_vmodmask = 0;
- for (n = 0; n < nSyms; n++) {
- if (interps[n]) {
- unsigned effMods;
- pActs[n] = *((XkbAction *) &interps[n]->act);
- if ((n == 0) || ((interps[n]->match & XkbSI_LevelOneOnly) == 0)) {
- effMods = mods;
- if (interps[n]->virtual_mod != XkbNoModifier)
- new_vmodmask |= (1 << interps[n]->virtual_mod);
- }
- else
- effMods = 0;
- _XkbSetActionKeyMods(xkb, &pActs[n], effMods);
- }
- else
- pActs[n].type = XkbSA_NoAction;
- }
- if (((explicit & XkbExplicitVModMapMask) == 0) &&
- (xkb->server->vmodmap[key] != new_vmodmask)) {
- changed |= XkbVirtualModMapMask;
- xkb->server->vmodmap[key] = new_vmodmask;
- }
- if (interps[0]) {
- if ((interps[0]->flags & XkbSI_LockingKey) &&
- ((explicit & XkbExplicitBehaviorMask) == 0)) {
- xkb->server->behaviors[key].type = XkbKB_Lock;
- changed |= XkbKeyBehaviorsMask;
- }
- if (((explicit & XkbExplicitAutoRepeatMask) == 0) && (xkb->ctrls)) {
- CARD8 old;
- old = BitIsOn(xkb->ctrls->per_key_repeat, key);
- if (interps[0]->flags & XkbSI_AutoRepeat)
- SetBit(xkb->ctrls->per_key_repeat, key);
- else
- ClearBit(xkb->ctrls->per_key_repeat, key);
- if (changes && old != BitIsOn(xkb->ctrls->per_key_repeat, key))
- changes->ctrls.changed_ctrls |= XkbPerKeyRepeatMask;
- }
- }
- }
- if ((!found) || (interps[0] == NULL)) {
- if (((explicit & XkbExplicitAutoRepeatMask) == 0) && (xkb->ctrls)) {
- CARD8 old;
- old = BitIsOn(xkb->ctrls->per_key_repeat, key);
- SetBit(xkb->ctrls->per_key_repeat, key);
- if (changes && (old != BitIsOn(xkb->ctrls->per_key_repeat, key)))
- changes->ctrls.changed_ctrls |= XkbPerKeyRepeatMask;
- }
- if (((explicit & XkbExplicitBehaviorMask) == 0) &&
- (xkb->server->behaviors[key].type == XkbKB_Lock)) {
- xkb->server->behaviors[key].type = XkbKB_Default;
- changed |= XkbKeyBehaviorsMask;
- }
- }
- if (changes) {
- XkbMapChangesPtr mc;
- mc = &changes->map;
- tmp = (changed & mc->changed);
- if (tmp & XkbKeyActionsMask)
- _XkbAddKeyChange(&mc->first_key_act, &mc->num_key_acts, key);
- else if (changed & XkbKeyActionsMask) {
- mc->changed |= XkbKeyActionsMask;
- mc->first_key_act = key;
- mc->num_key_acts = 1;
- }
- if (tmp & XkbKeyBehaviorsMask) {
- _XkbAddKeyChange(&mc->first_key_behavior, &mc->num_key_behaviors,
- key);
- }
- else if (changed & XkbKeyBehaviorsMask) {
- mc->changed |= XkbKeyBehaviorsMask;
- mc->first_key_behavior = key;
- mc->num_key_behaviors = 1;
- }
- if (tmp & XkbVirtualModMapMask)
- _XkbAddKeyChange(&mc->first_vmodmap_key, &mc->num_vmodmap_keys,
- key);
- else if (changed & XkbVirtualModMapMask) {
- mc->changed |= XkbVirtualModMapMask;
- mc->first_vmodmap_key = key;
- mc->num_vmodmap_keys = 1;
- }
- mc->changed |= changed;
- }
- if (interps != ibuf)
- free(interps);
- return TRUE;
- }
- Status
- XkbChangeTypesOfKey(XkbDescPtr xkb,
- int key,
- int nGroups,
- unsigned groups, int *newTypesIn, XkbMapChangesPtr changes)
- {
- XkbKeyTypePtr pOldType, pNewType;
- register int i;
- int width, nOldGroups, oldWidth, newTypes[XkbNumKbdGroups];
- if ((!xkb) || (!XkbKeycodeInRange(xkb, key)) || (!xkb->map) ||
- (!xkb->map->types) || (!newTypesIn) ||
- ((groups & XkbAllGroupsMask) == 0) || (nGroups > XkbNumKbdGroups)) {
- return BadMatch;
- }
- if (nGroups == 0) {
- for (i = 0; i < XkbNumKbdGroups; i++) {
- xkb->map->key_sym_map[key].kt_index[i] = XkbOneLevelIndex;
- }
- i = xkb->map->key_sym_map[key].group_info;
- i = XkbSetNumGroups(i, 0);
- xkb->map->key_sym_map[key].group_info = i;
- XkbResizeKeySyms(xkb, key, 0);
- return Success;
- }
- nOldGroups = XkbKeyNumGroups(xkb, key);
- oldWidth = XkbKeyGroupsWidth(xkb, key);
- for (width = i = 0; i < nGroups; i++) {
- if (groups & (1 << i))
- newTypes[i] = newTypesIn[i];
- else if (i < nOldGroups)
- newTypes[i] = XkbKeyKeyTypeIndex(xkb, key, i);
- else if (nOldGroups > 0)
- newTypes[i] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup1Index);
- else
- newTypes[i] = XkbTwoLevelIndex;
- if (newTypes[i] > xkb->map->num_types)
- return BadMatch;
- pNewType = &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels > width)
- width = pNewType->num_levels;
- }
- if ((xkb->ctrls) && (nGroups > xkb->ctrls->num_groups))
- xkb->ctrls->num_groups = nGroups;
- if ((width != oldWidth) || (nGroups != nOldGroups)) {
- KeySym oldSyms[XkbMaxSymsPerKey], *pSyms;
- int nCopy;
- if (nOldGroups == 0) {
- pSyms = XkbResizeKeySyms(xkb, key, width * nGroups);
- if (pSyms != NULL) {
- i = xkb->map->key_sym_map[key].group_info;
- i = XkbSetNumGroups(i, nGroups);
- xkb->map->key_sym_map[key].group_info = i;
- xkb->map->key_sym_map[key].width = width;
- for (i = 0; i < nGroups; i++) {
- xkb->map->key_sym_map[key].kt_index[i] = newTypes[i];
- }
- return Success;
- }
- return BadAlloc;
- }
- pSyms = XkbKeySymsPtr(xkb, key);
- memcpy(oldSyms, pSyms, XkbKeyNumSyms(xkb, key) * sizeof(KeySym));
- pSyms = XkbResizeKeySyms(xkb, key, width * nGroups);
- if (pSyms == NULL)
- return BadAlloc;
- memset(pSyms, 0, width * nGroups * sizeof(KeySym));
- for (i = 0; (i < nGroups) && (i < nOldGroups); i++) {
- pOldType = XkbKeyKeyType(xkb, key, i);
- pNewType = &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels > pOldType->num_levels)
- nCopy = pOldType->num_levels;
- else
- nCopy = pNewType->num_levels;
- memcpy(&pSyms[i * width], &oldSyms[i * oldWidth],
- nCopy * sizeof(KeySym));
- }
- if (XkbKeyHasActions(xkb, key)) {
- XkbAction oldActs[XkbMaxSymsPerKey], *pActs;
- pActs = XkbKeyActionsPtr(xkb, key);
- memcpy(oldActs, pActs, XkbKeyNumSyms(xkb, key) * sizeof(XkbAction));
- pActs = XkbResizeKeyActions(xkb, key, width * nGroups);
- if (pActs == NULL)
- return BadAlloc;
- memset(pActs, 0, width * nGroups * sizeof(XkbAction));
- for (i = 0; (i < nGroups) && (i < nOldGroups); i++) {
- pOldType = XkbKeyKeyType(xkb, key, i);
- pNewType = &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels > pOldType->num_levels)
- nCopy = pOldType->num_levels;
- else
- nCopy = pNewType->num_levels;
- memcpy(&pActs[i * width], &oldActs[i * oldWidth],
- nCopy * sizeof(XkbAction));
- }
- }
- i = xkb->map->key_sym_map[key].group_info;
- i = XkbSetNumGroups(i, nGroups);
- xkb->map->key_sym_map[key].group_info = i;
- xkb->map->key_sym_map[key].width = width;
- }
- width = 0;
- for (i = 0; i < nGroups; i++) {
- xkb->map->key_sym_map[key].kt_index[i] = newTypes[i];
- if (xkb->map->types[newTypes[i]].num_levels > width)
- width = xkb->map->types[newTypes[i]].num_levels;
- }
- xkb->map->key_sym_map[key].width = width;
- if (changes != NULL) {
- if (changes->changed & XkbKeySymsMask) {
- _XkbAddKeyChange(&changes->first_key_sym, &changes->num_key_syms,
- key);
- }
- else {
- changes->changed |= XkbKeySymsMask;
- changes->first_key_sym = key;
- changes->num_key_syms = 1;
- }
- }
- return Success;
- }
- /***====================================================================***/
- Bool
- XkbVirtualModsToReal(XkbDescPtr xkb, unsigned virtual_mask, unsigned *mask_rtrn)
- {
- register int i, bit;
- register unsigned mask;
- if (xkb == NULL)
- return FALSE;
- if (virtual_mask == 0) {
- *mask_rtrn = 0;
- return TRUE;
- }
- if (xkb->server == NULL)
- return FALSE;
- for (i = mask = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
- if (virtual_mask & bit)
- mask |= xkb->server->vmods[i];
- }
- *mask_rtrn = mask;
- return TRUE;
- }
- /***====================================================================***/
- static Bool
- XkbUpdateActionVirtualMods(XkbDescPtr xkb, XkbAction *act, unsigned changed)
- {
- unsigned int tmp;
- switch (act->type) {
- case XkbSA_SetMods:
- case XkbSA_LatchMods:
- case XkbSA_LockMods:
- if (((tmp = XkbModActionVMods(&act->mods)) & changed) != 0) {
- XkbVirtualModsToReal(xkb, tmp, &tmp);
- act->mods.mask = act->mods.real_mods;
- act->mods.mask |= tmp;
- return TRUE;
- }
- break;
- case XkbSA_ISOLock:
- if ((((tmp = XkbModActionVMods(&act->iso)) != 0) & changed) != 0) {
- XkbVirtualModsToReal(xkb, tmp, &tmp);
- act->iso.mask = act->iso.real_mods;
- act->iso.mask |= tmp;
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
- static void
- XkbUpdateKeyTypeVirtualMods(XkbDescPtr xkb,
- XkbKeyTypePtr type,
- unsigned int changed, XkbChangesPtr changes)
- {
- register unsigned int i;
- unsigned int mask;
- XkbVirtualModsToReal(xkb, type->mods.vmods, &mask);
- type->mods.mask = type->mods.real_mods | mask;
- if ((type->map_count > 0) && (type->mods.vmods != 0)) {
- XkbKTMapEntryPtr entry;
- for (i = 0, entry = type->map; i < type->map_count; i++, entry++) {
- if (entry->mods.vmods != 0) {
- XkbVirtualModsToReal(xkb, entry->mods.vmods, &mask);
- entry->mods.mask = entry->mods.real_mods | mask;
- /* entry is active if vmods are bound */
- entry->active = (mask != 0);
- }
- else
- entry->active = 1;
- }
- }
- if (changes) {
- int type_ndx;
- type_ndx = type - xkb->map->types;
- if ((type_ndx < 0) || (type_ndx > xkb->map->num_types))
- return;
- if (changes->map.changed & XkbKeyTypesMask) {
- int last;
- last = changes->map.first_type + changes->map.num_types - 1;
- if (type_ndx < changes->map.first_type) {
- changes->map.first_type = type_ndx;
- changes->map.num_types = (last - type_ndx) + 1;
- }
- else if (type_ndx > last) {
- changes->map.num_types =
- (type_ndx - changes->map.first_type) + 1;
- }
- }
- else {
- changes->map.changed |= XkbKeyTypesMask;
- changes->map.first_type = type_ndx;
- changes->map.num_types = 1;
- }
- }
- return;
- }
- Bool
- XkbApplyVirtualModChanges(XkbDescPtr xkb, unsigned changed,
- XkbChangesPtr changes)
- {
- register int i;
- unsigned int checkState = 0;
- if ((!xkb) || (!xkb->map) || (changed == 0))
- return FALSE;
- for (i = 0; i < xkb->map->num_types; i++) {
- if (xkb->map->types[i].mods.vmods & changed)
- XkbUpdateKeyTypeVirtualMods(xkb, &xkb->map->types[i], changed,
- changes);
- }
- if (changed & xkb->ctrls->internal.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb, xkb->ctrls->internal.vmods, &newMask);
- newMask |= xkb->ctrls->internal.real_mods;
- if (xkb->ctrls->internal.mask != newMask) {
- xkb->ctrls->internal.mask = newMask;
- if (changes) {
- changes->ctrls.changed_ctrls |= XkbInternalModsMask;
- checkState = TRUE;
- }
- }
- }
- if (changed & xkb->ctrls->ignore_lock.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb, xkb->ctrls->ignore_lock.vmods, &newMask);
- newMask |= xkb->ctrls->ignore_lock.real_mods;
- if (xkb->ctrls->ignore_lock.mask != newMask) {
- xkb->ctrls->ignore_lock.mask = newMask;
- if (changes) {
- changes->ctrls.changed_ctrls |= XkbIgnoreLockModsMask;
- checkState = TRUE;
- }
- }
- }
- if (xkb->indicators != NULL) {
- XkbIndicatorMapPtr map;
- map = &xkb->indicators->maps[0];
- for (i = 0; i < XkbNumIndicators; i++, map++) {
- if (map->mods.vmods & changed) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb, map->mods.vmods, &newMask);
- newMask |= map->mods.real_mods;
- if (newMask != map->mods.mask) {
- map->mods.mask = newMask;
- if (changes) {
- changes->indicators.map_changes |= (1 << i);
- checkState = TRUE;
- }
- }
- }
- }
- }
- if (xkb->compat != NULL) {
- XkbCompatMapPtr compat;
- compat = xkb->compat;
- for (i = 0; i < XkbNumKbdGroups; i++) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb, compat->groups[i].vmods, &newMask);
- newMask |= compat->groups[i].real_mods;
- if (compat->groups[i].mask != newMask) {
- compat->groups[i].mask = newMask;
- if (changes) {
- changes->compat.changed_groups |= (1 << i);
- checkState = TRUE;
- }
- }
- }
- }
- if (xkb->map && xkb->server) {
- int highChange = 0, lowChange = -1;
- for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
- if (XkbKeyHasActions(xkb, i)) {
- register XkbAction *pAct;
- register int n;
- pAct = XkbKeyActionsPtr(xkb, i);
- for (n = XkbKeyNumActions(xkb, i); n > 0; n--, pAct++) {
- if ((pAct->type != XkbSA_NoAction) &&
- XkbUpdateActionVirtualMods(xkb, pAct, changed)) {
- if (lowChange < 0)
- lowChange = i;
- highChange = i;
- }
- }
- }
- }
- if (changes && (lowChange > 0)) { /* something changed */
- if (changes->map.changed & XkbKeyActionsMask) {
- int last;
- if (changes->map.first_key_act < lowChange)
- lowChange = changes->map.first_key_act;
- last =
- changes->map.first_key_act + changes->map.num_key_acts - 1;
- if (last > highChange)
- highChange = last;
- }
- changes->map.changed |= XkbKeyActionsMask;
- changes->map.first_key_act = lowChange;
- changes->map.num_key_acts = (highChange - lowChange) + 1;
- }
- }
- return checkState;
- }
|