static void virtual_keyboard_commit_preedit(struct virtual_keyboard *keyboard) { char *surrounding_text; if (!keyboard->preedit_string || strlen(keyboard->preedit_string) == 0) return; wl_input_method_context_cursor_position(keyboard->context, 0, 0); wl_input_method_context_commit_string(keyboard->context, keyboard->serial, keyboard->preedit_string); if (keyboard->surrounding_text) { surrounding_text = insert_text(keyboard->surrounding_text, keyboard->surrounding_cursor, keyboard->preedit_string); free(keyboard->surrounding_text); keyboard->surrounding_text = surrounding_text; keyboard->surrounding_cursor += strlen(keyboard->preedit_string); } else { keyboard->surrounding_text = strdup(keyboard->preedit_string); keyboard->surrounding_cursor = strlen(keyboard->preedit_string); } 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 wl_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]) { wl_input_method_context_key(context, keyboard->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) { wl_input_method_context_preedit_cursor(keyboard->context, 0); wl_input_method_context_preedit_string(keyboard->context, keyboard->serial, "", ""); wl_input_method_context_cursor_position(keyboard->context, 0, 0); wl_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); } wl_input_method_context_preedit_cursor(keyboard->context, strlen(text)); wl_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); } wl_input_method_context_preedit_cursor(keyboard->context, 0); wl_input_method_context_preedit_string(keyboard->context, keyboard->serial, "", ""); wl_input_method_context_cursor_position(keyboard->context, 0, 0); wl_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) { wl_input_method_context_key(context, serial, time, key, state); return; } if (state == WL_KEYBOARD_KEY_STATE_PRESSED) return; wl_input_method_context_cursor_position(keyboard->context, 0, 0); wl_input_method_context_commit_string(keyboard->context, keyboard->serial, text); }