int main(int, char **) { Display *display = 0; int opcode = -1; int xkbEventBase = -1; int xkbErrorBase = -1; int xkblibMajor = XkbMajorVersion; int xkblibMinor = XkbMinorVersion; XkbQueryExtension(display, &opcode, &xkbEventBase, &xkbErrorBase, &xkblibMajor, &xkblibMinor); int keycode = 0; unsigned int state = 0; KeySym keySym; unsigned int consumedModifiers; XkbLookupKeySym(display, keycode, state, &consumedModifiers, &keySym); XkbDescPtr xkbDesc = XkbGetMap(display, XkbAllClientInfoMask, XkbUseCoreKbd); int w = XkbKeyGroupsWidth(xkbDesc, keycode); keySym = XkbKeySym(xkbDesc, keycode, w-1); XkbFreeClientMap(xkbDesc, XkbAllClientInfoMask, true); state = XkbPCF_GrabsUseXKBStateMask; (void) XkbSetPerClientControls(display, state, &state); return 0; }
int XkbTranslateKey( register Display * dpy, KeyCode key, register unsigned int mods, unsigned int * mods_rtrn, KeySym * keysym_rtrn) { return XkbLookupKeySym(dpy,key,mods,mods_rtrn,keysym_rtrn); }
static unsigned int keysym_mod_mask (KeySym keysym, KeyCode keycode) { /* we really should use XKB and look directly at the keymap */ /* this is very inelegant */ Display *display = spi_get_display (); unsigned int mods_rtn = 0; unsigned int retval = 0; KeySym sym_rtn; if (XkbLookupKeySym (display, keycode, 0, &mods_rtn, &sym_rtn) && (sym_rtn == keysym)) { retval = 0; } else if (XkbLookupKeySym (display, keycode, ShiftMask, &mods_rtn, &sym_rtn) && (sym_rtn == keysym)) { retval = ShiftMask; } else if (XkbLookupKeySym (display, keycode, Mod2Mask, &mods_rtn, &sym_rtn) && (sym_rtn == keysym)) { retval = Mod2Mask; } else if (XkbLookupKeySym (display, keycode, Mod3Mask, &mods_rtn, &sym_rtn) && (sym_rtn == keysym)) { retval = Mod3Mask; } else if (XkbLookupKeySym (display, keycode, ShiftMask | Mod2Mask, &mods_rtn, &sym_rtn) && (sym_rtn == keysym)) { retval = (Mod2Mask | ShiftMask); } else if (XkbLookupKeySym (display, keycode, ShiftMask | Mod3Mask, &mods_rtn, &sym_rtn) && (sym_rtn == keysym)) { retval = (Mod3Mask | ShiftMask); } else if (XkbLookupKeySym (display, keycode, ShiftMask | Mod4Mask, &mods_rtn, &sym_rtn) && (sym_rtn == keysym)) { retval = (Mod4Mask | ShiftMask); } else retval = 0xFFFF; return retval; }
int main(int argc, char **argv) { Display *d; XEvent ev; unsigned int mods; KeySym ks; char buf[20]; const char *kss; char *bufptr; int ret; d = XOpenDisplay(NULL); ret = XGrabKeyboard(d, DefaultRootWindow(d), False, GrabModeAsync, GrabModeAsync, CurrentTime); fprintf(stderr, "XGrabKeyboard returns %d\n", ret); while (1) { assert(!XWindowEvent(d, DefaultRootWindow(d), KeyPressMask, &ev)); XkbLookupKeySym(d, ev.xkey.keycode, ev.xkey.state, &mods, &ks); /* ignore the modifier keypresses */ switch (ks) /* from keysymdef.h */ { case XK_Shift_L : /* Left shift */ case XK_Shift_R : /* Right shift */ case XK_Control_L : /* Left control */ case XK_Control_R : /* Right control */ case XK_Caps_Lock : /* Caps lock */ case XK_Shift_Lock: /* Shift lock */ case XK_Meta_L : /* Left meta */ case XK_Meta_R : /* Right meta */ case XK_Alt_L : /* Left alt */ case XK_Alt_R : /* Right alt */ case XK_Super_L : /* Left super */ case XK_Super_R : /* Right super */ case XK_Hyper_L : /* Left hyper */ case XK_Hyper_R : /* Right hyper */ continue; } kss = XKeysymToString(ks); bufptr = buf; if (ev.xkey.state & ShiftMask) { } if (ev.xkey.state & ControlMask) bufptr += sprintf(bufptr, "C-"); if (ev.xkey.state & Mod1Mask) bufptr += sprintf(bufptr, "M-"); if (ev.xkey.state & Mod2Mask) { } if (ev.xkey.state & Mod3Mask) { } if (ev.xkey.state & Mod4Mask) bufptr += sprintf(bufptr, "S-"); // S = super bufptr += sprintf(bufptr, kss); fprintf(stdout, "%s\n", buf); fflush(stdout); if (!strcmp(buf, "C-C")) break; //printf("%s\n", buf); /* { */ /* Window cur; */ /* int revert_to_return; */ /* XGetInputFocus(d, &cur, &revert_to_return); */ /* XSendEvent(d, cur, False, KeyPressMask, &ev); */ /* } */ } XCloseDisplay(d); }
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); }