static CARD32 AccessXTimeoutExpire(OsTimerPtr timer,CARD32 now,pointer arg) { DeviceIntPtr dev = (DeviceIntPtr)arg; XkbSrvInfoPtr xkbi= dev->key->xkbInfo; XkbControlsPtr ctrls= xkbi->desc->ctrls; XkbControlsRec old; xkbControlsNotify cn; XkbEventCauseRec cause; XkbSrvLedInfoPtr sli; if (xkbi->lastPtrEventTime) { unsigned timeToWait = (ctrls->ax_timeout*1000); unsigned timeElapsed = (now-xkbi->lastPtrEventTime); if (timeToWait > timeElapsed) return (timeToWait - timeElapsed); } old= *ctrls; xkbi->shiftKeyCount= 0; ctrls->enabled_ctrls&= ~ctrls->axt_ctrls_mask; ctrls->enabled_ctrls|= (ctrls->axt_ctrls_values&ctrls->axt_ctrls_mask); if (ctrls->axt_opts_mask) { ctrls->ax_options&= ~ctrls->axt_opts_mask; ctrls->ax_options|= (ctrls->axt_opts_values&ctrls->axt_opts_mask); } if (XkbComputeControlsNotify(dev,&old,ctrls,&cn,False)) { cn.keycode = 0; cn.eventType = 0; cn.requestMajor = 0; cn.requestMinor = 0; XkbSendControlsNotify(dev,&cn); } XkbSetCauseUnknown(&cause); sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause); if (ctrls->ax_options!=old.ax_options) { unsigned set,cleared,bell; set= ctrls->ax_options&(~old.ax_options); cleared= (~ctrls->ax_options)&old.ax_options; if (set && cleared) bell= _BEEP_FEATURE_CHANGE; else if (set) bell= _BEEP_FEATURE_ON; else bell= _BEEP_FEATURE_OFF; XkbDDXAccessXBeep(dev,bell,XkbAccessXTimeoutMask); } xkbi->krgTimerActive= _OFF_TIMER; return 0; }
_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; }
KeyCode vncAddKeysym(KeySym keysym, unsigned state) { DeviceIntPtr master; XkbDescPtr xkb; unsigned int key; XkbEventCauseRec cause; XkbChangesRec changes; int types[1]; KeySym *syms; KeySym upper, lower; master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); xkb = master->key->xkbInfo->desc; for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) { if (XkbKeyNumGroups(xkb, key) == 0) break; } if (key < xkb->min_key_code) return 0; memset(&changes, 0, sizeof(changes)); memset(&cause, 0, sizeof(cause)); XkbSetCauseUnknown(&cause); /* * Tools like xkbcomp get confused if there isn't a name * assigned to the keycode we're trying to use. */ if (xkb->names && xkb->names->keys && (xkb->names->keys[key].name[0] == '\0')) { xkb->names->keys[key].name[0] = 'I'; xkb->names->keys[key].name[1] = '0' + (key / 100) % 10; xkb->names->keys[key].name[2] = '0' + (key / 10) % 10; xkb->names->keys[key].name[3] = '0' + (key / 1) % 10; changes.names.changed |= XkbKeyNamesMask; changes.names.first_key = key; changes.names.num_keys = 1; } /* FIXME: Verify that ONE_LEVEL/ALPHABETIC isn't screwed up */ /* * For keysyms that are affected by Lock, we are better off * using ALPHABETIC rather than ONE_LEVEL as the latter * generally cannot produce lower case when Lock is active. */ XkbConvertCase(keysym, &lower, &upper); if (upper == lower) types[XkbGroup1Index] = XkbOneLevelIndex; else types[XkbGroup1Index] = XkbAlphabeticIndex; XkbChangeTypesOfKey(xkb, key, 1, XkbGroup1Mask, types, &changes.map); syms = XkbKeySymsPtr(xkb,key); if (upper == lower) syms[0] = keysym; else { syms[0] = lower; syms[1] = upper; } changes.map.changed |= XkbKeySymsMask; changes.map.first_key_sym = key; changes.map.num_key_syms = 1; XkbSendNotification(master, &changes, &cause); return key; }
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; }