diff options
Diffstat (limited to 'xorg-server/xkb/xkbUtils.c')
-rw-r--r-- | xorg-server/xkb/xkbUtils.c | 493 |
1 files changed, 205 insertions, 288 deletions
diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c index 71b0f6661..63b1e31c7 100644 --- a/xorg-server/xkb/xkbUtils.c +++ b/xorg-server/xkb/xkbUtils.c @@ -56,21 +56,19 @@ DEALINGS IN THE SOFTWARE. #include <stdio.h> #include <ctype.h> #include <math.h> -#define NEED_EVENTS 1 #include <X11/X.h> #include <X11/Xproto.h> #define XK_CYRILLIC #include <X11/keysym.h> #include "misc.h" #include "inputstr.h" +#include "eventstr.h" #define XKBSRV_NEED_FILE_FUNCS #include <xkbsrv.h> #include "xkbgeom.h" #include "xkb.h" -int XkbDisableLockActions = 0; - /***====================================================================***/ int @@ -216,13 +214,13 @@ register unsigned mask; void XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev, + KeySymsPtr pCore, KeyCode first, CARD8 num, XkbChangesPtr changes) { XkbDescPtr xkb; unsigned key,nG,explicit; -KeySymsPtr pCore; int types[XkbNumKbdGroups]; KeySym tsyms[XkbMaxSymsPerKey],*syms; XkbMapChangesPtr mc; @@ -235,8 +233,7 @@ XkbMapChangesPtr mc; mc= (changes?(&changes->map):NULL); - pCore= &pXDev->key->curKeySyms; - syms= &pCore->map[(first-xkb->min_key_code)*pCore->mapWidth]; + syms= &pCore->map[(first - pCore->minKeyCode) * pCore->mapWidth]; for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) { explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask; types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); @@ -358,59 +355,24 @@ CARD8 * repeat; return; } -void -XkbUpdateCoreDescription(DeviceIntPtr keybd,Bool resize) +KeySymsPtr +XkbGetCoreMap(DeviceIntPtr keybd) { register int key,tmp; -int maxSymsPerKey,maxKeysPerMod; -int first,last,firstCommon,lastCommon; +int maxSymsPerKey, maxGroup1Width; XkbDescPtr xkb; -KeyClassPtr keyc; -CARD8 keysPerMod[XkbNumModifiers]; +KeySymsPtr syms; +int maxNumberOfGroups; if (!keybd || !keybd->key || !keybd->key->xkbInfo) - return; + return NULL; + xkb= keybd->key->xkbInfo->desc; - keyc= keybd->key; - maxSymsPerKey= maxKeysPerMod= 0; - bzero(keysPerMod,sizeof(keysPerMod)); - memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1); - if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&& - (xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) { - first= firstCommon= xkb->min_key_code; - last= lastCommon= xkb->max_key_code; - } - else if (resize) { - keyc->curKeySyms.minKeyCode= xkb->min_key_code; - keyc->curKeySyms.maxKeyCode= xkb->max_key_code; - tmp= keyc->curKeySyms.mapWidth*_XkbCoreNumKeys(keyc); - keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym); - if (!keyc->curKeySyms.map) - FatalError("Couldn't allocate keysyms\n"); - first= firstCommon= xkb->min_key_code; - last= lastCommon= xkb->max_key_code; - } - else { - if (xkb->min_key_code<keyc->curKeySyms.minKeyCode) { - first= xkb->min_key_code; - firstCommon= keyc->curKeySyms.minKeyCode; - } - else { - firstCommon= xkb->min_key_code; - first= keyc->curKeySyms.minKeyCode; - } - if (xkb->max_key_code>keyc->curKeySyms.maxKeyCode) { - lastCommon= keyc->curKeySyms.maxKeyCode; - last= xkb->max_key_code; - } - else { - lastCommon= xkb->max_key_code; - last= keyc->curKeySyms.maxKeyCode; - } - } + maxSymsPerKey= maxGroup1Width= 0; + maxNumberOfGroups = 0; /* determine sizes */ - for (key=first;key<=last;key++) { + for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) { if (XkbKeycodeInRange(xkb,key)) { int nGroups; int w; @@ -420,6 +382,9 @@ CARD8 keysPerMod[XkbNumModifiers]; if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2) tmp+= 2; else tmp+= w + 2; + /* remember highest G1 width */ + if (w > maxGroup1Width) + maxGroup1Width = w; } if (nGroups>1) { if (tmp <= 2) { @@ -437,141 +402,113 @@ CARD8 keysPerMod[XkbNumModifiers]; tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index); if (tmp>maxSymsPerKey) maxSymsPerKey= tmp; + if (nGroups > maxNumberOfGroups) + maxNumberOfGroups = nGroups; } - if (_XkbCoreKeycodeInRange(keyc,key)) { - if (keyc->modifierMap[key]!=0) { - register unsigned bit,i,mask; - mask= keyc->modifierMap[key]; - for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) { - if (mask&bit) { - keysPerMod[i]++; - if (keysPerMod[i]>maxKeysPerMod) - maxKeysPerMod= keysPerMod[i]; - } - } - } - } - } - - if (maxKeysPerMod>0) { - tmp= maxKeysPerMod*XkbNumModifiers; - if (keyc->modifierKeyMap==NULL) - keyc->modifierKeyMap= (KeyCode *)_XkbCalloc(1, tmp); - else if (keyc->maxKeysPerModifier<maxKeysPerMod) - keyc->modifierKeyMap= (KeyCode *)_XkbRealloc(keyc->modifierKeyMap,tmp); - if (keyc->modifierKeyMap==NULL) - FatalError("Couldn't allocate modifierKeyMap in UpdateCore\n"); - bzero(keyc->modifierKeyMap,tmp); - } - else if ((keyc->maxKeysPerModifier>0)&&(keyc->modifierKeyMap!=NULL)) { - _XkbFree(keyc->modifierKeyMap); - keyc->modifierKeyMap= NULL; } - keyc->maxKeysPerModifier= maxKeysPerMod; - if (maxSymsPerKey>0) { - tmp= maxSymsPerKey*_XkbCoreNumKeys(keyc); - keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym); - if (keyc->curKeySyms.map==NULL) - FatalError("Couldn't allocate symbols map in UpdateCore\n"); + if (maxSymsPerKey <= 0) + return NULL; + + syms = xcalloc(1, sizeof(*syms)); + if (!syms) + return NULL; + + /* See Section 12.4 of the XKB Protocol spec. Because of the + * single-group distribution for multi-group keyboards, we have to + * have enough symbols for the largest group 1 to replicate across the + * number of groups on the keyboard. e.g. a single-group key with 4 + * symbols on a keyboard that has 3 groups -> 12 syms per key */ + if (maxSymsPerKey < maxNumberOfGroups * maxGroup1Width) + maxSymsPerKey = maxNumberOfGroups * maxGroup1Width; + + syms->mapWidth = maxSymsPerKey; + syms->minKeyCode = xkb->min_key_code; + syms->maxKeyCode = xkb->max_key_code; + + tmp = syms->mapWidth * (xkb->max_key_code - xkb->min_key_code + 1); + syms->map = xcalloc(tmp, sizeof(*syms->map)); + if (!syms->map) { + xfree(syms); + return NULL; } - else if ((keyc->curKeySyms.mapWidth>0)&&(keyc->curKeySyms.map!=NULL)) { - _XkbFree(keyc->curKeySyms.map); - keyc->curKeySyms.map= NULL; - } - keyc->curKeySyms.mapWidth= maxSymsPerKey; - - bzero(keysPerMod,sizeof(keysPerMod)); - for (key=firstCommon;key<=lastCommon;key++) { - if (keyc->curKeySyms.map!=NULL) { - KeySym *pCore,*pXKB; - unsigned nGroups,groupWidth,n,nOut; - nGroups= XkbKeyNumGroups(xkb,key); - n= (key-keyc->curKeySyms.minKeyCode)*maxSymsPerKey; - pCore= &keyc->curKeySyms.map[n]; - bzero(pCore,maxSymsPerKey*sizeof(KeySym)); - pXKB= XkbKeySymsPtr(xkb,key); - nOut= 2; - if (nGroups>0) { - groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index); - if (groupWidth>0) pCore[0]= pXKB[0]; - if (groupWidth>1) pCore[1]= pXKB[1]; - for (n=2;n<groupWidth;n++) { - pCore[2+n]= pXKB[n]; - } - if (groupWidth>2) - nOut= groupWidth; - } + for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) { + KeySym *pCore,*pXKB; + unsigned nGroups,groupWidth,n,nOut; + + nGroups= XkbKeyNumGroups(xkb,key); + n= (key-xkb->min_key_code)*syms->mapWidth; + pCore= &syms->map[n]; + pXKB= XkbKeySymsPtr(xkb,key); + nOut= 2; + if (nGroups>0) { + groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index); + if (groupWidth>0) pCore[0]= pXKB[0]; + if (groupWidth>1) pCore[1]= pXKB[1]; + for (n=2;n<groupWidth;n++) + pCore[2+n]= pXKB[n]; + if (groupWidth>2) + nOut= groupWidth; + } - /* See XKB Protocol Sec, Section 12.4. - A 1-group key with ABCDE on a 2 group keyboard must be - duplicated across all groups as ABABCDECDE. - */ - if (nGroups == 1) + /* See XKB Protocol Sec, Section 12.4. + A 1-group key with ABCDE on a 2 group keyboard must be + duplicated across all groups as ABABCDECDE. + */ + if (nGroups == 1) + { + int idx, j; + + groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index); + + /* AB..CDE... -> ABABCDE... */ + if (groupWidth > 0 && syms->mapWidth >= 3) + pCore[2] = pCore[0]; + if (groupWidth > 1 && syms->mapWidth >= 4) + pCore[3] = pCore[1]; + + /* ABABCDE... -> ABABCDECDE */ + idx = 2 + groupWidth; + while (groupWidth > 2 && idx < syms->mapWidth && + idx < groupWidth * 2) { - int idx; - - groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index); - - /* AB..CDE... -> ABABCDE... */ - if (groupWidth > 0 && maxSymsPerKey >= 3) - pCore[2] = pCore[0]; - if (groupWidth > 1 && maxSymsPerKey >= 4) - pCore[3] = pCore[1]; - - /* ABABCDE... -> ABABCDECDE */ - idx = 2 + groupWidth; - while (groupWidth > 2 && - idx < maxSymsPerKey && - idx < groupWidth * 2) - { - pCore[idx] = pCore[idx - groupWidth + 2]; - idx++; - } - idx = 2 * groupWidth; - if (idx < 4) - idx = 4; - /* 3 or more groups: ABABCDECDEABCDEABCDE */ + pCore[idx] = pCore[idx - groupWidth + 2]; + idx++; + } + idx = 2 * groupWidth; + if (idx < 4) + idx = 4; + /* 3 or more groups: ABABCDECDEABCDEABCDE */ + for (j = 3; j <= maxNumberOfGroups; j++) for (n = 0; n < groupWidth && idx < maxSymsPerKey; n++) pCore[idx++] = pXKB[n]; - } + } - pXKB+= XkbKeyGroupsWidth(xkb,key); - nOut+= 2; - if (nGroups>1) { - groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index); - if (groupWidth>0) pCore[2]= pXKB[0]; - if (groupWidth>1) pCore[3]= pXKB[1]; - for (n=2;n<groupWidth;n++) { - pCore[nOut+(n-2)]= pXKB[n]; - } - if (groupWidth>2) - nOut+= (groupWidth-2); - } - pXKB+= XkbKeyGroupsWidth(xkb,key); - for (n=XkbGroup3Index;n<nGroups;n++) { - register int s; - groupWidth= XkbKeyGroupWidth(xkb,key,n); - for (s=0;s<groupWidth;s++) { - pCore[nOut++]= pXKB[s]; - } - pXKB+= XkbKeyGroupsWidth(xkb,key); + pXKB+= XkbKeyGroupsWidth(xkb,key); + nOut+= 2; + if (nGroups>1) { + groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index); + if (groupWidth>0) pCore[2]= pXKB[0]; + if (groupWidth>1) pCore[3]= pXKB[1]; + for (n=2;n<groupWidth;n++) { + pCore[nOut+(n-2)]= pXKB[n]; } + if (groupWidth>2) + nOut+= (groupWidth-2); } - if (keyc->modifierMap[key]!=0) { - register unsigned bit,i,mask; - mask= keyc->modifierMap[key]; - for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) { - if (mask&bit) { - tmp= i*maxKeysPerMod+keysPerMod[i]; - keyc->modifierKeyMap[tmp]= key; - keysPerMod[i]++; - } + pXKB+= XkbKeyGroupsWidth(xkb,key); + for (n=XkbGroup3Index;n<nGroups;n++) { + register int s; + groupWidth= XkbKeyGroupWidth(xkb,key,n); + for (s=0;s<groupWidth;s++) { + pCore[nOut++]= pXKB[s]; } + pXKB+= XkbKeyGroupsWidth(xkb,key); } } - return; + + return syms; } void @@ -598,46 +535,50 @@ XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff) return; } +/* Applies a change to a single device, does not traverse the device tree. */ void -XkbApplyMappingChange( DeviceIntPtr kbd, - CARD8 request, - KeyCode firstKey, - CARD8 num, - ClientPtr client) +XkbApplyMappingChange(DeviceIntPtr kbd, KeySymsPtr map, KeyCode first_key, + CARD8 num_keys, CARD8 *modmap, ClientPtr client) { -XkbEventCauseRec cause; -XkbChangesRec changes; -unsigned check; - - if (kbd->key->xkbInfo==NULL) - XkbInitDevice(kbd); - bzero(&changes,sizeof(XkbChangesRec)); - check= 0; - if (request==MappingKeyboard) { - XkbSetCauseCoreReq(&cause,X_ChangeKeyboardMapping,client); - XkbUpdateKeyTypesFromCore(kbd,firstKey,num,&changes); - XkbUpdateActions(kbd,firstKey,num,&changes,&check,&cause); - if (check) - XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause); - } - else if (request==MappingModifier) { - XkbDescPtr xkb= kbd->key->xkbInfo->desc; + XkbDescPtr xkb = kbd->key->xkbInfo->desc; + XkbEventCauseRec cause; + XkbChangesRec changes; + unsigned int check; + + memset(&changes, 0, sizeof(changes)); + memset(&cause, 0, sizeof(cause)); - XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client); + if (map && first_key && num_keys) { + check = 0; + XkbSetCauseCoreReq(&cause, X_ChangeKeyboardMapping, client); - num = xkb->max_key_code-xkb->min_key_code+1; - memcpy(xkb->map->modmap,kbd->key->modifierMap,xkb->max_key_code+1); + XkbUpdateKeyTypesFromCore(kbd, map, first_key, num_keys, &changes); + XkbUpdateActions(kbd, first_key, num_keys, &changes, &check, &cause); - changes.map.changed|= XkbModifierMapMask; - changes.map.first_modmap_key= xkb->min_key_code; - changes.map.num_modmap_keys= num; - XkbUpdateActions(kbd,xkb->min_key_code,num,&changes,&check,&cause); - if (check) - XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause); + if (check) + XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause); } - /* 3/26/94 (ef) -- XXX! Doesn't deal with input extension requests */ - XkbSendNotification(kbd,&changes,&cause); - return; + + if (modmap) { + /* A keymap change can imply a modmap change, se we prefer the + * former. */ + if (!cause.mjr) + XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client); + + check = 0; + num_keys = xkb->max_key_code - xkb->min_key_code + 1; + changes.map.changed |= XkbModifierMapMask; + changes.map.first_modmap_key = xkb->min_key_code; + changes.map.num_modmap_keys = num_keys; + memcpy(kbd->key->xkbInfo->desc->map->modmap, modmap, MAP_LENGTH); + XkbUpdateActions(kbd, xkb->min_key_code, num_keys, &changes, &check, + &cause); + + if (check) + XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause); + } + + XkbSendNotification(kbd, &changes, &cause); } void @@ -751,8 +692,7 @@ unsigned char grp; if (!state || !ctrls) return; - state->mods= (state->base_mods|state->latched_mods); - state->mods|= state->locked_mods; + state->mods= (state->base_mods|state->latched_mods|state->locked_mods); state->lookup_mods= state->mods&(~ctrls->internal.mask); state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask); state->grab_mods|= @@ -842,7 +782,7 @@ XkbSrvLedInfoPtr sli; #define MAX_TOC 16 -XkbGeometryPtr +XkbGeometryPtr XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree) { XkbSrvInfoPtr xkbi= dev->key->xkbInfo; @@ -2103,97 +2043,44 @@ _XkbCopyControls(XkbDescPtr src, XkbDescPtr dst) */ Bool -XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) +XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src) { - DeviceIntPtr pDev = NULL, tmpDev = NULL; - xkbMapNotify mn; - xkbNewKeyboardNotify nkn; - if (!src || !dst || src == dst) + if (!src || !dst) { + DebugF("XkbCopyKeymap: src (%p) or dst (%p) is NULL\n", src, dst); return FALSE; + } - if (!_XkbCopyClientMap(src, dst)) - return FALSE; - if (!_XkbCopyServerMap(src, dst)) - return FALSE; - if (!_XkbCopyIndicators(src, dst)) + if (src == dst) + return TRUE; + + if (!_XkbCopyClientMap(src, dst)) { + DebugF("XkbCopyKeymap: failed to copy client map\n"); return FALSE; - if (!_XkbCopyControls(src, dst)) + } + if (!_XkbCopyServerMap(src, dst)) { + DebugF("XkbCopyKeymap: failed to copy server map\n"); return FALSE; - if (!_XkbCopyNames(src, dst)) + } + if (!_XkbCopyIndicators(src, dst)) { + DebugF("XkbCopyKeymap: failed to copy indicators\n"); return FALSE; - if (!_XkbCopyCompat(src, dst)) + } + if (!_XkbCopyControls(src, dst)) { + DebugF("XkbCopyKeymap: failed to copy controls\n"); return FALSE; - if (!_XkbCopyGeom(src, dst)) + } + if (!_XkbCopyNames(src, dst)) { + DebugF("XkbCopyKeymap: failed to copy names\n"); return FALSE; - - if (inputInfo.keyboard->key->xkbInfo && - inputInfo.keyboard->key->xkbInfo->desc == dst) { - pDev = inputInfo.keyboard; } - else { - for (tmpDev = inputInfo.devices; tmpDev && !pDev; - tmpDev = tmpDev->next) { - if (tmpDev->key && tmpDev->key->xkbInfo && - tmpDev->key->xkbInfo->desc == dst) { - pDev = tmpDev; - break; - } - } - for (tmpDev = inputInfo.off_devices; tmpDev && !pDev; - tmpDev = tmpDev->next) { - if (tmpDev->key && tmpDev->key->xkbInfo && - tmpDev->key->xkbInfo->desc == dst) { - pDev = tmpDev; - break; - } - } + if (!_XkbCopyCompat(src, dst)) { + DebugF("XkbCopyKeymap: failed to copy compat map\n"); + return FALSE; } - - if (sendNotifies) { - if (!pDev) { - ErrorF("[xkb] XkbCopyKeymap: asked for notifies, but can't find device!\n"); - } - else { - /* send NewKeyboardNotify if the keycode range changed, else - * just MapNotify. we also need to send NKN if the geometry - * changed (obviously ...). */ - if ((src->min_key_code != dst->min_key_code || - src->max_key_code != dst->max_key_code)) { - nkn.oldMinKeyCode = dst->min_key_code; - nkn.oldMaxKeyCode = dst->max_key_code; - nkn.deviceID = nkn.oldDeviceID = pDev->id; - nkn.minKeyCode = src->min_key_code; - nkn.maxKeyCode = src->max_key_code; - nkn.requestMajor = XkbReqCode; - nkn.requestMinor = X_kbSetMap; /* XXX bare-faced lie */ - nkn.changed = XkbAllNewKeyboardEventsMask; - XkbSendNewKeyboardNotify(pDev, &nkn); - } else - { - mn.deviceID = pDev->id; - mn.minKeyCode = src->min_key_code; - mn.maxKeyCode = src->max_key_code; - mn.firstType = 0; - mn.nTypes = src->map->num_types; - mn.firstKeySym = src->min_key_code; - mn.nKeySyms = XkbNumKeys(src); - mn.firstKeyAct = src->min_key_code; - mn.nKeyActs = XkbNumKeys(src); - /* Cargo-culted from ProcXkbGetMap. */ - mn.firstKeyBehavior = src->min_key_code; - mn.nKeyBehaviors = XkbNumKeys(src); - mn.firstKeyExplicit = src->min_key_code; - mn.nKeyExplicit = XkbNumKeys(src); - mn.firstModMapKey = src->min_key_code; - mn.nModMapKeys = XkbNumKeys(src); - mn.firstVModMapKey = src->min_key_code; - mn.nVModMapKeys = XkbNumKeys(src); - mn.virtualMods = ~0; /* ??? */ - mn.changed = XkbAllMapComponentsMask; - XkbSendMapNotify(pDev, &mn); - } - } + if (!_XkbCopyGeom(src, dst)) { + DebugF("XkbCopyKeymap: failed to copy geometry\n"); + return FALSE; } dst->min_key_code = src->min_key_code; @@ -2201,3 +2088,33 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) return TRUE; } + +Bool +XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src) +{ + xkbNewKeyboardNotify nkn; + Bool ret; + + if (!dst->key || !src->key) + return FALSE; + + memset(&nkn, 0, sizeof(xkbNewKeyboardNotify)); + nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code; + nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code; + nkn.deviceID = dst->id; + nkn.oldDeviceID = dst->id; /* maybe src->id? */ + nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code; + nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code; + nkn.requestMajor = XkbReqCode; + nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */ + nkn.changed = XkbNKN_KeycodesMask; + if (src->key->xkbInfo->desc->geom) + nkn.changed |= XkbNKN_GeometryMask; + + ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc); + if (ret) + XkbSendNewKeyboardNotify(dst, &nkn); + + return ret; +} + |