From 17e22931b61836f3d4e6f829d0eb92346de638a8 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Wed, 26 Oct 2022 16:04:21 +0900 Subject: [PATCH] implement ds_tizen_remote_surface This is the server implementation for tizen_remote_surface protocol. Change-Id: I96bfae99814b9ac9331f510c5f378ed2a5c56c7e --- include/libds-tizen/remote_surface.h | 317 ++++++++ packaging/libds-tizen.spec | 32 + src/meson.build | 1 + src/remote_surface/meson.build | 30 + src/remote_surface/remote_surface.c | 1309 ++++++++++++++++++++++++++++++++++ tests/meson.build | 19 + tests/mockclient.cpp | 5 + tests/mockclient.h | 1 + tests/tc_remote_surface.cpp | 815 +++++++++++++++++++++ 9 files changed, 2529 insertions(+) create mode 100644 include/libds-tizen/remote_surface.h create mode 100644 src/remote_surface/meson.build create mode 100644 src/remote_surface/remote_surface.c create mode 100644 tests/tc_remote_surface.cpp diff --git a/include/libds-tizen/remote_surface.h b/include/libds-tizen/remote_surface.h new file mode 100644 index 0000000..7e8cf2c --- /dev/null +++ b/include/libds-tizen/remote_surface.h @@ -0,0 +1,317 @@ +#ifndef LIBDS_TIZEN_REMOTE_SURFACE_H +#define LIBDS_TIZEN_REMOTE_SURFACE_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum ds_tizen_remote_surface_visibility_type { + DS_TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_INVISIBLE = 0, + DS_TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE = 1, +}; + +enum ds_tizen_remote_surface_input_event_type { + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_NONE = 0, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_MOUSE_DOWN = 1, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_MOUSE_UP = 2, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_MOUSE_MOVE = 3, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_TOUCH_DOWN = 4, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_TOUCH_UP = 5, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_TOUCH_MOVE = 6, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_KEY_DOWN = 7, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_KEY_UP = 8, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_MOUSE_IN = 9, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_MOUSE_OUT = 10, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_TYPE_KEY_CANCEL = 11, +}; + +enum ds_tizen_remote_surface_input_event_filter { + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_NONE = 0x00000001, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_UP_DOWN = 0x00000002, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_MOVE_X = 0x00000003, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_MOVE_Y = 0x00000004, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_MOVE_X_Y = 0x00000005, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_UP_DOWN_MOVE_X = 0x00000006, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_UP_DOWN_MOVE_Y = 0x00000007, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_UP_DOWN_MOVE_X_Y = 0x00000008, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_ALL = 0x0000000e, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_FLAG = 0x0000000f, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_WHEEL_NONE = 0x00000010, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_WHEEL_ALL = 0x000000e0, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_MOUSE_WHEEL_FLAG = 0x000000f0, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_NONE = 0x00000100, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_UP_DOWN = 0x00000200, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_MOVE_X = 0x00000300, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_MOVE_Y = 0x00000400, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_MOVE_X_Y = 0x00000500, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_UP_DOWN_MOVE_X = 0x00000600, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_UP_DOWN_MOVE_Y = 0x00000700, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_UP_DOWN_MOVE_X_Y = 0x00000800, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_ALL = 0x00000e00, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_FLAG = 0x00000f00, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_CANCEL_NONE = 0x00001000, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_CANCEL_ALL = 0x0000e000, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_TOUCH_CANCEL_FLAG = 0x0000f000, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_KEY_NONE = 0x00010000, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_KEY_ALL = 0x000e0000, + DS_TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILITER_KEY_FLAG = 0x000f0000, +}; + +enum ds_tizen_remote_surface_buffer_type { + DS_TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM = 0, + DS_TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE = 1, +}; + +enum ds_tizen_remote_surface_changed_buffer_event_filter { + DS_TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_NONE = 0x00000000, + DS_TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM = 0x00000001, + DS_TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE = 0x00000002, +}; + +struct ds_tizen_remote_surface_manager_bind_surface_event { + struct ds_tizen_remote_surface *remote_surface; + struct ds_surface *surface; +}; + +struct ds_tizen_remote_surface_transfer_mouse_event { + struct ds_tizen_remote_surface *remote_surface; + enum ds_tizen_remote_surface_input_event_type event_type; + int32_t device; + int32_t button; + int32_t x; + int32_t y; + wl_fixed_t radius_x; + wl_fixed_t radius_y; + wl_fixed_t pressure; + wl_fixed_t angle; + uint32_t clas; + uint32_t subclas; + const char *identifier; + uint32_t time; +}; + +struct ds_tizen_remote_surface_transfer_mouse_wheel_event { + struct ds_tizen_remote_surface *remote_surface; + uint32_t direction; + int32_t z; + uint32_t clas; + uint32_t subclas; + const char *identifier; + uint32_t time; +}; + +struct ds_tizen_remote_surface_transfer_touch_event { + struct ds_tizen_remote_surface *remote_surface; + enum ds_tizen_remote_surface_input_event_type event_type; + int32_t device; + int32_t button; + int32_t x; + int32_t y; + wl_fixed_t radius_x; + wl_fixed_t radius_y; + wl_fixed_t pressure; + wl_fixed_t angle; + uint32_t clas; + uint32_t subclas; + const char *identifier; + uint32_t time; +}; + +struct ds_tizen_remote_surface_transfer_touch_cancel_event { + struct ds_tizen_remote_surface *remote_surface; +}; + +struct ds_tizen_remote_surface_transfer_key_event { + struct ds_tizen_remote_surface *remote_surface; + enum ds_tizen_remote_surface_input_event_type event_type; + int32_t keycode; + uint32_t clas; + uint32_t subclas; + const char *identifier; + uint32_t time; +}; + +struct ds_tizen_remote_surface_transfer_visibility_event { + struct ds_tizen_remote_surface *remote_surface; + enum ds_tizen_remote_surface_visibility_type visibility; +}; + +struct ds_tizen_remote_surface_buffer_release_event { + struct ds_tizen_remote_surface *remote_surface; + struct ds_buffer *buffer; +}; + +struct ds_tizen_remote_surface_current_buffer_event { + struct ds_tizen_remote_surface *remote_surface; + enum ds_tizen_remote_surface_buffer_type buffer_type; + uint32_t request_serial; +}; + +struct ds_tizen_remote_surface_manager; + +struct ds_tizen_remote_surface_provider; + +struct ds_tizen_remote_surface; + +struct ds_tizen_remote_surface_region; + +struct ds_tizen_remote_surface_manager * +ds_tizen_remote_surface_manager_create(struct wl_display *display); + +void +ds_tizen_remote_surface_manager_add_destroy_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_manager_add_new_provider_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_manager_add_new_surface_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_manager_add_bind_surface_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_provider_add_destroy_listener( + struct ds_tizen_remote_surface_provider *remote_provider, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_provider_add_set_offscreen_listener( + struct ds_tizen_remote_surface_provider *remote_provider, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_provider_add_set_input_event_filter_listener( + struct ds_tizen_remote_surface_provider *remote_provider, + struct wl_listener *listener); + +bool +ds_tizen_remote_surface_provider_get_offscreen( + struct ds_tizen_remote_surface_provider *remote_provider); + +uint32_t +ds_tizen_remote_surface_provider_get_input_event_filter( + struct ds_tizen_remote_surface_provider *remote_provider); + +void +ds_tizen_remote_surface_provider_send_visibility( + struct ds_tizen_remote_surface_provider *remote_provider, + enum ds_tizen_remote_surface_visibility_type visibility); + +void +ds_tizen_remote_surface_add_destroy_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +struct wl_resource * +ds_tizen_remote_surface_get_wl_tbm_resource( + struct ds_tizen_remote_surface *remote_surface); + +void +ds_tizen_remote_surface_add_set_redirect_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +bool +ds_tizen_remote_surface_get_redirect( + struct ds_tizen_remote_surface *remote_surface); + +void +ds_tizen_remote_surface_add_set_owner_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +struct ds_surface * +ds_tizen_remote_surface_get_owner( + struct ds_tizen_remote_surface *remote_surface); + +void +ds_tizen_remote_surface_add_buffer_release_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_add_set_remote_render_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +bool +ds_tizen_remote_surface_get_remote_render( + struct ds_tizen_remote_surface *remote_surface); + +void +ds_tizen_remote_surface_add_set_changed_buffer_event_filter_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +uint32_t +ds_tizen_remote_surface_get_changed_buffer_event_filter( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_add_get_current_buffer_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_send_changed_buffer( + struct ds_tizen_remote_surface *remote_surface, + struct ds_buffer *buffer, + uint32_t time, + struct wl_array *options); + +void +ds_tizen_remote_surface_send_changed_buffer_image_file( + struct ds_tizen_remote_surface *remote_surface, + int image_file_fd, + int image_file_size, + uint32_t time, + struct wl_array *options); + +void +ds_tizen_remote_surface_send_missing( + struct ds_tizen_remote_surface *remote_surface); + +void +ds_tizen_remote_surface_send_input_event_filter( + struct ds_tizen_remote_surface *remote_surface, + uint32_t input_event_filter); + +void +ds_tizen_remote_surface_add_new_region_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_region_add_destroy_listener( + struct ds_tizen_remote_surface_region *remote_region, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_region_add_set_geometry_listener( + struct ds_tizen_remote_surface_region *remote_region, + struct wl_listener *listener); + +void +ds_tizen_remote_surface_region_get_geometry( + struct ds_tizen_remote_surface_region *remote_region, + int32_t *x,int32_t *y, int32_t *w, int32_t *h); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 838a569..c4bfb93 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -34,6 +34,8 @@ BuildRequires: pkgconfig(tizen-surface-server) BuildRequires: pkgconfig(tizen-surface-client) BuildRequires: pkgconfig(tizen-hwc-server) BuildRequires: pkgconfig(tizen-hwc-client) +BuildRequires: pkgconfig(tizen-remote-surface-server) +BuildRequires: pkgconfig(tizen-remote-surface-client) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(libsmack) @@ -391,6 +393,21 @@ Group: Development/Libraries %description eom-devel Development package for tizen eom +## libds-tizen-remote-surface +%package remote-surface +Summary: Library for tizen remote-surface +Group: Development/Libraries + +%description remote-surface +Library for tizen remote-surface + +%package remote-surface-devel +Summary: Development package for tizen remote surface +Group: Development/Libraries + +%description remote-surface-devel +Development package for tizen remote surface + %prep %setup -q cp %{SOURCE1001} . @@ -754,3 +771,18 @@ ninja -C builddir install %{_includedir}/libds-tizen/eom.h %{_libdir}/pkgconfig/libds-tizen-eom.pc %{_libdir}/libds-tizen-eom.so + +%files remote-surface +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-remote-surface.so* + +%files remote-surface-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/remote_surface.h +%{_libdir}/pkgconfig/libds-tizen-remote-surface.pc +%{_libdir}/libds-tizen-remote-surface.so* +%{_bindir}/libds-tizen-remote-surface-tests diff --git a/src/meson.build b/src/meson.build index 4ec2cd6..d0c0e13 100644 --- a/src/meson.build +++ b/src/meson.build @@ -55,3 +55,4 @@ subdir('screenshooter') subdir('scaler') subdir('video') subdir('eom') +subdir('remote_surface') diff --git a/src/remote_surface/meson.build b/src/remote_surface/meson.build new file mode 100644 index 0000000..f087a2e --- /dev/null +++ b/src/remote_surface/meson.build @@ -0,0 +1,30 @@ +libds_tizen_remote_surface_files = [ + 'remote_surface.c', +] + +libds_tizen_remote_surface_deps = [ + deps_libds_tizen, + deps_libds_tizen_tbm_server, + dependency('tizen-remote-surface-server', required: true), +] + +lib_libds_tizen_remote_surface = shared_library('ds-tizen-remote-surface', libds_tizen_remote_surface_files, + dependencies: libds_tizen_remote_surface_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_remote_surface = declare_dependency( + link_with: lib_libds_tizen_remote_surface, + dependencies: libds_tizen_remote_surface_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_remote_surface, + version: meson.project_version(), + filebase: 'libds-tizen-remote-surface', + name: 'libds-tizen-remote-surface', + description: 'tizen remote surface extension of libds-tizen for tizen platform', +) diff --git a/src/remote_surface/remote_surface.c b/src/remote_surface/remote_surface.c new file mode 100644 index 0000000..a16e34c --- /dev/null +++ b/src/remote_surface/remote_surface.c @@ -0,0 +1,1309 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "libds-tizen/remote_surface.h" +#include + +#define TIZEN_REMOTE_SURFACE_VERSION 6 + +static uint32_t resource_id = 1; + +struct ds_tizen_remote_surface_manager +{ + struct wl_global *global; + + struct wl_listener destroy; + + struct wl_list remote_providers; + struct wl_list remote_surfaces; + + struct { + struct wl_signal destroy; + struct wl_signal new_provider; + struct wl_signal new_surface; + struct wl_signal bind_surface; + } events; +}; + +struct ds_tizen_remote_surface_client +{ + struct ds_tizen_remote_surface_manager *remote_manager; + + struct wl_resource *resource; + struct wl_client *wl_client; + + struct { + struct wl_listener surface_destroy; + } listener; + + struct { + struct wl_signal destroy; + } events; +}; + +struct ds_tizen_remote_surface_provider +{ + struct wl_list link; + + struct wl_resource *resource; + + struct ds_surface *surface; + + uint32_t input_event_filter; + uint32_t offscreen; + + unsigned int resource_id; + + struct { + struct wl_listener surface_destroy; + } listener; + + struct { + struct wl_signal destroy; + struct wl_signal set_offscreen; + struct wl_signal set_input_event_filter; + } events; +}; + +struct ds_tizen_remote_surface +{ + struct wl_list link; + + struct wl_resource *resource; + + struct ds_surface *surface; + + struct wl_resource *wl_tbm_resource; + + bool redirect; + struct ds_surface *owner_surface; + bool remote_render; + uint32_t changed_buffer_event_filter; + + struct { + struct wl_listener surface_destroy; + struct wl_listener owner_surface_destroy; + struct wl_listener wl_tbm_resource_destroy; + } listener; + + struct { + struct wl_signal destroy; + struct wl_signal set_redirect; + struct wl_signal transfer_mouse_event; + struct wl_signal transfer_mouse_wheel_event; + struct wl_signal transfer_touch_event; + struct wl_signal transfer_touch_cancel_event; + struct wl_signal transfer_key_event; + struct wl_signal transfer_visibility_event; + struct wl_signal set_owner; + struct wl_signal new_region; + struct wl_signal buffer_release; + struct wl_signal set_remote_render; + struct wl_signal set_changed_buffer_event_filter; + struct wl_signal get_current_buffer; + } events; +}; + +struct ds_tizen_remote_surface_region +{ + struct wl_resource *resource; + + int32_t x; + int32_t y; + int32_t w; + int32_t h; + + struct { + struct wl_signal destroy; + struct wl_signal set_geometry; + } events; +}; + +static int +remote_surface_dummy_fd_get(void) +{ + static const char template[] = "/libds_rsm_dummy_fdXXXXXX"; + const char *path; + char *name; + size_t name_size; + long flags; + static int fd = -1; + + if (fd >= 0) + return fd; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) { + ds_err("fail to get XDG_RUNTIME_DIR"); + return -1; + } + + name_size = strlen(path) + sizeof(template); + name = malloc(name_size); + if (!name) { + ds_err("malloc() failed"); + return -1; + } + + snprintf(name, name_size, "%s%s", path, template); + fd = mkstemp(name); + if (fd < 0) { + ds_err("mkstemp() failed"); + free(name); + return -1; + } + + flags = fcntl(fd, F_GETFD); + if (flags == -1) { + ds_err("fcntl(F_GETFD) failed"); + unlink(name); + free(name); + return -1; + } + + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + ds_err("fcntl(F_SETFD, FD_CLOEXEC) failed"); + unlink(name); + free(name); + return -1; + } + + unlink(name); + free(name); + + return fd; +} + +static void +remote_surface_provider_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +remote_surface_provider_handle_set_offscreen(struct wl_client *wl_client, + struct wl_resource *provider_resource, uint32_t offscreen) +{ + struct ds_tizen_remote_surface_provider *remote_provider; + + remote_provider = wl_resource_get_user_data(provider_resource); + + if (remote_provider->offscreen == offscreen) + return; + + remote_provider->offscreen = offscreen; + + wl_signal_emit(&remote_provider->events.set_offscreen, remote_provider); +} + +static void +remote_surface_provider_handle_set_input_event_filter(struct wl_client *wl_client, + struct wl_resource *provider_resource, uint32_t event_filter) +{ + struct ds_tizen_remote_surface_provider *remote_provider; + + remote_provider = wl_resource_get_user_data(provider_resource); + + if (remote_provider->input_event_filter == event_filter) + return; + + remote_provider->input_event_filter = event_filter; + + wl_signal_emit(&remote_provider->events.set_input_event_filter, remote_provider); +} + +static const struct tizen_remote_surface_provider_interface remote_surface_provider_impl = +{ + .destroy = remote_surface_provider_handle_destroy, + .offscreen_set = remote_surface_provider_handle_set_offscreen, + .set_input_event_filter = remote_surface_provider_handle_set_input_event_filter, +}; + +static void +remote_surface_provider_handle_surface_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_remote_surface_provider *remote_provider; + + remote_provider = wl_container_of(listener, remote_provider, listener.surface_destroy); + + if (remote_provider->listener.surface_destroy.notify) { + wl_list_remove(&remote_provider->listener.surface_destroy.link); + remote_provider->listener.surface_destroy.notify = NULL; + } + + remote_provider->surface = NULL; +} + +static void +remote_surface_provider_handle_resource_destroy(struct wl_resource *remote_provider_resource) +{ + struct ds_tizen_remote_surface_provider *remote_provider; + + remote_provider = wl_resource_get_user_data(remote_provider_resource); + + ds_inf("remote_surface_provider:%p destroy", remote_provider); + + if (remote_provider->listener.surface_destroy.notify) { + wl_list_remove(&remote_provider->listener.surface_destroy.link); + remote_provider->listener.surface_destroy.notify = NULL; + } + + wl_list_remove(&remote_provider->link); + + wl_signal_emit(&remote_provider->events.destroy, remote_provider); + + free(remote_provider); +} + +static void +remote_surface_manager_handle_create_provider(struct wl_client *wl_client, + struct wl_resource *remote_surface_client_resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + struct ds_tizen_remote_surface_client *remote_client; + struct ds_tizen_remote_surface_provider *remote_provider; + struct ds_surface *surface; + + remote_client = wl_resource_get_user_data(remote_surface_client_resource); + surface = ds_surface_from_resource(surface_resource); + + remote_provider = calloc(1, sizeof *remote_provider); + if (!remote_provider) { + wl_client_post_no_memory(wl_client); + return; + } + + remote_provider->resource = wl_resource_create(wl_client, &tizen_remote_surface_provider_interface, + wl_resource_get_version(remote_client->resource), id); + if (!remote_provider->resource) { + wl_client_post_no_memory(wl_client); + free(remote_provider); + return; + } + + remote_provider->listener.surface_destroy.notify = remote_surface_provider_handle_surface_destroy; + ds_surface_add_destroy_listener(surface, &remote_provider->listener.surface_destroy); + remote_provider->surface = surface; + + wl_resource_set_implementation(remote_provider->resource, &remote_surface_provider_impl, + remote_provider, remote_surface_provider_handle_resource_destroy); + + ds_inf("remote_surface_provider:%p create", remote_provider); + + wl_signal_init(&remote_provider->events.destroy); + wl_signal_init(&remote_provider->events.set_offscreen); + wl_signal_init(&remote_provider->events.set_input_event_filter); + + wl_signal_emit(&remote_client->remote_manager->events.new_provider, remote_provider); + + remote_provider->resource_id = resource_id++; + + tizen_remote_surface_provider_send_resource_id(remote_provider->resource, remote_provider->resource_id); + + wl_list_insert(&remote_client->remote_manager->remote_providers, &remote_provider->link); +} + +static void +remote_surface_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +remote_surface_handle_redirect(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + remote_surface->redirect = true; + + wl_signal_emit(&remote_surface->events.set_redirect, remote_surface); +} + +static void +remote_surface_handle_unredirect(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + remote_surface->redirect = false; + + wl_signal_emit(&remote_surface->events.set_redirect, remote_surface); +} + +static void +remote_surface_handle_transfer_mouse_event(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + uint32_t event_type, int32_t device, int32_t button, + int32_t x, int32_t y, wl_fixed_t radius_x, wl_fixed_t radius_y, + wl_fixed_t pressure, wl_fixed_t angle, uint32_t clas, uint32_t subclas, + const char *identifier, uint32_t time) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_transfer_mouse_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + event.remote_surface = remote_surface; + event.event_type = event_type; + event.device = device; + event.button = button; + event.x = x; + event.y = y; + event.radius_x = radius_x; + event.radius_y = radius_y; + event.pressure = pressure; + event.angle = angle; + event.clas = clas; + event.subclas = subclas; + event.identifier = identifier; + event.time = time; + + wl_signal_emit(&remote_surface->events.transfer_mouse_event, &event); +} + +static void +remote_surface_handle_transfer_mouse_wheel(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + uint32_t direction, int32_t z, uint32_t clas, uint32_t subclas, + const char *identifier, uint32_t time) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_transfer_mouse_wheel_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + event.remote_surface = remote_surface; + event.direction = direction; + event.z = z; + event.clas = clas; + event.subclas = subclas; + event.identifier = identifier; + event.time = time; + + wl_signal_emit(&remote_surface->events.transfer_mouse_wheel_event, &event); +} + +static void +remote_surface_handle_transfer_touch_event(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + uint32_t event_type, int32_t device, int32_t button, int32_t x, int32_t y, + wl_fixed_t radius_x, wl_fixed_t radius_y, wl_fixed_t pressure, wl_fixed_t angle, + uint32_t clas, uint32_t subclas, const char *identifier, uint32_t time) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_transfer_touch_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + event.remote_surface = remote_surface; + event.event_type = event_type; + event.device = device; + event.button = button; + event.x = x; + event.y = y; + event.radius_x = radius_x; + event.radius_y = radius_y; + event.pressure = pressure; + event.angle = angle; + event.clas = clas; + event.subclas = subclas; + event.identifier = identifier; + event.time = time; + + wl_signal_emit(&remote_surface->events.transfer_touch_event, &event); +} + +static void +remote_surface_handle_transfer_touch_cancel(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_transfer_touch_cancel_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + event.remote_surface = remote_surface; + + wl_signal_emit(&remote_surface->events.transfer_touch_cancel_event, &event); +} + +static void +remote_surface_handle_transfer_key_event(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + uint32_t event_type, int32_t keycode, uint32_t clas, uint32_t subclas, + const char *identifier, uint32_t time) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_transfer_key_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + event.remote_surface = remote_surface; + event.event_type = event_type; + event.keycode = keycode; + event.clas = clas; + event.subclas = subclas; + event.identifier = identifier; + event.time = time; + + wl_signal_emit(&remote_surface->events.transfer_key_event, &event); +} + +static void +remote_surface_handle_transfer_visibility(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + uint32_t visibility_type) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_transfer_visibility_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + event.remote_surface = remote_surface; + event.visibility = visibility_type; + + wl_signal_emit(&remote_surface->events.transfer_visibility_event, &event); +} + +static void +remote_surface_handle_owner_surface_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_container_of(listener, remote_surface, listener.surface_destroy); + + if (remote_surface->listener.owner_surface_destroy.notify) { + wl_list_remove(&remote_surface->listener.owner_surface_destroy.link); + remote_surface->listener.owner_surface_destroy.notify = NULL; + } + + remote_surface->owner_surface = NULL; +} + +static void +remote_surface_handle_set_owner(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_surface *surface; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + surface = ds_surface_from_resource(surface_resource); + + remote_surface->listener.owner_surface_destroy.notify = remote_surface_handle_owner_surface_destroy; + ds_surface_add_destroy_listener(surface, &remote_surface->listener.owner_surface_destroy); + remote_surface->owner_surface = surface; + + wl_signal_emit(&remote_surface->events.set_owner, remote_surface); +} + +static void +remote_region_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +remote_region_handle_set_geometry(struct wl_client *wl_client, + struct wl_resource *remote_region_resource, + int32_t x, int32_t y, int32_t w, int32_t h) +{ + struct ds_tizen_remote_surface_region *remote_region; + + remote_region = wl_resource_get_user_data(remote_region_resource); + + remote_region->x = x; + remote_region->y = y; + remote_region->w = w; + remote_region->h = h; + + wl_signal_emit(&remote_region->events.set_geometry, remote_region); +} + +static const struct tizen_remote_surface_region_interface remote_surface_region_impl = +{ + .destroy = remote_region_handle_destroy, + .set_geometry = remote_region_handle_set_geometry, +}; + +static void +remote_surface_region_handle_resource_destroy(struct wl_resource *remote_region_resource) +{ + struct ds_tizen_remote_surface_region *remote_region; + + remote_region = wl_resource_get_user_data(remote_region_resource); + + ds_inf("remote_region:%p destroy", remote_region); + + wl_signal_emit(&remote_region->events.destroy, remote_region); + + free(remote_region); +} + +static void +remote_surface_handle_create_region(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + uint32_t id) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_region *remote_region; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + remote_region = calloc(1, sizeof *remote_region); + if (!remote_region) { + wl_client_post_no_memory(wl_client); + return; + } + + remote_region->resource = wl_resource_create(wl_client, &tizen_remote_surface_region_interface, + 1, id); + if (!remote_region->resource) { + wl_client_post_no_memory(wl_client); + free(remote_region); + return; + } + + wl_resource_set_implementation(remote_region->resource, &remote_surface_region_impl, + remote_region, remote_surface_region_handle_resource_destroy); + + ds_inf("remote_surface_region:%p create", remote_region); + + wl_signal_init(&remote_region->events.destroy); + wl_signal_init(&remote_region->events.set_geometry); + + wl_signal_emit(&remote_surface->events.new_region, remote_region); +} + +static void +remote_surface_handle_release(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + struct wl_resource *remote_buffer_resource) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_buffer *buffer; + struct ds_tizen_remote_surface_buffer_release_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + buffer = ds_buffer_from_resource(remote_buffer_resource); + + event.remote_surface = remote_surface; + event.buffer = buffer; + + wl_signal_emit(&remote_surface->events.buffer_release, &event); +} + +static void +remote_surface_handle_set_remote_render(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + uint32_t set) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + if (set > 0) + remote_surface->remote_render = true; + else + remote_surface->remote_render = false; + + wl_signal_emit(&remote_surface->events.set_remote_render, remote_surface); +} + +static void +remote_surface_handle_set_changed_buffer_event_filter(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + enum tizen_remote_surface_changed_buffer_event_filter filter) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + remote_surface->changed_buffer_event_filter = filter; + + wl_signal_emit(&remote_surface->events.set_changed_buffer_event_filter, remote_surface); +} + +static void +remote_surface_handle_get_current_buffer(struct wl_client *wl_client, + struct wl_resource *remote_surface_resource, + enum tizen_remote_surface_buffer_type buff_type, + uint32_t req_serial) +{ + struct ds_tizen_remote_surface *remote_surface; + struct ds_tizen_remote_surface_current_buffer_event event; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + event.remote_surface = remote_surface; + event.buffer_type = buff_type; + event.request_serial = req_serial; + + wl_signal_emit(&remote_surface->events.get_current_buffer, &event); +} + +static const struct tizen_remote_surface_interface remote_surface_impl = +{ + .destroy = remote_surface_handle_destroy, + .redirect = remote_surface_handle_redirect, + .unredirect = remote_surface_handle_unredirect, + .transfer_mouse_event = remote_surface_handle_transfer_mouse_event, + .transfer_mouse_wheel = remote_surface_handle_transfer_mouse_wheel, + .transfer_touch_event = remote_surface_handle_transfer_touch_event, + .transfer_touch_cancel = remote_surface_handle_transfer_touch_cancel, + .transfer_key_event = remote_surface_handle_transfer_key_event, + .transfer_visibility = remote_surface_handle_transfer_visibility, + .set_owner = remote_surface_handle_set_owner, + .create_region = remote_surface_handle_create_region, + .release = remote_surface_handle_release, + .set_remote_render = remote_surface_handle_set_remote_render, + .set_changed_buffer_event_filter = remote_surface_handle_set_changed_buffer_event_filter, + .get_current_buffer = remote_surface_handle_get_current_buffer, +}; + +static void +remote_surface_handle_surface_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_container_of(listener, remote_surface, listener.surface_destroy); + + if (remote_surface->listener.surface_destroy.notify) { + wl_list_remove(&remote_surface->listener.surface_destroy.link); + remote_surface->listener.surface_destroy.notify = NULL; + } + + remote_surface->surface = NULL; +} + +static void +remote_surface_handle_wl_tbm_resource_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_container_of(listener, remote_surface, listener.wl_tbm_resource_destroy); + + if (remote_surface->listener.wl_tbm_resource_destroy.notify) { + wl_list_remove(&remote_surface->listener.wl_tbm_resource_destroy.link); + remote_surface->listener.wl_tbm_resource_destroy.notify = NULL; + } + + remote_surface->wl_tbm_resource = NULL; +} + +static void +remote_surface_handle_resource_destroy(struct wl_resource *remote_surface_resource) +{ + struct ds_tizen_remote_surface *remote_surface; + + remote_surface = wl_resource_get_user_data(remote_surface_resource); + + ds_inf("remote_surface:%p destroy", remote_surface); + + if (remote_surface->listener.surface_destroy.notify) { + wl_list_remove(&remote_surface->listener.surface_destroy.link); + remote_surface->listener.surface_destroy.notify = NULL; + } + + if (remote_surface->listener.owner_surface_destroy.notify) { + wl_list_remove(&remote_surface->listener.owner_surface_destroy.link); + remote_surface->listener.owner_surface_destroy.notify = NULL; + } + + wl_list_remove(&remote_surface->link); + + wl_signal_emit(&remote_surface->events.destroy, remote_surface); + + free(remote_surface); +} + +static void +remote_surface_manager_handle_create_surface(struct wl_client *wl_client, + struct wl_resource *remote_surface_client_resource, + uint32_t id, + uint32_t resource_id, + struct wl_resource *wl_tbm_resource) +{ + struct ds_tizen_remote_surface_client *remote_client; + struct ds_tizen_remote_surface *remote_surface; + struct ds_surface *surface = NULL; + struct ds_tizen_remote_surface_provider *remote_provider; + + remote_client = wl_resource_get_user_data(remote_surface_client_resource); + + wl_list_for_each(remote_provider, &remote_client->remote_manager->remote_providers, link) { + if (remote_provider->resource_id == resource_id) { + surface = remote_provider->surface; + break; + } + } + + if (!surface) { + ds_err("fail to find ds_surface from resource_id:%d", resource_id); + return; + } + + remote_surface = calloc(1, sizeof *remote_surface); + if (!remote_surface) { + wl_client_post_no_memory(wl_client); + return; + } + + remote_surface->resource = wl_resource_create(wl_client, &tizen_remote_surface_interface, + wl_resource_get_version(remote_client->resource), id); + if (!remote_surface->resource) { + wl_client_post_no_memory(wl_client); + free(remote_surface); + return; + } + + remote_surface->listener.surface_destroy.notify = remote_surface_handle_surface_destroy; + ds_surface_add_destroy_listener(surface, &remote_surface->listener.surface_destroy); + remote_surface->surface = surface; + + remote_surface->listener.wl_tbm_resource_destroy.notify = remote_surface_handle_wl_tbm_resource_destroy; + wl_resource_add_destroy_listener(wl_tbm_resource, &remote_surface->listener.wl_tbm_resource_destroy); + remote_surface->wl_tbm_resource = wl_tbm_resource; + + wl_resource_set_implementation(remote_surface->resource, &remote_surface_impl, + remote_surface, remote_surface_handle_resource_destroy); + + ds_inf("remote_surface:%p create", remote_surface); + + wl_signal_init(&remote_surface->events.destroy); + wl_signal_init(&remote_surface->events.set_redirect); + wl_signal_init(&remote_surface->events.transfer_mouse_event); + wl_signal_init(&remote_surface->events.transfer_mouse_wheel_event); + wl_signal_init(&remote_surface->events.transfer_touch_event); + wl_signal_init(&remote_surface->events.transfer_touch_cancel_event); + wl_signal_init(&remote_surface->events.transfer_key_event); + wl_signal_init(&remote_surface->events.transfer_visibility_event); + wl_signal_init(&remote_surface->events.set_owner); + wl_signal_init(&remote_surface->events.new_region); + wl_signal_init(&remote_surface->events.buffer_release); + wl_signal_init(&remote_surface->events.set_remote_render); + wl_signal_init(&remote_surface->events.set_changed_buffer_event_filter); + wl_signal_init(&remote_surface->events.get_current_buffer); + + wl_list_insert(&remote_client->remote_manager->remote_surfaces, &remote_surface->link); + + wl_signal_emit(&remote_client->remote_manager->events.new_surface, remote_surface); +} + +static void +remote_surface_manager_handle_bind_surface(struct wl_client *wl_client, + struct wl_resource *remote_surface_client_resource, + struct wl_resource *surface_resource, + struct wl_resource *remote_surface_resource) +{ + struct ds_tizen_remote_surface_manager_bind_surface_event event; + struct ds_tizen_remote_surface_client *remote_client; + struct ds_tizen_remote_surface *remote_surface; + struct ds_surface *surface; + + remote_client = wl_resource_get_user_data(remote_surface_client_resource); + surface = ds_surface_from_resource(surface_resource); + remote_surface = wl_resource_get_user_data(surface_resource); + + event.remote_surface = remote_surface; + event.surface = surface; + + wl_signal_emit(&remote_client->remote_manager->events.bind_surface, &event); +} + +static void +remote_surface_manager_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +remote_surface_manager_handle_create_surface_with_wl_surface(struct wl_client *wl_client, + struct wl_resource *remote_client_resource, + uint32_t id, + uint32_t resource_id, + struct wl_resource *wl_tbm_resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_remote_surface_client *remote_client; + struct ds_tizen_remote_surface *remote_surface; + struct ds_surface *surface = NULL, *owner_surface; + struct ds_tizen_remote_surface_provider *remote_provider; + + remote_client = wl_resource_get_user_data(remote_client_resource); + owner_surface = ds_surface_from_resource(surface_resource); + + wl_list_for_each(remote_provider, &remote_client->remote_manager->remote_providers, link) { + if (remote_provider->resource_id == resource_id) { + surface = remote_provider->surface; + break; + } + } + + if (!surface) { + ds_err("fail to find ds_surface from resource_id:%d", resource_id); + return; + } + + remote_surface = calloc(1, sizeof *remote_surface); + if (!remote_surface) { + wl_client_post_no_memory(wl_client); + return; + } + + remote_surface->resource = wl_resource_create(wl_client, &tizen_remote_surface_interface, + wl_resource_get_version(remote_client->resource), id); + if (!remote_surface->resource) { + wl_client_post_no_memory(wl_client); + free(remote_surface); + return; + } + + remote_surface->listener.owner_surface_destroy.notify = remote_surface_handle_owner_surface_destroy; + ds_surface_add_destroy_listener(owner_surface, &remote_surface->listener.owner_surface_destroy); + remote_surface->owner_surface = owner_surface; + + remote_surface->listener.surface_destroy.notify = remote_surface_handle_surface_destroy; + ds_surface_add_destroy_listener(surface, &remote_surface->listener.surface_destroy); + remote_surface->surface = surface; + + remote_surface->listener.wl_tbm_resource_destroy.notify = remote_surface_handle_wl_tbm_resource_destroy; + wl_resource_add_destroy_listener(wl_tbm_resource, &remote_surface->listener.wl_tbm_resource_destroy); + remote_surface->wl_tbm_resource = wl_tbm_resource; + + wl_resource_set_implementation(remote_surface->resource, &remote_surface_impl, + remote_surface, remote_surface_handle_resource_destroy); + + ds_inf("remote_surface:%p create", remote_surface); + + wl_signal_init(&remote_surface->events.destroy); + wl_signal_init(&remote_surface->events.set_redirect); + wl_signal_init(&remote_surface->events.transfer_mouse_event); + wl_signal_init(&remote_surface->events.transfer_mouse_wheel_event); + wl_signal_init(&remote_surface->events.transfer_touch_event); + wl_signal_init(&remote_surface->events.transfer_touch_cancel_event); + wl_signal_init(&remote_surface->events.transfer_key_event); + wl_signal_init(&remote_surface->events.transfer_visibility_event); + wl_signal_init(&remote_surface->events.set_owner); + wl_signal_init(&remote_surface->events.new_region); + wl_signal_init(&remote_surface->events.buffer_release); + wl_signal_init(&remote_surface->events.set_remote_render); + wl_signal_init(&remote_surface->events.set_changed_buffer_event_filter); + wl_signal_init(&remote_surface->events.get_current_buffer); + + wl_list_insert(&remote_client->remote_manager->remote_surfaces, &remote_surface->link); + + wl_signal_emit(&remote_client->remote_manager->events.new_surface, remote_surface); + wl_signal_emit(&remote_surface->events.set_owner, remote_surface); +} + +static const struct tizen_remote_surface_manager_interface remote_surface_manager_impl = +{ + .create_provider = remote_surface_manager_handle_create_provider, + .create_surface = remote_surface_manager_handle_create_surface, + .bind_surface = remote_surface_manager_handle_bind_surface, + .destroy = remote_surface_manager_handle_destroy, + .create_surface_with_wl_surface = remote_surface_manager_handle_create_surface_with_wl_surface, +}; + +static void +tizen_remote_surface_client_handle_resource_destroy(struct wl_resource *resource) +{ + struct ds_tizen_remote_surface_client *remote_client; + + remote_client = wl_resource_get_user_data(resource); + + ds_inf("_tizen_remote_surface_client_handle_destroy (client:%p)", remote_client); + + free(remote_client); +} + +static void +remote_surface_manager_bind(struct wl_client *wl_client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_remote_surface_manager *remote_manager = data; + struct ds_tizen_remote_surface_client *remote_client; + + remote_client = calloc(1, sizeof *remote_client); + if (!remote_client) { + ds_err("calloc() failed. tizen_remote_surface_client"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_remote_surface_client binds. (client:%p)", remote_client); + + remote_client->remote_manager = remote_manager; + remote_client->wl_client = wl_client; + + remote_client->resource = wl_resource_create(wl_client, &tizen_remote_surface_manager_interface, + MIN(version, TIZEN_REMOTE_SURFACE_VERSION), id); + if (!remote_client->resource) { + ds_err("tizen_remote_surface : wl_resource_create() failed."); + free(remote_client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(remote_client->resource, &remote_surface_manager_impl, + remote_client, tizen_remote_surface_client_handle_resource_destroy); + + wl_signal_init(&remote_client->events.destroy); +} + +static void +remote_surface_manager_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_remote_surface_manager *remote_manager; + + remote_manager = wl_container_of(listener, remote_manager, destroy); + + ds_inf("Global destroy: remote_surface_manager(%p)", remote_manager); + + wl_signal_emit(&remote_manager->events.destroy, remote_manager); + wl_list_remove(&remote_manager->destroy.link); + wl_global_destroy(remote_manager->global); + free(remote_manager); +} + +WL_EXPORT struct ds_tizen_remote_surface_manager * +ds_tizen_remote_surface_manager_create(struct wl_display *display) +{ + struct ds_tizen_remote_surface_manager *remote_manager; + + remote_manager = calloc(1, sizeof *remote_manager); + if (!remote_manager) { + ds_err("calloc() failed."); + return NULL; + } + + remote_manager->global = wl_global_create(display, &tizen_remote_surface_manager_interface, + TIZEN_REMOTE_SURFACE_VERSION, remote_manager, remote_surface_manager_bind); + if (!remote_manager->global) { + ds_err("wl_global_create() failed. tizen_remote_surface_interface"); + free(remote_manager); + return NULL; + } + + remote_manager->destroy.notify = remote_surface_manager_handle_display_destroy; + wl_display_add_destroy_listener(display, &remote_manager->destroy); + + wl_list_init(&remote_manager->remote_providers); + wl_list_init(&remote_manager->remote_surfaces); + + wl_signal_init(&remote_manager->events.destroy); + wl_signal_init(&remote_manager->events.new_provider); + wl_signal_init(&remote_manager->events.new_surface); + wl_signal_init(&remote_manager->events.bind_surface); + + ds_inf("Global created: tizen_remote_surface_manager(%p)", remote_manager); + + return remote_manager; +} + +WL_EXPORT void +ds_tizen_remote_surface_manager_add_destroy_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener) +{ + wl_signal_add(&remote_manager->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_manager_add_new_provider_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener) +{ + wl_signal_add(&remote_manager->events.new_provider, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_manager_add_new_surface_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener) +{ + wl_signal_add(&remote_manager->events.new_surface, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_manager_add_bind_surface_listener( + struct ds_tizen_remote_surface_manager *remote_manager, + struct wl_listener *listener) +{ + wl_signal_add(&remote_manager->events.bind_surface, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_provider_add_destroy_listener( + struct ds_tizen_remote_surface_provider *remote_provider, + struct wl_listener *listener) +{ + wl_signal_add(&remote_provider->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_provider_add_set_offscreen_listener( + struct ds_tizen_remote_surface_provider *remote_provider, + struct wl_listener *listener) +{ + wl_signal_add(&remote_provider->events.set_offscreen, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_provider_add_set_input_event_filter_listener( + struct ds_tizen_remote_surface_provider *remote_provider, + struct wl_listener *listener) +{ + wl_signal_add(&remote_provider->events.set_input_event_filter, listener); +} + +WL_EXPORT bool +ds_tizen_remote_surface_provider_get_offscreen( + struct ds_tizen_remote_surface_provider *remote_provider) +{ + return remote_provider->offscreen; +} + +WL_EXPORT uint32_t +ds_tizen_remote_surface_provider_get_input_event_filter( + struct ds_tizen_remote_surface_provider *remote_provider) +{ + return remote_provider->input_event_filter; +} + +WL_EXPORT void +ds_tizen_remote_surface_provider_send_visibility( + struct ds_tizen_remote_surface_provider *remote_provider, + enum ds_tizen_remote_surface_visibility_type visibility) +{ + tizen_remote_surface_provider_send_visibility(remote_provider->resource, + visibility); +} + +WL_EXPORT void +ds_tizen_remote_surface_add_destroy_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.destroy, listener); +} + +struct wl_resource * +ds_tizen_remote_surface_get_wl_tbm_resource( + struct ds_tizen_remote_surface *remote_surface) +{ + return remote_surface->wl_tbm_resource; +} + +WL_EXPORT void +ds_tizen_remote_surface_add_set_redirect_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.set_redirect, listener); +} + +WL_EXPORT bool +ds_tizen_remote_surface_get_redirect( + struct ds_tizen_remote_surface *remote_surface) +{ + return remote_surface->redirect; +} + +WL_EXPORT void +ds_tizen_remote_surface_add_set_owner_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.set_owner, listener); +} + +WL_EXPORT struct ds_surface * +ds_tizen_remote_surface_get_owner( + struct ds_tizen_remote_surface *remote_surface) +{ + return remote_surface->owner_surface; +} + +WL_EXPORT void +ds_tizen_remote_surface_add_buffer_release_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.buffer_release, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_add_set_remote_render_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.set_remote_render, listener); +} + +WL_EXPORT bool +ds_tizen_remote_surface_get_remote_render( + struct ds_tizen_remote_surface *remote_surface) +{ + return remote_surface->remote_render; +} + +WL_EXPORT void +ds_tizen_remote_surface_add_set_changed_buffer_event_filter_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.set_changed_buffer_event_filter, listener); +} + +WL_EXPORT uint32_t +ds_tizen_remote_surface_get_changed_buffer_event_filter( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + return remote_surface->changed_buffer_event_filter; +} + +WL_EXPORT void +ds_tizen_remote_surface_add_get_current_buffer_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.get_current_buffer, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_send_changed_buffer( + struct ds_tizen_remote_surface *remote_surface, + struct ds_buffer *buffer, + uint32_t time, + struct wl_array *options) +{ + int version; + struct ds_tbm_client_buffer *tbm_client_buffer; + struct wl_resource *buffer_resource; + + version = wl_resource_get_version(remote_surface->resource); + + tbm_client_buffer = ds_tbm_client_buffer_from_buffer(buffer); + if (!tbm_client_buffer) { + ds_err("not support buffer"); + return; + } + + buffer_resource = ds_buffer_get_resource(buffer); + if (!buffer_resource) { + ds_err("buffer resource is null"); + return; + } + + if (version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION) { + tizen_remote_surface_send_changed_buffer(remote_surface->resource, + TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM, + buffer_resource, + remote_surface_dummy_fd_get(), + 0, + time, + options); + } else { + tizen_remote_surface_send_update_buffer(remote_surface->resource, + buffer_resource, + time); + } +} + +WL_EXPORT void +ds_tizen_remote_surface_send_changed_buffer_image_file( + struct ds_tizen_remote_surface *remote_surface, + int image_file_fd, + int image_file_size, + uint32_t time, + struct wl_array *options) +{ + int version; + + version = wl_resource_get_version(remote_surface->resource); + + if (version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION) { + ds_err("not support remote_surface:%p version:%d", remote_surface, version); + return; + } + + tizen_remote_surface_send_changed_buffer(remote_surface->resource, + TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE, + NULL, + image_file_fd, + image_file_size, + time, + options); +} + +WL_EXPORT void +ds_tizen_remote_surface_send_missing( + struct ds_tizen_remote_surface *remote_surface) +{ + tizen_remote_surface_send_missing(remote_surface->resource); +} + +WL_EXPORT void +ds_tizen_remote_surface_send_input_event_filter( + struct ds_tizen_remote_surface *remote_surface, + uint32_t input_event_filter) +{ + tizen_remote_surface_send_input_event_filter(remote_surface->resource, + input_event_filter); +} + +WL_EXPORT void +ds_tizen_remote_surface_add_new_region_listener( + struct ds_tizen_remote_surface *remote_surface, + struct wl_listener *listener) +{ + wl_signal_add(&remote_surface->events.new_region, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_region_add_destroy_listener( + struct ds_tizen_remote_surface_region *remote_region, + struct wl_listener *listener) +{ + wl_signal_add(&remote_region->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_region_add_set_geometry_listener( + struct ds_tizen_remote_surface_region *remote_region, + struct wl_listener *listener) +{ + wl_signal_add(&remote_region->events.set_geometry, listener); +} + +WL_EXPORT void +ds_tizen_remote_surface_region_get_geometry( + struct ds_tizen_remote_surface_region *remote_region, + int32_t *x,int32_t *y, int32_t *w, int32_t *h) +{ + if (x) *x = remote_region->x; + if (y) *y = remote_region->y; + if (w) *w = remote_region->w; + if (h) *h = remote_region->h; +} diff --git a/tests/meson.build b/tests/meson.build index bf9a9d8..59201d4 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -383,3 +383,22 @@ executable('libds-tizen-video-tests', install_dir: libds_tizen_bindir, install : true ) + +tc_remote_surface_files = [ + 'tc_main.cpp', + 'tc_remote_surface.cpp', +] + +executable('libds-tizen-remote-surface-tests', + [ + tc_mock_files, + tc_remote_surface_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_remote_surface, + dependency('tizen-remote-surface-client', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/mockclient.cpp b/tests/mockclient.cpp index 135c51c..3c12d65 100644 --- a/tests/mockclient.cpp +++ b/tests/mockclient.cpp @@ -112,3 +112,8 @@ void MockClient::ExpectProtocolError(const struct wl_interface *intf, << "Should get interface '" << intf->name << "' but got '" << interface->name << "'"; } + +struct wl_display * MockClient::GetWlDisplay() +{ + return display; +} diff --git a/tests/mockclient.h b/tests/mockclient.h index d3f4bf6..3fdd2eb 100644 --- a/tests/mockclient.h +++ b/tests/mockclient.h @@ -41,6 +41,7 @@ public: void RoundTrip(); void ExpectNoError(); void ExpectProtocolError(const struct wl_interface *intf, uint32_t code); + struct wl_display * GetWlDisplay(); private: struct wl_display *display; diff --git a/tests/tc_remote_surface.cpp b/tests/tc_remote_surface.cpp new file mode 100644 index 0000000..3cbfd6d --- /dev/null +++ b/tests/tc_remote_surface.cpp @@ -0,0 +1,815 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" + +#include +#include +#include +#include +#include +#include + +TEST(RemoteSurfaceSimpleTest, CreateRemoteSurfaceManager) +{ + struct wl_display *display = wl_display_create(); + + struct ds_tizen_remote_surface_manager *remote_surface_manager = + ds_tizen_remote_surface_manager_create(display); + ASSERT_NE(remote_surface_manager, nullptr); + + wl_display_destroy(display); +} + +class RemoteSurfaceCompositor : public MockCompositor, public ::testing::Test +{ +public: + RemoteSurfaceCompositor() : + MockCompositor(&RemoteSurfaceCompositor::SetUpComp, this) + { + } + + static void SetUpComp(void *data) + { + RemoteSurfaceCompositor *comp = static_cast(data); + + struct ds_tizen_remote_surface_manager *remote_surface_manager = + ds_tizen_remote_surface_manager_create(comp->GetWlDisplay()); + ASSERT_NE(remote_surface_manager, nullptr); + + struct wayland_tbm_server *tbm_server = + wayland_tbm_server_init(comp->GetWlDisplay(), NULL, -1, 0);; + ASSERT_NE(tbm_server, nullptr); + } +}; + +static void handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version); +static void handle_global_remove(void *data, struct wl_registry *registry, + uint32_t name); + +static const struct wl_registry_listener registry_listener = { + .global = handle_global, + .global_remove = handle_global_remove, +}; + +class MockRemoteSurfaceClient : public MockClient +{ +public: + MockRemoteSurfaceClient() : MockClient(®istry_listener, this), + resource_id(0), + provider_visibility(0), + input_event_filter(0) + { + EXPECT_NE(this->compositor, nullptr); + EXPECT_NE(this->remote_surface_manager, nullptr); + + surface = wl_compositor_create_surface(this->compositor); + EXPECT_NE(this->surface, nullptr); + + surface2 = wl_compositor_create_surface(this->compositor); + EXPECT_NE(this->surface, nullptr); + + wl_tbm_client = wayland_tbm_client_init(GetWlDisplay()); + EXPECT_NE(wl_tbm_client, nullptr); + + wl_tbm = wayland_tbm_client_get_wl_tbm(wl_tbm_client); + } + + ~MockRemoteSurfaceClient() + { + wl_surface_destroy(this->surface); + tizen_remote_surface_manager_destroy(this->remote_surface_manager); + wl_compositor_destroy(this->compositor); + } + + struct wl_compositor *compositor; + struct tizen_remote_surface_manager *remote_surface_manager; + struct wl_surface *surface, *surface2; + uint32_t resource_id; + uint32_t provider_visibility; + uint32_t input_event_filter; + struct wayland_tbm_client *wl_tbm_client; + struct wl_tbm *wl_tbm; +}; + +static void +handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) +{ + MockRemoteSurfaceClient *client = static_cast(data); + + if (strcmp(interface, "wl_compositor") == 0) { + client->compositor = static_cast( + wl_registry_bind(registry, name, &wl_compositor_interface, 4)); + } else if (strcmp(interface, "tizen_remote_surface_manager") == 0) { + client->remote_surface_manager = static_cast( + wl_registry_bind(registry, name, &tizen_remote_surface_manager_interface, 6)); + } +} + +static void +handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ +} + +static void +handle_provider_resource_id(void *data, + struct tizen_remote_surface_provider *provider, + uint32_t resource_id) +{ + MockRemoteSurfaceClient *client = static_cast(data); + + client->resource_id = resource_id; +} + +static void +handle_provider_visibility(void *data, + struct tizen_remote_surface_provider *provider, + uint32_t visibility) +{ + MockRemoteSurfaceClient *client = static_cast(data); + + client->provider_visibility = visibility; +} + +static const struct tizen_remote_surface_provider_listener provider_listener = +{ + handle_provider_resource_id, + handle_provider_visibility, +}; + +static void +handle_remote_surface_update_buffer(void *data, + struct tizen_remote_surface *remote_surface, + struct wl_buffer *buffer, + uint32_t time) +{ + wl_buffer_destroy(buffer); +} + +static void +handle_remote_surface_missing(void *data, + struct tizen_remote_surface *remote_surface) +{ +} + +static void +handle_remote_surface_changed_buffer(void *data, + struct tizen_remote_surface *remote_surface, + uint32_t type, + struct wl_buffer *tbm, + int32_t fd, + uint32_t size, + uint32_t time, + struct wl_array *keys) +{ + tbm_surface_h tbm_surface; + + if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM) { + tbm_surface = static_cast(wl_buffer_get_user_data(tbm)); + ASSERT_EQ(tbm_surface, nullptr); + + wl_buffer_destroy(tbm); + } + + close(fd); +} + +static void +handle_remote_surface_input_ev_filter(void *data, + struct tizen_remote_surface *tizen_remote_surface, + uint32_t input_event_filter) +{ + MockRemoteSurfaceClient *client = static_cast(data); + + client->input_event_filter = input_event_filter; +} + +static const struct tizen_remote_surface_listener remote_surface_listener = +{ + handle_remote_surface_update_buffer, /* deprecated */ + handle_remote_surface_missing, + handle_remote_surface_changed_buffer, + handle_remote_surface_input_ev_filter, +}; + +TEST_F(RemoteSurfaceCompositor, CreateProvider) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, ProviderOffscreenSet) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + tizen_remote_surface_provider_offscreen_set(remote_surface_provider, 1); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, ProviderSetInputEventFilter) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + tizen_remote_surface_provider_set_input_event_filter(remote_surface_provider, + TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_ALL| + TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_WHEEL_ALL | + TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_ALL | + TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_CANCEL_ALL | + TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_KEY_ALL); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, CreateSurface) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, CreateSurfaceWithWlSurface) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceRedirect) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_redirect(remote_surface); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceUnredirect) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_unredirect(remote_surface); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceTransferMouseEvent) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + uint32_t event_type = 0; + int32_t device = 0; + int32_t button = 0; + int32_t x = 0, y = 0; + wl_fixed_t radius_x = 0, radius_y = 0; + wl_fixed_t pressure = 0; + wl_fixed_t angle = 0; + uint32_t clas = 0, subclas = 0; + const char *identifier = "test_identifier"; + uint32_t time = 0; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_transfer_mouse_event(remote_surface, + event_type, + device, + button, + x, + y, + radius_x, + radius_y, + pressure, + angle, + clas, + subclas, + identifier, + time); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceTransferMouseWheel) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + uint32_t direction = 0; + int32_t z = 0; + uint32_t clas = 0, subclas = 0; + const char *identifier = "test_identifier"; + uint32_t time = 0; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_transfer_mouse_wheel(remote_surface, + direction, + z, + clas, + subclas, + identifier, + time); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceTransferTouchEvent) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + uint32_t event_type = 0; + int32_t device = 0; + int32_t button = 0; + int32_t x = 0, y = 0; + wl_fixed_t radius_x = 0, radius_y = 0; + wl_fixed_t pressure = 0; + wl_fixed_t angle = 0; + uint32_t clas = 0, subclas = 0; + const char *identifier = "test_identifier"; + uint32_t time = 0; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_transfer_touch_event(remote_surface, + event_type, + device, + button, + x, + y, + radius_x, + radius_y, + pressure, + angle, + clas, + subclas, + identifier, + time); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceTransferTouchCancel) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_transfer_touch_cancel(remote_surface); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceTransferKeyEvent) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + uint32_t event_type = 0; + int32_t keycode = 0; + uint32_t clas = 0, subclas = 0; + const char *identifier = "test_identifier"; + uint32_t time = 0; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_transfer_key_event(remote_surface, + event_type, + keycode, + clas, + subclas, + identifier, + time); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceTransferVisibility) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_transfer_visibility(remote_surface, + TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceSetOwner) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_set_owner(remote_surface, client->surface2); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceSetRemoteRender) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_set_remote_render(remote_surface, 1); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceSetChangedBufferEventFilter) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_set_changed_buffer_event_filter(remote_surface, + TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM | + TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, SurfaceGetCurrentBuffer) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + tizen_remote_surface_get_current_buffer(remote_surface, TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM, 1); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} + +TEST_F(RemoteSurfaceCompositor, RegionSetGeometry) +{ + MockRemoteSurfaceClient *client = new MockRemoteSurfaceClient(); + + struct tizen_remote_surface_provider *remote_surface_provider; + struct tizen_remote_surface *remote_surface; + struct tizen_remote_surface_region *region; + + remote_surface_provider = + tizen_remote_surface_manager_create_provider(client->remote_surface_manager, + client->surface); + EXPECT_TRUE(remote_surface_provider); + + tizen_remote_surface_provider_add_listener(remote_surface_provider, + &provider_listener, + client); + client->ExpectNoError(); + + remote_surface = tizen_remote_surface_manager_create_surface_with_wl_surface( + client->remote_surface_manager, client->resource_id, client->wl_tbm, client->surface2); + EXPECT_TRUE(remote_surface); + + tizen_remote_surface_add_listener(remote_surface, &remote_surface_listener, NULL); + client->ExpectNoError(); + + region = tizen_remote_surface_create_region(remote_surface); + EXPECT_TRUE(region); + + tizen_remote_surface_region_set_geometry(region, 0, 0, 100, 100); + client->ExpectNoError(); + + tizen_remote_surface_provider_destroy(remote_surface_provider); + tizen_remote_surface_destroy(remote_surface); + delete client; +} -- 2.7.4