From 148bb1ff136ee225aaa93ff9b40700feb81503c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 10 Oct 2020 22:14:35 +0200 Subject: [PATCH] ime: wip: add text-input object to seat --- ime.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ime.h | 5 +++ meson.build | 2 ++ wayland.c | 36 ++++++++++++++++++++ wayland.h | 7 ++++ 5 files changed, 147 insertions(+) create mode 100644 ime.c create mode 100644 ime.h diff --git a/ime.c b/ime.c new file mode 100644 index 00000000..baac7db5 --- /dev/null +++ b/ime.c @@ -0,0 +1,97 @@ +#include "ime.h" + +#include "text-input-unstable-v3.h" + +#define LOG_MODULE "ime" +#define LOG_ENABLE_DBG 1 +#include "log.h" +#include "terminal.h" +#include "wayland.h" + +static void +enter(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, + struct wl_surface *surface) +{ + struct seat *seat = data; + LOG_DBG("enter: seat=%s", seat->name); + + assert(seat->kbd_focus != NULL); + + switch (term_surface_kind(seat->kbd_focus, surface)) { + case TERM_SURF_GRID: + zwp_text_input_v3_enable(seat->wl_text_input); + zwp_text_input_v3_set_content_type( + seat->wl_text_input, + ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, + ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL); + + /* TODO: set cursor rectangle */ + zwp_text_input_v3_set_cursor_rectangle(seat->wl_text_input, 0, 0, 15, 15); + break; + + case TERM_SURF_SEARCH: + /* TODO */ + /* FALLTHROUGH */ + + case TERM_SURF_NONE: + case TERM_SURF_SCROLLBACK_INDICATOR: + case TERM_SURF_RENDER_TIMER: + case TERM_SURF_TITLE: + case TERM_SURF_BORDER_LEFT: + case TERM_SURF_BORDER_RIGHT: + case TERM_SURF_BORDER_TOP: + case TERM_SURF_BORDER_BOTTOM: + case TERM_SURF_BUTTON_MINIMIZE: + case TERM_SURF_BUTTON_MAXIMIZE: + case TERM_SURF_BUTTON_CLOSE: + zwp_text_input_v3_disable(seat->wl_text_input); + break; + } + + zwp_text_input_v3_commit(seat->wl_text_input); +} + +static void +leave(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, + struct wl_surface *surface) +{ + struct seat *seat = data; + LOG_DBG("leave: seat=%s", seat->name); +} + +static void +preedit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, + const char *text, int32_t cursor_begin, int32_t cursor_end) +{ + LOG_DBG("preedit-strig: text=%s, begin=%d, end=%d", text, cursor_begin, cursor_end); +} + +static void +commit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, + const char *text) +{ + LOG_DBG("commit: text=%s", text); +} + +static void +delete_surrounding_text(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, + uint32_t before_length, uint32_t after_length) +{ + LOG_DBG("delete-surrounding: before=%d, after=%d", before_length, after_length); +} + +static void +done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, + uint32_t serial) +{ + LOG_DBG("done: serial=%u", serial); +} + +const struct zwp_text_input_v3_listener text_input_listener = { + .enter = &enter, + .leave = &leave, + .preedit_string = &preedit_string, + .commit_string = &commit_string, + .delete_surrounding_text = &delete_surrounding_text, + .done = &done, +}; diff --git a/ime.h b/ime.h new file mode 100644 index 00000000..d1ce7ff0 --- /dev/null +++ b/ime.h @@ -0,0 +1,5 @@ +#pragma once + +#include "text-input-unstable-v3.h" + +extern const struct zwp_text_input_v3_listener text_input_listener; diff --git a/meson.build b/meson.build index 6b9a8c4d..1aa018a9 100644 --- a/meson.build +++ b/meson.build @@ -78,6 +78,7 @@ foreach prot : [ wayland_protocols_datadir + '/unstable/xdg-output/xdg-output-unstable-v1.xml', wayland_protocols_datadir + '/unstable/primary-selection/primary-selection-unstable-v1.xml', wayland_protocols_datadir + '/stable/presentation-time/presentation-time.xml', + wayland_protocols_datadir + '/unstable/text-input/text-input-unstable-v3.xml', ] wl_proto_headers += custom_target( @@ -147,6 +148,7 @@ executable( 'commands.c', 'commands.h', 'extract.c', 'extract.h', 'fdm.c', 'fdm.h', + 'ime.c', 'ime.h', 'input.c', 'input.h', 'main.c', 'quirks.c', 'quirks.h', diff --git a/wayland.c b/wayland.c index 8007eeba..2f7b3b95 100644 --- a/wayland.c +++ b/wayland.c @@ -18,6 +18,7 @@ #include #include #include +#include #define LOG_MODULE "wayland" #define LOG_ENABLE_DBG 0 @@ -25,6 +26,7 @@ #include "config.h" #include "terminal.h" +#include "ime.h" #include "input.h" #include "render.h" #include "selection.h" @@ -111,6 +113,23 @@ seat_add_primary_selection(struct seat *seat) primary_selection_device, &primary_selection_device_listener, seat); } +static void +seat_add_text_input(struct seat *seat) +{ + if (seat->wayl->text_input_manager == NULL) + return; + + struct zwp_text_input_v3 *text_input + = zwp_text_input_manager_v3_get_text_input( + seat->wayl->text_input_manager, seat->wl_seat); + + if (text_input == NULL) + return; + + seat->wl_text_input = text_input; + zwp_text_input_v3_add_listener(text_input, &text_input_listener, seat); +} + static void seat_destroy(struct seat *seat) { @@ -165,6 +184,8 @@ seat_destroy(struct seat *seat) wl_keyboard_release(seat->wl_keyboard); if (seat->wl_pointer != NULL) wl_pointer_release(seat->wl_pointer); + if (seat->wl_text_input != NULL) + zwp_text_input_v3_destroy(seat->wl_text_input); if (seat->wl_seat != NULL) wl_seat_release(seat->wl_seat); @@ -815,6 +836,7 @@ handle_global(void *data, struct wl_registry *registry, seat_add_data_device(seat); seat_add_primary_selection(seat); + seat_add_text_input(seat); wl_seat_add_listener(wl_seat, &seat_listener, seat); } @@ -895,6 +917,18 @@ handle_global(void *data, struct wl_registry *registry, wayl->presentation, &presentation_listener, wayl); } } + + else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) { + const uint32_t required = 1; + if (!verify_iface_version(interface, version, required)) + return; + + wayl->text_input_manager = wl_registry_bind( + wayl->registry, name, &zwp_text_input_manager_v3_interface, required); + + tll_foreach(wayl->seats, it) + seat_add_text_input(&it->item); + } } static void @@ -1154,6 +1188,8 @@ wayl_destroy(struct wayland *wayl) seat_destroy(&it->item); tll_free(wayl->seats); + if (wayl->text_input_manager != NULL) + zwp_text_input_manager_v3_destroy(wayl->text_input_manager); if (wayl->xdg_output_manager != NULL) zxdg_output_manager_v1_destroy(wayl->xdg_output_manager); if (wayl->shell != NULL) diff --git a/wayland.h b/wayland.h index faee928e..e006b395 100644 --- a/wayland.h +++ b/wayland.h @@ -220,6 +220,11 @@ struct seat { struct wl_clipboard clipboard; struct wl_primary primary; + + /* Input Method Editor */ + struct zwp_text_input_v3 *wl_text_input; + //struct { + //} ime; }; enum csd_surface { @@ -374,6 +379,8 @@ struct wayland { struct wp_presentation *presentation; uint32_t presentation_clock_id; + struct zwp_text_input_manager_v3 *text_input_manager; + bool have_argb8888; tll(struct monitor) monitors; /* All available outputs */ tll(struct seat) seats;