XkbComponentListPtr XkbListComponents( Display * dpy, unsigned deviceSpec, XkbComponentNamesPtr ptrns, int * max_inout) { register xkbListComponentsReq* req; xkbListComponentsReply rep; XkbInfoPtr xkbi; XkbComponentListPtr list; XkbReadBufferRec buf; int left; char * str; int extraLen,len,mapLen,codesLen,typesLen,compatLen,symsLen,geomLen; if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) || (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || (ptrns==NULL) || (max_inout==NULL)) return NULL; xkbi= dpy->xkb_info; LockDisplay(dpy); GetReq(kbListComponents, req); req->reqType = xkbi->codes->major_opcode; req->xkbReqType = X_kbListComponents; req->deviceSpec = deviceSpec; req->maxNames = *max_inout; mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0; if (ptrns->keymap) mapLen= (int)strlen(ptrns->keymap); if (ptrns->keycodes) codesLen= (int)strlen(ptrns->keycodes); if (ptrns->types) typesLen= (int)strlen(ptrns->types); if (ptrns->compat) compatLen= (int)strlen(ptrns->compat); if (ptrns->symbols) symsLen= (int)strlen(ptrns->symbols); if (ptrns->geometry) geomLen= (int)strlen(ptrns->geometry); if (mapLen>255) mapLen= 255; if (codesLen>255) codesLen= 255; if (typesLen>255) typesLen= 255; if (compatLen>255) compatLen= 255; if (symsLen>255) symsLen= 255; if (geomLen>255) geomLen= 255; len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6; len= XkbPaddedSize(len); req->length+= len/4; BufAlloc(char *,str,len); *str++= mapLen; if (mapLen>0) { memcpy(str,ptrns->keymap,mapLen); str+= mapLen; } *str++= codesLen; if (codesLen>0) { memcpy(str,ptrns->keycodes,codesLen); str+= codesLen; } *str++= typesLen; if (typesLen>0) { memcpy(str,ptrns->types,typesLen); str+= typesLen; } *str++= compatLen; if (compatLen>0) { memcpy(str,ptrns->compat,compatLen); str+= compatLen; } *str++= symsLen; if (symsLen>0) { memcpy(str,ptrns->symbols,symsLen); str+= symsLen; } *str++= geomLen; if (geomLen>0) { memcpy(str,ptrns->geometry,geomLen); str+= geomLen; } if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) goto BAILOUT; extraLen= (int)rep.length*4; *max_inout= rep.extra; if (extraLen==0) { /* no matches, but we don't want to report a failure */ list= _XkbTypedCalloc(1,XkbComponentListRec); UnlockDisplay(dpy); SyncHandle(); return list; } if (_XkbInitReadBuffer(dpy,&buf,extraLen)) { Status status; status= Success; list= _XkbTypedCalloc(1,XkbComponentListRec); if (!list) { _XkbFreeReadBuffer(&buf); goto BAILOUT; } list->num_keymaps= rep.nKeymaps; list->num_keycodes= rep.nKeycodes; list->num_types= rep.nTypes; list->num_compat= rep.nCompatMaps; list->num_symbols= rep.nSymbols; list->num_geometry= rep.nGeometries; if ((status==Success)&&(list->num_keymaps>0)) list->keymaps= _ReadListing(&buf,list->num_keymaps,&status); if ((status==Success)&&(list->num_keycodes>0)) list->keycodes= _ReadListing(&buf,list->num_keycodes,&status); if ((status==Success)&&(list->num_types>0)) list->types= _ReadListing(&buf,list->num_types,&status); if ((status==Success)&&(list->num_compat>0)) list->compat= _ReadListing(&buf,list->num_compat,&status); if ((status==Success)&&(list->num_symbols>0)) list->symbols= _ReadListing(&buf,list->num_symbols,&status); if ((status==Success)&&(list->num_geometry>0)) list->geometry= _ReadListing(&buf,list->num_geometry,&status); left= _XkbFreeReadBuffer(&buf); if ((status!=Success)||(buf.error)||(left>2)) { XkbFreeComponentList(list); goto BAILOUT; } UnlockDisplay(dpy); SyncHandle(); return list; } BAILOUT: UnlockDisplay(dpy); SyncHandle(); return NULL; }
Status XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases) { XkbNamesPtr names; if (xkb==NULL) return BadMatch; if (xkb->names==NULL) { xkb->names = _XkbTypedCalloc(1,XkbNamesRec); if (xkb->names==NULL) return BadAlloc; } names= xkb->names; if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){ register int i; XkbKeyTypePtr type; type= xkb->map->types; for (i=0;i<xkb->map->num_types;i++,type++) { if (type->level_names==NULL) { type->level_names= _XkbTypedCalloc(type->num_levels,Atom); if (type->level_names==NULL) return BadAlloc; } } } if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) { if ((!XkbIsLegalKeycode(xkb->min_key_code))|| (!XkbIsLegalKeycode(xkb->max_key_code))|| (xkb->max_key_code<xkb->min_key_code)) return BadValue; names->keys= _XkbTypedCalloc((xkb->max_key_code+1),XkbKeyNameRec); if (names->keys==NULL) return BadAlloc; } if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) { if (names->key_aliases==NULL) { names->key_aliases= _XkbTypedCalloc(nTotalAliases,XkbKeyAliasRec); } else if (nTotalAliases>names->num_key_aliases) { XkbKeyAliasRec *prev_aliases = names->key_aliases; names->key_aliases= _XkbTypedRealloc(names->key_aliases, nTotalAliases,XkbKeyAliasRec); if (names->key_aliases!=NULL) { _XkbClearElems(names->key_aliases,names->num_key_aliases, nTotalAliases-1,XkbKeyAliasRec); } else { _XkbFree(prev_aliases); } } if (names->key_aliases==NULL) { names->num_key_aliases= 0; return BadAlloc; } names->num_key_aliases= nTotalAliases; } if ((which&XkbRGNamesMask)&&(nTotalRG>0)) { if (names->radio_groups==NULL) { names->radio_groups= _XkbTypedCalloc(nTotalRG,Atom); } else if (nTotalRG>names->num_rg) { Atom *prev_radio_groups = names->radio_groups; names->radio_groups= _XkbTypedRealloc(names->radio_groups,nTotalRG, Atom); if (names->radio_groups!=NULL) { _XkbClearElems(names->radio_groups,names->num_rg,nTotalRG-1, Atom); } else { _XkbFree(prev_radio_groups); } } if (names->radio_groups==NULL) return BadAlloc; names->num_rg= nTotalRG; } return Success; }
Bool XkbInitKeyboardDeviceStruct( DeviceIntPtr dev, XkbComponentNamesPtr names, KeySymsPtr pSymsIn, CARD8 pModsIn[], void (*bellProc)( int /*percent*/, DeviceIntPtr /*device*/, pointer /*ctrl*/, int), void (*ctrlProc)( DeviceIntPtr /*device*/, KeybdCtrl * /*ctrl*/)) { XkbFileInfo finfo; KeySymsRec tmpSyms,*pSyms; CARD8 tmpMods[XkbMaxLegalKeyCode+1],*pMods; char name[PATH_MAX],*rules; Bool ok=False; XPointer config; XkbComponentNamesRec cfgNames; XkbRF_VarDefsRec defs; if ((dev->key!=NULL)||(dev->kbdfeed!=NULL)) return False; pSyms= pSymsIn; pMods= pModsIn; bzero(&defs,sizeof(XkbRF_VarDefsRec)); bzero(&cfgNames,sizeof(XkbComponentNamesRec)); rules= XkbGetRulesDflts(&defs); config= XkbDDXPreloadConfig(&rules,&defs,&cfgNames,dev); /* * The strings are duplicated because it is not guaranteed that * they are allocated, or that they are allocated for every server * generation. Eventually they will be freed at the end of this * function. */ if (names->keymap) names->keymap = _XkbDupString(names->keymap); if (names->keycodes) names->keycodes = _XkbDupString(names->keycodes); if (names->types) names->types = _XkbDupString(names->types); if (names->compat) names->compat = _XkbDupString(names->compat); if (names->geometry) names->geometry = _XkbDupString(names->geometry); if (names->symbols) names->symbols = _XkbDupString(names->symbols); if (defs.model && defs.layout && rules) { XkbComponentNamesRec rNames; bzero(&rNames,sizeof(XkbComponentNamesRec)); if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) { if (rNames.keymap) { if (!names->keymap) names->keymap = rNames.keymap; else _XkbFree(rNames.keymap); } if (rNames.keycodes) { if (!names->keycodes) names->keycodes = rNames.keycodes; else _XkbFree(rNames.keycodes); } if (rNames.types) { if (!names->types) names->types = rNames.types; else _XkbFree(rNames.types); } if (rNames.compat) { if (!names->compat) names->compat = rNames.compat; else _XkbFree(rNames.compat); } if (rNames.symbols) { if (!names->symbols) names->symbols = rNames.symbols; else _XkbFree(rNames.symbols); } if (rNames.geometry) { if (!names->geometry) names->geometry = rNames.geometry; else _XkbFree(rNames.geometry); } XkbSetRulesUsed(&defs); } } if (cfgNames.keymap){ if (names->keymap) _XkbFree(names->keymap); names->keymap= cfgNames.keymap; } if (cfgNames.keycodes){ if (names->keycodes) _XkbFree(names->keycodes); names->keycodes= cfgNames.keycodes; } if (cfgNames.types) { if (names->types) _XkbFree(names->types); names->types= cfgNames.types; } if (cfgNames.compat) { if (names->compat) _XkbFree(names->compat); names->compat= cfgNames.compat; } if (cfgNames.symbols){ if (names->symbols) _XkbFree(names->symbols); names->symbols= cfgNames.symbols; } if (cfgNames.geometry) { if (names->geometry) _XkbFree(names->geometry); names->geometry= cfgNames.geometry; } if (names->keymap) { XkbComponentNamesRec tmpNames; bzero(&tmpNames,sizeof(XkbComponentNamesRec)); tmpNames.keymap = names->keymap; ok = (Bool) XkbDDXLoadKeymapByNames(dev,&tmpNames,XkmAllIndicesMask,0, &finfo,name,PATH_MAX); } if (!(ok && (finfo.xkb!=NULL))) ok = (Bool) XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0, &finfo,name,PATH_MAX); if (ok && (finfo.xkb!=NULL)) { XkbDescPtr xkb; KeyCode minKC,maxKC; xkb= finfo.xkb; minKC= xkb->min_key_code; maxKC= xkb->max_key_code; if (XkbIsLegalKeycode(minKC)&&XkbIsLegalKeycode(maxKC)&&(minKC<=maxKC)&& ((minKC!=pSyms->minKeyCode)||(maxKC!=pSyms->maxKeyCode))) { if (xkb->map!=NULL) { KeySym *inSym,*outSym; int width= pSymsIn->mapWidth; tmpSyms.minKeyCode= minKC; tmpSyms.maxKeyCode= maxKC; if (minKC<pSymsIn->minKeyCode) minKC= pSymsIn->minKeyCode; if (maxKC>pSymsIn->maxKeyCode) maxKC= pSymsIn->maxKeyCode; tmpSyms.mapWidth= width; tmpSyms.map= _XkbTypedCalloc(width*XkbNumKeys(xkb),KeySym); inSym= &pSymsIn->map[(minKC-pSymsIn->minKeyCode)*width]; outSym= &tmpSyms.map[(minKC-tmpSyms.minKeyCode)*width]; memcpy(outSym,inSym,((maxKC-minKC+1)*width)*sizeof(KeySym)); pSyms= &tmpSyms; } if ((xkb->map!=NULL)&&(xkb->map->modmap!=NULL)) { bzero(tmpMods,XkbMaxKeyCount); memcpy(tmpMods,xkb->map->modmap,maxKC+1); pMods= tmpMods; } } _XkbInitFileInfo= &finfo; } else { LogMessage(X_WARNING, "Couldn't load XKB keymap, falling back to pre-XKB keymap\n"); } ok= InitKeyboardDeviceStruct((DevicePtr)dev,pSyms,pMods,bellProc,ctrlProc); if ((config!=NULL)&&(dev && dev->key && dev->key->xkbInfo)) XkbDDXApplyConfig(config,dev->key->xkbInfo); _XkbInitFileInfo= NULL; if ((pSyms==&tmpSyms)&&(pSyms->map!=NULL)) { _XkbFree(pSyms->map); pSyms->map= NULL; } if (names->keymap) _XkbFree(names->keymap); names->keymap = NULL; if (names->keycodes) _XkbFree(names->keycodes); names->keycodes = NULL; if (names->types) _XkbFree(names->types); names->types = NULL; if (names->compat) _XkbFree(names->compat); names->compat = NULL; if (names->geometry) _XkbFree(names->geometry); names->geometry = NULL; if (names->symbols) _XkbFree(names->symbols); names->symbols = NULL; return ok; }
Status XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes) { register int i; XkbClientMapPtr map; if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes))) return BadValue; if ((which&XkbKeySymsMask)&& ((!XkbIsLegalKeycode(xkb->min_key_code))|| (!XkbIsLegalKeycode(xkb->max_key_code))|| (xkb->max_key_code<xkb->min_key_code))) { #ifdef DEBUG fprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n", xkb->min_key_code,xkb->max_key_code); #endif return BadValue; } if (xkb->map==NULL) { map= _XkbTypedCalloc(1,XkbClientMapRec); if (map==NULL) return BadAlloc; xkb->map= map; } else map= xkb->map; if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) { if (map->types==NULL) { map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec); if (map->types==NULL) return BadAlloc; map->num_types= 0; map->size_types= nTotalTypes; } else if (map->size_types<nTotalTypes) { XkbKeyTypeRec *prev_types = map->types; map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec); if (map->types==NULL) { _XkbFree(prev_types); map->num_types= map->size_types= 0; return BadAlloc; } map->size_types= nTotalTypes; bzero(&map->types[map->num_types], ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec))); } } if (which&XkbKeySymsMask) { int nKeys= XkbNumKeys(xkb); if (map->syms==NULL) { map->size_syms= (nKeys*15)/10; map->syms= _XkbTypedCalloc(map->size_syms,KeySym); if (!map->syms) { map->size_syms= 0; return BadAlloc; } map->num_syms= 1; map->syms[0]= NoSymbol; } if (map->key_sym_map==NULL) { i= xkb->max_key_code+1; map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec); if (map->key_sym_map==NULL) return BadAlloc; } } if (which&XkbModifierMapMask) { if ((!XkbIsLegalKeycode(xkb->min_key_code))|| (!XkbIsLegalKeycode(xkb->max_key_code))|| (xkb->max_key_code<xkb->min_key_code)) return BadMatch; if (map->modmap==NULL) { i= xkb->max_key_code+1; map->modmap= _XkbTypedCalloc(i,unsigned char); if (map->modmap==NULL) return BadAlloc; } }
void XkbInitDevice(DeviceIntPtr pXDev) { int i; XkbSrvInfoPtr xkbi; XkbChangesRec changes; SrvXkmInfo file; unsigned check; XkbEventCauseRec cause; file.dev= pXDev; file.file=NULL; bzero(&file.xkbinfo,sizeof(XkbFileInfo)); bzero(&changes,sizeof(XkbChangesRec)); if (XkbAutoLoad && (XkbInitialMap!=NULL)) { if ((file.file=XkbDDXOpenConfigFile(XkbInitialMap,NULL,0))!=NULL) { XkmReadFile(file.file,0,XkmKeymapLegal,&file.xkbinfo); if (file.xkbinfo.xkb==NULL) { LogMessage(X_ERROR, "Error loading keymap file %s (%s in %s)\n" "\treverting to defaults\n", XkbInitialMap, _XkbErrMessages[_XkbErrCode], (_XkbErrLocation?_XkbErrLocation:"unknown")); fclose(file.file); file.file= NULL; bzero(&file.xkbinfo,sizeof(XkbFileInfo)); } else { if (_XkbInitFileInfo!=NULL) { XkbDescPtr tmp; if ((tmp=_XkbInitFileInfo->xkb)!=NULL) { XkbFreeKeyboard(tmp,XkbAllComponentsMask,True); _XkbInitFileInfo->xkb= NULL; } } _XkbInitFileInfo= &file.xkbinfo; } } else { LogMessage(X_ERROR, "Error opening keymap file %s, reverting to defaults\n", XkbInitialMap); } } pXDev->key->xkbInfo= xkbi= _XkbTypedCalloc(1,XkbSrvInfoRec); if ( xkbi ) { XkbDescPtr xkb; if ((_XkbInitFileInfo!=NULL)&&(_XkbInitFileInfo->xkb!=NULL)) { file.xkbinfo= *_XkbInitFileInfo; xkbi->desc= _XkbInitFileInfo->xkb; _XkbInitFileInfo= NULL; } else { xkbi->desc= XkbAllocKeyboard(); if (!xkbi->desc) FatalError("Couldn't allocate keyboard description\n"); xkbi->desc->min_key_code = pXDev->key->curKeySyms.minKeyCode; xkbi->desc->max_key_code = pXDev->key->curKeySyms.maxKeyCode; } xkb= xkbi->desc; if (xkb->min_key_code == 0) xkb->min_key_code = pXDev->key->curKeySyms.minKeyCode; if (xkb->max_key_code == 0) xkb->max_key_code = pXDev->key->curKeySyms.maxKeyCode; if ((pXDev->key->curKeySyms.minKeyCode!=xkbi->desc->min_key_code)|| (pXDev->key->curKeySyms.maxKeyCode!=xkbi->desc->max_key_code)) { /* 12/9/95 (ef) -- XXX! Maybe we should try to fix up one or */ /* the other here, but for now just complain */ /* can't just update the core range without */ /* reallocating the KeySymsRec (pain) */ ErrorF("Internal Error!! XKB and core keymap have different range\n"); } if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) FatalError("Couldn't allocate client map in XkbInitDevice\n"); i= XkbNumKeys(xkb)/3+1; if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,i)!=Success) FatalError("Couldn't allocate server map in XkbInitDevice\n"); xkbi->dfltPtrDelta=1; xkbi->device = pXDev; file.xkbinfo.xkb= xkb; XkbInitSemantics(xkb,&file); XkbInitNames(xkbi,&file); XkbInitRadioGroups(xkbi,&file); /* 12/31/94 (ef) -- XXX! Should check if state loaded from file */ bzero(&xkbi->state,sizeof(XkbStateRec)); XkbInitControls(pXDev,xkbi,&file); if (file.xkbinfo.defined&XkmSymbolsMask) memcpy(pXDev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1); else memcpy(xkb->map->modmap,pXDev->key->modifierMap,xkb->max_key_code+1); XkbInitIndicatorMap(xkbi,&file); XkbDDXInitDevice(pXDev); if (!(file.xkbinfo.defined&XkmSymbolsMask)) { XkbUpdateKeyTypesFromCore(pXDev,xkb->min_key_code,XkbNumKeys(xkb), &changes); } else { XkbUpdateCoreDescription(pXDev,True); } XkbSetCauseUnknown(&cause); XkbUpdateActions(pXDev,xkb->min_key_code, XkbNumKeys(xkb),&changes, &check,&cause); /* For sanity. The first time the connection * is opened, the client side min and max are set * using QueryMinMaxKeyCodes() which grabs them * from pXDev. */ pXDev->key->curKeySyms.minKeyCode = xkb->min_key_code; pXDev->key->curKeySyms.maxKeyCode = xkb->max_key_code; } if (file.file!=NULL) fclose(file.file); return; }