[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