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

Reply via email to