static void print_keycode(struct keyboard *kbd, xkb_keycode_t keycode) { unsigned int i; struct xkb_keymap *keymap; struct xkb_state *state; const xkb_keysym_t *syms; unsigned int nsyms; char s[16]; uint32_t unicode; xkb_layout_index_t layout; xkb_mod_index_t mod; xkb_led_index_t led; state = kbd->state; keymap = xkb_state_get_keymap(state); nsyms = xkb_state_key_get_syms(state, keycode, &syms); if (nsyms <= 0) return; printf("keysyms [ "); for (i = 0; i < nsyms; i++) { xkb_keysym_get_name(syms[i], s, sizeof(s)); printf("%-*s ", (int)sizeof(s), s); } printf("] "); /* * Only do this if wchar_t is UCS-4, so we can be lazy and print * with %lc. */ #ifdef __STDC_ISO_10646__ printf("unicode [ "); for (i = 0; i < nsyms; i++) { unicode = xkb_keysym_to_utf32(syms[i]); printf("%lc ", (int)(unicode ? unicode : L' ')); } printf("] "); #endif layout = xkb_state_key_get_layout(state, keycode); printf("layout [ %s (%d) ] ", xkb_keymap_layout_get_name(keymap, layout), layout); printf("level [ %d ] ", xkb_state_key_get_level(state, keycode, layout)); printf("mods [ "); for (mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) { if (xkb_state_mod_index_is_active(state, mod, XKB_STATE_MODS_EFFECTIVE) <= 0) continue; if (xkb_state_mod_index_is_consumed(state, keycode, mod)) printf("-%s ", xkb_keymap_mod_get_name(keymap, mod)); else printf("%s ", xkb_keymap_mod_get_name(keymap, mod)); } printf("] "); printf("leds [ "); for (led = 0; led < xkb_keymap_num_leds(keymap); led++) { if (xkb_state_led_index_is_active(state, led) <= 0) continue; printf("%s ", xkb_keymap_led_get_name(keymap, led)); } printf("] "); printf("\n"); }
/** Handle keypress event. * \param L Lua stack to push the key pressed. * \param e Received XKeyEvent. * \return True if a key was successfully retrieved, false otherwise. */ bool keygrabber_handlekpress(lua_State *L, xcb_key_press_event_t *e) { /* convert keysym to string */ char buf[MAX(MB_LEN_MAX, 32)]; /* snprintf-like return value could be used here, but that should not be * necessary, as we have buffer big enough */ xkb_state_key_get_utf8(globalconf.xkb_state, e->detail, buf, countof(buf) ); if (is_control(buf)) { /* Use text names for control characters, ignoring all modifiers. */ xcb_keysym_t keysym = xcb_key_symbols_get_keysym(globalconf.keysyms, e->detail, 0); xkb_keysym_get_name(keysym, buf, countof(buf)); } luaA_pushmodifiers(L, e->state); lua_pushstring(L, buf); switch(e->response_type) { case XCB_KEY_PRESS: lua_pushliteral(L, "press"); break; case XCB_KEY_RELEASE: lua_pushliteral(L, "release"); break; } return true; }
static void kdata_print(idev_data *data) { idev_data_keyboard *k = &data->keyboard; char buf[128]; uint32_t i, c; int cwidth; /* Key-press state: UP/DOWN/REPEAT */ printf(" %-6s", k->value == 0 ? "UP" : k->value == 1 ? "DOWN" : "REPEAT"); /* Resync state */ printf(" | %-6s", data->resync ? "RESYNC" : ""); /* Keycode that triggered the event */ printf(" | %5u", (unsigned)k->keycode); /* Well-known name of the keycode */ printf(" | %-20s", libevdev_event_code_get_name(EV_KEY, k->keycode) ? : "<unknown>"); /* Well-known modifiers */ printf(" | %-5s", (k->mods & IDEV_KBDMOD_SHIFT) ? "SHIFT" : ""); printf(" %-4s", (k->mods & IDEV_KBDMOD_CTRL) ? "CTRL" : ""); printf(" %-3s", (k->mods & IDEV_KBDMOD_ALT) ? "ALT" : ""); printf(" %-5s", (k->mods & IDEV_KBDMOD_LINUX) ? "LINUX" : ""); printf(" %-4s", (k->mods & IDEV_KBDMOD_CAPS) ? "CAPS" : ""); /* Consumed modifiers */ printf(" | %-5s", (k->consumed_mods & IDEV_KBDMOD_SHIFT) ? "SHIFT" : ""); printf(" %-4s", (k->consumed_mods & IDEV_KBDMOD_CTRL) ? "CTRL" : ""); printf(" %-3s", (k->consumed_mods & IDEV_KBDMOD_ALT) ? "ALT" : ""); printf(" %-5s", (k->consumed_mods & IDEV_KBDMOD_LINUX) ? "LINUX" : ""); printf(" %-4s", (k->consumed_mods & IDEV_KBDMOD_CAPS) ? "CAPS" : ""); /* Resolved symbols */ printf(" |"); for (i = 0; i < k->n_syms; ++i) { buf[0] = 0; xkb_keysym_get_name(k->keysyms[i], buf, sizeof(buf)); if (is_locale_utf8()) { c = k->codepoints[i]; if (c < 0x110000 && c > 0x20 && (c < 0x7f || c > 0x9f)) { /* "%4lc" doesn't work well, so hard-code it */ cwidth = mk_wcwidth(c); while (cwidth++ < 2) printf(" "); printf(" '%lc':", (wchar_t)c); } else { printf(" "); } } printf(" XKB_KEY_%-30s", buf); } printf("\n"); }
static int test_keysym(xkb_keysym_t keysym, const char *expected) { char s[16]; xkb_keysym_get_name(keysym, s, sizeof(s)); fprintf(stderr, "Expected keysym %#x -> %s\n", keysym, expected); fprintf(stderr, "Received keysym %#x -> %s\n\n", keysym, s); return streq(s, expected); }
/* It's caller's responsibility to release the returned string. */ static char * get_keysym_name(xkb_keysym_t keysym) { const ssize_t bufsize = 64; char *buf = p_new(char, bufsize); ssize_t len; if((len = xkb_keysym_get_name(keysym, buf, bufsize)) == -1) { p_delete(&buf); return NULL; } if(len + 1 > bufsize) { p_realloc(&buf, len + 1); if(xkb_keysym_get_name(keysym, buf, len + 1) != len) { p_delete(&buf); return NULL; } } return buf; }
static void input_arrived(struct uterm_input *input, struct uterm_input_event *ev, void *data) { char s[32]; xkb_keysym_get_name(ev->keysyms[0], s, sizeof(s)); printf("sym %s ", s); if (ev->codepoints[0] != UTERM_INPUT_INVALID) { /* * Just a proof-of-concept hack. This works because glibc uses * UTF-32 (= UCS-4) as the internal wchar_t encoding. */ printf("unicode %lc ", ev->codepoints[0]); } print_modifiers(ev->mods); }
static int luaA_key_get_key(lua_State *L, keyb_t *k) { if(k->keycode) { char buf[12]; int slen = snprintf(buf, sizeof(buf), "#%u", k->keycode); lua_pushlstring(L, buf, slen); } else { char buf[MAX(MB_LEN_MAX, 32)]; if (xkb_keysym_get_name(k->keysym, buf, countof(buf)) < 0) { return 0; } lua_pushstring(L, buf); } return 1; }
static int gram_keysym_print (SCM keysym_smob, SCM port, scm_print_state * pstate) { struct gram_keysym *keysym = (struct gram_keysym *) SCM_SMOB_DATA (keysym_smob); scm_puts ("#<keysym ", port); if (keysym->mods.mods & WLC_BIT_MOD_LOGO) { scm_puts ("S-", port); } if (keysym->mods.mods & WLC_BIT_MOD_CTRL) { scm_puts ("C-", port); } if (keysym->mods.mods & WLC_BIT_MOD_ALT) { scm_puts ("M-", port); } if(keysym->mouse) { scm_puts ("Mouse", port); scm_putc(keysym->mouse_button + '0', port); } else { char buf[64]; xkb_keysym_to_utf8 (keysym->sym, buf, 64); if (buf[0] > 0 && buf[0] <= 0x7F) { xkb_keysym_get_name (keysym->sym, buf, 64); } SCM name = scm_from_utf8_string (buf); scm_display (name, port); } scm_puts (">", port); return 1; }
static int uxkb_desc_init(struct kbd_desc **out, const char *layout, const char *variant, const char *options) { int ret; struct kbd_desc *desc; struct xkb_rule_names rmlvo = { .rules = "evdev", .model = "evdev", .layout = layout, .variant = variant, .options = options, }; if (!out) return -EINVAL; desc = malloc(sizeof(*desc)); if (!desc) return -ENOMEM; memset(desc, 0, sizeof(*desc)); desc->ref = 1; desc->ops = &uxkb_desc_ops; desc->uxkb.ctx = xkb_context_new(0); if (!desc->uxkb.ctx) { ret = -ENOMEM; goto err_desc; } desc->uxkb.keymap = xkb_map_new_from_names(desc->uxkb.ctx, &rmlvo, 0); if (!desc->uxkb.keymap) { log_warn("failed to create keymap (%s, %s, %s), " "reverting to default US keymap", layout, variant, options); rmlvo.layout = "us"; rmlvo.variant = ""; rmlvo.options = ""; desc->uxkb.keymap = xkb_map_new_from_names(desc->uxkb.ctx, &rmlvo, 0); if (!desc->uxkb.keymap) { log_warn("failed to create keymap"); ret = -EFAULT; goto err_ctx; } } log_debug("new keyboard description (%s, %s, %s)", layout, variant, options); *out = desc; return 0; err_ctx: xkb_context_unref(desc->uxkb.ctx); err_desc: free(desc); return ret; } static void uxkb_desc_ref(struct kbd_desc *desc) { if (!desc || !desc->ref) return; ++desc->ref; } static void uxkb_desc_unref(struct kbd_desc *desc) { if (!desc || !desc->ref || --desc->ref) return; log_debug("destroying keyboard description"); xkb_map_unref(desc->uxkb.keymap); xkb_context_unref(desc->uxkb.ctx); free(desc); } static int uxkb_desc_alloc(struct kbd_desc *desc, struct kbd_dev **out) { struct kbd_dev *kbd; kbd = malloc(sizeof(*kbd)); if (!kbd) return -ENOMEM; memset(kbd, 0, sizeof(*kbd)); kbd->ref = 1; kbd->desc = desc; kbd->ops = &uxkb_dev_ops; kbd->uxkb.state = xkb_state_new(desc->uxkb.keymap); if (!kbd->uxkb.state) { free(kbd); return -ENOMEM; } kbd_desc_ref(desc); *out = kbd; return 0; } static void uxkb_keysym_to_string(uint32_t keysym, char *str, size_t size) { xkb_keysym_get_name(keysym, str, size); }
/* * Test a sequence of keysyms, resulting from a sequence of key presses, * against the keysyms they're supposed to generate. * * - Each test runs with a clean state. * - Each line in the test is made up of: * + A keycode, given as a KEY_* from linux/input.h. * + A direction - DOWN for press, UP for release, BOTH for * immediate press + release, REPEAT to just get the syms. * + A sequence of keysyms that should result from this keypress. * * The vararg format is: * <KEY_*> <DOWN | UP | BOTH> <XKB_KEY_* (zero or more)> <NEXT | FINISH> * * See below for examples. */ int test_key_seq_va(struct xkb_keymap *keymap, va_list ap) { struct xkb_state *state; xkb_keycode_t kc; int op; xkb_keysym_t keysym; const xkb_keysym_t *syms; xkb_keysym_t sym; unsigned int nsyms, i; char ksbuf[64]; fprintf(stderr, "----\n"); state = xkb_state_new(keymap); assert(state); for (;;) { kc = va_arg(ap, int) + EVDEV_OFFSET; op = va_arg(ap, int); nsyms = xkb_state_key_get_syms(state, kc, &syms); if (nsyms == 1) { sym = xkb_state_key_get_one_sym(state, kc); syms = &sym; } fprintf(stderr, "got %u syms for keycode %u: [", nsyms, kc); if (op == DOWN || op == BOTH) xkb_state_update_key(state, kc, XKB_KEY_DOWN); if (op == UP || op == BOTH) xkb_state_update_key(state, kc, XKB_KEY_UP); for (i = 0; i < nsyms; i++) { keysym = va_arg(ap, int); xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf)); fprintf(stderr, "%s%s", (i != 0) ? ", " : "", ksbuf); if (keysym == FINISH || keysym == NEXT) { xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf)); fprintf(stderr, "Did not expect keysym: %s.\n", ksbuf); goto fail; } if (keysym != syms[i]) { xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf)); fprintf(stderr, "Expected keysym: %s. ", ksbuf);; xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf)); fprintf(stderr, "Got keysym: %s.\n", ksbuf);; goto fail; } } if (nsyms == 0) { keysym = va_arg(ap, int); if (keysym != XKB_KEY_NoSymbol) { xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf)); fprintf(stderr, "Expected %s, but got no keysyms.\n", ksbuf); goto fail; } } fprintf(stderr, "]\n"); keysym = va_arg(ap, int); if (keysym == NEXT) continue; if (keysym == FINISH) break; xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf)); fprintf(stderr, "Expected keysym: %s. Didn't get it.\n", ksbuf); goto fail; }