_X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo, BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func) { int i; unsigned int check; XkbSrvInfoPtr xkbi; XkbDescPtr xkb; XkbSrvLedInfoPtr sli; XkbChangesRec changes; XkbEventCauseRec cause; XkbRMLVOSet rmlvo_dflts = { NULL }; if (dev->key || dev->kbdfeed) return FALSE; if (!rmlvo) { rmlvo = &rmlvo_dflts; XkbGetRulesDflts(rmlvo); } memset(&changes, 0, sizeof(changes)); XkbSetCauseUnknown(&cause); dev->key = calloc(1, sizeof(*dev->key)); if (!dev->key) { ErrorF("XKB: Failed to allocate key class\n"); return FALSE; } dev->key->sourceid = dev->id; dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed)); if (!dev->kbdfeed) { ErrorF("XKB: Failed to allocate key feedback class\n"); goto unwind_key; } xkbi = calloc(1, sizeof(*xkbi)); if (!xkbi) { ErrorF("XKB: Failed to allocate XKB info\n"); goto unwind_kbdfeed; } dev->key->xkbInfo = xkbi; if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) { XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE); xkb_cached_map = NULL; } if (xkb_cached_map) LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n"); else { xkb_cached_map = XkbCompileKeymap(dev, rmlvo); if (!xkb_cached_map) { ErrorF("XKB: Failed to compile keymap\n"); goto unwind_info; } } xkb = XkbAllocKeyboard(); if (!xkb) { ErrorF("XKB: Failed to allocate keyboard description\n"); goto unwind_info; } if (!XkbCopyKeymap(xkb, xkb_cached_map)) { ErrorF("XKB: Failed to copy keymap\n"); goto unwind_desc; } xkb->defined = xkb_cached_map->defined; xkb->flags = xkb_cached_map->flags; xkb->device_spec = xkb_cached_map->device_spec; xkbi->desc = xkb; if (xkb->min_key_code == 0) xkb->min_key_code = 8; if (xkb->max_key_code == 0) xkb->max_key_code = 255; i = XkbNumKeys(xkb) / 3 + 1; if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success) goto unwind_desc; if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success) goto unwind_desc; xkbi->dfltPtrDelta = 1; xkbi->device = dev; XkbInitSemantics(xkb); XkbInitNames(xkbi); XkbInitRadioGroups(xkbi); XkbInitControls(dev, xkbi); XkbInitIndicatorMap(xkbi); XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes, &check, &cause); InitFocusClassDeviceStruct(dev); xkbi->kbdProc = ctrl_func; dev->kbdfeed->BellProc = bell_func; dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc; dev->kbdfeed->ctrl = defaultKeyboardControl; if (dev->kbdfeed->ctrl.autoRepeat) xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask; memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat, XkbPerKeyBitArraySize); sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0); if (sli) XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask); else DebugF("XKB: No indicator feedback in XkbFinishInit!\n"); dev->kbdfeed->CtrlProc(dev,&dev->kbdfeed->ctrl); XkbSetRulesDflts(rmlvo); XkbSetRulesUsed(rmlvo); XkbFreeRMLVOSet(&rmlvo_dflts, FALSE); return TRUE; unwind_desc: XkbFreeKeyboard(xkb, 0, TRUE); unwind_info: free(xkbi); dev->key->xkbInfo = NULL; unwind_kbdfeed: free(dev->kbdfeed); dev->kbdfeed = NULL; unwind_key: free(dev->key); dev->key = NULL; return FALSE; }
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; }