diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2008-08-01 16:41:08 +0930 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2008-08-06 11:12:24 +0930 |
commit | 5ba87c3327786dd7c6e8e265a19c858e8faae8fd (patch) | |
tree | 2af7804ae16e61ebe73fa6f09851b6dcd6dc89b5 | |
parent | 7e45c80204e06562d4475741caea65bc8758f3c7 (diff) |
xkb: ProcXkbSetNames should work on all attached SDs.
If called with XkbUseCoreKbd, run through all attached SDs and replicate the
call. This way, we keep the SDs in sync with the MD as long as core clients
control the MDs.
-rw-r--r-- | xkb/xkb.c | 624 |
1 files changed, 353 insertions, 271 deletions
@@ -3862,17 +3862,323 @@ char * str; return True; } -/* FIXME: Needs to set names on all core-sending devices. */ -int -ProcXkbSetNames(ClientPtr client) +/** + * Check the device-dependent data in the request against the device. Returns + * Success, or the appropriate error code. + */ +static int +_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, + xkbSetNamesReq *stuff, CARD32 *data) { - DeviceIntPtr dev; XkbDescRec *xkb; XkbNamesRec *names; - xkbNamesNotify nn; CARD32 *tmp; Atom bad; + tmp = data; + xkb = dev->key->xkbInfo->desc; + names = xkb->names; + + + if (stuff->which & XkbKeyTypeNamesMask) { + int i; + CARD32 *old; + if ( stuff->nTypes<1 ) { + client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); + return BadValue; + } + if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { + client->errorValue = _XkbErrCode4(0x03,stuff->firstType, + stuff->nTypes, + xkb->map->num_types); + return BadValue; + } + if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { + client->errorValue = _XkbErrCode2(0x04,stuff->firstType); + return BadAccess; + } + old= tmp; + tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); + if (!tmp) { + client->errorValue= bad; + return BadAtom; + } + for (i=0;i<stuff->nTypes;i++,old++) { + if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) + client->errorValue= _XkbErrCode2(0x05,i); + } + } + if (stuff->which&XkbKTLevelNamesMask) { + unsigned i; + XkbKeyTypePtr type; + CARD8 * width; + if ( stuff->nKTLevels<1 ) { + client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); + return BadValue; + } + if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= + xkb->map->num_types) { + client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, + stuff->nKTLevels,xkb->map->num_types); + return BadValue; + } + width = (CARD8 *)tmp; + tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); + type = &xkb->map->types[stuff->firstKTLevel]; + for (i=0;i<stuff->nKTLevels;i++,type++) { + if (width[i]==0) + continue; + else if (width[i]!=type->num_levels) { + client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, + type->num_levels,width[i]); + return BadMatch; + } + tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); + if (!tmp) { + client->errorValue= bad; + return BadAtom; + } + } + } + if (stuff->which&XkbIndicatorNamesMask) { + if (stuff->indicators==0) { + client->errorValue= 0x08; + return BadMatch; + } + tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, + client->swapped,&bad); + if (!tmp) { + client->errorValue= bad; + return BadAtom; + } + } + if (stuff->which&XkbVirtualModNamesMask) { + if (stuff->virtualMods==0) { + client->errorValue= 0x09; + return BadMatch; + } + tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, + (CARD32)stuff->virtualMods, + client->swapped,&bad); + if (!tmp) { + client->errorValue = bad; + return BadAtom; + } + } + if (stuff->which&XkbGroupNamesMask) { + if (stuff->groupNames==0) { + client->errorValue= 0x0a; + return BadMatch; + } + tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, + (CARD32)stuff->groupNames, + client->swapped,&bad); + if (!tmp) { + client->errorValue = bad; + return BadAtom; + } + } + if (stuff->which&XkbKeyNamesMask) { + if (stuff->firstKey<(unsigned)xkb->min_key_code) { + client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, + stuff->firstKey); + return BadValue; + } + if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| + (stuff->nKeys<1)) { + client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, + stuff->firstKey,stuff->nKeys); + return BadValue; + } + tmp+= stuff->nKeys; + } + if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { + tmp+= stuff->nKeyAliases*2; + } + if (stuff->which&XkbRGNamesMask) { + if ( stuff->nRadioGroups<1 ) { + client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); + return BadValue; + } + tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); + if (!tmp) { + client->errorValue= bad; + return BadAtom; + } + } + if ((tmp-((CARD32 *)stuff))!=stuff->length) { + client->errorValue = stuff->length; + return BadLength; + } + + + + return Success; +} + +static int +_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff) +{ + XkbDescRec *xkb; + XkbNamesRec *names; + CARD32 *tmp; + xkbNamesNotify nn; + + tmp = (CARD32 *)&stuff[1]; + xkb = dev->key->xkbInfo->desc; + names = xkb->names; + + if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, + stuff->nKeyAliases)!=Success) { + return BadAlloc; + } + + bzero(&nn,sizeof(xkbNamesNotify)); + nn.changed= stuff->which; + tmp = (CARD32 *)&stuff[1]; + if (stuff->which&XkbKeycodesNameMask) + names->keycodes= *tmp++; + if (stuff->which&XkbGeometryNameMask) + names->geometry= *tmp++; + if (stuff->which&XkbSymbolsNameMask) + names->symbols= *tmp++; + if (stuff->which&XkbPhysSymbolsNameMask) + names->phys_symbols= *tmp++; + if (stuff->which&XkbTypesNameMask) + names->types= *tmp++; + if (stuff->which&XkbCompatNameMask) + names->compat= *tmp++; + if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { + register unsigned i; + register XkbKeyTypePtr type; + + type= &xkb->map->types[stuff->firstType]; + for (i=0;i<stuff->nTypes;i++,type++) { + type->name= *tmp++; + } + nn.firstType= stuff->firstType; + nn.nTypes= stuff->nTypes; + } + if (stuff->which&XkbKTLevelNamesMask) { + register XkbKeyTypePtr type; + register unsigned i; + CARD8 *width; + + width = (CARD8 *)tmp; + tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); + type= &xkb->map->types[stuff->firstKTLevel]; + for (i=0;i<stuff->nKTLevels;i++,type++) { + if (width[i]>0) { + if (type->level_names) { + register unsigned n; + for (n=0;n<width[i];n++) { + type->level_names[n]= tmp[n]; + } + } + tmp+= width[i]; + } + } + nn.firstLevelName= 0; + nn.nLevelNames= stuff->nTypes; + } + if (stuff->which&XkbIndicatorNamesMask) { + tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, + stuff->indicators); + nn.changedIndicators= stuff->indicators; + } + if (stuff->which&XkbVirtualModNamesMask) { + tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, + stuff->virtualMods); + nn.changedVirtualMods= stuff->virtualMods; + } + if (stuff->which&XkbGroupNamesMask) { + tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, + stuff->groupNames); + nn.changedVirtualMods= stuff->groupNames; + } + if (stuff->which&XkbKeyNamesMask) { + memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, + stuff->nKeys*XkbKeyNameLength); + tmp+= stuff->nKeys; + nn.firstKey= stuff->firstKey; + nn.nKeys= stuff->nKeys; + } + if (stuff->which&XkbKeyAliasesMask) { + if (stuff->nKeyAliases>0) { + register int na= stuff->nKeyAliases; + if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) + return BadAlloc; + memcpy((char *)names->key_aliases,(char *)tmp, + stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); + tmp+= stuff->nKeyAliases*2; + } + else if (names->key_aliases!=NULL) { + _XkbFree(names->key_aliases); + names->key_aliases= NULL; + names->num_key_aliases= 0; + } + nn.nAliases= names->num_key_aliases; + } + if (stuff->which&XkbRGNamesMask) { + if (stuff->nRadioGroups>0) { + register unsigned i,nrg; + nrg= stuff->nRadioGroups; + if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) + return BadAlloc; + + for (i=0;i<stuff->nRadioGroups;i++) { + names->radio_groups[i]= tmp[i]; + } + tmp+= stuff->nRadioGroups; + } + else if (names->radio_groups) { + _XkbFree(names->radio_groups); + names->radio_groups= NULL; + names->num_rg= 0; + } + nn.nRadioGroups= names->num_rg; + } + if (nn.changed) { + Bool needExtEvent; + needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; + XkbSendNamesNotify(dev,&nn); + if (needExtEvent) { + XkbSrvLedInfoPtr sli; + xkbExtensionDeviceNotify edev; + register int i; + register unsigned bit; + + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, + XkbXI_IndicatorsMask); + sli->namesPresent= 0; + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (names->indicators[i]!=None) + sli->namesPresent|= bit; + } + bzero(&edev,sizeof(xkbExtensionDeviceNotify)); + edev.reason= XkbXI_IndicatorNamesMask; + edev.ledClass= KbdFeedbackClass; + edev.ledID= dev->kbdfeed->ctrl.id; + edev.ledsDefined= sli->namesPresent|sli->mapsPresent; + edev.ledState= sli->effectiveState; + edev.firstBtn= 0; + edev.nBtns= 0; + edev.supported= XkbXI_AllFeaturesMask; + edev.unsupported= 0; + XkbSendExtensionDeviceNotify(dev,client,&edev); + } + } + return Success; +} + +int +ProcXkbSetNames(ClientPtr client) +{ + DeviceIntPtr dev; + CARD32 *tmp; + Atom bad; + int rc; + REQUEST(xkbSetNamesReq); REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); @@ -3882,8 +4188,7 @@ ProcXkbSetNames(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); - xkb = dev->key->xkbInfo->desc; - names = xkb->names; + /* check device-independent stuff */ tmp = (CARD32 *)&stuff[1]; if (stuff->which&XkbKeycodesNameMask) { @@ -3928,277 +4233,54 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } - if (stuff->which&XkbKeyTypeNamesMask) { - register int i; - CARD32 *old; - if ( stuff->nTypes<1 ) { - client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); - return BadValue; - } - if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { - client->errorValue = _XkbErrCode4(0x03,stuff->firstType, - stuff->nTypes, - xkb->map->num_types); - return BadValue; - } - if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { - client->errorValue = _XkbErrCode2(0x04,stuff->firstType); - return BadAccess; - } - old= tmp; - tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - for (i=0;i<stuff->nTypes;i++,old++) { - if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) - client->errorValue= _XkbErrCode2(0x05,i); - } - } - if (stuff->which&XkbKTLevelNamesMask) { - register unsigned i; - XkbKeyTypePtr type; - CARD8 * width; - if ( stuff->nKTLevels<1 ) { - client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); - return BadValue; - } - if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= - xkb->map->num_types) { - client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, - stuff->nKTLevels,xkb->map->num_types); - return BadValue; - } - width = (CARD8 *)tmp; - tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); - type = &xkb->map->types[stuff->firstKTLevel]; - for (i=0;i<stuff->nKTLevels;i++,type++) { - if (width[i]==0) - continue; - else if (width[i]!=type->num_levels) { - client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, - type->num_levels,width[i]); - return BadMatch; - } - tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - } - } - if (stuff->which&XkbIndicatorNamesMask) { - if (stuff->indicators==0) { - client->errorValue= 0x08; - return BadMatch; - } - tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, - client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - } - if (stuff->which&XkbVirtualModNamesMask) { - if (stuff->virtualMods==0) { - client->errorValue= 0x09; - return BadMatch; - } - tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, - (CARD32)stuff->virtualMods, - client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbGroupNamesMask) { - if (stuff->groupNames==0) { - client->errorValue= 0x0a; - return BadMatch; - } - tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, - (CARD32)stuff->groupNames, - client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbKeyNamesMask) { - if (stuff->firstKey<(unsigned)xkb->min_key_code) { - client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, - stuff->firstKey); - return BadValue; - } - if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| - (stuff->nKeys<1)) { - client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, - stuff->firstKey,stuff->nKeys); - return BadValue; - } - tmp+= stuff->nKeys; - } - if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { - tmp+= stuff->nKeyAliases*2; - } - if (stuff->which&XkbRGNamesMask) { - if ( stuff->nRadioGroups<1 ) { - client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); - return BadValue; - } - tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - } - if ((tmp-((CARD32 *)stuff))!=stuff->length) { - client->errorValue = stuff->length; - return BadLength; - } - if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, - stuff->nKeyAliases)!=Success) { - return BadAlloc; + + /* start of device-dependent tests */ + rc = _XkbSetNamesCheck(client, dev, stuff, tmp); + if (rc != Success) + return rc; + + if (stuff->deviceSpec == XkbUseCoreKbd) + { + DeviceIntPtr other; + for (other = inputInfo.devices; other; other = other->next) + { + if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) + { + + rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); + if (rc == Success) + { + rc = _XkbSetNamesCheck(client, other, stuff, tmp); + if (rc != Success) + return rc; + } + } + } } /* everything is okay -- update names */ - bzero(&nn,sizeof(xkbNamesNotify)); - nn.changed= stuff->which; - tmp = (CARD32 *)&stuff[1]; - if (stuff->which&XkbKeycodesNameMask) - names->keycodes= *tmp++; - if (stuff->which&XkbGeometryNameMask) - names->geometry= *tmp++; - if (stuff->which&XkbSymbolsNameMask) - names->symbols= *tmp++; - if (stuff->which&XkbPhysSymbolsNameMask) - names->phys_symbols= *tmp++; - if (stuff->which&XkbTypesNameMask) - names->types= *tmp++; - if (stuff->which&XkbCompatNameMask) - names->compat= *tmp++; - if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { - register unsigned i; - register XkbKeyTypePtr type; - type= &xkb->map->types[stuff->firstType]; - for (i=0;i<stuff->nTypes;i++,type++) { - type->name= *tmp++; - } - nn.firstType= stuff->firstType; - nn.nTypes= stuff->nTypes; - } - if (stuff->which&XkbKTLevelNamesMask) { - register XkbKeyTypePtr type; - register unsigned i; - CARD8 *width; - - width = (CARD8 *)tmp; - tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); - type= &xkb->map->types[stuff->firstKTLevel]; - for (i=0;i<stuff->nKTLevels;i++,type++) { - if (width[i]>0) { - if (type->level_names) { - register unsigned n; - for (n=0;n<width[i];n++) { - type->level_names[n]= tmp[n]; - } - } - tmp+= width[i]; - } - } - nn.firstLevelName= 0; - nn.nLevelNames= stuff->nTypes; - } - if (stuff->which&XkbIndicatorNamesMask) { - tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, - stuff->indicators); - nn.changedIndicators= stuff->indicators; - } - if (stuff->which&XkbVirtualModNamesMask) { - tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, - stuff->virtualMods); - nn.changedVirtualMods= stuff->virtualMods; - } - if (stuff->which&XkbGroupNamesMask) { - tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, - stuff->groupNames); - nn.changedVirtualMods= stuff->groupNames; - } - if (stuff->which&XkbKeyNamesMask) { - memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, - stuff->nKeys*XkbKeyNameLength); - tmp+= stuff->nKeys; - nn.firstKey= stuff->firstKey; - nn.nKeys= stuff->nKeys; - } - if (stuff->which&XkbKeyAliasesMask) { - if (stuff->nKeyAliases>0) { - register int na= stuff->nKeyAliases; - if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) - return BadAlloc; - memcpy((char *)names->key_aliases,(char *)tmp, - stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); - tmp+= stuff->nKeyAliases*2; - } - else if (names->key_aliases!=NULL) { - _XkbFree(names->key_aliases); - names->key_aliases= NULL; - names->num_key_aliases= 0; - } - nn.nAliases= names->num_key_aliases; - } - if (stuff->which&XkbRGNamesMask) { - if (stuff->nRadioGroups>0) { - register unsigned i,nrg; - nrg= stuff->nRadioGroups; - if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) - return BadAlloc; + rc = _XkbSetNames(client, dev, stuff); + if (rc != Success) + return rc; - for (i=0;i<stuff->nRadioGroups;i++) { - names->radio_groups[i]= tmp[i]; - } - tmp+= stuff->nRadioGroups; - } - else if (names->radio_groups) { - _XkbFree(names->radio_groups); - names->radio_groups= NULL; - names->num_rg= 0; - } - nn.nRadioGroups= names->num_rg; - } - if (nn.changed) { - Bool needExtEvent; - needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; - XkbSendNamesNotify(dev,&nn); - if (needExtEvent) { - XkbSrvLedInfoPtr sli; - xkbExtensionDeviceNotify edev; - register int i; - register unsigned bit; + if (stuff->deviceSpec == XkbUseCoreKbd) + { + DeviceIntPtr other; + for (other = inputInfo.devices; other; other = other->next) + { + if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) + { - sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, - XkbXI_IndicatorsMask); - sli->namesPresent= 0; - for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - if (names->indicators[i]!=None) - sli->namesPresent|= bit; - } - bzero(&edev,sizeof(xkbExtensionDeviceNotify)); - edev.reason= XkbXI_IndicatorNamesMask; - edev.ledClass= KbdFeedbackClass; - edev.ledID= dev->kbdfeed->ctrl.id; - edev.ledsDefined= sli->namesPresent|sli->mapsPresent; - edev.ledState= sli->effectiveState; - edev.firstBtn= 0; - edev.nBtns= 0; - edev.supported= XkbXI_AllFeaturesMask; - edev.unsupported= 0; - XkbSendExtensionDeviceNotify(dev,client,&edev); - } + rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); + if (rc == Success) + _XkbSetNames(client, other, stuff); + } + } } + + /* everything is okay -- update names */ + return client->noClientException; } |