aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/xkb/xkbUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/xkb/xkbUtils.c')
-rw-r--r--xorg-server/xkb/xkbUtils.c493
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;
+}
+