From f5fbf8e54a44f3c0998c54e5c465a483d738eb53 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Thu, 21 Jul 2022 16:43:21 +0900 Subject: [PATCH 01/16] impelement libds-tizen-renderer This is the server implementation for tizen_renderer protocol. Change-Id: Id7d91034cf43e0ee201cc9ea3e92eb05305e2787 --- include/libds-tizen/renderer.h | 44 ++++++ packaging/libds-tizen.spec | 29 ++++ src/meson.build | 1 + src/renderer/meson.build | 29 ++++ src/renderer/renderer.c | 334 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 437 insertions(+) create mode 100644 include/libds-tizen/renderer.h create mode 100644 src/renderer/meson.build create mode 100644 src/renderer/renderer.c diff --git a/include/libds-tizen/renderer.h b/include/libds-tizen/renderer.h new file mode 100644 index 0000000..6f02ca0 --- /dev/null +++ b/include/libds-tizen/renderer.h @@ -0,0 +1,44 @@ +#ifndef LIBDS_TIZEN_RENDERER_H +#define LIBDS_TIZEN_RENDERER_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_renderer; +struct ds_tizen_renderer_info; + +struct ds_tizen_renderer * +ds_tizen_renderer_create(struct wl_display *display); + +void +ds_tizen_renderer_add_destroy_listener(struct ds_tizen_renderer *renderer, + struct wl_listener *listener); + +void +ds_tizen_renderer_add_get_renderer_surface_info_listener( + struct ds_tizen_renderer *renderer, + struct wl_listener *listener); + +void +ds_tizen_renderer_info_add_destroy_listener( + struct ds_tizen_renderer_info *info, + struct wl_listener *listener); + +struct ds_surface * +ds_tizen_renderer_info_get_surface( + struct ds_tizen_renderer_info *info); + +void +ds_tizen_renderer_info_send_redraw( + struct ds_tizen_renderer_info *info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 9777876..8eddf79 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -201,6 +201,21 @@ Group: Development/Libraries %description memory-flusher-devel Development package for tizen memory flusher +## libds-tizen-renderer +%package renderer +Summary: Library for tizen renderer +Group: Development/Libraries + +%description renderer +Library for tizen renderer + +%package renderer-devel +Summary: Development package for tizen renderer +Group: Development/Libraries + +%description renderer-devel +Development package for tizen renderer + %prep %setup -q cp %{SOURCE1001} . @@ -387,3 +402,17 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-memory-flusher.pc %{_libdir}/libds-tizen-memory-flusher.so %{_bindir}/libds-tizen-memory-flusher-tests + +%files renderer +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-renderer.so.* + +%files renderer-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/renderer.h +%{_libdir}/pkgconfig/libds-tizen-renderer.pc +%{_libdir}/libds-tizen-renderer.so diff --git a/src/meson.build b/src/meson.build index c1c88ac..a8df30b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -38,3 +38,4 @@ subdir('clipboard') subdir('launch') subdir('display_policy') subdir('memory_flusher') +subdir('renderer') diff --git a/src/renderer/meson.build b/src/renderer/meson.build new file mode 100644 index 0000000..fab95f3 --- /dev/null +++ b/src/renderer/meson.build @@ -0,0 +1,29 @@ +libds_tizen_renderer_files = [ + 'renderer.c', +] + +libds_tizen_renderer_deps = [ + deps_libds_tizen, + dependency('tizen-extension-server', required: true), +] + +lib_libds_tizen_renderer = shared_library('ds-tizen-renderer', libds_tizen_renderer_files, + dependencies: libds_tizen_renderer_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_renderer = declare_dependency( + link_with: lib_libds_tizen_renderer, + dependencies: libds_tizen_renderer_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_renderer, + version: meson.project_version(), + filebase: 'libds-tizen-renderer', + name: 'libds-tizen-renderer', + description: 'tizen renderer extension of libds-tizen for tizen platform', +) diff --git a/src/renderer/renderer.c b/src/renderer/renderer.c new file mode 100644 index 0000000..f1e0e84 --- /dev/null +++ b/src/renderer/renderer.c @@ -0,0 +1,334 @@ +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "libds-tizen/renderer.h" + +#define TIZEN_RENDERER_VERSION 1 + +struct ds_tizen_renderer +{ + struct wl_global *global; + + struct wl_list clients; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal get_renderer_surface; + } events; +}; + +struct ds_tizen_renderer_client +{ + struct ds_tizen_renderer *renderer; + + struct wl_resource *resource; + struct wl_client *wl_client; + + struct wl_list infos; + + struct { + struct wl_signal destroy; + } events; + + struct wl_list link; // ds_tizen_renderer::clients +}; + +struct ds_tizen_renderer_info +{ + struct ds_tizen_renderer_client *client; + + struct wl_resource *resource; + + struct ds_surface *surface; + + struct wl_list link; // ds_tizen_renderer_client::infos +}; + +static void renderer_handle_display_destroy(struct wl_listener *listener, + void *data); + +static void renderer_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id); + +static struct ds_tizen_renderer_info *tizen_renderer_client_find_info( + struct ds_tizen_renderer_client *client, + struct ds_surface *surface); + +static struct ds_tizen_renderer_info *tizen_renderer_client_get_info( + struct ds_tizen_renderer_client *client, + struct ds_surface *surface); + +WL_EXPORT struct ds_tizen_renderer * +ds_tizen_renderer_create(struct wl_display *display) +{ + struct ds_tizen_renderer *renderer; + + renderer = calloc(1, sizeof *renderer); + if (!renderer) { + ds_err("calloc() failed."); + return NULL; + } + + renderer->global = wl_global_create(display, &tizen_renderer_interface, + TIZEN_RENDERER_VERSION, renderer, renderer_bind); + if (!renderer->global) { + ds_err("wl_global_create() failed. tizen_renderer_interface"); + free(renderer); + return NULL; + } + + wl_list_init(&renderer->clients); + + renderer->destroy.notify = renderer_handle_display_destroy; + wl_display_add_destroy_listener(display, &renderer->destroy); + + wl_signal_init(&renderer->events.destroy); + wl_signal_init(&renderer->events.get_renderer_surface); + + ds_inf("Global created: tizen_renderer(%p)", renderer); + + return renderer; +} + +WL_EXPORT void +ds_tizen_renderer_add_destroy_listener( + struct ds_tizen_renderer *renderer, + struct wl_listener *listener) +{ + wl_signal_add(&renderer->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_renderer_add_get_renderer_surface_info_listener( + struct ds_tizen_renderer *renderer, + struct wl_listener *listener) +{ + wl_signal_add(&renderer->events.get_renderer_surface, listener); +} + +WL_EXPORT void +ds_tizen_renderer_info_add_destroy_listener( + struct ds_tizen_renderer_info *info, + struct wl_listener *listener) +{ + wl_signal_add(&info->client->events.destroy, listener); +} + +WL_EXPORT struct ds_surface * +ds_tizen_renderer_info_get_surface( + struct ds_tizen_renderer_info *info) +{ + return info->surface; +} + +WL_EXPORT void +ds_tizen_renderer_info_send_redraw( + struct ds_tizen_renderer_info *info) +{ + tizen_renderer_surface_send_redraw_request(info->resource); +} + +static struct ds_tizen_renderer_info * +tizen_renderer_client_find_info(struct ds_tizen_renderer_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_renderer_info *info; + + wl_list_for_each(info, &client->infos, link) { + if (surface == info->surface) + return info; + } + + return NULL; +} + +static struct ds_tizen_renderer_info * +tizen_renderer_client_get_info(struct ds_tizen_renderer_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_renderer_info *info; + + info = tizen_renderer_client_find_info(client, surface); + if (info) + return info; + + info = calloc(1, sizeof *info); + if (info == NULL) { + ds_err("calloc() failed. tizen_renderer"); + return NULL; + } + + info->client = client; + info->surface = surface; + + wl_list_insert(&client->infos, &info->link); + + return info; +} + +static void +renderer_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_renderer *renderer; + + renderer = wl_container_of(listener, renderer, destroy); + + ds_inf("Global destroy: renderer(%p)", renderer); + + wl_signal_emit(&renderer->events.destroy, renderer); + wl_list_remove(&renderer->destroy.link); + wl_global_destroy(renderer->global); + free(renderer); +} + +static void +renderer_surface_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_renderer_surface_interface renderer_surface_impl = +{ + renderer_surface_handle_destroy, +}; + +static void +_tizen_renderer_info_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_renderer_info *info; + + info = wl_resource_get_user_data(resource); + + ds_inf("_tizen_renderer_info_handle_destroy (info:%p)", info); + + wl_signal_emit(&info->client->events.destroy, info); + wl_list_remove(&info->link); + free(info); +} + +static void +renderer_handle_get_renderer_surface(struct wl_client *wl_client, + struct wl_resource *resource,uint32_t id, + struct wl_resource *surface_resource) +{ + struct ds_tizen_renderer_client *client; + struct ds_tizen_renderer_info *info; + struct ds_surface *surface; + + ds_inf("tizen_renderer: get_renderer_surface"); + + client = wl_resource_get_user_data(resource); + surface = ds_surface_from_resource(surface_resource); + + info = tizen_renderer_client_get_info(client, surface); + if (info == NULL) { + ds_err("tizen_renderer_client_get_info() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + info->resource = wl_resource_create(wl_client, + &tizen_renderer_surface_interface, wl_resource_get_version(resource), + id); + if (info->resource == NULL) { + ds_err("tizen_renderer : wl_resource_create() failed."); + wl_list_remove(&info->link); + free(info); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(info->resource, &renderer_surface_impl, info, + _tizen_renderer_info_handle_destroy); + + wl_signal_emit(&client->renderer->events.get_renderer_surface, info); +} + +static void +renderer_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + struct ds_tizen_renderer_client *client; + + client = wl_resource_get_user_data(resource); + + if (!wl_list_empty(&client->infos)) { + ds_err("tizen_renderer was destroyed before children"); + return; + } + + wl_resource_destroy(resource); +} + +static const struct tizen_renderer_interface renderer_impl = +{ + renderer_handle_get_renderer_surface, + renderer_handle_destroy, +}; + +static void +_tizen_renderer_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_renderer_client *client; + struct ds_tizen_renderer_info *info, *tmp; + + client = wl_resource_get_user_data(resource); + + ds_inf("_tizen_renderer_client_handle_destroy (client:%p)", client); + + wl_list_for_each_safe(info, tmp, &client->infos, link) { + wl_signal_emit(&client->events.destroy, info); + wl_list_remove(&info->link); + free(info); + } + + wl_list_remove(&client->link); + free(client); +} + +static void +renderer_bind(struct wl_client *wl_client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_renderer *renderer = data; + struct ds_tizen_renderer_client *client; + + client = calloc(1, sizeof *client); + if (client == NULL) { + ds_err("calloc() failed. tizen_renderer"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_renderer_client binds. (client:%p)", client); + + client->renderer = renderer; + client->wl_client = wl_client; + + wl_list_init(&client->infos); + + client->resource = wl_resource_create(wl_client, &tizen_renderer_interface, + MIN(version, TIZEN_RENDERER_VERSION), id); + + if (client->resource == NULL) { + ds_err("tizen_renderer : wl_resource_create() failed."); + free(client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(client->resource, &renderer_impl, client, + _tizen_renderer_client_handle_destroy); + + wl_signal_init(&client->events.destroy); + + wl_list_insert(&renderer->clients, &client->link); +} -- 2.7.4 From d889e114a4fa9a32af3c04550f3b123c27a37d1a Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 22 Jul 2022 11:15:18 +0900 Subject: [PATCH 02/16] add test cases for ds_tizen_renderer Change-Id: I4f669d3fcf727c7109f0b8a81d14a12c55d3edbe --- packaging/libds-tizen.spec | 1 + tests/meson.build | 21 +++ tests/tc_renderer.cpp | 382 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 404 insertions(+) create mode 100644 tests/tc_renderer.cpp diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 8eddf79..38942c7 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -416,3 +416,4 @@ ninja -C builddir install %{_includedir}/libds-tizen/renderer.h %{_libdir}/pkgconfig/libds-tizen-renderer.pc %{_libdir}/libds-tizen-renderer.so +%{_bindir}/libds-tizen-renderer-tests diff --git a/tests/meson.build b/tests/meson.build index 11af746..b375f18 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -125,3 +125,24 @@ executable('libds-tizen-memory-flusher-tests', install_dir: libds_tizen_bindir, install : true ) + +## renderer tests +tc_renderer_files = [ + 'tc_main.cpp', + 'tc_renderer.cpp', +] + +executable('libds-tizen-renderer-tests', + [ + tc_mock_files, + tc_renderer_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_renderer, + dependency('libdrm', required: true), + dependency('tizen-extension-client', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/tc_renderer.cpp b/tests/tc_renderer.cpp new file mode 100644 index 0000000..078f782 --- /dev/null +++ b/tests/tc_renderer.cpp @@ -0,0 +1,382 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include + +#define TIZEN_RENDERER_VERSION 1 + +class MockRendererCompositor : public MockCompositor +{ +public: + MockRendererCompositor() + : MockCompositor(&MockRendererCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bSurfaceDestroyed = false; + + bDestroyed = false; + bGetRendererSurface = false; + bDestroyRendererInfo = false; + } + + ~MockRendererCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockRendererCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + // new surface listener + mockComp->mNewSurfaceListener.notify = + MockRendererCompositor::NewSurfaceCallback; + mockComp->mNewSurfaceListener.parent = mockComp; + ds_compositor_add_new_surface_listener(comp->compositor, + &mockComp->mNewSurfaceListener); + + mockComp->mRenderer = + ds_tizen_renderer_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockRendererCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_renderer_add_destroy_listener(mockComp->mRenderer, + &mockComp->mDestroyListener); + + // get_flusher_info listener + mockComp->mGetFlusherInfoListener.notify = + MockRendererCompositor::GetRendererSurfaceCallback; + mockComp->mGetFlusherInfoListener.parent = mockComp; + ds_tizen_renderer_add_get_renderer_surface_info_listener( + mockComp->mRenderer, + &mockComp->mGetFlusherInfoListener); + } + + static void NewSurfaceCallback(struct wl_listener *listener, void *data) + { + MockRendererCompositor *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 = + MockRendererCompositor::DelSurfaceCallback; + mockComp->mDelSurfaceListener.parent = mockComp; + ds_surface_add_destroy_listener(surface, + &mockComp->mDelSurfaceListener); + } + + static void DelSurfaceCallback(struct wl_listener *listener, void *data) + { + MockRendererCompositor *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__); + + MockRendererCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void GetRendererSurfaceCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockRendererCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_renderer_info *info = + static_cast(data); + + ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info); + + mockComp->bGetRendererSurface = true; + + mockComp->mInfo = info; + mockComp->mSurface = + ds_tizen_renderer_info_get_surface(mockComp->mInfo); + + // info destroy listener + mockComp->mRendererInfoDestroyListener.notify = + MockRendererCompositor::RendererInfoDestroyCallback; + mockComp->mRendererInfoDestroyListener.parent = mockComp; + ds_tizen_renderer_info_add_destroy_listener(mockComp->mInfo, + &mockComp->mRendererInfoDestroyListener); + } + + static void RendererInfoDestroyCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockRendererCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_renderer_info *info = + static_cast(data); + + ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info); + + if (mockComp->mInfo == info) { + ds_inf("%s: info is deleted.", __func__); + mockComp->bDestroyRendererInfo = true; + } + } + + void SendRendererInfoRedraw() + { + ds_inf("%s", __func__); + + ds_tizen_renderer_info_send_redraw(mInfo); + } + +public: + bool bSurfaceDestroyed; + bool bDestroyed; + bool bGetRendererSurface; + bool bDestroyRendererInfo; + +private: + struct ds_tizen_renderer_info *mInfo; + struct ds_surface *mSurface; + + struct NewSurfaceListener : ::wl_listener { + MockRendererCompositor *parent; + }; + NewSurfaceListener mNewSurfaceListener; + + struct DelSurfaceListener : ::wl_listener { + MockRendererCompositor *parent; + }; + DelSurfaceListener mDelSurfaceListener; + + struct ds_tizen_renderer *mRenderer; + + struct DestroyListener : ::wl_listener { + MockRendererCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct GetFlusherInfoListener : ::wl_listener { + MockRendererCompositor *parent; + }; + GetFlusherInfoListener mGetFlusherInfoListener; + + struct FlusherInfoDestroyListener : ::wl_listener { + MockRendererCompositor *parent; + }; + FlusherInfoDestroyListener mRendererInfoDestroyListener; +}; + +class MockRendererClient : public MockClient +{ +public: + MockRendererClient() + : bRedrawEvent(false), + compositor_res(nullptr), + renderer_res(nullptr) + {} + MockRendererClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + + bRedrawEvent = false; + } + ~MockRendererClient() + { + 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 SetTizenRenderer(struct tizen_renderer *resource) + { + ds_inf("%s", __func__); + + renderer_res = resource; + } + + struct tizen_renderer *GetTizenRenderer() + { + ds_inf("%s", __func__); + + return renderer_res; + } + +public: + bool bRedrawEvent; + +private: + struct wl_compositor *compositor_res; + struct tizen_renderer *renderer_res; +}; + +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__); + + MockRendererClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct tizen_renderer *renderer_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_renderer")) { + renderer_res = (struct tizen_renderer *)wl_registry_bind(registry, + name, &tizen_renderer_interface, TIZEN_RENDERER_VERSION); + if (renderer_res == nullptr) { + ds_err("wl_registry_bind() failed. tizen_renderer resource."); + return; + } + client->SetTizenRenderer(renderer_res); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockRendererClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct tizen_renderer *renderer_res = client->GetTizenRenderer(); + + tizen_renderer_destroy(renderer_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 +client_tizen_renderer_surface_cb_redraw_request(void *data, + struct tizen_renderer_surface *renderer_surface_res) +{ + ds_inf("%s", __func__); + + MockRendererClient *client = static_cast(data); + + client->bRedrawEvent = true; +} + +static const struct +tizen_renderer_surface_listener renderer_surface_cb_listener = { + .redraw_request = client_tizen_renderer_surface_cb_redraw_request, +}; + +class RendererTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockRendererCompositor *comp; + MockRendererClient *client; + struct wl_compositor *compositor_res; + struct tizen_renderer *renderer_res; + struct wl_surface *surface_res; + struct tizen_renderer_surface *renderer_surface_res; +}; + +void +RendererTest::SetUp(void) +{ + //ds_log_init(DS_DBG, NULL); + + ds_inf("%s", __func__); + + comp = new MockRendererCompositor(); + client = new MockRendererClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + renderer_res = client->GetTizenRenderer(); + surface_res = wl_compositor_create_surface(compositor_res); + + renderer_surface_res = + tizen_renderer_get_renderer_surface(renderer_res, surface_res); + + tizen_renderer_surface_add_listener(renderer_surface_res, + &renderer_surface_cb_listener, client); + + client->RoundTrip(); +} + +void +RendererTest::TearDown(void) +{ + ds_inf("%s", __func__); + + tizen_renderer_surface_destroy(renderer_surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bDestroyRendererInfo); + + wl_surface_destroy(surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bSurfaceDestroyed); + + delete client; + delete comp; +} + +TEST_F(RendererTest, Create_P) +{ + EXPECT_TRUE(true); + EXPECT_TRUE(comp->bGetRendererSurface); +} + +TEST_F(RendererTest, Ev_TizenRendererSurfaceRedraw) +{ + comp->SendRendererInfoRedraw(); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->bRedrawEvent); +} -- 2.7.4 From dfdd1dbbce29af320bc2a29f43ff5e082189ad45 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Thu, 21 Jul 2022 17:19:58 +0900 Subject: [PATCH 03/16] impelement libds-tizen-screen-rotation This is the server implementation for tizen_screen_rotation protocol. Change-Id: I5c7a71543edf8e6e12c6616cfaef8e7dec43fc01 --- include/libds-tizen/screen_rotation.h | 45 ++++++ packaging/libds-tizen.spec | 29 ++++ src/meson.build | 1 + src/screen_rotation/meson.build | 29 ++++ src/screen_rotation/screen_rotation.c | 294 ++++++++++++++++++++++++++++++++++ 5 files changed, 398 insertions(+) create mode 100644 include/libds-tizen/screen_rotation.h create mode 100644 src/screen_rotation/meson.build create mode 100644 src/screen_rotation/screen_rotation.c diff --git a/include/libds-tizen/screen_rotation.h b/include/libds-tizen/screen_rotation.h new file mode 100644 index 0000000..ad19b15 --- /dev/null +++ b/include/libds-tizen/screen_rotation.h @@ -0,0 +1,45 @@ +#ifndef LIBDS_TIZEN_SCREEN_ROTATION_H +#define LIBDS_TIZEN_SCREEN_ROTATION_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_screen_rotation; +struct ds_tizen_screen_rotation_info; + +struct ds_tizen_screen_rotation * +ds_tizen_screen_rotation_create(struct wl_display *display); + +void +ds_tizen_screen_rotation_add_destroy_listener( + struct ds_tizen_screen_rotation *screen_rotation, + struct wl_listener *listener); + +void +ds_tizen_screen_rotation_add_get_ignore_output_transform_info_listener( + struct ds_tizen_screen_rotation *screen_rotation, + struct wl_listener *listener); + +void +ds_tizen_screen_rotation_info_add_destroy_listener( + struct ds_tizen_screen_rotation_info *info, + struct wl_listener *listener); + +struct ds_surface * +ds_tizen_screen_rotation_info_get_surface( + struct ds_tizen_screen_rotation_info *info); + +void +ds_tizen_screen_rotation_send_ignore_output_transform( + struct ds_tizen_screen_rotation_info *info, uint32_t ignore); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 38942c7..0dfbbd8 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -216,6 +216,21 @@ Group: Development/Libraries %description renderer-devel Development package for tizen renderer +## libds-tizen-screen-rotation +%package screen-rotation +Summary: Library for tizen screen rotation +Group: Development/Libraries + +%description screen-rotation +Library for tizen screen rotation + +%package screen-rotation-devel +Summary: Development package for tizen screen rotation +Group: Development/Libraries + +%description screen-rotation-devel +Development package for tizen screen rotation + %prep %setup -q cp %{SOURCE1001} . @@ -417,3 +432,17 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-renderer.pc %{_libdir}/libds-tizen-renderer.so %{_bindir}/libds-tizen-renderer-tests + +%files screen-rotation +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-screen-rotation.so.* + +%files screen-rotation-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/screen_rotation.h +%{_libdir}/pkgconfig/libds-tizen-screen-rotation.pc +%{_libdir}/libds-tizen-screen-rotation.so diff --git a/src/meson.build b/src/meson.build index a8df30b..4fee86e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -39,3 +39,4 @@ subdir('launch') subdir('display_policy') subdir('memory_flusher') subdir('renderer') +subdir('screen_rotation') diff --git a/src/screen_rotation/meson.build b/src/screen_rotation/meson.build new file mode 100644 index 0000000..4261a97 --- /dev/null +++ b/src/screen_rotation/meson.build @@ -0,0 +1,29 @@ +libds_tizen_screen_rotation_files = [ + 'screen_rotation.c', +] + +libds_tizen_screen_rotation_deps = [ + deps_libds_tizen, + dependency('tizen-extension-server', required: true), +] + +lib_libds_tizen_screen_rotation = shared_library('ds-tizen-screen-rotation', libds_tizen_screen_rotation_files, + dependencies: libds_tizen_screen_rotation_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_screen_rotation = declare_dependency( + link_with: lib_libds_tizen_screen_rotation, + dependencies: libds_tizen_screen_rotation_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_screen_rotation, + version: meson.project_version(), + filebase: 'libds-tizen-screen-rotation', + name: 'libds-tizen-screen-rotation', + description: 'tizen screen_rotation extension of libds-tizen for tizen platform', +) diff --git a/src/screen_rotation/screen_rotation.c b/src/screen_rotation/screen_rotation.c new file mode 100644 index 0000000..e4ddb6b --- /dev/null +++ b/src/screen_rotation/screen_rotation.c @@ -0,0 +1,294 @@ +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "libds-tizen/screen_rotation.h" + +#define TIZEN_SCREEN_ROTATION_VERSION 1 + +struct ds_tizen_screen_rotation +{ + struct wl_global *global; + + struct wl_list clients; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal get_ignore_output_transfrom; + } events; +}; + +struct ds_tizen_screen_rotation_client +{ + struct ds_tizen_screen_rotation *screen_rotation; + + struct wl_resource *resource; + struct wl_client *wl_client; + + struct wl_list infos; + + struct { + struct wl_signal destroy; + } events; + + struct wl_list link; // ds_tizen_screen_rotation::clients +}; + +struct ds_tizen_screen_rotation_info +{ + struct ds_tizen_screen_rotation_client *client; + + struct ds_surface *surface; + + struct wl_list link; // ds_tizen_screen_rotation_client::infos +}; + +static void screen_rotation_handle_display_destroy(struct wl_listener *listener, + void *data); + +static void screen_rotation_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id); + +static struct ds_tizen_screen_rotation_info *tizen_screen_rotation_client_find_info( + struct ds_tizen_screen_rotation_client *client, + struct ds_surface *surface); + +static struct ds_tizen_screen_rotation_info *tizen_screen_rotation_client_get_info( + struct ds_tizen_screen_rotation_client *client, + struct ds_surface *surface); + +WL_EXPORT struct ds_tizen_screen_rotation * +ds_tizen_screen_rotation_create(struct wl_display *display) +{ + struct ds_tizen_screen_rotation *screen_rotation; + + screen_rotation = calloc(1, sizeof *screen_rotation); + if (!screen_rotation) { + ds_err("calloc() failed."); + return NULL; + } + + screen_rotation->global = wl_global_create(display, + &tizen_screen_rotation_interface, TIZEN_SCREEN_ROTATION_VERSION, + screen_rotation, screen_rotation_bind); + if (!screen_rotation->global) { + ds_err("wl_global_create() failed. tizen_screen_rotation_interface"); + free(screen_rotation); + return NULL; + } + + wl_list_init(&screen_rotation->clients); + + screen_rotation->destroy.notify = screen_rotation_handle_display_destroy; + wl_display_add_destroy_listener(display, &screen_rotation->destroy); + + wl_signal_init(&screen_rotation->events.destroy); + wl_signal_init(&screen_rotation->events.get_ignore_output_transfrom); + + ds_inf("Global created: tizen_screen_rotation(%p)", screen_rotation); + + return screen_rotation; +} + +WL_EXPORT void +ds_tizen_screen_rotation_add_destroy_listener( + struct ds_tizen_screen_rotation *screen_rotation, + struct wl_listener *listener) +{ + wl_signal_add(&screen_rotation->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_screen_rotation_add_get_ignore_output_transform_info_listener( + struct ds_tizen_screen_rotation *screen_rotation, + struct wl_listener *listener) +{ + wl_signal_add(&screen_rotation->events.get_ignore_output_transfrom, + listener); +} + +WL_EXPORT void +ds_tizen_screen_rotation_info_add_destroy_listener( + struct ds_tizen_screen_rotation_info *info, + struct wl_listener *listener) +{ + wl_signal_add(&info->client->events.destroy, listener); +} + +WL_EXPORT struct ds_surface * +ds_tizen_screen_rotation_info_get_surface( + struct ds_tizen_screen_rotation_info *info) +{ + return info->surface; +} + +WL_EXPORT void +ds_tizen_screen_rotation_send_ignore_output_transform( + struct ds_tizen_screen_rotation_info *info, uint32_t ignore) +{ + tizen_screen_rotation_send_ignore_output_transform(info->client->resource, + ds_surface_get_wl_resource(info->surface), ignore); +} + +static struct ds_tizen_screen_rotation_info * +tizen_screen_rotation_client_find_info(struct ds_tizen_screen_rotation_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_screen_rotation_info *info; + + wl_list_for_each(info, &client->infos, link) { + if (surface == info->surface) + return info; + } + + return NULL; +} + +static struct ds_tizen_screen_rotation_info * +tizen_screen_rotation_client_get_info(struct ds_tizen_screen_rotation_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_screen_rotation_info *info; + + info = tizen_screen_rotation_client_find_info(client, surface); + if (info) + return info; + + info = calloc(1, sizeof *info); + if (info == NULL) { + ds_err("calloc() failed. tizen_screen_rotation"); + return NULL; + } + + info->client = client; + info->surface = surface; + + wl_list_insert(&client->infos, &info->link); + + return info; +} + +static void +screen_rotation_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_screen_rotation *screen_rotation; + + screen_rotation = wl_container_of(listener, screen_rotation, destroy); + + ds_inf("Global destroy: screen_rotation(%p)", screen_rotation); + + wl_signal_emit(&screen_rotation->events.destroy, screen_rotation); + wl_list_remove(&screen_rotation->destroy.link); + wl_global_destroy(screen_rotation->global); + free(screen_rotation); +} + +static void +screen_rotation_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + struct ds_tizen_screen_rotation_client *client; + + client = wl_resource_get_user_data(resource); + + if (!wl_list_empty(&client->infos)) { + ds_err("tizen_screen_rotation was destroyed before children"); + return; + } + + wl_resource_destroy(resource); +} + +static void +screen_rotation_handle_get_ignore_output_transfrom(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_screen_rotation_client *client; + struct ds_tizen_screen_rotation_info *info; + struct ds_surface *surface; + + ds_inf("tizen_screen_rotation: get_ignore_output_transfrom"); + + client = wl_resource_get_user_data(resource); + surface = ds_surface_from_resource(surface_resource); + + info = tizen_screen_rotation_client_get_info(client, surface); + if (info == NULL) { + ds_err("tizen_screen_rotation_client_get_info() failed. tizen_screen_rotation"); + wl_client_post_no_memory(wl_client); + return; + } + + wl_signal_emit(&client->screen_rotation->events.get_ignore_output_transfrom, info); +} + +static const struct tizen_screen_rotation_interface screen_rotation_impl = +{ + screen_rotation_handle_get_ignore_output_transfrom, + screen_rotation_handle_destroy, +}; + +static void +_tizen_screen_rotation_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_screen_rotation_client *client; + struct ds_tizen_screen_rotation_info *info, *tmp; + + client = wl_resource_get_user_data(resource); + + ds_inf("_tizen_screen_rotation_client_handle_destroy (client:%p)", client); + + wl_list_for_each_safe(info, tmp, &client->infos, link) { + wl_signal_emit(&client->events.destroy, info); + wl_list_remove(&info->link); + free(info); + } + + wl_list_remove(&client->link); + free(client); +} + +static void +screen_rotation_bind(struct wl_client *wl_client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_screen_rotation *screen_rotation = data; + struct ds_tizen_screen_rotation_client *client; + + client = calloc(1, sizeof *client); + if (client == NULL) { + ds_err("calloc() failed. tizen_screen_rotation"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_screen_rotation_client binds. (client:%p)", client); + + client->screen_rotation = screen_rotation; + client->wl_client = wl_client; + + wl_list_init(&client->infos); + + client->resource = wl_resource_create(wl_client, &tizen_screen_rotation_interface, + MIN(version, TIZEN_SCREEN_ROTATION_VERSION), id); + + if (client->resource == NULL) { + ds_err("tizen_screen_rotation : wl_resource_create() failed."); + free(client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(client->resource, &screen_rotation_impl, client, + _tizen_screen_rotation_client_handle_destroy); + + wl_signal_init(&client->events.destroy); + + wl_list_insert(&screen_rotation->clients, &client->link); +} -- 2.7.4 From 6d2b24bba1dc3a3f595825e1068f75ff129dd749 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 22 Jul 2022 14:31:13 +0900 Subject: [PATCH 04/16] add test cases for ds_tizen_screen_rotation Change-Id: I35a3d6f5519d7c4f0f93d66bd71788415e8a83ef --- packaging/libds-tizen.spec | 1 + tests/meson.build | 21 +++ tests/tc_screen_rotation.cpp | 390 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 412 insertions(+) create mode 100644 tests/tc_screen_rotation.cpp diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 0dfbbd8..70f06e5 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -446,3 +446,4 @@ ninja -C builddir install %{_includedir}/libds-tizen/screen_rotation.h %{_libdir}/pkgconfig/libds-tizen-screen-rotation.pc %{_libdir}/libds-tizen-screen-rotation.so +%{_bindir}/libds-tizen-screen-rotation-tests diff --git a/tests/meson.build b/tests/meson.build index b375f18..43b227e 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -146,3 +146,24 @@ executable('libds-tizen-renderer-tests', install_dir: libds_tizen_bindir, install : true ) + +## screen-rotation tests +tc_screen_rotation_files = [ + 'tc_main.cpp', + 'tc_screen_rotation.cpp', +] + +executable('libds-tizen-screen-rotation-tests', + [ + tc_mock_files, + tc_screen_rotation_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_screen_rotation, + dependency('libdrm', required: true), + dependency('tizen-extension-client', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/tc_screen_rotation.cpp b/tests/tc_screen_rotation.cpp new file mode 100644 index 0000000..cb257fa --- /dev/null +++ b/tests/tc_screen_rotation.cpp @@ -0,0 +1,390 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include + +#define TIZEN_SCREEN_ROTATION_VERSION 1 + +class MockScreenRotationCompositor : public MockCompositor +{ +public: + MockScreenRotationCompositor() + : MockCompositor(&MockScreenRotationCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bSurfaceDestroyed = false; + + bDestroyed = false; + bGetIgnoreOutputTransform = false; + bDestroyScreenRotationInfo = false; + } + + ~MockScreenRotationCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockScreenRotationCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + // new surface listener + mockComp->mNewSurfaceListener.notify = + MockScreenRotationCompositor::NewSurfaceCallback; + mockComp->mNewSurfaceListener.parent = mockComp; + ds_compositor_add_new_surface_listener(comp->compositor, + &mockComp->mNewSurfaceListener); + + mockComp->mScreenRotation = + ds_tizen_screen_rotation_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockScreenRotationCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_screen_rotation_add_destroy_listener(mockComp->mScreenRotation, + &mockComp->mDestroyListener); + + // add_ignore_output_transform listener + mockComp->mGetIgnoreOutputTransformListener.notify = + MockScreenRotationCompositor::GetIgnoreOutputTransformCallback; + mockComp->mGetIgnoreOutputTransformListener.parent = mockComp; + ds_tizen_screen_rotation_add_get_ignore_output_transform_info_listener( + mockComp->mScreenRotation, + &mockComp->mGetIgnoreOutputTransformListener); + } + + static void NewSurfaceCallback(struct wl_listener *listener, void *data) + { + MockScreenRotationCompositor *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 = + MockScreenRotationCompositor::DelSurfaceCallback; + mockComp->mDelSurfaceListener.parent = mockComp; + ds_surface_add_destroy_listener(surface, + &mockComp->mDelSurfaceListener); + } + + static void DelSurfaceCallback(struct wl_listener *listener, void *data) + { + MockScreenRotationCompositor *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__); + + MockScreenRotationCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void GetIgnoreOutputTransformCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenRotationCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_screen_rotation_info *info = + static_cast(data); + + ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info); + + mockComp->bGetIgnoreOutputTransform = true; + + mockComp->mInfo = info; + mockComp->mSurface = + ds_tizen_screen_rotation_info_get_surface(mockComp->mInfo); + + // info destroy listener + mockComp->mScreenRotationInfoDestroyListener.notify = + MockScreenRotationCompositor::ScreenRotationInfoDestroyCallback; + mockComp->mScreenRotationInfoDestroyListener.parent = mockComp; + ds_tizen_screen_rotation_info_add_destroy_listener(mockComp->mInfo, + &mockComp->mScreenRotationInfoDestroyListener); + } + + static void ScreenRotationInfoDestroyCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenRotationCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_screen_rotation_info *info = + static_cast(data); + + ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info); + + if (mockComp->mInfo == info) { + ds_inf("%s: info is deleted.", __func__); + mockComp->bDestroyScreenRotationInfo = true; + } + } + + void SendIgnoreOutputTransform(uint32_t ignore) + { + ds_inf("%s", __func__); + + ds_tizen_screen_rotation_send_ignore_output_transform(mInfo, ignore); + } + +public: + bool bSurfaceDestroyed; + bool bDestroyed; + bool bGetIgnoreOutputTransform; + bool bDestroyScreenRotationInfo; + +private: + struct ds_tizen_screen_rotation_info *mInfo; + struct ds_surface *mSurface; + + struct NewSurfaceListener : ::wl_listener { + MockScreenRotationCompositor *parent; + }; + NewSurfaceListener mNewSurfaceListener; + + struct DelSurfaceListener : ::wl_listener { + MockScreenRotationCompositor *parent; + }; + DelSurfaceListener mDelSurfaceListener; + + struct ds_tizen_screen_rotation *mScreenRotation; + + struct DestroyListener : ::wl_listener { + MockScreenRotationCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct GetIgnoreOutputTransformListener : ::wl_listener { + MockScreenRotationCompositor *parent; + }; + GetIgnoreOutputTransformListener mGetIgnoreOutputTransformListener; + + struct ScreenRotationInfoDestroyListener : ::wl_listener { + MockScreenRotationCompositor *parent; + }; + ScreenRotationInfoDestroyListener mScreenRotationInfoDestroyListener; +}; + +class MockScreenRotationClient : public MockClient +{ +public: + MockScreenRotationClient() + : bIgnoreOutputTransformEvent(false), + mIgnore(0), + compositor_res(nullptr), + screen_rotation_res(nullptr) + {} + MockScreenRotationClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + + bIgnoreOutputTransformEvent = false; + mIgnore = 0; + } + ~MockScreenRotationClient() + { + 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 SetTizenScreenRotation(struct tizen_screen_rotation *resource) + { + ds_inf("%s", __func__); + + screen_rotation_res = resource; + } + + struct tizen_screen_rotation *GetTizenScreenRotation() + { + ds_inf("%s", __func__); + + return screen_rotation_res; + } + +public: + bool bIgnoreOutputTransformEvent; + uint32_t mIgnore; + +private: + struct wl_compositor *compositor_res; + struct tizen_screen_rotation *screen_rotation_res; +}; + +static void +client_tizen_screen_rotation_cb_ignore_output_transform(void *data, + struct tizen_screen_rotation *screen_rotation_res, + struct wl_surface *surface_resource, uint32_t ignore) +{ + ds_inf("%s", __func__); + + MockScreenRotationClient *client = static_cast(data); + + client->bIgnoreOutputTransformEvent = true; + client->mIgnore = ignore; +} + +static const struct +tizen_screen_rotation_listener screen_rotation_cb_listener = { + .ignore_output_transform = client_tizen_screen_rotation_cb_ignore_output_transform, +}; + +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__); + + MockScreenRotationClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct tizen_screen_rotation *screen_rotation_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_screen_rotation")) { + screen_rotation_res = (struct tizen_screen_rotation *)wl_registry_bind(registry, + name, &tizen_screen_rotation_interface, TIZEN_SCREEN_ROTATION_VERSION); + if (screen_rotation_res == nullptr) { + ds_err("wl_registry_bind() failed. tizen_screen_rotation resource."); + return; + } + client->SetTizenScreenRotation(screen_rotation_res); + + tizen_screen_rotation_add_listener(screen_rotation_res, + &screen_rotation_cb_listener, client); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockScreenRotationClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct tizen_screen_rotation *screen_rotation_res = client->GetTizenScreenRotation(); + + tizen_screen_rotation_destroy(screen_rotation_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 ScreenRotationTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockScreenRotationCompositor *comp; + MockScreenRotationClient *client; + struct wl_compositor *compositor_res; + struct tizen_screen_rotation *screen_rotation_res; + struct wl_surface *surface_res; +}; + +void +ScreenRotationTest::SetUp(void) +{ + //ds_log_init(DS_DBG, NULL); + + ds_inf("%s", __func__); + + comp = new MockScreenRotationCompositor(); + client = new MockScreenRotationClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + screen_rotation_res = client->GetTizenScreenRotation(); + surface_res = wl_compositor_create_surface(compositor_res); + + client->RoundTrip(); +} + +void +ScreenRotationTest::TearDown(void) +{ + ds_inf("%s", __func__); + + wl_surface_destroy(surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bSurfaceDestroyed); + + delete client; + delete comp; +} + +TEST_F(ScreenRotationTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(ScreenRotationTest, Req_TizenScreenRotationGetIgnoreOutputTransform) +{ + tizen_screen_rotation_get_ignore_output_transform(screen_rotation_res, surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bGetIgnoreOutputTransform); +} + +TEST_F(ScreenRotationTest, Ev_TizenScreenRotationSurfaceRedraw) +{ + tizen_screen_rotation_get_ignore_output_transform(screen_rotation_res, surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bGetIgnoreOutputTransform); + + comp->SendIgnoreOutputTransform(1); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->bIgnoreOutputTransformEvent); + EXPECT_TRUE(client->mIgnore == 1); +} -- 2.7.4 From c1236f2b41a263b068b7ab5030da69d0385f1423 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Thu, 21 Jul 2022 20:54:26 +0900 Subject: [PATCH 05/16] impelement libds-tizen-global-resource This is the server implementation for tizen_surface protocol. Change-Id: I40e97d4fedabe68e364ff9c9a95791311646216a --- include/libds-tizen/global_resource.h | 45 +++++ packaging/libds-tizen.spec | 29 +++ src/global_resource/global_resource.c | 345 ++++++++++++++++++++++++++++++++++ src/global_resource/meson.build | 30 +++ src/meson.build | 1 + 5 files changed, 450 insertions(+) create mode 100644 include/libds-tizen/global_resource.h create mode 100644 src/global_resource/global_resource.c create mode 100644 src/global_resource/meson.build diff --git a/include/libds-tizen/global_resource.h b/include/libds-tizen/global_resource.h new file mode 100644 index 0000000..82612cd --- /dev/null +++ b/include/libds-tizen/global_resource.h @@ -0,0 +1,45 @@ +#ifndef LIBDS_TIZEN_GLOBAL_RESOURCE_H +#define LIBDS_TIZEN_GLOBAL_RESOURCE_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_global_resource; +struct ds_tizen_global_resource_info; + +struct ds_tizen_global_resource * +ds_tizen_global_resource_create(struct wl_display *display); + +void +ds_tizen_global_resource_add_destroy_listener( + struct ds_tizen_global_resource *global_resource, + struct wl_listener *listener); + +void +ds_tizen_global_resource_add_get_resource_info_listener( + struct ds_tizen_global_resource *global_resource, + struct wl_listener *listener); + +void +ds_tizen_global_resource_info_add_destroy_listener( + struct ds_tizen_global_resource_info *info, + struct wl_listener *listener); + +struct ds_surface * +ds_tizen_global_resource_info_get_surface( + struct ds_tizen_global_resource_info *info); + +uint32_t +ds_tizen_global_resource_get_universal_id( + struct ds_tizen_global_resource_info *info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 70f06e5..abfe00c 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -231,6 +231,21 @@ Group: Development/Libraries %description screen-rotation-devel Development package for tizen screen rotation +## libds-tizen-global-resource +%package global-resource +Summary: Library for tizen global resource +Group: Development/Libraries + +%description global-resource +Library for tizen global resource + +%package global-resource-devel +Summary: Development package for tizen global resource +Group: Development/Libraries + +%description global-resource-devel +Development package for tizen global resource + %prep %setup -q cp %{SOURCE1001} . @@ -447,3 +462,17 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-screen-rotation.pc %{_libdir}/libds-tizen-screen-rotation.so %{_bindir}/libds-tizen-screen-rotation-tests + +%files global-resource +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-global-resource.so.* + +%files global-resource-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/global_resource.h +%{_libdir}/pkgconfig/libds-tizen-global-resource.pc +%{_libdir}/libds-tizen-global-resource.so diff --git a/src/global_resource/global_resource.c b/src/global_resource/global_resource.c new file mode 100644 index 0000000..3c15f23 --- /dev/null +++ b/src/global_resource/global_resource.c @@ -0,0 +1,345 @@ +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "libds-tizen/global_resource.h" + +#define TIZEN_SURFACE_VERSION 1 + +static uint32_t unique_id = 0; + +struct ds_tizen_global_resource +{ + struct wl_global *global; + + struct wl_list clients; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal get_resource_info; + } events; +}; + +struct ds_tizen_global_resource_client +{ + struct ds_tizen_global_resource *global_resource; + + struct wl_resource *resource; + struct wl_client *wl_client; + + struct wl_list infos; + + struct { + struct wl_signal destroy; + } events; + + struct wl_list link; // ds_tizen_global_resource::clients +}; + +struct ds_tizen_global_resource_info +{ + struct ds_tizen_global_resource_client *client; + + struct wl_resource *resource; + + struct ds_surface *surface; + + uint32_t universal_id; + + struct wl_list link; // ds_tizen_global_resource_client::infos +}; + +static void resource_handle_display_destroy(struct wl_listener *listener, + void *data); + +static void resource_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id); + +static struct ds_tizen_global_resource_info *tizen_global_resource_client_find_info( + struct ds_tizen_global_resource_client *client, + struct ds_surface *surface); + +static struct ds_tizen_global_resource_info *tizen_global_resource_client_get_info( + struct ds_tizen_global_resource_client *client, + struct ds_surface *surface); + +WL_EXPORT struct ds_tizen_global_resource * +ds_tizen_global_resource_create(struct wl_display *display) +{ + struct ds_tizen_global_resource *global_resource; + + global_resource = calloc(1, sizeof *global_resource); + if (!global_resource) { + ds_err("calloc() failed."); + return NULL; + } + + global_resource->global = wl_global_create(display, &tizen_surface_interface, + TIZEN_SURFACE_VERSION, global_resource, resource_bind); + if (!global_resource->global) { + ds_err("wl_global_create() failed. tizen_resource_interface"); + free(global_resource); + return NULL; + } + + wl_list_init(&global_resource->clients); + + global_resource->destroy.notify = resource_handle_display_destroy; + wl_display_add_destroy_listener(display, &global_resource->destroy); + + wl_signal_init(&global_resource->events.destroy); + wl_signal_init(&global_resource->events.get_resource_info); + + ds_inf("Global created: tizen_global_resource(%p)", global_resource); + + return global_resource; +} + +WL_EXPORT void +ds_tizen_global_resource_add_destroy_listener( + struct ds_tizen_global_resource *global_resource, + struct wl_listener *listener) +{ + wl_signal_add(&global_resource->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_global_resource_add_get_resource_info_listener( + struct ds_tizen_global_resource *global_resource, + struct wl_listener *listener) +{ + wl_signal_add(&global_resource->events.get_resource_info, listener); +} + +WL_EXPORT void +ds_tizen_global_resource_info_add_destroy_listener( + struct ds_tizen_global_resource_info *info, + struct wl_listener *listener) +{ + wl_signal_add(&info->client->events.destroy, listener); +} + +WL_EXPORT struct ds_surface * +ds_tizen_global_resource_info_get_surface( + struct ds_tizen_global_resource_info *info) +{ + return info->surface; +} + +WL_EXPORT uint32_t +ds_tizen_global_resource_get_universal_id( + struct ds_tizen_global_resource_info *info) +{ + return info->universal_id; +} + +static struct ds_tizen_global_resource_info * +tizen_global_resource_client_find_info( + struct ds_tizen_global_resource_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_global_resource_info *info; + + wl_list_for_each(info, &client->infos, link) { + if (surface == info->surface) + return info; + } + + return NULL; +} + +static struct ds_tizen_global_resource_info * +tizen_global_resource_client_get_info( + struct ds_tizen_global_resource_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_global_resource_info *info; + + info = tizen_global_resource_client_find_info(client, surface); + if (info) + return info; + + info = calloc(1, sizeof *info); + if (info == NULL) { + ds_err("calloc() failed. tizen_global_resource"); + return NULL; + } + + info->client = client; + info->surface = surface; + + wl_list_insert(&client->infos, &info->link); + + return info; +} + +static void +resource_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_global_resource *global_resource; + + global_resource = wl_container_of(listener, global_resource, destroy); + + ds_inf("Global destroy: resource(%p)", global_resource); + + wl_signal_emit(&global_resource->events.destroy, global_resource); + wl_list_remove(&global_resource->destroy.link); + wl_global_destroy(global_resource->global); + free(global_resource); +} + +static void +resource_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_resource_interface resource_impl = +{ + resource_handle_destroy, +}; + +static void +_tizen_surface_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_global_resource_info *info; + + info = wl_resource_get_user_data(resource); + + ds_inf("_tizen_surface_handle_destroy (info:%p)", info); + + wl_signal_emit(&info->client->events.destroy, info); + wl_list_remove(&info->link); + free(info); +} + +static void +surface_handle_get_tizen_global_resource(struct wl_client *wl_client, + struct wl_resource *resource,uint32_t id, + struct wl_resource *surface_resource) +{ + struct ds_tizen_global_resource_client *client; + struct ds_tizen_global_resource_info *info; + struct ds_surface *surface; + + ds_inf("tizen_global_resource: surface_handle_get_tizen_global_resource"); + + client = wl_resource_get_user_data(resource); + surface = ds_surface_from_resource(surface_resource); + + info = tizen_global_resource_client_get_info(client, surface); + if (info == NULL) { + ds_err("tizen_global_resource_client_get_info() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + info->resource = wl_resource_create(wl_client, + &tizen_resource_interface, wl_resource_get_version(resource), + id); + if (info->resource == NULL) { + ds_err("tizen_global_resource : wl_resource_create() failed."); + wl_list_remove(&info->link); + free(info); + wl_client_post_no_memory(wl_client); + return; + } + + // generate the univeral_id; + info->universal_id = unique_id++; + + wl_resource_set_implementation(info->resource, &resource_impl, info, + _tizen_surface_handle_destroy); + + wl_signal_emit(&client->global_resource->events.get_resource_info, info); + + tizen_resource_send_resource_id(info->resource, info->universal_id); +} + +static void +surface_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + struct ds_tizen_global_resource_client *client; + + client = wl_resource_get_user_data(resource); + + if (!wl_list_empty(&client->infos)) { + ds_err("tizen_global_resource was destroyed before children"); + return; + } + + wl_resource_destroy(resource); +} + +static const struct tizen_surface_interface surface_impl = +{ + surface_handle_get_tizen_global_resource, + surface_handle_destroy, +}; + +static void +_tizen_global_resource_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_global_resource_client *client; + struct ds_tizen_global_resource_info *info, *tmp; + + client = wl_resource_get_user_data(resource); + + ds_inf("_tizen_global_resource_client_handle_destroy (client:%p)", client); + + wl_list_for_each_safe(info, tmp, &client->infos, link) { + wl_signal_emit(&info->client->events.destroy, info); + wl_list_remove(&info->link); + free(info); + } + + wl_list_remove(&client->link); + free(client); +} + +static void +resource_bind(struct wl_client *wl_client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_global_resource *global_resource = data; + struct ds_tizen_global_resource_client *client; + + client = calloc(1, sizeof *client); + if (client == NULL) { + ds_err("calloc() failed. tizen_global_resource"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_global_resource_client binds. (client:%p)", client); + + client->global_resource = global_resource; + client->wl_client = wl_client; + + wl_list_init(&client->infos); + + client->resource = wl_resource_create(wl_client, &tizen_surface_interface, + MIN(version, TIZEN_SURFACE_VERSION), id); + + if (client->resource == NULL) { + ds_err("tizen_global_resource : wl_resource_create() failed."); + free(client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(client->resource, &surface_impl, client, + _tizen_global_resource_client_handle_destroy); + + wl_signal_init(&client->events.destroy); + + wl_list_insert(&global_resource->clients, &client->link); +} diff --git a/src/global_resource/meson.build b/src/global_resource/meson.build new file mode 100644 index 0000000..13d5d7a --- /dev/null +++ b/src/global_resource/meson.build @@ -0,0 +1,30 @@ +libds_tizen_global_resource_files = [ + 'global_resource.c', +] + +libds_tizen_global_resource_deps = [ + deps_libds_tizen, + dependency('tizen-extension-server', required: true), +] + +lib_libds_tizen_global_resource = shared_library('ds-tizen-global-resource', + libds_tizen_global_resource_files, + dependencies: libds_tizen_global_resource_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_global_resource = declare_dependency( + link_with: lib_libds_tizen_global_resource, + dependencies: libds_tizen_global_resource_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_global_resource, + version: meson.project_version(), + filebase: 'libds-tizen-global-resource', + name: 'libds-tizen-global-resource', + description: 'tizen resource extension of libds-tizen for tizen platform', +) diff --git a/src/meson.build b/src/meson.build index 4fee86e..66f10c6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -40,3 +40,4 @@ subdir('display_policy') subdir('memory_flusher') subdir('renderer') subdir('screen_rotation') +subdir('global_resource') -- 2.7.4 From 63c321527adedb6076865bc83b2588ffcadee43b Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 22 Jul 2022 15:24:01 +0900 Subject: [PATCH 06/16] add test cases for ds_tizen_global_resource Change-Id: I5ee07c9a598c6470f5703aef3d71a1cd564cd7a2 --- packaging/libds-tizen.spec | 1 + tests/meson.build | 21 +++ tests/tc_global_resource.cpp | 371 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 393 insertions(+) create mode 100644 tests/tc_global_resource.cpp diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index abfe00c..4165443 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -476,3 +476,4 @@ ninja -C builddir install %{_includedir}/libds-tizen/global_resource.h %{_libdir}/pkgconfig/libds-tizen-global-resource.pc %{_libdir}/libds-tizen-global-resource.so +%{_bindir}/libds-tizen-global-resource-tests diff --git a/tests/meson.build b/tests/meson.build index 43b227e..40e737e 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -167,3 +167,24 @@ executable('libds-tizen-screen-rotation-tests', install_dir: libds_tizen_bindir, install : true ) + +## global-resource tests +tc_global_resource_files = [ + 'tc_main.cpp', + 'tc_global_resource.cpp', +] + +executable('libds-tizen-global-resource-tests', + [ + tc_mock_files, + tc_global_resource_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_global_resource, + dependency('libdrm', required: true), + dependency('tizen-extension-client', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/tc_global_resource.cpp b/tests/tc_global_resource.cpp new file mode 100644 index 0000000..fbf5a4e --- /dev/null +++ b/tests/tc_global_resource.cpp @@ -0,0 +1,371 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include + +#define TIZEN_SURFACE_VERSION 1 + +class MockGlobalResourceCompositor : public MockCompositor +{ +public: + MockGlobalResourceCompositor() + : MockCompositor(&MockGlobalResourceCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bSurfaceDestroyed = false; + + bDestroyed = false; + bGetResourceInfo = false; + bDestroyResourceInfo = false; + mResourceId = 0; + } + + ~MockGlobalResourceCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockGlobalResourceCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + // new surface listener + mockComp->mNewSurfaceListener.notify = + MockGlobalResourceCompositor::NewSurfaceCallback; + mockComp->mNewSurfaceListener.parent = mockComp; + ds_compositor_add_new_surface_listener(comp->compositor, + &mockComp->mNewSurfaceListener); + + mockComp->mGlobalResource = + ds_tizen_global_resource_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockGlobalResourceCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_global_resource_add_destroy_listener(mockComp->mGlobalResource, + &mockComp->mDestroyListener); + + // get_resource_info listener + mockComp->mGetResourceInfoListener.notify = + MockGlobalResourceCompositor::GetResourceInfoCallback; + mockComp->mGetResourceInfoListener.parent = mockComp; + ds_tizen_global_resource_add_get_resource_info_listener( + mockComp->mGlobalResource, + &mockComp->mGetResourceInfoListener); + } + + static void NewSurfaceCallback(struct wl_listener *listener, void *data) + { + MockGlobalResourceCompositor *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 = + MockGlobalResourceCompositor::DelSurfaceCallback; + mockComp->mDelSurfaceListener.parent = mockComp; + ds_surface_add_destroy_listener(surface, + &mockComp->mDelSurfaceListener); + } + + static void DelSurfaceCallback(struct wl_listener *listener, void *data) + { + MockGlobalResourceCompositor *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__); + + MockGlobalResourceCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void GetResourceInfoCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockGlobalResourceCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_global_resource_info *info = + static_cast(data); + + ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info); + + mockComp->bGetResourceInfo = true; + + mockComp->mInfo = info; + mockComp->mSurface = + ds_tizen_global_resource_info_get_surface(mockComp->mInfo); + + mockComp->mResourceId = ds_tizen_global_resource_get_universal_id(mockComp->mInfo); + + // info destroy listener + mockComp->mGobalResourceInfoDestroyListener.notify = + MockGlobalResourceCompositor::GobalResourceInfoDestroyCallback; + mockComp->mGobalResourceInfoDestroyListener.parent = mockComp; + ds_tizen_global_resource_info_add_destroy_listener(mockComp->mInfo, + &mockComp->mGobalResourceInfoDestroyListener); + } + + static void GobalResourceInfoDestroyCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockGlobalResourceCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_global_resource_info *info = + static_cast(data); + + ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info); + + if (mockComp->mInfo == info) { + ds_inf("%s: info is deleted.", __func__); + mockComp->bDestroyResourceInfo = true; + } + } + +public: + bool bSurfaceDestroyed; + bool bDestroyed; + bool bGetResourceInfo; + bool bDestroyResourceInfo; + uint32_t mResourceId; + +private: + struct ds_tizen_global_resource_info *mInfo; + struct ds_surface *mSurface; + + struct NewSurfaceListener : ::wl_listener { + MockGlobalResourceCompositor *parent; + }; + NewSurfaceListener mNewSurfaceListener; + + struct DelSurfaceListener : ::wl_listener { + MockGlobalResourceCompositor *parent; + }; + DelSurfaceListener mDelSurfaceListener; + + struct ds_tizen_global_resource *mGlobalResource; + + struct DestroyListener : ::wl_listener { + MockGlobalResourceCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct GetResourceInfoListener : ::wl_listener { + MockGlobalResourceCompositor *parent; + }; + GetResourceInfoListener mGetResourceInfoListener; + + struct GobalResourceInfoDestroyListener : ::wl_listener { + MockGlobalResourceCompositor *parent; + }; + GobalResourceInfoDestroyListener mGobalResourceInfoDestroyListener; +}; + +class MockGlobalResourceClient : public MockClient +{ +public: + MockGlobalResourceClient() + : mResourceId(0), + compositor_res(nullptr), + tizen_surface_res(nullptr) + {} + MockGlobalResourceClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + + mResourceId = 0; + } + ~MockGlobalResourceClient() + { + 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 SetTizenSurfaceShm(struct tizen_surface *global_res) + { + ds_inf("%s", __func__); + + tizen_surface_res = global_res; + } + + struct tizen_surface *GetTizenSurfaceShm() + { + ds_inf("%s", __func__); + + return tizen_surface_res; + } + +public: + uint32_t mResourceId; + +private: + struct wl_compositor *compositor_res; + struct tizen_surface *tizen_surface_res; +}; + +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__); + + MockGlobalResourceClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct tizen_surface *tizen_surface_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_surface")) { + tizen_surface_res = (struct tizen_surface *)wl_registry_bind(registry, + name, &tizen_surface_interface, TIZEN_SURFACE_VERSION); + if (tizen_surface_res == nullptr) { + ds_err("wl_registry_bind() failed. tizen_surface resource."); + return; + } + client->SetTizenSurfaceShm(tizen_surface_res); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockGlobalResourceClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct tizen_surface *tizen_surface_res = client->GetTizenSurfaceShm(); + + tizen_surface_destroy(tizen_surface_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 +client_tizen_resource_cb_resoruce_id(void *data, + struct tizen_resource *resource_res, uint32_t id) +{ + ds_inf("%s", __func__); + + MockGlobalResourceClient *client = + static_cast(data); + + client->mResourceId = id; +} + +static const struct +tizen_resource_listener resource_cb_listener = { + .resource_id = client_tizen_resource_cb_resoruce_id, +}; + +class GlobalResourceTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockGlobalResourceCompositor *comp; + MockGlobalResourceClient *client; + struct wl_compositor *compositor_res; + struct tizen_surface *tizen_surface_res; + struct wl_surface *surface_res; + struct tizen_resource *resource_res; +}; + +void +GlobalResourceTest::SetUp(void) +{ + //ds_log_init(DS_DBG, NULL); + + ds_inf("%s", __func__); + + comp = new MockGlobalResourceCompositor(); + client = new MockGlobalResourceClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + tizen_surface_res = client->GetTizenSurfaceShm(); + surface_res = wl_compositor_create_surface(compositor_res); + + resource_res = + tizen_surface_get_tizen_resource(tizen_surface_res, surface_res); + + tizen_resource_add_listener(resource_res, &resource_cb_listener, client); + + client->RoundTrip(); +} + +void +GlobalResourceTest::TearDown(void) +{ + ds_inf("%s", __func__); + + tizen_resource_destroy(resource_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bDestroyResourceInfo); + + wl_surface_destroy(surface_res); + client->RoundTrip(); + EXPECT_TRUE(comp->bSurfaceDestroyed); + + delete client; + delete comp; +} + +TEST_F(GlobalResourceTest, Create_P) +{ + EXPECT_TRUE(true); + EXPECT_TRUE(comp->bGetResourceInfo); + EXPECT_TRUE(client->mResourceId == 0); +} -- 2.7.4 From 5ba6f6798d45fe9a9984418c57c8a4907a1e61bf Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 22 Jul 2022 15:47:45 +0900 Subject: [PATCH 07/16] fix the typo Change-Id: Iab7a6a560047d7ae545515a3cfefff960c56e013 --- packaging/libds-tizen.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 4165443..546a832 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -387,7 +387,6 @@ ninja -C builddir install %{_libdir}/libds-tizen-clipboard.so %{_bindir}/libds-tizen-clipboard-tests -<<<<<<< HEAD %files launch %manifest %{name}.manifest %defattr(-,root,root,-) -- 2.7.4 From 32e169aae6628ced9a0d90f8cc7d4fcf0ad6a560 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Thu, 28 Jul 2022 14:54:09 +0900 Subject: [PATCH 08/16] launch: implement tizen_launch_effect, tizen_launch_splash Change-Id: I58c4c5e3b56237d370f56d0b7b96a5e8b058bfcc --- examples/meson.build | 1 + examples/tinyds-tdm-libinput.c | 163 +++++++++++ include/libds-tizen/launch/effect.h | 92 ++++++ packaging/libds-tizen.spec | 2 + src/launch/effect.c | 557 ++++++++++++++++++++++++++++++++++++ src/launch/meson.build | 1 + tests/meson.build | 19 ++ tests/tc_launch_effect.cpp | 476 ++++++++++++++++++++++++++++++ 8 files changed, 1311 insertions(+) create mode 100644 include/libds-tizen/launch/effect.h create mode 100644 src/launch/effect.c create mode 100644 tests/tc_launch_effect.cpp diff --git a/examples/meson.build b/examples/meson.build index d9fca10..4d90eb7 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -48,6 +48,7 @@ executable('tinyds-tdm-libinput', common_deps, deps_libds_tizen_backend_tdm, deps_libds_tizen_input_devicemgr, + deps_libds_tizen_launch, dependency('pixman-1', required: true), dependency('threads', required: true), ], diff --git a/examples/tinyds-tdm-libinput.c b/examples/tinyds-tdm-libinput.c index 10c02bb..faf666b 100644 --- a/examples/tinyds-tdm-libinput.c +++ b/examples/tinyds-tdm-libinput.c @@ -26,6 +26,7 @@ #include #include #include +#include #define USE_TDM_BUFFER_QUEUE @@ -79,6 +80,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 tinyds_output *output; struct wl_event_source *stdin_source; @@ -90,6 +93,11 @@ struct tinyds_server struct wl_listener new_xdg_surface; struct wl_listener devicemgr_destroy; struct wl_listener pointer_warp; + struct wl_listener effect_destroy; + struct wl_listener effect_type_set; + struct wl_listener effect_type_unset; + struct wl_listener new_splash; + struct wl_listener splash_owner; struct wl_list keyboards; struct wl_list pointers; @@ -110,6 +118,9 @@ struct tinyds_view int x, y; bool mapped; + + pid_t pid; + int effect_type; }; struct tinyds_pointer @@ -219,6 +230,25 @@ main(void) } static void +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); + + 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); + 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); + ds_inf("view effect_type(%d)", view->effect_type); +} + +static void view_handle_xdg_surface_map(struct wl_listener *listener, void *data TINYDS_UNUSED) { @@ -228,6 +258,8 @@ view_handle_xdg_surface_map(struct wl_listener *listener, view = wl_container_of(listener, view, xdg_surface_map); view->mapped = true; + view_populate_pid(view); + wl_list_for_each(kbd, &view->server->keyboards, link) { keyboard = ds_input_device_get_keyboard(kbd->dev); if (keyboard != NULL) { @@ -320,6 +352,9 @@ server_new_xdg_surface(struct wl_listener *listener, void *data) view->x = rand() % 1000; view->y = rand() % 500; + view->pid = 0; + view->effect_type = -1; + ds_inf("view at (%d, %d)", view->x, view->y); } @@ -508,6 +543,113 @@ devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) server->devicemgr = NULL; } +static void +launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_server *server = + wl_container_of(listener, server, effect_destroy); + + wl_list_remove(&server->effect_destroy.link); + wl_list_remove(&server->effect_type_set.link); + wl_list_remove(&server->effect_type_unset.link); + wl_list_remove(&server->new_splash.link); + + server->effect = NULL; +} + +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 tinyds_view *view = NULL; + bool existing = false; + + server = wl_container_of(listener, server, effect_type_set); + + ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch"); + + wl_list_for_each(view, &server->views, link) { + if (view->pid == event->pid) { + view->effect_type = event->effect_type; + ds_inf("Launch effect. existing pid"); + existing = true; + } + } + if (existing) { + ds_tizen_effect_unset_effect_type(server->effect, event->pid); + } else { + ds_tizen_effect_set_effect_type(server->effect, event->pid, event->effect_type); + } +} + +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 tinyds_view *view = NULL; + + server = wl_container_of(listener, server, effect_type_unset); + + ds_inf("Launch effect. type_unset: pid(%u)", event->pid); + + wl_list_for_each(view, &server->views, link) { + if (view->pid == event->pid) { + view->effect_type = -1; + ds_inf("Launch effect. pid found"); + } + } + ds_tizen_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 tinyds_view *view = NULL; + + server = wl_container_of(listener, server, splash_owner); + + ds_inf("Splash owner. pid(%u)", event->pid); + + wl_list_for_each(view, &server->views, link) { + if (view->pid == event->pid) { + if (event->pid == ds_tizen_splash_get_pid(server->splash)) + ;// + else { + ds_tizen_splash_set_pid(server->splash, event->pid); + } + } + } +} + +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 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; + + server->splash = event->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); + + server->splash_owner.notify = launch_splash_handle_owner; + ds_tizen_splash_add_owner_listener(server->splash, + &server->splash_owner); +} + static bool init_server(struct tinyds_server *server, struct wl_display *display) { @@ -574,6 +716,27 @@ 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); + if (!server->effect) { + goto err; + } + + server->effect_destroy.notify = launch_effect_handle_destroy; + ds_tizen_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, + &server->effect_type_set); + + server->effect_type_unset.notify = launch_effect_handle_type_unset; + ds_tizen_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, + &server->new_splash); + return true; err: diff --git a/include/libds-tizen/launch/effect.h b/include/libds-tizen/launch/effect.h new file mode 100644 index 0000000..d49fa33 --- /dev/null +++ b/include/libds-tizen/launch/effect.h @@ -0,0 +1,92 @@ +#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 546a832..b76d434 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -398,9 +398,11 @@ ninja -C builddir install %defattr(-,root,root,-) %license LICENSE %{_includedir}/libds-tizen/launch/appinfo.h +%{_includedir}/libds-tizen/launch/effect.h %{_libdir}/pkgconfig/libds-tizen-launch.pc %{_libdir}/libds-tizen-launch.so %{_bindir}/libds-tizen-launch-appinfo-tests +%{_bindir}/libds-tizen-launch-effect-tests %files display-policy %manifest %{name}.manifest diff --git a/src/launch/effect.c b/src/launch/effect.c new file mode 100644 index 0000000..fc38c77 --- /dev/null +++ b/src/launch/effect.c @@ -0,0 +1,557 @@ +#include +#include +#include +#include + +#include "util.h" +#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 wl_global *global; + + struct wl_list clients; + struct wl_list infos; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal type_set; + struct wl_signal type_unset; + struct wl_signal new_splash; + } events; +}; + +struct ds_tizen_effect_client +{ + struct ds_tizen_effect *effect; + + struct wl_resource *resource; + struct wl_client *wl_client; + + struct wl_list splashs; + + struct wl_list link; // ds_tizen_effect::clients +}; + +struct ds_tizen_effect_info +{ + uint32_t pid; + int effect_type; + + struct wl_list link; // ds_tizen_effect::infos +}; + +struct ds_tizen_splash +{ + struct ds_tizen_effect *effect; + + struct ds_tizen_effect_client *client; + struct wl_resource *resource; + + uint32_t pid; + char *appid; + bool custom_effect_callee; + + struct { + struct wl_signal destroy; + struct wl_signal owner; + } events; + + struct wl_list link; // ds_tizen_effect_client::splashs +}; + +static void effect_handle_display_destroy(struct wl_listener *listener, + void *data); + +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) +{ + struct ds_tizen_effect *effect; + + effect = calloc(1, sizeof *effect); + if (!effect) { + ds_err("calloc() failed."); + return NULL; + } + + effect->global = wl_global_create(display, &tizen_launch_effect_interface, + TIZEN_EFFECT_VERSION, effect, effect_bind); + if (!effect->global) { + ds_err("wl_global_create() failed. tizen_launch_effect_interface"); + free(effect); + return NULL; + } + + wl_list_init(&effect->clients); + wl_list_init(&effect->infos); + + effect->destroy.notify = effect_handle_display_destroy; + wl_display_add_destroy_listener(display, &effect->destroy); + + wl_signal_init(&effect->events.destroy); + wl_signal_init(&effect->events.type_set); + wl_signal_init(&effect->events.type_unset); + wl_signal_init(&effect->events.new_splash); + + ds_inf("Global create: tizen_launch_effect. effect(%p)", effect); + + return effect; +} + +//launch_effect +WL_EXPORT void +ds_tizen_effect_add_destroy_listener( + struct ds_tizen_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) +{ + 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) +{ + 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) +{ + wl_signal_add(&effect->events.new_splash, listener); +} + +WL_EXPORT void +ds_tizen_effect_set_effect_type(struct ds_tizen_effect *effect, + uint32_t pid, int effect_type) +{ + struct ds_tizen_effect_info *info; + + ds_inf("ds_tizen_effect_set_effect_type() pid(%u), effect_type(%d)", pid, effect_type); + + info = calloc(1, sizeof *info); + if (info == NULL) { + ds_err("calloc() failed. tizen_effect_info"); + return; + } + info->pid = pid; + info->effect_type = effect_type; + + wl_list_insert(&effect->infos, &info->link); +} + +WL_EXPORT void +ds_tizen_effect_unset_effect_type(struct ds_tizen_effect *effect, + uint32_t pid) +{ + struct ds_tizen_effect_info *info, *tmp; + + ds_inf("ds_tizen_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); + wl_list_remove(&info->link); + free(info); + } + } +} + +WL_EXPORT int +ds_tizen_effect_get_effect_type(struct ds_tizen_effect *effect, + uint32_t pid) +{ + struct ds_tizen_effect_info *info; + + ds_inf("ds_tizen_effect_get_effect_type() pid(%u)", pid); + + wl_list_for_each(info, &effect->infos, link) { + if (info->pid == pid) { + return info->effect_type; + } + } + return -1; +} + +//launch_splash +WL_EXPORT void +ds_tizen_splash_add_destroy_listener( + struct ds_tizen_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) +{ + wl_signal_add(&splash->events.owner, listener); +} + +WL_EXPORT uint32_t +ds_tizen_splash_get_pid(struct ds_tizen_splash *splash) +{ + return splash->pid; +} + +WL_EXPORT void +ds_tizen_splash_set_pid(struct ds_tizen_splash *splash, uint32_t pid) +{ + splash->pid = pid; +} + +static void +effect_client_destroy(struct ds_tizen_effect_client *client) +{ + struct ds_tizen_splash *splash, *tmp; + + wl_list_for_each_safe(splash, tmp, &client->splashs, link) { + wl_signal_emit(&splash->events.destroy, splash); + wl_list_remove(&splash->link); + free(splash); + } + + wl_list_remove(&client->link); + free(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; + + effect = wl_container_of(listener, effect, destroy); + + ds_inf("Global destroy: effect(%p)", effect); + + wl_signal_emit(&effect->events.destroy, effect); + wl_list_remove(&effect->destroy.link); + + wl_list_for_each_safe(client, tmp_client, &effect->clients, link) { + effect_client_destroy(client); + } + + wl_list_for_each_safe(info, tmp_info, &effect->infos, link) { + wl_list_remove(&info->link); + free(info); + } + + wl_global_destroy(effect->global); + free(effect); +} + +static int +effect_get_effect_type(const char *effect_type) +{ + enum ds_tizen_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; + + return type; +} + +static void +splash_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +splash_handle_launch(struct wl_client *wl_client, + struct wl_resource *resource, const char *pfname, uint32_t ftype, + uint32_t depth, uint32_t angle, uint32_t indicator, + 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; + + 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); + ds_inf("theme_type(%s), options(%p)",theme_type, options); + + splash = wl_resource_get_user_data(resource); + splash->pid = SPLASH_CLIENT_PID; + effect = splash->effect; + if (effect) { + ds_event.pid = SPLASH_CLIENT_PID; + ds_event.effect_type = effect_get_effect_type(effect_type); + + ds_inf("Effect type_set. pid:%u type:%s", ds_event.pid, effect_type); + + wl_signal_emit(&effect->events.type_set, &ds_event); + } +} + +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; + + ds_inf("splash set owner. pid:%u", pid); + + splash = wl_resource_get_user_data(resource); + + ds_event.pid = pid; + wl_signal_emit(&splash->events.owner, &ds_event); +} + +static void +splash_handle_launch_v2(struct wl_client *wl_client, + struct wl_resource *resource, const char *pfname, uint32_t ftype, + uint32_t depth, uint32_t angle, uint32_t indicator, + 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; + + 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); + ds_inf("theme_type(%s) options(%p) extra_config(%p)", theme_type, options, extra_config); + + splash = wl_resource_get_user_data(resource); + splash->pid = SPLASH_CLIENT_PID; + effect = splash->effect; + if (effect) { + ds_event.pid = SPLASH_CLIENT_PID; + ds_event.effect_type = effect_get_effect_type(effect_type); + + ds_inf("Effect type_set. pid:%u type:%s", ds_event.pid, effect_type); + + wl_signal_emit(&effect->events.type_set, &ds_event); + } + + //Parse extra config + if ((extra_config) && (extra_config->size)) { + char *p_char; + int len = 0; + int size = extra_config->size; + + while (size > 0) { + p_char = extra_config->data + len; + len = strlen(p_char) + 1; + size -= len; + + if (!strcmp(p_char, CUSTOM_EFFECT_CALLEE)) { + //parse next data(appid) from array + if (size > 0) { + p_char = p_char + len; + len = strlen(p_char) + 1; + size -= len; + + splash->appid = strdup(p_char); + splash->custom_effect_callee = true; + + ds_inf("custom effect callee set appid(%s)", + splash->appid); + } + else break; + } + } + } +} + +static const struct tizen_launch_splash_interface splash_impl = +{ + splash_handle_destroy, + splash_handle_launch, + splash_handle_owner, + splash_handle_launch_v2, +}; + +static void +splash_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_splash *splash; + + splash = wl_resource_get_user_data(resource); + + ds_inf("splash_client_handle_destroy (client:%p)", splash->client); + + wl_signal_emit(&splash->events.destroy, splash); + wl_list_remove(&splash->link); + free(splash); +} + +struct ds_tizen_splash* +splash_create_splash_img(struct ds_tizen_effect_client *client, uint32_t id) +{ + struct ds_tizen_splash *splash; + + splash = calloc(1, sizeof *splash); + if (!splash) { + wl_client_post_no_memory(client->wl_client); + return NULL; + } + + splash->resource = wl_resource_create(client->wl_client, + &tizen_launch_splash_interface, wl_resource_get_version(client->resource), + id); + if (!splash->resource) { + free(splash); + wl_client_post_no_memory(client->wl_client); + return NULL; + } + splash->client = client; + splash->effect = client->effect; + splash->pid = SPLASH_CLIENT_PID; + + wl_signal_init(&splash->events.destroy); + wl_signal_init(&splash->events.owner); + + wl_resource_set_implementation(splash->resource, &splash_impl, + splash, splash_client_handle_destroy); + + wl_list_insert(&client->splashs, &splash->link); + + ds_inf("New Splash img %p (res %p)", splash, splash->resource); + + return splash; +} + +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; + + 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); +} + +static void +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; + + client = wl_resource_get_user_data(resource); + effect = client->effect; + + ds_event.pid = pid; + ds_event.effect_type = effect_get_effect_type(effect_type); + + ds_inf("Effect type_set. pid:%u type:%s", pid, effect_type); + + wl_signal_emit(&effect->events.type_set, &ds_event); +} + +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; + + client = wl_resource_get_user_data(resource); + effect = client->effect; + + ds_event.pid = pid; + + ds_inf("Effect type_unset. pid:%u", pid); + + wl_signal_emit(&effect->events.type_unset, &ds_event); +} + +static void +effect_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_launch_effect_interface effect_impl = +{ + effect_handle_create_splash_img, + effect_handle_type_set, + effect_handle_type_unset, + effect_handle_destroy, +}; + +static void +effect_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_effect_client *client; + + client = wl_resource_get_user_data(resource); + + ds_inf("effect_client_handle_destroy (client:%p)", client); + + effect_client_destroy(client); +} + +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; + + client = calloc(1, sizeof *client); + if (client == NULL) { + ds_err("calloc() failed. tizen_,launch_effect"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_effect. client binds. (client:%p)", client); + + client->effect = effect; + client->wl_client = wl_client; + + client->resource = wl_resource_create(wl_client, + &tizen_launch_effect_interface, + MIN(version, TIZEN_EFFECT_VERSION), id); + + if (client->resource == NULL) { + ds_err("tizen_effect : wl_resource_create() failed."); + free(client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_list_init(&client->splashs); + + wl_resource_set_implementation(client->resource, &effect_impl, client, + effect_client_handle_destroy); + + wl_list_insert(&effect->clients, &client->link); +} diff --git a/src/launch/meson.build b/src/launch/meson.build index b3e2efd..494a933 100644 --- a/src/launch/meson.build +++ b/src/launch/meson.build @@ -1,5 +1,6 @@ libds_tizen_launch_files = [ 'appinfo.c', + 'effect.c', ] libds_tizen_launch_deps = [ diff --git a/tests/meson.build b/tests/meson.build index 40e737e..58051f6 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -85,6 +85,25 @@ executable('libds-tizen-launch-appinfo-tests', install : true ) +## launch effect tests +tc_launch_effect_files = [ + 'tc_main.cpp', + 'tc_launch_effect.cpp', +] + +executable('libds-tizen-launch-effect-tests', + [ + tc_mock_files, + tc_launch_effect_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_launch, + ], + install_dir: libds_tizen_bindir, + install : true +) + ## display-policy tests tc_display_policy_files = [ 'tc_main.cpp', diff --git a/tests/tc_launch_effect.cpp b/tests/tc_launch_effect.cpp new file mode 100644 index 0000000..ebfd8ca --- /dev/null +++ b/tests/tc_launch_effect.cpp @@ -0,0 +1,476 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include +#include + +#define TIZEN_EFFECT_VERSION 1 +#define SPLASH_CLIENT_PID 321 // no meaning +#define CUSTOM_EFFECT_CALLEE "_CUSTOM_EFFECT_CALLEE_" +#define SPLASH_TYPE_IMG 0 +#define SPLASH_TYPE_EDC 1 + +//code from e-tizen-testcase +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 +{ +public: + MockEffectCompositor() + : MockCompositor(&MockEffectCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bDestroyed = false; + bTypeSet = false; + bNewSplash = false; + bOwner = false; + + mPid = 0; + mEffectType = -1; + } + + ~MockEffectCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockEffectCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + mockComp->mEffect = ds_tizen_effect_create(comp->display); + + // destroy listener + mockComp->mDestroyListener.notify = + MockEffectCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_effect_add_destroy_listener(mockComp->mEffect, + &mockComp->mDestroyListener); + + // type_set listener + mockComp->mTypeSetListener.notify = + MockEffectCompositor::TypeSetCallback; + mockComp->mTypeSetListener.parent = mockComp; + ds_tizen_effect_add_type_set_listener(mockComp->mEffect, + &mockComp->mTypeSetListener); + + // type_unset listener + mockComp->mTypeUnsetListener.notify = + MockEffectCompositor::TypeUnsetCallback; + mockComp->mTypeUnsetListener.parent = mockComp; + ds_tizen_effect_add_type_unset_listener(mockComp->mEffect, + &mockComp->mTypeUnsetListener); + + // new_splash listener + mockComp->mNewSplashListener.notify = + MockEffectCompositor::NewSplashCallback; + mockComp->mNewSplashListener.parent = mockComp; + ds_tizen_effect_add_new_splash_listener(mockComp->mEffect, + &mockComp->mNewSplashListener); + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockEffectCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void TypeSetCallback(struct wl_listener *listener, void *data) + { + struct ds_tizen_effect_event_type_set *event = (ds_tizen_effect_event_type_set *)data; + ds_inf("%s", __func__); + + MockEffectCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bTypeSet = true; + mockComp->mPid = event->pid; + mockComp->mEffectType = event->effect_type; + } + + static void TypeUnsetCallback(struct wl_listener *listener, void *data) + { + struct ds_tizen_effect_event_type_unset *event = (ds_tizen_effect_event_type_unset *)data; + ds_inf("%s", __func__); + + MockEffectCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bTypeSet = false; + mockComp->mPid = event->pid; + mockComp->mEffectType = -1; + } + + + static void NewSplashCallback(struct wl_listener *listener, void *data) + { + struct ds_tizen_effect_event_new_splash *event = (ds_tizen_effect_event_new_splash *)data; + ds_inf("%s", __func__); + + MockEffectCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bNewSplash = true; + mockComp->mSplash = event->splash; + + // owner listener + mockComp->mOwnerListener.notify = + MockEffectCompositor::OwnerCallback; + mockComp->mOwnerListener.parent = mockComp; + ds_tizen_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; + ds_inf("%s", __func__); + + MockEffectCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->mPid = event->pid; + } + +public: + bool bDestroyed; + bool bTypeSet; + bool bNewSplash; + bool bOwner; + + uint32_t mPid; + int mEffectType; + +private: + struct ds_tizen_effect *mEffect; + struct ds_tizen_splash *mSplash; + struct DestroyListener: ::wl_listener { + MockEffectCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct TypeSetListener: ::wl_listener { + MockEffectCompositor *parent; + }; + TypeSetListener mTypeSetListener; + + struct TypeUnsetListener: ::wl_listener { + MockEffectCompositor *parent; + }; + TypeUnsetListener mTypeUnsetListener; + + struct NewSplashListener: ::wl_listener { + MockEffectCompositor *parent; + }; + NewSplashListener mNewSplashListener; + + struct OwnerListener: ::wl_listener { + MockEffectCompositor *parent; + }; + OwnerListener mOwnerListener; +}; + +class MockEffectClient : public MockClient +{ +public: + MockEffectClient() + : compositor_res(nullptr), + tizen_launch_effect(nullptr) + {} + + MockEffectClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + } + + ~MockEffectClient() + { + 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 SetTizenEffect(struct tizen_launch_effect *global_res) + { + ds_inf("%s", __func__); + tizen_launch_effect = global_res; + } + + struct tizen_launch_effect *GetTizenEffect() + { + ds_inf("%s", __func__); + + return tizen_launch_effect; + } + +public: + +private: + struct wl_compositor *compositor_res; + struct tizen_launch_effect *tizen_launch_effect; +}; + +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__); + + MockEffectClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct tizen_launch_effect *tizen_launch_effect; + + 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_launch_effect")) { + tizen_launch_effect = (struct tizen_launch_effect *)wl_registry_bind(registry, + name, &tizen_launch_effect_interface, TIZEN_EFFECT_VERSION); + if (tizen_launch_effect == nullptr) { + ds_err("wl_registry_bind() failed. tizen_launch_effect resource."); + return; + } + client->SetTizenEffect(tizen_launch_effect); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockEffectClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct tizen_launch_effect *effect_res = client->GetTizenEffect(); + + tizen_launch_effect_destroy(effect_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 EffectTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockEffectCompositor *comp; + MockEffectClient *client; + struct wl_compositor *compositor_res; + struct tizen_launch_effect *effect_res; +}; + +void +EffectTest::SetUp(void) +{ + ds_inf("%s", __func__); + + comp = new MockEffectCompositor(); + client = new MockEffectClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + effect_res = client->GetTizenEffect(); + + client->RoundTrip(); +} + +void +EffectTest::TearDown(void) +{ + ds_inf("%s", __func__); + + client->RoundTrip(); + + delete client; + delete comp; +} + +TEST_F(EffectTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(EffectTest, Req_TizenEffectTypeSet) +{ + uint pid = 12345; + const char *effect_type; + + effect_type = "launch"; + tizen_launch_effect_type_set(effect_res, effect_type, pid, NULL); + client->RoundTrip(); + EXPECT_TRUE(comp->bTypeSet); + EXPECT_TRUE(comp->mPid == pid); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_LAUNCH); +} + +TEST_F(EffectTest, Req_TizenEffectTypeUnSet) +{ + uint pid = 12345; + const char *effect_type; + + effect_type = "depth-in"; + tizen_launch_effect_type_set(effect_res, effect_type, pid, NULL); + client->RoundTrip(); + EXPECT_TRUE(comp->bTypeSet); + EXPECT_TRUE(comp->mPid == pid); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_DEPTH_IN); + + tizen_launch_effect_type_unset(effect_res, pid); + client->RoundTrip(); + EXPECT_FALSE(comp->bTypeSet); + EXPECT_TRUE(comp->mPid == pid); + EXPECT_TRUE(comp->mEffectType == -1); +} + +TEST_F(EffectTest, Req_TizenEffectCreateSplashImg) +{ + struct tizen_launch_splash *splash = NULL; + + splash = tizen_launch_effect_create_splash_img(effect_res); + client->RoundTrip(); + EXPECT_TRUE(splash != NULL); + EXPECT_TRUE(comp->bNewSplash); +} + +TEST_F(EffectTest, Req_TizenSplashLaunch_EDC) +{ + struct tizen_launch_splash *splash = NULL; + struct wl_array options; + + splash = tizen_launch_effect_create_splash_img(effect_res); + client->RoundTrip(); + EXPECT_TRUE(splash != NULL); + EXPECT_TRUE(comp->bNewSplash); + + wl_array_init(&options); + + tizen_launch_splash_launch(splash, path_edc,\ + SPLASH_TYPE_EDC, 24, 0, 0, "launch", "default", &options); + client->RoundTrip(); + wl_array_release(&options); + EXPECT_TRUE(comp->mPid == SPLASH_CLIENT_PID); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_LAUNCH); +} + +TEST_F(EffectTest, Req_TizenSplashLaunch_IMG) +{ + struct tizen_launch_splash *splash = NULL; + struct wl_array options; + + splash = tizen_launch_effect_create_splash_img(effect_res); + client->RoundTrip(); + EXPECT_TRUE(splash != NULL); + EXPECT_TRUE(comp->bNewSplash); + + wl_array_init(&options); + + tizen_launch_splash_launch(splash, path_img,\ + SPLASH_TYPE_IMG, 24, 0, 0, "launch", "default", &options); + client->RoundTrip(); + wl_array_release(&options); + EXPECT_TRUE(comp->mPid == SPLASH_CLIENT_PID); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_EFFECT_TYPE_LAUNCH); +} + +TEST_F(EffectTest, Req_TizenSplashSetOwner) +{ + struct tizen_launch_splash *splash = NULL; + struct wl_array options; + uint32_t pid = 12345; + + splash = tizen_launch_effect_create_splash_img(effect_res); + client->RoundTrip(); + EXPECT_TRUE(splash != NULL); + EXPECT_TRUE(comp->bNewSplash); + + wl_array_init(&options); + + tizen_launch_splash_launch(splash, path_img,\ + SPLASH_TYPE_IMG, 24, 0, 0, "depth-in", "default", &options); + client->RoundTrip(); + wl_array_release(&options); + EXPECT_TRUE(comp->mPid == SPLASH_CLIENT_PID); + EXPECT_TRUE(comp->mEffectType == DS_TIZEN_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); +} + +TEST_F(EffectTest, Req_TizenSplashLaunch_v2) + +{ + struct tizen_launch_splash *splash = NULL; + struct wl_array options; + struct wl_array extra_config; + int custom_effect = 0; + void *data; + int size; + const char *appid = "org.tizen.libds-tizen-launch-effect-test"; + + splash = tizen_launch_effect_create_splash_img(effect_res); + client->RoundTrip(); + EXPECT_TRUE(splash != NULL); + EXPECT_TRUE(comp->bNewSplash); + + // set + wl_array_init(&options); + size = strlen(appid) + 1; + data = wl_array_add(&options, size); + memcpy(data, appid, size); + + wl_array_init(&extra_config); + size = strlen(CUSTOM_EFFECT_CALLEE) + 1; + data = wl_array_add(&extra_config, size); + memcpy(data, CUSTOM_EFFECT_CALLEE, size); + + size = strlen(appid) + 1; + data = wl_array_add(&extra_config, size); + memcpy(data, appid, size); + + if (extra_config.size > 0) + custom_effect = 1; + + tizen_launch_splash_launch_v2(splash, path_edc,\ + SPLASH_TYPE_EDC, 24, 0, 0, "depth-in", "default", &options, custom_effect ? &extra_config : NULL); + client->RoundTrip(); + 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); +} -- 2.7.4 From f58c53e13ab83c353b5e9b9db944dffe659a9949 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 8 Aug 2022 15:46:33 +0900 Subject: [PATCH 09/16] merge tizends-tdm-dpms code to tinyds-tdm Change-Id: I647578cf6321fceb28ff15a4313f027a303e0241 --- examples/meson.build | 17 +- examples/tinyds-tdm-dpms.c | 672 --------------------------------------------- examples/tinyds-tdm.c | 97 +++++++ packaging/libds-tizen.spec | 1 - 4 files changed, 98 insertions(+), 689 deletions(-) delete mode 100644 examples/tinyds-tdm-dpms.c diff --git a/examples/meson.build b/examples/meson.build index 4d90eb7..ec5c244 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -28,6 +28,7 @@ executable('tinyds-tdm', common_deps, deps_libds_tizen_backend_tdm, deps_libds_tizen_tbm_server, + deps_libds_tizen_dpms, dependency('pixman-1', required: true), dependency('threads', required: true), ], @@ -56,22 +57,6 @@ executable('tinyds-tdm-libinput', install : true ) -executable('tinyds-tdm-dpms', - 'tinyds-tdm-dpms.c', - 'pixman-helper.c', - 'pixman-tbm-helper.c', - 'tinyds-tdm-renderer.c', - dependencies: [ - common_deps, - deps_libds_tizen_backend_tdm, - deps_libds_tizen_dpms, - dependency('pixman-1', required: true), - dependency('threads', required: true), - ], - install_dir: libds_tizen_bindir, - install : true -) - tinyds_tdm_hwc_files = [ 'tinyds-tdm-hwc.c', 'pixman-helper.c', diff --git a/examples/tinyds-tdm-dpms.c b/examples/tinyds-tdm-dpms.c deleted file mode 100644 index dc32e8f..0000000 --- a/examples/tinyds-tdm-dpms.c +++ /dev/null @@ -1,672 +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; - - bool drawable; - bool damaged; -}; - -struct tinyds_dpms -{ - struct ds_tizen_dpms *ds_dpms; - struct tinyds_server *server; - - struct wl_listener destroy; - struct wl_listener set_dpms; - struct wl_listener get_dpms; -}; - -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 tinyds_dpms *dpms; - 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 - - 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); -#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 -static void dpms_handle_destroy(struct wl_listener *listener, void *data); -static void dpms_handle_set_dpms(struct wl_listener *listener, void *data); -static void dpms_handle_get_dpms(struct wl_listener *listener, void *data); - - -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; - struct tinyds_server *server; - - view = wl_container_of(listener, view, xdg_surface_destroy); - server = view->server; - - 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); - - draw_server_with_damage(server); -} - -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); - - wl_list_insert(server->views.prev, &view->link); - - view->x = rand() % 1000; - view->y = rand() % 500; -} - -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->drawable = true; - output->damaged = 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->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; - - draw_output(output); -} - -static bool -add_new_dpms(struct tinyds_server *server) -{ - struct tinyds_dpms *dpms; - - dpms = calloc(1, sizeof *dpms); - if (!dpms) - return false; - - dpms->ds_dpms = ds_tizen_dpms_create(server->display); - if (!dpms->ds_dpms) - return false; - - dpms->destroy.notify = dpms_handle_destroy; - ds_tizen_dpms_add_destroy_listener(dpms->ds_dpms, &dpms->destroy); - - dpms->set_dpms.notify = dpms_handle_set_dpms; - ds_tizen_dpms_add_set_dpms_listener(dpms->ds_dpms, &dpms->set_dpms); - - dpms->get_dpms.notify = dpms_handle_get_dpms; - ds_tizen_dpms_add_get_dpms_listener(dpms->ds_dpms, &dpms->get_dpms); - - server->dpms = dpms; - - ds_inf("Dpms (%p) added", dpms); - - return true; -} - -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); - - if (!add_new_dpms(server)) { - ds_backend_destroy(server->backend); - return false; - } - - 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_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); -} - -static void -draw_server_with_damage(struct tinyds_server *server) -{ - server->output->damaged = true; - draw_output(server->output); -} - -#ifdef USE_TDM_BUFFER_QUEUE -static void -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); -} - -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, 80, 80, 80); -} - -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; - - if (!view->mapped) - 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; - - 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, 80, 80, 80); - - wl_list_for_each(view, &output->server->views, link) { - if (!view->mapped) - 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) -{ - - 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; -} - -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); - 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 int -server_dispatch_stdin(int fd, uint32_t mask, void *data) -{ - struct tinyds_server *server = data; - - wl_display_terminate(server->display); - - return 1; -} - -static void -dpms_handle_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_dpms *dpms; - - dpms = wl_container_of(listener, dpms, destroy); - - ds_inf("Dpms(%p) destroyed", dpms); - - wl_list_remove(&dpms->destroy.link); - wl_list_remove(&dpms->set_dpms.link); - wl_list_remove(&dpms->get_dpms.link); - - free(dpms); -} - -static void -dpms_handle_set_dpms(struct wl_listener *listener, void *data) -{ - struct tinyds_dpms *dpms; - struct ds_tizen_dpms_event *event = data; - - dpms = wl_container_of(listener, dpms, set_dpms); - - ds_inf("Dpms(%p) set dpms : %d", dpms, event->mode); - - //To do - //set dpms mode to output - ds_tizen_dpms_send_set_result(dpms->ds_dpms, event->mode, - DS_TIZEN_DPMS_ERROR_NONE); -} - -static void -dpms_handle_get_dpms(struct wl_listener *listener, void *data) -{ - struct tinyds_dpms *dpms; - - dpms = wl_container_of(listener, dpms, get_dpms); - - ds_inf("Dpms(%p) get dpms", dpms); - - //To do - //get dpms mode from output - ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON, - DS_TIZEN_DPMS_ERROR_NONE); -} \ No newline at end of file diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 4bc08f1..98b9a0a 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -16,6 +16,7 @@ #include #include #include +#include #define USE_TDM_BUFFER_QUEUE @@ -53,6 +54,16 @@ struct tinyds_output bool damaged; }; +struct tinyds_dpms +{ + struct ds_tizen_dpms *ds_dpms; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener set_dpms; + struct wl_listener get_dpms; +}; + struct tinyds_server { struct ds_tbm_server *tbm_server; @@ -64,6 +75,7 @@ struct tinyds_server struct ds_xdg_shell *xdg_shell; struct tinyds_output *output; + struct tinyds_dpms *dpms; struct wl_event_source *stdin_source; struct wl_list views; @@ -110,6 +122,10 @@ static void output_swapchain_init(struct tinyds_output *output, static void output_draw_with_swapchain(struct tinyds_output *output); static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); #endif +static void dpms_handle_destroy(struct wl_listener *listener, void *data); +static void dpms_handle_set_dpms(struct wl_listener *listener, void *data); +static void dpms_handle_get_dpms(struct wl_listener *listener, void *data); + int main(void) @@ -290,6 +306,35 @@ backend_handle_new_output(struct wl_listener *listener, void *data) } static bool +add_new_dpms(struct tinyds_server *server) +{ + struct tinyds_dpms *dpms; + + dpms = calloc(1, sizeof *dpms); + if (!dpms) + return false; + + dpms->ds_dpms = ds_tizen_dpms_create(server->display); + if (!dpms->ds_dpms) + return false; + + dpms->destroy.notify = dpms_handle_destroy; + ds_tizen_dpms_add_destroy_listener(dpms->ds_dpms, &dpms->destroy); + + dpms->set_dpms.notify = dpms_handle_set_dpms; + ds_tizen_dpms_add_set_dpms_listener(dpms->ds_dpms, &dpms->set_dpms); + + dpms->get_dpms.notify = dpms_handle_get_dpms; + ds_tizen_dpms_add_get_dpms_listener(dpms->ds_dpms, &dpms->get_dpms); + + server->dpms = dpms; + + ds_inf("Dpms (%p) added", dpms); + + return true; +} + +static bool init_server(struct tinyds_server *server, struct wl_display *display) { server->display = display; @@ -329,6 +374,11 @@ init_server(struct tinyds_server *server, struct wl_display *display) ds_xdg_shell_add_new_surface_listener(server->xdg_shell, &server->new_xdg_surface); + if (!add_new_dpms(server)) { + ds_backend_destroy(server->backend); + return false; + } + return true; } @@ -573,3 +623,50 @@ server_dispatch_stdin(int fd, uint32_t mask, void *data) return 1; } + +static void +dpms_handle_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_dpms *dpms; + + dpms = wl_container_of(listener, dpms, destroy); + + ds_inf("Dpms(%p) destroyed", dpms); + + wl_list_remove(&dpms->destroy.link); + wl_list_remove(&dpms->set_dpms.link); + wl_list_remove(&dpms->get_dpms.link); + + free(dpms); +} + +static void +dpms_handle_set_dpms(struct wl_listener *listener, void *data) +{ + struct tinyds_dpms *dpms; + struct ds_tizen_dpms_event *event = data; + + dpms = wl_container_of(listener, dpms, set_dpms); + + ds_inf("Dpms(%p) set dpms : %d", dpms, event->mode); + + //To do + //set dpms mode to output + ds_tizen_dpms_send_set_result(dpms->ds_dpms, event->mode, + DS_TIZEN_DPMS_ERROR_NONE); +} + +static void +dpms_handle_get_dpms(struct wl_listener *listener, void *data) +{ + struct tinyds_dpms *dpms; + + dpms = wl_container_of(listener, dpms, get_dpms); + + ds_inf("Dpms(%p) get dpms", dpms); + + //To do + //get dpms mode from output + ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON, + DS_TIZEN_DPMS_ERROR_NONE); +} diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index b76d434..1ab1978 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -354,7 +354,6 @@ ninja -C builddir install %{_includedir}/libds-tizen/dpms.h %{_libdir}/pkgconfig/libds-tizen-dpms.pc %{_libdir}/libds-tizen-dpms.so -%{_bindir}/tinyds-tdm-dpms %{_bindir}/ds-simple-dpms %files indicator -- 2.7.4 From 0b7b11607617abe39b7f458869a17d84fa78da87 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 8 Aug 2022 15:55:50 +0900 Subject: [PATCH 10/16] merge tizends-tdm-libinput code to tinyds-tdm Change-Id: Iac7a17b98776e88eb1a434f7318ed69c7cf839c8 --- examples/meson.build | 19 - examples/tinyds-tdm-libinput.c | 1369 ---------------------------------------- examples/tinyds-tdm.c | 820 +++++++++++++++++++++++- packaging/libds-tizen.spec | 1 - 4 files changed, 805 insertions(+), 1404 deletions(-) delete mode 100644 examples/tinyds-tdm-libinput.c diff --git a/examples/meson.build b/examples/meson.build index ec5c244..3370f26 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -29,25 +29,6 @@ executable('tinyds-tdm', deps_libds_tizen_backend_tdm, deps_libds_tizen_tbm_server, deps_libds_tizen_dpms, - dependency('pixman-1', required: true), - dependency('threads', required: true), - ], - install_dir: libds_tizen_bindir, - install : true -) - -tinyds_tdm_libinput_files = [ - 'tinyds-tdm-libinput.c', - 'pixman-helper.c', - 'pixman-tbm-helper.c', - 'tinyds-tdm-renderer.c', -] - -executable('tinyds-tdm-libinput', - tinyds_tdm_libinput_files, - dependencies: [ - common_deps, - deps_libds_tizen_backend_tdm, deps_libds_tizen_input_devicemgr, deps_libds_tizen_launch, dependency('pixman-1', required: true), diff --git a/examples/tinyds-tdm-libinput.c b/examples/tinyds-tdm-libinput.c deleted file mode 100644 index faf666b..0000000 --- a/examples/tinyds-tdm-libinput.c +++ /dev/null @@ -1,1369 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#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_keyboard; -struct tinyds_pointer; - -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; - - bool drawable; - bool damaged; -}; - -struct tinyds_server -{ - struct ds_tbm_server *tbm_server; - - struct wl_display *display; - - struct ds_backend *backend; - struct ds_backend *input_backend; - struct ds_compositor *compositor; - struct ds_xdg_shell *xdg_shell; - struct ds_seat *seat; - 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 tinyds_output *output; - struct wl_event_source *stdin_source; - - struct wl_list views; - - struct wl_listener new_output; - struct wl_listener new_input; - struct wl_listener new_xdg_surface; - struct wl_listener devicemgr_destroy; - struct wl_listener pointer_warp; - struct wl_listener effect_destroy; - struct wl_listener effect_type_set; - struct wl_listener effect_type_unset; - struct wl_listener new_splash; - struct wl_listener splash_owner; - - struct wl_list keyboards; - struct wl_list pointers; -}; - -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 - - int x, y; - bool mapped; - - pid_t pid; - int effect_type; -}; - -struct tinyds_pointer -{ - struct ds_input_device *dev; - struct tinyds_server *server; - - struct tinyds_view *focused_view; - - struct wl_listener destroy; - struct wl_listener motion; //relative - struct wl_listener button; - struct wl_listener frame; - struct wl_list link; //tinyds_server::pointers -}; - -struct tinyds_keyboard -{ - struct ds_input_device *dev; - struct tinyds_server *server; - - struct wl_listener destroy; - struct wl_listener key; - struct wl_list link; //tinyds_server::keyboards -}; - -struct tinyds_touch -{ - struct ds_input_device *dev; - struct tinyds_server *server; - - struct wl_listener destroy; - struct wl_listener down; - struct wl_listener up; - struct wl_listener motion; -}; - -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); -#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 -static void server_add_keyboard(struct tinyds_server *server, - struct ds_input_device *dev); -static void server_add_pointer(struct tinyds_server *server, - struct ds_input_device *dev); -static void server_add_touch(struct tinyds_server *server, - struct ds_input_device *dev); - -static struct tinyds_view * -server_view_at(struct tinyds_server *server, double lx, double ly, - double *sx, double *sy); - -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); - ds_backend_start(server->input_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_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); - - 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); - 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); - ds_inf("view effect_type(%d)", view->effect_type); -} - -static void -view_handle_xdg_surface_map(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - struct ds_keyboard *keyboard; - struct tinyds_keyboard *kbd; - view = wl_container_of(listener, view, xdg_surface_map); - view->mapped = true; - - view_populate_pid(view); - - wl_list_for_each(kbd, &view->server->keyboards, link) { - keyboard = ds_input_device_get_keyboard(kbd->dev); - if (keyboard != NULL) { - ds_seat_keyboard_notify_enter(view->server->seat, - ds_xdg_surface_get_surface(view->xdg_surface), - keyboard->keycodes, keyboard->num_keycodes, - &keyboard->modifiers); - return; - } - } -} - -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; - struct tinyds_server *server; - - view = wl_container_of(listener, view, xdg_surface_destroy); - server = view->server; - - 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); - - draw_server_with_damage(server); -} - -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); - - wl_list_insert(server->views.prev, &view->link); - - view->x = rand() % 1000; - view->y = rand() % 500; - - view->pid = 0; - view->effect_type = -1; - - ds_inf("view at (%d, %d)", view->x, view->y); -} - -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->drawable = true; - output->damaged = 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->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); - - ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height); - - server->output = output; - - draw_output(output); -} - -static void -backend_handle_new_input(struct wl_listener *listener, void *data) -{ - struct tinyds_server *server; - struct ds_input_device *dev = data; - enum ds_input_device_type dev_type; - - server = wl_container_of(listener, server, new_input); - - dev_type = ds_input_device_get_type(dev); - - switch (dev_type) { - case DS_INPUT_DEVICE_KEYBOARD: - server_add_keyboard(server, dev); - server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD; - break; - case DS_INPUT_DEVICE_TOUCH: - server_add_touch(server, dev); - server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH; - break; - case DS_INPUT_DEVICE_POINTER: - server_add_pointer(server, dev); - server->seat_caps |= WL_SEAT_CAPABILITY_POINTER; - break; - default: - ds_err("Unknown type(%d) of ds_input_device", dev_type); - break; - } - - ds_seat_set_capabilities(server->seat, server->seat_caps); -} - -static void -devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode) -{ - struct ds_tizen_input_devicemgr_keymap_data *data; - - data = calloc(1, sizeof *data); - if (!data) { - ds_err("Failed to alloc memory\n"); - return; - } - - data->name = strdup(name); - data->keycode = keycode; - - wl_list_insert(list, &data->link); -} - -static void -devicemgr_remove_keymap_data(struct wl_list *list, int keycode) -{ - 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); - } - } -} - -static void -devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr) -{ - struct wl_list keymap_list; - bool res; - - wl_list_init(&keymap_list); - - devicemgr_add_keymap_data(&keymap_list, "XF86VolumeRaise", 455); - devicemgr_add_keymap_data(&keymap_list, "XF86VolumeLower", 456); - devicemgr_add_keymap_data(&keymap_list, "XF86LightOn", 457); - devicemgr_add_keymap_data(&keymap_list, "XF86LightOff", 458); - - res = ds_tizen_input_devicemgr_set_keymap_list(devicemgr, &keymap_list); - 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); -} - -static void -devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data) -{ - struct tinyds_server *server; - struct tinyds_pointer *pointer; - struct ds_tizen_input_devicemgr_event_pointer_warp *event = data; - double sx = 0.f, sy = 0.f; - struct tinyds_view *view = NULL; - - server = wl_container_of(listener, server, pointer_warp); - - ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface, - event->x, event->y); - - wl_list_for_each(pointer, &server->pointers, link){ - if (!pointer->focused_view) continue; - view = pointer->focused_view; - } - if (!view) return; - - if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) { - ds_inf("Pointer is not on the requested surface"); - return; - } - - server->output_x = view->x + (event->x * server->output->width); - server->output_y = view->y + (event->y * server->output->height); - - server_view_at(server, server->output_x, server->output_y, &sx, &sy); - - ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f", - sx, sy, server->output_x, server->output_y); - - ds_seat_pointer_notify_motion(server->seat, - event->time_msec, sx, sy); -} - -static void -devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) -{ - struct tinyds_server *server = - wl_container_of(listener, server, devicemgr_destroy); - - wl_list_remove(&server->devicemgr_destroy.link); - wl_list_remove(&server->pointer_warp.link); - - server->devicemgr = NULL; -} - -static void -launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) -{ - struct tinyds_server *server = - wl_container_of(listener, server, effect_destroy); - - wl_list_remove(&server->effect_destroy.link); - wl_list_remove(&server->effect_type_set.link); - wl_list_remove(&server->effect_type_unset.link); - wl_list_remove(&server->new_splash.link); - - server->effect = NULL; -} - -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 tinyds_view *view = NULL; - bool existing = false; - - server = wl_container_of(listener, server, effect_type_set); - - ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch"); - - wl_list_for_each(view, &server->views, link) { - if (view->pid == event->pid) { - view->effect_type = event->effect_type; - ds_inf("Launch effect. existing pid"); - existing = true; - } - } - if (existing) { - ds_tizen_effect_unset_effect_type(server->effect, event->pid); - } else { - ds_tizen_effect_set_effect_type(server->effect, event->pid, event->effect_type); - } -} - -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 tinyds_view *view = NULL; - - server = wl_container_of(listener, server, effect_type_unset); - - ds_inf("Launch effect. type_unset: pid(%u)", event->pid); - - wl_list_for_each(view, &server->views, link) { - if (view->pid == event->pid) { - view->effect_type = -1; - ds_inf("Launch effect. pid found"); - } - } - ds_tizen_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 tinyds_view *view = NULL; - - server = wl_container_of(listener, server, splash_owner); - - ds_inf("Splash owner. pid(%u)", event->pid); - - wl_list_for_each(view, &server->views, link) { - if (view->pid == event->pid) { - if (event->pid == ds_tizen_splash_get_pid(server->splash)) - ;// - else { - ds_tizen_splash_set_pid(server->splash, event->pid); - } - } - } -} - -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 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; - - server->splash = event->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); - - server->splash_owner.notify = launch_splash_handle_owner; - ds_tizen_splash_add_owner_listener(server->splash, - &server->splash_owner); -} - -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->input_backend = ds_libinput_backend_create(display); - if (!server->input_backend) { - ds_backend_destroy(server->backend); - return false; - } - - server->new_output.notify = backend_handle_new_output; - ds_backend_add_new_output_listener(server->backend, - &server->new_output); - - wl_list_init(&server->keyboards); - wl_list_init(&server->pointers); - server->new_input.notify = backend_handle_new_input; - ds_backend_add_new_input_listener(server->input_backend, &server->new_input); - - server->compositor = ds_compositor_create(display); - if (!server->compositor) - goto err; - - server->tbm_server = ds_tbm_server_create(display); - if (!server->tbm_server) - goto err; - - server->xdg_shell = ds_xdg_shell_create(display); - if (!server->xdg_shell) - goto err; - - server->new_xdg_surface.notify = server_new_xdg_surface; - ds_xdg_shell_add_new_surface_listener(server->xdg_shell, - &server->new_xdg_surface); - - server->seat = ds_seat_create(display, "seat0" /* arbitrary name */); - if (!server->seat) - goto err; - server->seat_caps = 0; - - server->devicemgr = ds_tizen_input_devicemgr_create( - server->input_backend, server->seat); - if (!server->devicemgr) { - goto err; - } - - devicemgr_set_keymap(server->devicemgr); - - server->devicemgr_destroy.notify = devicemgr_handle_destroy; - ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr, - &server->devicemgr_destroy); - - server->pointer_warp.notify = devicemgr_handle_pointer_warp; - ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr, - &server->pointer_warp); - - server->effect = ds_tizen_effect_create(display); - if (!server->effect) { - goto err; - } - - server->effect_destroy.notify = launch_effect_handle_destroy; - ds_tizen_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, - &server->effect_type_set); - - server->effect_type_unset.notify = launch_effect_handle_type_unset; - ds_tizen_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, - &server->new_splash); - - return true; - -err: - ds_backend_destroy(server->backend); - ds_backend_destroy(server->input_backend); - - return false; -} - -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_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); -} - -static void -draw_server_with_damage(struct tinyds_server *server) -{ - server->output->damaged = true; - draw_output(server->output); -} - -#ifdef USE_TDM_BUFFER_QUEUE -static void -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); -} - -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, 80, 80, 80); -} - -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; - - if (!view->mapped) - 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; - - 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, 80, 80, 80); - - wl_list_for_each(view, &output->server->views, link) { - if (!view->mapped) - 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) -{ - - 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; -} - -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); - 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 int -server_dispatch_stdin(int fd, uint32_t mask, void *data) -{ - struct tinyds_server *server = data; - - wl_display_terminate(server->display); - - return 1; -} - - -static void -keyboard_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_keyboard *kbd; - - kbd = wl_container_of(listener, kbd, destroy); - - ds_inf("Keyboard(%p) destroyed", kbd); - - wl_list_remove(&kbd->destroy.link); - wl_list_remove(&kbd->key.link); - wl_list_remove(&kbd->link); - - free(kbd); -} - -static bool -server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) -{ - switch (sym) { - case XKB_KEY_BackSpace: - wl_display_terminate(server->display); - break; - default: - return false; - } - - return true; -} - -static void -keyboard_handle_key(struct wl_listener *listener, void *data) -{ - struct tinyds_keyboard *kbd; - struct ds_event_keyboard_key *event = data; - struct ds_keyboard *ds_keyboard; - struct xkb_state *xkb_state; - const xkb_keysym_t *syms; - int nsyms; - bool handled = false; - - kbd = wl_container_of(listener, kbd, key); - - ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), " - "update_state(%d)", kbd->dev, - event->keycode, event->state, event->time_msec, - event->update_state); - - ds_keyboard = ds_input_device_get_keyboard(kbd->dev); - - if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); - if (xkb_state) { - nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, - &syms); - for (int i = 0; i < nsyms; i++) { - handled = server_handle_keybinding(kbd->server, syms[i]); - } - } - } - - if (!handled) { - ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec, - event->keycode, event->state); - } -} - -static void -server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) -{ - struct tinyds_keyboard *kbd; - struct xkb_context *context; - struct xkb_keymap *keymap; - - kbd = calloc(1, sizeof *kbd); - assert(kbd); - - kbd->dev = dev; - kbd->server = server; - - context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - 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); - } - - ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap); - - xkb_keymap_unref(keymap); - xkb_context_unref(context); - - kbd->destroy.notify = keyboard_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &kbd->destroy); - - kbd->key.notify = keyboard_handle_key; - ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); - - wl_list_insert(&server->keyboards, &kbd->link); - - ds_inf("Keyboard(%p) added", kbd); -} - -static struct tinyds_view * -server_view_at(struct tinyds_server *server, double lx, double ly, - double *sx, double *sy) -{ - struct tinyds_view *view; - struct ds_surface *surface; - struct ds_buffer *buffer; - int x, y, w = 0, h = 0; - - wl_list_for_each(view, &server->views, link) { - surface = ds_xdg_surface_get_surface(view->xdg_surface); - buffer = ds_surface_get_buffer(surface); - ds_buffer_get_size(buffer, &w, &h); - - x = view->x; - y = view->y; - - if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) { - *sx = lx - x; - *sy = ly - y; - - return view; - } - } - - return NULL; -} - -static void -touch_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_touch *touch; - - touch = wl_container_of(listener, touch, destroy); - - ds_inf("Touch(%p) destroyed", touch); - - wl_list_remove(&touch->destroy.link); - wl_list_remove(&touch->down.link); - wl_list_remove(&touch->up.link); - wl_list_remove(&touch->motion.link); - - free(touch); -} - -static void -touch_handle_down(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_down *event = data; - struct tinyds_touch *touch; - struct tinyds_view *view; - struct tinyds_server *server; - double sx = 0.f, sy = 0.f; - - touch = wl_container_of(listener, touch, down); - - server = touch->server; - server->output_x = event->x * server->output->width; - server->output_y = event->y * server->output->height; - - ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f", - touch->dev, event->id, event->x, event->y, server->output_x, server->output_y); - - view = server_view_at(server, server->output_x, server->output_y, &sx, &sy); - - if (view) { - ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface), - event->time_msec, event->id, sx, sy); - } -} - -static void -touch_handle_up(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_up *event = data; - struct tinyds_touch *touch; - - touch = wl_container_of(listener, touch, up); - - ds_inf("Touch(%p) event up: id(%d) time_msec(%d)", - touch->dev, event->id, event->time_msec); - - ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id); -} - -static void -touch_handle_motion(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_motion *event = data; - struct tinyds_touch *touch; - struct tinyds_view *view; - struct tinyds_server *server; - double sx = 0.f, sy = 0.f; - - touch = wl_container_of(listener, touch, motion); - - server = touch->server; - server->output_x = event->x * server->output->width; - server->output_y = event->y * server->output->height; - - ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f", - touch->dev, event->id, event->x, event->y, server->output_x, server->output_y); - - view = server_view_at(server, server->output_x, server->output_y, &sx, &sy); - - if (view) { - ds_seat_touch_notify_motion(server->seat, event->time_msec, - event->id, sx, sy); - } -} - -static void -server_add_touch(struct tinyds_server *server, struct ds_input_device *dev) -{ - struct tinyds_touch *touch; - - touch = calloc(1, sizeof *touch); - assert(touch); - - touch->dev = dev; - touch->server = server; - - touch->destroy.notify = touch_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &touch->destroy); - - touch->down.notify = touch_handle_down; - ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down); - - touch->up.notify = touch_handle_up; - ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up); - - touch->motion.notify = touch_handle_motion; - ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion); - - ds_inf("Touch(%p) added", touch); -} - -static void -pointer_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - - pointer = wl_container_of(listener, pointer, destroy); - - ds_inf("Pointer(%p) destroyed", pointer); - - wl_list_remove(&pointer->destroy.link); - wl_list_remove(&pointer->motion.link); - wl_list_remove(&pointer->button.link); - wl_list_remove(&pointer->frame.link); - wl_list_remove(&pointer->link); - - free(pointer); -} - -static void -pointer_handle_motion(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - struct ds_event_pointer_motion *event = data; - struct tinyds_view *view; - struct tinyds_server *server; - int ow = 0, oh = 0; - double sx, sy; - - pointer = wl_container_of(listener, pointer, motion); - - server = pointer->server; - if (server->output) { - ow = server->output->width; - oh = server->output->height; - } - - if (server->output_x + event->delta_x >= ow) - server->output_x = ow; - else if(server->output_x + event->delta_x <= 0.f) - server->output_x = 0.f; - else - server->output_x = server->output_x + event->delta_x ; - if (server->output_y + event->delta_y >= oh) - server->output_y = oh; - else if(server->output_y + event->delta_y <= 0.f) - server->output_y = 0.f; - else - server->output_y = server->output_y + event->delta_y ; - - ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f", - pointer, event->delta_x, event->delta_y, server->output_x, server->output_y); - - view = server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy); - - if (pointer->focused_view != view) { - if (pointer->focused_view) { - ds_inf("Clear pointer focus from view(%p)", pointer->focused_view); - ds_seat_pointer_notify_clear_focus(pointer->server->seat); - pointer->focused_view = NULL; - } - - if (view) { - ds_inf("Set pointer focus to view(%p)", view); - ds_seat_pointer_notify_enter(pointer->server->seat, - ds_xdg_surface_get_surface(view->xdg_surface), sx, sy); - pointer->focused_view = view; - } - } - - if (view) { - ds_seat_pointer_notify_motion(pointer->server->seat, - event->time_msec, sx, sy); - } -} - -static void -pointer_handle_button(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - struct ds_event_pointer_button *event = data; - - pointer = wl_container_of(listener, pointer, button); - - ds_inf("Pointer(%p) button(%d): state(%s) time(%d)", - pointer, event->button, - (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released", - event->time_msec); - - ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state); -} - -static void -pointer_handle_frame(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - - pointer = wl_container_of(listener, pointer, frame); - - ds_inf("Pointer(%p) frame", pointer); - ds_seat_pointer_notify_frame(pointer->server->seat); -} - -static void -server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) -{ - struct tinyds_pointer *pointer; - - pointer = calloc(1, sizeof *pointer); - assert(pointer); - - pointer->dev = dev; - pointer->server = server; - server->output_x = 200; - server->output_y = 200; - - pointer->destroy.notify = pointer_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &pointer->destroy); - - pointer->motion.notify = pointer_handle_motion; - ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev), - &pointer->motion); - - pointer->button.notify = pointer_handle_button; - ds_pointer_add_button_listener(ds_input_device_get_pointer(dev), - &pointer->button); - - pointer->frame.notify = pointer_handle_frame; - ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev), - &pointer->frame); - - pointer->focused_view = NULL; - - wl_list_insert(&server->pointers, &pointer->link); - - ds_inf("Pointer(%p) added", pointer); -} diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 98b9a0a..0abb4b0 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -15,8 +15,18 @@ #include #include #include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define USE_TDM_BUFFER_QUEUE @@ -30,6 +40,8 @@ #include "pixman-helper.h" #define TINYDS_UNUSED __attribute__((unused)) +struct tinyds_keyboard; +struct tinyds_pointer; struct tinyds_output { @@ -71,8 +83,15 @@ struct tinyds_server struct wl_display *display; struct ds_backend *backend; + struct ds_backend *input_backend; struct ds_compositor *compositor; struct ds_xdg_shell *xdg_shell; + struct ds_seat *seat; + 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 tinyds_output *output; struct tinyds_dpms *dpms; @@ -81,7 +100,18 @@ struct tinyds_server struct wl_list views; struct wl_listener new_output; + struct wl_listener new_input; struct wl_listener new_xdg_surface; + struct wl_listener devicemgr_destroy; + struct wl_listener pointer_warp; + struct wl_listener effect_destroy; + struct wl_listener effect_type_set; + struct wl_listener effect_type_unset; + struct wl_listener new_splash; + struct wl_listener splash_owner; + + struct wl_list keyboards; + struct wl_list pointers; }; struct tinyds_view @@ -99,6 +129,44 @@ struct tinyds_view int x, y; bool mapped; + + pid_t pid; + int effect_type; +}; + +struct tinyds_pointer +{ + struct ds_input_device *dev; + struct tinyds_server *server; + + struct tinyds_view *focused_view; + + struct wl_listener destroy; + struct wl_listener motion; //relative + struct wl_listener button; + struct wl_listener frame; + struct wl_list link; //tinyds_server::pointers +}; + +struct tinyds_keyboard +{ + struct ds_input_device *dev; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener key; + struct wl_list link; //tinyds_server::keyboards +}; + +struct tinyds_touch +{ + struct ds_input_device *dev; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener down; + struct wl_listener up; + struct wl_listener motion; }; struct tinyds_server tinyds; @@ -125,7 +193,16 @@ static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); static void dpms_handle_destroy(struct wl_listener *listener, void *data); static void dpms_handle_set_dpms(struct wl_listener *listener, void *data); static void dpms_handle_get_dpms(struct wl_listener *listener, void *data); +static void server_add_keyboard(struct tinyds_server *server, + struct ds_input_device *dev); +static void server_add_pointer(struct tinyds_server *server, + struct ds_input_device *dev); +static void server_add_touch(struct tinyds_server *server, + struct ds_input_device *dev); +static struct tinyds_view * +server_view_at(struct tinyds_server *server, double lx, double ly, + double *sx, double *sy); int main(void) @@ -148,6 +225,7 @@ main(void) assert(socket); ds_backend_start(server->backend); + ds_backend_start(server->input_backend); setenv("WAYLAND_DISPLAY", socket, true); @@ -166,13 +244,47 @@ main(void) } static void +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); + + 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); + 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); + ds_inf("view effect_type(%d)", view->effect_type); +} + +static void view_handle_xdg_surface_map(struct wl_listener *listener, void *data TINYDS_UNUSED) { struct tinyds_view *view; + struct ds_keyboard *keyboard; + struct tinyds_keyboard *kbd; view = wl_container_of(listener, view, xdg_surface_map); view->mapped = true; + + view_populate_pid(view); + + wl_list_for_each(kbd, &view->server->keyboards, link) { + keyboard = ds_input_device_get_keyboard(kbd->dev); + if (keyboard != NULL) { + ds_seat_keyboard_notify_enter(view->server->seat, + ds_xdg_surface_get_surface(view->xdg_surface), + keyboard->keycodes, keyboard->num_keycodes, + &keyboard->modifiers); + return; + } + } } static void @@ -254,6 +366,11 @@ server_new_xdg_surface(struct wl_listener *listener, void *data) view->x = rand() % 1000; view->y = rand() % 500; + + view->pid = 0; + view->effect_type = -1; + + ds_inf("view at (%d, %d)", view->x, view->y); } static void @@ -300,6 +417,8 @@ backend_handle_new_output(struct wl_listener *listener, void *data) output->output_frame.notify = output_handle_frame; ds_output_add_frame_listener(ds_output, &output->output_frame); + ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height); + server->output = output; draw_output(output); @@ -334,6 +453,247 @@ add_new_dpms(struct tinyds_server *server) return true; } +static void +backend_handle_new_input(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct ds_input_device *dev = data; + enum ds_input_device_type dev_type; + + server = wl_container_of(listener, server, new_input); + + dev_type = ds_input_device_get_type(dev); + + switch (dev_type) { + case DS_INPUT_DEVICE_KEYBOARD: + server_add_keyboard(server, dev); + server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD; + break; + case DS_INPUT_DEVICE_TOUCH: + server_add_touch(server, dev); + server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH; + break; + case DS_INPUT_DEVICE_POINTER: + server_add_pointer(server, dev); + server->seat_caps |= WL_SEAT_CAPABILITY_POINTER; + break; + default: + ds_err("Unknown type(%d) of ds_input_device", dev_type); + break; + } + + ds_seat_set_capabilities(server->seat, server->seat_caps); +} + +static void +devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode) +{ + struct ds_tizen_input_devicemgr_keymap_data *data; + + data = calloc(1, sizeof *data); + if (!data) { + ds_err("Failed to alloc memory\n"); + return; + } + + data->name = strdup(name); + data->keycode = keycode; + + wl_list_insert(list, &data->link); +} + +static void +devicemgr_remove_keymap_data(struct wl_list *list, int keycode) +{ + 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); + } + } +} + +static void +devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr) +{ + struct wl_list keymap_list; + bool res; + + wl_list_init(&keymap_list); + + devicemgr_add_keymap_data(&keymap_list, "XF86VolumeRaise", 455); + devicemgr_add_keymap_data(&keymap_list, "XF86VolumeLower", 456); + devicemgr_add_keymap_data(&keymap_list, "XF86LightOn", 457); + devicemgr_add_keymap_data(&keymap_list, "XF86LightOff", 458); + + res = ds_tizen_input_devicemgr_set_keymap_list(devicemgr, &keymap_list); + 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); +} + +static void +devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct tinyds_pointer *pointer; + struct ds_tizen_input_devicemgr_event_pointer_warp *event = data; + double sx = 0.f, sy = 0.f; + struct tinyds_view *view = NULL; + + server = wl_container_of(listener, server, pointer_warp); + + ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface, + event->x, event->y); + + wl_list_for_each(pointer, &server->pointers, link){ + if (!pointer->focused_view) continue; + view = pointer->focused_view; + } + if (!view) return; + + if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) { + ds_inf("Pointer is not on the requested surface"); + return; + } + + server->output_x = view->x + (event->x * server->output->width); + server->output_y = view->y + (event->y * server->output->height); + + server_view_at(server, server->output_x, server->output_y, &sx, &sy); + + ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f", + sx, sy, server->output_x, server->output_y); + + ds_seat_pointer_notify_motion(server->seat, + event->time_msec, sx, sy); +} + +static void +devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_server *server = + wl_container_of(listener, server, devicemgr_destroy); + + wl_list_remove(&server->devicemgr_destroy.link); + wl_list_remove(&server->pointer_warp.link); + + server->devicemgr = NULL; +} + +static void +launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_server *server = + wl_container_of(listener, server, effect_destroy); + + wl_list_remove(&server->effect_destroy.link); + wl_list_remove(&server->effect_type_set.link); + wl_list_remove(&server->effect_type_unset.link); + wl_list_remove(&server->new_splash.link); + + server->effect = NULL; +} + +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 tinyds_view *view = NULL; + bool existing = false; + + server = wl_container_of(listener, server, effect_type_set); + + ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch"); + + wl_list_for_each(view, &server->views, link) { + if (view->pid == event->pid) { + view->effect_type = event->effect_type; + ds_inf("Launch effect. existing pid"); + existing = true; + } + } + if (existing) { + ds_tizen_effect_unset_effect_type(server->effect, event->pid); + } else { + ds_tizen_effect_set_effect_type(server->effect, event->pid, event->effect_type); + } +} + +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 tinyds_view *view = NULL; + + server = wl_container_of(listener, server, effect_type_unset); + + ds_inf("Launch effect. type_unset: pid(%u)", event->pid); + + wl_list_for_each(view, &server->views, link) { + if (view->pid == event->pid) { + view->effect_type = -1; + ds_inf("Launch effect. pid found"); + } + } + ds_tizen_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 tinyds_view *view = NULL; + + server = wl_container_of(listener, server, splash_owner); + + ds_inf("Splash owner. pid(%u)", event->pid); + + wl_list_for_each(view, &server->views, link) { + if (view->pid == event->pid) { + if (event->pid == ds_tizen_splash_get_pid(server->splash)) + ;// + else { + ds_tizen_splash_set_pid(server->splash, event->pid); + } + } + } +} + +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 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; + + server->splash = event->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); + + server->splash_owner.notify = launch_splash_handle_owner; + ds_tizen_splash_add_owner_listener(server->splash, + &server->splash_owner); +} + static bool init_server(struct tinyds_server *server, struct wl_display *display) { @@ -348,38 +708,89 @@ init_server(struct tinyds_server *server, struct wl_display *display) if (!server->backend) return false; + server->input_backend = ds_libinput_backend_create(display); + if (!server->input_backend) { + ds_backend_destroy(server->backend); + return false; + } + server->new_output.notify = backend_handle_new_output; ds_backend_add_new_output_listener(server->backend, &server->new_output); + wl_list_init(&server->keyboards); + wl_list_init(&server->pointers); + server->new_input.notify = backend_handle_new_input; + ds_backend_add_new_input_listener(server->input_backend, &server->new_input); + server->compositor = ds_compositor_create(display); - if (!server->compositor) { - ds_backend_destroy(server->backend); - return false; - } + if (!server->compositor) + goto err; server->tbm_server = ds_tbm_server_create(display); - if (!server->tbm_server) { - ds_backend_destroy(server->backend); - return false; - } + if (!server->tbm_server) + goto err; server->xdg_shell = ds_xdg_shell_create(display); - if (!server->xdg_shell) { - ds_backend_destroy(server->backend); - return false; - } + if (!server->xdg_shell) + goto err; server->new_xdg_surface.notify = server_new_xdg_surface; ds_xdg_shell_add_new_surface_listener(server->xdg_shell, &server->new_xdg_surface); - if (!add_new_dpms(server)) { - ds_backend_destroy(server->backend); - return false; + if (!add_new_dpms(server)) + goto err; + + server->seat = ds_seat_create(display, "seat0" /* arbitrary name */); + if (!server->seat) + goto err; + server->seat_caps = 0; + + server->devicemgr = ds_tizen_input_devicemgr_create( + server->input_backend, server->seat); + if (!server->devicemgr) { + goto err; + } + + devicemgr_set_keymap(server->devicemgr); + + server->devicemgr_destroy.notify = devicemgr_handle_destroy; + ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr, + &server->devicemgr_destroy); + + server->pointer_warp.notify = devicemgr_handle_pointer_warp; + ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr, + &server->pointer_warp); + + server->effect = ds_tizen_effect_create(display); + if (!server->effect) { + goto err; } + server->effect_destroy.notify = launch_effect_handle_destroy; + ds_tizen_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, + &server->effect_type_set); + + server->effect_type_unset.notify = launch_effect_handle_type_unset; + ds_tizen_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, + &server->new_splash); + return true; + +err: + ds_backend_destroy(server->backend); + ds_backend_destroy(server->input_backend); + + return false; } static void @@ -670,3 +1081,382 @@ dpms_handle_get_dpms(struct wl_listener *listener, void *data) ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON, DS_TIZEN_DPMS_ERROR_NONE); } + +static void +keyboard_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + + kbd = wl_container_of(listener, kbd, destroy); + + ds_inf("Keyboard(%p) destroyed", kbd); + + wl_list_remove(&kbd->destroy.link); + wl_list_remove(&kbd->key.link); + wl_list_remove(&kbd->link); + + free(kbd); +} + +static bool +server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) +{ + switch (sym) { + case XKB_KEY_BackSpace: + wl_display_terminate(server->display); + break; + default: + return false; + } + + return true; +} + +static void +keyboard_handle_key(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + struct ds_event_keyboard_key *event = data; + struct ds_keyboard *ds_keyboard; + struct xkb_state *xkb_state; + const xkb_keysym_t *syms; + int nsyms; + bool handled = false; + + kbd = wl_container_of(listener, kbd, key); + + ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), " + "update_state(%d)", kbd->dev, + event->keycode, event->state, event->time_msec, + event->update_state); + + ds_keyboard = ds_input_device_get_keyboard(kbd->dev); + + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); + if (xkb_state) { + nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, + &syms); + for (int i = 0; i < nsyms; i++) { + handled = server_handle_keybinding(kbd->server, syms[i]); + } + } + } + + if (!handled) { + ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec, + event->keycode, event->state); + } +} + +static void +server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_keyboard *kbd; + struct xkb_context *context; + struct xkb_keymap *keymap; + + kbd = calloc(1, sizeof *kbd); + assert(kbd); + + kbd->dev = dev; + kbd->server = server; + + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + 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); + } + + ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap); + + xkb_keymap_unref(keymap); + xkb_context_unref(context); + + kbd->destroy.notify = keyboard_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &kbd->destroy); + + kbd->key.notify = keyboard_handle_key; + ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); + + wl_list_insert(&server->keyboards, &kbd->link); + + ds_inf("Keyboard(%p) added", kbd); +} + +static struct tinyds_view * +server_view_at(struct tinyds_server *server, double lx, double ly, + double *sx, double *sy) +{ + struct tinyds_view *view; + struct ds_surface *surface; + struct ds_buffer *buffer; + int x, y, w = 0, h = 0; + + wl_list_for_each(view, &server->views, link) { + surface = ds_xdg_surface_get_surface(view->xdg_surface); + buffer = ds_surface_get_buffer(surface); + ds_buffer_get_size(buffer, &w, &h); + + x = view->x; + y = view->y; + + if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) { + *sx = lx - x; + *sy = ly - y; + + return view; + } + } + + return NULL; +} + +static void +touch_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_touch *touch; + + touch = wl_container_of(listener, touch, destroy); + + ds_inf("Touch(%p) destroyed", touch); + + wl_list_remove(&touch->destroy.link); + wl_list_remove(&touch->down.link); + wl_list_remove(&touch->up.link); + wl_list_remove(&touch->motion.link); + + free(touch); +} + +static void +touch_handle_down(struct wl_listener *listener, void *data) +{ + struct ds_event_touch_down *event = data; + struct tinyds_touch *touch; + struct tinyds_view *view; + struct tinyds_server *server; + double sx = 0.f, sy = 0.f; + + touch = wl_container_of(listener, touch, down); + + server = touch->server; + server->output_x = event->x * server->output->width; + server->output_y = event->y * server->output->height; + + ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f", + touch->dev, event->id, event->x, event->y, server->output_x, server->output_y); + + view = server_view_at(server, server->output_x, server->output_y, &sx, &sy); + + if (view) { + ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface), + event->time_msec, event->id, sx, sy); + } +} + +static void +touch_handle_up(struct wl_listener *listener, void *data) +{ + struct ds_event_touch_up *event = data; + struct tinyds_touch *touch; + + touch = wl_container_of(listener, touch, up); + + ds_inf("Touch(%p) event up: id(%d) time_msec(%d)", + touch->dev, event->id, event->time_msec); + + ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id); +} + +static void +touch_handle_motion(struct wl_listener *listener, void *data) +{ + struct ds_event_touch_motion *event = data; + struct tinyds_touch *touch; + struct tinyds_view *view; + struct tinyds_server *server; + double sx = 0.f, sy = 0.f; + + touch = wl_container_of(listener, touch, motion); + + server = touch->server; + server->output_x = event->x * server->output->width; + server->output_y = event->y * server->output->height; + + ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f", + touch->dev, event->id, event->x, event->y, server->output_x, server->output_y); + + view = server_view_at(server, server->output_x, server->output_y, &sx, &sy); + + if (view) { + ds_seat_touch_notify_motion(server->seat, event->time_msec, + event->id, sx, sy); + } +} + +static void +server_add_touch(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_touch *touch; + + touch = calloc(1, sizeof *touch); + assert(touch); + + touch->dev = dev; + touch->server = server; + + touch->destroy.notify = touch_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &touch->destroy); + + touch->down.notify = touch_handle_down; + ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down); + + touch->up.notify = touch_handle_up; + ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up); + + touch->motion.notify = touch_handle_motion; + ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion); + + ds_inf("Touch(%p) added", touch); +} + +static void +pointer_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + + pointer = wl_container_of(listener, pointer, destroy); + + ds_inf("Pointer(%p) destroyed", pointer); + + wl_list_remove(&pointer->destroy.link); + wl_list_remove(&pointer->motion.link); + wl_list_remove(&pointer->button.link); + wl_list_remove(&pointer->frame.link); + wl_list_remove(&pointer->link); + + free(pointer); +} + +static void +pointer_handle_motion(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + struct ds_event_pointer_motion *event = data; + struct tinyds_view *view; + struct tinyds_server *server; + int ow = 0, oh = 0; + double sx, sy; + + pointer = wl_container_of(listener, pointer, motion); + + server = pointer->server; + if (server->output) { + ow = server->output->width; + oh = server->output->height; + } + + if (server->output_x + event->delta_x >= ow) + server->output_x = ow; + else if(server->output_x + event->delta_x <= 0.f) + server->output_x = 0.f; + else + server->output_x = server->output_x + event->delta_x ; + if (server->output_y + event->delta_y >= oh) + server->output_y = oh; + else if(server->output_y + event->delta_y <= 0.f) + server->output_y = 0.f; + else + server->output_y = server->output_y + event->delta_y ; + + ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f", + pointer, event->delta_x, event->delta_y, server->output_x, server->output_y); + + view = server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy); + + if (pointer->focused_view != view) { + if (pointer->focused_view) { + ds_inf("Clear pointer focus from view(%p)", pointer->focused_view); + ds_seat_pointer_notify_clear_focus(pointer->server->seat); + pointer->focused_view = NULL; + } + + if (view) { + ds_inf("Set pointer focus to view(%p)", view); + ds_seat_pointer_notify_enter(pointer->server->seat, + ds_xdg_surface_get_surface(view->xdg_surface), sx, sy); + pointer->focused_view = view; + } + } + + if (view) { + ds_seat_pointer_notify_motion(pointer->server->seat, + event->time_msec, sx, sy); + } +} + +static void +pointer_handle_button(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + struct ds_event_pointer_button *event = data; + + pointer = wl_container_of(listener, pointer, button); + + ds_inf("Pointer(%p) button(%d): state(%s) time(%d)", + pointer, event->button, + (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released", + event->time_msec); + + ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state); +} + +static void +pointer_handle_frame(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + + pointer = wl_container_of(listener, pointer, frame); + + ds_inf("Pointer(%p) frame", pointer); + ds_seat_pointer_notify_frame(pointer->server->seat); +} + +static void +server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_pointer *pointer; + + pointer = calloc(1, sizeof *pointer); + assert(pointer); + + pointer->dev = dev; + pointer->server = server; + server->output_x = 200; + server->output_y = 200; + + pointer->destroy.notify = pointer_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &pointer->destroy); + + pointer->motion.notify = pointer_handle_motion; + ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev), + &pointer->motion); + + pointer->button.notify = pointer_handle_button; + ds_pointer_add_button_listener(ds_input_device_get_pointer(dev), + &pointer->button); + + pointer->frame.notify = pointer_handle_frame; + ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev), + &pointer->frame); + + pointer->focused_view = NULL; + + wl_list_insert(&server->pointers, &pointer->link); + + ds_inf("Pointer(%p) added", pointer); +} diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 1ab1978..ceb30a2 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -338,7 +338,6 @@ ninja -C builddir install %{_includedir}/libds-tizen/input_devicemgr.h %{_libdir}/pkgconfig/libds-tizen-input-devicemgr.pc %{_libdir}/libds-tizen-input-devicemgr.so -%{_bindir}/tinyds-tdm-libinput %{_bindir}/input-generator %files dpms -- 2.7.4 From 6493d93fb983f8e753bb13240b05841e2aa0d7b0 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 8 Aug 2022 10:40:04 +0900 Subject: [PATCH 11/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 12/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 13/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 14/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 15/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 16/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