/* Find the modifier mask for Num_Lock. */ unsigned int find_numlock_mask(void) { int i; XModifierKeymap *map; unsigned int modmask = 0; if ( (map = XGetModifierMapping(display)) == NULL) { fputs("xrun: Failed to find your numlock key\n", stderr); return 0; } for (i = 0; i < 8; ++i) { int j; for (j = 0; j < map->max_keypermod; ++j) { KeySym sym; char *s; int index = 0; int min_keycode, max_keycode, keysyms_per_keycode = 0; const KeyCode keycode = *(map->modifiermap + (i * map->max_keypermod) + j); if (keycode == 0) { continue; } XDisplayKeycodes(display, &min_keycode, &max_keycode); XGetKeyboardMapping(display, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode); do { sym = XKeycodeToKeysym(display, keycode, index); index++; } while (sym == NoSymbol && index < keysyms_per_keycode); s = XKeysymToString(sym); /* If the name is Num_Lock */ if (s != NULL && strcmp(s, "Num_Lock") == 0) { #ifndef NDEBUG puts("Found Num_Lock modifier"); #endif switch (i) { case 0: modmask |= ShiftMask; break; case 1: modmask |= LockMask; break; case 2: modmask |= ControlMask; break; case 3: modmask |= Mod1Mask; break; case 4: modmask |= Mod2Mask; break; case 5: modmask |= Mod3Mask; break; case 6: modmask |= Mod4Mask; break; case 7: modmask |= Mod5Mask; break; default: assert(0); break; } } } } if (map != NULL) { XFreeModifiermap(map); } return modmask; }