static void input_method_context_reset(void *data, struct input_method_context *context) { struct virtual_keyboard *keyboard = data; fprintf(stderr, "Reset pre-edit buffer\n"); if (strlen(keyboard->preedit_string)) { input_method_context_preedit_string(context, "", 0); free(keyboard->preedit_string); keyboard->preedit_string = strdup(""); } }
static void simple_im_key_handler(struct simple_im *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t sym, enum wl_keyboard_key_state state) { struct input_method_context *context = keyboard->context; char text[64]; if (sym == XKB_KEY_Multi_key && state == WL_KEYBOARD_KEY_STATE_RELEASED && keyboard->compose_state == state_normal) { keyboard->compose_state = state_compose; memset(&keyboard->compose_seq, 0, sizeof(struct compose_seq)); return; } if (keyboard->compose_state == state_compose) { uint32_t i = 0; struct compose_seq *cs; if (state == WL_KEYBOARD_KEY_STATE_PRESSED) return; for (i = 0; i < sizeof(ignore_keys_on_compose) / sizeof(ignore_keys_on_compose[0]); i++) { if (sym == ignore_keys_on_compose[i]) { input_method_context_key(context, serial, time, key, state); return; } } for (i = 0; keyboard->compose_seq.keys[i] != 0; i++); keyboard->compose_seq.keys[i] = sym; cs = bsearch (&keyboard->compose_seq, compose_seqs, sizeof(compose_seqs) / sizeof(compose_seqs[0]), sizeof(compose_seqs[0]), compare_compose_keys); if (cs) { if (cs->keys[i + 1] == 0) { input_method_context_preedit_cursor(keyboard->context, keyboard->serial, 0); input_method_context_preedit_string(keyboard->context, keyboard->serial, "", ""); input_method_context_cursor_position(keyboard->context, keyboard->serial, 0, 0); input_method_context_commit_string(keyboard->context, keyboard->serial, cs->text); keyboard->compose_state = state_normal; } else { uint32_t j = 0, idx = 0; for (; j <= i; j++) { idx += xkb_keysym_to_utf8(cs->keys[j], text + idx, sizeof(text) - idx); } input_method_context_preedit_cursor(keyboard->context, keyboard->serial, strlen(text)); input_method_context_preedit_string(keyboard->context, keyboard->serial, text, text); } } else { uint32_t j = 0, idx = 0; for (; j <= i; j++) { idx += xkb_keysym_to_utf8(keyboard->compose_seq.keys[j], text + idx, sizeof(text) - idx); } input_method_context_preedit_cursor(keyboard->context, keyboard->serial, 0); input_method_context_preedit_string(keyboard->context, keyboard->serial, "", ""); input_method_context_cursor_position(keyboard->context, keyboard->serial, 0, 0); input_method_context_commit_string(keyboard->context, keyboard->serial, text); keyboard->compose_state = state_normal; } return; } if (xkb_keysym_to_utf8(sym, text, sizeof(text)) <= 0) { input_method_context_key(context, serial, time, key, state); return; } if (state == WL_KEYBOARD_KEY_STATE_PRESSED) return; input_method_context_cursor_position(keyboard->context, keyboard->serial, 0, 0); input_method_context_commit_string(keyboard->context, keyboard->serial, text); }
static void keyboard_handle_key(struct keyboard *keyboard, const struct key *key) { const char *label = keyboard->state == keyboardstate_default ? key->label : key->alt; switch (key->key_type) { case keytype_default: keyboard->keyboard->preedit_string = strcat(keyboard->keyboard->preedit_string, label); input_method_context_preedit_string(keyboard->keyboard->context, keyboard->keyboard->preedit_string, strlen(keyboard->keyboard->preedit_string)); break; case keytype_backspace: if (strlen(keyboard->keyboard->preedit_string) == 0) { input_method_context_delete_surrounding_text(keyboard->keyboard->context, -1, 1); } else { keyboard->keyboard->preedit_string[strlen(keyboard->keyboard->preedit_string) - 1] = '\0'; input_method_context_preedit_string(keyboard->keyboard->context, keyboard->keyboard->preedit_string, strlen(keyboard->keyboard->preedit_string)); } break; case keytype_enter: input_method_context_key(keyboard->keyboard->context, XKB_KEY_KP_Enter, WL_KEYBOARD_KEY_STATE_PRESSED); break; case keytype_space: keyboard->keyboard->preedit_string = strcat(keyboard->keyboard->preedit_string, " "); input_method_context_preedit_string(keyboard->keyboard->context, "", 0); input_method_context_commit_string(keyboard->keyboard->context, keyboard->keyboard->preedit_string, strlen(keyboard->keyboard->preedit_string)); free(keyboard->keyboard->preedit_string); keyboard->keyboard->preedit_string = strdup(""); break; case keytype_switch: if (keyboard->state == keyboardstate_default) keyboard->state = keyboardstate_uppercase; else keyboard->state = keyboardstate_default; break; case keytype_symbols: break; case keytype_tab: input_method_context_key(keyboard->keyboard->context, XKB_KEY_Tab, WL_KEYBOARD_KEY_STATE_PRESSED); break; case keytype_arrow_up: input_method_context_key(keyboard->keyboard->context, XKB_KEY_Up, WL_KEYBOARD_KEY_STATE_PRESSED); break; case keytype_arrow_left: input_method_context_key(keyboard->keyboard->context, XKB_KEY_Left, WL_KEYBOARD_KEY_STATE_PRESSED); break; case keytype_arrow_right: input_method_context_key(keyboard->keyboard->context, XKB_KEY_Right, WL_KEYBOARD_KEY_STATE_PRESSED); break; case keytype_arrow_down: input_method_context_key(keyboard->keyboard->context, XKB_KEY_Down, WL_KEYBOARD_KEY_STATE_PRESSED); break; } }