[PATCH 14/15] editor: Add support for hardware key events
Jan Arne Petersen
jpetersen at openismus.com
Sun Nov 4 18:26:52 PST 2012
From: Jan Arne Petersen <jpetersen at openismus.com>
Listen to keys sent via the wl_keyboard interface from the input method.
Signed-off-by: Jan Arne Petersen <jpetersen at openismus.com>
---
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
More information about the wayland-devel
mailing list