#include #include #include #include #include #include #include "mod.h" unsigned int ignored_mask = LockMask | Mod2Mask | Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask; char *mod_string[] = { "shift", "lock", "control", "mod1", "mod2", "mod3", "mod4", "mod5", "alt" }; unsigned int mod_mask[] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask, Mod1Mask }; /* -> key */ int parse_key(const char *name_, struct key *key) { char *s; char *stok = NULL; key->state = 0; key->keysym = 0; if(!strcasecmp(name_,"none")) { key->name = NULL; return 0; } key->name = strdup(name_); char *name = alloca(strlen(name_) + 1); strcpy(name,key->name); s = strrchr(name, '-'); key->keysym = XStringToKeysym(s ? s + 1 : name); if(key->keysym == NoSymbol) { fprintf(stderr, "unknown keysym: '%s'\n", s ? s + 1 : name); free(key->name); key->name = NULL; return 1; } if(!s) return 0; *s = '\0'; while (( s = strtok_r(name, "-", &stok))) { int i = 0; if(!strcmp("*",s)) { key->state = AnyModifier; } else { for(; i < sizeof(mod_mask)/sizeof(mod_mask[0]); i++) if(!strcasecmp(mod_string[i], s)) { key->state |= mod_mask[i]; break; } if(i == sizeof(mod_mask)/sizeof(mod_mask[0])) { fprintf(stderr, "unknown modifer: '%s'\n", s ); free(key->name); key->name = NULL; return 1; } } if(name) name = NULL; } return 0; } static char * print_key(struct key *key) { int i; char *s; char buf[256]; char *p = buf; *p = '\0'; if(!key) return strdup("(none)"); if (key->state == AnyModifier) { strcpy(p,"*-"); p += 2; } else for(i = 0; i < sizeof(mod_mask)/sizeof(mod_mask[0]); i++) { if(key->state & mod_mask[i]) { p+= sprintf(p, "%s-", mod_string[i]); } } s = XKeysymToString(key->keysym); if(s) { strcpy(p,s); } else { sprintf(p, "0x%x", key->keysym); } return strdup(buf); } // return 0 if key does not match, return 1 if it does int xevent_match_key(XEvent *ev, struct key *key) { switch (ev->type) { case KeyPress: return ((key->keysym == XLookupKeysym(&ev->xkey, 0)) &&( key->state == (ev->xkey.state & ~ignored_mask))); case ButtonPress: return ((key->keysym == ev->xbutton.button + 0xFEE8) && (key->state == (ev->xbutton.state & ~ignored_mask))); } return 0; } // Return 1 if event does not match a key, fills in key and returns 0 otherwise. int xevent_to_key(XEvent *ev, struct key *key) { switch (ev->type) { case KeyPress: key->keysym = XLookupKeysym(&ev->xkey, 0); key->state = ev->xkey.state & ~ignored_mask; key->name = print_key(key); case ButtonPress: key->keysym = ev->xbutton.button + 0xFEE8; key->state = ev->xbutton.state & ~ignored_mask; key->name = print_key(key); default: return 1; } return 0; }