KeySym XkbKeycodeToKeysym(Display *dpy, #if NeedWidePrototypes unsigned int kc, #else KeyCode kc, #endif int group, int level) { XkbDescRec *xkb; if (_XkbUnavailable(dpy)) return NoSymbol; _XkbCheckPendingRefresh(dpy,dpy->xkb_info); xkb = dpy->xkb_info->desc; if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code)) return NoSymbol; if ((group<0)||(level<0)||(group>=XkbKeyNumGroups(xkb,kc))) return NoSymbol; if (level>=XkbKeyGroupWidth(xkb,kc,group)) { /* for compatibility with the core protocol, _always_ allow */ /* two symbols in the first two groups. If either of the */ /* two is of type ONE_LEVEL, just replicate the first symbol */ if ((group>XkbGroup2Index)||(XkbKeyGroupWidth(xkb,kc,group)!=1)|| (level!=1)) { return NoSymbol; } level= 0; } return XkbKeySymEntry(xkb,kc,level,group); }
unsigned XkbKeysymToModifiers(Display *dpy,KeySym ks) { XkbDescRec *xkb; register int i,j; register KeySym *pSyms; CARD8 mods; if (_XkbUnavailable(dpy)) return _XKeysymToModifiers(dpy,ks); _XkbCheckPendingRefresh(dpy,dpy->xkb_info); if (_XkbNeedModmap(dpy->xkb_info)&&(!_XkbComputeModmap(dpy))) return _XKeysymToModifiers(dpy,ks); xkb= dpy->xkb_info->desc; mods= 0; for (i = xkb->min_key_code; i <= (int)xkb->max_key_code; i++) { pSyms= XkbKeySymsPtr(xkb,i); for (j=XkbKeyNumSyms(xkb,i)-1;j>=0;j--) { if (pSyms[j]==ks) { mods|= xkb->map->modmap[i]; break; } } } return mods; }
KeySym XLookupKeysym(register XKeyEvent *event, int col) { Display *dpy = event->display; if (_XkbUnavailable(dpy)) return _XLookupKeysym(event, col); _XkbCheckPendingRefresh(dpy,dpy->xkb_info); return XKeycodeToKeysym(dpy, event->keycode, col); }
Bool XkbLookupKeySym( register Display * dpy, KeyCode key, register unsigned int mods, unsigned int * mods_rtrn, KeySym * keysym_rtrn) { if (_XkbUnavailable(dpy)) return _XTranslateKey(dpy, key, mods, mods_rtrn, keysym_rtrn); _XkbCheckPendingRefresh(dpy,dpy->xkb_info); return XkbTranslateKeyCode(dpy->xkb_info->desc,key,mods,mods_rtrn, keysym_rtrn); }
KeySym XKeycodeToKeysym(Display *dpy, #if NeedWidePrototypes unsigned int kc, #else KeyCode kc, #endif int col) { XkbDescRec *xkb; if (_XkbUnavailable(dpy)) return _XKeycodeToKeysym(dpy, kc, col); _XkbCheckPendingRefresh(dpy,dpy->xkb_info); xkb = dpy->xkb_info->desc; if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code)) return NoSymbol; if (col>3) { int lastSym,tmp,nGrp; lastSym= 3; nGrp= XkbKeyNumGroups(xkb,kc); if ((nGrp>0)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup1Index))>2)) { if (col<=(lastSym+tmp-2)) return XkbKeycodeToKeysym(dpy,kc,XkbGroup1Index,col-lastSym+2); lastSym+= tmp-2; } if ((nGrp>1)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup2Index))>2)) { if (col<=(lastSym+tmp-2)) return XkbKeycodeToKeysym(dpy,kc,XkbGroup2Index,col-lastSym+2); lastSym+= tmp-2; } if (nGrp>2) { tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup3Index); if (col<=lastSym+tmp) return XkbKeycodeToKeysym(dpy,kc,XkbGroup3Index,col-lastSym); lastSym+= tmp; } if (nGrp>3) { tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup4Index); if (col<=lastSym+tmp) return XkbKeycodeToKeysym(dpy,kc,XkbGroup4Index,col-lastSym); } return NoSymbol; } return XkbKeycodeToKeysym(dpy,kc,(col>>1),(col&1)); }
void _XkbReloadDpy(Display *dpy) { XkbInfoPtr xkbi; XkbDescRec *desc; unsigned oldDeviceID; if (_XkbUnavailable(dpy)) return; xkbi = dpy->xkb_info; LockDisplay(dpy); if (xkbi->desc) { oldDeviceID= xkbi->desc->device_spec; XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True); xkbi->desc= NULL; xkbi->flags&= ~(XkbMapPending|XkbXlibNewKeyboard); xkbi->changes.changed= 0; } else oldDeviceID= XkbUseCoreKbd; UnlockDisplay(dpy); desc = XkbGetMap(dpy,XkbAllClientInfoMask,XkbUseCoreKbd); if (!desc) return; LockDisplay(dpy); xkbi->desc = desc; UnlockDisplay(dpy); if (desc->device_spec!=oldDeviceID) { /* transfer(?) event masks here */ #ifdef NOTYET unsigned oldEvents; oldEvents= xkbi->selected_events; XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbMapNotify, XkbAllMapComponentsMask,XkbAllClientInfoMask); LockDisplay(dpy); xkbi->selected_events= oldEvents; UnlockDisplay(dpy); #endif } return; }
Status XkbRefreshKeyboardMapping(register XkbMapNotifyEvent *event) { Display *dpy = event->display; XkbInfoPtr xkbi; if (_XkbUnavailable(dpy)) { _XRefreshKeyboardMapping((XMappingEvent *)event); return Success; } xkbi= dpy->xkb_info; if (((event->type&0x7f)-xkbi->codes->first_event)!=XkbEventCode) return BadMatch; if (event->xkb_type==XkbNewKeyboardNotify) { _XkbReloadDpy(dpy); return Success; } if (event->xkb_type==XkbMapNotify) { XkbMapChangesRec changes; Status rtrn; if (xkbi->flags&XkbMapPending) changes= xkbi->changes; else bzero(&changes,sizeof(changes)); XkbNoteMapChanges(&changes,event,XKB_XLIB_MAP_MASK); LockDisplay(dpy); if ((rtrn=XkbGetMapChanges(dpy,xkbi->desc,&changes))!=Success) { #ifdef DEBUG fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n"); #endif xkbi->changes= changes; } else if (xkbi->flags&XkbMapPending) { xkbi->flags&= ~XkbMapPending; bzero(&xkbi->changes,sizeof(XkbMapChangesRec)); } UnlockDisplay(dpy); return rtrn; } return BadMatch; }
KeyCode XKeysymToKeycode(Display *dpy, KeySym ks) { register int i, j, gotOne; if (_XkbUnavailable(dpy)) return _XKeysymToKeycode(dpy,ks); _XkbCheckPendingRefresh(dpy,dpy->xkb_info); j= 0; do { register XkbDescRec *xkb = dpy->xkb_info->desc; gotOne= 0; for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { if ( j<(int)XkbKeyNumSyms(xkb,i) ) { gotOne = 1; if ((XkbKeySym(xkb,i,j)==ks)) return i; } } j++; } while (gotOne); return 0; }
int XLookupString ( register XKeyEvent * event, char * buffer, int nbytes, KeySym * keysym, XComposeStatus * status) { KeySym dummy; int rtrnLen; unsigned int new_mods; Display *dpy = event->display; if (keysym==NULL) keysym= &dummy; if (!XkbLookupKeySym(dpy,event->keycode,event->state, &new_mods,keysym)) return 0; new_mods= (event->state&(~new_mods)); /* find the group where a symbol can be converted to control one */ if (new_mods&ControlMask && *keysym > 0x7F && (dpy->xkb_info->xlib_ctrls & XkbLC_ControlFallback)) { XKeyEvent tmp_ev = *event; KeySym tmp_keysym; unsigned int tmp_new_mods; if (_XkbUnavailable(dpy)) { tmp_ev.state= event->state ^ dpy->mode_switch; if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state, &tmp_new_mods, &tmp_keysym) && tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) { *keysym = tmp_keysym; } } else { int n = XkbKeyNumGroups(dpy->xkb_info->desc, tmp_ev.keycode); int i; for (i = 0; i < n; i++) { if (XkbGroupForCoreState(event->state) == i) continue; tmp_ev.state= XkbBuildCoreState(tmp_ev.state, i); if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state, &tmp_new_mods, &tmp_keysym) && tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) { *keysym = tmp_keysym; new_mods= (event->state&(~tmp_new_mods)); break; } } } } #ifdef USE_OWN_COMPOSE if ( status ) { static int been_here= 0; if ( !been_here ) { XimCompInitTables(); been_here = 1; } if ( !XimCompLegalStatus(status) ) { status->compose_ptr = NULL; status->chars_matched = 0; } if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) || XimCompIsComposeKey(*keysym,event->keycode,status) ) { XimCompRtrn rtrn; switch (XimCompProcessSym(status,*keysym,&rtrn)) { case XIM_COMP_IGNORE: break; case XIM_COMP_IN_PROGRESS: if ( keysym!=NULL ) *keysym = NoSymbol; #ifndef NO_COMPOSE_LED if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) { XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED, True,True,False,NULL); } #endif return 0; case XIM_COMP_FAIL: { static Atom _ComposeFail= None; int n = 0, len= 0; #ifndef NO_COMPOSE_LED if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) { XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED, True,False,False,NULL); } #endif #ifndef NO_BELL_ON_COMPOSE_FAIL if (dpy->xkb_info->xlib_ctrls&XkbLC_BeepOnComposeFail) { if (_ComposeFail==None) _ComposeFail= XInternAtom(dpy,"ComposeFail",0); XkbBell(dpy,event->window,0,_ComposeFail); } #endif for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { if ( nbytes-len > 0 ) { len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],new_mods, buffer+len,nbytes-len, NULL); } } if ( keysym!=NULL ) { if ( n==1 ) *keysym = rtrn.sym[0]; else *keysym = NoSymbol; } return len; } case XIM_COMP_SUCCEED: { int len,n = 0; #ifndef NO_COMPOSE_LED if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) { XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED, True,False,False,NULL); } #endif *keysym = rtrn.matchSym; if ( rtrn.str[0]!='\0' ) { strncpy(buffer,rtrn.str,nbytes-1); buffer[nbytes-1]= '\0'; len = (int)strlen(buffer); } else { len = XkbTranslateKeySym(dpy,keysym,new_mods, buffer,nbytes, NULL); } for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { if ( nbytes-len > 0 ) { len+= XkbTranslateKeySym(dpy,&rtrn.sym[n], event->state, buffer+len,nbytes-len, NULL); } } return len; } } } } #endif /* We *should* use the new_mods (which does not contain any modifiers */ /* that were used to compute the symbol here, but pre-XKB XLookupString */ /* did not and we have to remain compatible. Sigh. */ if (_XkbUnavailable(dpy) || (dpy->xkb_info->xlib_ctrls&XkbLC_ConsumeLookupMods)==0) new_mods= event->state; rtrnLen= XkbLookupKeyBinding(dpy,*keysym,new_mods,buffer,nbytes,NULL); if (rtrnLen>0) return rtrnLen; return XkbTranslateKeySym(dpy,keysym,new_mods,buffer,nbytes,NULL); }
int XRefreshKeyboardMapping(register XMappingEvent *event) { XkbEvent *xkbevent = (XkbEvent *)event; Display *dpy = event->display; XkbMapChangesRec changes; XkbInfoPtr xkbi; /* always do this for input methods, which still use the old keymap */ (void) _XRefreshKeyboardMapping(event); if (_XkbUnavailable(dpy)) return 1; xkbi = dpy->xkb_info; if (((event->type&0x7f)-xkbi->codes->first_event)==XkbEventCode) return XkbRefreshKeyboardMapping(&xkbevent->map); if (xkbi->flags&XkbXlibNewKeyboard) { _XkbReloadDpy(dpy); return 1; } if ((xkbi->flags&XkbMapPending)||(event->request==MappingKeyboard)) { if (xkbi->flags&XkbMapPending) { changes= xkbi->changes; _XkbNoteCoreMapChanges(&changes,event,XKB_XLIB_MAP_MASK); } else { bzero(&changes,sizeof(changes)); changes.changed= XkbKeySymsMask; if (xkbi->desc->min_key_code<xkbi->desc->max_key_code) { changes.first_key_sym= xkbi->desc->min_key_code; changes.num_key_syms= xkbi->desc->max_key_code- xkbi->desc->min_key_code+1; } else { changes.first_key_sym= event->first_keycode; changes.num_key_syms= event->count; } } if (XkbGetMapChanges(dpy,xkbi->desc, &changes)!=Success) { #ifdef DEBUG fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n"); if (changes.changed&XkbKeyTypesMask) { int first= changes.first_type; int last= changes.first_type+changes.num_types-1; fprintf(stderr," types: %d..%d\n",first,last); } if (changes.changed&XkbKeySymsMask) { int first= changes.first_key_sym; int last= changes.first_key_sym+changes.num_key_syms-1; fprintf(stderr," symbols: %d..%d\n",first,last); } if (changes.changed&XkbKeyActionsMask) { int last,first= changes.first_key_act; last= changes.first_key_act+changes.num_key_acts-1; fprintf(stderr," acts: %d..%d\n",first,last); } if (changes.changed&XkbKeyBehaviorsMask) { int last,first= changes.first_key_behavior; last= first+changes.num_key_behaviors-1; fprintf(stderr," behaviors: %d..%d\n",first,last); } if (changes.changed&XkbVirtualModsMask) { fprintf(stderr,"virtual mods: 0x%04x\n", changes.vmods); } if (changes.changed&XkbExplicitComponentsMask) { int last,first= changes.first_key_explicit; last= first+changes.num_key_explicit-1; fprintf(stderr," explicit: %d..%d\n",first,last); } #endif } LockDisplay(dpy); if (xkbi->flags&XkbMapPending) { xkbi->flags&= ~XkbMapPending; bzero(&xkbi->changes,sizeof(XkbMapChangesRec)); } UnlockDisplay(dpy); } if (event->request==MappingModifier) { LockDisplay(dpy); if (xkbi->desc->map->modmap) { _XkbFree(xkbi->desc->map->modmap); xkbi->desc->map->modmap= NULL; } if (dpy->key_bindings) { register struct _XKeytrans *p; for (p = dpy->key_bindings; p; p = p->next) { register int i; p->state= 0; if (p->mlen>0) { for (i = 0; i < p->mlen; i++) { p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); } if (p->state) p->state &= AllMods; else p->state = AnyModifier; } } } UnlockDisplay(dpy); } return 1; }