From 6493d93fb983f8e753bb13240b05841e2aa0d7b0 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 8 Aug 2022 10:40:04 +0900 Subject: [PATCH 01/16] implement ds_tizen_embedded_compsitor This implement the server impelmentation for tizen_embedded_compositor interface. Change-Id: Icd0c42ad490397616bd91c023a3ca0661f0a3e5a --- include/libds-tizen/embedded_compositor.h | 24 ++++ packaging/libds-tizen.spec | 29 +++++ src/embedded_compositor/embedded_compositor.c | 180 ++++++++++++++++++++++++++ src/embedded_compositor/meson.build | 29 +++++ src/meson.build | 1 + 5 files changed, 263 insertions(+) create mode 100644 include/libds-tizen/embedded_compositor.h create mode 100644 src/embedded_compositor/embedded_compositor.c create mode 100644 src/embedded_compositor/meson.build diff --git a/include/libds-tizen/embedded_compositor.h b/include/libds-tizen/embedded_compositor.h new file mode 100644 index 0000000..adcabfa --- /dev/null +++ b/include/libds-tizen/embedded_compositor.h @@ -0,0 +1,24 @@ +#ifndef LIBDS_TIZEN_EMBEDDED_COMPOSITOR_H +#define LIBDS_TIZEN_EMBEDDED_COMPOSITOR_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_embedded_compositor; + +struct ds_tizen_embedded_compositor * +ds_tizen_embedded_compositor_create(struct wl_display *display); + +void +ds_tizen_embedded_compositor_add_destroy_listener( + struct ds_tizen_embedded_compositor *embedded_compositor, + struct wl_listener *listener); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index ceb30a2..64a9b1d 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -246,6 +246,21 @@ Group: Development/Libraries %description global-resource-devel Development package for tizen global resource +## libds-tizen-embedded-compositor +%package embedded-compositor +Summary: Library for tizen embedded compositor +Group: Development/Libraries + +%description embedded-compositor +Library for tizen embedded compositor + +%package embedded-compositor-devel +Summary: Development package for tizen embedded compositor +Group: Development/Libraries + +%description embedded-compositor-devel +Development package for tizen embedded compositor + %prep %setup -q cp %{SOURCE1001} . @@ -476,3 +491,17 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-global-resource.pc %{_libdir}/libds-tizen-global-resource.so %{_bindir}/libds-tizen-global-resource-tests + +%files embedded-compositor +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-embedded-compositor.so.* + +%files embedded-compositor-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/embedded_compositor.h +%{_libdir}/pkgconfig/libds-tizen-embedded-compositor.pc +%{_libdir}/libds-tizen-embedded-compositor.so diff --git a/src/embedded_compositor/embedded_compositor.c b/src/embedded_compositor/embedded_compositor.c new file mode 100644 index 0000000..29f3bb9 --- /dev/null +++ b/src/embedded_compositor/embedded_compositor.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "libds-tizen/embedded_compositor.h" + +#define TIZEN_EMBEDDED_COMPOSITOR_VERSION 1 + +struct ds_tizen_embedded_compositor +{ + struct wl_global *global; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + } events; +}; + +struct ds_tizen_embedded_compositor_client +{ + struct ds_tizen_embedded_compositor *embedded_compositor; + + struct wl_resource *resource; + struct wl_client *wl_client; +}; + +static void embedded_compositor_handle_display_destroy(struct wl_listener *listener, + void *data); + +static void embedded_compositor_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id); + +WL_EXPORT struct ds_tizen_embedded_compositor * +ds_tizen_embedded_compositor_create(struct wl_display *display) +{ + struct ds_tizen_embedded_compositor *embedded_compositor; + + embedded_compositor = calloc(1, sizeof *embedded_compositor); + if (!embedded_compositor) { + ds_err("calloc() failed."); + return NULL; + } + + embedded_compositor->global = wl_global_create(display, &tizen_embedded_compositor_interface, + TIZEN_EMBEDDED_COMPOSITOR_VERSION, embedded_compositor, embedded_compositor_bind); + if (!embedded_compositor->global) { + ds_err("wl_global_create() failed. tizen_embedded_compositor_interface"); + free(embedded_compositor); + return NULL; + } + + embedded_compositor->destroy.notify = embedded_compositor_handle_display_destroy; + wl_display_add_destroy_listener(display, &embedded_compositor->destroy); + + wl_signal_init(&embedded_compositor->events.destroy); + + ds_inf("Global created: tizen_embedded_compositor(%p)", embedded_compositor); + + return embedded_compositor; +} + +WL_EXPORT void +ds_tizen_embedded_compositor_add_destroy_listener( + struct ds_tizen_embedded_compositor *embedded_compositor, + struct wl_listener *listener) +{ + wl_signal_add(&embedded_compositor->events.destroy, listener); +} + +static void +embedded_compositor_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_embedded_compositor *embedded_compositor; + + embedded_compositor = wl_container_of(listener, embedded_compositor, destroy); + + ds_inf("Global destroy: embedded_compositor(%p)", embedded_compositor); + + wl_signal_emit(&embedded_compositor->events.destroy, embedded_compositor); + wl_list_remove(&embedded_compositor->destroy.link); + wl_global_destroy(embedded_compositor->global); + free(embedded_compositor); +} + +static void +embedded_compositor_handle_get_socket(struct wl_client *wl_client, + struct wl_resource *resource) +{ + struct ds_tizen_embedded_compositor_client *client; + int sock_fd=-1; + pid_t pid = 0; + + ds_inf("tizen_embedded_compositor: get_socket"); + + client = wl_resource_get_user_data(resource); + + wl_client_get_credentials(client->wl_client, &pid, NULL, NULL); + + sock_fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (sock_fd < 0) { + ds_err("Could not create socket: %m, (client=%p, pid=%d)", client, pid); + return; + } + + tizen_embedded_compositor_send_socket(resource, sock_fd); + + ds_inf("tizen_embedded_compositor: (sock_fd,%d) sent! (client,%p) (pid,%d)", + sock_fd, client, pid); + + close(sock_fd); +} + +static void +embedded_compositor_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_embedded_compositor_interface embedded_compositor_impl = +{ + embedded_compositor_handle_get_socket, + embedded_compositor_handle_destroy, +}; + +static void +_tizen_embedded_compositor_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_embedded_compositor_client *client; + + client = wl_resource_get_user_data(resource); + + ds_inf("_tizen_embedded_compositor_client_handle_destroy (client:%p)", client); + + free(client); +} + +static void +embedded_compositor_bind(struct wl_client *wl_client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_embedded_compositor *embedded_compositor = data; + struct ds_tizen_embedded_compositor_client *client; + + client = calloc(1, sizeof *client); + if (client == NULL) { + ds_err("calloc() failed. tizen_embedded_compositor"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_embedded_compositor_client binds. (client:%p)", client); + + client->embedded_compositor = embedded_compositor; + client->wl_client = wl_client; + + client->resource = wl_resource_create(wl_client, + &tizen_embedded_compositor_interface, + MIN(version, TIZEN_EMBEDDED_COMPOSITOR_VERSION), id); + + if (client->resource == NULL) { + ds_err("tizen_embedded_compositor : wl_resource_create() failed."); + free(client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(client->resource, &embedded_compositor_impl, + client, _tizen_embedded_compositor_client_handle_destroy); +} diff --git a/src/embedded_compositor/meson.build b/src/embedded_compositor/meson.build new file mode 100644 index 0000000..632d23c --- /dev/null +++ b/src/embedded_compositor/meson.build @@ -0,0 +1,29 @@ +libds_tizen_embedded_compositor_files = [ + 'embedded_compositor.c', +] + +libds_tizen_embedded_compositor_deps = [ + deps_libds_tizen, + dependency('tizen-extension-server', required: true), +] + +lib_libds_tizen_embedded_compositor = shared_library('ds-tizen-embedded-compositor', libds_tizen_embedded_compositor_files, + dependencies: libds_tizen_embedded_compositor_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_embedded_compositor = declare_dependency( + link_with: lib_libds_tizen_embedded_compositor, + dependencies: libds_tizen_embedded_compositor_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_embedded_compositor, + version: meson.project_version(), + filebase: 'libds-tizen-embedded-compositor', + name: 'libds-tizen-embedded-compositor', + description: 'tizen memory flusher extension of libds-tizen for tizen platform', +) diff --git a/src/meson.build b/src/meson.build index 66f10c6..a1ba1ab 100644 --- a/src/meson.build +++ b/src/meson.build @@ -41,3 +41,4 @@ subdir('memory_flusher') subdir('renderer') subdir('screen_rotation') subdir('global_resource') +subdir('embedded_compositor') -- 2.7.4 From d6d78b67fa1c4df8682280f87efef2f8ac8e88b5 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 8 Aug 2022 11:35:53 +0900 Subject: [PATCH 02/16] add test cases for ds_tizen_embedded_compositor Change-Id: Ic9a11417dfde46aec23bfc21164b4d7f1d39fbc5 --- packaging/libds-tizen.spec | 1 + tests/meson.build | 20 +++ tests/tc_embedded_compositor.cpp | 305 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+) create mode 100644 tests/tc_embedded_compositor.cpp diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 64a9b1d..710ac9b 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -505,3 +505,4 @@ ninja -C builddir install %{_includedir}/libds-tizen/embedded_compositor.h %{_libdir}/pkgconfig/libds-tizen-embedded-compositor.pc %{_libdir}/libds-tizen-embedded-compositor.so +%{_bindir}/libds-tizen-embedded-compositor-tests diff --git a/tests/meson.build b/tests/meson.build index 58051f6..34b9245 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -207,3 +207,23 @@ executable('libds-tizen-global-resource-tests', install_dir: libds_tizen_bindir, install : true ) + +## embedded-compositor tests +tc_embedded_compositor_files = [ + 'tc_main.cpp', + 'tc_embedded_compositor.cpp', +] + +executable('libds-tizen-embedded-compositor-tests', + [ + tc_mock_files, + tc_embedded_compositor_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_embedded_compositor, + dependency('tizen-extension-client', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) \ No newline at end of file diff --git a/tests/tc_embedded_compositor.cpp b/tests/tc_embedded_compositor.cpp new file mode 100644 index 0000000..56535ba --- /dev/null +++ b/tests/tc_embedded_compositor.cpp @@ -0,0 +1,305 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include +#include + +#define TIZEN_EMBEDDED_COMPOSITOR_VERSION 1 + +class MockEmbeddedCompositorCompositor : public MockCompositor +{ +public: + MockEmbeddedCompositorCompositor() + : MockCompositor(&MockEmbeddedCompositorCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bSurfaceDestroyed = false; + + bDestroyed = false; + } + + ~MockEmbeddedCompositorCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockEmbeddedCompositorCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + // new surface listener + mockComp->mNewSurfaceListener.notify = + MockEmbeddedCompositorCompositor::NewSurfaceCallback; + mockComp->mNewSurfaceListener.parent = mockComp; + ds_compositor_add_new_surface_listener(comp->compositor, + &mockComp->mNewSurfaceListener); + + mockComp->mEmbeddedCompositor = + ds_tizen_embedded_compositor_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockEmbeddedCompositorCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_embedded_compositor_add_destroy_listener(mockComp->mEmbeddedCompositor, + &mockComp->mDestroyListener); + } + + static void NewSurfaceCallback(struct wl_listener *listener, void *data) + { + MockEmbeddedCompositorCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_surface *surface = static_cast(data); + + ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface); + + mockComp->mSurface = surface; + + // del surface listener + mockComp->mDelSurfaceListener.notify = + MockEmbeddedCompositorCompositor::DelSurfaceCallback; + mockComp->mDelSurfaceListener.parent = mockComp; + ds_surface_add_destroy_listener(surface, + &mockComp->mDelSurfaceListener); + } + + static void DelSurfaceCallback(struct wl_listener *listener, void *data) + { + MockEmbeddedCompositorCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_surface *surface = static_cast(data); + + ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface); + + if (ds_surface_get_wl_resource(mockComp->mSurface) == + ds_surface_get_wl_resource(surface)) { + ds_inf("%s: surface is deleted.", __func__); + mockComp->bSurfaceDestroyed = true; + } + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockEmbeddedCompositorCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + +public: + bool bSurfaceDestroyed; + bool bDestroyed; + +private: + struct ds_surface *mSurface; + + struct NewSurfaceListener : ::wl_listener { + MockEmbeddedCompositorCompositor *parent; + }; + NewSurfaceListener mNewSurfaceListener; + + struct DelSurfaceListener : ::wl_listener { + MockEmbeddedCompositorCompositor *parent; + }; + DelSurfaceListener mDelSurfaceListener; + + struct ds_tizen_embedded_compositor *mEmbeddedCompositor; + + struct DestroyListener : ::wl_listener { + MockEmbeddedCompositorCompositor *parent; + }; + DestroyListener mDestroyListener; +}; + +class MockEmbeddedCompositorClient : public MockClient +{ +public: + MockEmbeddedCompositorClient() + : bSocketEvent(false), + socket_fd(-1), + compositor_res(nullptr), + tizen_embedded_compositor(nullptr) + {} + MockEmbeddedCompositorClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + + bSocketEvent = false; + socket_fd = -1; + } + ~MockEmbeddedCompositorClient() + { + 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 SetTizenEmbeddedCompositor(struct tizen_embedded_compositor *global_res) + { + ds_inf("%s", __func__); + + tizen_embedded_compositor = global_res; + } + + struct tizen_embedded_compositor *GetTizenEmbeddedCompositor() + { + ds_inf("%s", __func__); + + return tizen_embedded_compositor; + } + +public: + bool bSocketEvent; + int32_t socket_fd; + +private: + struct wl_compositor *compositor_res; + struct tizen_embedded_compositor *tizen_embedded_compositor; +}; + +static void +client_tizen_embedded_compositor_cb_socket(void *data, + struct tizen_embedded_compositor *embedded_compositor, int32_t socket_fd) +{ + ds_inf("%s", __func__); + + MockEmbeddedCompositorClient *client = static_cast(data); + + client->bSocketEvent = true; + client->socket_fd = socket_fd; +} + +static const struct tizen_embedded_compositor_listener embedded_compositor_cb_listener = { + .socket = client_tizen_embedded_compositor_cb_socket, +}; + +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__); + + MockEmbeddedCompositorClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct tizen_embedded_compositor *embedded_compositor_res; + + 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, "tizen_embedded_compositor")) { + embedded_compositor_res = (struct tizen_embedded_compositor *)wl_registry_bind(registry, + name, &tizen_embedded_compositor_interface, TIZEN_EMBEDDED_COMPOSITOR_VERSION); + if (embedded_compositor_res == nullptr) { + ds_err("wl_registry_bind() failed. tizen_embedded_compositor resource."); + return; + } + client->SetTizenEmbeddedCompositor(embedded_compositor_res); + + tizen_embedded_compositor_add_listener(embedded_compositor_res, + &embedded_compositor_cb_listener, client); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockEmbeddedCompositorClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct tizen_embedded_compositor *embedded_compositor_res = client->GetTizenEmbeddedCompositor(); + + tizen_embedded_compositor_destroy(embedded_compositor_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 +}; + +class EmbeddedCompositorTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockEmbeddedCompositorCompositor *comp; + MockEmbeddedCompositorClient *client; + struct wl_compositor *compositor_res; + struct tizen_embedded_compositor *embedded_compositor_res; + struct wl_surface *surface_res; +}; + +void +EmbeddedCompositorTest::SetUp(void) +{ + //ds_log_init(DS_DBG, NULL); + + ds_inf("%s", __func__); + + comp = new MockEmbeddedCompositorCompositor(); + client = new MockEmbeddedCompositorClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + embedded_compositor_res = client->GetTizenEmbeddedCompositor(); + surface_res = wl_compositor_create_surface(compositor_res); + + client->RoundTrip(); +} + +void +EmbeddedCompositorTest::TearDown(void) +{ + ds_inf("%s", __func__); + + wl_surface_destroy(surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bSurfaceDestroyed); + + delete client; + delete comp; +} + +TEST_F(EmbeddedCompositorTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(EmbeddedCompositorTest, Ev_GetSocket) +{ + tizen_embedded_compositor_get_socket(embedded_compositor_res); + client->RoundTrip(); + + comp->Process(); + EXPECT_TRUE(client->bSocketEvent); + EXPECT_TRUE(client->socket_fd >= 0) + << "get socket_fd : " << client->socket_fd << std::endl; +} -- 2.7.4 From c6a777d8b75b7b82672b468c523c4d75a9646381 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Tue, 9 Aug 2022 13:18:00 +0900 Subject: [PATCH 03/16] launch: merge header files in one (launch.h) Change-Id: I37f92da33205a3d8c457483be68f1c2519b3c682 --- examples/tinyds-tdm.c | 48 ++++++------ include/libds-tizen/launch.h | 115 +++++++++++++++++++++++++++ include/libds-tizen/launch/appinfo.h | 42 ---------- include/libds-tizen/launch/effect.h | 92 ---------------------- packaging/libds-tizen.spec | 3 +- src/launch/appinfo.c | 134 +++++++++++++++---------------- src/launch/effect.c | 148 +++++++++++++++++------------------ tests/tc_launch_appinfo.cpp | 112 +++++++++++++------------- tests/tc_launch_effect.cpp | 136 ++++++++++++++++---------------- 9 files changed, 404 insertions(+), 426 deletions(-) create mode 100644 include/libds-tizen/launch.h delete mode 100644 include/libds-tizen/launch/appinfo.h delete mode 100644 include/libds-tizen/launch/effect.h diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 0abb4b0..2158bac 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #define USE_TDM_BUFFER_QUEUE @@ -90,8 +90,8 @@ struct tinyds_server uint32_t seat_caps; double output_x, output_y; struct ds_tizen_input_devicemgr *devicemgr; - struct ds_tizen_effect *effect; - struct ds_tizen_splash *splash; + struct ds_tizen_launch_effect *effect; + struct ds_tizen_launch_splash *splash; struct tinyds_output *output; struct tinyds_dpms *dpms; @@ -257,8 +257,8 @@ view_populate_pid(struct tinyds_view *view) ds_inf("view pid(%u)", pid); view->pid = pid; - view->effect_type = ds_tizen_effect_get_effect_type(view->server->effect, pid); - ds_tizen_effect_unset_effect_type(view->server->effect, pid); + view->effect_type = ds_tizen_launch_effect_get_effect_type(view->server->effect, pid); + ds_tizen_launch_effect_unset_effect_type(view->server->effect, pid); ds_inf("view effect_type(%d)", view->effect_type); } @@ -605,7 +605,7 @@ static void launch_effect_handle_type_set(struct wl_listener *listener, void *data) { struct tinyds_server *server; - struct ds_tizen_effect_event_type_set *event = data; + struct ds_tizen_launch_effect_event_type_set *event = data; struct tinyds_view *view = NULL; bool existing = false; @@ -621,9 +621,9 @@ launch_effect_handle_type_set(struct wl_listener *listener, void *data) } } if (existing) { - ds_tizen_effect_unset_effect_type(server->effect, event->pid); + ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid); } else { - ds_tizen_effect_set_effect_type(server->effect, event->pid, event->effect_type); + ds_tizen_launch_effect_set_effect_type(server->effect, event->pid, event->effect_type); } } @@ -631,7 +631,7 @@ static void launch_effect_handle_type_unset(struct wl_listener *listener, void *data) { struct tinyds_server *server; - struct ds_tizen_effect_event_type_unset *event = data; + struct ds_tizen_launch_effect_event_type_unset *event = data; struct tinyds_view *view = NULL; server = wl_container_of(listener, server, effect_type_unset); @@ -644,14 +644,14 @@ launch_effect_handle_type_unset(struct wl_listener *listener, void *data) ds_inf("Launch effect. pid found"); } } - ds_tizen_effect_unset_effect_type(server->effect, event->pid); + ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid); } static void launch_splash_handle_owner(struct wl_listener *listener, void *data) { struct tinyds_server *server; - struct ds_tizen_splash_event_owner *event = data; + struct ds_tizen_launch_splash_event_owner *event = data; struct tinyds_view *view = NULL; server = wl_container_of(listener, server, splash_owner); @@ -660,10 +660,10 @@ launch_splash_handle_owner(struct wl_listener *listener, void *data) wl_list_for_each(view, &server->views, link) { if (view->pid == event->pid) { - if (event->pid == ds_tizen_splash_get_pid(server->splash)) + if (event->pid == ds_tizen_launch_splash_get_pid(server->splash)) ;// else { - ds_tizen_splash_set_pid(server->splash, event->pid); + ds_tizen_launch_splash_set_pid(server->splash, event->pid); } } } @@ -673,24 +673,24 @@ static void launch_effect_handle_new_splash(struct wl_listener *listener, void *data) { struct tinyds_server *server; - struct ds_tizen_effect_event_new_splash *event = data; + struct ds_tizen_launch_splash *splash = data; struct tinyds_view *view = NULL; server = wl_container_of(listener, server, new_splash); - ds_inf("Launch new splash. splash(%p)", event->splash); - if (!event->splash) return; + ds_inf("Launch new splash. splash(%p)", splash); + if (!splash) return; - server->splash = event->splash; + server->splash = splash; // new view for "Launchscreen" view = calloc(1, sizeof *view); assert(view); wl_list_insert(server->views.prev, &view->link); - view->pid = ds_tizen_splash_get_pid(event->splash); + view->pid = ds_tizen_launch_splash_get_pid(splash); server->splash_owner.notify = launch_splash_handle_owner; - ds_tizen_splash_add_owner_listener(server->splash, + ds_tizen_launch_splash_add_owner_listener(server->splash, &server->splash_owner); } @@ -763,25 +763,25 @@ init_server(struct tinyds_server *server, struct wl_display *display) ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr, &server->pointer_warp); - server->effect = ds_tizen_effect_create(display); + server->effect = ds_tizen_launch_effect_create(display); if (!server->effect) { goto err; } server->effect_destroy.notify = launch_effect_handle_destroy; - ds_tizen_effect_add_destroy_listener(server->effect, + ds_tizen_launch_effect_add_destroy_listener(server->effect, &server->effect_destroy); server->effect_type_set.notify = launch_effect_handle_type_set; - ds_tizen_effect_add_type_set_listener(server->effect, + ds_tizen_launch_effect_add_type_set_listener(server->effect, &server->effect_type_set); server->effect_type_unset.notify = launch_effect_handle_type_unset; - ds_tizen_effect_add_type_unset_listener(server->effect, + ds_tizen_launch_effect_add_type_unset_listener(server->effect, &server->effect_type_unset); server->new_splash.notify = launch_effect_handle_new_splash; - ds_tizen_effect_add_new_splash_listener(server->effect, + ds_tizen_launch_effect_add_new_splash_listener(server->effect, &server->new_splash); return true; diff --git a/include/libds-tizen/launch.h b/include/libds-tizen/launch.h new file mode 100644 index 0000000..1e00348 --- /dev/null +++ b/include/libds-tizen/launch.h @@ -0,0 +1,115 @@ +#ifndef LIBDS_TIZEN_LAUNCH_SPLASH_H +#define LIBDS_TIZEN_LAUNCH_SPLASH_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum ds_tizen_launch_effect_type +{ + DS_TIZEN_LAUNCH_EFFECT_TYPE_LAUNCH = 0, + DS_TIZEN_LAUNCH_EFFECT_TYPE_DEPTH_IN, +}; + +struct ds_tizen_launch_effect_event_type_set +{ + uint32_t pid; + enum ds_tizen_launch_effect_type effect_type; +}; + +struct ds_tizen_launch_effect_event_type_unset +{ + uint32_t pid; +}; + +enum ds_tizen_launch_splash_file_type +{ + DS_TIZEN_LAUNCH_SPLASH_FILE_TYPE_ERR = -1, + DS_TIZEN_LAUNCH_SPLASH_FILE_TYPE_IMG, + DS_TIZEN_LAUNCH_SPLASH_FILE_TYPE_EDJ, +}; + +struct ds_tizen_launch_splash_event_owner +{ + uint32_t pid; +}; + +struct ds_tizen_launch_appinfo_mgr; +struct ds_tizen_launch_appinfo; + +struct ds_tizen_launch_effect; +struct ds_tizen_launch_splash; + +// launch_appinfo +struct ds_tizen_launch_appinfo_mgr * +ds_tizen_launch_appinfo_mgr_create(struct wl_display *display); + +void +ds_tizen_launch_appinfo_mgr_add_destroy_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); + +void +ds_tizen_launch_appinfo_mgr_add_set_pid_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); + +void +ds_tizen_launch_appinfo_mgr_add_set_appid_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); + +void +ds_tizen_launch_appinfo_mgr_add_metadata_ready_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); + +//for gtest +struct wl_resource * +ds_tizen_launch_appinfo_mgr_get_appinfo_resource( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr); + +// launch_effect +struct ds_tizen_launch_effect * +ds_tizen_launch_effect_create(struct wl_display *display); + +void +ds_tizen_launch_effect_add_destroy_listener( + struct ds_tizen_launch_effect *effect, struct wl_listener *listener); +void +ds_tizen_launch_effect_add_type_set_listener( + struct ds_tizen_launch_effect *effect, struct wl_listener *listener); +void +ds_tizen_launch_effect_add_type_unset_listener(struct ds_tizen_launch_effect *effect, + struct wl_listener *listener); +void +ds_tizen_launch_effect_add_new_splash_listener(struct ds_tizen_launch_effect *effect, + struct wl_listener *listener); + +void +ds_tizen_launch_effect_set_effect_type(struct ds_tizen_launch_effect *effect, + uint32_t pid, int effect_type); +void +ds_tizen_launch_effect_unset_effect_type(struct ds_tizen_launch_effect *effect, + uint32_t pid); +int +ds_tizen_launch_effect_get_effect_type(struct ds_tizen_launch_effect *effect, + uint32_t pid); + +// launch_splash +void +ds_tizen_launch_splash_add_destroy_listener( + struct ds_tizen_launch_splash *splash, struct wl_listener *listener); +void +ds_tizen_launch_splash_add_owner_listener( + struct ds_tizen_launch_splash *splash, struct wl_listener *listener); + +uint32_t +ds_tizen_launch_splash_get_pid(struct ds_tizen_launch_splash *splash); +void +ds_tizen_launch_splash_set_pid(struct ds_tizen_launch_splash *splash, uint32_t pid); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libds-tizen/launch/appinfo.h b/include/libds-tizen/launch/appinfo.h deleted file mode 100644 index bd62e9b..0000000 --- a/include/libds-tizen/launch/appinfo.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef LIBDS_TIZEN_APPINFO_H -#define LIBDS_TIZEN_APPINFO_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_tizen_appinfo_mgr; -struct ds_tizen_appinfo; - -struct ds_tizen_appinfo_mgr * -ds_tizen_appinfo_mgr_create(struct wl_display *display); - -void -ds_tizen_appinfo_mgr_add_destroy_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); - -void -ds_tizen_appinfo_mgr_add_set_pid_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); - -void -ds_tizen_appinfo_mgr_add_set_appid_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); - -void -ds_tizen_appinfo_mgr_add_metadata_ready_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener); - -//for gtest -struct wl_resource * -ds_tizen_appinfo_mgr_get_appinfo_resource( - struct ds_tizen_appinfo_mgr *appinfo_mgr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds-tizen/launch/effect.h b/include/libds-tizen/launch/effect.h deleted file mode 100644 index d49fa33..0000000 --- a/include/libds-tizen/launch/effect.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef LIBDS_TIZEN_EFFECT_H -#define LIBDS_TIZEN_EFFECT_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_tizen_effect; -struct ds_tizen_splash; - -enum ds_tizen_effect_type -{ - DS_TIZEN_EFFECT_TYPE_LAUNCH = 0, - DS_TIZEN_EFFECT_TYPE_DEPTH_IN, -}; - -struct ds_tizen_effect_event_type_set -{ - uint32_t pid; - enum ds_tizen_effect_type effect_type; -}; - -struct ds_tizen_effect_event_type_unset -{ - uint32_t pid; -}; - -struct ds_tizen_effect_event_new_splash -{ - struct ds_tizen_splash *splash; -}; - -enum ds_tizen_splash_file_type -{ - DS_TIZEN_SPLASH_FILE_TYPE_ERR = -1, - DS_TIZEN_SPLASH_FILE_TYPE_IMG, - DS_TIZEN_SPLASH_FILE_TYPE_EDJ, -}; - -struct ds_tizen_splash_event_owner -{ - uint32_t pid; -}; - -// launch_effect -struct ds_tizen_effect * -ds_tizen_effect_create(struct wl_display *display); - -void -ds_tizen_effect_add_destroy_listener( - struct ds_tizen_effect *effect, struct wl_listener *listener); -void -ds_tizen_effect_add_type_set_listener( - struct ds_tizen_effect *effect, struct wl_listener *listener); -void -ds_tizen_effect_add_type_unset_listener(struct ds_tizen_effect *effect, - struct wl_listener *listener); -void -ds_tizen_effect_add_new_splash_listener(struct ds_tizen_effect *effect, - struct wl_listener *listener); - -void -ds_tizen_effect_set_effect_type(struct ds_tizen_effect *effect, - uint32_t pid, int effect_type); -void -ds_tizen_effect_unset_effect_type(struct ds_tizen_effect *effect, - uint32_t pid); -int -ds_tizen_effect_get_effect_type(struct ds_tizen_effect *effect, - uint32_t pid); - -// launch_splash -void -ds_tizen_splash_add_destroy_listener( - struct ds_tizen_splash *splash, struct wl_listener *listener); -void -ds_tizen_splash_add_owner_listener( - struct ds_tizen_splash *splash, struct wl_listener *listener); - -uint32_t -ds_tizen_splash_get_pid(struct ds_tizen_splash *splash); -void -ds_tizen_splash_set_pid(struct ds_tizen_splash *splash, uint32_t pid); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 710ac9b..8b36016 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -410,8 +410,7 @@ ninja -C builddir install %manifest %{name}.manifest %defattr(-,root,root,-) %license LICENSE -%{_includedir}/libds-tizen/launch/appinfo.h -%{_includedir}/libds-tizen/launch/effect.h +%{_includedir}/libds-tizen/launch.h %{_libdir}/pkgconfig/libds-tizen-launch.pc %{_libdir}/libds-tizen-launch.so %{_bindir}/libds-tizen-launch-appinfo-tests diff --git a/src/launch/appinfo.c b/src/launch/appinfo.c index 0b6c8c2..b079836 100644 --- a/src/launch/appinfo.c +++ b/src/launch/appinfo.c @@ -4,11 +4,11 @@ #include #include "util.h" -#include +#include #define TIZEN_APPINFO_VERSION 1 -struct ds_tizen_appinfo_mgr +struct ds_tizen_launch_appinfo_mgr { struct wl_global *global; @@ -27,34 +27,34 @@ struct ds_tizen_appinfo_mgr struct wl_resource *resource; //for gtest }; -struct ds_tizen_appinfo_client +struct ds_tizen_launch_appinfo_client { - struct ds_tizen_appinfo_mgr *appinfo_mgr; + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr; struct wl_resource *resource; struct wl_client *wl_client; - struct wl_list link; // ds_tizen_appinfo_mgr::clients + struct wl_list link; // ds_tizen_launch_appinfo_mgr::clients }; -enum ds_tizen_appinfo_owner +enum ds_tizen_launch_appinfo_owner { - DS_TIZEN_APPINFO_OWNER_SERVER, - DS_TIZEN_APPINFO_OWNER_CLIENT, + DS_TIZEN_LAUNCH_APPINFO_OWNER_SERVER, + DS_TIZEN_LAUNCH_APPINFO_OWNER_CLIENT, }; -struct ds_tizen_appinfo +struct ds_tizen_launch_appinfo { - struct ds_tizen_appinfo_mgr *appinfo_mgr; + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr; pid_t pid; char *appid; bool base_output_available; int base_output_width; int base_output_height; - enum ds_tizen_appinfo_owner owner; + enum ds_tizen_launch_appinfo_owner owner; - struct wl_list link; //ds_tizen_appinfo_mgr::infos; + struct wl_list link; //ds_tizen_launch_appinfo_mgr::infos; }; static void appinfo_mgr_handle_display_destroy(struct wl_listener *listener, @@ -63,10 +63,10 @@ static void appinfo_mgr_handle_display_destroy(struct wl_listener *listener, static void appinfo_mgr_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id); -WL_EXPORT struct ds_tizen_appinfo_mgr * -ds_tizen_appinfo_mgr_create(struct wl_display *display) +WL_EXPORT struct ds_tizen_launch_appinfo_mgr * +ds_tizen_launch_appinfo_mgr_create(struct wl_display *display) { - struct ds_tizen_appinfo_mgr *appinfo_mgr; + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr; appinfo_mgr = calloc(1, sizeof *appinfo_mgr); if (!appinfo_mgr) { @@ -99,29 +99,29 @@ ds_tizen_appinfo_mgr_create(struct wl_display *display) } WL_EXPORT void -ds_tizen_appinfo_mgr_add_destroy_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) +ds_tizen_launch_appinfo_mgr_add_destroy_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) { wl_signal_add(&appinfo_mgr->events.destroy, listener); } WL_EXPORT void -ds_tizen_appinfo_mgr_add_set_pid_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) +ds_tizen_launch_appinfo_mgr_add_set_pid_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) { wl_signal_add(&appinfo_mgr->events.set_pid, listener); } WL_EXPORT void -ds_tizen_appinfo_mgr_add_set_appid_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) +ds_tizen_launch_appinfo_mgr_add_set_appid_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) { wl_signal_add(&appinfo_mgr->events.set_appid, listener); } WL_EXPORT void -ds_tizen_appinfo_mgr_add_metadata_ready_listener( - struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) +ds_tizen_launch_appinfo_mgr_add_metadata_ready_listener( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener) { wl_signal_add(&appinfo_mgr->events.metadata_ready, listener); } @@ -129,9 +129,9 @@ ds_tizen_appinfo_mgr_add_metadata_ready_listener( static void appinfo_mgr_handle_display_destroy(struct wl_listener *listener, void *data) { - struct ds_tizen_appinfo_mgr *appinfo_mgr; - struct ds_tizen_appinfo_client *client, *tmp_client; - struct ds_tizen_appinfo *info, *tmp_info; + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr; + struct ds_tizen_launch_appinfo_client *client, *tmp_client; + struct ds_tizen_launch_appinfo *info, *tmp_info; appinfo_mgr = wl_container_of(listener, appinfo_mgr, destroy); @@ -161,11 +161,11 @@ appinfo_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource wl_resource_destroy(resource); } -static struct ds_tizen_appinfo * -appinfo_mgr_find_with_pid(struct ds_tizen_appinfo_mgr *appinfo_mgr, +static struct ds_tizen_launch_appinfo * +appinfo_mgr_find_with_pid(struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, pid_t pid) { - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo *info; wl_list_for_each(info, &appinfo_mgr->infos, link) { if (pid == info->pid) @@ -175,11 +175,11 @@ appinfo_mgr_find_with_pid(struct ds_tizen_appinfo_mgr *appinfo_mgr, return NULL; } -static struct ds_tizen_appinfo * -appinfo_mgr_find_with_appid(struct ds_tizen_appinfo_mgr *appinfo_mgr, +static struct ds_tizen_launch_appinfo * +appinfo_mgr_find_with_appid(struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, const char *appid) { - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo *info; wl_list_for_each(info, &appinfo_mgr->infos, link) { if (appid && !strcmp(appid, info->appid)) @@ -188,11 +188,11 @@ appinfo_mgr_find_with_appid(struct ds_tizen_appinfo_mgr *appinfo_mgr, return NULL; } -static struct ds_tizen_appinfo * -appinfo_mgr_get_info(struct ds_tizen_appinfo_mgr *appinfo_mgr, +static struct ds_tizen_launch_appinfo * +appinfo_mgr_get_info(struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, pid_t pid, const char *appid) { - struct ds_tizen_appinfo *info = NULL; + struct ds_tizen_launch_appinfo *info = NULL; if (pid > 0) info = appinfo_mgr_find_with_pid(appinfo_mgr, pid); @@ -222,7 +222,7 @@ appinfo_mgr_get_info(struct ds_tizen_appinfo_mgr *appinfo_mgr, } static void -appinfo_destroy(struct ds_tizen_appinfo *info) +appinfo_destroy(struct ds_tizen_launch_appinfo *info) { wl_list_remove(&info->link); free(info->appid); @@ -230,10 +230,10 @@ appinfo_destroy(struct ds_tizen_appinfo *info) } static bool -appinfo_set_pid(struct ds_tizen_appinfo *info, pid_t pid) +appinfo_set_pid(struct ds_tizen_launch_appinfo *info, pid_t pid) { - struct ds_tizen_appinfo_mgr *appinfo_mgr; - struct ds_tizen_appinfo *info2, *tmp; + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr; + struct ds_tizen_launch_appinfo *info2, *tmp; if (!info) return false; if (pid < 0) return false; @@ -264,10 +264,10 @@ appinfo_set_pid(struct ds_tizen_appinfo *info, pid_t pid) } static bool -appinfo_set_appid(struct ds_tizen_appinfo *info, const char *appid) +appinfo_set_appid(struct ds_tizen_launch_appinfo *info, const char *appid) { - struct ds_tizen_appinfo_mgr *appinfo_mgr; - struct ds_tizen_appinfo *info2, *tmp; + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr; + struct ds_tizen_launch_appinfo *info2, *tmp; if (!info) return false; if (!appid) return false; @@ -301,7 +301,7 @@ appinfo_set_appid(struct ds_tizen_appinfo *info, const char *appid) } static bool -appinfo_get_base_output_resolution(struct ds_tizen_appinfo *info, int *width, int *height) +appinfo_get_base_output_resolution(struct ds_tizen_launch_appinfo *info, int *width, int *height) { if (!info) return false; if (!width) return false; @@ -319,7 +319,7 @@ appinfo_get_base_output_resolution(struct ds_tizen_appinfo *info, int *width, in } static void -appinfo_set_owner(struct ds_tizen_appinfo *info, enum ds_tizen_appinfo_owner owner) +appinfo_set_owner(struct ds_tizen_launch_appinfo *info, enum ds_tizen_launch_appinfo_owner owner) { if (!info) return; @@ -330,8 +330,8 @@ static void appinfo_handle_register_pid(struct wl_client *wl_client, struct wl_resource *resource, uint32_t pid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; client = wl_resource_get_user_data(resource); @@ -348,7 +348,7 @@ appinfo_handle_register_pid(struct wl_client *wl_client, } appinfo_set_pid(info, pid); - appinfo_set_owner(info, DS_TIZEN_APPINFO_OWNER_CLIENT); + appinfo_set_owner(info, DS_TIZEN_LAUNCH_APPINFO_OWNER_CLIENT); } @@ -356,8 +356,8 @@ static void appinfo_handle_deregister_pid(struct wl_client *wl_client, struct wl_resource *resource, uint32_t pid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; client = wl_resource_get_user_data(resource); @@ -374,8 +374,8 @@ static void appinfo_handle_set_appid(struct wl_client *wl_client, struct wl_resource *resource, uint32_t pid, const char *appid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; client = wl_resource_get_user_data(resource); @@ -397,8 +397,8 @@ appinfo_handle_set_appid(struct wl_client *wl_client, //for gtest WL_EXPORT struct wl_resource * -ds_tizen_appinfo_mgr_get_appinfo_resource( - struct ds_tizen_appinfo_mgr *appinfo_mgr) +ds_tizen_launch_appinfo_mgr_get_appinfo_resource( + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr) { return appinfo_mgr->resource; } @@ -407,8 +407,8 @@ static void appinfo_handle_get_base_output_resolution(struct wl_client *wl_client, struct wl_resource *resource, uint32_t pid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; int width = 0, height = 0; client = wl_resource_get_user_data(resource); @@ -442,8 +442,8 @@ static void appinfo_handle_register_appid(struct wl_client *wl_client, struct wl_resource *resource, const char *appid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; client = wl_resource_get_user_data(resource); @@ -455,15 +455,15 @@ appinfo_handle_register_appid(struct wl_client *wl_client, struct wl_resource *r } appinfo_set_appid(info, appid); - appinfo_set_owner(info, DS_TIZEN_APPINFO_OWNER_CLIENT); + appinfo_set_owner(info, DS_TIZEN_LAUNCH_APPINFO_OWNER_CLIENT); } static void appinfo_handle_deregister_appid(struct wl_client *wl_client, struct wl_resource *resource, const char *appid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; client = wl_resource_get_user_data(resource); @@ -480,8 +480,8 @@ static void appinfo_handle_set_pid(struct wl_client *wl_client, struct wl_resource *resource, const char *appid, uint32_t pid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; client = wl_resource_get_user_data(resource); @@ -498,8 +498,8 @@ static void appinfo_handle_ready_metadata(struct wl_client *wl_client, struct wl_resource *resource, const char *appid, uint32_t pid) { - struct ds_tizen_appinfo_client *client; - struct ds_tizen_appinfo *info; + struct ds_tizen_launch_appinfo_client *client; + struct ds_tizen_launch_appinfo *info; client = wl_resource_get_user_data(resource); @@ -533,7 +533,7 @@ static const struct tizen_launch_appinfo_interface appinfo_impl = static void _tizen_appinfo_client_handle_destroy(struct wl_resource *resource) { - struct ds_tizen_appinfo_client *client; + struct ds_tizen_launch_appinfo_client *client; client = wl_resource_get_user_data(resource); @@ -546,8 +546,8 @@ _tizen_appinfo_client_handle_destroy(struct wl_resource *resource) static void appinfo_mgr_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id) { - struct ds_tizen_appinfo_mgr *appinfo_mgr = data; - struct ds_tizen_appinfo_client *client; + struct ds_tizen_launch_appinfo_mgr *appinfo_mgr = data; + struct ds_tizen_launch_appinfo_client *client; client = calloc(1, sizeof *client); if (client == NULL) { diff --git a/src/launch/effect.c b/src/launch/effect.c index fc38c77..3ad0bea 100644 --- a/src/launch/effect.c +++ b/src/launch/effect.c @@ -4,13 +4,13 @@ #include #include "util.h" -#include +#include #define TIZEN_EFFECT_VERSION 1 #define SPLASH_CLIENT_PID 321 // no meaning #define CUSTOM_EFFECT_CALLEE "_CUSTOM_EFFECT_CALLEE_" -struct ds_tizen_effect +struct ds_tizen_launch_effect { struct wl_global *global; @@ -27,31 +27,31 @@ struct ds_tizen_effect } events; }; -struct ds_tizen_effect_client +struct ds_tizen_launch_effect_client { - struct ds_tizen_effect *effect; + struct ds_tizen_launch_effect *effect; struct wl_resource *resource; struct wl_client *wl_client; struct wl_list splashs; - struct wl_list link; // ds_tizen_effect::clients + struct wl_list link; // ds_tizen_launch_effect::clients }; -struct ds_tizen_effect_info +struct ds_tizen_launch_effect_info { uint32_t pid; int effect_type; - struct wl_list link; // ds_tizen_effect::infos + struct wl_list link; // ds_tizen_launch_effect::infos }; -struct ds_tizen_splash +struct ds_tizen_launch_splash { - struct ds_tizen_effect *effect; + struct ds_tizen_launch_effect *effect; - struct ds_tizen_effect_client *client; + struct ds_tizen_launch_effect_client *client; struct wl_resource *resource; uint32_t pid; @@ -63,7 +63,7 @@ struct ds_tizen_splash struct wl_signal owner; } events; - struct wl_list link; // ds_tizen_effect_client::splashs + struct wl_list link; // ds_tizen_launch_effect_client::splashs }; static void effect_handle_display_destroy(struct wl_listener *listener, @@ -72,10 +72,10 @@ static void effect_handle_display_destroy(struct wl_listener *listener, static void effect_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id); -WL_EXPORT struct ds_tizen_effect * -ds_tizen_effect_create(struct wl_display *display) +WL_EXPORT struct ds_tizen_launch_effect * +ds_tizen_launch_effect_create(struct wl_display *display) { - struct ds_tizen_effect *effect; + struct ds_tizen_launch_effect *effect; effect = calloc(1, sizeof *effect); if (!effect) { @@ -109,40 +109,40 @@ ds_tizen_effect_create(struct wl_display *display) //launch_effect WL_EXPORT void -ds_tizen_effect_add_destroy_listener( - struct ds_tizen_effect *effect, struct wl_listener *listener) +ds_tizen_launch_effect_add_destroy_listener( + struct ds_tizen_launch_effect *effect, struct wl_listener *listener) { wl_signal_add(&effect->events.destroy, listener); } WL_EXPORT void -ds_tizen_effect_add_type_set_listener( - struct ds_tizen_effect *effect, struct wl_listener *listener) +ds_tizen_launch_effect_add_type_set_listener( + struct ds_tizen_launch_effect *effect, struct wl_listener *listener) { wl_signal_add(&effect->events.type_set, listener); } WL_EXPORT void -ds_tizen_effect_add_type_unset_listener( - struct ds_tizen_effect *effect, struct wl_listener *listener) +ds_tizen_launch_effect_add_type_unset_listener( + struct ds_tizen_launch_effect *effect, struct wl_listener *listener) { wl_signal_add(&effect->events.type_unset, listener); } WL_EXPORT void -ds_tizen_effect_add_new_splash_listener( - struct ds_tizen_effect *effect, struct wl_listener *listener) +ds_tizen_launch_effect_add_new_splash_listener( + struct ds_tizen_launch_effect *effect, struct wl_listener *listener) { wl_signal_add(&effect->events.new_splash, listener); } WL_EXPORT void -ds_tizen_effect_set_effect_type(struct ds_tizen_effect *effect, +ds_tizen_launch_effect_set_effect_type(struct ds_tizen_launch_effect *effect, uint32_t pid, int effect_type) { - struct ds_tizen_effect_info *info; + struct ds_tizen_launch_effect_info *info; - ds_inf("ds_tizen_effect_set_effect_type() pid(%u), effect_type(%d)", pid, effect_type); + ds_inf("ds_tizen_launch_effect_set_effect_type() pid(%u), effect_type(%d)", pid, effect_type); info = calloc(1, sizeof *info); if (info == NULL) { @@ -156,16 +156,16 @@ ds_tizen_effect_set_effect_type(struct ds_tizen_effect *effect, } WL_EXPORT void -ds_tizen_effect_unset_effect_type(struct ds_tizen_effect *effect, +ds_tizen_launch_effect_unset_effect_type(struct ds_tizen_launch_effect *effect, uint32_t pid) { - struct ds_tizen_effect_info *info, *tmp; + struct ds_tizen_launch_effect_info *info, *tmp; - ds_inf("ds_tizen_effect_unset_effect_type() pid(%u)", pid); + ds_inf("ds_tizen_launch_effect_unset_effect_type() pid(%u)", pid); wl_list_for_each_safe(info, tmp, &effect->infos, link) { if (info->pid == pid) { - ds_inf("ds_tizen_effect_unset_effect_type() pid found.", pid); + ds_inf("ds_tizen_launch_effect_unset_effect_type() pid found.", pid); wl_list_remove(&info->link); free(info); } @@ -173,12 +173,12 @@ ds_tizen_effect_unset_effect_type(struct ds_tizen_effect *effect, } WL_EXPORT int -ds_tizen_effect_get_effect_type(struct ds_tizen_effect *effect, +ds_tizen_launch_effect_get_effect_type(struct ds_tizen_launch_effect *effect, uint32_t pid) { - struct ds_tizen_effect_info *info; + struct ds_tizen_launch_effect_info *info; - ds_inf("ds_tizen_effect_get_effect_type() pid(%u)", pid); + ds_inf("ds_tizen_launch_effect_get_effect_type() pid(%u)", pid); wl_list_for_each(info, &effect->infos, link) { if (info->pid == pid) { @@ -190,35 +190,35 @@ ds_tizen_effect_get_effect_type(struct ds_tizen_effect *effect, //launch_splash WL_EXPORT void -ds_tizen_splash_add_destroy_listener( - struct ds_tizen_splash *splash, struct wl_listener *listener) +ds_tizen_launch_splash_add_destroy_listener( + struct ds_tizen_launch_splash *splash, struct wl_listener *listener) { wl_signal_add(&splash->events.destroy, listener); } WL_EXPORT void -ds_tizen_splash_add_owner_listener( - struct ds_tizen_splash *splash, struct wl_listener *listener) +ds_tizen_launch_splash_add_owner_listener( + struct ds_tizen_launch_splash *splash, struct wl_listener *listener) { wl_signal_add(&splash->events.owner, listener); } WL_EXPORT uint32_t -ds_tizen_splash_get_pid(struct ds_tizen_splash *splash) +ds_tizen_launch_splash_get_pid(struct ds_tizen_launch_splash *splash) { return splash->pid; } WL_EXPORT void -ds_tizen_splash_set_pid(struct ds_tizen_splash *splash, uint32_t pid) +ds_tizen_launch_splash_set_pid(struct ds_tizen_launch_splash *splash, uint32_t pid) { splash->pid = pid; } static void -effect_client_destroy(struct ds_tizen_effect_client *client) +effect_client_destroy(struct ds_tizen_launch_effect_client *client) { - struct ds_tizen_splash *splash, *tmp; + struct ds_tizen_launch_splash *splash, *tmp; wl_list_for_each_safe(splash, tmp, &client->splashs, link) { wl_signal_emit(&splash->events.destroy, splash); @@ -233,9 +233,9 @@ effect_client_destroy(struct ds_tizen_effect_client *client) static void effect_handle_display_destroy(struct wl_listener *listener, void *data) { - struct ds_tizen_effect *effect; - struct ds_tizen_effect_client *client, *tmp_client; - struct ds_tizen_effect_info *info, *tmp_info; + struct ds_tizen_launch_effect *effect; + struct ds_tizen_launch_effect_client *client, *tmp_client; + struct ds_tizen_launch_effect_info *info, *tmp_info; effect = wl_container_of(listener, effect, destroy); @@ -260,12 +260,12 @@ static void effect_handle_display_destroy(struct wl_listener *listener, static int effect_get_effect_type(const char *effect_type) { - enum ds_tizen_effect_type type = 0; + enum ds_tizen_launch_effect_type type = 0; if (!effect_type) return 0; - if (!strncmp(effect_type, "launch", sizeof("launch"))) type = DS_TIZEN_EFFECT_TYPE_LAUNCH; - else if (!strncmp(effect_type, "depth-in", sizeof("depth-in"))) type = DS_TIZEN_EFFECT_TYPE_DEPTH_IN; + if (!strncmp(effect_type, "launch", sizeof("launch"))) type = DS_TIZEN_LAUNCH_EFFECT_TYPE_LAUNCH; + else if (!strncmp(effect_type, "depth-in", sizeof("depth-in"))) type = DS_TIZEN_LAUNCH_EFFECT_TYPE_DEPTH_IN; return type; } @@ -283,13 +283,13 @@ splash_handle_launch(struct wl_client *wl_client, const char *effect_type, const char *theme_type, struct wl_array *options) { - struct ds_tizen_effect_event_type_set ds_event; - struct ds_tizen_splash *splash; - struct ds_tizen_effect *effect; + struct ds_tizen_launch_effect_event_type_set ds_event; + struct ds_tizen_launch_splash *splash; + struct ds_tizen_launch_effect *effect; ds_inf("splash launch"); ds_inf("path %s(%s), indicator(%d), angle(%d), effect_type(%s)", - pfname, (ftype == DS_TIZEN_SPLASH_FILE_TYPE_IMG) ? "IMG" : "EDC", indicator, angle, effect_type); + pfname, (ftype == DS_TIZEN_LAUNCH_SPLASH_FILE_TYPE_IMG) ? "IMG" : "EDC", indicator, angle, effect_type); ds_inf("theme_type(%s), options(%p)",theme_type, options); splash = wl_resource_get_user_data(resource); @@ -309,8 +309,8 @@ static void splash_handle_owner(struct wl_client *wl_client, struct wl_resource *resource, uint32_t pid) { - struct ds_tizen_splash *splash; - struct ds_tizen_splash_event_owner ds_event; + struct ds_tizen_launch_splash *splash; + struct ds_tizen_launch_splash_event_owner ds_event; ds_inf("splash set owner. pid:%u", pid); @@ -327,13 +327,13 @@ splash_handle_launch_v2(struct wl_client *wl_client, const char *effect_type, const char *theme_type, struct wl_array *options, struct wl_array *extra_config) { - struct ds_tizen_effect_event_type_set ds_event; - struct ds_tizen_splash *splash; - struct ds_tizen_effect *effect; + struct ds_tizen_launch_effect_event_type_set ds_event; + struct ds_tizen_launch_splash *splash; + struct ds_tizen_launch_effect *effect; ds_inf("splash launch_v2"); ds_inf("path %s(%s), indicator(%d), angle(%d), effect_type(%s)", - pfname, (ftype == DS_TIZEN_SPLASH_FILE_TYPE_IMG) ? "IMG" : "EDC", indicator, angle, effect_type); + pfname, (ftype == DS_TIZEN_LAUNCH_SPLASH_FILE_TYPE_IMG) ? "IMG" : "EDC", indicator, angle, effect_type); ds_inf("theme_type(%s) options(%p) extra_config(%p)", theme_type, options, extra_config); splash = wl_resource_get_user_data(resource); @@ -389,7 +389,7 @@ static const struct tizen_launch_splash_interface splash_impl = static void splash_client_handle_destroy(struct wl_resource *resource) { - struct ds_tizen_splash *splash; + struct ds_tizen_launch_splash *splash; splash = wl_resource_get_user_data(resource); @@ -400,10 +400,10 @@ splash_client_handle_destroy(struct wl_resource *resource) free(splash); } -struct ds_tizen_splash* -splash_create_splash_img(struct ds_tizen_effect_client *client, uint32_t id) +struct ds_tizen_launch_splash* +splash_create_splash_img(struct ds_tizen_launch_effect_client *client, uint32_t id) { - struct ds_tizen_splash *splash; + struct ds_tizen_launch_splash *splash; splash = calloc(1, sizeof *splash); if (!splash) { @@ -440,18 +440,16 @@ static void effect_handle_create_splash_img(struct wl_client *wl_client, struct wl_resource *resource, uint32_t id) { - struct ds_tizen_effect *effect; - struct ds_tizen_effect_client *client; - struct ds_tizen_effect_event_new_splash ds_event; - struct ds_tizen_splash *splash; + struct ds_tizen_launch_effect *effect; + struct ds_tizen_launch_effect_client *client; + struct ds_tizen_launch_splash *splash; client = wl_resource_get_user_data(resource); splash = splash_create_splash_img(client, id); if (!splash) return; effect = client->effect; - ds_event.splash = splash; - wl_signal_emit(&effect->events.new_splash, &ds_event); + wl_signal_emit(&effect->events.new_splash, splash); } static void @@ -459,9 +457,9 @@ effect_handle_type_set(struct wl_client *wl_client, struct wl_resource *resource, const char *effect_type, uint32_t pid, struct wl_array *options) { - struct ds_tizen_effect *effect; - struct ds_tizen_effect_client *client; - struct ds_tizen_effect_event_type_set ds_event; + struct ds_tizen_launch_effect *effect; + struct ds_tizen_launch_effect_client *client; + struct ds_tizen_launch_effect_event_type_set ds_event; client = wl_resource_get_user_data(resource); effect = client->effect; @@ -478,9 +476,9 @@ static void effect_handle_type_unset(struct wl_client *wl_client, struct wl_resource *resource, uint32_t pid) { - struct ds_tizen_effect *effect; - struct ds_tizen_effect_client *client; - struct ds_tizen_effect_event_type_unset ds_event; + struct ds_tizen_launch_effect *effect; + struct ds_tizen_launch_effect_client *client; + struct ds_tizen_launch_effect_event_type_unset ds_event; client = wl_resource_get_user_data(resource); effect = client->effect; @@ -510,7 +508,7 @@ static const struct tizen_launch_effect_interface effect_impl = static void effect_client_handle_destroy(struct wl_resource *resource) { - struct ds_tizen_effect_client *client; + struct ds_tizen_launch_effect_client *client; client = wl_resource_get_user_data(resource); @@ -522,8 +520,8 @@ effect_client_handle_destroy(struct wl_resource *resource) static void effect_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id) { - struct ds_tizen_effect *effect = data; - struct ds_tizen_effect_client *client; + struct ds_tizen_launch_effect *effect = data; + struct ds_tizen_launch_effect_client *client; client = calloc(1, sizeof *client); if (client == NULL) { diff --git a/tests/tc_launch_appinfo.cpp b/tests/tc_launch_appinfo.cpp index 9e7bab1..15630d6 100644 --- a/tests/tc_launch_appinfo.cpp +++ b/tests/tc_launch_appinfo.cpp @@ -1,17 +1,17 @@ #include "tc_main.h" #include "mockclient.h" #include "mockcompositor.h" -#include +#include #include #include #define TIZEN_APPINFO_VERSION 1 -class MockAppinfoCompositor : public MockCompositor +class MockLaunchAppinfoCompositor : public MockCompositor { public: - MockAppinfoCompositor() - : MockCompositor(&MockAppinfoCompositor::TestSetup, this) + MockLaunchAppinfoCompositor() + : MockCompositor(&MockLaunchAppinfoCompositor::TestSetup, this) { ds_inf("%s : this(%p)", __func__, this); @@ -23,47 +23,47 @@ public: bMetadataReady = false; } - ~MockAppinfoCompositor() + ~MockLaunchAppinfoCompositor() { ds_inf("%s : this(%p)", __func__, this); } static void TestSetup(void *data) { - MockAppinfoCompositor *mockComp = - static_cast(data); + MockLaunchAppinfoCompositor *mockComp = + static_cast(data); Compositor *comp = mockComp->compositor; ds_inf("%s: mockComp(%p)", __func__, mockComp); - mockComp->mAppinfoMgr = ds_tizen_appinfo_mgr_create(comp->display); + mockComp->mAppinfoMgr = ds_tizen_launch_appinfo_mgr_create(comp->display); // destroy listener mockComp->mDestroyListener.notify = - MockAppinfoCompositor::DestroyCallback; + MockLaunchAppinfoCompositor::DestroyCallback; mockComp->mDestroyListener.parent = mockComp; - ds_tizen_appinfo_mgr_add_destroy_listener(mockComp->mAppinfoMgr, + ds_tizen_launch_appinfo_mgr_add_destroy_listener(mockComp->mAppinfoMgr, &mockComp->mDestroyListener); // set_pid listener mockComp->mSetPidListener.notify = - MockAppinfoCompositor::SetPidCallback; + MockLaunchAppinfoCompositor::SetPidCallback; mockComp->mSetPidListener.parent = mockComp; - ds_tizen_appinfo_mgr_add_set_pid_listener(mockComp->mAppinfoMgr, + ds_tizen_launch_appinfo_mgr_add_set_pid_listener(mockComp->mAppinfoMgr, &mockComp->mSetPidListener); // set_appid listener mockComp->mSetAppidListener.notify = - MockAppinfoCompositor::SetAppidCallback; + MockLaunchAppinfoCompositor::SetAppidCallback; mockComp->mSetAppidListener.parent = mockComp; - ds_tizen_appinfo_mgr_add_set_appid_listener(mockComp->mAppinfoMgr, + ds_tizen_launch_appinfo_mgr_add_set_appid_listener(mockComp->mAppinfoMgr, &mockComp->mSetAppidListener); // metadata_ready listener mockComp->mMetadataReadyListener.notify = - MockAppinfoCompositor::MetadataReadyCallback; + MockLaunchAppinfoCompositor::MetadataReadyCallback; mockComp->mMetadataReadyListener.parent = mockComp; - ds_tizen_appinfo_mgr_add_metadata_ready_listener( + ds_tizen_launch_appinfo_mgr_add_metadata_ready_listener( mockComp->mAppinfoMgr, &mockComp->mMetadataReadyListener); } @@ -72,7 +72,7 @@ public: { ds_inf("%s", __func__); - MockAppinfoCompositor *mockComp = + MockLaunchAppinfoCompositor *mockComp = reinterpret_cast(listener)->parent; mockComp->bDestroyed = true; @@ -82,9 +82,9 @@ public: { ds_inf("%s", __func__); - MockAppinfoCompositor *mockComp = + MockLaunchAppinfoCompositor *mockComp = reinterpret_cast(listener)->parent; - struct ds_tizen_appinfo *info = static_cast(data); + struct ds_tizen_launch_appinfo *info = static_cast(data); ds_inf("%s: mockComp(%p), appinfo(%p)", __func__, mockComp, info); @@ -95,9 +95,9 @@ public: { ds_inf("%s", __func__); - MockAppinfoCompositor *mockComp = + MockLaunchAppinfoCompositor *mockComp = reinterpret_cast(listener)->parent; - struct ds_tizen_appinfo *info = static_cast(data); + struct ds_tizen_launch_appinfo *info = static_cast(data); ds_inf("%s: mockComp(%p), appinfo(%p)", __func__, mockComp, info); @@ -109,9 +109,9 @@ public: { ds_inf("%s", __func__); - MockAppinfoCompositor *mockComp = + MockLaunchAppinfoCompositor *mockComp = reinterpret_cast(listener)->parent; - struct ds_tizen_appinfo *info = static_cast(data); + struct ds_tizen_launch_appinfo *info = static_cast(data); ds_inf("%s: mockComp(%p), appinfo(%p)", __func__, mockComp, info); @@ -122,7 +122,7 @@ public: { ds_inf("%s", __func__); - wl_resource *res_appinfo = ds_tizen_appinfo_mgr_get_appinfo_resource(mAppinfoMgr); + wl_resource *res_appinfo = ds_tizen_launch_appinfo_mgr_get_appinfo_resource(mAppinfoMgr); tizen_launch_appinfo_send_base_output_resolution_done(res_appinfo, pid, width, height); } @@ -134,36 +134,36 @@ public: bool bMetadataReady; private: - struct ds_tizen_appinfo_mgr *mAppinfoMgr; + struct ds_tizen_launch_appinfo_mgr *mAppinfoMgr; struct DestroyListener: ::wl_listener { - MockAppinfoCompositor *parent; + MockLaunchAppinfoCompositor *parent; }; DestroyListener mDestroyListener; struct SetPidListener: ::wl_listener { - MockAppinfoCompositor *parent; + MockLaunchAppinfoCompositor *parent; }; SetPidListener mSetPidListener; struct SetAppidListener: ::wl_listener { - MockAppinfoCompositor *parent; + MockLaunchAppinfoCompositor *parent; }; SetAppidListener mSetAppidListener; struct MetadataReadyListener: ::wl_listener { - MockAppinfoCompositor *parent; + MockLaunchAppinfoCompositor *parent; }; MetadataReadyListener mMetadataReadyListener; }; -class MockAppinfoClient : public MockClient +class MockLaunchAppinfoClient : public MockClient { public: - MockAppinfoClient() + MockLaunchAppinfoClient() : bBaseOutputResolutionDone(false), mBaseOutputResolutionWidth(0), mBaseOutputResolutionHeight(0), compositor_res(nullptr), tizen_launch_appinfo(nullptr) {} - MockAppinfoClient(const struct wl_registry_listener *listener) + MockLaunchAppinfoClient(const struct wl_registry_listener *listener) : MockClient(listener, this) { ds_inf("%s", __func__); @@ -172,7 +172,7 @@ public: mBaseOutputResolutionWidth = 0; mBaseOutputResolutionHeight = 0; } - ~MockAppinfoClient() + ~MockLaunchAppinfoClient() { ds_inf("%s", __func__); } @@ -191,13 +191,13 @@ public: return compositor_res; } - void SetTizenAppinfo(struct tizen_launch_appinfo *global_res) + void SetTizenLaunchAppinfo(struct tizen_launch_appinfo *global_res) { ds_inf("%s", __func__); tizen_launch_appinfo = global_res; } - struct tizen_launch_appinfo *GetTizenAppinfo() + struct tizen_launch_appinfo *GetTizenLaunchAppinfo() { ds_inf("%s", __func__); @@ -221,7 +221,7 @@ client_tizen_appinfo_cb_base_output_resolution_done(void *data, { ds_inf("%s", __func__); - MockAppinfoClient *client = static_cast(data); + MockLaunchAppinfoClient *client = static_cast(data); client->bBaseOutputResolutionDone = true; client->mBaseOutputResolutionWidth = width; @@ -238,7 +238,7 @@ client_registry_cb_global(void *data, struct wl_registry *registry, { ds_inf("%s", __func__); - MockAppinfoClient *client = static_cast(data); + MockLaunchAppinfoClient *client = static_cast(data); struct wl_compositor *compositor_res; struct tizen_launch_appinfo *tizen_launch_appinfo; @@ -257,7 +257,7 @@ client_registry_cb_global(void *data, struct wl_registry *registry, ds_err("wl_registry_bind() failed. tizen_launch_appinfo resource."); return; } - client->SetTizenAppinfo(tizen_launch_appinfo); + client->SetTizenLaunchAppinfo(tizen_launch_appinfo); tizen_launch_appinfo_add_listener(tizen_launch_appinfo, &appinfo_cb_listener, client); @@ -270,9 +270,9 @@ client_registry_cb_global_remove(void *data, struct wl_registry *registry, { ds_inf("%s", __func__); - MockAppinfoClient *client = static_cast(data); + MockLaunchAppinfoClient *client = static_cast(data); struct wl_compositor *compositor_res = client->GetWlCompositor(); - struct tizen_launch_appinfo *appinfo_res = client->GetTizenAppinfo(); + struct tizen_launch_appinfo *appinfo_res = client->GetTizenLaunchAppinfo(); tizen_launch_appinfo_destroy(appinfo_res); wl_compositor_destroy(compositor_res); @@ -283,33 +283,33 @@ static const struct wl_registry_listener registry_listener = { .global_remove = client_registry_cb_global_remove }; -class AppinfoTest : public ::testing::Test +class LaunchAppinfoTest : public ::testing::Test { public: void SetUp(void) override; void TearDown(void) override; - MockAppinfoCompositor *comp; - MockAppinfoClient *client; + MockLaunchAppinfoCompositor *comp; + MockLaunchAppinfoClient *client; struct wl_compositor *compositor_res; struct tizen_launch_appinfo *appinfo_res; }; void -AppinfoTest::SetUp(void) +LaunchAppinfoTest::SetUp(void) { ds_inf("%s", __func__); - comp = new MockAppinfoCompositor(); - client = new MockAppinfoClient(®istry_listener); + comp = new MockLaunchAppinfoCompositor(); + client = new MockLaunchAppinfoClient(®istry_listener); compositor_res = client->GetWlCompositor(); - appinfo_res = client->GetTizenAppinfo(); + appinfo_res = client->GetTizenLaunchAppinfo(); client->RoundTrip(); } void -AppinfoTest::TearDown(void) +LaunchAppinfoTest::TearDown(void) { ds_inf("%s", __func__); @@ -319,12 +319,12 @@ AppinfoTest::TearDown(void) delete comp; } -TEST_F(AppinfoTest, Create_P) +TEST_F(LaunchAppinfoTest, Create_P) { EXPECT_TRUE(true); } -TEST_F(AppinfoTest, Req_TizenAppinfoRegisterPid) +TEST_F(LaunchAppinfoTest, Req_TizenLaunchAppinfoRegisterPid) { uint32_t pid = 1234; @@ -333,7 +333,7 @@ TEST_F(AppinfoTest, Req_TizenAppinfoRegisterPid) EXPECT_TRUE(comp->bSetPid); } -TEST_F(AppinfoTest, Req_TizenAppinfoSetAppid) +TEST_F(LaunchAppinfoTest, Req_TizenLaunchAppinfoSetAppid) { uint32_t pid = 1234; const char *appid = "org.tizen.libds-tizen-appinfo-test"; @@ -347,7 +347,7 @@ TEST_F(AppinfoTest, Req_TizenAppinfoSetAppid) EXPECT_TRUE(comp->bSetAppid); } -TEST_F(AppinfoTest, Req_TizenAppinfoRegisterAppid) +TEST_F(LaunchAppinfoTest, Req_TizenLaunchAppinfoRegisterAppid) { const char *appid = "org.tizen.libds-tizen-appinfo-test"; @@ -356,7 +356,7 @@ TEST_F(AppinfoTest, Req_TizenAppinfoRegisterAppid) EXPECT_TRUE(comp->bSetAppid); } -TEST_F(AppinfoTest, Req_TizenAppinfoSetPid) +TEST_F(LaunchAppinfoTest, Req_TizenLaunchAppinfoSetPid) { uint32_t pid = 1234; const char *appid = "org.tizen.libds-tizen-appinfo-test"; @@ -370,7 +370,7 @@ TEST_F(AppinfoTest, Req_TizenAppinfoSetPid) EXPECT_TRUE(comp->bSetPid); } -TEST_F(AppinfoTest, Req_TizenAppinfoMetadataReady) +TEST_F(LaunchAppinfoTest, Req_TizenLaunchAppinfoMetadataReady) { const char *appid = "org.tizen.libds-tizen-appinfo-test"; uint32_t pid = 1234; @@ -384,7 +384,7 @@ TEST_F(AppinfoTest, Req_TizenAppinfoMetadataReady) EXPECT_TRUE(comp->bMetadataReady); } -TEST_F(AppinfoTest, Req_TizenAppinfoGetBaseOutputResolution) +TEST_F(LaunchAppinfoTest, Req_TizenLaunchAppinfoGetBaseOutputResolution) { uint32_t pid = 1234; @@ -400,7 +400,7 @@ TEST_F(AppinfoTest, Req_TizenAppinfoGetBaseOutputResolution) EXPECT_TRUE(client->mBaseOutputResolutionHeight == 1920); // default value } -TEST_F(AppinfoTest, Ev_TizenAppinfoBaseOutputResolutionDone) +TEST_F(LaunchAppinfoTest, Ev_TizenLaunchAppinfoBaseOutputResolutionDone) { uint32_t pid = 1234, width = 1920, height = 1080; diff --git a/tests/tc_launch_effect.cpp b/tests/tc_launch_effect.cpp index ebfd8ca..e024956 100644 --- a/tests/tc_launch_effect.cpp +++ b/tests/tc_launch_effect.cpp @@ -1,7 +1,7 @@ #include "tc_main.h" #include "mockclient.h" #include "mockcompositor.h" -#include +#include #include #include @@ -15,11 +15,11 @@ char const *path_edc = "/usr/share/e_tizen_unittests/data/launch_splash.edj"; char const *path_img = "/usr/share/e_tizen_unittests/data/launchimg_splash.png"; -class MockEffectCompositor : public MockCompositor +class MockLaunchEffectCompositor : public MockCompositor { public: - MockEffectCompositor() - : MockCompositor(&MockEffectCompositor::TestSetup, this) + MockLaunchEffectCompositor() + : MockCompositor(&MockLaunchEffectCompositor::TestSetup, this) { ds_inf("%s : this(%p)", __func__, this); @@ -33,47 +33,47 @@ public: mEffectType = -1; } - ~MockEffectCompositor() + ~MockLaunchEffectCompositor() { ds_inf("%s : this(%p)", __func__, this); } static void TestSetup(void *data) { - MockEffectCompositor *mockComp = - static_cast(data); + MockLaunchEffectCompositor *mockComp = + static_cast(data); Compositor *comp = mockComp->compositor; ds_inf("%s: mockComp(%p)", __func__, mockComp); - mockComp->mEffect = ds_tizen_effect_create(comp->display); + mockComp->mEffect = ds_tizen_launch_effect_create(comp->display); // destroy listener mockComp->mDestroyListener.notify = - MockEffectCompositor::DestroyCallback; + MockLaunchEffectCompositor::DestroyCallback; mockComp->mDestroyListener.parent = mockComp; - ds_tizen_effect_add_destroy_listener(mockComp->mEffect, + ds_tizen_launch_effect_add_destroy_listener(mockComp->mEffect, &mockComp->mDestroyListener); // type_set listener mockComp->mTypeSetListener.notify = - MockEffectCompositor::TypeSetCallback; + MockLaunchEffectCompositor::TypeSetCallback; mockComp->mTypeSetListener.parent = mockComp; - ds_tizen_effect_add_type_set_listener(mockComp->mEffect, + ds_tizen_launch_effect_add_type_set_listener(mockComp->mEffect, &mockComp->mTypeSetListener); // type_unset listener mockComp->mTypeUnsetListener.notify = - MockEffectCompositor::TypeUnsetCallback; + MockLaunchEffectCompositor::TypeUnsetCallback; mockComp->mTypeUnsetListener.parent = mockComp; - ds_tizen_effect_add_type_unset_listener(mockComp->mEffect, + ds_tizen_launch_effect_add_type_unset_listener(mockComp->mEffect, &mockComp->mTypeUnsetListener); // new_splash listener mockComp->mNewSplashListener.notify = - MockEffectCompositor::NewSplashCallback; + MockLaunchEffectCompositor::NewSplashCallback; mockComp->mNewSplashListener.parent = mockComp; - ds_tizen_effect_add_new_splash_listener(mockComp->mEffect, + ds_tizen_launch_effect_add_new_splash_listener(mockComp->mEffect, &mockComp->mNewSplashListener); } @@ -81,7 +81,7 @@ public: { ds_inf("%s", __func__); - MockEffectCompositor *mockComp = + MockLaunchEffectCompositor *mockComp = reinterpret_cast(listener)->parent; mockComp->bDestroyed = true; @@ -89,10 +89,10 @@ public: static void TypeSetCallback(struct wl_listener *listener, void *data) { - struct ds_tizen_effect_event_type_set *event = (ds_tizen_effect_event_type_set *)data; + struct ds_tizen_launch_effect_event_type_set *event = (ds_tizen_launch_effect_event_type_set *)data; ds_inf("%s", __func__); - MockEffectCompositor *mockComp = + MockLaunchEffectCompositor *mockComp = reinterpret_cast(listener)->parent; mockComp->bTypeSet = true; @@ -102,10 +102,10 @@ public: static void TypeUnsetCallback(struct wl_listener *listener, void *data) { - struct ds_tizen_effect_event_type_unset *event = (ds_tizen_effect_event_type_unset *)data; + struct ds_tizen_launch_effect_event_type_unset *event = (ds_tizen_launch_effect_event_type_unset *)data; ds_inf("%s", __func__); - MockEffectCompositor *mockComp = + MockLaunchEffectCompositor *mockComp = reinterpret_cast(listener)->parent; mockComp->bTypeSet = false; @@ -116,29 +116,29 @@ public: static void NewSplashCallback(struct wl_listener *listener, void *data) { - struct ds_tizen_effect_event_new_splash *event = (ds_tizen_effect_event_new_splash *)data; + struct ds_tizen_launch_splash *splash = (ds_tizen_launch_splash *)data; ds_inf("%s", __func__); - MockEffectCompositor *mockComp = + MockLaunchEffectCompositor *mockComp = reinterpret_cast(listener)->parent; mockComp->bNewSplash = true; - mockComp->mSplash = event->splash; + mockComp->mSplash = splash; // owner listener mockComp->mOwnerListener.notify = - MockEffectCompositor::OwnerCallback; + MockLaunchEffectCompositor::OwnerCallback; mockComp->mOwnerListener.parent = mockComp; - ds_tizen_splash_add_owner_listener(mockComp->mSplash, + ds_tizen_launch_splash_add_owner_listener(mockComp->mSplash, &mockComp->mOwnerListener); } static void OwnerCallback(struct wl_listener *listener, void *data) { - struct ds_tizen_splash_event_owner *event = (ds_tizen_splash_event_owner *)data; + struct ds_tizen_launch_splash_event_owner *event = (ds_tizen_launch_splash_event_owner *)data; ds_inf("%s", __func__); - MockEffectCompositor *mockComp = + MockLaunchEffectCompositor *mockComp = reinterpret_cast(listener)->parent; mockComp->mPid = event->pid; @@ -154,49 +154,49 @@ public: int mEffectType; private: - struct ds_tizen_effect *mEffect; - struct ds_tizen_splash *mSplash; + struct ds_tizen_launch_effect *mEffect; + struct ds_tizen_launch_splash *mSplash; struct DestroyListener: ::wl_listener { - MockEffectCompositor *parent; + MockLaunchEffectCompositor *parent; }; DestroyListener mDestroyListener; struct TypeSetListener: ::wl_listener { - MockEffectCompositor *parent; + MockLaunchEffectCompositor *parent; }; TypeSetListener mTypeSetListener; struct TypeUnsetListener: ::wl_listener { - MockEffectCompositor *parent; + MockLaunchEffectCompositor *parent; }; TypeUnsetListener mTypeUnsetListener; struct NewSplashListener: ::wl_listener { - MockEffectCompositor *parent; + MockLaunchEffectCompositor *parent; }; NewSplashListener mNewSplashListener; struct OwnerListener: ::wl_listener { - MockEffectCompositor *parent; + MockLaunchEffectCompositor *parent; }; OwnerListener mOwnerListener; }; -class MockEffectClient : public MockClient +class MockLaunchEffectClient : public MockClient { public: - MockEffectClient() + MockLaunchEffectClient() : compositor_res(nullptr), tizen_launch_effect(nullptr) {} - MockEffectClient(const struct wl_registry_listener *listener) + MockLaunchEffectClient(const struct wl_registry_listener *listener) : MockClient(listener, this) { ds_inf("%s", __func__); } - ~MockEffectClient() + ~MockLaunchEffectClient() { ds_inf("%s", __func__); } @@ -215,13 +215,13 @@ public: return compositor_res; } - void SetTizenEffect(struct tizen_launch_effect *global_res) + void SetTizenLaunchEffect(struct tizen_launch_effect *global_res) { ds_inf("%s", __func__); tizen_launch_effect = global_res; } - struct tizen_launch_effect *GetTizenEffect() + struct tizen_launch_effect *GetTizenLaunchEffect() { ds_inf("%s", __func__); @@ -241,7 +241,7 @@ client_registry_cb_global(void *data, struct wl_registry *registry, { ds_inf("%s", __func__); - MockEffectClient *client = static_cast(data); + MockLaunchEffectClient *client = static_cast(data); struct wl_compositor *compositor_res; struct tizen_launch_effect *tizen_launch_effect; @@ -260,7 +260,7 @@ client_registry_cb_global(void *data, struct wl_registry *registry, ds_err("wl_registry_bind() failed. tizen_launch_effect resource."); return; } - client->SetTizenEffect(tizen_launch_effect); + client->SetTizenLaunchEffect(tizen_launch_effect); } } @@ -270,9 +270,9 @@ client_registry_cb_global_remove(void *data, struct wl_registry *registry, { ds_inf("%s", __func__); - MockEffectClient *client = static_cast(data); + MockLaunchEffectClient *client = static_cast(data); struct wl_compositor *compositor_res = client->GetWlCompositor(); - struct tizen_launch_effect *effect_res = client->GetTizenEffect(); + struct tizen_launch_effect *effect_res = client->GetTizenLaunchEffect(); tizen_launch_effect_destroy(effect_res); wl_compositor_destroy(compositor_res); @@ -283,33 +283,33 @@ static const struct wl_registry_listener registry_listener = { .global_remove = client_registry_cb_global_remove }; -class EffectTest : public ::testing::Test +class LaunchEffectTest : public ::testing::Test { public: void SetUp(void) override; void TearDown(void) override; - MockEffectCompositor *comp; - MockEffectClient *client; + MockLaunchEffectCompositor *comp; + MockLaunchEffectClient *client; struct wl_compositor *compositor_res; struct tizen_launch_effect *effect_res; }; void -EffectTest::SetUp(void) +LaunchEffectTest::SetUp(void) { ds_inf("%s", __func__); - comp = new MockEffectCompositor(); - client = new MockEffectClient(®istry_listener); + comp = new MockLaunchEffectCompositor(); + client = new MockLaunchEffectClient(®istry_listener); compositor_res = client->GetWlCompositor(); - effect_res = client->GetTizenEffect(); + effect_res = client->GetTizenLaunchEffect(); client->RoundTrip(); } void -EffectTest::TearDown(void) +LaunchEffectTest::TearDown(void) { ds_inf("%s", __func__); @@ -319,12 +319,12 @@ EffectTest::TearDown(void) delete comp; } -TEST_F(EffectTest, Create_P) +TEST_F(LaunchEffectTest, Create_P) { EXPECT_TRUE(true); } -TEST_F(EffectTest, Req_TizenEffectTypeSet) +TEST_F(LaunchEffectTest, Req_TizenLaunchEffectTypeSet) { uint pid = 12345; const char *effect_type; @@ -334,10 +334,10 @@ TEST_F(EffectTest, Req_TizenEffectTypeSet) client->RoundTrip(); EXPECT_TRUE(comp->bTypeSet); EXPECT_TRUE(comp->mPid == pid); - EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_LAUNCH); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_LAUNCH_EFFECT_TYPE_LAUNCH); } -TEST_F(EffectTest, Req_TizenEffectTypeUnSet) +TEST_F(LaunchEffectTest, Req_TizenLaunchEffectTypeUnSet) { uint pid = 12345; const char *effect_type; @@ -347,7 +347,7 @@ TEST_F(EffectTest, Req_TizenEffectTypeUnSet) client->RoundTrip(); EXPECT_TRUE(comp->bTypeSet); EXPECT_TRUE(comp->mPid == pid); - EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_DEPTH_IN); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_LAUNCH_EFFECT_TYPE_DEPTH_IN); tizen_launch_effect_type_unset(effect_res, pid); client->RoundTrip(); @@ -356,7 +356,7 @@ TEST_F(EffectTest, Req_TizenEffectTypeUnSet) EXPECT_TRUE(comp->mEffectType == -1); } -TEST_F(EffectTest, Req_TizenEffectCreateSplashImg) +TEST_F(LaunchEffectTest, Req_TizenLaunchEffectCreateSplashImg) { struct tizen_launch_splash *splash = NULL; @@ -366,7 +366,7 @@ TEST_F(EffectTest, Req_TizenEffectCreateSplashImg) EXPECT_TRUE(comp->bNewSplash); } -TEST_F(EffectTest, Req_TizenSplashLaunch_EDC) +TEST_F(LaunchEffectTest, Req_TizenLaunchSplashLaunch_EDC) { struct tizen_launch_splash *splash = NULL; struct wl_array options; @@ -383,10 +383,10 @@ TEST_F(EffectTest, Req_TizenSplashLaunch_EDC) client->RoundTrip(); wl_array_release(&options); EXPECT_TRUE(comp->mPid == SPLASH_CLIENT_PID); - EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_LAUNCH); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_LAUNCH_EFFECT_TYPE_LAUNCH); } -TEST_F(EffectTest, Req_TizenSplashLaunch_IMG) +TEST_F(LaunchEffectTest, Req_TizenLaunchSplashLaunch_IMG) { struct tizen_launch_splash *splash = NULL; struct wl_array options; @@ -403,10 +403,10 @@ TEST_F(EffectTest, Req_TizenSplashLaunch_IMG) client->RoundTrip(); wl_array_release(&options); EXPECT_TRUE(comp->mPid == SPLASH_CLIENT_PID); - EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_LAUNCH); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_LAUNCH_EFFECT_TYPE_LAUNCH); } -TEST_F(EffectTest, Req_TizenSplashSetOwner) +TEST_F(LaunchEffectTest, Req_TizenLaunchSplashSetOwner) { struct tizen_launch_splash *splash = NULL; struct wl_array options; @@ -424,15 +424,15 @@ TEST_F(EffectTest, Req_TizenSplashSetOwner) client->RoundTrip(); wl_array_release(&options); EXPECT_TRUE(comp->mPid == SPLASH_CLIENT_PID); - EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_DEPTH_IN); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_LAUNCH_EFFECT_TYPE_DEPTH_IN); tizen_launch_splash_owner(splash, pid); client->RoundTrip(); EXPECT_TRUE(comp->mPid == pid); - EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_DEPTH_IN); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_LAUNCH_EFFECT_TYPE_DEPTH_IN); } -TEST_F(EffectTest, Req_TizenSplashLaunch_v2) +TEST_F(LaunchEffectTest, Req_TizenLaunchSplashLaunch_v2) { struct tizen_launch_splash *splash = NULL; @@ -472,5 +472,5 @@ TEST_F(EffectTest, Req_TizenSplashLaunch_v2) wl_array_release(&options); wl_array_release(&extra_config); EXPECT_TRUE(comp->mPid == SPLASH_CLIENT_PID); - EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_DEPTH_IN); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_LAUNCH_EFFECT_TYPE_DEPTH_IN); } -- 2.7.4 From e07af42bf9d966206603b663c6d906cad6eb7f61 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 16 Aug 2022 16:33:47 +0900 Subject: [PATCH 04/16] export ds_tdm_output_hwc_set_client_target_buffer Change-Id: Ifb7fe17bb2b57357c059c716eb7593237039d61a --- include/libds-tizen/backend/tdm_output_hwc.h | 4 ++ src/backend/tdm/output.c | 31 ++++----------- src/backend/tdm/tdm_internal.h | 2 + src/backend/tdm/tdm_output_hwc.c | 59 ++++++++++++++++++++-------- src/backend/tdm/tdm_output_hwc.h | 6 +-- 5 files changed, 56 insertions(+), 46 deletions(-) diff --git a/include/libds-tizen/backend/tdm_output_hwc.h b/include/libds-tizen/backend/tdm_output_hwc.h index abde223..e04cdb3 100644 --- a/include/libds-tizen/backend/tdm_output_hwc.h +++ b/include/libds-tizen/backend/tdm_output_hwc.h @@ -24,6 +24,10 @@ WL_EXPORT void ds_tdm_output_hwc_set_enabled(struct ds_tdm_output_hwc *hwc, bool enabled); WL_EXPORT bool +ds_tdm_output_hwc_set_client_target_buffer(struct ds_tdm_output_hwc *hwc, + struct ds_buffer *buffer); + +WL_EXPORT bool ds_tdm_output_hwc_validate(struct ds_tdm_output_hwc *hwc, struct ds_tdm_output_hwc_window **composited_windows, uint32_t num_windows, uint32_t *num_changed); diff --git a/src/backend/tdm/output.c b/src/backend/tdm/output.c index 1baefd2..4a236a8 100644 --- a/src/backend/tdm/output.c +++ b/src/backend/tdm/output.c @@ -175,7 +175,7 @@ create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer) return buffer; } -static struct ds_tdm_buffer * +struct ds_tdm_buffer * get_or_create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer) { @@ -347,7 +347,7 @@ output_init_hwc(struct ds_tdm_output *output) return; } - output->hwc = ds_tdm_output_hwc_create(output->tdm.hwc); + output->hwc = ds_tdm_output_hwc_create(output, output->tdm.hwc); if (!output->hwc) { ds_err("Could not create ds_dm_hwc: output(%p)", output); return; @@ -379,31 +379,14 @@ static bool output_set_pending_fb(struct ds_tdm_output *output, struct ds_buffer *ds_buffer) { - struct ds_tdm_queue_buffer *queue_buffer; - struct ds_tdm_buffer *buffer; - tbm_surface_h surface = NULL; - - if (output->queue) { - queue_buffer = buffer_queue_find_buffer(output->queue, ds_buffer); - if (queue_buffer) { - ds_buffer_lock(ds_buffer); - surface = queue_buffer->surface; - } - } - - if (!surface) { - buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); - if (!buffer) + if (!output->hwc->enabled) { + if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, ds_buffer)) { + ds_err("Could not set hwc client target buffer"); return false; - - surface = buffer->surface; + } } - if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, surface)) { - ds_err("Could not set hwc client target buffer"); - ds_buffer_unlock(ds_buffer); - return false; - } + ds_buffer_lock(ds_buffer); output_attach_back_buffer(output, ds_buffer); diff --git a/src/backend/tdm/tdm_internal.h b/src/backend/tdm/tdm_internal.h index ef7d88f..2faa979 100644 --- a/src/backend/tdm/tdm_internal.h +++ b/src/backend/tdm/tdm_internal.h @@ -75,5 +75,7 @@ struct ds_tdm_output *create_tdm_output(struct ds_tdm_backend *tdm, void destroy_tdm_buffer(struct ds_tdm_buffer *buffer); +struct ds_tdm_buffer *get_or_create_tdm_buffer(struct ds_tdm_backend *backend, + struct ds_buffer *ds_buffer); #endif diff --git a/src/backend/tdm/tdm_output_hwc.c b/src/backend/tdm/tdm_output_hwc.c index 48aef1d..535fdef 100644 --- a/src/backend/tdm/tdm_output_hwc.c +++ b/src/backend/tdm/tdm_output_hwc.c @@ -9,6 +9,7 @@ #include "tdm_internal.h" #include "tdm_output_hwc.h" +#include "tdm_buffer_queue.h" static void hwc_window_update_front_buffer(struct ds_tdm_output_hwc_window *hwc_window) @@ -159,7 +160,7 @@ get_composition(tdm_hwc_window_composition composition) } struct ds_tdm_output_hwc * -ds_tdm_output_hwc_create(tdm_hwc *thwc) +ds_tdm_output_hwc_create(struct ds_tdm_output *output, tdm_hwc *thwc) { struct ds_tdm_output_hwc *hwc; @@ -168,6 +169,7 @@ ds_tdm_output_hwc_create(tdm_hwc *thwc) return NULL; hwc->thwc = thwc; + hwc->tdm_output = output; wl_list_init(&hwc->hwc_windows); wl_signal_init(&hwc->events.commit_handler); @@ -185,29 +187,52 @@ ds_tdm_output_hwc_destroy(struct ds_tdm_output_hwc *hwc) } bool -ds_tdm_output_hwc_set_client_target_buffer(struct ds_tdm_output_hwc *hwc, tbm_surface_h tsurface) +ds_tdm_output_hwc_set_client_target_buffer(struct ds_tdm_output_hwc *hwc, struct ds_buffer *buffer) { tdm_error terr; tdm_region fb_damage; + tbm_surface_h tsurface = NULL; + struct ds_tdm_queue_buffer *tdm_queue_buffer; + struct ds_tdm_buffer *tdm_buffer; + + if (buffer) { + if (hwc->tdm_output->queue) { + tdm_queue_buffer = buffer_queue_find_buffer(hwc->tdm_output->queue, buffer); + if (tdm_queue_buffer) + tsurface = tdm_queue_buffer->surface; + } - memset(&fb_damage, 0, sizeof(fb_damage)); - - hwc->target_buffer_info.src_config.pos.x = 0; - hwc->target_buffer_info.src_config.pos.y = 0; - hwc->target_buffer_info.src_config.pos.w = tbm_surface_get_width(tsurface); - hwc->target_buffer_info.src_config.pos.h = tbm_surface_get_height(tsurface); - hwc->target_buffer_info.src_config.size.h = get_horizontal_get(tsurface); - hwc->target_buffer_info.src_config.size.v = tbm_surface_get_height(tsurface); - hwc->target_buffer_info.src_config.format = tbm_surface_get_format(tsurface); + if (!tsurface) { + tdm_buffer = get_or_create_tdm_buffer(hwc->tdm_output->backend, buffer); + if (!tdm_buffer) { + ds_err("Could not get or create tdm buffer"); + return false; + } - hwc->target_buffer_info.dst_pos.x = 0; - hwc->target_buffer_info.dst_pos.y = 0; - hwc->target_buffer_info.dst_pos.w = tbm_surface_get_width(tsurface); - hwc->target_buffer_info.dst_pos.h = tbm_surface_get_height(tsurface); + tsurface = tdm_buffer->surface; + } + } - hwc->target_buffer_info.transform = TDM_TRANSFORM_NORMAL; + memset(&fb_damage, 0, sizeof(fb_damage)); - tdm_hwc_set_client_target_buffer_info(hwc->thwc, &hwc->target_buffer_info); + if (tsurface) { + hwc->target_buffer_info.src_config.pos.x = 0; + hwc->target_buffer_info.src_config.pos.y = 0; + hwc->target_buffer_info.src_config.pos.w = tbm_surface_get_width(tsurface); + hwc->target_buffer_info.src_config.pos.h = tbm_surface_get_height(tsurface); + hwc->target_buffer_info.src_config.size.h = get_horizontal_get(tsurface); + hwc->target_buffer_info.src_config.size.v = tbm_surface_get_height(tsurface); + hwc->target_buffer_info.src_config.format = tbm_surface_get_format(tsurface); + + hwc->target_buffer_info.dst_pos.x = 0; + hwc->target_buffer_info.dst_pos.y = 0; + hwc->target_buffer_info.dst_pos.w = tbm_surface_get_width(tsurface); + hwc->target_buffer_info.dst_pos.h = tbm_surface_get_height(tsurface); + + hwc->target_buffer_info.transform = TDM_TRANSFORM_NORMAL; + + tdm_hwc_set_client_target_buffer_info(hwc->thwc, &hwc->target_buffer_info); + } terr = tdm_hwc_set_client_target_buffer(hwc->thwc, tsurface, fb_damage); if (terr != TDM_ERROR_NONE) { diff --git a/src/backend/tdm/tdm_output_hwc.h b/src/backend/tdm/tdm_output_hwc.h index bb634d2..905e2ee 100644 --- a/src/backend/tdm/tdm_output_hwc.h +++ b/src/backend/tdm/tdm_output_hwc.h @@ -52,16 +52,12 @@ struct ds_tdm_output_hwc { }; struct ds_tdm_output_hwc * -ds_tdm_output_hwc_create(tdm_hwc *thwc); +ds_tdm_output_hwc_create(struct ds_tdm_output *output, tdm_hwc *thwc); void ds_tdm_output_hwc_destroy(struct ds_tdm_output_hwc *hwc); bool -ds_tdm_output_hwc_set_client_target_buffer(struct ds_tdm_output_hwc *hwc, - tbm_surface_h tsurface); - -bool ds_tdm_output_hwc_commit(struct ds_tdm_output_hwc *hwc); void -- 2.7.4 From 0073e07742b9137f228fd62c7aeea1f7cef755e0 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 16 Aug 2022 16:34:36 +0900 Subject: [PATCH 05/16] merge tinyds-tdm-hwc code to tinyds-tdm Change-Id: I15e9fd39f646b8fd7fd75ae4b957504a42b69c88 --- examples/meson.build | 18 -- examples/tinyds-tdm-hwc.c | 768 --------------------------------------------- examples/tinyds-tdm.c | 318 +++++++++++++++++-- packaging/libds-tizen.spec | 1 - 4 files changed, 290 insertions(+), 815 deletions(-) delete mode 100644 examples/tinyds-tdm-hwc.c diff --git a/examples/meson.build b/examples/meson.build index 3370f26..899529e 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -37,21 +37,3 @@ executable('tinyds-tdm', install_dir: libds_tizen_bindir, install : true ) - -tinyds_tdm_hwc_files = [ - 'tinyds-tdm-hwc.c', - 'pixman-helper.c', - 'pixman-tbm-helper.c', - 'tinyds-tdm-renderer.c', -] -executable('tinyds-tdm-hwc', - tinyds_tdm_hwc_files, - dependencies: [ - common_deps, - deps_libds_tizen_backend_tdm, - dependency('pixman-1', required: true), - dependency('threads', required: true), - ], - install_dir: libds_tizen_bindir, - install : true -) diff --git a/examples/tinyds-tdm-hwc.c b/examples/tinyds-tdm-hwc.c deleted file mode 100644 index 46925f1..0000000 --- a/examples/tinyds-tdm-hwc.c +++ /dev/null @@ -1,768 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define USE_TDM_BUFFER_QUEUE - -#ifdef USE_TDM_BUFFER_QUEUE -#include "pixman-tbm-helper.h" -#include "tinyds-tdm-renderer.h" -#else -#include -#endif - -#include "pixman-helper.h" - -#define TINYDS_UNUSED __attribute__((unused)) - -struct tinyds_output -{ - struct tinyds_server *server; - struct ds_output *ds_output; - struct ds_allocator *allocator; -#ifdef USE_TDM_BUFFER_QUEUE - struct tinyds_renderer renderer; - struct ds_tdm_buffer_queue *buffer_queue; - struct wl_listener buffer_queue_acquirable; -#else - struct ds_swapchain *swapchain; -#endif - struct ds_buffer *front_buffer; - - struct wl_listener output_destroy; - struct wl_listener output_frame; - - int width, height; - - struct wl_event_source *idle_commit; - bool commitable; - bool damaged; - - struct ds_tdm_output_hwc *hwc; -}; - -struct tinyds_server -{ - struct ds_tbm_server *tbm_server; - - struct wl_display *display; - - struct ds_backend *backend; - struct ds_compositor *compositor; - struct ds_xdg_shell *xdg_shell; - - struct tinyds_output *output; - struct wl_event_source *stdin_source; - - struct wl_list views; - - struct wl_listener new_output; - struct wl_listener new_xdg_surface; -}; - -struct tinyds_view -{ - struct tinyds_server *server; - - struct tinyds_texture *texture; - struct ds_xdg_surface *xdg_surface; - - struct wl_listener xdg_surface_map; - struct wl_listener xdg_surface_unmap; - struct wl_listener xdg_surface_destroy; - struct wl_listener surface_commit; - struct wl_list link; // tinyds_server::views - - struct ds_tdm_output_hwc_window *hwc_window; - - int x, y; - bool mapped; -}; - -struct tinyds_server tinyds; - -static bool init_server(struct tinyds_server *server, struct wl_display *display); -static int server_dispatch_stdin(int fd, uint32_t mask, void *data); -static void output_handle_destroy(struct wl_listener *listener, void *data); -static void output_handle_frame(struct wl_listener *listener, void *data); -static void draw_server_with_damage(struct tinyds_server *server); -static void draw_output(struct tinyds_output *output); -static void output_swap_buffer(struct tinyds_output *output, - struct ds_buffer *buffer); -static void view_send_frame_done(struct tinyds_view *view); -static void output_hwc_init(struct tinyds_output *output); -static void output_schedule_commit(struct tinyds_output *output); -static void output_commit(struct tinyds_output *output); -#ifdef USE_TDM_BUFFER_QUEUE -static void output_buffer_queue_init(struct tinyds_output *output); -static void output_renderer_init(struct tinyds_output *output); -static void output_draw_with_renderer(struct tinyds_output *output); -#else -static void output_swapchain_init(struct tinyds_output *output, - int width, int height, uint32_t format); -static void output_draw_with_swapchain(struct tinyds_output *output); -static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); -#endif - -int -main(void) -{ - struct tinyds_server *server = &tinyds; - struct wl_display *display; - struct wl_event_loop *loop; - const char *socket; - bool res; - - ds_log_init(DS_INF, NULL); - - display = wl_display_create(); - assert(display); - - res = init_server(server, display); - assert(res); - - socket = wl_display_add_socket_auto(display); - assert(socket); - - ds_backend_start(server->backend); - - setenv("WAYLAND_DISPLAY", socket, true); - - ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); - - loop = wl_display_get_event_loop(display); - server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO, - WL_EVENT_READABLE, server_dispatch_stdin, server); - - wl_display_run(display); - - wl_display_destroy_clients(display); - wl_display_destroy(display); - - return 0; -} - -static void -view_handle_xdg_surface_map(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, xdg_surface_map); - view->mapped = true; -} - -static void -view_handle_xdg_surface_unmap(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, xdg_surface_unmap); - view->mapped = false; -} - -static void -view_handle_xdg_surface_destroy(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, xdg_surface_destroy); - - draw_server_with_damage(view->server); - - ds_tdm_output_hwc_window_destroy(view->hwc_window); - - wl_list_remove(&view->xdg_surface_destroy.link); - wl_list_remove(&view->xdg_surface_map.link); - wl_list_remove(&view->xdg_surface_unmap.link); - wl_list_remove(&view->surface_commit.link); - wl_list_remove(&view->link); - free(view); -} - -static void -view_handle_surface_commit(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, surface_commit); - - draw_server_with_damage(view->server); -} - -static void -server_new_xdg_surface(struct wl_listener *listener, void *data) -{ - struct tinyds_server *server; - struct tinyds_view *view; - struct ds_xdg_surface *xdg_surface; - - server = wl_container_of(listener, server, new_xdg_surface); - xdg_surface = data; - - ds_inf("New xdg_surface(%p)", (void *)xdg_surface); - - view = calloc(1, sizeof *view); - assert(view); - - view->server = server; - view->xdg_surface = xdg_surface; - - view->xdg_surface_map.notify = view_handle_xdg_surface_map; - ds_xdg_surface_add_map_listener(xdg_surface, - &view->xdg_surface_map); - - view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap; - ds_xdg_surface_add_unmap_listener(xdg_surface, - &view->xdg_surface_unmap); - - view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy; - ds_xdg_surface_add_destroy_listener(xdg_surface, - &view->xdg_surface_destroy); - - view->surface_commit.notify = view_handle_surface_commit; - ds_surface_add_commit_listener( - ds_xdg_surface_get_surface(xdg_surface), - &view->surface_commit); - - view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc); - - wl_list_insert(server->views.prev, &view->link); -} - -static void -backend_handle_new_output(struct wl_listener *listener, void *data) -{ - struct tinyds_server *server; - struct tinyds_output *output; - struct ds_output *ds_output; - const struct ds_output_mode *mode; - - server = wl_container_of(listener, server, new_output); - ds_output = data; - - ds_inf("New output(%p)", ds_output); - - if (server->output) - return; - - mode = ds_output_get_preferred_mode(ds_output); - ds_output_set_mode(ds_output, mode); - - output = calloc(1, sizeof *output); - if (!output) - return; - - output->server = server; - output->ds_output = ds_output; - output->width = mode->width; - output->height = mode->height; - output->damaged = true; - output->commitable = true; - -#ifdef USE_TDM_BUFFER_QUEUE - output_buffer_queue_init(output); - output_renderer_init(output); -#else - output_swapchain_init(output, mode->width, mode->height, - DRM_FORMAT_XRGB8888); -#endif - - output_hwc_init(output); - - output->output_destroy.notify = output_handle_destroy; - ds_output_add_destroy_listener(ds_output, &output->output_destroy); - - output->output_frame.notify = output_handle_frame; - ds_output_add_frame_listener(ds_output, &output->output_frame); - - server->output = output; - - output_schedule_commit(output); -} - -static bool -init_server(struct tinyds_server *server, struct wl_display *display) -{ - server->display = display; - - wl_list_init(&server->views); - - if (wl_display_init_shm(display) != 0) - return false; - - server->backend = ds_tdm_backend_create(display); - if (!server->backend) - return false; - - server->new_output.notify = backend_handle_new_output; - ds_backend_add_new_output_listener(server->backend, - &server->new_output); - - server->compositor = ds_compositor_create(display); - if (!server->compositor) { - ds_backend_destroy(server->backend); - return false; - } - - server->tbm_server = ds_tbm_server_create(display); - if (!server->tbm_server) { - ds_backend_destroy(server->backend); - return false; - } - - server->xdg_shell = ds_xdg_shell_create(display); - if (!server->xdg_shell) { - ds_backend_destroy(server->backend); - return false; - } - - server->new_xdg_surface.notify = server_new_xdg_surface; - ds_xdg_shell_add_new_surface_listener(server->xdg_shell, - &server->new_xdg_surface); - - return true; -} - -static void -output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) -{ - struct tinyds_output *output = - wl_container_of(listener, output, output_destroy); - - wl_list_remove(&output->output_destroy.link); - wl_list_remove(&output->output_frame.link); - - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); - -#ifdef USE_TDM_BUFFER_QUEUE - fini_renderer(&output->renderer); -#else - if (output->swapchain) - ds_swapchain_destroy(output->swapchain); - - if (output->allocator) - ds_allocator_destroy(output->allocator); -#endif - - wl_display_terminate(output->server->display); - - output->server->output = NULL; - - free(output); -} -static void -output_commit(struct tinyds_output *output) -{ - uint32_t num_changed = 0; - uint32_t num_windows = 0, current_num_windows = 0; - struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL; - struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL; - enum ds_tdm_output_hwc_window_composition composition; - struct tinyds_view *view; - int i; - bool need_target = false; - - if (!output->commitable || !output->damaged) - return; - - wl_list_for_each_reverse(view, &output->server->views, link) { - if (!view->hwc_window) - continue; - - if (view->mapped) - num_windows++; - } - - if (num_windows) { - composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows); - if (!composited_hwc_windows) - return; - } - - wl_list_for_each_reverse(view, &output->server->views, link) { - struct ds_buffer *ds_buffer; - struct ds_tdm_box src_box; - int w = 0, h = 0; - - if (!view->hwc_window) - continue; - - ds_buffer = ds_surface_get_buffer( - ds_xdg_surface_get_surface(view->xdg_surface)); - if (!ds_buffer) - continue; - - ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer); - - if (ds_buffer) - ds_buffer_get_size(ds_buffer, &w, &h); - - src_box.x = 0; - src_box.y = 0; - src_box.width = w; - src_box.height = h; - - ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box); - ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y); - ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h); - ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL); - - if (view->mapped) { - ds_tdm_output_hwc_window_set_composition(view->hwc_window, - DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE); - - composited_hwc_windows[current_num_windows] = view->hwc_window; - current_num_windows++; - } else { - ds_tdm_output_hwc_window_set_composition(view->hwc_window, - DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE); - } - } - - if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows, - num_windows, &num_changed)) { - free(composited_hwc_windows); - ds_err("Could not hwc validate"); - return; - } - - if (composited_hwc_windows) - free(composited_hwc_windows); - - if (num_changed > 0) { - changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows); - if (!changed_hwc_windows) - return; - - if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed, - changed_hwc_windows)) { - ds_err("Could not get chaged composition"); - return; - } - - for (i = 0; i < num_changed; i++) { - composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]); - if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) { - need_target = true; - break; - } - } - } - - if (changed_hwc_windows) - free(changed_hwc_windows); - - if (!ds_tdm_output_hwc_accept_validation(output->hwc)) { - ds_err("Could not hwc accept validateion"); - return; - } - - if (need_target) - draw_output(output); - -#ifdef USE_TDM_BUFFER_QUEUE - struct ds_buffer *buffer; - - buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue); - if (buffer) - output_swap_buffer(output, buffer); -#endif - - ds_output_commit(output->ds_output); - - output->commitable = false; - output->damaged = false; - - wl_list_for_each(view, &output->server->views, link) { - enum ds_tdm_output_hwc_window_composition composition; - - if (!view->mapped) - continue; - - composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); - if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || - (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || - (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) - view_send_frame_done(view); - } - - ds_inf("output:%p commit", output); -} - -static void -output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) -{ - struct tinyds_output *output = - wl_container_of(listener, output, output_frame); - - ds_inf("output:%p handle frame", output); - - output->commitable = true; - - output_commit(output); -} - -static void -draw_server_with_damage(struct tinyds_server *server) -{ - server->output->damaged = true; - output_schedule_commit(server->output); -} - -static void -output_hwc_init(struct tinyds_output *output) -{ - struct ds_tdm_output *tdm_output; - - tdm_output = ds_tdm_output_from_output(output->ds_output); - assert(tdm_output); - - output->hwc = ds_tdm_output_get_hwc(tdm_output); - assert(output->hwc); - - ds_tdm_output_hwc_set_enabled(output->hwc, true); -} - -#ifdef USE_TDM_BUFFER_QUEUE -static void -output_handle_buffer_queue_acquirable(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_output *output; - - output = wl_container_of(listener, output, buffer_queue_acquirable); - - draw_server_with_damage(output->server); -} - -static void -output_buffer_queue_init(struct tinyds_output *output) -{ - struct ds_tdm_output *tdm_output; - - tdm_output = ds_tdm_output_from_output(output->ds_output); - assert(tdm_output); - - output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output); - assert(output->buffer_queue); - - output->buffer_queue_acquirable.notify = - output_handle_buffer_queue_acquirable; - ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue, - &output->buffer_queue_acquirable); -} - -static void -output_renderer_init(struct tinyds_output *output) -{ - init_renderer(&output->renderer); - - renderer_set_surface_queue(&output->renderer, - ds_tdm_buffer_queue_get_native_queue(output->buffer_queue)); - - renderer_set_bg_color(&output->renderer, 0, 0, 0); -} - -static void -output_draw_with_renderer(struct tinyds_output *output) -{ - struct tinyds_view *view; - - ds_dbg(">> BEGIN UPDATE TEXTURES"); - - wl_list_for_each(view, &output->server->views, link) { - struct ds_buffer *ds_buffer; - struct ds_tbm_client_buffer *tbm_buffer; - tbm_surface_h surface; - enum ds_tdm_output_hwc_window_composition composition; - - if (!view->mapped) - continue; - - composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); - if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || - (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || - (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) - continue; - - ds_buffer = ds_surface_get_buffer( - ds_xdg_surface_get_surface(view->xdg_surface)); - assert(ds_buffer); - - tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer); - assert(tbm_buffer); - - surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer); - - renderer_add_texture(&output->renderer, surface, view->x, view->y); - - view_send_frame_done(view); - } - - ds_dbg("<< END UPDATE TEXTURES"); - - renderer_draw(&output->renderer); -} - -#else -static void -output_swapchain_init(struct tinyds_output *output, - int width, int height, uint32_t format) - -{ - output->allocator = ds_tbm_allocator_create(); - assert(output->allocator); - - output->swapchain = ds_swapchain_create(output->allocator, - width, height, format); - assert(output->swapchain); -} - -static void -output_draw_with_swapchain(struct tinyds_output *output) -{ - struct tinyds_view *view; - struct ds_buffer *output_buffer; - pixman_image_t *output_image; - enum ds_tdm_output_hwc_window_composition composition; - - output_buffer = ds_swapchain_acquire(output->swapchain, NULL); - if (!output_buffer) - return; - - output_image = pixman_image_from_buffer(output_buffer, - DS_BUFFER_DATA_PTR_ACCESS_WRITE); - if (!output_image) { - ds_buffer_unlock(output_buffer); - return; - } - - pixman_image_fill_color(output_image, 0, 0, 0); - - wl_list_for_each(view, &output->server->views, link) { - if (!view->mapped) - continue; - - composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); - if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || - (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || - (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) - continue; - - draw_view(view, output_image); - } - pixman_image_unref(output_image); - - output_swap_buffer(output, output_buffer); -} - -static void -draw_view(struct tinyds_view *view, pixman_image_t *dst_image) -{ - struct ds_buffer *buffer; - pixman_image_t *src_image; - - buffer = ds_surface_get_buffer( - ds_xdg_surface_get_surface(view->xdg_surface)); - if (!buffer) - return; - - src_image = pixman_image_from_buffer(buffer, - DS_BUFFER_DATA_PTR_ACCESS_READ); - pixman_image_composite32(PIXMAN_OP_OVER, - src_image, - NULL, - dst_image, - 0, 0, 0, 0, - view->x, view->y, - pixman_image_get_width(src_image), - pixman_image_get_height(src_image)); - pixman_image_unref(src_image); - - view_send_frame_done(view); -} -#endif - -static void -draw_output(struct tinyds_output *output) -{ -#ifdef USE_TDM_BUFFER_QUEUE - output_draw_with_renderer(output); -#else - output_draw_with_swapchain(output); -#endif - - ds_inf("output:%p draw", output); -} - -static void -output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer) -{ - ds_output_attach_buffer(output->ds_output, buffer); - - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); - output->front_buffer = buffer; -} - -static void -view_send_frame_done(struct tinyds_view *view) -{ - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), - &now); -} - -static void -output_schedule_commit_handle_idle_timer(void *data) -{ - struct tinyds_output *output = data; - output->idle_commit = NULL; - - output_commit(output); -} - -static void -output_schedule_commit(struct tinyds_output *output) -{ - if (output->idle_commit) - return; - - output->damaged = true; - - struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display); - output->idle_commit = - wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output); -} - -static int -server_dispatch_stdin(int fd, uint32_t mask, void *data) -{ - struct tinyds_server *server = data; - - wl_display_terminate(server->display); - - return 1; -} diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 2158bac..e8416ab 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -27,6 +27,7 @@ #include #include #include +#include #define USE_TDM_BUFFER_QUEUE @@ -62,8 +63,13 @@ struct tinyds_output int width, height; - bool drawable; + struct wl_event_source *idle_commit; + bool committable; bool damaged; + bool target_updated; + + struct ds_tdm_output_hwc *hwc; + struct ds_tdm_output_hwc_window *bg_hwc_window; }; struct tinyds_dpms @@ -127,6 +133,8 @@ struct tinyds_view struct wl_listener surface_commit; struct wl_list link; // tinyds_server::views + struct ds_tdm_output_hwc_window *hwc_window; + int x, y; bool mapped; @@ -180,6 +188,9 @@ static void draw_output(struct tinyds_output *output); static void output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer); static void view_send_frame_done(struct tinyds_view *view); +static void output_hwc_init(struct tinyds_output *output); +static void output_schedule_commit(struct tinyds_output *output); +static void output_commit(struct tinyds_output *output); #ifdef USE_TDM_BUFFER_QUEUE static void output_buffer_queue_init(struct tinyds_output *output); static void output_renderer_init(struct tinyds_output *output); @@ -302,10 +313,12 @@ view_handle_xdg_surface_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) { struct tinyds_view *view; - struct tinyds_server *server; view = wl_container_of(listener, view, xdg_surface_destroy); - server = view->server; + + draw_server_with_damage(view->server); + + ds_tdm_output_hwc_window_destroy(view->hwc_window); wl_list_remove(&view->xdg_surface_destroy.link); wl_list_remove(&view->xdg_surface_map.link); @@ -313,8 +326,6 @@ view_handle_xdg_surface_destroy(struct wl_listener *listener, wl_list_remove(&view->surface_commit.link); wl_list_remove(&view->link); free(view); - - draw_server_with_damage(server); } static void @@ -362,11 +373,14 @@ server_new_xdg_surface(struct wl_listener *listener, void *data) ds_xdg_surface_get_surface(xdg_surface), &view->surface_commit); - wl_list_insert(server->views.prev, &view->link); - view->x = rand() % 1000; view->y = rand() % 500; + view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc); + assert(view->hwc_window); + + wl_list_insert(server->views.prev, &view->link); + view->pid = 0; view->effect_type = -1; @@ -380,6 +394,7 @@ backend_handle_new_output(struct wl_listener *listener, void *data) struct tinyds_output *output; struct ds_output *ds_output; const struct ds_output_mode *mode; + struct ds_tdm_box src_box; server = wl_container_of(listener, server, new_output); ds_output = data; @@ -400,8 +415,10 @@ backend_handle_new_output(struct wl_listener *listener, void *data) output->ds_output = ds_output; output->width = mode->width; output->height = mode->height; - output->drawable = true; output->damaged = true; + output->committable = true; + + output_hwc_init(output); #ifdef USE_TDM_BUFFER_QUEUE output_buffer_queue_init(output); @@ -411,6 +428,19 @@ backend_handle_new_output(struct wl_listener *listener, void *data) DRM_FORMAT_XRGB8888); #endif + output->bg_hwc_window = ds_tdm_output_hwc_window_create(output->hwc); + assert(output->bg_hwc_window); + + src_box.x = 0; + src_box.y = 0; + src_box.width = output->width; + src_box.height = output->height; + + ds_tdm_output_hwc_window_set_src_box(output->bg_hwc_window, &src_box); + ds_tdm_output_hwc_window_set_position(output->bg_hwc_window, 0, 0); + ds_tdm_output_hwc_window_set_dest_size(output->bg_hwc_window, output->width, output->height); + ds_tdm_output_hwc_window_set_transform(output->bg_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL); + output->output_destroy.notify = output_handle_destroy; ds_output_add_destroy_listener(ds_output, &output->output_destroy); @@ -421,7 +451,7 @@ backend_handle_new_output(struct wl_listener *listener, void *data) server->output = output; - draw_output(output); + output_schedule_commit(output); } static bool @@ -799,6 +829,9 @@ output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) struct tinyds_output *output = wl_container_of(listener, output, output_destroy); + if (output->bg_hwc_window) + ds_tdm_output_hwc_window_destroy(output->bg_hwc_window); + wl_list_remove(&output->output_destroy.link); wl_list_remove(&output->output_frame.link); @@ -823,20 +856,213 @@ output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) } static void +output_commit(struct tinyds_output *output) +{ + uint32_t num_changed = 0; + uint32_t num_windows = 0, current_num_windows = 0; + struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL; + struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL; + enum ds_tdm_output_hwc_window_composition composition; + struct tinyds_view *view; + int i; + bool need_target = false; + bool fully_obscured = false; + struct ds_buffer *ds_buffer; + struct ds_tdm_box src_box; + int w = 0, h = 0; + + if (!output->committable) + return; + + if (!output->damaged && !output->target_updated) + return; + + wl_list_for_each_reverse(view, &output->server->views, link) { + if (!view->hwc_window) + continue; + + ds_buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + if (!ds_buffer) + continue; + + if (!view->mapped) + continue; + + num_windows++; + + ds_buffer_get_size(ds_buffer, &w, &h); + + if ((output->width <= w) && (output->height <= h)) + fully_obscured = true; + } + + if (fully_obscured) { + ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE); + } else { + ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT); + num_windows++; + need_target = true; + } + + if (num_windows) { + composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows); + if (!composited_hwc_windows) + return; + + wl_list_for_each_reverse(view, &output->server->views, link) { + if (!view->hwc_window) + continue; + + ds_buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + if (!ds_buffer) + continue; + + ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer); + + ds_buffer_get_size(ds_buffer, &w, &h); + + src_box.x = 0; + src_box.y = 0; + src_box.width = w; + src_box.height = h; + + ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box); + ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y); + ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h); + ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL); + + if (view->mapped) { + ds_tdm_output_hwc_window_set_composition(view->hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE); + + composited_hwc_windows[current_num_windows] = view->hwc_window; + current_num_windows++; + } else { + ds_tdm_output_hwc_window_set_composition(view->hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE); + } + } + + if (!fully_obscured) { + composited_hwc_windows[current_num_windows] = output->bg_hwc_window; + current_num_windows++; + } + } + + if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows, + num_windows, &num_changed)) { + free(composited_hwc_windows); + ds_err("Could not hwc validate"); + return; + } + + if (composited_hwc_windows) + free(composited_hwc_windows); + + if (num_changed > 0) { + changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows); + if (!changed_hwc_windows) + return; + + if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed, + changed_hwc_windows)) { + free(changed_hwc_windows); + ds_err("Could not get chaged composition"); + return; + } + + for (i = 0; i < num_changed; i++) { + composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]); + if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) { + need_target = true; + break; + } + } + } + + if (changed_hwc_windows) + free(changed_hwc_windows); + + if (need_target && output->damaged) + draw_output(output); + +#ifdef USE_TDM_BUFFER_QUEUE + struct ds_buffer *buffer; + + buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue); + if (buffer) { + if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, buffer)) { + ds_err("Could not set hwc client target buffer"); + return; + } + + output_swap_buffer(output, buffer); + } +#endif + + if (!ds_tdm_output_hwc_accept_validation(output->hwc)) { + ds_err("Could not hwc accept validateion"); + return; + } + + ds_output_commit(output->ds_output); + + output->committable = false; + output->damaged = false; + output->target_updated = false; + + wl_list_for_each(view, &output->server->views, link) { + enum ds_tdm_output_hwc_window_composition composition; + + if (!view->mapped) + continue; + + composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); + if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) + view_send_frame_done(view); + } + + ds_dbg("output:%p commit", output); +} + +static void output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) { struct tinyds_output *output = wl_container_of(listener, output, output_frame); - output->drawable = true; - draw_output(output); + ds_dbg("output:%p handle frame", output); + + output->committable = true; + + output_commit(output); } static void draw_server_with_damage(struct tinyds_server *server) { server->output->damaged = true; - draw_output(server->output); + output_schedule_commit(server->output); +} + +static void +output_hwc_init(struct tinyds_output *output) +{ + struct ds_tdm_output *tdm_output; + + tdm_output = ds_tdm_output_from_output(output->ds_output); + assert(tdm_output); + + output->hwc = ds_tdm_output_get_hwc(tdm_output); + assert(output->hwc); + + ds_tdm_output_hwc_set_enabled(output->hwc, true); } #ifdef USE_TDM_BUFFER_QUEUE @@ -845,14 +1071,11 @@ output_handle_buffer_queue_acquirable(struct wl_listener *listener, void *data TINYDS_UNUSED) { struct tinyds_output *output; - struct ds_buffer *buffer; output = wl_container_of(listener, output, buffer_queue_acquirable); - buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue); - assert(buffer); - - output_swap_buffer(output, buffer); + output->target_updated = true; + output_schedule_commit(output); } static void @@ -894,18 +1117,29 @@ output_draw_with_renderer(struct tinyds_output *output) struct ds_buffer *ds_buffer; struct ds_tbm_client_buffer *tbm_buffer; tbm_surface_h surface; + enum ds_tdm_output_hwc_window_composition composition; if (!view->mapped) continue; + composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); + if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) + continue; + ds_buffer = ds_surface_get_buffer( ds_xdg_surface_get_surface(view->xdg_surface)); - assert(ds_buffer); + if (!ds_buffer) + continue; tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer); - assert(tbm_buffer); + if (!tbm_buffer) + continue; surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer); + if (!surface) + continue; renderer_add_texture(&output->renderer, surface, view->x, view->y); @@ -915,12 +1149,11 @@ output_draw_with_renderer(struct tinyds_output *output) ds_dbg("<< END UPDATE TEXTURES"); renderer_draw(&output->renderer); - } #else static void output_swapchain_init(struct tinyds_output *output, - int width, int height, uint32_t format); + int width, int height, uint32_t format) { output->allocator = ds_tbm_allocator_create(); @@ -937,6 +1170,7 @@ output_draw_with_swapchain(struct tinyds_output *output) struct tinyds_view *view; struct ds_buffer *output_buffer; pixman_image_t *output_image; + enum ds_tdm_output_hwc_window_composition composition; output_buffer = ds_swapchain_acquire(output->swapchain, NULL); if (!output_buffer) @@ -954,10 +1188,23 @@ output_draw_with_swapchain(struct tinyds_output *output) wl_list_for_each(view, &output->server->views, link) { if (!view->mapped) continue; + + composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); + if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) + continue; + draw_view(view, output_image); } pixman_image_unref(output_image); + if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, output_buffer)) { + ds_err("Could not set hwc client target buffer"); + ds_buffer_unlock(output_buffer); + return; + } + output_swap_buffer(output, output_buffer); } @@ -991,25 +1238,19 @@ draw_view(struct tinyds_view *view, pixman_image_t *dst_image) static void draw_output(struct tinyds_output *output) { - - if (!output->drawable || !output->damaged) - return; - #ifdef USE_TDM_BUFFER_QUEUE output_draw_with_renderer(output); #else output_draw_with_swapchain(output); #endif - output->drawable = false; - output->damaged = false; + ds_dbg("output:%p draw", output); } static void output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer) { ds_output_attach_buffer(output->ds_output, buffer); - ds_output_commit(output->ds_output); if (output->front_buffer) ds_buffer_unlock(output->front_buffer); @@ -1460,3 +1701,24 @@ server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) ds_inf("Pointer(%p) added", pointer); } + + +static void +output_schedule_commit_handle_idle_timer(void *data) +{ + struct tinyds_output *output = data; + output->idle_commit = NULL; + + output_commit(output); +} + +static void +output_schedule_commit(struct tinyds_output *output) +{ + if (output->idle_commit) + return; + + struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display); + output->idle_commit = + wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output); +} diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 8b36016..09fbf34 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -309,7 +309,6 @@ ninja -C builddir install %{_libdir}/libds-tizen-backend-tdm.so %{_bindir}/tdm-backend %{_bindir}/tinyds-tdm -%{_bindir}/tinyds-tdm-hwc %{_bindir}/ds-simple-tbm %files tbm-server -- 2.7.4 From 9e1942009c723a5b5b08e6557cff41c5e296d26c Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 12 Aug 2022 14:22:56 +0900 Subject: [PATCH 06/16] devicemgr: null-checking to prevent null pointer dereference Change-Id: Id40d4e7fde37d963bde2071d0def3fc4cc80c4d9 --- src/input_devicemgr/input_devicemgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input_devicemgr/input_devicemgr.c b/src/input_devicemgr/input_devicemgr.c index 00c99b0..69cae4f 100644 --- a/src/input_devicemgr/input_devicemgr.c +++ b/src/input_devicemgr/input_devicemgr.c @@ -1195,7 +1195,7 @@ tz_devicemgr_pressed_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr) wl_list_length(&tz_devicemgr->devices.kbd->key.pressed)); wl_list_for_each_safe(keydata, tmp, &tz_devicemgr->devices.kbd->key.pressed, link) { - if (tz_devicemgr->devices.kbd) + if (tz_devicemgr->devices.kbd->input_device) tz_devicemgr_generate_key(tz_devicemgr->devices.kbd->input_device, keydata->keycode, false); wl_list_remove(&keydata->link); -- 2.7.4 From aa207412ddd175d550dc6df42dfd9c2512e039b2 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 12 Aug 2022 14:41:38 +0900 Subject: [PATCH 07/16] tinyds-tdm: free() an allocated object to prevent a memory leak Change-Id: I8b3a6f9ebe22d50a5489a8a28757a5e7df395cb2 --- examples/tinyds-tdm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index e8416ab..eb542d0 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -464,8 +464,11 @@ add_new_dpms(struct tinyds_server *server) return false; dpms->ds_dpms = ds_tizen_dpms_create(server->display); - if (!dpms->ds_dpms) + if (!dpms->ds_dpms) { + free(dpms); + ds_err("Could not create ds_tizen_dpms"); return false; + } dpms->destroy.notify = dpms_handle_destroy; ds_tizen_dpms_add_destroy_listener(dpms->ds_dpms, &dpms->destroy); -- 2.7.4 From 62c2ec02966d658acd098f66740dc0279c462445 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 12 Aug 2022 15:32:37 +0900 Subject: [PATCH 08/16] tdm: the return value from read() should be checked Change-Id: I53526cb576f16eca858a900394f77d6af70544db --- src/backend/tdm/tdm_buffer_queue.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/tdm/tdm_buffer_queue.c b/src/backend/tdm/tdm_buffer_queue.c index 40e6353..6f0e497 100644 --- a/src/backend/tdm/tdm_buffer_queue.c +++ b/src/backend/tdm/tdm_buffer_queue.c @@ -300,9 +300,10 @@ buffer_queue_handle_acquirable_efd(int fd, uint32_t mask, void *data) { struct ds_tdm_buffer_queue *queue = data; uint64_t acquirable_event; + int len; - if (read(fd, &acquirable_event, sizeof(acquirable_event)) < 0 && - errno != EAGAIN) + len = read(fd, &acquirable_event, sizeof(acquirable_event)); + if (len < 0 && errno != EAGAIN) return -1; wl_signal_emit(&queue->events.acquirable, queue); -- 2.7.4 From 08b921ba90a7823aee6232df6fbdab62f5293992 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 12 Aug 2022 17:13:32 +0900 Subject: [PATCH 09/16] tinyds-tdm: clean up devicemgr related code Change-Id: I92d3142f98f26c8d21dca7f3abd82a7698ca7c5f --- examples/tinyds-tdm.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index eb542d0..9a82f65 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -525,7 +525,7 @@ devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode) data = calloc(1, sizeof *data); if (!data) { - ds_err("Failed to alloc memory\n"); + ds_err("Failed to alloc memory"); return; } @@ -536,15 +536,14 @@ devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode) } static void -devicemgr_remove_keymap_data(struct wl_list *list, int keycode) +devicemgr_cleanup_keymap_list(struct wl_list *list) { struct ds_tizen_input_devicemgr_keymap_data *data, *tmp; wl_list_for_each_safe(data, tmp, list, link) { - if (data->keycode == keycode) { - wl_list_remove(&data->link); - free(data); - } + wl_list_remove(&data->link); + free(data->name); + free(data); } } @@ -565,10 +564,7 @@ devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr) if (!res) ds_inf("Failed to set keymap"); - devicemgr_remove_keymap_data(&keymap_list, 455); - devicemgr_remove_keymap_data(&keymap_list, 456); - devicemgr_remove_keymap_data(&keymap_list, 457); - devicemgr_remove_keymap_data(&keymap_list, 458); + devicemgr_cleanup_keymap_list(&keymap_list); } static void @@ -783,6 +779,7 @@ init_server(struct tinyds_server *server, struct wl_display *display) server->devicemgr = ds_tizen_input_devicemgr_create( server->input_backend, server->seat); if (!server->devicemgr) { + ds_err("Could not create ds_tizen_input_devicemgr"); goto err; } -- 2.7.4 From bbd7c4024ee9c9250c7fb085110e8396469c6a1e Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 12 Aug 2022 17:46:36 +0900 Subject: [PATCH 10/16] tinyds-tdm: returns early to prevent null dereference Change-Id: I691bed00f777f74b2c504d9fa8a41749b48e3e3b --- examples/tinyds-tdm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 9a82f65..2fb1f0e 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -1404,12 +1404,16 @@ server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) kbd->server = server; context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!context) + goto err; + keymap = xkb_keymap_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS); if (!keymap) { ds_err("Failed to compile keymap"); xkb_context_unref(context); + goto err; } ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap); @@ -1426,6 +1430,11 @@ server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) wl_list_insert(&server->keyboards, &kbd->link); ds_inf("Keyboard(%p) added", kbd); + + return; + +err: + free(kbd); } static struct tinyds_view * -- 2.7.4 From 69904952bfe65e89cd19c159d6b46596c58f8839 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 12 Aug 2022 18:09:26 +0900 Subject: [PATCH 11/16] tinyds-tdm: add null-check to prevent null pointer dereference Change-Id: I8e62560f3fb7ebb6e828978d9d20b5c6d502b9b2 --- examples/tinyds-tdm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 2fb1f0e..a7428f1 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -259,10 +259,16 @@ view_populate_pid(struct tinyds_view *view) { pid_t pid; struct wl_client *client = NULL; - struct ds_surface *surface = ds_xdg_surface_get_surface(view->xdg_surface); + struct ds_surface *surface; + + surface = ds_xdg_surface_get_surface(view->xdg_surface); + if (!surface) + return; + + client = wl_resource_get_client(ds_surface_get_wl_resource(surface)); + if (!client) + return; - if (surface) - client = wl_resource_get_client(ds_surface_get_wl_resource(surface)); wl_client_get_credentials(client, &pid, NULL, NULL); ds_inf("view pid(%u)", pid); -- 2.7.4 From 83b2d594dc1dcfd1c37cdf1687f73f87ed6a47cc Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 11 Aug 2022 09:56:06 +0900 Subject: [PATCH 12/16] input_devicemgr: Apply change of function name This change should be applied with follow commit. commit 6b492bf069a1a8754ebac49b6caf42d91ccd0c04 (HEAD -> dnd) Author: Seunghun Lee Date: Thu Aug 11 09:45:03 2022 +0900 seat: Rename ds_seat_keyboard_destroy_grab properly This renames ds_seat_keyboard_destroy_grab to ds_seat_keyboard_grab_destroy The function takes ds_seat_keyboard_grab as a first argument, and we use, by convention, name of object at the beginning of function name. Change-Id: Id993400d0376c7cef4924a1641d186bb1452e03c --- src/input_devicemgr/input_devicemgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input_devicemgr/input_devicemgr.c b/src/input_devicemgr/input_devicemgr.c index 69cae4f..d410fa7 100644 --- a/src/input_devicemgr/input_devicemgr.c +++ b/src/input_devicemgr/input_devicemgr.c @@ -270,7 +270,7 @@ tz_devicemgr_destroy(struct ds_tizen_input_devicemgr *tz_devicemgr) tz_devicemgr_keymap_list_cleanup(tz_devicemgr); tz_devicemgr_blocked_keys_cleanup(tz_devicemgr); tz_devicemgr_ungrab_keyboard(tz_devicemgr); - ds_seat_keyboard_destroy_grab(tz_devicemgr->grab); + ds_seat_keyboard_grab_destroy(tz_devicemgr->grab); wl_signal_emit(&tz_devicemgr->events.destroy, tz_devicemgr); wl_list_remove(&tz_devicemgr->backend_destroy.link); -- 2.7.4 From 54a2d77025db03b479fb9d9eb162cd67bba8ad0c Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Thu, 18 Aug 2022 17:26:03 +0900 Subject: [PATCH 13/16] tbm_server: add get_resource function Change-Id: Ib4d3345dba45c8b3ce7c2276126d8efcdb54b725 Signed-off-by: Junkyeong Kim --- src/tbm_server/tbm_server.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tbm_server/tbm_server.c b/src/tbm_server/tbm_server.c index 0fd25cd..3ae411d 100644 --- a/src/tbm_server/tbm_server.c +++ b/src/tbm_server/tbm_server.c @@ -179,10 +179,21 @@ tbm_client_buffer_iface_end_ptr_access(struct ds_buffer *ds_buffer) tbm_surface_unmap(buffer->surface); } +static struct wl_resource * +tbm_client_buffer_iface_get_resource(struct ds_buffer *ds_buffer) +{ + struct ds_tbm_client_buffer *buffer; + + buffer = tbm_client_buffer_from_buffer(ds_buffer); + + return buffer->resource; +} + static const struct ds_buffer_interface tbm_client_buffer_iface = { .destroy = tbm_client_buffer_iface_destroy, .begin_data_ptr_access = tbm_client_buffer_iface_begin_data_ptr_access, .end_data_ptr_access = tbm_client_buffer_iface_end_ptr_access, + .get_resource = tbm_client_buffer_iface_get_resource, }; static struct ds_tbm_client_buffer * -- 2.7.4 From d2c775cad597a1c2508a7e3d12bb4b0b44b9d27a Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 19 Aug 2022 19:08:17 +0900 Subject: [PATCH 14/16] input_method: implement zwp_input_method and context Change-Id: Icc35ccd4f9e6285c37f9143630cca852b8edfd90 --- include/libds-tizen/input_method.h | 152 ++++++++++ packaging/libds-tizen.spec | 32 ++ src/input_method/input_method.c | 598 +++++++++++++++++++++++++++++++++++++ src/input_method/meson.build | 29 ++ src/meson.build | 1 + tests/meson.build | 21 +- tests/tc_input_method.cpp | 346 +++++++++++++++++++++ 7 files changed, 1178 insertions(+), 1 deletion(-) create mode 100644 include/libds-tizen/input_method.h create mode 100644 src/input_method/input_method.c create mode 100644 src/input_method/meson.build create mode 100644 tests/tc_input_method.cpp diff --git a/include/libds-tizen/input_method.h b/include/libds-tizen/input_method.h new file mode 100644 index 0000000..c79c534 --- /dev/null +++ b/include/libds-tizen/input_method.h @@ -0,0 +1,152 @@ +#ifndef LIBDS_TIZEN_INPUT_METHOD_H +#define LIBDS_TIZEN_INPUT_METHOD_H + +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_input_method_context_event_commit_string +{ + uint32_t serial; + const char *text; +}; + +struct ds_tizen_input_method_context_event_preedit_string +{ + uint32_t serial; + const char *text, *commit; +}; + +struct ds_tizen_input_method_context_event_preedit_styling +{ + uint32_t index, length, style; +}; + +struct ds_tizen_input_method_context_event_preedit_cursor +{ + int32_t index; +}; + +struct ds_tizen_input_method_context_event_delete_surrounding_text +{ + int32_t index; + uint32_t length; +}; + +struct ds_tizen_input_method_context_event_cursor_position +{ + int32_t index, anchor; +}; + +struct ds_tizen_input_method_context_event_modifiers_map +{ + struct wl_array *map; +}; + +struct ds_tizen_input_method_context_event_keysym +{ + uint32_t serial, time, sym, state, modifiers; +}; + +struct ds_tizen_input_method_context_event_language +{ + uint32_t serial; + const char *language; +}; + +struct ds_tizen_input_method_context_event_text_direction +{ + uint32_t serial, direction; +}; + +//input_method +struct ds_tizen_input_method * +ds_tizen_input_method_create(struct wl_display *display); + +struct ds_tizen_input_method_context * +ds_tizen_input_method_create_context(struct ds_tizen_input_method *input_method); + +void +ds_tizen_input_method_add_destroy_listener( + struct ds_tizen_input_method *im, struct wl_listener *listener); +void +ds_tizen_input_method_add_new_input_method_context_listener( + struct ds_tizen_input_method *im, struct wl_listener *listener); + +// events +void ds_tizen_input_method_send_activate(struct ds_tizen_input_method *im, + struct ds_tizen_input_method_context *context); +void ds_tizen_input_method_send_deactivate(struct ds_tizen_input_method *im, + struct ds_tizen_input_method_context *context); + +//input_method_context +void +ds_tizen_input_method_context_add_destroy_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_commit_string_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_preedit_string_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_preedit_styling_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_preedit_cursor_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_delete_surrounding_text_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_cursor_position_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_modifiers_map_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_keysym_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_grab_keyboard_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_key_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_modifiers_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_language_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); +void +ds_tizen_input_method_context_add_text_direction_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener); + +// events +void +ds_tizen_input_method_context_send_surrounding_text(struct ds_tizen_input_method_context *context, + const char *text, uint32_t cursor, uint32_t anchor); +void +ds_tizen_input_method_context_send_reset(struct ds_tizen_input_method_context *context); +void +ds_tizen_input_method_context_send_content_type( + struct ds_tizen_input_method_context *context, uint32_t hint, uint32_t purpose); +void +ds_tizen_input_method_context_send_invoke_action( + struct ds_tizen_input_method_context *context, uint32_t button, uint32_t index); +void +ds_tizen_input_method_context_send_commit_state( + struct ds_tizen_input_method_context *context, uint32_t serial); +void +ds_tizen_input_method_context_send_preferred_language( + struct ds_tizen_input_method_context *context, const char *launguage); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 09fbf34..65b6c33 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(input-method-server) +BuildRequires: pkgconfig(input-method-client) BuildRequires: pkgconfig(pixman-1) BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(xkbcommon) @@ -261,6 +263,21 @@ Group: Development/Libraries %description embedded-compositor-devel Development package for tizen embedded compositor +## libds-tizen-input-method +%package input-method +Summary: Library for tizen input-method +Group: Development/Libraries + +%description input-method +Library for tizen input-method + +%package input-method-devel +Summary: Development package for tizen input-method +Group: Development/Libraries + +%description input-method-devel +Development package for tizen input-method + %prep %setup -q cp %{SOURCE1001} . @@ -504,3 +521,18 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-embedded-compositor.pc %{_libdir}/libds-tizen-embedded-compositor.so %{_bindir}/libds-tizen-embedded-compositor-tests + +%files input-method +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-input-method.so.* + +%files input-method-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/input_method.h +%{_libdir}/pkgconfig/libds-tizen-input-method.pc +%{_libdir}/libds-tizen-input-method.so +%{_bindir}/libds-tizen-input-method-tests diff --git a/src/input_method/input_method.c b/src/input_method/input_method.c new file mode 100644 index 0000000..0481e1a --- /dev/null +++ b/src/input_method/input_method.c @@ -0,0 +1,598 @@ +#include +#include +#include +#include + +#include "util.h" +#include +#include + +#define INPUT_METHOD_VERSION 1 + +struct ds_tizen_input_method; + +struct ds_tizen_input_method_context { + struct wl_resource *resource; + struct ds_tizen_input_method *input_method; + + struct { + struct wl_signal destroy; + struct wl_signal commit_string; + struct wl_signal preedit_string; + struct wl_signal preedit_styling; + struct wl_signal preedit_cursor; + struct wl_signal delete_surrounding_text; + struct wl_signal cursor_position; + struct wl_signal modifiers_map; + struct wl_signal keysym; + struct wl_signal grab_keyboard; + struct wl_signal key; + struct wl_signal modifiers; + struct wl_signal language; + struct wl_signal text_direction; + } events; +}; + +struct ds_tizen_input_method { + struct wl_global *global; + struct wl_resource *resource; + struct ds_tizen_input_method_context *context; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal new_input_method_context; + } events; +}; + +static const struct zwp_input_method_context_v1_interface context_impl; + +WL_EXPORT void +ds_tizen_input_method_add_destroy_listener( + struct ds_tizen_input_method *im, struct wl_listener *listener) +{ + wl_signal_add(&im->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_input_method_add_new_input_method_context_listener( + struct ds_tizen_input_method *im, struct wl_listener *listener) +{ + wl_signal_add(&im->events.new_input_method_context, listener); +} + +WL_EXPORT void +ds_tizen_input_method_send_activate(struct ds_tizen_input_method *im, + struct ds_tizen_input_method_context *context) +{ + if (!im || !context) return; + + ds_inf("ds_tizen_input_method_send_activate"); + zwp_input_method_v1_send_activate(im->resource, context->resource); +} + +WL_EXPORT void +ds_tizen_input_method_send_deactivate(struct ds_tizen_input_method *im, + struct ds_tizen_input_method_context *context) +{ + if (!im || !context) return; + + ds_inf("ds_tizen_input_method_send_deactivate"); + zwp_input_method_v1_send_deactivate(im->resource, context->resource); +} + +static void +context_destroy(struct ds_tizen_input_method_context *context) +{ + ds_inf("input_method_context(%p) destroy", context); + + wl_signal_emit(&context->events.destroy, context); + + free(context); +} + +static void +input_method_context_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method *input_method; + + ds_inf("input_method_context_client_handle_destroy"); + + input_method = context->input_method; + input_method->context = NULL; + + context_destroy(context); +} + +WL_EXPORT struct ds_tizen_input_method_context * +ds_tizen_input_method_create_context(struct ds_tizen_input_method *input_method) +{ + struct ds_tizen_input_method_context *context; + struct wl_resource *binding; + + ds_inf("ds_tizen_input_method_create_context"); + context = calloc(1, sizeof *context); + if (context == NULL) + return NULL; + + binding = input_method->resource; + if (!binding) return NULL; + context->resource = wl_resource_create(wl_resource_get_client(binding), + &zwp_input_method_context_v1_interface, INPUT_METHOD_VERSION, 0); + wl_resource_set_implementation(context->resource, &context_impl, + context, input_method_context_client_handle_destroy); + + wl_signal_init(&context->events.destroy); + wl_signal_init(&context->events.commit_string); + wl_signal_init(&context->events.preedit_string); + wl_signal_init(&context->events.preedit_styling); + wl_signal_init(&context->events.preedit_cursor); + wl_signal_init(&context->events.delete_surrounding_text); + wl_signal_init(&context->events.cursor_position); + wl_signal_init(&context->events.modifiers_map); + wl_signal_init(&context->events.keysym); + wl_signal_init(&context->events.grab_keyboard); + wl_signal_init(&context->events.key); + wl_signal_init(&context->events.modifiers); + wl_signal_init(&context->events.language); + wl_signal_init(&context->events.text_direction); + + wl_signal_emit(&input_method->events.new_input_method_context, context); + + ds_tizen_input_method_send_activate(input_method, context); + + input_method->context = context; + context->input_method = input_method; + + return context; +} + +WL_EXPORT void +ds_tizen_input_method_context_add_destroy_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_commit_string_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.commit_string, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_preedit_string_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.preedit_string, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_preedit_styling_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.preedit_styling, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_preedit_cursor_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.preedit_cursor, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_delete_surrounding_text_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.delete_surrounding_text, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_cursor_position_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.cursor_position, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_modifiers_map_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.modifiers_map, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_keysym_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.keysym, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_grab_keyboard_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.grab_keyboard, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_key_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.key, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_modifiers_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.modifiers, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_language_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.language, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_add_text_direction_listener( + struct ds_tizen_input_method_context *context, struct wl_listener *listener) +{ + wl_signal_add(&context->events.text_direction, listener); +} + +WL_EXPORT void +ds_tizen_input_method_context_send_surrounding_text(struct ds_tizen_input_method_context *context, + const char *text, uint32_t cursor, uint32_t anchor) +{ + if (!context || !context->resource) return; + + ds_inf("ds_tizen_input_method_context_send_surrounding_text"); + zwp_input_method_context_v1_send_surrounding_text(context->resource, text, cursor, anchor); +} + +WL_EXPORT void +ds_tizen_input_method_context_send_reset( + struct ds_tizen_input_method_context *context) +{ + if (!context || !context->resource) return; + + ds_inf("ds_tizen_input_method_context_send_reset"); + zwp_input_method_context_v1_send_reset(context->resource); +} + +WL_EXPORT void +ds_tizen_input_method_context_send_content_type( + struct ds_tizen_input_method_context *context, uint32_t hint, uint32_t purpose) +{ + if (!context || !context->resource) return; + + ds_inf("ds_tizen_input_method_context_send_content_type"); + zwp_input_method_context_v1_send_content_type(context->resource, hint, purpose); +} + +WL_EXPORT void +ds_tizen_input_method_context_send_invoke_action( + struct ds_tizen_input_method_context *context, uint32_t button, uint32_t index) +{ + if (!context || !context->resource) return; + + ds_inf("ds_tizen_input_method_context_send_invoke_action"); + zwp_input_method_context_v1_send_invoke_action(context->resource, button, index); +} + +WL_EXPORT void +ds_tizen_input_method_context_send_commit_state( + struct ds_tizen_input_method_context *context, uint32_t serial) +{ + if (!context || !context->resource) return; + + ds_inf("ds_tizen_input_method_context_send_commit_state"); + zwp_input_method_context_v1_send_commit_state(context->resource, serial); +} + +WL_EXPORT void +ds_tizen_input_method_context_send_preferred_language( + struct ds_tizen_input_method_context *context, const char *language) +{ + if (!context || !context->resource) return; + + ds_inf("ds_tizen_input_method_context_send_preferred_language"); + zwp_input_method_context_v1_send_preferred_language(context->resource, language); +} + +static void +context_handle_destroy(struct wl_client *client, struct wl_resource *resource) +{ + ds_inf("context_handle_destroy"); + wl_resource_destroy(resource); +} + +static void +context_handle_commit_string(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, const char *text) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_commit_string ds_event; + + ds_inf("context_handle_commit_string"); + ds_event.serial = serial; + ds_event.text = text; + + wl_signal_emit(&context->events.commit_string, &ds_event); +} + +static void +context_handle_preedit_string(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, const char *text, + const char *commit) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_preedit_string ds_event; + + ds_inf("context_handle_preedit_string() serial:%u, text:%s, commit:%s", + serial, text, commit); + + ds_event.serial = serial; + ds_event.text = text; + ds_event.commit = commit; + + wl_signal_emit(&context->events.preedit_string, &ds_event); +} + +static void +context_handle_preedit_styling(struct wl_client *client, + struct wl_resource *resource, uint32_t index, uint32_t length, + uint32_t style) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_preedit_styling ds_event; + + ds_inf("context_handle_preedit_styling() index:%u, length:%u, style:%u", + index, length, style); + + ds_event.index = index; + ds_event.length = length; + ds_event.style = style; + + wl_signal_emit(&context->events.preedit_styling, &ds_event); +} + +static void +context_handle_preedit_cursor(struct wl_client *client, + struct wl_resource *resource, int32_t index) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_preedit_cursor ds_event; + + ds_inf("context_handle_preedit_cursor() cursor:%d", index); + + ds_event.index = index; + wl_signal_emit(&context->events.preedit_styling, &ds_event); +} + +static void +context_handle_delete_surrounding_text(struct wl_client *client, + struct wl_resource *resource, int32_t index, uint32_t length) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_delete_surrounding_text ds_event; + + ds_inf("context_handle_delete_surrounding_text() index:%d, length:%u", index, length); + + ds_event.index = index; + ds_event.length = length; + wl_signal_emit(&context->events.delete_surrounding_text, &ds_event); +} + +static void +context_handle_cursor_position(struct wl_client *client, + struct wl_resource *resource, int32_t index, int32_t anchor) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_cursor_position ds_event; + + ds_inf("context_handle_cursor_position() index:%d anchor:%d", index, anchor); + + ds_event.index = index; + ds_event.anchor = anchor; + wl_signal_emit(&context->events.cursor_position, &ds_event); +} + +static void +context_handle_modifiers_map(struct wl_client *client, + struct wl_resource *resource, struct wl_array *map) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_modifiers_map ds_event; + + ds_inf("context_handle_modifiers_map() map(%p)", map); + + ds_event.map = map; + wl_signal_emit(&context->events.modifiers_map, &ds_event); +} + +static void +context_handle_keysym(struct wl_client *client, struct wl_resource *resource, + uint32_t serial, uint32_t time, uint32_t sym, + uint32_t state, uint32_t modifiers) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_keysym ds_event; + + ds_inf("context_handle_keysym() serial(%u), time(%u), sym(%u), state(%u), modifiers(%u)", + serial, time, sym, state, modifiers); + + ds_event.serial = serial; + ds_event.time = time; + ds_event.sym = sym; + ds_event.state = state; + ds_event.modifiers = modifiers; + wl_signal_emit(&context->events.keysym, &ds_event); +} + +static void +context_handle_grab_keyboard(struct wl_client *client, + struct wl_resource *resource, uint32_t id) +{ + ds_inf("context_handle_grab_keyboard() nothing done"); + //TODO +} + +static void +context_handle_key(struct wl_client *client, struct wl_resource *resource, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w) +{ + ds_inf("context_handle_key() nothing done"); + //TODO +} + +static void +context_handle_modifiers(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ + ds_inf("context_handle_modifiers() nothing done"); + //TODO +} + +static void +context_handle_language(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, const char *language) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_language ds_event; + + ds_inf("context_handle_language() serial(%u) language(%s)", serial, language); + + ds_event.serial = serial; + ds_event.language = language; + wl_signal_emit(&context->events.language, &ds_event); +} + +static void +context_handle_text_direction(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, uint32_t direction) +{ + struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource); + struct ds_tizen_input_method_context_event_text_direction ds_event; + + ds_inf("context_handle_text_direction() serial(%u) direction(%u)", serial, direction); + + ds_event.serial = serial; + ds_event.direction = direction; + wl_signal_emit(&context->events.text_direction, &ds_event); +} + +static const struct zwp_input_method_context_v1_interface context_impl = { + .destroy = context_handle_destroy, + .commit_string = context_handle_commit_string, + .preedit_string = context_handle_preedit_string, + .preedit_styling = context_handle_preedit_styling, + .preedit_cursor = context_handle_preedit_cursor, + .delete_surrounding_text = context_handle_delete_surrounding_text, + .cursor_position = context_handle_cursor_position, + .modifiers_map = context_handle_modifiers_map, + .keysym = context_handle_keysym, + .grab_keyboard = context_handle_grab_keyboard, + .key = context_handle_key, + .modifiers = context_handle_modifiers, + .language = context_handle_language, + .text_direction = context_handle_text_direction, + //for tizen_only + .selection_region = NULL, + .private_command = NULL, + .update_input_panel_data = NULL, + .hide_input_panel = NULL, + .get_selection_text = NULL, + .get_surrounding_text = NULL, + .filter_key_event_done = NULL, + .update_ise_geometry = NULL, + .recapture_string = NULL, + .input_panel_event = NULL, + .commit_content = NULL, + .update_candidate_state = NULL, + .reshow_input_panel = NULL, + .set_floating_panel = NULL, + .set_floating_drag_enabled = NULL, +}; + +static void +input_method_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_input_method *input_method; + + input_method = wl_container_of(listener, input_method, destroy); + + ds_inf("Global destroy: input_method(%p)", input_method); + + if (input_method->context) + context_destroy(input_method->context); + + wl_signal_emit(&input_method->events.destroy, input_method); + wl_list_remove(&input_method->destroy.link); + + wl_global_destroy(input_method->global); + free(input_method); +} + +static void +input_method_client_handle_destroy(struct wl_resource *resource) +{ + ds_inf("input_method_client_handle_destroy"); +} + +static void +input_method_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id) +{ + struct ds_tizen_input_method *input_method = data; + + ds_inf("input_method. client binds. (client:%p)", wl_client); + + input_method->resource = wl_resource_create(wl_client, + &zwp_input_method_v1_interface, + version, id); + if (input_method->resource == NULL) { + ds_err("input_method. wl_resource_create() failed."); + wl_client_post_no_memory(wl_client); + return; + } + wl_resource_set_implementation(input_method->resource, NULL, + input_method, input_method_client_handle_destroy); +} + +WL_EXPORT struct ds_tizen_input_method * +ds_tizen_input_method_create(struct wl_display *display) +{ + struct ds_tizen_input_method *input_method; + + input_method = calloc(1, sizeof *input_method); + if (input_method == NULL) { + ds_err("calloc() failed. ds_tizen_input_method"); + return NULL; + } + + input_method->global = wl_global_create(display, + &zwp_input_method_v1_interface, INPUT_METHOD_VERSION, input_method, input_method_bind); + if (!input_method->global) { + free(input_method); + return NULL; + } + + wl_signal_init(&input_method->events.destroy); + wl_signal_init(&input_method->events.new_input_method_context); + + input_method->destroy.notify = input_method_handle_display_destroy; + wl_display_add_destroy_listener(display, &input_method->destroy); + + ds_inf("Global create: zwp_input_method_v1. input_method(%p)", input_method); + + return input_method; +} diff --git a/src/input_method/meson.build b/src/input_method/meson.build new file mode 100644 index 0000000..eb20352 --- /dev/null +++ b/src/input_method/meson.build @@ -0,0 +1,29 @@ +libds_tizen_input_method_files = [ + 'input_method.c', +] + +libds_tizen_input_method_deps = [ + deps_libds_tizen, + dependency('input-method-server', required: true), +] + +lib_libds_tizen_input_method = shared_library('ds-tizen-input-method', libds_tizen_input_method_files, + dependencies: libds_tizen_input_method_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_input_method = declare_dependency( + link_with: lib_libds_tizen_input_method, + dependencies: libds_tizen_input_method_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_input_method, + version: meson.project_version(), + filebase: 'libds-tizen-input-method', + name: 'libds-tizen-input-method', + description: 'tizen input-method extension of libds-tizen for tizen platform', +) diff --git a/src/meson.build b/src/meson.build index a1ba1ab..37ef631 100644 --- a/src/meson.build +++ b/src/meson.build @@ -42,3 +42,4 @@ subdir('renderer') subdir('screen_rotation') subdir('global_resource') subdir('embedded_compositor') +subdir('input_method') diff --git a/tests/meson.build b/tests/meson.build index 34b9245..9ec62fa 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -226,4 +226,23 @@ executable('libds-tizen-embedded-compositor-tests', ], install_dir: libds_tizen_bindir, install : true -) \ No newline at end of file +) + +## input method tests +tc_input_method_files = [ + 'tc_main.cpp', + 'tc_input_method.cpp', +] + +executable('libds-tizen-input-method-tests', + [ + tc_mock_files, + tc_input_method_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_input_method, + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/tc_input_method.cpp b/tests/tc_input_method.cpp new file mode 100644 index 0000000..1bbc1be --- /dev/null +++ b/tests/tc_input_method.cpp @@ -0,0 +1,346 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include +#include + +#define INPUT_METHOD_VERSION 1 + +class MockInputMethodCompositor : public MockCompositor +{ +public: + MockInputMethodCompositor() + : MockCompositor(&MockInputMethodCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bDestroyed = false; + bNewInputMethodContext = false; + } + + ~MockInputMethodCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockInputMethodCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + mockComp->mInputMethod = ds_tizen_input_method_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockInputMethodCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_input_method_add_destroy_listener(mockComp->mInputMethod, + &mockComp->mDestroyListener); + + // new input method context listener + mockComp->mNewInputMethodContextListener.notify = + MockInputMethodCompositor::NewInputMethodContextCallback; + mockComp->mNewInputMethodContextListener.parent = mockComp; + ds_tizen_input_method_add_new_input_method_context_listener(mockComp->mInputMethod, + &mockComp->mNewInputMethodContextListener); + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockInputMethodCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void NewInputMethodContextCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockInputMethodCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_input_method_context *context = + static_cast(data); + + ds_inf("%s: mockComp(%p), input_method_context(%p)", __func__, mockComp, context); + + mockComp->mInputMethodContext = context; + mockComp->bNewInputMethodContext = true; + } + + void CreateInputMethodContext() + { + ds_inf("%s", __func__); + + ds_tizen_input_method_create_context(mInputMethod); + } + + void SendActivate() + { + ds_inf("%s", __func__); + + ds_tizen_input_method_send_activate(mInputMethod, mInputMethodContext); + } + + void SendDeactivate() + { + ds_inf("%s", __func__); + + ds_tizen_input_method_send_deactivate(mInputMethod, mInputMethodContext); + } + +public: + bool bDestroyed; + bool bNewInputMethodContext; + +private: + struct ds_tizen_input_method_manager *mInputMethodMgr; + struct ds_tizen_input_method *mInputMethod; + struct ds_tizen_input_method_context *mInputMethodContext; + + struct DestroyListener: ::wl_listener { + MockInputMethodCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct NewInputMethodContextListener: ::wl_listener { + MockInputMethodCompositor *parent; + }; + NewInputMethodContextListener mNewInputMethodContextListener; +}; + +class MockInputMethodClient : public MockClient +{ +public: + MockInputMethodClient() + : bActivate(false), + bDeactivate(false), + compositor_res(nullptr), + zwp_input_method(nullptr) + {} + + MockInputMethodClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + } + + ~MockInputMethodClient() + { + 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 SetInputMethod(struct zwp_input_method_v1 *global_res) + { + ds_inf("%s", __func__); + zwp_input_method = global_res; + } + + struct zwp_input_method_v1 *GetInputMethod() + { + ds_inf("%s", __func__); + + return zwp_input_method; + } + +public: + bool bActivate; + bool bDeactivate; + +private: + struct wl_compositor *compositor_res; + struct zwp_input_method_v1 *zwp_input_method; +}; + +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__); + + MockInputMethodClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct zwp_input_method_v1 *zwp_input_method; + + 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, "zwp_input_method_v1")) { + zwp_input_method = (struct zwp_input_method_v1 *)wl_registry_bind(registry, + name, &zwp_input_method_v1_interface, INPUT_METHOD_VERSION); + if (zwp_input_method == nullptr) { + ds_err("wl_registry_bind() failed. zwp_input_method_v1 resource."); + return; + } + client->SetInputMethod(zwp_input_method); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockInputMethodClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct zwp_input_method_v1 *input_method_res = client->GetInputMethod(); + + zwp_input_method_v1_destroy(input_method_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 +im_cb_activate (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx) +{ + ds_inf("%s", __func__); + + MockInputMethodClient *client = static_cast(data); + client->bActivate = true; +} +static void +im_cb_deactivate (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx) +{ + ds_inf("%s", __func__); + + MockInputMethodClient *client = static_cast(data); + client->bDeactivate = true; +} +static void +im_cb_destroy (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx) +{} +static void +im_cb_show_input_panel (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx, uint32_t angle) +{} +static void +im_cb_hide_input_panel (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx) +{} +static void +im_cb_open_connection (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx) +{} +static void +im_cb_close_connection (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx) +{} +static void +im_cb_set_text_input_id (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx, uint32_t text_input_id) +{} +static const struct zwp_input_method_v1_listener input_method_cb_listener = { + .activate = im_cb_activate, + .deactivate = im_cb_deactivate, + //for tizen only + .destroy = im_cb_destroy, + .show_input_panel = im_cb_show_input_panel, + .hide_input_panel = im_cb_hide_input_panel, + .open_connection = im_cb_open_connection, + .close_connection = im_cb_close_connection, + .set_text_input_id = im_cb_set_text_input_id, +}; + +class InputMethodTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockInputMethodCompositor *comp; + MockInputMethodClient *client; + struct wl_compositor *compositor_res; + struct zwp_input_method_v1 *input_method_res; +}; + +void +InputMethodTest::SetUp(void) +{ + ds_log_init(DS_INF, NULL); + + ds_inf("%s", __func__); + + comp = new MockInputMethodCompositor(); + client = new MockInputMethodClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + input_method_res = client->GetInputMethod(); + + zwp_input_method_v1_add_listener(input_method_res, + &input_method_cb_listener, client); + + client->RoundTrip(); +} + +void +InputMethodTest::TearDown(void) +{ + ds_inf("%s", __func__); + + client->RoundTrip(); + + delete client; + delete comp; +} + +TEST_F(InputMethodTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(InputMethodTest, CreateInputMethodContext) +{ + comp->CreateInputMethodContext(); + comp->Process(); + + EXPECT_TRUE(comp->bNewInputMethodContext); +} + +TEST_F(InputMethodTest, Ev_Activate) +{ + comp->CreateInputMethodContext(); + comp->Process(); + + comp->SendActivate(); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->bActivate); +} + +TEST_F(InputMethodTest, Ev_Deactivate) +{ + comp->CreateInputMethodContext(); + comp->Process(); + + comp->SendDeactivate(); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->bDeactivate); +} -- 2.7.4 From 025afe5a1bdd21b7353b05c5c20e1b96b962f9e9 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 19 Aug 2022 19:19:24 +0900 Subject: [PATCH 15/16] input_method: implement zwp_input_method_manager Change-Id: Ia98c1e325f014ad0f4c3f2445f236b2b4e93eba8 --- include/libds-tizen/input_method.h | 16 +++ packaging/libds-tizen.spec | 1 + src/input_method/input_method.c | 121 ++++++++++++++++++ tests/meson.build | 19 +++ tests/tc_input_method_manager.cpp | 255 +++++++++++++++++++++++++++++++++++++ 5 files changed, 412 insertions(+) create mode 100644 tests/tc_input_method_manager.cpp diff --git a/include/libds-tizen/input_method.h b/include/libds-tizen/input_method.h index c79c534..731b889 100644 --- a/include/libds-tizen/input_method.h +++ b/include/libds-tizen/input_method.h @@ -8,6 +8,11 @@ extern "C" { #endif +struct ds_tizen_input_method_manager_event_set_transient_for +{ + uint32_t pid_parent, pid_child; +}; + struct ds_tizen_input_method_context_event_commit_string { uint32_t serial; @@ -62,6 +67,17 @@ struct ds_tizen_input_method_context_event_text_direction uint32_t serial, direction; }; +//input_method_manager +struct ds_tizen_input_method_manager * +ds_tizen_input_method_manager_create(struct wl_display *display); + +void +ds_tizen_input_method_manager_add_destroy_listener( + struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener); +void +ds_tizen_input_method_manager_add_set_transient_for_listener( + struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener); + //input_method struct ds_tizen_input_method * ds_tizen_input_method_create(struct wl_display *display); diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 65b6c33..4db5813 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -536,3 +536,4 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-input-method.pc %{_libdir}/libds-tizen-input-method.so %{_bindir}/libds-tizen-input-method-tests +%{_bindir}/libds-tizen-input-method-manager-tests diff --git a/src/input_method/input_method.c b/src/input_method/input_method.c index 0481e1a..2293272 100644 --- a/src/input_method/input_method.c +++ b/src/input_method/input_method.c @@ -46,7 +46,128 @@ struct ds_tizen_input_method { } events; }; +struct ds_tizen_input_method_manager { + struct wl_global *global; + struct wl_resource *resource; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal set_transient_for; + } events; +}; + static const struct zwp_input_method_context_v1_interface context_impl; +static const struct zwp_input_method_manager_v1_interface input_method_mgr_impl; + +WL_EXPORT void +ds_tizen_input_method_manager_add_destroy_listener( + struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener) +{ + wl_signal_add(&im_mgr->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_input_method_manager_add_set_transient_for_listener( + struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener) +{ + wl_signal_add(&im_mgr->events.set_transient_for, listener); +} + +static void +input_method_mgr_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_input_method_manager *input_method_mgr; + + input_method_mgr = wl_container_of(listener, input_method_mgr, destroy); + + ds_inf("Global destroy: input_method_mgr(%p)", input_method_mgr); + + wl_signal_emit(&input_method_mgr->events.destroy, input_method_mgr); + wl_list_remove(&input_method_mgr->destroy.link); + + wl_global_destroy(input_method_mgr->global); + free(input_method_mgr); +} + +static void +input_method_mgr_handle_set_transient_for(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t parent_pid, uint32_t child_pid) +{ + struct ds_tizen_input_method_manager_event_set_transient_for ds_event; + struct ds_tizen_input_method_manager *input_method_mgr; + + input_method_mgr = wl_resource_get_user_data(resource); + + ds_inf("input_method_mgr_handle_set_transient_for() parent:%u, child:%u", + parent_pid, child_pid); + + ds_event.pid_parent = parent_pid; + ds_event.pid_child = child_pid; + wl_signal_emit(&input_method_mgr->events.set_transient_for, &ds_event); +} + +static const struct zwp_input_method_manager_v1_interface input_method_mgr_impl = +{ + .set_transient_for = input_method_mgr_handle_set_transient_for, +}; + +static void +input_method_mgr_client_handle_destroy(struct wl_resource *resource) +{ + ds_inf("input_method_mgr_client_handle_destroy"); +} + +static void +input_method_mgr_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id) +{ + struct ds_tizen_input_method_manager *input_method_mgr = data; + struct wl_resource *resource; + + ds_inf("input_method_mgr. client binds. (client:%p)", wl_client); + + resource = wl_resource_create(wl_client, + &zwp_input_method_manager_v1_interface, + version, id); + if (resource == NULL) { + ds_err("input_method_mgr. wl_resource_create() failed."); + wl_client_post_no_memory(wl_client); + return; + } + wl_resource_set_implementation(resource, &input_method_mgr_impl, + input_method_mgr, input_method_mgr_client_handle_destroy); +} + +WL_EXPORT struct ds_tizen_input_method_manager * +ds_tizen_input_method_manager_create(struct wl_display *display) +{ + struct ds_tizen_input_method_manager *input_method_mgr; + + input_method_mgr = calloc(1, sizeof *input_method_mgr); + if (input_method_mgr == NULL) { + ds_err("calloc() failed. ds_tizen_input_method_manager"); + return NULL; + } + + input_method_mgr->global = wl_global_create(display, + &zwp_input_method_manager_v1_interface, INPUT_METHOD_VERSION, input_method_mgr, input_method_mgr_bind); + if (!input_method_mgr->global) { + free(input_method_mgr); + return NULL; + } + + wl_signal_init(&input_method_mgr->events.destroy); + wl_signal_init(&input_method_mgr->events.set_transient_for); + + input_method_mgr->destroy.notify = input_method_mgr_handle_display_destroy; + wl_display_add_destroy_listener(display, &input_method_mgr->destroy); + + ds_inf("Global create: zwp_input_method_manager_v1. input_method_mgr(%p)", input_method_mgr); + + return input_method_mgr; +} WL_EXPORT void ds_tizen_input_method_add_destroy_listener( diff --git a/tests/meson.build b/tests/meson.build index 9ec62fa..e8e4421 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -246,3 +246,22 @@ executable('libds-tizen-input-method-tests', install_dir: libds_tizen_bindir, install : true ) + +## input method tests +tc_input_method_manager_files = [ + 'tc_main.cpp', + 'tc_input_method_manager.cpp', +] + +executable('libds-tizen-input-method-manager-tests', + [ + tc_mock_files, + tc_input_method_manager_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_input_method, + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/tc_input_method_manager.cpp b/tests/tc_input_method_manager.cpp new file mode 100644 index 0000000..a338d8f --- /dev/null +++ b/tests/tc_input_method_manager.cpp @@ -0,0 +1,255 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include +#include + +#define INPUT_METHOD_VERSION 1 + +class MockInputMethodMgrCompositor : public MockCompositor +{ +public: + MockInputMethodMgrCompositor() + : MockCompositor(&MockInputMethodMgrCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bDestroyed = false; + + bSetTransientFor = false; + mParentPid = 0; + mChildPid = 0; + } + + ~MockInputMethodMgrCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockInputMethodMgrCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + mockComp->mInputMethodMgr = ds_tizen_input_method_manager_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockInputMethodMgrCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_input_method_manager_add_destroy_listener(mockComp->mInputMethodMgr, + &mockComp->mDestroyListener); + + // set_transient_for listener + mockComp->mSetTransientForListener.notify = + MockInputMethodMgrCompositor::SetTransientForCallback; + mockComp->mSetTransientForListener.parent = mockComp; + ds_tizen_input_method_manager_add_set_transient_for_listener(mockComp->mInputMethodMgr, + &mockComp->mSetTransientForListener); + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockInputMethodMgrCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void SetTransientForCallback(struct wl_listener *listener, void *data) + { + struct ds_tizen_input_method_manager_event_set_transient_for *event = + (struct ds_tizen_input_method_manager_event_set_transient_for *)data; + + ds_inf("%s", __func__); + + MockInputMethodMgrCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bSetTransientFor = true; + mockComp->mParentPid = event->pid_parent; + mockComp->mChildPid = event->pid_child; + } + +public: + bool bDestroyed; + bool bSetTransientFor; + uint32_t mParentPid; + uint32_t mChildPid; + +private: + struct ds_tizen_input_method_manager *mInputMethodMgr; + struct DestroyListener: ::wl_listener { + MockInputMethodMgrCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct SetTransientForListener: ::wl_listener { + MockInputMethodMgrCompositor *parent; + }; + SetTransientForListener mSetTransientForListener; +}; + +class MockInputMethodMgrClient : public MockClient +{ +public: + MockInputMethodMgrClient() + : bActivated(false), + compositor_res(nullptr), + zwp_input_method_manager(nullptr) + {} + + MockInputMethodMgrClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + } + + ~MockInputMethodMgrClient() + { + 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 SetInputMethodMgr(struct zwp_input_method_manager_v1 *global_res) + { + ds_inf("%s", __func__); + zwp_input_method_manager = global_res; + } + + struct zwp_input_method_manager_v1 *GetInputMethodMgr() + { + ds_inf("%s", __func__); + + return zwp_input_method_manager; + } + +public: + bool bActivated; + +private: + struct wl_compositor *compositor_res; + struct zwp_input_method_manager_v1 *zwp_input_method_manager; +}; + +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__); + + MockInputMethodMgrClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct zwp_input_method_manager_v1 *zwp_input_method_manager; + + 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, "zwp_input_method_manager_v1")) { + zwp_input_method_manager = (struct zwp_input_method_manager_v1 *)wl_registry_bind(registry, + name, &zwp_input_method_manager_v1_interface, INPUT_METHOD_VERSION); + if (zwp_input_method_manager == nullptr) { + ds_err("wl_registry_bind() failed. zwp_input_method_manager_v1 resource."); + return; + } + client->SetInputMethodMgr(zwp_input_method_manager); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockInputMethodMgrClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct zwp_input_method_manager_v1 *input_method_mgr_res = client->GetInputMethodMgr(); + + zwp_input_method_manager_v1_destroy(input_method_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 +}; + +class InputMethodMgrTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockInputMethodMgrCompositor *comp; + MockInputMethodMgrClient *client; + struct wl_compositor *compositor_res; + struct zwp_input_method_manager_v1 *input_method_mgr_res; +}; + +void +InputMethodMgrTest::SetUp(void) +{ + ds_log_init(DS_INF, NULL); + + ds_inf("%s", __func__); + + comp = new MockInputMethodMgrCompositor(); + client = new MockInputMethodMgrClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + input_method_mgr_res = client->GetInputMethodMgr(); + + client->RoundTrip(); +} + +void +InputMethodMgrTest::TearDown(void) +{ + ds_inf("%s", __func__); + + client->RoundTrip(); + + delete client; + delete comp; +} + +TEST_F(InputMethodMgrTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(InputMethodMgrTest, Req_SetTransientFor) +{ + uint32_t parent_pid = 123; + uint32_t child_pid = 321; + + zwp_input_method_manager_v1_set_transient_for(input_method_mgr_res, parent_pid, child_pid); + client->RoundTrip(); + EXPECT_TRUE(comp->mParentPid == parent_pid); + EXPECT_TRUE(comp->mChildPid == child_pid); +} \ No newline at end of file -- 2.7.4 From a27b3a06a1b1d7aac09d794d9bf10d13c1477440 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Mon, 22 Aug 2022 10:16:15 +0900 Subject: [PATCH 16/16] 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