From a27b3a06a1b1d7aac09d794d9bf10d13c1477440 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Mon, 22 Aug 2022 10:16:15 +0900 Subject: [PATCH] text_input: implement wl_text_input and manager Change-Id: Ibfa33280ad057afaac5168e3be15d10cb341f017 --- include/libds-tizen/text_input.h | 131 ++++++ packaging/libds-tizen.spec | 32 ++ src/meson.build | 1 + src/text_input/meson.build | 29 ++ src/text_input/text_input.c | 532 +++++++++++++++++++++ tests/meson.build | 19 + tests/tc_text_input.cpp | 967 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 1711 insertions(+) create mode 100644 include/libds-tizen/text_input.h create mode 100644 src/text_input/meson.build create mode 100644 src/text_input/text_input.c create mode 100644 tests/tc_text_input.cpp diff --git a/include/libds-tizen/text_input.h b/include/libds-tizen/text_input.h new file mode 100644 index 0000000..ecd3e6f --- /dev/null +++ b/include/libds-tizen/text_input.h @@ -0,0 +1,131 @@ +#ifndef LIBDS_TIZEN_TEXT_INPUT_H +#define LIBDS_TIZEN_TEXT_INPUT_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_text_input; +struct ds_tizen_text_input_manager; + +struct ds_tizen_text_input_event_activate +{ + struct ds_tizen_text_input *text_input; + struct ds_seat *seat; + struct ds_surface *surface; +}; + +struct ds_tizen_text_input_event_deactivate +{ + struct ds_tizen_text_input *text_input; + struct ds_seat *seat; +}; + +struct ds_tizen_text_input_event_set_content_type +{ + struct ds_tizen_text_input *text_input; + uint32_t hint, purpose; +}; + +struct ds_tizen_text_input_event_set_preferred_language +{ + struct ds_tizen_text_input *text_input; + const char *language; +}; + +struct ds_tizen_text_input_event_commit_state +{ + struct ds_tizen_text_input *text_input; + uint32_t serial; +}; + +struct ds_tizen_text_input_event_invoke_action +{ + struct ds_tizen_text_input *text_input; + uint32_t button, index; +}; + +struct ds_tizen_text_input_manager * +ds_tizen_text_input_manager_create(struct wl_display *display); + +void +ds_tizen_text_input_manager_add_destroy_listener( + struct ds_tizen_text_input_manager *ti_mgr, struct wl_listener *listener); +void +ds_tizen_text_input_manager_add_new_text_input_listener( + struct ds_tizen_text_input_manager *ti_mgr, struct wl_listener *listener); + +void +ds_tizen_text_input_add_destroy_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); +void +ds_tizen_text_input_add_activate_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); +void +ds_tizen_text_input_add_deactivate_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); +void +ds_tizen_text_input_add_reset_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); +void +ds_tizen_text_input_add_set_content_type_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); +void +ds_tizen_text_input_add_set_preferred_language_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); +void +ds_tizen_text_input_add_commit_state_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); +void +ds_tizen_text_input_add_invoke_action_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener); + +void +ds_tizen_text_input_send_enter(struct ds_tizen_text_input *ti, struct ds_surface *surface); +void +ds_tizen_text_input_send_leave(struct ds_tizen_text_input *ti); +void +ds_tizen_text_input_send_modifiers_map(struct ds_tizen_text_input *ti, + struct wl_array *map); +void +ds_tizen_text_input_send_input_panel_state(struct ds_tizen_text_input *ti, + uint32_t input_panel_state); +void +ds_tizen_text_input_send_preedit_string(struct ds_tizen_text_input *ti, + uint32_t serial, const char *text, const char *commit); +void +ds_tizen_text_input_send_preedit_styling(struct ds_tizen_text_input *ti, + uint32_t index, uint32_t length, uint32_t style); +void +ds_tizen_text_input_send_preedit_cursor(struct ds_tizen_text_input *ti, + uint32_t index); +void +ds_tizen_text_input_send_commit_string(struct ds_tizen_text_input *ti, + uint32_t serial, const char *text); +void +ds_tizen_text_input_send_cursor_position(struct ds_tizen_text_input *ti, + int32_t index, int32_t anchor); +void +ds_tizen_text_input_send_delete_surrounding_text(struct ds_tizen_text_input *ti, + int32_t index, uint32_t length); +void +ds_tizen_text_input_send_keysym(struct ds_tizen_text_input *ti, + uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, + uint32_t modifiers); +void +ds_tizen_text_input_send_language(struct ds_tizen_text_input *ti, + uint32_t serial, const char *language); +void +ds_tizen_text_input_send_text_direction(struct ds_tizen_text_input *ti, + uint32_t serial, uint32_t direction); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 4db5813..f392041 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -16,6 +16,8 @@ BuildRequires: pkgconfig(tizen-extension-server) BuildRequires: pkgconfig(tizen-extension-client) BuildRequires: pkgconfig(tizen-launch-server) BuildRequires: pkgconfig(tizen-launch-client) +BuildRequires: pkgconfig(text-server) +BuildRequires: pkgconfig(text-client) BuildRequires: pkgconfig(input-method-server) BuildRequires: pkgconfig(input-method-client) BuildRequires: pkgconfig(pixman-1) @@ -263,6 +265,21 @@ Group: Development/Libraries %description embedded-compositor-devel Development package for tizen embedded compositor +## libds-tizen-text-input +%package text-input +Summary: Library for tizen text-input +Group: Development/Libraries + +%description text-input +Library for tizen text-input + +%package text-input-devel +Summary: Development package for tizen text-input +Group: Development/Libraries + +%description text-input-devel +Development package for tizen text-input + ## libds-tizen-input-method %package input-method Summary: Library for tizen input-method @@ -522,6 +539,21 @@ ninja -C builddir install %{_libdir}/libds-tizen-embedded-compositor.so %{_bindir}/libds-tizen-embedded-compositor-tests +%files text-input +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-text-input.so.* + +%files text-input-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/text_input.h +%{_libdir}/pkgconfig/libds-tizen-text-input.pc +%{_libdir}/libds-tizen-text-input.so +%{_bindir}/libds-tizen-text-input-tests + %files input-method %manifest %{name}.manifest %defattr(-,root,root,-) diff --git a/src/meson.build b/src/meson.build index 37ef631..aef63ac 100644 --- a/src/meson.build +++ b/src/meson.build @@ -43,3 +43,4 @@ subdir('screen_rotation') subdir('global_resource') subdir('embedded_compositor') subdir('input_method') +subdir('text_input') \ No newline at end of file diff --git a/src/text_input/meson.build b/src/text_input/meson.build new file mode 100644 index 0000000..796758e --- /dev/null +++ b/src/text_input/meson.build @@ -0,0 +1,29 @@ +libds_tizen_text_input_files = [ + 'text_input.c', +] + +libds_tizen_text_input_deps = [ + deps_libds_tizen, + dependency('text-server', required: true), +] + +lib_libds_tizen_text_input = shared_library('ds-tizen-text-input', libds_tizen_text_input_files, + dependencies: libds_tizen_text_input_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_text_input = declare_dependency( + link_with: lib_libds_tizen_text_input, + dependencies: libds_tizen_text_input_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_text_input, + version: meson.project_version(), + filebase: 'libds-tizen-text-input', + name: 'libds-tizen-text-input', + description: 'tizen text-input extension of libds-tizen for tizen platform', +) diff --git a/src/text_input/text_input.c b/src/text_input/text_input.c new file mode 100644 index 0000000..7a9c4f2 --- /dev/null +++ b/src/text_input/text_input.c @@ -0,0 +1,532 @@ +#include +#include +#include +#include + +#include "util.h" +#include + +#define TEXT_INPUT_VERSION 1 + +struct ds_tizen_text_input { + struct wl_resource *resource; + + struct wl_list link; + + struct { + struct wl_signal destroy; + struct wl_signal activate; + struct wl_signal deactivate; + struct wl_signal reset; + struct wl_signal set_content_type; + struct wl_signal invoke_action; + struct wl_signal commit_state; + struct wl_signal set_preferred_language; + } events; +}; + +struct ds_tizen_text_input_manager { + struct wl_global *global; + struct wl_list text_inputs; + + struct wl_listener destroy; + + struct { + struct wl_signal new_text_input; + struct wl_signal destroy; + } events; +}; + +static const struct wl_text_input_interface text_input_impl; +static const struct wl_text_input_manager_interface text_input_mgr_impl; + +WL_EXPORT void +ds_tizen_text_input_manager_add_destroy_listener( + struct ds_tizen_text_input_manager *ti_mgr, struct wl_listener *listener) +{ + wl_signal_add(&ti_mgr->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_text_input_manager_add_new_text_input_listener( + struct ds_tizen_text_input_manager *ti_mgr, struct wl_listener *listener) +{ + wl_signal_add(&ti_mgr->events.new_text_input, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_destroy_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_activate_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.activate, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_deactivate_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.deactivate, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_reset_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.reset, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_set_content_type_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.set_content_type, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_set_preferred_language_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.set_preferred_language, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_commit_state_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.commit_state, listener); +} + +WL_EXPORT void +ds_tizen_text_input_add_invoke_action_listener( + struct ds_tizen_text_input *ti, struct wl_listener *listener) +{ + wl_signal_add(&ti->events.invoke_action, listener); +} + +WL_EXPORT void +ds_tizen_text_input_send_enter(struct ds_tizen_text_input *ti, + struct ds_surface *surface) +{ + struct wl_resource *resource; + + ds_inf("ds_tizen_text_input_send_enter"); + resource = ds_surface_get_wl_resource(surface); + wl_text_input_send_enter(ti->resource, resource); +} + +WL_EXPORT void +ds_tizen_text_input_send_leave(struct ds_tizen_text_input *ti) +{ + ds_inf("ds_tizen_text_input_send_leave"); + wl_text_input_send_leave(ti->resource); +} + +WL_EXPORT void +ds_tizen_text_input_send_modifiers_map(struct ds_tizen_text_input *ti, + struct wl_array *map) +{ + ds_inf("ds_tizen_text_input_send_modifiers_map"); + wl_text_input_send_modifiers_map(ti->resource, map); +} + +WL_EXPORT void +ds_tizen_text_input_send_input_panel_state(struct ds_tizen_text_input *ti, + uint32_t state) +{ + ds_inf("ds_tizen_text_input_send_input_panel_state"); + wl_text_input_send_input_panel_state(ti->resource, state); +} + +WL_EXPORT void +ds_tizen_text_input_send_preedit_string(struct ds_tizen_text_input *ti, + uint32_t serial, const char *text, const char *commit) +{ + ds_inf("ds_tizen_text_input_send_preedit_string"); + wl_text_input_send_preedit_string(ti->resource, serial, text, commit); +} + +WL_EXPORT void +ds_tizen_text_input_send_preedit_styling(struct ds_tizen_text_input *ti, + uint32_t index, uint32_t length, uint32_t style) +{ + ds_inf("ds_tizen_text_input_send_preedit_styling"); + wl_text_input_send_preedit_styling(ti->resource, index, length, style); +} + +WL_EXPORT void +ds_tizen_text_input_send_preedit_cursor(struct ds_tizen_text_input *ti, + uint32_t index) +{ + ds_inf("ds_tizen_text_input_send_preedit_cursor"); + wl_text_input_send_preedit_cursor(ti->resource, index); +} + +WL_EXPORT void +ds_tizen_text_input_send_commit_string(struct ds_tizen_text_input *ti, + uint32_t serial, const char *text) +{ + ds_inf("ds_tizen_text_input_send_commit_string"); + wl_text_input_send_commit_string(ti->resource, serial, text); +} + +WL_EXPORT void +ds_tizen_text_input_send_cursor_position(struct ds_tizen_text_input *ti, + int32_t index, int32_t anchor) +{ + ds_inf("ds_tizen_text_input_send_cursor_position"); + wl_text_input_send_cursor_position(ti->resource, index, anchor); +} + +WL_EXPORT void +ds_tizen_text_input_send_delete_surrounding_text(struct ds_tizen_text_input *ti, + int32_t index, uint32_t length) +{ + ds_inf("ds_tizen_text_input_send_delete_surrounding_text"); + wl_text_input_send_delete_surrounding_text(ti->resource, index, length); +} + +WL_EXPORT void +ds_tizen_text_input_send_keysym(struct ds_tizen_text_input *ti, + uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, + uint32_t modifiers) +{ + ds_inf("ds_tizen_text_input_send_keysym"); + wl_text_input_send_keysym(ti->resource, serial, time, sym, state, modifiers); +} + +WL_EXPORT void +ds_tizen_text_input_send_language(struct ds_tizen_text_input *ti, + uint32_t serial, const char *language) +{ + ds_inf("ds_tizen_text_input_send_language"); + wl_text_input_send_language(ti->resource, serial, language); +} + +WL_EXPORT void +ds_tizen_text_input_send_text_direction(struct ds_tizen_text_input *ti, + uint32_t serial, uint32_t direction) +{ + ds_inf("ds_tizen_text_input_send_text_direction"); + wl_text_input_send_text_direction(ti->resource, serial, direction); +} + +static void +text_input_handle_destroy(struct wl_client *client, struct wl_resource *resource) +{ + ds_inf("text_input_handle_destroy"); + wl_resource_destroy(resource); +} + +static void +text_input_handle_activate(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *seat, struct wl_resource *surface) +{ + struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource); + struct ds_tizen_text_input_event_activate ds_event; + struct ds_surface *ds_surf; + struct ds_seat_client *seat_client; + + ds_inf("text_input_handle_activate"); + ds_surf = ds_surface_from_resource(surface); + + ds_event.text_input = text_input; + seat_client = ds_seat_client_from_resource(seat); + if (seat_client) + ds_event.seat = ds_seat_client_get_seat(seat_client); + ds_event.surface = ds_surf; + wl_signal_emit(&text_input->events.activate, &ds_event); + + ds_tizen_text_input_send_enter(text_input, ds_surf); +} + +static void +text_input_handle_deactivate(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *seat) +{ + struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource); + struct ds_tizen_text_input_event_deactivate ds_event; + struct ds_seat_client *seat_client; + + ds_inf("text_input_handle_deactivate"); + ds_event.text_input = text_input; + seat_client = ds_seat_client_from_resource(seat); + if (seat_client) + ds_event.seat = ds_seat_client_get_seat(seat_client); + wl_signal_emit(&text_input->events.deactivate, &ds_event); + + ds_tizen_text_input_send_leave(text_input); +} + +static void +text_input_handle_show_input_panel(struct wl_client *client, + struct wl_resource *resource) +{ + ds_inf("text_input_handle_show_input_panel"); +} + +static void +text_input_handle_hide_input_panel(struct wl_client *client, + struct wl_resource *resource) +{ + ds_inf("text_input_handle_hide_input_panel"); +} + +static void +text_input_handle_reset(struct wl_client *client, struct wl_resource *resource) +{ + struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource); + + ds_inf("text_input_handle_reset"); + wl_signal_emit(&text_input->events.reset, text_input); +} + +static void +text_input_handle_set_content_type(struct wl_client *client, + struct wl_resource *resource, uint32_t hint, uint32_t purpose) +{ + struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource); + struct ds_tizen_text_input_event_set_content_type ds_event; + + ds_inf("text_input_handle_set_content_type"); + ds_event.hint = hint; + ds_event.purpose = purpose; + ds_event.text_input = text_input; + + wl_signal_emit(&text_input->events.set_content_type, &ds_event); +} + +static void +text_input_handle_set_cursor_rectangle(struct wl_client *client, + struct wl_resource *resource, int32_t x, int32_t y, + int32_t width, int32_t height) +{ + ds_inf("text_input_handle_set_cursor_rectangle"); +} + +static void +text_input_handle_set_preferred_language(struct wl_client *client, + struct wl_resource *resource, const char *language) +{ + struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource); + struct ds_tizen_text_input_event_set_preferred_language ds_event; + + ds_inf("text_input_handle_set_preferred_language"); + ds_event.language = language; + ds_event.text_input = text_input; + + wl_signal_emit(&text_input->events.set_preferred_language, &ds_event); +} + +static void +text_input_handle_commit_state(struct wl_client *client, + struct wl_resource *resource, uint32_t serial) +{ + struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource); + struct ds_tizen_text_input_event_commit_state ds_event; + + ds_inf("text_input_handle_invoke_action"); + ds_event.serial = serial; + ds_event.text_input = text_input; + + wl_signal_emit(&text_input->events.commit_state, &ds_event); +} + +static void +text_input_handle_invoke_action(struct wl_client *client, + struct wl_resource *resource, uint32_t button, uint32_t index) +{ + struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource); + struct ds_tizen_text_input_event_invoke_action ds_event; + + ds_inf("text_input_handle_invoke_action"); + + ds_event.button = button; + ds_event.index = index; + ds_event.text_input = text_input; + + wl_signal_emit(&text_input->events.invoke_action, &ds_event); +} + +static const struct wl_text_input_interface text_input_impl = { + .destroy = text_input_handle_destroy, + .activate = text_input_handle_activate, + .deactivate = text_input_handle_deactivate, + .show_input_panel = text_input_handle_show_input_panel, + .hide_input_panel = text_input_handle_hide_input_panel, + .reset = text_input_handle_reset, + .set_content_type = text_input_handle_set_content_type, + .set_cursor_rectangle = text_input_handle_set_cursor_rectangle, + .set_preferred_language = text_input_handle_set_preferred_language, + .commit_state = text_input_handle_commit_state, + .invoke_action = text_input_handle_invoke_action, + //for tizen only + .set_return_key_type = NULL, + .set_return_key_disabled = NULL, + .set_input_panel_data = NULL, + .bidi_direction = NULL, + .set_cursor_position = NULL, + .process_input_device_event = NULL, + .filter_key_event = NULL, + .get_hide_permission = NULL, + .set_capital_mode = NULL, + .prediction_hint = NULL, + .set_mime_type = NULL, + .set_input_panel_position = NULL, + .finalize_content = NULL, + .prediction_hint_data = NULL, + .input_panel_enabled = NULL, +}; + +static void +text_input_destroy(struct ds_tizen_text_input *text_input) +{ + wl_signal_emit(&text_input->events.destroy, text_input); + wl_list_remove(&text_input->link); + + free(text_input); +} + +static void +text_input_mgr_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_text_input_manager *text_input_mgr; + struct ds_tizen_text_input *text_input, *tmp; + + text_input_mgr = wl_container_of(listener, text_input_mgr, destroy); + + ds_inf("Global destroy: text_input_mgr(%p)", text_input_mgr); + + wl_signal_emit(&text_input_mgr->events.destroy, text_input_mgr); + wl_list_remove(&text_input_mgr->destroy.link); + + wl_list_for_each_safe(text_input, tmp, &text_input_mgr->text_inputs, link) { + text_input_destroy(text_input); + } + + wl_global_destroy(text_input_mgr->global); + free(text_input_mgr); +} + +static void +text_input_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_text_input *text_input; + + ds_inf("text_input_client_handle_destroy"); + + text_input = wl_resource_get_user_data(resource); + text_input_destroy(text_input); +} + +static void +text_input_manager_handle_create_text_input(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t id) +{ + struct ds_tizen_text_input *text_input; + struct ds_tizen_text_input_manager *text_input_mgr; + + ds_inf("text_input_manager_handle_create_text_input"); + + text_input_mgr = wl_resource_get_user_data(resource); + + text_input = calloc(1, sizeof *text_input); + if (text_input == NULL) { + ds_err("calloc() failed. ds_tizen_text_input"); + return; + } + + text_input->resource = wl_resource_create(wl_client, + &wl_text_input_interface, + TEXT_INPUT_VERSION, id); + if (text_input->resource == NULL) { + ds_err("text_input. wl_resource_create() failed."); + wl_client_post_no_memory(wl_client); + return; + } + wl_resource_set_implementation(text_input->resource, &text_input_impl, + text_input, text_input_client_handle_destroy); + + wl_signal_init(&text_input->events.activate); + wl_signal_init(&text_input->events.deactivate); + wl_signal_init(&text_input->events.reset); + wl_signal_init(&text_input->events.set_content_type); + wl_signal_init(&text_input->events.invoke_action); + wl_signal_init(&text_input->events.commit_state); + wl_signal_init(&text_input->events.set_preferred_language); + wl_signal_init(&text_input->events.destroy); + + wl_list_insert(&text_input_mgr->text_inputs, &text_input->link); + wl_signal_emit(&text_input_mgr->events.new_text_input, text_input); +} + +static const struct wl_text_input_manager_interface text_input_mgr_impl = +{ + .create_text_input = text_input_manager_handle_create_text_input, +}; + +static void +text_input_mgr_client_handle_destroy(struct wl_resource *resource) +{ + ds_inf("text_input_mgr_client_handle_destroy"); +} + +static void +text_input_mgr_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id) +{ + struct ds_tizen_text_input_manager *text_input_mgr = data; + struct wl_resource *resource; + + ds_inf("text_input_mgr. client binds. (client:%p)", wl_client); + + resource = wl_resource_create(wl_client, + &wl_text_input_manager_interface, + version, id); + if (resource == NULL) { + ds_err("text_input_mgr. wl_resource_create() failed."); + wl_client_post_no_memory(wl_client); + return; + } + wl_resource_set_implementation(resource, &text_input_mgr_impl, + text_input_mgr, text_input_mgr_client_handle_destroy); +} + +WL_EXPORT struct ds_tizen_text_input_manager * +ds_tizen_text_input_manager_create(struct wl_display *display) +{ + struct ds_tizen_text_input_manager *text_input_mgr; + + text_input_mgr = calloc(1, sizeof *text_input_mgr); + if (text_input_mgr == NULL) { + ds_err("calloc() failed. ds_tizen_text_input_manager"); + return NULL; + } + + text_input_mgr->global = wl_global_create(display, + &wl_text_input_manager_interface, TEXT_INPUT_VERSION, text_input_mgr, + text_input_mgr_bind); + if (!text_input_mgr->global) { + free(text_input_mgr); + return NULL; + } + + wl_list_init(&text_input_mgr->text_inputs); + + wl_signal_init(&text_input_mgr->events.new_text_input); + wl_signal_init(&text_input_mgr->events.destroy); + + + text_input_mgr->destroy.notify = text_input_mgr_handle_display_destroy; + wl_display_add_destroy_listener(display, &text_input_mgr->destroy); + + ds_inf("Global create: wl_text_input_manager. text_input_mgr(%p)", text_input_mgr); + + return text_input_mgr; +} diff --git a/tests/meson.build b/tests/meson.build index e8e4421..0405794 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -265,3 +265,22 @@ executable('libds-tizen-input-method-manager-tests', install_dir: libds_tizen_bindir, install : true ) + +## text input tests +tc_text_input_files = [ + 'tc_main.cpp', + 'tc_text_input.cpp', +] + +executable('libds-tizen-text-input-tests', + [ + tc_mock_files, + tc_text_input_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_text_input, + ], + install_dir: libds_tizen_bindir, + install : true +) \ No newline at end of file diff --git a/tests/tc_text_input.cpp b/tests/tc_text_input.cpp new file mode 100644 index 0000000..f9ad47e --- /dev/null +++ b/tests/tc_text_input.cpp @@ -0,0 +1,967 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include +#include +#include + +#define TEXT_INPUT_MGR_VERSION 1 +#define SEAT_VERSION 7 + +class MockTextInputCompositor : public MockCompositor +{ +public: + MockTextInputCompositor() + : MockCompositor(&MockTextInputCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bDestroyed = false; + bNewTextInput = false; + bActivated = false; + bReset = false;; + bContentType = false; + bInvokeAction = false; + bCommitState = false; + bPreferredLanguage = false; + } + + ~MockTextInputCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockTextInputCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + ds_seat_create(comp->display, "seat0"); //for client to be bound to wl_seat_interface + + mockComp->mTextInputMgr = ds_tizen_text_input_manager_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockTextInputCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_text_input_manager_add_destroy_listener(mockComp->mTextInputMgr, + &mockComp->mDestroyListener); + + mockComp->mNewTextInputListener.notify = + MockTextInputCompositor::NewTextInputCallback; + mockComp->mNewTextInputListener.parent = mockComp; + ds_tizen_text_input_manager_add_new_text_input_listener(mockComp->mTextInputMgr, + &mockComp->mNewTextInputListener); + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void NewTextInputCallback(struct wl_listener *listener, void *data) + { + struct ds_tizen_text_input *text_input = (ds_tizen_text_input *)data; + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bNewTextInput = true; + mockComp->mTextInput = text_input; + + mockComp->mActivateListener.notify = + MockTextInputCompositor::ActivateCallback; + mockComp->mActivateListener.parent = mockComp; + ds_tizen_text_input_add_activate_listener(mockComp->mTextInput, + &mockComp->mActivateListener); + + mockComp->mDeactivateListener.notify = + MockTextInputCompositor::DeactivateCallback; + mockComp->mDeactivateListener.parent = mockComp; + ds_tizen_text_input_add_deactivate_listener(mockComp->mTextInput, + &mockComp->mDeactivateListener); + + mockComp->mResetListener.notify = + MockTextInputCompositor::ResetCallback; + mockComp->mResetListener.parent = mockComp; + ds_tizen_text_input_add_reset_listener(mockComp->mTextInput, + &mockComp->mResetListener); + + mockComp->mContentTypeListener.notify = + MockTextInputCompositor::ContentTypeCallback; + mockComp->mContentTypeListener.parent = mockComp; + ds_tizen_text_input_add_set_content_type_listener(mockComp->mTextInput, + &mockComp->mContentTypeListener); + + mockComp->mInvokeActionListener.notify = + MockTextInputCompositor::InvokeActionCallback; + mockComp->mInvokeActionListener.parent = mockComp; + ds_tizen_text_input_add_invoke_action_listener(mockComp->mTextInput, + &mockComp->mInvokeActionListener); + + mockComp->mCommitStateListener.notify = + MockTextInputCompositor::CommitStateCallback; + mockComp->mCommitStateListener.parent = mockComp; + ds_tizen_text_input_add_commit_state_listener(mockComp->mTextInput, + &mockComp->mCommitStateListener); + + mockComp->mPreferredLanguageListener.notify = + MockTextInputCompositor::PreferredLanguageCallback; + mockComp->mPreferredLanguageListener.parent = mockComp; + ds_tizen_text_input_add_set_preferred_language_listener(mockComp->mTextInput, + &mockComp->mPreferredLanguageListener); + } + + static void ActivateCallback(struct wl_listener *listener, void *data) + { + struct ds_tizen_text_input_event_activate *event = (struct ds_tizen_text_input_event_activate *)data; + + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bActivated = true; + mockComp->mSeat = event->seat; + mockComp->mSurface = event->surface; + } + + static void DeactivateCallback(struct wl_listener *listener, void *data) + { + struct ds_tizen_text_input_event_deactivate *event = (struct ds_tizen_text_input_event_deactivate *)data; + + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bActivated = false; + if (mockComp->mSeat == event->seat) + mockComp->mSeat = NULL; + mockComp->mSurface = NULL; + } + + + static void ResetCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bReset = true; + } + + static void ContentTypeCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bContentType = true; + } + + static void InvokeActionCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bInvokeAction = true; + } + + static void CommitStateCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bCommitState = true; + } + + static void PreferredLanguageCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockTextInputCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bPreferredLanguage = true; + } + + void SendEnter() + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_enter(mTextInput, mSurface); + } + void SendLeave() + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_leave(mTextInput); + } + void SendModifiersMap(struct wl_array *map) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_modifiers_map(mTextInput, map); + } + void SendInputPanelState(uint32_t state) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_input_panel_state(mTextInput, state); + } + void SendPreeditString(uint32_t serial, const char *text, const char *commit) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_preedit_string(mTextInput, serial, text, commit); + } + void SendPreeditStyling(uint32_t index, uint32_t length, uint32_t style) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_preedit_styling(mTextInput, index, length, style); + } + void SendPreeditCursor(uint32_t index) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_preedit_cursor(mTextInput, index); + } + void SendCommitString(uint32_t serial, const char *text) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_commit_string(mTextInput, serial, text); + } + void SendCursorPosition(int32_t index, int32_t anchor) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_cursor_position(mTextInput, index, anchor); + } + void SendDeleteSurroundingText(int32_t index, uint32_t length) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_delete_surrounding_text(mTextInput, index, length); + } + void SendKeysym(uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, + uint32_t modifiers) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_keysym(mTextInput, serial, time, sym, state, modifiers); + } + void SendLanguage(uint32_t serial, const char *language) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_language(mTextInput, serial, language); + } + void SendTextDirection(uint32_t serial, uint32_t direction) + { + ds_inf("%s", __func__); + + ds_tizen_text_input_send_text_direction(mTextInput, serial, direction); + } + +public: + bool bDestroyed; + bool bNewTextInput; + bool bActivated; + + bool bReset; + bool bContentType; + bool bInvokeAction; + bool bCommitState; + bool bPreferredLanguage; + + struct ds_seat *mSeat; + struct ds_surface *mSurface; + +private: + struct ds_tizen_text_input_manager *mTextInputMgr; + struct ds_tizen_text_input *mTextInput; + + struct DestroyListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct NewTextInputListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + NewTextInputListener mNewTextInputListener; + + struct ActivateListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + ActivateListener mActivateListener; + + struct DeactivateListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + DeactivateListener mDeactivateListener; + + struct ResetListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + ResetListener mResetListener; + + struct ContentTypeListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + ContentTypeListener mContentTypeListener; + + struct InvokeActionListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + InvokeActionListener mInvokeActionListener; + + struct CommitStateListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + CommitStateListener mCommitStateListener; + + struct PreferredLanguageListener: ::wl_listener { + MockTextInputCompositor *parent; + }; + PreferredLanguageListener mPreferredLanguageListener; +}; + +class MockTextInputClient : public MockClient +{ +public: + MockTextInputClient() + : bEnter(false), + bLeave(false), + bCallback(false), + compositor_res(nullptr), + wl_text_input_manager(nullptr), + wl_seat(nullptr) + {} + + MockTextInputClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + } + + ~MockTextInputClient() + { + ds_inf("%s", __func__); + } + + void SetWlCompositor(struct wl_compositor *global_res) + { + ds_inf("%s", __func__); + + compositor_res = global_res; + } + + struct wl_compositor *GetWlCompositor() + { + ds_inf("%s", __func__); + + return compositor_res; + } + + void SetTextInputMgr(struct wl_text_input_manager *global_res) + { + ds_inf("%s", __func__); + wl_text_input_manager = global_res; + } + + struct wl_text_input_manager *GetTextInputMgr() + { + ds_inf("%s", __func__); + + return wl_text_input_manager; + } + + void SetSeat(struct wl_seat *global_res) + { + ds_inf("%s", __func__); + wl_seat = global_res; + } + + struct wl_seat *GetSeat() + { + ds_inf("%s", __func__); + + return wl_seat; + } + +public: + bool bEnter; + bool bLeave; + bool bCallback; + +private: + struct wl_compositor *compositor_res; + struct wl_text_input_manager *wl_text_input_manager; + struct wl_seat *wl_seat; +}; + +static void +client_registry_cb_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) +{ + ds_inf("%s", __func__); + + MockTextInputClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct wl_text_input_manager *wl_text_input_manager; + struct wl_seat *wl_seat; + + if (!strcmp(interface, "wl_compositor")) { + compositor_res = (struct wl_compositor *)wl_registry_bind(registry, + name, &wl_compositor_interface, 1); + if (compositor_res == nullptr) { + ds_err("wl_registry_bind() failed. wl_compositor resource."); + return; + } + client->SetWlCompositor(compositor_res); + } else if (!strcmp(interface, "wl_text_input_manager")) { + wl_text_input_manager = (struct wl_text_input_manager *)wl_registry_bind(registry, + name, &wl_text_input_manager_interface, TEXT_INPUT_MGR_VERSION); + if (wl_text_input_manager == nullptr) { + ds_err("wl_registry_bind() failed. wl_text_input_manager resource."); + return; + } + client->SetTextInputMgr(wl_text_input_manager); + } else if (!strcmp(interface, "wl_seat")) { + wl_seat = (struct wl_seat *)wl_registry_bind(registry, + name, &wl_seat_interface, SEAT_VERSION); + if (wl_seat == nullptr) { + ds_err("wl_registry_bind() failed. wl_seat resource."); + return; + } + client->SetSeat(wl_seat); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockTextInputClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct wl_text_input_manager *text_input_mgr_res = client->GetTextInputMgr(); + struct wl_seat *seat_res = client->GetSeat(); + + wl_seat_destroy(seat_res); + wl_text_input_manager_destroy(text_input_mgr_res); + wl_compositor_destroy(compositor_res); +} + +static const struct wl_registry_listener registry_listener = { + .global = client_registry_cb_global, + .global_remove = client_registry_cb_global_remove +}; + +static void +text_input_cb_enter(void *data, struct wl_text_input *text_input, + struct wl_surface *surface) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bEnter = true; +} +static void +text_input_cb_leave(void *data, struct wl_text_input *text_input) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bLeave = true; +} +static void +text_input_cb_modifiers_map(void *data, struct wl_text_input *text_input, + struct wl_array *map) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_input_panel_state(void *data, struct wl_text_input *text_input, + uint32_t state) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_preedit_string(void *data, struct wl_text_input *text_input, + uint32_t serial, const char *text, const char *commit) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_preedit_styling(void *data, struct wl_text_input *text_input, + uint32_t index, uint32_t length, uint32_t style) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_preedit_cursor(void *data, struct wl_text_input *text_input, + int32_t index) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_commit_string(void *data, struct wl_text_input *text_input, + uint32_t serial, const char *text) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_cursor_position(void *data, struct wl_text_input *text_input, + int32_t index, int32_t anchor) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_delete_surrounding_text(void *data, + struct wl_text_input *text_input, int32_t index, uint32_t length) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_keysym(void *data, struct wl_text_input *text_input, + uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, + uint32_t modifiers) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_language(void *data, struct wl_text_input *text_input, + uint32_t serial, const char *language) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +static void +text_input_cb_text_direction(void *data, struct wl_text_input *text_input, + uint32_t serial, uint32_t direction) +{ + ds_inf("%s", __func__); + MockTextInputClient *client = static_cast(data); + client->bCallback = true; +} +//for tizen only +static void +text_input_cb_selection_region(void *data, + struct wl_text_input *text_input, + uint32_t serial, + int32_t start, + int32_t end) +{} +static void +text_input_cb_private_command(void *data, + struct wl_text_input *text_input, + uint32_t serial, + const char *command) +{} +static void +text_input_cb_input_panel_geometry(void *data, + struct wl_text_input *text_input, + uint32_t x, + uint32_t y, + uint32_t w, + uint32_t h) +{} +static void +text_input_cb_input_panel_data(void *data, + struct wl_text_input *text_input, + uint32_t serial, + const char *input_panel_data, + uint32_t length) +{} +static void +text_input_cb_get_selection_text (void *data, + struct wl_text_input *text_input, + int32_t fd) +{} +static void +text_input_cb_get_surrounding_text (void *data, + struct wl_text_input *text_input, + uint32_t maxlen_before, + uint32_t maxlen_after, + int32_t fd) +{} +static void +text_input_cb_filter_key_event_done(void *data, + struct wl_text_input *text_input, + uint32_t serial, + uint32_t state) +{} +static void +text_input_cb_hide_permission(void *data, + struct wl_text_input *text_input, + uint32_t permission) +{} +static void +text_input_cb_recapture_string(void *data, + struct wl_text_input *text_input, + uint32_t serial, + int32_t index, + uint32_t length, + const char *preedit, + const char *preedit_commit, + const char *commit) +{} +static void +text_input_cb_input_panel_event(void *data, + struct wl_text_input *text_input, + uint32_t serial, + uint32_t event_type, + uint32_t value) +{} + +static void +text_input_cb_commit_content(void *data, + struct wl_text_input *text_input, + uint32_t serial, + const char *content, + const char *description, + const char *mime_types) +{} +static const struct wl_text_input_listener text_input_cb_listener = +{ + .enter = text_input_cb_enter, + .leave = text_input_cb_leave, + .modifiers_map = text_input_cb_modifiers_map, + .input_panel_state = text_input_cb_input_panel_state, + .preedit_string = text_input_cb_preedit_string, + .preedit_styling = text_input_cb_preedit_styling, + .preedit_cursor = text_input_cb_preedit_cursor, + .commit_string = text_input_cb_commit_string, + .cursor_position = text_input_cb_cursor_position, + .delete_surrounding_text = text_input_cb_delete_surrounding_text, + .keysym = text_input_cb_keysym, + .language = text_input_cb_language, + .text_direction = text_input_cb_text_direction, + //for tizen only + .selection_region = text_input_cb_selection_region, + .private_command = text_input_cb_private_command, + .input_panel_geometry = text_input_cb_input_panel_geometry, + .input_panel_data = text_input_cb_input_panel_data, + .get_selection_text = text_input_cb_get_selection_text, + .get_surrounding_text = text_input_cb_get_surrounding_text, + .filter_key_event_done = text_input_cb_filter_key_event_done, + .hide_permission = text_input_cb_hide_permission, + .recapture_string = text_input_cb_recapture_string, + .input_panel_event = text_input_cb_input_panel_event, + .commit_content = text_input_cb_commit_content, +}; + +class TextInputTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockTextInputCompositor *comp; + MockTextInputClient *client; + struct wl_compositor *compositor_res; + struct wl_text_input_manager *text_input_mgr_res; + struct wl_text_input *text_input_res; + struct wl_seat *seat_res; +}; + +void +TextInputTest::SetUp(void) +{ + ds_inf("%s", __func__); + + comp = new MockTextInputCompositor(); + client = new MockTextInputClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + text_input_mgr_res = client->GetTextInputMgr(); + seat_res = client->GetSeat(); + + text_input_res = wl_text_input_manager_create_text_input(text_input_mgr_res); + + wl_text_input_add_listener(text_input_res, + &text_input_cb_listener, client); + + client->RoundTrip(); +} + +void +TextInputTest::TearDown(void) +{ + ds_inf("%s", __func__); + + client->RoundTrip(); + + delete client; + delete comp; +} + +TEST_F(TextInputTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(TextInputTest, Req_TextInputMgr_CreateTextInput) +{ + EXPECT_TRUE(comp->bNewTextInput); + EXPECT_TRUE(text_input_res != NULL); +} + +TEST_F(TextInputTest, Req_TextInput_Activate) +{ + struct wl_surface *surface_res; + + surface_res = wl_compositor_create_surface(compositor_res); + client->RoundTrip(); + EXPECT_TRUE(surface_res != NULL); + wl_text_input_activate(text_input_res, seat_res, surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bActivated); + EXPECT_TRUE(comp->mSeat != NULL); + EXPECT_TRUE(comp->mSurface != NULL); + + EXPECT_TRUE(client->bEnter); +} + +TEST_F(TextInputTest, Req_TextInput_Deactivate) +{ + struct wl_surface *surface_res; + + surface_res = wl_compositor_create_surface(compositor_res); + client->RoundTrip(); + EXPECT_TRUE(surface_res != NULL); + wl_text_input_activate(text_input_res, seat_res, surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bActivated); + EXPECT_TRUE(comp->mSeat != NULL); + EXPECT_TRUE(comp->mSurface != NULL); + + EXPECT_TRUE(client->bEnter); + + wl_text_input_deactivate(text_input_res, seat_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bActivated == false); + EXPECT_TRUE(comp->mSeat == NULL); + EXPECT_TRUE(comp->mSurface == NULL); + + EXPECT_TRUE(client->bLeave); +} + +TEST_F(TextInputTest, Req_TextInput_Reset) +{ + wl_text_input_reset(text_input_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bReset); +} + +TEST_F(TextInputTest, Req_TextInput_SetContentType) +{ + uint32_t hint = 0, purpose = 0; + wl_text_input_set_content_type(text_input_res, hint, purpose); + client->RoundTrip(); + EXPECT_TRUE(comp->bContentType); +} + +TEST_F(TextInputTest, Req_TextInput_SetPreferredLanguage) +{ + wl_text_input_set_preferred_language(text_input_res, "en"); + client->RoundTrip(); + EXPECT_TRUE(comp->bPreferredLanguage); +} + +TEST_F(TextInputTest, Req_TextInput_CommitState) +{ + uint32_t serial = 1; + + wl_text_input_commit_state(text_input_res, serial); + client->RoundTrip(); + EXPECT_TRUE(comp->bCommitState); +} + +TEST_F(TextInputTest, Req_TextInput_InvokeAction) +{ + uint32_t button = 0, index = 1; + wl_text_input_invoke_action(text_input_res, button, index); + client->RoundTrip(); + EXPECT_TRUE(comp->bInvokeAction); +} + +TEST_F(TextInputTest, Ev_TextInput_Enter) +{ + struct wl_surface *surface_res; + + surface_res = wl_compositor_create_surface(compositor_res); + client->RoundTrip(); + EXPECT_TRUE(surface_res != NULL); + wl_text_input_activate(text_input_res, seat_res, surface_res); + client->RoundTrip(); + + EXPECT_TRUE(comp->mSurface != NULL); + comp->SendEnter(); + comp->Process(); + + EXPECT_TRUE(client->bEnter); +} + +TEST_F(TextInputTest, Ev_TextInput_Leave) +{ + struct wl_surface *surface_res; + + surface_res = wl_compositor_create_surface(compositor_res); + client->RoundTrip(); + EXPECT_TRUE(surface_res != NULL); + wl_text_input_activate(text_input_res, seat_res, surface_res); + client->RoundTrip(); + + EXPECT_TRUE(comp->mSurface != NULL); + comp->SendLeave(); + comp->Process(); + + EXPECT_TRUE(client->bLeave); +} + +TEST_F(TextInputTest, Ev_TextInput_ModifiersMap) +{ + struct wl_array map_data; + int size; + void *data; + const char *modShift = "Shift", *modControl = "Control", *mod1 = "Mod1"; + + wl_array_init(&map_data); + + size = strlen(modShift) + 1; + data = wl_array_add(&map_data, size); + memcpy(data, modShift, size); + + size = strlen(modControl) + 1; + data = wl_array_add(&map_data, size); + memcpy(data, modControl, size); + + size = strlen(mod1) + 1; + data = wl_array_add(&map_data, size); + memcpy(data, mod1, size); + + comp->SendModifiersMap(&map_data); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_InputPanelState) +{ + comp->SendInputPanelState(WL_TEXT_INPUT_INPUT_PANEL_STATE_SHOW); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_PreeditString) +{ + comp->SendPreeditString(1, "", ""); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_PreeditStyling) +{ + comp->SendPreeditStyling(1, 1, 1); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_PreeditCursor) +{ + comp->SendPreeditCursor(0); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_CommitString) +{ + comp->SendCommitString(0, ""); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_CursorPosition) +{ + comp->SendCursorPosition(1, 1); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_DeleteSurroundingText) +{ + comp->SendDeleteSurroundingText(1, 1); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_Keysym) +{ + comp->SendKeysym(1, 10, 65, 1, 1); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_Language) +{ + comp->SendLanguage(1, "en_US"); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} + +TEST_F(TextInputTest, Ev_TextInput_TextDirection) +{ + comp->SendTextDirection(1, 1); + comp->Process(); + + EXPECT_TRUE(client->bCallback); +} \ No newline at end of file -- 2.7.4