From: Jan Arne Petersen <[email protected]> Listen to keys sent via the wl_keyboard interface from the input method.
Signed-off-by: Jan Arne Petersen <[email protected]> --- clients/editor.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/clients/editor.c b/clients/editor.c index dd7c29b..84d201c 100644 --- a/clients/editor.c +++ b/clients/editor.c @@ -30,6 +30,7 @@ #include <cairo.h> #include "window.h" +#include "keyboard-utils.h" #include "text-client-protocol.h" static const char *font_name = "sans-serif"; @@ -55,6 +56,7 @@ struct text_entry { uint32_t preedit_cursor; struct text_model *model; struct text_layout *layout; + struct keyboard_input *keyboard_input; }; struct editor { @@ -279,6 +281,9 @@ static void text_entry_button_handler(struct widget *widget, struct input *input, uint32_t time, uint32_t button, enum wl_pointer_button_state state, void *data); +static void text_entry_key_handler(struct keyboard_input *keyboard_input, + uint32_t time, uint32_t key, uint32_t unicode, + enum wl_keyboard_key_state state, void *data); static void text_entry_insert_at_cursor(struct text_entry *entry, const char *text); static void text_entry_set_preedit(struct text_entry *entry, const char *preedit_text, @@ -427,16 +432,61 @@ text_model_locale(void *data, } static void +keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, + uint32_t format, int fd, uint32_t size) +{ + struct text_entry *entry = data; + + keyboard_input_handle_keymap(entry->keyboard_input, format, fd, size); +} + +static void +keyboard_handle_key(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, + uint32_t state_w) +{ + struct text_entry *entry = data; + + keyboard_input_handle_key(entry->keyboard_input, serial, time, key, state_w); +} + +static void +keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + struct text_entry *entry = data; + + keyboard_input_handle_modifiers(entry->keyboard_input, serial, mods_depressed, + mods_latched, mods_locked, group); +} + +static const struct wl_keyboard_listener keyboard_listener = { + keyboard_handle_keymap, + NULL, + NULL, + keyboard_handle_key, + keyboard_handle_modifiers, +}; + +static void text_model_enter(void *data, struct text_model *text_model, struct wl_seat *seat, struct wl_surface *surface) { struct text_entry *entry = data; + struct wl_keyboard *keyboard; if (surface != window_get_wl_surface(entry->window)) return; + keyboard = text_model_get_keyboard(text_model, seat); + wl_keyboard_add_listener(keyboard, + &keyboard_listener, + entry); + entry->active = 1; widget_schedule_redraw(entry->widget); @@ -470,6 +520,7 @@ static struct text_entry* text_entry_create(struct editor *editor, const char *text) { struct text_entry *entry; + struct display *display; entry = malloc(sizeof *entry); @@ -490,6 +541,11 @@ text_entry_create(struct editor *editor, const char *text) widget_set_redraw_handler(entry->widget, text_entry_redraw_handler); widget_set_button_handler(entry->widget, text_entry_button_handler); + display = window_get_display(entry->window); + entry->keyboard_input = keyboard_input_create(display_get_xkb_context(display)); + keyboard_input_set_key_handler(entry->keyboard_input, text_entry_key_handler); + keyboard_input_set_user_data(entry->keyboard_input, entry); + return entry; } @@ -499,6 +555,7 @@ text_entry_destroy(struct text_entry *entry) widget_destroy(entry->widget); text_model_destroy(entry->model); text_layout_destroy(entry->layout); + keyboard_input_destroy(entry->keyboard_input); free(entry->text); free(entry); } @@ -889,6 +946,72 @@ text_entry_button_handler(struct widget *widget, } static void +text_entry_key_handler(struct keyboard_input *keyboard_input, + uint32_t time, uint32_t key, uint32_t sym, + enum wl_keyboard_key_state state, void *data) +{ + struct text_entry *entry = data; + char text[16]; + const char *start, *end, *new_char; + + if (state != WL_KEYBOARD_KEY_STATE_PRESSED) + return; + + switch (sym) { + case XKB_KEY_BackSpace: + start = utf8_prev_char(entry->text, entry->text + entry->cursor); + + if (start == NULL) + break; + + end = utf8_end_char(entry->text + entry->cursor); + text_entry_delete_text(entry, + start - entry->text, + end - start); + break; + case XKB_KEY_Delete: + start = utf8_start_char(entry->text, entry->text + entry->cursor); + + if (start == NULL) + break; + + end = utf8_next_char(start); + + if (end == NULL) + break; + + text_entry_delete_text(entry, + start - entry->text, + end - start); + break; + case XKB_KEY_Left: + new_char = utf8_prev_char(entry->text, entry->text + entry->cursor); + if (new_char != NULL) { + entry->cursor = new_char - entry->text; + entry->anchor = entry->cursor; + widget_schedule_redraw(entry->widget); + } + break; + case XKB_KEY_Right: + new_char = utf8_next_char(entry->text + entry->cursor); + if (new_char != NULL) { + entry->cursor = new_char - entry->text; + entry->anchor = entry->cursor; + widget_schedule_redraw(entry->widget); + } + break; + default: + if (xkb_keysym_to_utf8(sym, text, sizeof(text)) <= 0) + break; + + text_entry_insert_at_cursor(entry, text); + break; + } + + widget_schedule_redraw(entry->widget); +} + +static void editor_button_handler(struct widget *widget, struct input *input, uint32_t time, uint32_t button, -- 1.7.11.7 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
