From 7945614beaa50b35324e2d5d515fc5108d6e9901 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 27 Feb 2017 17:29:33 +0900 Subject: [PATCH 01/16] Add an exception handling about destroying the watcher handle We should check whether the surface handle is NULL or NOT. Change-Id: Idca2b162a2e08a68f913118206f655f6336555b7 Signed-off-by: Hwankyu Jhun --- screen_connector_watcher/src/screen_connector_watcher.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index ad29f4e..1328adf 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -250,10 +250,12 @@ static void __destroy_watcher_h(screen_connector_watcher_h handle) if (!handle) return; - tizen_remote_surface_set_user_data(handle->surface, NULL); - tizen_remote_surface_unredirect(handle->surface); - tizen_remote_surface_destroy(handle->surface); - handle->surface = NULL; + if (handle->surface) { + tizen_remote_surface_set_user_data(handle->surface, NULL); + tizen_remote_surface_unredirect(handle->surface); + tizen_remote_surface_destroy(handle->surface); + handle->surface = NULL; + } if (handle->appid) { free(handle->appid); -- 2.7.4 From 8aaed29cad5cc38cae744da90aad20906ef9ba96 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Thu, 2 Mar 2017 21:28:24 +0900 Subject: [PATCH 02/16] Remove handle from watcher list when watcher destroyed If viewer try to remove handle without removing evas object, handle remain in watcher list. Change-Id: I88f04d69ad56aa6b380e430d94b733c86d07f2f2 Signed-off-by: Hyunho Kang (cherry picked from commit de30a1b347eeb91c75de828647f65f6b7b89bd45) --- screen_connector_watcher/src/screen_connector_watcher.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index 1328adf..5e1aa33 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -257,6 +257,12 @@ static void __destroy_watcher_h(screen_connector_watcher_h handle) handle->surface = NULL; } + if (__pending_watcher_list) + __pending_watcher_list = g_list_remove(__pending_watcher_list, handle); + + if (__watcher_list) + __watcher_list = g_list_remove(__watcher_list, handle); + if (handle->appid) { free(handle->appid); handle->appid = NULL; -- 2.7.4 From 01eb6ed5231533d0e04055fb349d8d6030dfddd1 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Mon, 20 Feb 2017 22:22:45 +0900 Subject: [PATCH 03/16] Refactor screen-connector Old version screen connecotor handle UI app and widget exactly same way. So viewer have to know running app list to watch other app screen. It's not a good design and make problems like timing issue. Old design also make troubles with widgets because it is watching app with appid so, in multi instance senario sometimes timing issue was occured. To solve those problems we divide screen connector into two API sets. For watching UI apps, we provide screen_connector_watcher* API set. For widget/watch apps, we provide screen_connector_toolkit* API set. Change-Id: Ifdff15e80d36945747fcc37b90a760fc2e5df561 Signed-off-by: Hyunho Kang (cherry picked from commit dde5ccecdbb88c1dfc7b344872b8811a2b007347) --- .../src/screen_connector_provider.c | 11 +- .../include/screen_connector_toolkit.h | 86 ++ .../include/screen_connector_trs.h | 35 + .../include/screen_connector_watcher.h | 47 +- .../src/screen_connector_toolkit.c | 397 +++++++++ .../src/screen_connector_trs.c | 117 +++ .../src/screen_connector_watcher.c | 386 ++++----- .../include/screen_connector_toolkit_evas.h | 117 +++ .../include/screen_connector_watcher_evas.h | 65 +- .../src/screen_connector_toolkit_evas.c | 903 +++++++++++++++++++++ .../src/screen_connector_watcher_evas.c | 790 +++--------------- 11 files changed, 1972 insertions(+), 982 deletions(-) create mode 100644 screen_connector_watcher/include/screen_connector_toolkit.h create mode 100644 screen_connector_watcher/include/screen_connector_trs.h create mode 100644 screen_connector_watcher/src/screen_connector_toolkit.c create mode 100644 screen_connector_watcher/src/screen_connector_trs.c create mode 100644 screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h create mode 100644 screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c diff --git a/screen_connector_provider/src/screen_connector_provider.c b/screen_connector_provider/src/screen_connector_provider.c index 9213c39..70575e4 100644 --- a/screen_connector_provider/src/screen_connector_provider.c +++ b/screen_connector_provider/src/screen_connector_provider.c @@ -47,8 +47,15 @@ struct screen_connector_provider_s { static void __rsp_resource_id_cb(void *data, struct tizen_remote_surface_provider *provider, uint32_t res_id) { - LOGE("add app screen : %d", res_id); - aul_screen_connector_add_app_screen(res_id); + struct screen_connector_provider_s *remote = (struct screen_connector_provider_s *)data; + + if (remote == NULL) { + LOGE("null remote"); + return; + } + + LOGD("add app screen : %s, %d", remote->id, res_id); + aul_screen_connector_add_app_screen(remote->id, res_id); } static void __rsp_visibility_cb(void *data, struct tizen_remote_surface_provider *provider, uint32_t visibility) diff --git a/screen_connector_watcher/include/screen_connector_toolkit.h b/screen_connector_watcher/include/screen_connector_toolkit.h new file mode 100644 index 0000000..a5db07e --- /dev/null +++ b/screen_connector_watcher/include/screen_connector_toolkit.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SCREEN_CONNECTOR_TOOLKIT_H__ +#define __SCREEN_CONNECTOR_TOOLKIT_H__ + +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_UP_DOWN = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_UP_DOWN, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_X = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_MOVE_X, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_MOVE_Y, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_X_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_MOVE_X_Y, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_WHEEL = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_WHEEL_ALL, + SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_UP_DOWN = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_UP_DOWN, + SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_MOVE_X = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_MOVE_X, + SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_MOVE_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_MOVE_Y, + SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_MOVE_X_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_MOVE_X_Y, + SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_CANCEL = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_CANCEL_ALL, + SCREEN_CONNECTOR_INPUT_TYPE_KEY = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_KEY_ALL, +} screen_connector_input_type_e; + +typedef enum { + SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET = AUL_SCREEN_TYPE_WIDGET, + SCREEN_CONNECTOR_SCREEEN_TYPE_WATCH = AUL_SCREEN_TYPE_WATCH, + SCREEN_CONNECTOR_SCREEEN_TYPE_UI = AUL_SCREEN_TYPE_UI, + SCREEN_CONNECTOR_SCREEEN_TYPE_ALL = AUL_SCREEN_TYPE_ALL, +} screen_connector_screen_type_e; + +typedef void (*screen_connector_toolkit_added_cb)(const char *appid, const char *instance_id, const int pid, void *data); +typedef void (*screen_connector_toolkit_removed_cb)(const char *appid, const char *instance_id, const int pid, void *data); +typedef void (*screen_connector_toolkit_update_cb)(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, + int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, + const char *appid, const char *instance_id, const int pid, void *data); + +typedef struct _screen_connector_toolkit_ops { + screen_connector_toolkit_added_cb added_cb; + screen_connector_toolkit_removed_cb removed_cb; + screen_connector_toolkit_update_cb updated_cb; +} screen_connector_toolkit_ops; + +typedef struct _screen_connector_toolkit_h *screen_connector_toolkit_h; +typedef struct _screen_connector_type_h *screen_connector_type_h; + +int screen_connector_toolkit_init(screen_connector_screen_type_e type); +int screen_connector_toolkit_fini(screen_connector_screen_type_e type); +screen_connector_toolkit_h screen_connector_toolkit_add(screen_connector_toolkit_ops *ops, char *id, + screen_connector_screen_type_e type, void *data); +int screen_connector_toolkit_remove(screen_connector_toolkit_h h); +int screen_connector_toolkit_update(const char *appid, const char *instance_id); +const char *screen_connector_toolkit_get_appid(screen_connector_toolkit_h h); +const char *screen_connector_toolkit_get_instance_id(screen_connector_toolkit_h h); +int screen_connector_toolkit_get_pid(screen_connector_toolkit_h h); +int screen_connector_toolkit_get_surface_id(screen_connector_toolkit_h h); +void *screen_connector_toolkit_get_user_data(screen_connector_toolkit_h h); + +unsigned int screen_connector_toolkit_get_event_filter(screen_connector_toolkit_h h); +int screen_connector_toolkit_check_input_disabled(screen_connector_toolkit_h h, screen_connector_input_type_e input); +screen_connector_toolkit_h screen_connector_toolkit_create_handle(char *id, int surface_id, + screen_connector_toolkit_ops *ops, void *data); +struct tizen_remote_surface *screen_connector_toolkit_get_trs(screen_connector_toolkit_h h); +int screen_connector_toolkit_redirect_surface(screen_connector_toolkit_h info); + +#ifdef __cplusplus +} +#endif + +#endif /* __SCREEN_CONNECTOR_WATCHER_H__ */ diff --git a/screen_connector_watcher/include/screen_connector_trs.h b/screen_connector_watcher/include/screen_connector_trs.h new file mode 100644 index 0000000..dade8de --- /dev/null +++ b/screen_connector_watcher/include/screen_connector_trs.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SCREEN_CONNECTOR_TRS_H__ +#define __SCREEN_CONNECTOR_TRS_H__ + +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +int screen_connector_trs_init(void); +int screen_connector_trs_fini(void); +struct wl_tbm *screen_connector_get_tbm(); +struct tizen_remote_surface_manager *screen_connector_get_rsm(); + +#ifdef __cplusplus +} +#endif + +#endif /* __SCREEN_CONNECTOR_WATCHER_H__ */ diff --git a/screen_connector_watcher/include/screen_connector_watcher.h b/screen_connector_watcher/include/screen_connector_watcher.h index e9a7d17..31d6b85 100644 --- a/screen_connector_watcher/include/screen_connector_watcher.h +++ b/screen_connector_watcher/include/screen_connector_watcher.h @@ -23,47 +23,36 @@ extern "C" { #endif -typedef enum { - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_UP_DOWN = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_UP_DOWN, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_X = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_MOVE_X, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_MOVE_Y, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_X_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_MOVE_X_Y, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_WHEEL = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_MOUSE_WHEEL_ALL, - SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_UP_DOWN = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_UP_DOWN, - SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_MOVE_X = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_MOVE_X, - SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_MOVE_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_MOVE_Y, - SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_MOVE_X_Y = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_MOVE_X_Y, - SCREEN_CONNECTOR_INPUT_TYPE_TOUCH_CANCEL = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_TOUCH_CANCEL_ALL, - SCREEN_CONNECTOR_INPUT_TYPE_KEY = TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_KEY_ALL, -} screen_connector_input_type_e; - -typedef void (*screen_connector_watcher_update_cb)(struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time, void *data); -typedef void (*screen_connector_watcher_missing_cb)(struct tizen_remote_surface *trs, void *data); -typedef void (*screen_connector_watcher_change_cb)(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, - int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, void *data); +typedef void (*screen_connector_watcher_added_cb)(const char *appid, const char *instance_id, const int pid, void *data); +typedef void (*screen_connector_watcher_removed_cb)(const char *appid, const char *instance_id, const int pid, void *data); +typedef void (*screen_connector_watcher_update_cb)(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, + int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, + const char *appid, const char *instance_id, const int pid,void *data); typedef struct _screen_connector_watcher_ops { - screen_connector_watcher_update_cb update_cb; - screen_connector_watcher_missing_cb missing_cb; - screen_connector_watcher_change_cb change_cb; + screen_connector_watcher_added_cb added_cb; + screen_connector_watcher_removed_cb removed_cb; + screen_connector_watcher_update_cb updated_cb; } screen_connector_watcher_ops; typedef struct _screen_connector_watcher_h *screen_connector_watcher_h; +typedef struct _screen_connector_info_h *screen_connector_info_h; int screen_connector_watcher_init(void); int screen_connector_watcher_fini(void); -screen_connector_watcher_h screen_connector_watcher_add(screen_connector_watcher_ops *ops, char *id, void *data); +screen_connector_watcher_h screen_connector_watcher_add(screen_connector_watcher_ops *ops, void *data); int screen_connector_watcher_remove(screen_connector_watcher_h h); -int screen_connector_watcher_update(const char *appid); -char *screen_connector_watcher_get_appid(screen_connector_watcher_h h); -int screen_connector_watcher_get_pid(screen_connector_watcher_h h); -int screen_connector_watcher_get_resource_id(screen_connector_watcher_h h); +int screen_connector_watcher_update(screen_connector_watcher_h h, const char *instance_id); +char *screen_connector_watcher_get_appid(screen_connector_info_h h); +char *screen_connector_watcher_get_instance_id(screen_connector_info_h h); +int screen_connector_watcher_get_pid(screen_connector_info_h h); +int screen_connector_watcher_get_surface_id(screen_connector_info_h h); +void *screen_connector_watcher_get_user_data(screen_connector_info_h h); + int screen_connector_watcher_set_resource_id(screen_connector_watcher_h h, int rid); -unsigned int screen_connector_watcher_get_event_filter(screen_connector_watcher_h h); -int screen_connector_watcher_check_input_disabled(screen_connector_watcher_h h, screen_connector_input_type_e input); struct tizen_remote_surface *screen_connector_watcher_get_trs(screen_connector_watcher_h h); screen_connector_watcher_h screen_connector_watcher_create_handle(char *id, int pid, screen_connector_watcher_ops *ops, void *data); -void screen_connector_watcher_redirect_surface(screen_connector_watcher_h watcher_h); +int screen_connector_watcher_redirect_surface(screen_connector_info_h info); #ifdef __cplusplus } diff --git a/screen_connector_watcher/src/screen_connector_toolkit.c b/screen_connector_watcher/src/screen_connector_toolkit.c new file mode 100644 index 0000000..98864ff --- /dev/null +++ b/screen_connector_watcher/src/screen_connector_toolkit.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "screen_connector_trs.h" +#include "screen_connector_toolkit.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "SC_WATCHER" + +struct _screen_connector_type_h { + GHashTable *toolkit_table; + aul_screen_viewer_h aul_handle; +}; + +struct _screen_connector_toolkit_h { + void (*update_cb)(struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time, void *data); + void (*missing_cb)(struct tizen_remote_surface *trs, void *data); + void (*change_cb)(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, + int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, void *data); + screen_connector_toolkit_ops *ops; + unsigned int event_filter; + char *appid; + char *instance_id; + int pid; + int surface_id; + struct tizen_remote_surface *surface; + struct _screen_connector_type_h *type_h; + void *data; +}; + +static GHashTable *__type_table; +static void __buffer_updated(void *data, struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time) +{ +} + +static void __buffer_missing(void *data, struct tizen_remote_surface *trs) +{ + screen_connector_toolkit_h toolkit_h = (screen_connector_toolkit_h)data; + + if (toolkit_h) + toolkit_h->ops->removed_cb(toolkit_h->appid, toolkit_h->instance_id, toolkit_h->pid, toolkit_h->data); +} + +static void __buffer_changed(void *data, struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, + int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys) +{ + screen_connector_toolkit_h toolkit_h = (screen_connector_toolkit_h)data; + + if (toolkit_h && toolkit_h->ops) + toolkit_h->ops->updated_cb(trs, type, tbm, img_file_fd, img_file_size, time, keys, toolkit_h->appid, + toolkit_h->instance_id, toolkit_h->pid, toolkit_h->data); +} + +static void __input_event_filter(void *data, struct tizen_remote_surface *trs, uint32_t event_filter) +{ + screen_connector_toolkit_h toolkit_h = (screen_connector_toolkit_h)data; + + if (toolkit_h) + toolkit_h->event_filter = event_filter; + + LOGD("event filter updated:%d", event_filter); +} + +static const struct tizen_remote_surface_listener __rs_listener = { + __buffer_updated, + __buffer_missing, + __buffer_changed, + __input_event_filter, +}; + +EXPORT_API int screen_connector_toolkit_redirect_surface(screen_connector_toolkit_h toolkit_h) +{ + + struct wl_tbm *tbm = screen_connector_get_tbm(); + struct tizen_remote_surface_manager *rsm = screen_connector_get_rsm(); + if (toolkit_h == NULL || rsm == NULL || tbm == NULL) + return -1; + + toolkit_h->surface = tizen_remote_surface_manager_create_surface(rsm, (uint32_t)toolkit_h->surface_id, tbm); + if (toolkit_h->surface == NULL) + return -1; + + LOGD("resource_id : %d, (%p), %s", toolkit_h->surface_id, toolkit_h->surface, toolkit_h->instance_id); + tizen_remote_surface_add_listener(toolkit_h->surface, &__rs_listener, toolkit_h); + tizen_remote_surface_redirect(toolkit_h->surface); + + return 0; +} + +static void __destroy_toolkit_h(gpointer data) +{ + screen_connector_toolkit_h toolkit_h = (screen_connector_toolkit_h)data; + if (!toolkit_h) + return; + + LOGD("__destroy_toolkit_h appid: %s surface_id %d", toolkit_h->appid, toolkit_h->surface_id); + + if (toolkit_h->appid) { + free(toolkit_h->appid); + toolkit_h->appid = NULL; + } + + if (toolkit_h->instance_id) { + free(toolkit_h->instance_id); + toolkit_h->instance_id = NULL; + } + + if (toolkit_h->surface) { + tizen_remote_surface_set_user_data(toolkit_h->surface, NULL); + tizen_remote_surface_unredirect(toolkit_h->surface); + tizen_remote_surface_destroy(toolkit_h->surface); + toolkit_h->surface = NULL; + } + + if (toolkit_h->ops) { + free(toolkit_h->ops); + toolkit_h->ops = NULL; + } + + free(toolkit_h); +} + +static void __destroy_type_h(gpointer data) +{ + screen_connector_type_h type_h = (screen_connector_type_h)data; + if (!type_h) + return; + + if (type_h->aul_handle) + aul_screen_connector_remove_screen_viewer(type_h->aul_handle); + if (type_h->toolkit_table) + g_hash_table_destroy(type_h->toolkit_table); + free(type_h); +} + +static void __aul_screen_viewer_cb(const char *appid, const char *instance_id, + const int pid, const unsigned int surface_id, + aul_screen_connector_event_type_e event_type, void *data) +{ + screen_connector_toolkit_h toolkit_h; + screen_connector_type_h type_h = (screen_connector_type_h)data; + + LOGD("__aul_screen_viewer_cb pid: %d, surface_id: %d, appid: %s instance_id: %s type %d", + pid, surface_id, appid, instance_id, event_type); + + if (type_h == NULL || type_h->toolkit_table == NULL) { + LOGE("NULL type info"); + return; + } + + toolkit_h = (screen_connector_toolkit_h)g_hash_table_lookup(type_h->toolkit_table, instance_id); + if (toolkit_h == NULL) { + LOGD("It's not my instance_id, maybe alread removed %s ", instance_id); + return; + } + + toolkit_h->appid = strdup(appid); + toolkit_h->pid = pid; + toolkit_h->surface_id = surface_id; + if (event_type == AUL_SCREEN_CONNECTOR_EVENT_TYPE_ADD) { + + toolkit_h->ops->added_cb(appid, instance_id, pid, toolkit_h->data); + screen_connector_toolkit_redirect_surface(toolkit_h); + + } else if (event_type == AUL_SCREEN_CONNECTOR_EVENT_TYPE_UPDATE) { + + } else if (event_type == AUL_SCREEN_CONNECTOR_EVENT_TYPE_REMOVE) { + + if (toolkit_h->ops) + toolkit_h->ops->removed_cb(appid, instance_id, pid, toolkit_h->data); + + g_hash_table_remove(type_h->toolkit_table, instance_id); + } +} + +EXPORT_API int screen_connector_toolkit_init(screen_connector_screen_type_e type) +{ + int ret = 0; + int *key; + screen_connector_type_h type_h; + + ret = screen_connector_trs_init(); + if (__type_table == NULL) + __type_table = g_hash_table_new_full(g_int_hash, g_int_equal, free, __destroy_type_h); + + type_h = g_hash_table_lookup(__type_table, &type); + if (type_h == NULL) { + key = (int *)calloc(1, sizeof(int)); + *key = type; + + type_h = (screen_connector_type_h)calloc(1, sizeof(struct _screen_connector_type_h)); + g_hash_table_insert(__type_table, key, type_h); + } + + return ret; +} + +EXPORT_API int screen_connector_toolkit_fini(screen_connector_screen_type_e type) +{ + int ret = 0; + screen_connector_type_h type_h; + + if (__type_table == NULL) { + LOGI("__type_table is NULL"); + return 0; + } + + type_h = g_hash_table_lookup(__type_table, &type); + if (type_h) + g_hash_table_remove(__type_table, &type); + + if (g_hash_table_size(__type_table) == 0) { + ret = screen_connector_trs_fini(); + g_hash_table_destroy(__type_table); + __type_table = NULL; + } + + return ret; +} + +EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_create_handle(char *id, int surface_id, + screen_connector_toolkit_ops *ops, void *data) +{ + screen_connector_toolkit_h toolkit_h = NULL; + + toolkit_h = (screen_connector_toolkit_h)calloc(1, sizeof(struct _screen_connector_toolkit_h)); + if (toolkit_h == NULL) { + LOGE("toolkit_h calloc fail"); + return NULL; + } + toolkit_h->surface_id = surface_id; + toolkit_h->appid = strdup(id); + toolkit_h->instance_id = strdup(id); + toolkit_h->data = data; + toolkit_h->ops = ops; + + return toolkit_h; +} + +EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_add(screen_connector_toolkit_ops *ops, char *id, + screen_connector_screen_type_e type, void *data) +{ + screen_connector_toolkit_h toolkit_h = NULL; + screen_connector_type_h type_h = NULL; + + if (id == NULL || ops == NULL) { + LOGE("Invalid param"); + return NULL; + } + + type_h = g_hash_table_lookup(__type_table, &type); + if (type_h == NULL) { + LOGE("type %d is not initialized !!", type); + return NULL; + } + + toolkit_h = (screen_connector_toolkit_h)calloc(1, sizeof(struct _screen_connector_toolkit_h)); + if (toolkit_h == NULL) { + LOGE("toolkit_h calloc fail"); + return NULL; + } + toolkit_h->instance_id = strdup(id); + toolkit_h->data = data; + toolkit_h->ops = ops; + toolkit_h->type_h = type_h; + + if (type_h->toolkit_table == NULL) + type_h->toolkit_table = g_hash_table_new_full(g_str_hash, + g_str_equal, free, __destroy_toolkit_h); + + g_hash_table_insert(type_h->toolkit_table, strdup(id), toolkit_h); + + if (type_h->aul_handle == NULL) + aul_screen_connector_add_screen_viewer(__aul_screen_viewer_cb, type, true, type_h, &type_h->aul_handle); + + return toolkit_h; +} + +EXPORT_API int screen_connector_toolkit_remove(screen_connector_toolkit_h h) +{ + if (h == NULL) { + LOGE("screen_connector_toolkit_h is NULL"); + return -1; + } + + if (h->type_h == NULL) { + LOGE("screen_connector_toolkit_h type_h is NULL"); + return -1; + } + + if (h->type_h->toolkit_table == NULL) { + LOGE("screen_connector_toolkit_h type_h toolkit_table is NULL"); + return -1; + } + + g_hash_table_remove(h->type_h->toolkit_table, h->instance_id); + + return 0; +} + +EXPORT_API int screen_connector_toolkit_update(const char *appid, const char *instance_id) +{ + return aul_screen_connector_send_update_request(appid, instance_id); +} + +EXPORT_API const char *screen_connector_toolkit_get_appid(screen_connector_toolkit_h h) +{ + if (h == NULL) + return NULL; + + return h->appid; +} + +EXPORT_API const char *screen_connector_toolkit_get_instance_id(screen_connector_toolkit_h h) +{ + if (h == NULL) + return NULL; + + return h->instance_id; +} + +EXPORT_API int screen_connector_toolkit_get_pid(screen_connector_toolkit_h h) +{ + if (h == NULL) + return -1; + + return h->pid; +} + +EXPORT_API int screen_connector_toolkit_get_surface_id(screen_connector_toolkit_h h) +{ + if (h == NULL) + return -1; + + return h->surface_id; +} + +EXPORT_API void *screen_connector_toolkit_get_user_data(screen_connector_toolkit_h h) +{ + if (h == NULL) + return NULL; + + return h->data; +} + +EXPORT_API unsigned int screen_connector_toolkit_get_event_filter(screen_connector_toolkit_h h) +{ + if (h == NULL) + return 0; + + return h->event_filter; +} + +EXPORT_API int screen_connector_toolkit_check_input_disabled(screen_connector_toolkit_h h, + screen_connector_input_type_e input) +{ + if (h == NULL) { + LOGE("inavlid argument"); + return -1; + } + + return ((h->event_filter & input) > 0); +} + +EXPORT_API struct tizen_remote_surface *screen_connector_toolkit_get_trs(screen_connector_toolkit_h h) +{ + if (h == NULL) + return 0; + + return h->surface; +} diff --git a/screen_connector_watcher/src/screen_connector_trs.c b/screen_connector_watcher/src/screen_connector_trs.c new file mode 100644 index 0000000..fedb303 --- /dev/null +++ b/screen_connector_watcher/src/screen_connector_trs.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "screen_connector_watcher.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "SC_WATCHER" + +static struct tizen_remote_surface_manager *__rsm = NULL; +static struct wayland_tbm_client *__tbm_client; +static struct wl_tbm *__tbm = NULL; +static bool __is_init; + +struct wl_tbm *screen_connector_get_tbm() +{ + return __tbm; +} + +struct tizen_remote_surface_manager *screen_connector_get_rsm() +{ + return __rsm; +} + +int screen_connector_trs_init(void) +{ + int ret = 0; + struct wl_registry *registry; + Ecore_Wl_Global *global; + Eina_Inlist *globals; + + if (__is_init) + return 0; + + ecore_wl_init(NULL); + + registry = ecore_wl_registry_get(); + globals = ecore_wl_globals_get(); + + if (!registry || !globals) { + LOGE("could not get registry(%p) or global list(%p)", registry, + globals); + return -1; + } + + EINA_INLIST_FOREACH(globals, global) { + if (!strcmp(global->interface, "tizen_remote_surface_manager")) { + __rsm = wl_registry_bind(registry, global->id, + &tizen_remote_surface_manager_interface, + global->version < 4 ? global->version : 4); + } + } + + if (!__rsm) { + LOGE("could not get remote surface manager"); + return -1; + } + + __tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get()); + if (!__tbm_client) { + LOGE("could not get tbm client"); + return -1; + } + + __tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(__tbm_client); + if (!__tbm) { + LOGE("could not get tbm"); + return -1; + } + + __is_init = true; + + return ret; +} + +int screen_connector_trs_fini(void) +{ + if (!__is_init) + return 0; + + if (__tbm_client) + wayland_tbm_client_deinit(__tbm_client); + + if (__rsm) + tizen_remote_surface_manager_destroy(__rsm); + + ecore_wl_shutdown(); + + __is_init = false; + return 0; +} + diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index 5e1aa33..36df1d9 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -25,6 +25,7 @@ #include #include +#include "screen_connector_trs.h" #include "screen_connector_watcher.h" #ifdef LOG_TAG @@ -34,215 +35,170 @@ #define LOG_TAG "SC_WATCHER" struct _screen_connector_watcher_h { - char *appid; - int pid; void (*update_cb)(struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time, void *data); void (*missing_cb)(struct tizen_remote_surface *trs, void *data); void (*change_cb)(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, void *data); + screen_connector_watcher_ops *ops; void *data; - struct tizen_remote_surface *surface; - unsigned int event_filter; - int resource_id; + GHashTable *info_table; + aul_screen_viewer_h aul_handle; }; -typedef struct _screen_connector_watcher_h *screen_connector_watcher_h; - -static struct tizen_remote_surface_manager *__rsm; -static struct wayland_tbm_client *__tbm_client; -static struct wl_tbm *__tbm; -static bool __is_init; -static GList *__watcher_list; -static GList *__pending_watcher_list; -static aul_screen_viewer_handler __aul_cbs; +struct _screen_connector_info_h { + char *appid; + char *instance_id; + int pid; + int surface_id; + screen_connector_watcher_ops *ops; + struct tizen_remote_surface *surface; + bool renderable; + void *data; +}; static void __buffer_updated(void *data, struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time) { - screen_connector_watcher_h watcher_h = (screen_connector_watcher_h)data; - - if (watcher_h) - watcher_h->update_cb(trs, buffer, time, watcher_h->data); } static void __buffer_missing(void *data, struct tizen_remote_surface *trs) { - screen_connector_watcher_h watcher_h = (screen_connector_watcher_h)data; + screen_connector_info_h info = (screen_connector_info_h)data; - if (watcher_h) - watcher_h->missing_cb(trs, watcher_h->data); + if (info) + info->ops->removed_cb(info->appid, info->instance_id, info->pid, info->data); } static void __buffer_changed(void *data, struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys) { - screen_connector_watcher_h watcher_h = (screen_connector_watcher_h)data; - - if (watcher_h) - watcher_h->change_cb(trs, type, tbm, img_file_fd, img_file_size, time, keys, watcher_h->data); -} + screen_connector_info_h info = (screen_connector_info_h)data; -static void __input_event_filter(void *data, struct tizen_remote_surface *trs, uint32_t event_filter) -{ - screen_connector_watcher_h watcher_h = (screen_connector_watcher_h)data; + if (info && info->ops) { - if (watcher_h) - watcher_h->event_filter = event_filter; + if (info->renderable) { + info->renderable = false; + tizen_remote_surface_set_remote_render(info->surface, 0); + } - LOGD("event filter updated:%d", event_filter); + info->ops->updated_cb(trs, type, tbm, img_file_fd, img_file_size, time, keys, info->appid, + info->instance_id, info->pid, info->data); + } } static const struct tizen_remote_surface_listener __rs_listener = { __buffer_updated, __buffer_missing, __buffer_changed, - __input_event_filter, }; -static void __app_removed(const char *appid, const int pid, void *data) +EXPORT_API int screen_connector_watcher_redirect_surface(screen_connector_info_h info) { -} -EXPORT_API void screen_connector_watcher_redirect_surface(screen_connector_watcher_h watcher_h) -{ - if (watcher_h == NULL) - return; + struct wl_tbm *tbm = screen_connector_get_tbm(); + struct tizen_remote_surface_manager *rsm = screen_connector_get_rsm(); + if (info == NULL || rsm == NULL || tbm == NULL) + return -1; - watcher_h->surface = tizen_remote_surface_manager_create_surface(__rsm, (uint32_t)watcher_h->resource_id, __tbm); - if (watcher_h->surface == NULL) - return; + info->surface = tizen_remote_surface_manager_create_surface(rsm, (uint32_t)info->surface_id, tbm); + if (info->surface == NULL) + return -1; - LOGD("resource_id : %d, (%p)", watcher_h->resource_id, watcher_h->surface); - tizen_remote_surface_add_listener(watcher_h->surface, &__rs_listener, watcher_h); - tizen_remote_surface_redirect(watcher_h->surface); + LOGD("resource_id : %d, (%p)", info->surface_id, info->surface); + tizen_remote_surface_add_listener(info->surface, &__rs_listener, info); + tizen_remote_surface_redirect(info->surface); + + return 0; } -static screen_connector_watcher_h __create_watcher_handle_info(char *appid) +static void __destroy_screen_info(gpointer data) { - screen_connector_watcher_h watcher_h; + screen_connector_info_h info = (screen_connector_info_h)data; - watcher_h = (screen_connector_watcher_h)calloc(1, sizeof(struct _screen_connector_watcher_h)); - if (watcher_h == NULL) { - LOGE("watcher_h calloc fail"); - return NULL; - } + if (info == NULL) + return; - watcher_h->appid = strdup(appid); - if (watcher_h->appid == NULL) { - LOGE("out of memory"); - free(watcher_h); - return NULL; - } + LOGD("__destroy_screen_info appid: %s surface_id %d", info->appid, info->surface_id); - return watcher_h; -} + if (info->appid) { + free(info->appid); + info->appid = NULL; + } -static void __app_added(const char *appid, const int pid, const unsigned int resource_id, void *data) -{ - screen_connector_watcher_h watcher_h = NULL; - screen_connector_watcher_h cur_h; - GList *watcher_list = __watcher_list; - - LOGD("__app_added pid: %d, resource_id: %d, appid: %s", pid, resource_id, appid); - for (; watcher_list != NULL; watcher_list = watcher_list->next) { - cur_h = (screen_connector_watcher_h)watcher_list->data; - if (strcmp(cur_h->appid, appid) == 0) { - watcher_h = cur_h; - __watcher_list = g_list_remove(__watcher_list, cur_h); - break; - } + if (info->instance_id) { + free(info->instance_id); + info->instance_id = NULL; } - if (watcher_h == NULL) { - watcher_h = __create_watcher_handle_info((char *)appid); - watcher_h->pid = pid; - watcher_h->resource_id = resource_id; - __pending_watcher_list = g_list_append(__pending_watcher_list, watcher_h); + if (info->surface) { + if (info->renderable) + tizen_remote_surface_set_remote_render(info->surface, 0); - LOGD("add pending list: %d, resource_id: %d, appid: %s", pid, resource_id, appid); - return; + tizen_remote_surface_set_user_data(info->surface, NULL); + tizen_remote_surface_unredirect(info->surface); + tizen_remote_surface_destroy(info->surface); + info->surface = NULL; } - watcher_h->resource_id = resource_id; - watcher_h->pid = pid; - if (resource_id > 0) - screen_connector_watcher_redirect_surface(watcher_h); - else - LOGE("bad tbm message received. missing arguments"); + free(info); } -EXPORT_API int screen_connector_watcher_init(void) +static void __aul_screen_viewer_cb(const char *appid, const char *instance_id, + const int pid, const unsigned int surface_id, + aul_screen_connector_event_type_e event_type, void *data) { - int ret = 0; - struct wl_registry *registry; - Ecore_Wl_Global *global; - Eina_Inlist *globals; + screen_connector_watcher_h watcher_h = (screen_connector_watcher_h)data; + screen_connector_info_h info = (screen_connector_info_h)calloc(1, sizeof(struct _screen_connector_info_h)); + screen_connector_info_h cur_info; - if (__is_init) - return 0; + LOGD("__aul_screen_viewer_cb pid: %d, surface_id: %d, appid: %s type %d", pid, surface_id, appid, event_type); + info->appid = strdup(appid); + info->instance_id = strdup(instance_id); + info->pid = pid; + info->surface_id = surface_id; + info->ops = watcher_h->ops; + info->data = watcher_h->data; + info->renderable = false; - ecore_wl_init(NULL); + if (event_type == AUL_SCREEN_CONNECTOR_EVENT_TYPE_ADD) { - registry = ecore_wl_registry_get(); - globals = ecore_wl_globals_get(); + g_hash_table_insert(watcher_h->info_table, + strdup(instance_id), info); - if (!registry || !globals) { - LOGE("could not get registry(%p) or global list(%p)", registry, - globals); - return -1; - } + info->ops->added_cb(appid, instance_id, pid, info->data); + screen_connector_watcher_redirect_surface(info); + + } else if (event_type == AUL_SCREEN_CONNECTOR_EVENT_TYPE_UPDATE) { - EINA_INLIST_FOREACH(globals, global) { - if (!strcmp(global->interface, "tizen_remote_surface_manager")) { - __rsm = wl_registry_bind(registry, global->id, - &tizen_remote_surface_manager_interface, - global->version < 4 ? global->version : 4); + cur_info = g_hash_table_lookup(watcher_h->info_table, instance_id); + if (cur_info && cur_info->surface_id != surface_id) { + cur_info->ops->removed_cb(appid, instance_id, pid, cur_info->data); + g_hash_table_remove(watcher_h->info_table, instance_id); } - } - if (!__rsm) { - LOGE("could not get remote surface manager"); - return -1; - } + g_hash_table_insert(watcher_h->info_table, strdup(instance_id), info); - __tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get()); - if (!__tbm_client) { - LOGE("could not get tbm client"); - return -1; - } + info->ops->added_cb(appid, instance_id, pid, info->data); + screen_connector_watcher_redirect_surface(info); + } else if (event_type == AUL_SCREEN_CONNECTOR_EVENT_TYPE_REMOVE) { - __tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(__tbm_client); - if (!__tbm) { - LOGE("could not get tbm"); - return -1; + info->ops->removed_cb(appid, instance_id, pid, info->data); + g_hash_table_remove(watcher_h->info_table, instance_id); + __destroy_screen_info(info); } +} - __aul_cbs.app_added = __app_added; - __aul_cbs.app_removed = __app_removed; - aul_screen_connector_add_screen_viewer(&__aul_cbs, NULL); - - __is_init = true; - +EXPORT_API int screen_connector_watcher_init(void) +{ + int ret = 0; + ret = screen_connector_trs_init(); return ret; } EXPORT_API int screen_connector_watcher_fini(void) { - if (!__is_init) - return 0; - - if (aul_screen_connector_remove_app_screen() != 0) - return -1; - - if (__tbm_client) - wayland_tbm_client_deinit(__tbm_client); - - if (__rsm) - tizen_remote_surface_manager_destroy(__rsm); - - ecore_wl_shutdown(); - - __is_init = false; - return 0; + int ret = 0; + ret = screen_connector_trs_fini(); + return ret; } static void __destroy_watcher_h(screen_connector_watcher_h handle) @@ -250,73 +206,31 @@ static void __destroy_watcher_h(screen_connector_watcher_h handle) if (!handle) return; - if (handle->surface) { - tizen_remote_surface_set_user_data(handle->surface, NULL); - tizen_remote_surface_unredirect(handle->surface); - tizen_remote_surface_destroy(handle->surface); - handle->surface = NULL; - } + if (handle->aul_handle) + aul_screen_connector_remove_screen_viewer(handle->aul_handle); - if (__pending_watcher_list) - __pending_watcher_list = g_list_remove(__pending_watcher_list, handle); - - if (__watcher_list) - __watcher_list = g_list_remove(__watcher_list, handle); - - if (handle->appid) { - free(handle->appid); - handle->appid = NULL; - } + if (handle->info_table) + g_hash_table_destroy(handle->info_table); free(handle); } -EXPORT_API screen_connector_watcher_h screen_connector_watcher_create_handle(char *id, int pid, screen_connector_watcher_ops *ops, void *data) +EXPORT_API screen_connector_watcher_h screen_connector_watcher_add(screen_connector_watcher_ops *ops, void *data) { screen_connector_watcher_h watcher_h = NULL; + aul_screen_viewer_h handle = NULL; - watcher_h = __create_watcher_handle_info(id); - if (watcher_h == NULL) + watcher_h = (screen_connector_watcher_h)calloc(1, sizeof(struct _screen_connector_watcher_h)); + if (watcher_h == NULL) { + LOGE("watcher_h calloc fail"); return NULL; - - watcher_h->update_cb = ops->update_cb; - watcher_h->change_cb = ops->change_cb; - watcher_h->missing_cb = ops->missing_cb; - watcher_h->pid = pid; - watcher_h->data = data; - - return watcher_h; -} - -EXPORT_API screen_connector_watcher_h screen_connector_watcher_add(screen_connector_watcher_ops *ops, char *id, void *data) -{ - screen_connector_watcher_h watcher_h = NULL; - screen_connector_watcher_h cur_h; - GList *watcher_list = __pending_watcher_list; - - for (; watcher_list != NULL; watcher_list = watcher_list->next) { - cur_h = (screen_connector_watcher_h)watcher_list->data; - if (strcmp(cur_h->appid, id) == 0) { - watcher_h = cur_h; - __pending_watcher_list = g_list_remove(__pending_watcher_list, cur_h); - break; - } - } - - if (watcher_h != NULL) { - watcher_h->update_cb = ops->update_cb; - watcher_h->change_cb = ops->change_cb; - watcher_h->missing_cb = ops->missing_cb; - watcher_h->data = data; - screen_connector_watcher_redirect_surface(watcher_h); - } else { - watcher_h = __create_watcher_handle_info(id); - watcher_h->update_cb = ops->update_cb; - watcher_h->change_cb = ops->change_cb; - watcher_h->missing_cb = ops->missing_cb; - watcher_h->data = data; - __watcher_list = g_list_append(__watcher_list, watcher_h); } + watcher_h->data = data; + watcher_h->ops = ops; + watcher_h->info_table = g_hash_table_new_full(g_str_hash, + g_str_equal, free, __destroy_screen_info); + aul_screen_connector_add_screen_viewer(__aul_screen_viewer_cb, AUL_SCREEN_TYPE_UI, false, watcher_h, &handle); + watcher_h->aul_handle = handle; return watcher_h; } @@ -332,67 +246,55 @@ EXPORT_API int screen_connector_watcher_remove(screen_connector_watcher_h h) return 0; } -EXPORT_API int screen_connector_watcher_update(const char *appid) +EXPORT_API int screen_connector_watcher_update(screen_connector_watcher_h h, const char *instance_id) { - return aul_screen_connector_update_app_screen(appid); -} + screen_connector_info_h info; -EXPORT_API char *screen_connector_watcher_get_appid(screen_connector_watcher_h h) -{ - if (h == NULL) - return NULL; + if (h == NULL) { + LOGE("toolkit_h is NULL"); + return -1; + } - return h->appid; -} + if (h->info_table == NULL) { + LOGE("info_table is NULL"); + return -1; + } -EXPORT_API int screen_connector_watcher_get_pid(screen_connector_watcher_h h) -{ - if (h == NULL) + info = (screen_connector_info_h)g_hash_table_lookup(h->info_table, instance_id); + if (info == NULL) { + LOGE("invalid instance_id %s", instance_id); return -1; + } - return h->pid; + LOGI("send update request to %s", instance_id); + tizen_remote_surface_set_remote_render(info->surface, 1); + /* flag will be cleared when buffer changed event received */ + info->renderable = true; + + return aul_screen_connector_send_update_request(info->appid, info->instance_id); } -EXPORT_API int screen_connector_watcher_get_resource_id(screen_connector_watcher_h h) +EXPORT_API char *screen_connector_watcher_get_appid(screen_connector_info_h h) { - if (h == NULL) - return -1; - - return h->resource_id; + return h->appid; } -EXPORT_API int screen_connector_watcher_set_resource_id(screen_connector_watcher_h h, int rid) +EXPORT_API char *screen_connector_watcher_get_instance_id(screen_connector_info_h h) { - if (h == NULL) - return -1; - - h->resource_id = rid; - return 0; + return h->instance_id; } -EXPORT_API struct tizen_remote_surface *screen_connector_watcher_get_trs(screen_connector_watcher_h h) +EXPORT_API int screen_connector_watcher_get_pid(screen_connector_info_h h) { - if (h == NULL) - return NULL; - - return h->surface; + return h->pid; } -EXPORT_API unsigned int screen_connector_watcher_get_event_filter(screen_connector_watcher_h h) +EXPORT_API int screen_connector_watcher_get_surface_id(screen_connector_info_h h) { - if (h == NULL) - return 0; - - return h->event_filter; + return h->surface_id; } -EXPORT_API int screen_connector_watcher_check_input_disabled(screen_connector_watcher_h h, - screen_connector_input_type_e input) +EXPORT_API void *screen_connector_watcher_get_user_data(screen_connector_info_h h) { - if (h == NULL) { - LOGE("inavlid argument"); - return -1; - } - - return ((h->event_filter & input) > 0); + return h->data; } diff --git a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h new file mode 100644 index 0000000..1fb75f6 --- /dev/null +++ b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SCREEN_CONNECTOR_TOOLKIT_EVAS_H__ +#define __SCREEN_CONNECTOR_TOOLKIT_EVAS_H__ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file screen_connector_toolkit_evas.h + * @brief This file declares API of libscreen_connector library + * @since_tizen 3.0 + */ + +/** + * @addtogroup CAPI_SCREEN_CONNECTOR_WATCHER_EVAS_MODULE + * @{ + */ + +typedef enum { + VISIBILITY_TYPE_UNOBSCURED, + VISIBILITY_TYPE_PARTIALLY_OBSCURED, + VISIBILITY_TYPE_FULLY_OBSCURED, +} visibility_type; + +typedef void (*screen_connector_toolkit_evas_added_cb)(const char *appid, const char *instance_id, const int pid, + Evas_Object *image, void *data); +typedef void (*screen_connector_toolkit_evas_removed_cb)(const char *appid, const char *instance_id, const int pid, + Evas_Object *image, void *data); +typedef void (*screen_connector_toolkit_evas_updated_cb)(const char *appid, const char *instance_id, const int pid, + Evas_Object *image, void *data); + +typedef struct _screen_connector_toolkit_evas_ops { + screen_connector_toolkit_evas_added_cb added_cb; + screen_connector_toolkit_evas_removed_cb removed_cb; + screen_connector_toolkit_evas_updated_cb updated_cb; +} screen_connector_toolkit_evas_ops; + +typedef struct _screen_connector_toolkit_evas_h *screen_connector_toolkit_evas_h; +typedef struct _screen_connector_type_evas_h *screen_connector_type_evas_h; + +int screen_connector_toolkit_evas_init(Evas_Object *win, screen_connector_screen_type_e type); +int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e type); +screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(screen_connector_toolkit_evas_ops *ops, char *id, + screen_connector_screen_type_e type, void *data); +int screen_connector_toolkit_evas_remove(screen_connector_toolkit_evas_h handle); +int screen_connector_toolkit_evas_update(const char *appid, const char *instance_id); +int screen_connector_toolkit_evas_start_visibility_notify(void); +int screen_connector_toolkit_evas_stop_visibility_notify(void); +int screen_connector_toolkit_evas_freeze_visibility(Evas_Object *obj, visibility_type type); +int screen_connector_toolkit_evas_thaw_visibility(Evas_Object *obj); +int screen_connector_toolkit_evas_send_mouse_up(Evas_Object *obj); +int screen_connector_toolkit_evas_send_touch_cancel(Evas_Object *obj); + +/** + * @brief Add screen connector toolkit by rid. + * @details Using this API, viewer can watch screen which already watched by other viewer.\n + * @since_tizen 3.0 + * @param[in] obj screen image object + * @param[out] pid screen provider pid + * @return 0 if success, negative value(<0) if fail + * + * @remark + * This API is only for main viewer. \n + * Sub viewer can not get provider's information like provider's pid by screen image object. + * @see screen_connector_toolkit_evas_add_by_rid() +*/ +int screen_connector_toolkit_evas_get_pid(Evas_Object *obj, int *pid); + +/** + * @brief Add screen connector toolkit by rid. + * @details Using this API, viewer can watch screen which already watched by other viewer.\n + * @since_tizen 3.0 + * @param[in] ops screen toolkit evas callback handler function + * @param[in] res_id screen provider rid + * @param[in] data user-supplied data for toolkit handler + * @return @c Not null on success + * + * @remark + * This API is only for sub viewer. \n + * Sub viewer can not get provider's information like provider's pid by screen image object. +*/ +screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_rid(screen_connector_toolkit_evas_ops *ops, int res_id, + screen_connector_screen_type_e type, void *data); +int screen_connector_toolkit_evas_get_rid(Evas_Object *obj, int *resource_id); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SCREEN_CONNECTOR_WATCHER_EVAS_H__ */ diff --git a/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h b/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h index 3e429cb..75959dd 100644 --- a/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h +++ b/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h @@ -20,11 +20,12 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { #endif - /** * @file screen_connector_watcher_evas.h * @brief This file declares API of libscreen_connector library @@ -36,66 +37,24 @@ extern "C" { * @{ */ -typedef enum { - VISIBILITY_TYPE_UNOBSCURED, - VISIBILITY_TYPE_PARTIALLY_OBSCURED, - VISIBILITY_TYPE_FULLY_OBSCURED, -} visibility_type; - -typedef void (*screen_connector_watcher_evas_added_cb)(const char *appid, Evas_Object *image, void *data); -typedef void (*screen_connector_watcher_evas_removed_cb)(const char *appid, Evas_Object *image, void *data); -typedef void (*screen_connector_watcher_evas_updated_cb)(const char *appid, Evas_Object *image, void *data); +typedef void (*screen_connector_watcher_evas_added_cb)(const char *appid, const char *instance_id, const int pid, void *data); +typedef void (*screen_connector_watcher_evas_removed_cb)(const char *appid, const char *instance_id, const int pid, void *data); +typedef void (*screen_connector_watcher_evas_updated_cb)(const char *appid, const char *instance_id, const int pid, + Evas_Object *image, void *data); typedef struct _screen_connector_watcher_evas_ops { - screen_connector_watcher_evas_added_cb added; - screen_connector_watcher_evas_removed_cb removed; - screen_connector_watcher_evas_updated_cb updated; + screen_connector_watcher_evas_added_cb added_cb; + screen_connector_watcher_evas_removed_cb removed_cb; + screen_connector_watcher_evas_updated_cb updated_cb; } screen_connector_watcher_evas_ops; typedef struct _screen_connector_watcher_evas_h *screen_connector_watcher_evas_h; int screen_connector_watcher_evas_init(Evas_Object *win); int screen_connector_watcher_evas_fini(void); -screen_connector_watcher_evas_h screen_connector_watcher_evas_add(screen_connector_watcher_evas_ops *ops, char *id, void *data); -int screen_connector_watcher_evas_remove(screen_connector_watcher_evas_h handle); -int screen_connector_watcher_evas_update(const char *appid); -int screen_connector_watcher_evas_start_visibility_notify(void); -int screen_connector_watcher_evas_stop_visibility_notify(void); -int screen_connector_watcher_evas_freeze_visibility(Evas_Object *obj, visibility_type type); -int screen_connector_watcher_evas_thaw_visibility(Evas_Object *obj); -int screen_connector_watcher_evas_send_mouse_up(Evas_Object *obj); -int screen_connector_watcher_evas_send_touch_cancel(Evas_Object *obj); - -/** - * @brief Add screen connector watcher by rid. - * @details Using this API, viewer can watch screen which already watched by other viewer.\n - * @since_tizen 3.0 - * @param[in] obj screen image object - * @param[out] pid screen provider pid - * @return 0 if success, negative value(<0) if fail - * - * @remark - * This API is only for main viewer. \n - * Sub viewer can not get provider's information like provider's pid by screen image object. - * @see screen_connector_watcher_evas_add_by_rid() -*/ -int screen_connector_watcher_evas_get_pid(Evas_Object *obj, int *pid); - -/** - * @brief Add screen connector watcher by rid. - * @details Using this API, viewer can watch screen which already watched by other viewer.\n - * @since_tizen 3.0 - * @param[in] ops screen watcher evas callback handler function - * @param[in] res_id screen provider rid - * @param[in] data user-supplied data for watcher handler - * @return @c Not null on success - * - * @remark - * This API is only for sub viewer. \n - * Sub viewer can not get provider's information like provider's pid by screen image object. -*/ -screen_connector_watcher_evas_h screen_connector_watcher_evas_add_by_rid(screen_connector_watcher_evas_ops *ops, int res_id, void *data); -int screen_connector_watcher_evas_get_rid(Evas_Object *obj, int *resource_id); +screen_connector_watcher_evas_h screen_connector_watcher_evas_add(screen_connector_watcher_evas_ops *ops, void *data); +int screen_connector_watcher_evas_remove(screen_connector_watcher_evas_h h); +int screen_connector_watcher_evas_update(screen_connector_watcher_evas_h watcher_evas_h, const char *instance_id); /** * @} diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c new file mode 100644 index 0000000..a442f36 --- /dev/null +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -0,0 +1,903 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "screen_connector_toolkit.h" +#include "screen_connector_toolkit_evas.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "SC_WATCHER_EVAS" + +struct _screen_connector_type_evas_h { + GHashTable *toolkit_table; + Evas_Object *viewer_win; +}; + +struct _screen_connector_toolkit_evas_h { + screen_connector_toolkit_evas_ops *ops; + screen_connector_toolkit_h toolkit_h; + int freeze; + bool is_init; + bool cancel_touch; + Evas_Object *img_tbm; + Evas_Object *img_file; + uint32_t img_type; + struct wl_buffer *pre_buffer; + struct _screen_connector_type_evas_h *type_h; + void *data; +}; + +static GHashTable *__type_table = NULL; +static Ecore_Event_Handler *__visibility_listener; + +static void __destroy_type_h(gpointer data) +{ + screen_connector_type_evas_h type_h = (screen_connector_type_evas_h)data; + if (!type_h) + return; + + if (type_h->toolkit_table) + g_hash_table_destroy(type_h->toolkit_table); + free(type_h); +} + +EXPORT_API int screen_connector_toolkit_evas_init(Evas_Object *win, screen_connector_screen_type_e type) +{ + screen_connector_type_evas_h type_h; + int *key; + + if (__type_table == NULL) + __type_table = g_hash_table_new_full(g_int_hash, g_int_equal, free, __destroy_type_h); + + type_h = g_hash_table_lookup(__type_table, &type); + if (type_h == NULL) { + key = (int *)calloc(1, sizeof(int)); + *key = type; + + type_h = (screen_connector_type_evas_h)calloc(1, sizeof(struct _screen_connector_type_evas_h)); + g_hash_table_insert(__type_table, key, type_h); + + type_h->toolkit_table = g_hash_table_new(g_direct_hash, g_direct_equal); + if (!type_h->toolkit_table) { + LOGE("failed to create table"); + return -1; + } + } + + type_h->viewer_win = win; + return screen_connector_toolkit_init(type); +} + +EXPORT_API int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e type) +{ + screen_connector_type_evas_h type_h; + + if (__type_table == NULL) { + LOGI("__type_table is NULL"); + return 0; + } + + type_h = g_hash_table_lookup(__type_table, &type); + if (type_h) { + if (type_h->toolkit_table) + g_hash_table_destroy(type_h->toolkit_table); + g_hash_table_remove(__type_table, &type); + } + + if (g_hash_table_size(__type_table) == 0) { + g_hash_table_destroy(__type_table); + __type_table = NULL; + } + + return screen_connector_toolkit_fini(type); +} + +static bool __obj_is_visible(Evas_Object *obj, screen_connector_toolkit_evas_h toolkit_evas_h) +{ + int x, y, w, h; + Ecore_Wl_Window *window = NULL; + int window_x, window_y, window_w, window_h; + int rotation; + + if (toolkit_evas_h->type_h == NULL || toolkit_evas_h->type_h->viewer_win == NULL) { + LOGE("type_h is NULL"); + return false; + } + + window = elm_win_wl_window_get(toolkit_evas_h->type_h->viewer_win); + ecore_wl_window_geometry_get(window, &window_x, &window_y, &window_w, &window_h); + evas_object_geometry_get(obj, &x, &y, &w, &h); + rotation = ecore_wl_window_rotation_get(window); + + if (x >= 0 && x < window_w && + y >= 0 && y < window_h && + (rotation == 0 || rotation == 180)) { + LOGD("x %d, y %d w %d h %d, window_w %d window_h %d rotation %d", + x, y, w, h, window_w, window_h, rotation); + return true; + } else if (x >= 0 && x < window_h && + y >= 0 && y < window_w && + (rotation == 90 || rotation == 270)) { + LOGD("x %d, y %d w %d h %d, window_w %d window_h %d rotation %d", + x, y, w, h, window_w, window_h, rotation); + return true; + } + + return false; +} + +static int __set_visibility(screen_connector_toolkit_evas_h toolkit_evas_h, visibility_type type) +{ + int obscured; + struct tizen_remote_surface *surface; + + if (!toolkit_evas_h) { + LOGE("obj not found"); + return -1; + } + + switch (type) { + case VISIBILITY_TYPE_UNOBSCURED: + case VISIBILITY_TYPE_PARTIALLY_OBSCURED: + obscured = TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE; + break; + case VISIBILITY_TYPE_FULLY_OBSCURED: + obscured = TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_INVISIBLE; + break; + default: + return -1; + } + + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface) + tizen_remote_surface_transfer_visibility(surface, obscured); + + return 0; +} + +static void __obj_update_visibility(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)data; + + if (!toolkit_evas_h->is_init) { + toolkit_evas_h->is_init = true; + return; + } + + if (__obj_is_visible(obj, toolkit_evas_h)) + __set_visibility(toolkit_evas_h, VISIBILITY_TYPE_UNOBSCURED); + else + __set_visibility(toolkit_evas_h, VISIBILITY_TYPE_FULLY_OBSCURED); +} + +static void __rs_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)data; + Evas_Event_Mouse_Down *ev = event_info; + const char *desc = evas_device_description_get(ev->dev); + int x; + int y; + int w; + int h; + struct tizen_remote_surface *surface; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + LOGD("mouse down: %d %d", ev->canvas.x - x, ev->canvas.y - y); + + if (desc == NULL) + desc = ""; + + if (screen_connector_toolkit_check_input_disabled(toolkit_evas_h->toolkit_h, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_UP_DOWN)) { + LOGD("mouse down disabled"); + return; + } + + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface == NULL) { + LOGE("surface is NULL"); + return; + } + + tizen_remote_surface_transfer_mouse_event(surface, + TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN, + 0, + ev->button, + ev->canvas.x - x, + ev->canvas.y - y, + wl_fixed_from_double(ev->radius_x), + wl_fixed_from_double(ev->radius_y), + wl_fixed_from_double(ev->pressure), + wl_fixed_from_double(ev->angle), + evas_device_class_get(ev->dev), + evas_device_subclass_get(ev->dev), + desc, + ev->timestamp); +} + +static void __rs_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)data; + Evas_Event_Mouse_Up *ev = event_info; + const char *desc = evas_device_description_get(ev->dev); + int x; + int y; + int w; + int h; + struct tizen_remote_surface *surface; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + LOGD("mouse up: %d %d", ev->canvas.x - x, ev->canvas.y - y); + + if (desc == NULL) + desc = ""; + + if (screen_connector_toolkit_check_input_disabled(toolkit_evas_h->toolkit_h, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_UP_DOWN)) { + LOGD("mouse up disabled"); + return; + } + + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface == NULL) { + LOGE("surface is NULL"); + return; + } + + tizen_remote_surface_transfer_mouse_event(surface, + TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP, + 0, + ev->button, + ev->canvas.x - x, + ev->canvas.y - y, + wl_fixed_from_double(ev->radius_x), + wl_fixed_from_double(ev->radius_y), + wl_fixed_from_double(ev->pressure), + wl_fixed_from_double(ev->angle), + evas_device_class_get(ev->dev), + evas_device_subclass_get(ev->dev), + desc, + ev->timestamp); +} + +static void __rs_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)data; + Evas_Event_Mouse_Move *ev = event_info; + const char *desc = evas_device_description_get(ev->dev); + int x; + int y; + int w; + int h; + struct tizen_remote_surface *surface; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + LOGD("mouse move: %d %d", ev->cur.canvas.x - x, ev->cur.canvas.y - y); + + if (desc == NULL) + desc = ""; + + if (screen_connector_toolkit_check_input_disabled(toolkit_evas_h->toolkit_h, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_X_Y)) { + LOGD("mouse move disabled"); + return; + } + + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface == NULL) { + LOGE("surface is NULL"); + return; + } + + tizen_remote_surface_transfer_mouse_event(surface, + TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE, + 0, + 0, + ev->cur.canvas.x - x, + ev->cur.canvas.y - y, + wl_fixed_from_double(ev->radius_x), + wl_fixed_from_double(ev->radius_y), + wl_fixed_from_double(ev->pressure), + wl_fixed_from_double(ev->angle), + evas_device_class_get(ev->dev), + evas_device_subclass_get(ev->dev), + desc, + ev->timestamp); +} + +static void __rs_cb_mouse_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)data; + Evas_Event_Mouse_Wheel *ev = event_info; + const char *desc = evas_device_description_get(ev->dev); + struct tizen_remote_surface *surface; + + LOGD("mouse wheel"); + + if (desc == NULL) + desc = ""; + + if (screen_connector_toolkit_check_input_disabled(toolkit_evas_h->toolkit_h, + SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_WHEEL)) { + LOGD("mouse wheel disabled"); + return; + } + + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface == NULL) { + LOGE("surface is NULL"); + return; + } + + tizen_remote_surface_transfer_mouse_wheel(surface, + ev->direction, + ev->z, + evas_device_class_get(ev->dev), + evas_device_subclass_get(ev->dev), + desc, + ev->timestamp); +} + +static void __rs_cb_show(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + LOGD("show"); + __obj_update_visibility(data, e, obj, event_info); +} + +static void __rs_cb_hide(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + LOGD("hide"); +} + +static void __rs_cb_resize(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + LOGD("resize"); + __obj_update_visibility(data, e, obj, event_info); +} + +static void __clear_img_tbm(screen_connector_toolkit_evas_h toolkit_evas_h) +{ + if (toolkit_evas_h->img_tbm == NULL) + return; + + g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm); + evas_object_del(toolkit_evas_h->img_tbm); + toolkit_evas_h->img_tbm = NULL; +} + +static void __clear_img_file(screen_connector_toolkit_evas_h toolkit_evas_h) +{ + if (toolkit_evas_h->img_file == NULL) + return; + + evas_object_del(toolkit_evas_h->img_file); + toolkit_evas_h->img_file = NULL; +} + +static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, + int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, + const char *appid, const char *instance_id, const int pid, void *data) +{ + bool is_added = false; + Evas_Native_Surface ns; + tbm_surface_h tbm_surface; + int width, height; + char *map; + char format[] = "png"; + char plug_id[256]; + screen_connector_toolkit_evas_h toolkit_evas_h; + + toolkit_evas_h = (screen_connector_toolkit_evas_h)data; + if (toolkit_evas_h->img_tbm == NULL) { + LOGD("first added !!!! %d, %d %s", (toolkit_evas_h->img_tbm == NULL), type, appid); + toolkit_evas_h->img_tbm = evas_object_image_filled_add( + evas_object_evas_get(toolkit_evas_h->type_h->viewer_win)); + + /* Image alpha set */ + evas_object_image_alpha_set(toolkit_evas_h->img_tbm, 1); + + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_MOUSE_DOWN, + __rs_cb_mouse_down, toolkit_evas_h); + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_MOUSE_UP, + __rs_cb_mouse_up, toolkit_evas_h); + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_MOUSE_MOVE, + __rs_cb_mouse_move, toolkit_evas_h); + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_MOUSE_WHEEL, + __rs_cb_mouse_wheel, toolkit_evas_h); + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_SHOW, + __rs_cb_show, toolkit_evas_h); + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_HIDE, + __rs_cb_hide, toolkit_evas_h); + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_RESIZE, + __rs_cb_resize, toolkit_evas_h); + + /* Store toolkit_evas_h */ + g_hash_table_insert(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm, toolkit_evas_h); + + /* Set data to use in accessibility */ + snprintf(plug_id, sizeof(plug_id), "%s:%d", appid, pid); + evas_object_data_set(toolkit_evas_h->img_tbm, "___PLUGID", strdup(plug_id)); + evas_object_event_callback_add(toolkit_evas_h->img_tbm, + EVAS_CALLBACK_MOVE, __obj_update_visibility, toolkit_evas_h); + } + + if (toolkit_evas_h->img_type != type) + is_added = true; + toolkit_evas_h->img_type = type; + + /* check type of given buffer */ + if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM) { + /* get tbm surface from buffer */ + tbm_surface = wl_buffer_get_user_data(tbm); + width = tbm_surface_get_width(tbm_surface); + height = tbm_surface_get_height(tbm_surface); + + memset(&ns, 0, sizeof(Evas_Native_Surface)); + ns.version = EVAS_NATIVE_SURFACE_VERSION; + ns.type = EVAS_NATIVE_SURFACE_TBM; + ns.data.tbm.buffer = tbm_surface; + + evas_object_resize(toolkit_evas_h->img_tbm, width, height); + evas_object_image_size_set(toolkit_evas_h->img_tbm, width, height); + evas_object_image_native_surface_set(toolkit_evas_h->img_tbm, &ns); /* set native surface */ + evas_object_image_pixels_dirty_set(toolkit_evas_h->img_tbm, EINA_TRUE); /* set dirty for image updating */ + } else if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE) { + if (!toolkit_evas_h->img_file) + toolkit_evas_h->img_file = evas_object_image_filled_add(evas_object_evas_get(toolkit_evas_h->type_h->viewer_win)); + + map = mmap(NULL, img_file_size, PROT_READ, MAP_SHARED, img_file_fd, 0); + evas_object_image_memfile_set(toolkit_evas_h->img_file, map, img_file_size, format, NULL); + evas_object_image_size_get(toolkit_evas_h->img_tbm, &width, &height); + evas_object_image_fill_set(toolkit_evas_h->img_file, 0, 0, width, height); + evas_object_resize(toolkit_evas_h->img_file, width, height); + munmap(map, img_file_size); + + evas_object_image_native_surface_set(toolkit_evas_h->img_tbm, NULL); /* set null to previous object for the tbm type */ + } + + if (toolkit_evas_h->pre_buffer) { + if (tizen_remote_surface_get_version(trs) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION) + tizen_remote_surface_release(trs, toolkit_evas_h->pre_buffer); + } + toolkit_evas_h->pre_buffer = tbm; + + if (is_added) { + LOGD("call added !!!! %s, type %d", appid, type); + if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE) { + toolkit_evas_h->ops->added_cb(appid, instance_id, pid, toolkit_evas_h->img_file, + toolkit_evas_h->data); + __clear_img_tbm(toolkit_evas_h); + } else { + toolkit_evas_h->ops->added_cb(appid, instance_id, pid, toolkit_evas_h->img_tbm, + toolkit_evas_h->data); + __clear_img_file(toolkit_evas_h); + } + } else { + LOGD("call updated !!!! %s, type %d", appid, type); + if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE) { + toolkit_evas_h->ops->updated_cb(appid, instance_id, pid, toolkit_evas_h->img_file, + toolkit_evas_h->data); + __clear_img_tbm(toolkit_evas_h); + } else { + toolkit_evas_h->ops->updated_cb(appid, instance_id, pid, toolkit_evas_h->img_tbm, + toolkit_evas_h->data); + __clear_img_file(toolkit_evas_h); + } + } + close(img_file_fd); /* close passed fd */ +} + +static void __toolkit_added_cb(const char *appid, const char *instance_id, const int pid, void *data) +{ +} + +static void __free_toolkit_evas_h(screen_connector_toolkit_evas_h toolkit_evas_h) +{ + if (!toolkit_evas_h) + return; + + if (toolkit_evas_h->toolkit_h) + screen_connector_toolkit_remove(toolkit_evas_h->toolkit_h); + + __clear_img_file(toolkit_evas_h); + __clear_img_tbm(toolkit_evas_h); + + if (toolkit_evas_h->ops) { + free(toolkit_evas_h->ops); + toolkit_evas_h->ops = NULL; + } + + free(toolkit_evas_h); +} + +static void __toolkit_removed_cb(const char *appid, const char *instance_id, const int pid, void *data) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + char *plug_id; + + LOGD("missing %s %s", appid, instance_id); + toolkit_evas_h = (screen_connector_toolkit_evas_h)data; + if (!toolkit_evas_h) { + LOGE("Null toolkit_evas_h"); + return; + } + + if (toolkit_evas_h->type_h->toolkit_table != NULL && toolkit_evas_h->img_tbm != NULL) { + g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm); + + /* Remove data used in accessibility */ + plug_id = evas_object_data_del(toolkit_evas_h->img_tbm, "___PLUGID"); + free(plug_id); + } + + if (toolkit_evas_h->img_tbm != NULL) + toolkit_evas_h->ops->removed_cb(appid, instance_id, pid, toolkit_evas_h->img_tbm, toolkit_evas_h->data); + else if (toolkit_evas_h->img_file != NULL) + toolkit_evas_h->ops->removed_cb(appid, instance_id, pid, toolkit_evas_h->img_file, toolkit_evas_h->data); + + __free_toolkit_evas_h(toolkit_evas_h); +} + +EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(screen_connector_toolkit_evas_ops *ops, char *id, + screen_connector_screen_type_e type, void *data) +{ + screen_connector_toolkit_evas_h handle; + screen_connector_toolkit_evas_ops *evas_ops; + screen_connector_toolkit_ops *toolkit_ops; + screen_connector_type_evas_h type_h; + int int_type = type; + + type_h = g_hash_table_lookup(__type_table, &int_type); + if (type_h == NULL) { + LOGE("type %d is not initialized !!", type); + return NULL; + } + + toolkit_ops = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); + toolkit_ops->added_cb = __toolkit_added_cb; + toolkit_ops->updated_cb = __toolkit_update_cb; + toolkit_ops->removed_cb = __toolkit_removed_cb; + + evas_ops = (screen_connector_toolkit_evas_ops *)calloc(1, sizeof(screen_connector_toolkit_evas_ops)); + if (evas_ops == NULL) { + LOGE("evas_ops calloc fail"); + return NULL; + } + + memcpy(evas_ops, ops, sizeof(screen_connector_toolkit_evas_ops)); + handle = (screen_connector_toolkit_evas_h)calloc(1, sizeof(struct _screen_connector_toolkit_evas_h)); + if (handle == NULL) { + LOGE("handle calloc fail"); + free(evas_ops); + return NULL; + } + handle->img_type = -1; + handle->ops = evas_ops; + handle->data = data; + handle->type_h = type_h; + handle->toolkit_h = screen_connector_toolkit_add(toolkit_ops, id, type, handle); + + return handle; +} + +EXPORT_API int screen_connector_toolkit_evas_remove(screen_connector_toolkit_evas_h handle) +{ + if (handle == NULL) + return -1; + + __free_toolkit_evas_h(handle); + return 0; +} + +EXPORT_API int screen_connector_toolkit_evas_update(const char *appid, const char *instance_id) +{ + return screen_connector_toolkit_update(appid, instance_id); +} + +static void __send_visibility(gpointer key, gpointer value, gpointer user_data) +{ + screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)value; + Evas_Object *evas_obj = (Evas_Object *)key; + unsigned int event = GPOINTER_TO_INT(user_data); + int ret; + visibility_type type; + + if (toolkit_evas_h->freeze) + return; + + if (!__obj_is_visible(evas_obj, toolkit_evas_h)) + return; + + if (event) + type = VISIBILITY_TYPE_FULLY_OBSCURED; + else + type = VISIBILITY_TYPE_UNOBSCURED; + + ret = __set_visibility(toolkit_evas_h, type); + if (ret == -1) + LOGE("failed to set object visibility set %p to %d", evas_obj, type); +} + +static Eina_Bool __visibility_cb(void *data, int type, void *event) +{ + Ecore_Wl_Event_Window_Visibility_Change *ev = event; + GHashTableIter iter; + gpointer key, value; + screen_connector_type_evas_h cur_type; + + LOGD("visibility change: %d %d", (unsigned int)ev->win, + (unsigned int)ev->fully_obscured); + + if (!__type_table) + return ECORE_CALLBACK_RENEW; + + g_hash_table_iter_init(&iter, __type_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + cur_type = (screen_connector_type_evas_h)value; + if (cur_type->toolkit_table) + g_hash_table_foreach(cur_type->toolkit_table, __send_visibility, + GINT_TO_POINTER(ev->fully_obscured)); + } + + return ECORE_CALLBACK_RENEW; +} + +EXPORT_API int screen_connector_toolkit_evas_start_visibility_notify(void) +{ + if (__visibility_listener) + return 0; + + __visibility_listener = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, __visibility_cb, NULL); + + return 0; +} + +EXPORT_API int screen_connector_toolkit_evas_stop_visibility_notify(void) +{ + if (!__visibility_listener) + return 0; + + ecore_event_handler_del(__visibility_listener); + __visibility_listener = NULL; + + return 0; +} + +screen_connector_toolkit_evas_h __find_toolkit_evas_h(Evas_Object *obj) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + GHashTableIter iter; + gpointer key, value; + screen_connector_type_evas_h cur_type; + + g_hash_table_iter_init(&iter, __type_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + cur_type = (screen_connector_type_evas_h)value; + if (cur_type->toolkit_table) { + toolkit_evas_h = g_hash_table_lookup(cur_type->toolkit_table, obj); + if (toolkit_evas_h != NULL) + return toolkit_evas_h; + } + } + + return NULL; +} + +EXPORT_API int screen_connector_toolkit_evas_freeze_visibility(Evas_Object *obj, visibility_type type) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("obj not found"); + return -1; + } + toolkit_evas_h->freeze = 1; + + return __set_visibility(toolkit_evas_h, type); +} + +EXPORT_API int screen_connector_toolkit_evas_thaw_visibility(Evas_Object *obj) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("obj not found"); + return -1; + } + toolkit_evas_h->freeze = 0; + + return 0; +} + +EXPORT_API int screen_connector_toolkit_evas_send_mouse_up(Evas_Object *obj) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + int x; + int y; + int w; + int h; + unsigned int timestamp; + struct tizen_remote_surface *surface; + + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("unknown object. not widget object."); + return -1; + } + + if (!toolkit_evas_h->img_tbm) { + LOGE("surface not yet initialized."); + return -1; + } + + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface == NULL) { + LOGE("surface is NULL"); + return -1; + } + + evas_object_geometry_get(obj, &x, &y, &w, &h); + timestamp = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff); + tizen_remote_surface_transfer_mouse_event(surface, + TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP, + 0, + 1, + w / 2, + h / 2, + 0, + 0, + 0, + 0, + TIZEN_INPUT_DEVICE_CLAS_MOUSE, + TIZEN_INPUT_DEVICE_SUBCLAS_NONE, + "", + timestamp); + + return 0; +} + +EXPORT_API int screen_connector_toolkit_evas_send_touch_cancel(Evas_Object *obj) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + struct tizen_remote_surface *surface; + + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("unknown object. not widget object."); + return -1; + } + + if (toolkit_evas_h->img_tbm) { + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface == NULL) { + LOGE("surface is NULL"); + return -1; + } + + tizen_remote_surface_transfer_touch_cancel(surface); + toolkit_evas_h->cancel_touch = true; + } else { + LOGE("surface not yet initialized."); + return -1; + } + + return 0; +} + +EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_rid(screen_connector_toolkit_evas_ops *ops, + int res_id, screen_connector_screen_type_e type, void *data) +{ + screen_connector_toolkit_evas_h handle; + screen_connector_toolkit_evas_ops *evas_ops; + screen_connector_toolkit_ops *toolkit_ops; + screen_connector_type_evas_h type_h; + char rid_str[32]; + + type_h = g_hash_table_lookup(__type_table, &type); + if (type_h == NULL) { + LOGE("type %d is not initialized !!", type); + return NULL; + } + + toolkit_ops = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); + toolkit_ops->added_cb = __toolkit_added_cb; + toolkit_ops->updated_cb = __toolkit_update_cb; + toolkit_ops->removed_cb = __toolkit_removed_cb; + + evas_ops = (screen_connector_toolkit_evas_ops *)calloc(1, sizeof(screen_connector_toolkit_evas_ops)); + if (evas_ops == NULL) { + LOGE("evas_ops calloc fail"); + return NULL; + } + + memcpy(evas_ops, ops, sizeof(screen_connector_toolkit_evas_ops)); + handle = (screen_connector_toolkit_evas_h)calloc(1, sizeof(struct _screen_connector_toolkit_evas_h)); + if (handle == NULL) { + LOGE("handle calloc fail"); + free(evas_ops); + return NULL; + } + handle->img_type = -1; + handle->ops = evas_ops; + handle->data = data; + handle->type_h = type_h; + + snprintf(rid_str, sizeof(rid_str), "%d", res_id); + handle->toolkit_h = screen_connector_toolkit_create_handle(rid_str, res_id, toolkit_ops, handle); + screen_connector_toolkit_redirect_surface(handle->toolkit_h); + + return handle; +} + +EXPORT_API int screen_connector_toolkit_evas_get_rid(Evas_Object *obj, int *resource_id) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("unknown object."); + return -1; + } + *resource_id = screen_connector_toolkit_get_surface_id(toolkit_evas_h->toolkit_h); + + return 0; +} + +EXPORT_API int screen_connector_toolkit_evas_get_pid(Evas_Object *obj, int *pid) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + int toolkit_pid = 0; + + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("unknown object."); + return -1; + } + + toolkit_pid = screen_connector_toolkit_get_pid(toolkit_evas_h->toolkit_h); + if (toolkit_pid == 0) { + LOGE("Invalid object"); + return -1; + } + + *pid = toolkit_pid; + + return 0; +} diff --git a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c index 5966e2b..175d03b 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include #include #include @@ -33,389 +32,148 @@ #define LOG_TAG "SC_WATCHER_EVAS" +static Evas_Object *__viewer_win; + struct _screen_connector_watcher_evas_h { screen_connector_watcher_evas_ops *ops; screen_connector_watcher_h watcher_h; - int freeze; - bool is_init; - bool cancel_touch; + void *data; +}; + +struct _img_info_h { Evas_Object *img_tbm; Evas_Object *img_file; - uint32_t img_type; struct wl_buffer *pre_buffer; - void *data; + char *appid; + char *instance_id; + int pid; }; -static Evas_Object *__viewer_win; -static Ecore_Event_Handler *__visibility_listener; -static GHashTable *__watcher_tbl; - -EXPORT_API int screen_connector_watcher_evas_init(Evas_Object *win) -{ - __viewer_win = win; - - __watcher_tbl = g_hash_table_new(g_direct_hash, g_direct_equal); - if (!__watcher_tbl) { - LOGE("failed to create table"); - return -1; - } - - return screen_connector_watcher_init(); -} - -EXPORT_API int screen_connector_watcher_evas_fini(void) -{ - if (__watcher_tbl) - g_hash_table_destroy(__watcher_tbl); - - __watcher_tbl = NULL; - return screen_connector_watcher_fini(); -} - -static bool __obj_is_visible(Evas_Object *obj) -{ - int x, y, w, h; - Ecore_Wl_Window *window = NULL; - int window_x, window_y, window_w, window_h; - int rotation; - - window = elm_win_wl_window_get(__viewer_win); - ecore_wl_window_geometry_get(window, &window_x, &window_y, &window_w, &window_h); - evas_object_geometry_get(obj, &x, &y, &w, &h); - rotation = ecore_wl_window_rotation_get(window); - - if (x >= 0 && x < window_w && - y >= 0 && y < window_h && - (rotation == 0 || rotation == 180)) { - LOGD("x %d, y %d w %d h %d, window_w %d window_h %d rotation %d", - x, y, w, h, window_w, window_h, rotation); - return true; - } else if (x >= 0 && x < window_h && - y >= 0 && y < window_w && - (rotation == 90 || rotation == 270)) { - LOGD("x %d, y %d w %d h %d, window_w %d window_h %d rotation %d", - x, y, w, h, window_w, window_h, rotation); - return true; - } - - return false; -} - -static int __set_visibility(screen_connector_watcher_evas_h watcher_evas_h, visibility_type type) -{ - int obscured; - struct tizen_remote_surface *surface; - - if (!watcher_evas_h) { - LOGE("obj not found"); - return -1; - } - - switch (type) { - case VISIBILITY_TYPE_UNOBSCURED: - case VISIBILITY_TYPE_PARTIALLY_OBSCURED: - obscured = TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE; - break; - case VISIBILITY_TYPE_FULLY_OBSCURED: - obscured = TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_INVISIBLE; - break; - default: - return -1; - } +typedef struct _img_info_h *img_info_h; +static GHashTable *__img_info_table = NULL; - surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); - if (surface) - tizen_remote_surface_transfer_visibility(surface, obscured); - - return 0; -} - -static void __obj_update_visibility(void *data, Evas *e, Evas_Object *obj, void *event_info) +static void __clear_img_tbm(img_info_h info) { - screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)data; - - if (!watcher_evas_h->is_init) { - watcher_evas_h->is_init = true; + if (info->img_tbm == NULL) return; - } - if (__obj_is_visible(obj)) - __set_visibility(watcher_evas_h, VISIBILITY_TYPE_UNOBSCURED); - else - __set_visibility(watcher_evas_h, VISIBILITY_TYPE_FULLY_OBSCURED); + evas_object_del(info->img_tbm); + info->img_tbm = NULL; } -static void __rs_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +static void __clear_img_file(img_info_h info) { - screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)data; - Evas_Event_Mouse_Down *ev = event_info; - const char *desc = evas_device_description_get(ev->dev); - int x; - int y; - int w; - int h; - struct tizen_remote_surface *surface; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - - LOGD("mouse down: %d %d", ev->canvas.x - x, ev->canvas.y - y); - - if (desc == NULL) - desc = ""; - - if (screen_connector_watcher_check_input_disabled(watcher_evas_h->watcher_h, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_UP_DOWN)) { - LOGD("mouse down disabled"); + if (info->img_file == NULL) return; - } - surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); - if (surface == NULL) { - LOGE("surface is NULL"); - return; - } - - tizen_remote_surface_transfer_mouse_event(surface, - TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN, - 0, - ev->button, - ev->canvas.x - x, - ev->canvas.y - y, - wl_fixed_from_double(ev->radius_x), - wl_fixed_from_double(ev->radius_y), - wl_fixed_from_double(ev->pressure), - wl_fixed_from_double(ev->angle), - evas_device_class_get(ev->dev), - evas_device_subclass_get(ev->dev), - desc, - ev->timestamp); + evas_object_del(info->img_file); + info->img_file = NULL; } -static void __rs_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)data; - Evas_Event_Mouse_Up *ev = event_info; - const char *desc = evas_device_description_get(ev->dev); - int x; - int y; - int w; - int h; - struct tizen_remote_surface *surface; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - - LOGD("mouse up: %d %d", ev->canvas.x - x, ev->canvas.y - y); - - if (desc == NULL) - desc = ""; - - if (screen_connector_watcher_check_input_disabled(watcher_evas_h->watcher_h, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_UP_DOWN)) { - LOGD("mouse up disabled"); - return; - } - - surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); - if (surface == NULL) { - LOGE("surface is NULL"); - return; - } - - tizen_remote_surface_transfer_mouse_event(surface, - TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP, - 0, - ev->button, - ev->canvas.x - x, - ev->canvas.y - y, - wl_fixed_from_double(ev->radius_x), - wl_fixed_from_double(ev->radius_y), - wl_fixed_from_double(ev->pressure), - wl_fixed_from_double(ev->angle), - evas_device_class_get(ev->dev), - evas_device_subclass_get(ev->dev), - desc, - ev->timestamp); -} -static void __rs_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) +static img_info_h __create_img_info(const char *appid, const char *instance_id, int pid) { - screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)data; - Evas_Event_Mouse_Move *ev = event_info; - const char *desc = evas_device_description_get(ev->dev); - int x; - int y; - int w; - int h; - struct tizen_remote_surface *surface; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - - LOGD("mouse move: %d %d", ev->cur.canvas.x - x, ev->cur.canvas.y - y); - - if (desc == NULL) - desc = ""; - - if (screen_connector_watcher_check_input_disabled(watcher_evas_h->watcher_h, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_MOVE_X_Y)) { - LOGD("mouse move disabled"); - return; - } - - surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); - if (surface == NULL) { - LOGE("surface is NULL"); - return; - } - - tizen_remote_surface_transfer_mouse_event(surface, - TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE, - 0, - 0, - ev->cur.canvas.x - x, - ev->cur.canvas.y - y, - wl_fixed_from_double(ev->radius_x), - wl_fixed_from_double(ev->radius_y), - wl_fixed_from_double(ev->pressure), - wl_fixed_from_double(ev->angle), - evas_device_class_get(ev->dev), - evas_device_subclass_get(ev->dev), - desc, - ev->timestamp); + img_info_h info = (img_info_h)calloc(1, sizeof(struct _img_info_h)); + info->appid = strdup(appid); + info->instance_id = strdup(instance_id); + info->pid = pid; + return info; } -static void __rs_cb_mouse_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info) +static void __destroy_img_info(gpointer data) { - screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)data; - Evas_Event_Mouse_Wheel *ev = event_info; - const char *desc = evas_device_description_get(ev->dev); - struct tizen_remote_surface *surface; - - LOGD("mouse wheel"); - - if (desc == NULL) - desc = ""; - - if (screen_connector_watcher_check_input_disabled(watcher_evas_h->watcher_h, - SCREEN_CONNECTOR_INPUT_TYPE_MOUSE_WHEEL)) { - LOGD("mouse wheel disabled"); + img_info_h info = (img_info_h)data; + if (info == NULL) return; + if (info->appid) { + free(info->appid); + info->appid = NULL; } - surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); - if (surface == NULL) { - LOGE("surface is NULL"); - return; + if (info->instance_id) { + free(info->instance_id); + info->instance_id = NULL; } + __clear_img_file(info); + __clear_img_tbm(info); - tizen_remote_surface_transfer_mouse_wheel(surface, - ev->direction, - ev->z, - evas_device_class_get(ev->dev), - evas_device_subclass_get(ev->dev), - desc, - ev->timestamp); + free(info); } -static void __rs_cb_show(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - LOGD("show"); - __obj_update_visibility(data, e, obj, event_info); -} -static void __rs_cb_hide(void *data, Evas *e, Evas_Object *obj, void *event_info) +EXPORT_API int screen_connector_watcher_evas_init(Evas_Object *win) { - LOGD("hide"); + __viewer_win = win; + __img_info_table = g_hash_table_new_full(g_str_hash, + g_str_equal, free, __destroy_img_info); + return screen_connector_watcher_init(); } -static void __rs_cb_resize(void *data, Evas *e, Evas_Object *obj, void *event_info) +EXPORT_API int screen_connector_watcher_evas_fini(void) { - LOGD("resize"); - __obj_update_visibility(data, e, obj, event_info); + g_hash_table_destroy(__img_info_table); + return screen_connector_watcher_fini(); } -static void __clear_img_tbm(screen_connector_watcher_evas_h watcher_evas_h) +static void __watcher_added_cb(const char *appid, const char *instance_id, const int pid, void *data) { - if (watcher_evas_h->img_tbm == NULL) - return; + LOGE("__watcher_added_cb %s %s %d", appid, instance_id, pid); + screen_connector_watcher_evas_h handle = (screen_connector_watcher_evas_h)data; - g_hash_table_remove(__watcher_tbl, watcher_evas_h->img_tbm); - evas_object_del(watcher_evas_h->img_tbm); - watcher_evas_h->img_tbm = NULL; + if (handle) + handle->ops->added_cb(appid, instance_id, pid, handle->data); } -static void __clear_img_file(screen_connector_watcher_evas_h watcher_evas_h) +static void __watcher_removed_cb(const char *appid, const char *instance_id, const int pid, void *data) { - if (watcher_evas_h->img_file == NULL) - return; + screen_connector_watcher_evas_h handle = (screen_connector_watcher_evas_h)data; + img_info_h cur_info; - evas_object_del(watcher_evas_h->img_file); - watcher_evas_h->img_file = NULL; + if (handle) + handle->ops->removed_cb(appid, instance_id, pid, handle->data); + + cur_info = g_hash_table_lookup(__img_info_table, instance_id); + if (cur_info) + g_hash_table_remove(__img_info_table, instance_id); } -static void __watcher_change_cb(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, - int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, void *data) +static void __watcher_update_cb(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, + int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, const char *appid, + const char *instance_id, int pid, void *data) { - bool is_added = false; Evas_Native_Surface ns; tbm_surface_h tbm_surface; int width, height; char *map; char format[] = "png"; - char plug_id[256]; - screen_connector_watcher_evas_h watcher_evas_h; - char *appid; - char pid; - - watcher_evas_h = (screen_connector_watcher_evas_h)data; - appid = screen_connector_watcher_get_appid(watcher_evas_h->watcher_h); - pid = screen_connector_watcher_get_pid(watcher_evas_h->watcher_h); - - if (watcher_evas_h->img_tbm == NULL) { - LOGD("first added !!!! %d, %d %s", (watcher_evas_h->img_tbm == NULL), type, appid); - watcher_evas_h->img_tbm = evas_object_image_filled_add( - evas_object_evas_get(__viewer_win)); - - /* Image alpha set */ - evas_object_image_alpha_set(watcher_evas_h->img_tbm, 1); - - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_MOUSE_DOWN, - __rs_cb_mouse_down, watcher_evas_h); - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_MOUSE_UP, - __rs_cb_mouse_up, watcher_evas_h); - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_MOUSE_MOVE, - __rs_cb_mouse_move, watcher_evas_h); - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_MOUSE_WHEEL, - __rs_cb_mouse_wheel, watcher_evas_h); - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_SHOW, - __rs_cb_show, watcher_evas_h); - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_HIDE, - __rs_cb_hide, watcher_evas_h); - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_RESIZE, - __rs_cb_resize, watcher_evas_h); - - /* Store watcher_evas_h */ - g_hash_table_insert(__watcher_tbl, watcher_evas_h->img_tbm, watcher_evas_h); - - /* Set data to use in accessibility */ - snprintf(plug_id, sizeof(plug_id), "%s:%d", appid, pid); - evas_object_data_set(watcher_evas_h->img_tbm, "___PLUGID", strdup(plug_id)); - evas_object_event_callback_add(watcher_evas_h->img_tbm, - EVAS_CALLBACK_MOVE, __obj_update_visibility, watcher_evas_h); + screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)data; + img_info_h info; + + if (tbm == NULL && type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM) { + LOGE("TBM is null !! %d, %s, %s", TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM, appid, instance_id); + return; } - if (watcher_evas_h->img_type != type) - is_added = true; - watcher_evas_h->img_type = type; + info = g_hash_table_lookup(__img_info_table, instance_id); + if (info == NULL) { + info = __create_img_info(appid, instance_id, pid); + g_hash_table_insert(__img_info_table, strdup(instance_id), info); + } /* check type of given buffer */ if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM) { + + if (info->img_tbm == NULL) { + LOGD("first added tbm type !!!! %d, %d %s", (info->img_tbm == NULL), type, appid); + if (info->img_file) { + watcher_evas_h->ops->removed_cb(appid, instance_id, pid, watcher_evas_h->data); + __clear_img_file(info); + } + info->img_tbm = evas_object_image_filled_add( + evas_object_evas_get(__viewer_win)); + watcher_evas_h->ops->added_cb(appid, instance_id, pid, watcher_evas_h->data); + } + /* get tbm surface from buffer */ tbm_surface = wl_buffer_get_user_data(tbm); width = tbm_surface_get_width(tbm_surface); @@ -426,121 +184,55 @@ static void __watcher_change_cb(struct tizen_remote_surface *trs, uint32_t type, ns.type = EVAS_NATIVE_SURFACE_TBM; ns.data.tbm.buffer = tbm_surface; - evas_object_resize(watcher_evas_h->img_tbm, width, height); - evas_object_image_size_set(watcher_evas_h->img_tbm, width, height); - evas_object_image_native_surface_set(watcher_evas_h->img_tbm, &ns); /* set native surface */ - evas_object_image_pixels_dirty_set(watcher_evas_h->img_tbm, EINA_TRUE); /* set dirty for image updating */ + evas_object_resize(info->img_tbm, width, height); + evas_object_image_size_set(info->img_tbm, width, height); + evas_object_image_native_surface_set(info->img_tbm, &ns); /* set native surface */ + evas_object_image_pixels_dirty_set(info->img_tbm, EINA_TRUE); /* set dirty for image updating */ + watcher_evas_h->ops->updated_cb(appid, instance_id, pid, info->img_tbm, watcher_evas_h->data); + } else if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE) { - if (!watcher_evas_h->img_file) - watcher_evas_h->img_file = evas_object_image_filled_add(evas_object_evas_get(__viewer_win)); + + if (info->img_file == NULL) { + LOGD("first added file type !!!! %d %s", type, appid); + if (info->img_tbm) { + watcher_evas_h->ops->removed_cb(appid, instance_id, pid, watcher_evas_h->data); + __clear_img_tbm(info); + } + info->img_file = evas_object_image_filled_add( + evas_object_evas_get(__viewer_win)); + watcher_evas_h->ops->added_cb(appid, instance_id, pid, watcher_evas_h->data); + } map = mmap(NULL, img_file_size, PROT_READ, MAP_SHARED, img_file_fd, 0); - evas_object_image_memfile_set(watcher_evas_h->img_file, map, img_file_size, format, NULL); - evas_object_image_size_get(watcher_evas_h->img_tbm, &width, &height); - evas_object_image_fill_set(watcher_evas_h->img_file, 0, 0, width, height); - evas_object_resize(watcher_evas_h->img_file, width, height); + evas_object_image_memfile_set(info->img_file, map, img_file_size, format, NULL); + evas_object_image_size_get(info->img_tbm, &width, &height); + evas_object_image_fill_set(info->img_file, 0, 0, width, height); + evas_object_resize(info->img_file, width, height); munmap(map, img_file_size); - evas_object_image_native_surface_set(watcher_evas_h->img_tbm, NULL); /* set null to previous object for the tbm type */ + evas_object_image_native_surface_set(info->img_tbm, NULL); /* set null to previous object for the tbm type */ + watcher_evas_h->ops->updated_cb(appid, instance_id, pid, info->img_file, watcher_evas_h->data); } - if (watcher_evas_h->pre_buffer) { + if (info->pre_buffer) { if (tizen_remote_surface_get_version(trs) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION) - tizen_remote_surface_release(trs, watcher_evas_h->pre_buffer); - } - watcher_evas_h->pre_buffer = tbm; - - if (is_added) { - LOGD("call added !!!! %s, type %d", appid, type); - if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE) { - watcher_evas_h->ops->added(appid, watcher_evas_h->img_file, - watcher_evas_h->data); - __clear_img_tbm(watcher_evas_h); - } else { - watcher_evas_h->ops->added(appid, watcher_evas_h->img_tbm, - watcher_evas_h->data); - __clear_img_file(watcher_evas_h); - } - } else { - LOGD("call updated !!!! %s, type %d", appid, type); - if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE) { - watcher_evas_h->ops->updated(appid, watcher_evas_h->img_file, - watcher_evas_h->data); - __clear_img_tbm(watcher_evas_h); - } else { - watcher_evas_h->ops->updated(appid, watcher_evas_h->img_tbm, - watcher_evas_h->data); - __clear_img_file(watcher_evas_h); - } + tizen_remote_surface_release(trs, info->pre_buffer); } + info->pre_buffer = tbm; close(img_file_fd); /* close passed fd */ } -static void __watcher_update_cb(struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time, void *data) -{ - __watcher_change_cb(trs, TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM, buffer, 0, 0, 0, NULL, data); -} - -static void __free_watcher_evas_h(screen_connector_watcher_evas_h watcher_evas_h) +EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add(screen_connector_watcher_evas_ops *ops, void *data) { - if (!watcher_evas_h) - return; - - if (watcher_evas_h->watcher_h) - screen_connector_watcher_remove(watcher_evas_h->watcher_h); - - if (watcher_evas_h->img_tbm) { - evas_object_del(watcher_evas_h->img_tbm); - watcher_evas_h->img_tbm = NULL; - } - - if (watcher_evas_h->ops) { - free(watcher_evas_h->ops); - watcher_evas_h->ops = NULL; - } - free(watcher_evas_h); -} - -static void __watcher_missing_cb(struct tizen_remote_surface *trs, void *data) -{ - screen_connector_watcher_evas_h watcher_evas_h; - char *plug_id; - char *appid; - - LOGD("missing"); - watcher_evas_h = (screen_connector_watcher_evas_h)data; - if (!watcher_evas_h) { - LOGE("Null watcher_evas_h"); - return; - } - - if (__watcher_tbl != NULL && watcher_evas_h->img_tbm != NULL) { - g_hash_table_remove(__watcher_tbl, watcher_evas_h->img_tbm); - - /* Remove data used in accessibility */ - plug_id = evas_object_data_del(watcher_evas_h->img_tbm, "___PLUGID"); - free(plug_id); - } - - appid = screen_connector_watcher_get_appid(watcher_evas_h->watcher_h); - if (watcher_evas_h->img_tbm != NULL) - watcher_evas_h->ops->removed(appid, watcher_evas_h->img_tbm, watcher_evas_h->data); - else - watcher_evas_h->ops->removed(appid, watcher_evas_h->img_file, watcher_evas_h->data); - - __free_watcher_evas_h(watcher_evas_h); -} - -EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add(screen_connector_watcher_evas_ops *ops, char *id, void *data) -{ screen_connector_watcher_evas_h handle; screen_connector_watcher_evas_ops *evas_ops; - screen_connector_watcher_ops watcher_ops; + screen_connector_watcher_ops *watcher_ops; - watcher_ops.change_cb = __watcher_change_cb; - watcher_ops.missing_cb = __watcher_missing_cb; - watcher_ops.update_cb = __watcher_update_cb; + watcher_ops = (screen_connector_watcher_ops *)calloc(1, sizeof(screen_connector_watcher_ops)); + watcher_ops->added_cb = __watcher_added_cb; + watcher_ops->updated_cb = __watcher_update_cb; + watcher_ops->removed_cb = __watcher_removed_cb; evas_ops = (screen_connector_watcher_evas_ops *)calloc(1, sizeof(screen_connector_watcher_evas_ops)); if (evas_ops == NULL) { @@ -555,261 +247,47 @@ EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add(scr free(evas_ops); return NULL; } - handle->img_type = -1; handle->ops = evas_ops; handle->data = data; - handle->watcher_h = screen_connector_watcher_add(&watcher_ops, id, handle); + handle->watcher_h = screen_connector_watcher_add(watcher_ops, handle); return handle; -} - -EXPORT_API int screen_connector_watcher_evas_remove(screen_connector_watcher_evas_h handle) -{ - if (handle == NULL) - return -1; - __free_watcher_evas_h(handle); - return 0; } -EXPORT_API int screen_connector_watcher_evas_update(const char *appid) +static void __destroy_watcher_evas_handle(screen_connector_watcher_evas_h watcher_evas_h) { - return screen_connector_watcher_update(appid); -} - -static void __send_visibility(gpointer key, gpointer value, gpointer user_data) -{ - screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)value; - Evas_Object *evas_obj = (Evas_Object *)key; - unsigned int event = GPOINTER_TO_INT(user_data); - int ret; - visibility_type type; - - if (watcher_evas_h->freeze) - return; - - if (!__obj_is_visible(evas_obj)) + if (!watcher_evas_h) return; - if (event) - type = VISIBILITY_TYPE_FULLY_OBSCURED; - else - type = VISIBILITY_TYPE_UNOBSCURED; - - ret = __set_visibility(watcher_evas_h, type); - if (ret == -1) - LOGE("failed to set object visibility set %p to %d", evas_obj, type); -} - -static Eina_Bool __visibility_cb(void *data, int type, void *event) -{ - Ecore_Wl_Event_Window_Visibility_Change *ev = event; - - LOGD("visibility change: %d %d", (unsigned int)ev->win, - (unsigned int)ev->fully_obscured); - - if (!__watcher_tbl) - return ECORE_CALLBACK_RENEW; - - g_hash_table_foreach(__watcher_tbl, __send_visibility, - GINT_TO_POINTER(ev->fully_obscured)); - - return ECORE_CALLBACK_RENEW; -} - -EXPORT_API int screen_connector_watcher_evas_start_visibility_notify(void) -{ - if (__visibility_listener) - return 0; - - __visibility_listener = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, __visibility_cb, NULL); - - return 0; -} - -EXPORT_API int screen_connector_watcher_evas_stop_visibility_notify(void) -{ - if (!__visibility_listener) - return 0; - - ecore_event_handler_del(__visibility_listener); - __visibility_listener = NULL; - - return 0; -} - -EXPORT_API int screen_connector_watcher_evas_freeze_visibility(Evas_Object *obj, visibility_type type) -{ - screen_connector_watcher_evas_h watcher_evas_h; - - watcher_evas_h = (screen_connector_watcher_evas_h)g_hash_table_lookup(__watcher_tbl, obj); - if (!watcher_evas_h) { - LOGE("obj not found"); - return -1; - } - watcher_evas_h->freeze = 1; - - return __set_visibility(watcher_evas_h, type); -} - -EXPORT_API int screen_connector_watcher_evas_thaw_visibility(Evas_Object *obj) -{ - screen_connector_watcher_evas_h watcher_evas_h; - - watcher_evas_h = (screen_connector_watcher_evas_h)g_hash_table_lookup(__watcher_tbl, obj); - if (!watcher_evas_h) { - LOGE("obj not found"); - return -1; - } - watcher_evas_h->freeze = 0; - - return 0; -} - -EXPORT_API int screen_connector_watcher_evas_send_mouse_up(Evas_Object *obj) -{ - screen_connector_watcher_evas_h watcher_evas_h; - int x; - int y; - int w; - int h; - unsigned int timestamp; - struct tizen_remote_surface *surface; - - watcher_evas_h = g_hash_table_lookup(__watcher_tbl, obj); - if (!watcher_evas_h) { - LOGE("unknown object. not widget object."); - return -1; - } - - if (!watcher_evas_h->img_tbm) { - LOGE("surface not yet initialized."); - return -1; - } - - surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); - if (surface == NULL) { - LOGE("surface is NULL"); - return -1; - } + if (watcher_evas_h->watcher_h) + screen_connector_watcher_remove(watcher_evas_h->watcher_h); - evas_object_geometry_get(obj, &x, &y, &w, &h); - timestamp = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff); - tizen_remote_surface_transfer_mouse_event(surface, - TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP, - 0, - 1, - w / 2, - h / 2, - 0, - 0, - 0, - 0, - TIZEN_INPUT_DEVICE_CLAS_MOUSE, - TIZEN_INPUT_DEVICE_SUBCLAS_NONE, - "", - timestamp); + if (watcher_evas_h->ops) + free(watcher_evas_h->ops); - return 0; + free(watcher_evas_h); } -EXPORT_API int screen_connector_watcher_evas_send_touch_cancel(Evas_Object *obj) +EXPORT_API int screen_connector_watcher_evas_remove(screen_connector_watcher_evas_h handle) { - screen_connector_watcher_evas_h watcher_evas_h; - struct tizen_remote_surface *surface; - - watcher_evas_h = g_hash_table_lookup(__watcher_tbl, obj); - if (!watcher_evas_h) { - LOGE("unknown object. not widget object."); - return -1; - } - - if (watcher_evas_h->img_tbm) { - surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); - if (surface == NULL) { - LOGE("surface is NULL"); - return -1; - } - - tizen_remote_surface_transfer_touch_cancel(surface); - watcher_evas_h->cancel_touch = true; - } else { - LOGE("surface not yet initialized."); - return -1; - } - + __destroy_watcher_evas_handle(handle); return 0; } -EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add_by_rid(screen_connector_watcher_evas_ops *ops, - int res_id, void *data) +EXPORT_API int screen_connector_watcher_evas_update(screen_connector_watcher_evas_h watcher_evas_h, + const char *instance_id) { - screen_connector_watcher_evas_h watcher_evas_h; - screen_connector_watcher_evas_ops *evas_ops; - char rid_str[32]; - int pid = 0; - screen_connector_watcher_ops watcher_ops; - - watcher_ops.change_cb = __watcher_change_cb; - watcher_ops.missing_cb = __watcher_missing_cb; - watcher_ops.update_cb = __watcher_update_cb; - - evas_ops = (screen_connector_watcher_evas_ops *)calloc(1, sizeof(screen_connector_watcher_evas_ops)); - if (evas_ops == NULL) { - LOGE("evas_ops calloc fail"); - return NULL; - } - - snprintf(rid_str, sizeof(rid_str), "%d", res_id); - memcpy(evas_ops, ops, sizeof(screen_connector_watcher_evas_ops)); - watcher_evas_h = (screen_connector_watcher_evas_h)calloc(1, sizeof(struct _screen_connector_watcher_evas_h)); if (watcher_evas_h == NULL) { - LOGE("handle calloc fail"); - free(evas_ops); - return NULL; - } - watcher_evas_h->img_type = -1; - watcher_evas_h->ops = evas_ops; - watcher_evas_h->data = data; - watcher_evas_h->watcher_h = screen_connector_watcher_create_handle(rid_str, pid, &watcher_ops, watcher_evas_h); - screen_connector_watcher_set_resource_id(watcher_evas_h->watcher_h, res_id); - screen_connector_watcher_redirect_surface(watcher_evas_h->watcher_h); - - return watcher_evas_h; -} - -EXPORT_API int screen_connector_watcher_evas_get_rid(Evas_Object *obj, int *resource_id) -{ - screen_connector_watcher_evas_h watcher_evas_h; - - watcher_evas_h = (screen_connector_watcher_evas_h)g_hash_table_lookup(__watcher_tbl, obj); - if (!watcher_evas_h) { - LOGE("unknown object."); - return -1; - } - *resource_id = screen_connector_watcher_get_resource_id(watcher_evas_h->watcher_h); - - return 0; -} - -EXPORT_API int screen_connector_watcher_evas_get_pid(Evas_Object *obj, int *pid) -{ - screen_connector_watcher_evas_h watcher_evas_h; - int watcher_pid; - - watcher_evas_h = (screen_connector_watcher_evas_h)g_hash_table_lookup(__watcher_tbl, obj); - if (!watcher_evas_h) { - LOGE("unknown object."); + LOGE("watcher_evas_h is NULL"); return -1; } - watcher_pid = screen_connector_watcher_get_pid(watcher_evas_h->watcher_h); - if (watcher_pid == 0) { - LOGE("Invalid object"); + if (watcher_evas_h->watcher_h == NULL) { + LOGE("watcher_h is NULL"); return -1; } - *pid = watcher_pid; - - return 0; + return screen_connector_watcher_update(watcher_evas_h->watcher_h, instance_id); } + -- 2.7.4 From 04d11fadf0e5dd168bc280e531043d8ebcf280a8 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 24 Mar 2017 17:39:29 +0900 Subject: [PATCH 04/16] Fix callback disapeared bug For locally declared callback function, screen_connector_toolkit_add should copy and store callback functions. Change-Id: I14ac550d5f062e03315046bedd0b69649972255f Signed-off-by: Hyunho Kang --- .../src/screen_connector_toolkit.c | 23 ++++++++++++++++++++-- .../src/screen_connector_toolkit_evas.c | 22 ++++++++++----------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/screen_connector_watcher/src/screen_connector_toolkit.c b/screen_connector_watcher/src/screen_connector_toolkit.c index 98864ff..f3e9028 100644 --- a/screen_connector_watcher/src/screen_connector_toolkit.c +++ b/screen_connector_watcher/src/screen_connector_toolkit.c @@ -248,17 +248,26 @@ EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_create_handle(cha screen_connector_toolkit_ops *ops, void *data) { screen_connector_toolkit_h toolkit_h = NULL; + screen_connector_toolkit_ops *ops_copy; + + ops_copy = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); + if (ops_copy == NULL) { + LOGE("ops_copy calloc fail"); + return NULL; + } + memcpy(ops_copy, ops, sizeof(screen_connector_toolkit_ops)); toolkit_h = (screen_connector_toolkit_h)calloc(1, sizeof(struct _screen_connector_toolkit_h)); if (toolkit_h == NULL) { LOGE("toolkit_h calloc fail"); + free(ops_copy); return NULL; } toolkit_h->surface_id = surface_id; toolkit_h->appid = strdup(id); toolkit_h->instance_id = strdup(id); toolkit_h->data = data; - toolkit_h->ops = ops; + toolkit_h->ops = ops_copy; return toolkit_h; } @@ -268,6 +277,7 @@ EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_add(screen_connec { screen_connector_toolkit_h toolkit_h = NULL; screen_connector_type_h type_h = NULL; + screen_connector_toolkit_ops *ops_copy; if (id == NULL || ops == NULL) { LOGE("Invalid param"); @@ -280,14 +290,23 @@ EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_add(screen_connec return NULL; } + ops_copy = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); + if (ops_copy == NULL) { + LOGE("ops_copy calloc fail"); + return NULL; + } + memcpy(ops_copy, ops, sizeof(screen_connector_toolkit_ops)); + toolkit_h = (screen_connector_toolkit_h)calloc(1, sizeof(struct _screen_connector_toolkit_h)); if (toolkit_h == NULL) { LOGE("toolkit_h calloc fail"); + free(ops_copy); return NULL; } + toolkit_h->instance_id = strdup(id); toolkit_h->data = data; - toolkit_h->ops = ops; + toolkit_h->ops = ops_copy; toolkit_h->type_h = type_h; if (type_h->toolkit_table == NULL) diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index a442f36..5d5baa0 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -578,7 +578,7 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(scr { screen_connector_toolkit_evas_h handle; screen_connector_toolkit_evas_ops *evas_ops; - screen_connector_toolkit_ops *toolkit_ops; + screen_connector_toolkit_ops toolkit_ops; screen_connector_type_evas_h type_h; int int_type = type; @@ -588,10 +588,9 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(scr return NULL; } - toolkit_ops = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); - toolkit_ops->added_cb = __toolkit_added_cb; - toolkit_ops->updated_cb = __toolkit_update_cb; - toolkit_ops->removed_cb = __toolkit_removed_cb; + toolkit_ops.added_cb = __toolkit_added_cb; + toolkit_ops.updated_cb = __toolkit_update_cb; + toolkit_ops.removed_cb = __toolkit_removed_cb; evas_ops = (screen_connector_toolkit_evas_ops *)calloc(1, sizeof(screen_connector_toolkit_evas_ops)); if (evas_ops == NULL) { @@ -610,7 +609,7 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(scr handle->ops = evas_ops; handle->data = data; handle->type_h = type_h; - handle->toolkit_h = screen_connector_toolkit_add(toolkit_ops, id, type, handle); + handle->toolkit_h = screen_connector_toolkit_add(&toolkit_ops, id, type, handle); return handle; } @@ -826,7 +825,7 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_ { screen_connector_toolkit_evas_h handle; screen_connector_toolkit_evas_ops *evas_ops; - screen_connector_toolkit_ops *toolkit_ops; + screen_connector_toolkit_ops toolkit_ops; screen_connector_type_evas_h type_h; char rid_str[32]; @@ -836,10 +835,9 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_ return NULL; } - toolkit_ops = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); - toolkit_ops->added_cb = __toolkit_added_cb; - toolkit_ops->updated_cb = __toolkit_update_cb; - toolkit_ops->removed_cb = __toolkit_removed_cb; + toolkit_ops.added_cb = __toolkit_added_cb; + toolkit_ops.updated_cb = __toolkit_update_cb; + toolkit_ops.removed_cb = __toolkit_removed_cb; evas_ops = (screen_connector_toolkit_evas_ops *)calloc(1, sizeof(screen_connector_toolkit_evas_ops)); if (evas_ops == NULL) { @@ -860,7 +858,7 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_ handle->type_h = type_h; snprintf(rid_str, sizeof(rid_str), "%d", res_id); - handle->toolkit_h = screen_connector_toolkit_create_handle(rid_str, res_id, toolkit_ops, handle); + handle->toolkit_h = screen_connector_toolkit_create_handle(rid_str, res_id, &toolkit_ops, handle); screen_connector_toolkit_redirect_surface(handle->toolkit_h); return handle; -- 2.7.4 From 03c4a27bace19ae79afaf85ba71a8e2b466677cf Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Mon, 13 Mar 2017 22:19:24 +0900 Subject: [PATCH 05/16] Fix destroy handle bug Change-Id: Ifc796724e8db62557fab4c80e6e912dbe022f169 Signed-off-by: Hyunho Kang (cherry picked from commit 505fb90a88d192f7a2311c49fc3693a4c2e82415) --- .../src/screen_connector_toolkit.c | 19 ++++++++-------- .../src/screen_connector_toolkit_evas.c | 25 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/screen_connector_watcher/src/screen_connector_toolkit.c b/screen_connector_watcher/src/screen_connector_toolkit.c index f3e9028..910d73f 100644 --- a/screen_connector_watcher/src/screen_connector_toolkit.c +++ b/screen_connector_watcher/src/screen_connector_toolkit.c @@ -154,8 +154,10 @@ static void __destroy_type_h(gpointer data) if (type_h->aul_handle) aul_screen_connector_remove_screen_viewer(type_h->aul_handle); - if (type_h->toolkit_table) + if (type_h->toolkit_table) { g_hash_table_destroy(type_h->toolkit_table); + type_h->toolkit_table = NULL; + } free(type_h); } @@ -202,20 +204,17 @@ static void __aul_screen_viewer_cb(const char *appid, const char *instance_id, EXPORT_API int screen_connector_toolkit_init(screen_connector_screen_type_e type) { int ret = 0; - int *key; screen_connector_type_h type_h; ret = screen_connector_trs_init(); if (__type_table == NULL) - __type_table = g_hash_table_new_full(g_int_hash, g_int_equal, free, __destroy_type_h); + __type_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __destroy_type_h); - type_h = g_hash_table_lookup(__type_table, &type); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h == NULL) { - key = (int *)calloc(1, sizeof(int)); - *key = type; type_h = (screen_connector_type_h)calloc(1, sizeof(struct _screen_connector_type_h)); - g_hash_table_insert(__type_table, key, type_h); + g_hash_table_insert(__type_table, GINT_TO_POINTER(type), type_h); } return ret; @@ -231,9 +230,9 @@ EXPORT_API int screen_connector_toolkit_fini(screen_connector_screen_type_e type return 0; } - type_h = g_hash_table_lookup(__type_table, &type); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h) - g_hash_table_remove(__type_table, &type); + g_hash_table_remove(__type_table, GINT_TO_POINTER(type)); if (g_hash_table_size(__type_table) == 0) { ret = screen_connector_trs_fini(); @@ -284,7 +283,7 @@ EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_add(screen_connec return NULL; } - type_h = g_hash_table_lookup(__type_table, &type); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h == NULL) { LOGE("type %d is not initialized !!", type); return NULL; diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index 5d5baa0..70f9a17 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -61,26 +61,25 @@ static void __destroy_type_h(gpointer data) if (!type_h) return; - if (type_h->toolkit_table) + if (type_h->toolkit_table) { g_hash_table_destroy(type_h->toolkit_table); + type_h->toolkit_table = NULL; + } free(type_h); } EXPORT_API int screen_connector_toolkit_evas_init(Evas_Object *win, screen_connector_screen_type_e type) { screen_connector_type_evas_h type_h; - int *key; if (__type_table == NULL) - __type_table = g_hash_table_new_full(g_int_hash, g_int_equal, free, __destroy_type_h); + __type_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __destroy_type_h); - type_h = g_hash_table_lookup(__type_table, &type); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h == NULL) { - key = (int *)calloc(1, sizeof(int)); - *key = type; type_h = (screen_connector_type_evas_h)calloc(1, sizeof(struct _screen_connector_type_evas_h)); - g_hash_table_insert(__type_table, key, type_h); + g_hash_table_insert(__type_table, GINT_TO_POINTER(type), type_h); type_h->toolkit_table = g_hash_table_new(g_direct_hash, g_direct_equal); if (!type_h->toolkit_table) { @@ -102,11 +101,13 @@ EXPORT_API int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e return 0; } - type_h = g_hash_table_lookup(__type_table, &type); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h) { - if (type_h->toolkit_table) + if (type_h->toolkit_table) { g_hash_table_destroy(type_h->toolkit_table); - g_hash_table_remove(__type_table, &type); + type_h->toolkit_table = NULL; + } + g_hash_table_remove(__type_table, GINT_TO_POINTER(type)); } if (g_hash_table_size(__type_table) == 0) { @@ -582,7 +583,7 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(scr screen_connector_type_evas_h type_h; int int_type = type; - type_h = g_hash_table_lookup(__type_table, &int_type); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(int_type)); if (type_h == NULL) { LOGE("type %d is not initialized !!", type); return NULL; @@ -829,7 +830,7 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_ screen_connector_type_evas_h type_h; char rid_str[32]; - type_h = g_hash_table_lookup(__type_table, &type); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h == NULL) { LOGE("type %d is not initialized !!", type); return NULL; -- 2.7.4 From 05cba774f590532a505a63216a7ae75d68170b15 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Thu, 16 Mar 2017 10:56:31 +0900 Subject: [PATCH 06/16] Add tbm buffer destroy logic tbm buffer should be handled by viewer side. If not, tbm_surface fd will be remained after widget is deleted. Change-Id: Ia6abc17c53af08c24d7d080378c121879e1a291d Signed-off-by: Hyunho Kang (cherry picked from commit 2d09ccf2a1b73ef116d700b1de5a0dbcbc901a89) --- .../src/screen_connector_toolkit_evas.c | 9 ++++++++- .../src/screen_connector_watcher_evas.c | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index 70f9a17..5a78547 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "screen_connector_toolkit.h" #include "screen_connector_toolkit_evas.h" @@ -415,6 +417,7 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, char format[] = "png"; char plug_id[256]; screen_connector_toolkit_evas_h toolkit_evas_h; + tbm_surface_h pre_tbm_surface; toolkit_evas_h = (screen_connector_toolkit_evas_h)data; if (toolkit_evas_h->img_tbm == NULL) { @@ -492,8 +495,12 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, } if (toolkit_evas_h->pre_buffer) { - if (tizen_remote_surface_get_version(trs) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION) + if (tizen_remote_surface_get_version(trs) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION) { tizen_remote_surface_release(trs, toolkit_evas_h->pre_buffer); + pre_tbm_surface = (tbm_surface_h)wl_buffer_get_user_data(toolkit_evas_h->pre_buffer); + tbm_surface_internal_unref(pre_tbm_surface); + wl_buffer_destroy(toolkit_evas_h->pre_buffer); + } } toolkit_evas_h->pre_buffer = tbm; diff --git a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c index 175d03b..3f0eddc 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "screen_connector_watcher.h" #include "screen_connector_watcher_evas.h" @@ -148,6 +150,7 @@ static void __watcher_update_cb(struct tizen_remote_surface *trs, uint32_t type, char format[] = "png"; screen_connector_watcher_evas_h watcher_evas_h = (screen_connector_watcher_evas_h)data; img_info_h info; + tbm_surface_h pre_tbm_surface; if (tbm == NULL && type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM) { LOGE("TBM is null !! %d, %s, %s", TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM, appid, instance_id); @@ -215,8 +218,12 @@ static void __watcher_update_cb(struct tizen_remote_surface *trs, uint32_t type, } if (info->pre_buffer) { - if (tizen_remote_surface_get_version(trs) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION) + if (tizen_remote_surface_get_version(trs) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION) { tizen_remote_surface_release(trs, info->pre_buffer); + pre_tbm_surface = (tbm_surface_h)wl_buffer_get_user_data(info->pre_buffer); + tbm_surface_internal_unref(pre_tbm_surface); + wl_buffer_destroy(info->pre_buffer); + } } info->pre_buffer = tbm; close(img_file_fd); /* close passed fd */ -- 2.7.4 From 37d3685ffff8645be11073128affd4f66e6565c1 Mon Sep 17 00:00:00 2001 From: "seungha.son" Date: Mon, 3 Apr 2017 09:39:45 +0900 Subject: [PATCH 07/16] Fix memory leak Signed-off-by: seungha.son Change-Id: I81669725500ecf915feca52bbb303aa8cb55bea1 (cherry picked from commit 7dc3034997783c336c8fcaab761d4cfffa93a0e9) --- screen_connector_watcher_evas/src/screen_connector_watcher_evas.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c index 3f0eddc..0e4d177 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -231,18 +231,22 @@ static void __watcher_update_cb(struct tizen_remote_surface *trs, uint32_t type, EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add(screen_connector_watcher_evas_ops *ops, void *data) { - screen_connector_watcher_evas_h handle; screen_connector_watcher_evas_ops *evas_ops; screen_connector_watcher_ops *watcher_ops; watcher_ops = (screen_connector_watcher_ops *)calloc(1, sizeof(screen_connector_watcher_ops)); + if (watcher_ops == NULL) { + LOGE("watcher_ops calloc fail"); + return NULL; + } watcher_ops->added_cb = __watcher_added_cb; watcher_ops->updated_cb = __watcher_update_cb; watcher_ops->removed_cb = __watcher_removed_cb; evas_ops = (screen_connector_watcher_evas_ops *)calloc(1, sizeof(screen_connector_watcher_evas_ops)); if (evas_ops == NULL) { + free(watcher_ops); LOGE("evas_ops calloc fail"); return NULL; } @@ -251,6 +255,7 @@ EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add(scr handle = (screen_connector_watcher_evas_h)calloc(1, sizeof(struct _screen_connector_watcher_evas_h)); if (handle == NULL) { LOGE("handle calloc fail"); + free(watcher_ops); free(evas_ops); return NULL; } @@ -259,7 +264,6 @@ EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add(scr handle->watcher_h = screen_connector_watcher_add(watcher_ops, handle); return handle; - } static void __destroy_watcher_evas_handle(screen_connector_watcher_evas_h watcher_evas_h) -- 2.7.4 From 197eb51514caf094a9dacfeb356e00c633543c36 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Mon, 3 Apr 2017 10:27:59 +0900 Subject: [PATCH 08/16] Fix memory leak Change-Id: Ie3ff7bcbb7340b1e6336e19ad5b2e1ab667dda0e Signed-off-by: Hyunho Kang (cherry picked from commit 0b07eb5a3e067f73857aae585ac369433ad8e1fa) --- screen_connector_watcher/src/screen_connector_watcher.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index 36df1d9..02bd07b 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -206,6 +206,9 @@ static void __destroy_watcher_h(screen_connector_watcher_h handle) if (!handle) return; + if (handle->ops) + free(handle->ops); + if (handle->aul_handle) aul_screen_connector_remove_screen_viewer(handle->aul_handle); -- 2.7.4 From e92ecd43a72a70a48a57653bc4d979a2d8d5ef0b Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Wed, 12 Apr 2017 20:39:40 +0900 Subject: [PATCH 09/16] Make widget work. The data of '___PLUGID' key is used on accessibility environment. A widget process window such as 'Alarm Widget' on wearable is using same data. Becase the widget process could make more than one window, the data should be the instance ID, NOT the application ID to separate thoes windows. Change-Id: I2ee38bc57128b4c6497111b1628183512ed9e0f2 --- screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index 5a78547..ea1d1ad 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -454,7 +454,7 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, g_hash_table_insert(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm, toolkit_evas_h); /* Set data to use in accessibility */ - snprintf(plug_id, sizeof(plug_id), "%s:%d", appid, pid); + snprintf(plug_id, sizeof(plug_id), "%s:%d", instance_id, pid); evas_object_data_set(toolkit_evas_h->img_tbm, "___PLUGID", strdup(plug_id)); evas_object_event_callback_add(toolkit_evas_h->img_tbm, EVAS_CALLBACK_MOVE, __obj_update_visibility, toolkit_evas_h); -- 2.7.4 From bdd46fd18e3e1ea115c7da869cf1b88655cf9020 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Tue, 18 Apr 2017 20:24:13 +0900 Subject: [PATCH 10/16] Add bind surface APIs - screen_connector_toolkit_add_with_surface - screen_connector_toolkit_evas_add_with_win Change-Id: I375e74a3a6b26da81befff3109987fc9b9a32234 Signed-off-by: Hyunho Kang (cherry picked from commit e4674c573afede712f7f0b92afefaae90dd46e73) --- .../include/screen_connector_toolkit.h | 2 + .../src/screen_connector_toolkit.c | 61 +++++++++++++++++++++ .../include/screen_connector_toolkit_evas.h | 3 ++ .../src/screen_connector_toolkit_evas.c | 62 ++++++++++++++++++++++ 4 files changed, 128 insertions(+) diff --git a/screen_connector_watcher/include/screen_connector_toolkit.h b/screen_connector_watcher/include/screen_connector_toolkit.h index a5db07e..39968b1 100644 --- a/screen_connector_watcher/include/screen_connector_toolkit.h +++ b/screen_connector_watcher/include/screen_connector_toolkit.h @@ -78,6 +78,8 @@ screen_connector_toolkit_h screen_connector_toolkit_create_handle(char *id, int screen_connector_toolkit_ops *ops, void *data); struct tizen_remote_surface *screen_connector_toolkit_get_trs(screen_connector_toolkit_h h); int screen_connector_toolkit_redirect_surface(screen_connector_toolkit_h info); +screen_connector_toolkit_h screen_connector_toolkit_add_with_surface(screen_connector_toolkit_ops *ops, char *id, + screen_connector_screen_type_e type, struct wl_surface *surface, void *data); #ifdef __cplusplus } diff --git a/screen_connector_watcher/src/screen_connector_toolkit.c b/screen_connector_watcher/src/screen_connector_toolkit.c index 910d73f..3a36df2 100644 --- a/screen_connector_watcher/src/screen_connector_toolkit.c +++ b/screen_connector_watcher/src/screen_connector_toolkit.c @@ -52,6 +52,7 @@ struct _screen_connector_toolkit_h { struct tizen_remote_surface *surface; struct _screen_connector_type_h *type_h; void *data; + struct wl_surface *bind_surface; }; static GHashTable *__type_table; @@ -110,6 +111,9 @@ EXPORT_API int screen_connector_toolkit_redirect_surface(screen_connector_toolki tizen_remote_surface_add_listener(toolkit_h->surface, &__rs_listener, toolkit_h); tizen_remote_surface_redirect(toolkit_h->surface); + if (toolkit_h->bind_surface != NULL) + tizen_remote_surface_manager_bind_surface(rsm, toolkit_h->bind_surface, toolkit_h->surface); + return 0; } @@ -271,6 +275,63 @@ EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_create_handle(cha return toolkit_h; } +EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_add_with_surface(screen_connector_toolkit_ops *ops, char *id, + screen_connector_screen_type_e type, struct wl_surface *surface, void *data) +{ + screen_connector_toolkit_h toolkit_h; + screen_connector_type_h type_h; + screen_connector_toolkit_ops *ops_copy; + + if (id == NULL || ops == NULL) { + LOGE("Invalid param"); + return NULL; + } + + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); + if (type_h == NULL) { + LOGE("type %d is not initialized !!", type); + return NULL; + } + + ops_copy = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); + if (ops_copy == NULL) { + LOGE("ops_copy calloc fail"); + return NULL; + } + memcpy(ops_copy, ops, sizeof(screen_connector_toolkit_ops)); + + toolkit_h = (screen_connector_toolkit_h)calloc(1, sizeof(struct _screen_connector_toolkit_h)); + if (toolkit_h == NULL) { + LOGE("toolkit_h calloc fail"); + free(ops_copy); + return NULL; + } + + toolkit_h->instance_id = strdup(id); + if (toolkit_h->instance_id == NULL) { + LOGE("strdup id fail"); + free(ops_copy); + free(toolkit_h); + return NULL; + } + + toolkit_h->data = data; + toolkit_h->ops = ops_copy; + toolkit_h->type_h = type_h; + toolkit_h->bind_surface = surface; + + if (type_h->toolkit_table == NULL) + type_h->toolkit_table = g_hash_table_new_full(g_str_hash, + g_str_equal, free, __destroy_toolkit_h); + + g_hash_table_insert(type_h->toolkit_table, strdup(id), toolkit_h); + + if (type_h->aul_handle == NULL) + aul_screen_connector_add_screen_viewer(__aul_screen_viewer_cb, type, true, type_h, &type_h->aul_handle); + + return toolkit_h; +} + EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_add(screen_connector_toolkit_ops *ops, char *id, screen_connector_screen_type_e type, void *data) { diff --git a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h index 1fb75f6..d0d4a89 100644 --- a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h +++ b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h @@ -105,6 +105,9 @@ int screen_connector_toolkit_evas_get_pid(Evas_Object *obj, int *pid); screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_rid(screen_connector_toolkit_evas_ops *ops, int res_id, screen_connector_screen_type_e type, void *data); int screen_connector_toolkit_evas_get_rid(Evas_Object *obj, int *resource_id); +screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_with_win(screen_connector_toolkit_evas_ops *ops, char *id, + screen_connector_screen_type_e type, Evas_Object *win, void *data); + /** * @} diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index ea1d1ad..ea8961a 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -581,6 +581,68 @@ static void __toolkit_removed_cb(const char *appid, const char *instance_id, con __free_toolkit_evas_h(toolkit_evas_h); } +EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_with_win(screen_connector_toolkit_evas_ops *ops, char *id, + screen_connector_screen_type_e type, Evas_Object *win, void *data) +{ + screen_connector_toolkit_evas_h handle; + screen_connector_toolkit_evas_ops *evas_ops; + screen_connector_toolkit_ops toolkit_ops; + screen_connector_type_evas_h type_h; + int int_type = type; + struct wl_surface *surface; + Ecore_Wl_Window *wl_win; + + if (win == NULL || ops == NULL || id == NULL + || type < SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET + || type > SCREEN_CONNECTOR_SCREEEN_TYPE_ALL) { + LOGE("Invalid param NULL"); + return NULL; + } + + wl_win = elm_win_wl_window_get(win); + if (wl_win == NULL) { + LOGE("failed to get wl_win"); + return NULL; + } + + surface = ecore_wl_window_surface_get(wl_win); + if (surface == NULL) { + LOGE("failed to get surface"); + return NULL; + } + + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(int_type)); + if (type_h == NULL) { + LOGE("type %d is not initialized !!", type); + return NULL; + } + + toolkit_ops.added_cb = __toolkit_added_cb; + toolkit_ops.updated_cb = NULL; + toolkit_ops.removed_cb = __toolkit_removed_cb; + + evas_ops = (screen_connector_toolkit_evas_ops *)calloc(1, sizeof(screen_connector_toolkit_evas_ops)); + if (evas_ops == NULL) { + LOGE("evas_ops calloc fail"); + return NULL; + } + + memcpy(evas_ops, ops, sizeof(screen_connector_toolkit_evas_ops)); + handle = (screen_connector_toolkit_evas_h)calloc(1, sizeof(struct _screen_connector_toolkit_evas_h)); + if (handle == NULL) { + LOGE("handle calloc fail"); + free(evas_ops); + return NULL; + } + handle->img_type = -1; + handle->ops = evas_ops; + handle->data = data; + handle->type_h = type_h; + handle->toolkit_h = screen_connector_toolkit_add_with_surface(&toolkit_ops, id, type, surface, handle); + + return handle; +} + EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(screen_connector_toolkit_evas_ops *ops, char *id, screen_connector_screen_type_e type, void *data) { -- 2.7.4 From 9d6abe60aaeed93ca7dfc1f7a81ec093cc076b11 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Wed, 19 Apr 2017 14:05:53 +0900 Subject: [PATCH 11/16] Fix toolkit_table destroy bug screen_connector_toolkit_evas_fini is called remote surface is destroyed but screen_connector_toolkit_evas_h will not freed, so callback which have a screen_connector_toolkit_evas_h as a user data like __rs_cb_mouse_move callback could cause crash when they try to send event through already destroyed remote surface Change-Id: Ifda77fa1cb0244186179c7ffe2dc77b536593586 Signed-off-by: Hyunho Kang (cherry picked from commit e5b91194895ffb1bb3b1b32a77c14dbb42963c64) --- .../src/screen_connector_toolkit_evas.c | 149 +++++++++++---------- 1 file changed, 80 insertions(+), 69 deletions(-) diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index ea8961a..da62bf8 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -34,6 +34,7 @@ #endif #define LOG_TAG "SC_WATCHER_EVAS" +#define SC_TOOLKIT_HANDLE_TAG "SC_TOOLKIT_HANDLE_TAG" struct _screen_connector_type_evas_h { GHashTable *toolkit_table; @@ -70,6 +71,53 @@ static void __destroy_type_h(gpointer data) free(type_h); } +static void __clear_img_tbm(screen_connector_toolkit_evas_h toolkit_evas_h) +{ + char *plug_id; + + if (toolkit_evas_h->img_tbm == NULL) + return; + + plug_id = evas_object_data_del(toolkit_evas_h->img_tbm, "___PLUGID"); + if (plug_id) + free(plug_id); + + evas_object_del(toolkit_evas_h->img_tbm); + toolkit_evas_h->img_tbm = NULL; +} + +static void __clear_img_file(screen_connector_toolkit_evas_h toolkit_evas_h) +{ + if (toolkit_evas_h->img_file == NULL) + return; + + evas_object_del(toolkit_evas_h->img_file); + toolkit_evas_h->img_file = NULL; +} + +static void __destroy_toolkit_evas_h(gpointer data) +{ + char *plug_id; + screen_connector_toolkit_evas_h toolkit_evas_h = data; + + if (!toolkit_evas_h) + return; + + if (toolkit_evas_h->img_tbm != NULL) { + plug_id = evas_object_data_del(toolkit_evas_h->img_tbm, "___PLUGID"); + if (plug_id) + free(plug_id); + } + + if (toolkit_evas_h->toolkit_h) + screen_connector_toolkit_remove(toolkit_evas_h->toolkit_h); + + if (toolkit_evas_h->ops) + free(toolkit_evas_h->ops); + + free(toolkit_evas_h); +} + EXPORT_API int screen_connector_toolkit_evas_init(Evas_Object *win, screen_connector_screen_type_e type) { screen_connector_type_evas_h type_h; @@ -83,7 +131,7 @@ EXPORT_API int screen_connector_toolkit_evas_init(Evas_Object *win, screen_conne type_h = (screen_connector_type_evas_h)calloc(1, sizeof(struct _screen_connector_type_evas_h)); g_hash_table_insert(__type_table, GINT_TO_POINTER(type), type_h); - type_h->toolkit_table = g_hash_table_new(g_direct_hash, g_direct_equal); + type_h->toolkit_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, __destroy_toolkit_evas_h); if (!type_h->toolkit_table) { LOGE("failed to create table"); return -1; @@ -120,7 +168,7 @@ EXPORT_API int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e return screen_connector_toolkit_fini(type); } -static bool __obj_is_visible(Evas_Object *obj, screen_connector_toolkit_evas_h toolkit_evas_h) +static bool __obj_is_visible(screen_connector_toolkit_evas_h toolkit_evas_h) { int x, y, w, h; Ecore_Wl_Window *window = NULL; @@ -132,9 +180,14 @@ static bool __obj_is_visible(Evas_Object *obj, screen_connector_toolkit_evas_h t return false; } + if (toolkit_evas_h->img_tbm == NULL) { + LOGE("img_tbm is NULL"); + return false; + } + window = elm_win_wl_window_get(toolkit_evas_h->type_h->viewer_win); ecore_wl_window_geometry_get(window, &window_x, &window_y, &window_w, &window_h); - evas_object_geometry_get(obj, &x, &y, &w, &h); + evas_object_geometry_get(toolkit_evas_h->img_tbm, &x, &y, &w, &h); rotation = ecore_wl_window_rotation_get(window); if (x >= 0 && x < window_w && @@ -192,7 +245,7 @@ static void __obj_update_visibility(void *data, Evas *e, Evas_Object *obj, void return; } - if (__obj_is_visible(obj, toolkit_evas_h)) + if (__obj_is_visible(toolkit_evas_h)) __set_visibility(toolkit_evas_h, VISIBILITY_TYPE_UNOBSCURED); else __set_visibility(toolkit_evas_h, VISIBILITY_TYPE_FULLY_OBSCURED); @@ -386,25 +439,6 @@ static void __rs_cb_resize(void *data, Evas *e, Evas_Object *obj, void *event_in __obj_update_visibility(data, e, obj, event_info); } -static void __clear_img_tbm(screen_connector_toolkit_evas_h toolkit_evas_h) -{ - if (toolkit_evas_h->img_tbm == NULL) - return; - - g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm); - evas_object_del(toolkit_evas_h->img_tbm); - toolkit_evas_h->img_tbm = NULL; -} - -static void __clear_img_file(screen_connector_toolkit_evas_h toolkit_evas_h) -{ - if (toolkit_evas_h->img_file == NULL) - return; - - evas_object_del(toolkit_evas_h->img_file); - toolkit_evas_h->img_file = NULL; -} - static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, const char *appid, const char *instance_id, const int pid, void *data) @@ -451,11 +485,13 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, __rs_cb_resize, toolkit_evas_h); /* Store toolkit_evas_h */ - g_hash_table_insert(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm, toolkit_evas_h); + g_hash_table_insert(toolkit_evas_h->type_h->toolkit_table, strdup(instance_id), toolkit_evas_h); /* Set data to use in accessibility */ snprintf(plug_id, sizeof(plug_id), "%s:%d", instance_id, pid); evas_object_data_set(toolkit_evas_h->img_tbm, "___PLUGID", strdup(plug_id)); + + evas_object_data_set(toolkit_evas_h->img_tbm, SC_TOOLKIT_HANDLE_TAG, toolkit_evas_h); evas_object_event_callback_add(toolkit_evas_h->img_tbm, EVAS_CALLBACK_MOVE, __obj_update_visibility, toolkit_evas_h); } @@ -534,25 +570,6 @@ static void __toolkit_added_cb(const char *appid, const char *instance_id, const { } -static void __free_toolkit_evas_h(screen_connector_toolkit_evas_h toolkit_evas_h) -{ - if (!toolkit_evas_h) - return; - - if (toolkit_evas_h->toolkit_h) - screen_connector_toolkit_remove(toolkit_evas_h->toolkit_h); - - __clear_img_file(toolkit_evas_h); - __clear_img_tbm(toolkit_evas_h); - - if (toolkit_evas_h->ops) { - free(toolkit_evas_h->ops); - toolkit_evas_h->ops = NULL; - } - - free(toolkit_evas_h); -} - static void __toolkit_removed_cb(const char *appid, const char *instance_id, const int pid, void *data) { screen_connector_toolkit_evas_h toolkit_evas_h; @@ -565,20 +582,18 @@ static void __toolkit_removed_cb(const char *appid, const char *instance_id, con return; } - if (toolkit_evas_h->type_h->toolkit_table != NULL && toolkit_evas_h->img_tbm != NULL) { - g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm); - - /* Remove data used in accessibility */ + if (toolkit_evas_h->img_tbm != NULL) { plug_id = evas_object_data_del(toolkit_evas_h->img_tbm, "___PLUGID"); - free(plug_id); - } + if (plug_id) + free(plug_id); - if (toolkit_evas_h->img_tbm != NULL) + evas_object_data_del(toolkit_evas_h->img_tbm, SC_TOOLKIT_HANDLE_TAG); toolkit_evas_h->ops->removed_cb(appid, instance_id, pid, toolkit_evas_h->img_tbm, toolkit_evas_h->data); - else if (toolkit_evas_h->img_file != NULL) + } else if (toolkit_evas_h->img_file != NULL) { toolkit_evas_h->ops->removed_cb(appid, instance_id, pid, toolkit_evas_h->img_file, toolkit_evas_h->data); + } - __free_toolkit_evas_h(toolkit_evas_h); + g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, instance_id); } EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_with_win(screen_connector_toolkit_evas_ops *ops, char *id, @@ -686,10 +701,18 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(scr EXPORT_API int screen_connector_toolkit_evas_remove(screen_connector_toolkit_evas_h handle) { + const char *instance_id; + if (handle == NULL) return -1; - __free_toolkit_evas_h(handle); + instance_id = screen_connector_toolkit_get_instance_id(handle->toolkit_h); + if (instance_id == NULL) { + LOGE("Null instance_id"); + return -1; + } + g_hash_table_remove(handle->type_h->toolkit_table, instance_id); + return 0; } @@ -701,7 +724,6 @@ EXPORT_API int screen_connector_toolkit_evas_update(const char *appid, const cha static void __send_visibility(gpointer key, gpointer value, gpointer user_data) { screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)value; - Evas_Object *evas_obj = (Evas_Object *)key; unsigned int event = GPOINTER_TO_INT(user_data); int ret; visibility_type type; @@ -709,7 +731,7 @@ static void __send_visibility(gpointer key, gpointer value, gpointer user_data) if (toolkit_evas_h->freeze) return; - if (!__obj_is_visible(evas_obj, toolkit_evas_h)) + if (!__obj_is_visible(toolkit_evas_h)) return; if (event) @@ -719,7 +741,7 @@ static void __send_visibility(gpointer key, gpointer value, gpointer user_data) ret = __set_visibility(toolkit_evas_h, type); if (ret == -1) - LOGE("failed to set object visibility set %p to %d", evas_obj, type); + LOGE("failed to set object visibility set %p to %d", toolkit_evas_h->img_tbm, type); } static Eina_Bool __visibility_cb(void *data, int type, void *event) @@ -770,21 +792,10 @@ EXPORT_API int screen_connector_toolkit_evas_stop_visibility_notify(void) screen_connector_toolkit_evas_h __find_toolkit_evas_h(Evas_Object *obj) { screen_connector_toolkit_evas_h toolkit_evas_h; - GHashTableIter iter; - gpointer key, value; - screen_connector_type_evas_h cur_type; - g_hash_table_iter_init(&iter, __type_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - cur_type = (screen_connector_type_evas_h)value; - if (cur_type->toolkit_table) { - toolkit_evas_h = g_hash_table_lookup(cur_type->toolkit_table, obj); - if (toolkit_evas_h != NULL) - return toolkit_evas_h; - } - } + toolkit_evas_h = evas_object_data_get(obj, SC_TOOLKIT_HANDLE_TAG); - return NULL; + return toolkit_evas_h; } EXPORT_API int screen_connector_toolkit_evas_freeze_visibility(Evas_Object *obj, visibility_type type) -- 2.7.4 From ca3456314b10f189efc3a53e418046225600f076 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Wed, 26 Apr 2017 14:08:33 +0900 Subject: [PATCH 12/16] Delay resuming time - This patch allows some widgets to postpone getting resuming callback - If widgets change the visibility repeatedly, the performance will not be good - Added API will help to adjust the delayed resuming time - By default, the delayed resuming time is 0 Change-Id: I87edb61a7706bd0abf28fe63c9289c56635d64e5 Signed-off-by: Junghoon Park (cherry picked from commit acf380a217578c085f28fa13b10f8cba00f5ae53) --- .../include/screen_connector_toolkit_evas.h | 1 + .../src/screen_connector_toolkit_evas.c | 51 +++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h index d0d4a89..b1ae572 100644 --- a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h +++ b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h @@ -65,6 +65,7 @@ int screen_connector_toolkit_evas_init(Evas_Object *win, screen_connector_screen int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e type); screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(screen_connector_toolkit_evas_ops *ops, char *id, screen_connector_screen_type_e type, void *data); +int screen_connector_toolkit_evas_set_delayed_resuming_time(int ms); int screen_connector_toolkit_evas_remove(screen_connector_toolkit_evas_h handle); int screen_connector_toolkit_evas_update(const char *appid, const char *instance_id); int screen_connector_toolkit_evas_start_visibility_notify(void); diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index da62bf8..7af5c5c 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -52,11 +52,13 @@ struct _screen_connector_toolkit_evas_h { uint32_t img_type; struct wl_buffer *pre_buffer; struct _screen_connector_type_evas_h *type_h; + guint resuming_timer; void *data; }; static GHashTable *__type_table = NULL; static Ecore_Event_Handler *__visibility_listener; +static int __delayed_resuming_time; static void __destroy_type_h(gpointer data) { @@ -115,6 +117,9 @@ static void __destroy_toolkit_evas_h(gpointer data) if (toolkit_evas_h->ops) free(toolkit_evas_h->ops); + if (toolkit_evas_h->resuming_timer > 0) + g_source_remove(toolkit_evas_h->resuming_timer); + free(toolkit_evas_h); } @@ -165,6 +170,8 @@ EXPORT_API int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e __type_table = NULL; } + __delayed_resuming_time = 0; + return screen_connector_toolkit_fini(type); } @@ -207,6 +214,22 @@ static bool __obj_is_visible(screen_connector_toolkit_evas_h toolkit_evas_h) return false; } +static gboolean __resuming_timeout_cb(gpointer user_data) +{ + screen_connector_toolkit_evas_h toolkit_evas_h = user_data; + struct tizen_remote_surface *surface; + + surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); + if (surface) { + tizen_remote_surface_transfer_visibility(surface, + TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE); + } + + toolkit_evas_h->resuming_timer = 0; + + return G_SOURCE_REMOVE; +} + static int __set_visibility(screen_connector_toolkit_evas_h toolkit_evas_h, visibility_type type) { int obscured; @@ -230,9 +253,28 @@ static int __set_visibility(screen_connector_toolkit_evas_h toolkit_evas_h, visi } surface = screen_connector_toolkit_get_trs(toolkit_evas_h->toolkit_h); - if (surface) + if (!surface) + return -1; + + if (__delayed_resuming_time == 0) { tizen_remote_surface_transfer_visibility(surface, obscured); + return 0; + } + + if (obscured == TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_INVISIBLE) { + if (toolkit_evas_h->resuming_timer > 0) { + g_source_remove(toolkit_evas_h->resuming_timer); + toolkit_evas_h->resuming_timer = 0; + } + tizen_remote_surface_transfer_visibility(surface, obscured); + } else { + if (toolkit_evas_h->resuming_timer == 0) { + toolkit_evas_h->resuming_timer = g_timeout_add(__delayed_resuming_time, + __resuming_timeout_cb, toolkit_evas_h); + } + } + return 0; } @@ -596,6 +638,13 @@ static void __toolkit_removed_cb(const char *appid, const char *instance_id, con g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, instance_id); } +EXPORT_API int screen_connector_toolkit_evas_set_delayed_resuming_time(int ms) +{ + __delayed_resuming_time = ms; + + return 0; +} + EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_with_win(screen_connector_toolkit_evas_ops *ops, char *id, screen_connector_screen_type_e type, Evas_Object *win, void *data) { -- 2.7.4 From 365a36cc65c0d7d6638a449d2a668d8cc46cfe3a Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Tue, 16 May 2017 11:18:24 +0900 Subject: [PATCH 13/16] Add APIs to control visibility Change-Id: I901d56fce6ab6703f865388fd361157b374f82d6 Signed-off-by: Junghoon Park (cherry picked from commit fcefc9d15e719d27fcc34919d2fd2eca079259fc) --- .../include/screen_connector_toolkit_evas.h | 1 + .../src/screen_connector_toolkit_evas.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h index b1ae572..7cd665d 100644 --- a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h +++ b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h @@ -72,6 +72,7 @@ int screen_connector_toolkit_evas_start_visibility_notify(void); int screen_connector_toolkit_evas_stop_visibility_notify(void); int screen_connector_toolkit_evas_freeze_visibility(Evas_Object *obj, visibility_type type); int screen_connector_toolkit_evas_thaw_visibility(Evas_Object *obj); +int screen_connector_toolkit_evas_send_visibility(Evas_Object *obj, visibility_type type); int screen_connector_toolkit_evas_send_mouse_up(Evas_Object *obj); int screen_connector_toolkit_evas_send_touch_cancel(Evas_Object *obj); diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index 7af5c5c..6dab25b 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -875,6 +875,19 @@ EXPORT_API int screen_connector_toolkit_evas_thaw_visibility(Evas_Object *obj) return 0; } +EXPORT_API int screen_connector_toolkit_evas_send_visibility(Evas_Object *obj, visibility_type type) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("obj not found"); + return -1; + } + + return __set_visibility(toolkit_evas_h, type); +} + EXPORT_API int screen_connector_toolkit_evas_send_mouse_up(Evas_Object *obj) { screen_connector_toolkit_evas_h toolkit_evas_h; -- 2.7.4 From dc8164a1c543c62c4f508c77f4a955519e017a94 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Wed, 31 May 2017 19:26:00 +0900 Subject: [PATCH 14/16] Add object visible check API - screen_connector_toolkit_evas_is_visible Change-Id: Id8010fa0507770ea85135fcf3597032f36ca0734 Signed-off-by: Hyunho Kang (cherry picked from commit 5616860841370bdd65cdc322ebf735199073f751) --- .../include/screen_connector_toolkit_evas.h | 1 + .../src/screen_connector_toolkit_evas.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h index 7cd665d..4a6dabf 100644 --- a/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h +++ b/screen_connector_watcher_evas/include/screen_connector_toolkit_evas.h @@ -109,6 +109,7 @@ screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_rid(screen_ int screen_connector_toolkit_evas_get_rid(Evas_Object *obj, int *resource_id); screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_with_win(screen_connector_toolkit_evas_ops *ops, char *id, screen_connector_screen_type_e type, Evas_Object *win, void *data); +int screen_connector_toolkit_evas_is_visible(Evas_Object *obj, bool *is_visible); /** diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index 6dab25b..dc5e989 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -1042,3 +1042,22 @@ EXPORT_API int screen_connector_toolkit_evas_get_pid(Evas_Object *obj, int *pid) return 0; } + +EXPORT_API int screen_connector_toolkit_evas_is_visible(Evas_Object *obj, bool *is_visible) +{ + screen_connector_toolkit_evas_h toolkit_evas_h; + + if (obj == NULL || is_visible == NULL) { + LOGE("invalid argument"); + return -1; + } + toolkit_evas_h = __find_toolkit_evas_h(obj); + if (!toolkit_evas_h) { + LOGE("obj not found"); + return -1; + } + + *is_visible = __obj_is_visible(toolkit_evas_h); + + return 0; +} -- 2.7.4 From 2984f4600a6f94d099b707689ea167a0b6cb55b5 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Thu, 25 May 2017 19:36:43 +0900 Subject: [PATCH 15/16] Add buffer changed event filter Some watcher application like task-manager want to receive only file type update event. Using these APIs developer can filter update event. - screen_connector_watcher_set_changed_event_filter - screen_connector_watcher_evas_set_changed_event_filter Change-Id: I773f6817d3ab6c2ac58941b1948940daaed90976 Signed-off-by: Hyunho Kang --- .../include/screen_connector_watcher.h | 10 ++++++++ .../src/screen_connector_trs.c | 2 +- .../src/screen_connector_watcher.c | 30 ++++++++++++++++++++++ .../include/screen_connector_watcher_evas.h | 9 +++++++ .../src/screen_connector_watcher_evas.c | 5 ++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/screen_connector_watcher/include/screen_connector_watcher.h b/screen_connector_watcher/include/screen_connector_watcher.h index 31d6b85..ca82edc 100644 --- a/screen_connector_watcher/include/screen_connector_watcher.h +++ b/screen_connector_watcher/include/screen_connector_watcher.h @@ -23,6 +23,14 @@ extern "C" { #endif +typedef enum { + SCREEN_CONNECTOR_CHANGED_EVENT_FILTER_NONE = TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_NONE, + SCREEN_CONNECTOR_CHANGED_EVENT_FILTER_TBM = TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM, + SCREEN_CONNECTOR_CHANGED_EVENT_FILTER_IMAGE_FILE = TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE, + SCREEN_CONNECTOR_CHANGED_EVENT_FILTER_ALL = + TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM | TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE, +} screen_connector_changed_event_filter_type; + typedef void (*screen_connector_watcher_added_cb)(const char *appid, const char *instance_id, const int pid, void *data); typedef void (*screen_connector_watcher_removed_cb)(const char *appid, const char *instance_id, const int pid, void *data); typedef void (*screen_connector_watcher_update_cb)(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, @@ -53,6 +61,8 @@ int screen_connector_watcher_set_resource_id(screen_connector_watcher_h h, int r struct tizen_remote_surface *screen_connector_watcher_get_trs(screen_connector_watcher_h h); screen_connector_watcher_h screen_connector_watcher_create_handle(char *id, int pid, screen_connector_watcher_ops *ops, void *data); int screen_connector_watcher_redirect_surface(screen_connector_info_h info); +int screen_connector_watcher_set_changed_event_filter(screen_connector_watcher_h h, + screen_connector_changed_event_filter_type type); #ifdef __cplusplus } diff --git a/screen_connector_watcher/src/screen_connector_trs.c b/screen_connector_watcher/src/screen_connector_trs.c index fedb303..548fcc1 100644 --- a/screen_connector_watcher/src/screen_connector_trs.c +++ b/screen_connector_watcher/src/screen_connector_trs.c @@ -72,7 +72,7 @@ int screen_connector_trs_init(void) if (!strcmp(global->interface, "tizen_remote_surface_manager")) { __rsm = wl_registry_bind(registry, global->id, &tizen_remote_surface_manager_interface, - global->version < 4 ? global->version : 4); + global->version < 5 ? global->version : 5); } } diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index 02bd07b..d4653a7 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -43,6 +43,7 @@ struct _screen_connector_watcher_h { void *data; GHashTable *info_table; aul_screen_viewer_h aul_handle; + screen_connector_changed_event_filter_type changed_filter; }; struct _screen_connector_info_h { @@ -54,6 +55,7 @@ struct _screen_connector_info_h { struct tizen_remote_surface *surface; bool renderable; void *data; + screen_connector_changed_event_filter_type changed_filter; }; static void __buffer_updated(void *data, struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time) @@ -106,6 +108,8 @@ EXPORT_API int screen_connector_watcher_redirect_surface(screen_connector_info_h LOGD("resource_id : %d, (%p)", info->surface_id, info->surface); tizen_remote_surface_add_listener(info->surface, &__rs_listener, info); tizen_remote_surface_redirect(info->surface); + tizen_remote_surface_set_changed_buffer_event_filter(info->surface, info->changed_filter); + LOGD("set filter [%d] for [%s]", info->changed_filter, info->instance_id); return 0; } @@ -158,6 +162,7 @@ static void __aul_screen_viewer_cb(const char *appid, const char *instance_id, info->ops = watcher_h->ops; info->data = watcher_h->data; info->renderable = false; + info->changed_filter = watcher_h->changed_filter; if (event_type == AUL_SCREEN_CONNECTOR_EVENT_TYPE_ADD) { @@ -228,6 +233,7 @@ EXPORT_API screen_connector_watcher_h screen_connector_watcher_add(screen_connec LOGE("watcher_h calloc fail"); return NULL; } + watcher_h->changed_filter = SCREEN_CONNECTOR_CHANGED_EVENT_FILTER_ALL; watcher_h->data = data; watcher_h->ops = ops; watcher_h->info_table = g_hash_table_new_full(g_str_hash, @@ -301,3 +307,27 @@ EXPORT_API void *screen_connector_watcher_get_user_data(screen_connector_info_h { return h->data; } + +EXPORT_API int screen_connector_watcher_set_changed_event_filter(screen_connector_watcher_h h, + screen_connector_changed_event_filter_type type) +{ + GHashTableIter iter; + gpointer key, value; + screen_connector_info_h info; + + if (h == NULL || h->info_table == NULL) { + LOGE("Invalid param"); + return -1; + } + + g_hash_table_iter_init(&iter, h->info_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + info = (screen_connector_info_h)value; + LOGD("set filter [%d] for [%s]", type, info->instance_id); + tizen_remote_surface_set_changed_buffer_event_filter(info->surface, type); + } + + h->changed_filter = type; + + return 0; +} diff --git a/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h b/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h index 75959dd..97e4528 100644 --- a/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h +++ b/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h @@ -36,6 +36,13 @@ extern "C" { * @addtogroup CAPI_SCREEN_CONNECTOR_WATCHER_EVAS_MODULE * @{ */ +typedef enum { + SCREEN_CONNECTOR_EVAS_CHANGED_EVENT_FILTER_NONE = TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_NONE, + SCREEN_CONNECTOR_EVAS_CHANGED_EVENT_FILTER_TBM = TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM, + SCREEN_CONNECTOR_EVAS_CHANGED_EVENT_FILTER_IMAGE_FILE = TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE, + SCREEN_CONNECTOR_EVAS_CHANGED_EVENT_FILTER_ALL = + TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM | TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE, +} screen_connector_evas_changed_event_filter_type; typedef void (*screen_connector_watcher_evas_added_cb)(const char *appid, const char *instance_id, const int pid, void *data); typedef void (*screen_connector_watcher_evas_removed_cb)(const char *appid, const char *instance_id, const int pid, void *data); @@ -55,6 +62,8 @@ int screen_connector_watcher_evas_fini(void); screen_connector_watcher_evas_h screen_connector_watcher_evas_add(screen_connector_watcher_evas_ops *ops, void *data); int screen_connector_watcher_evas_remove(screen_connector_watcher_evas_h h); int screen_connector_watcher_evas_update(screen_connector_watcher_evas_h watcher_evas_h, const char *instance_id); +int screen_connector_watcher_evas_set_changed_event_filter(screen_connector_watcher_evas_h watcher_evas_h, + screen_connector_evas_changed_event_filter_type type); /** * @} diff --git a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c index 0e4d177..b39b4cf 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -302,3 +302,8 @@ EXPORT_API int screen_connector_watcher_evas_update(screen_connector_watcher_eva return screen_connector_watcher_update(watcher_evas_h->watcher_h, instance_id); } +EXPORT_API int screen_connector_watcher_evas_set_changed_event_filter(screen_connector_watcher_evas_h watcher_evas_h, + screen_connector_evas_changed_event_filter_type type) +{ + return screen_connector_watcher_set_changed_event_filter(watcher_evas_h->watcher_h, type); +} -- 2.7.4 From 30b7fa3bf70ae082cd7bcb717060996700cc9b6c Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 2 Jun 2017 16:34:04 +0900 Subject: [PATCH 16/16] Fix add by rid bug - Only main viewer should remove prev tbm buffer. - Resources which generated by add_by_rid should be managed Change-Id: Icf2dfdc47b131e2efd86b82aabdb1ff683d30203 Signed-off-by: Hyunho Kang --- .../include/screen_connector_toolkit.h | 7 +- .../src/screen_connector_toolkit.c | 23 +++++- .../src/screen_connector_toolkit_evas.c | 83 ++++++++++++++++++---- 3 files changed, 96 insertions(+), 17 deletions(-) diff --git a/screen_connector_watcher/include/screen_connector_toolkit.h b/screen_connector_watcher/include/screen_connector_toolkit.h index 39968b1..7fe718c 100644 --- a/screen_connector_watcher/include/screen_connector_toolkit.h +++ b/screen_connector_watcher/include/screen_connector_toolkit.h @@ -74,13 +74,16 @@ void *screen_connector_toolkit_get_user_data(screen_connector_toolkit_h h); unsigned int screen_connector_toolkit_get_event_filter(screen_connector_toolkit_h h); int screen_connector_toolkit_check_input_disabled(screen_connector_toolkit_h h, screen_connector_input_type_e input); -screen_connector_toolkit_h screen_connector_toolkit_create_handle(char *id, int surface_id, - screen_connector_toolkit_ops *ops, void *data); +screen_connector_toolkit_h screen_connector_toolkit_add_by_rid(screen_connector_toolkit_ops *ops, char *id, + screen_connector_screen_type_e type, int surface_id, void *data); struct tizen_remote_surface *screen_connector_toolkit_get_trs(screen_connector_toolkit_h h); int screen_connector_toolkit_redirect_surface(screen_connector_toolkit_h info); screen_connector_toolkit_h screen_connector_toolkit_add_with_surface(screen_connector_toolkit_ops *ops, char *id, screen_connector_screen_type_e type, struct wl_surface *surface, void *data); +int screen_connector_toolkit_bind(screen_connector_toolkit_h h, struct wl_surface *surface); +int screen_connector_toolkit_unbind(screen_connector_toolkit_h h); + #ifdef __cplusplus } #endif diff --git a/screen_connector_watcher/src/screen_connector_toolkit.c b/screen_connector_watcher/src/screen_connector_toolkit.c index 3a36df2..0227d48 100644 --- a/screen_connector_watcher/src/screen_connector_toolkit.c +++ b/screen_connector_watcher/src/screen_connector_toolkit.c @@ -247,11 +247,18 @@ EXPORT_API int screen_connector_toolkit_fini(screen_connector_screen_type_e type return ret; } -EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_create_handle(char *id, int surface_id, - screen_connector_toolkit_ops *ops, void *data) +EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_add_by_rid(screen_connector_toolkit_ops *ops, char *id, + screen_connector_screen_type_e type, int surface_id, void *data) { screen_connector_toolkit_h toolkit_h = NULL; screen_connector_toolkit_ops *ops_copy; + screen_connector_type_h type_h; + + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); + if (type_h == NULL) { + LOGE("type %d is not initialized !!", type); + return NULL; + } ops_copy = (screen_connector_toolkit_ops *)calloc(1, sizeof(screen_connector_toolkit_ops)); if (ops_copy == NULL) { @@ -271,6 +278,18 @@ EXPORT_API screen_connector_toolkit_h screen_connector_toolkit_create_handle(cha toolkit_h->instance_id = strdup(id); toolkit_h->data = data; toolkit_h->ops = ops_copy; + toolkit_h->type_h = type_h; + + if (type_h->toolkit_table == NULL) + type_h->toolkit_table = g_hash_table_new_full(g_str_hash, + g_str_equal, free, __destroy_toolkit_h); + + g_hash_table_insert(type_h->toolkit_table, strdup(id), toolkit_h); + + if (type_h->aul_handle == NULL) + aul_screen_connector_add_screen_viewer(__aul_screen_viewer_cb, type, true, type_h, &type_h->aul_handle); + + screen_connector_toolkit_redirect_surface(toolkit_h); return toolkit_h; } diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index dc5e989..d2ef2f3 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "screen_connector_toolkit.h" #include "screen_connector_toolkit_evas.h" @@ -41,6 +42,12 @@ struct _screen_connector_type_evas_h { Evas_Object *viewer_win; }; +struct _cur_buffer_info_h { + struct wl_buffer *cur_buffer; + int ref_count; +}; +typedef struct _cur_buffer_info_h *cur_buffer_info_h; + struct _screen_connector_toolkit_evas_h { screen_connector_toolkit_evas_ops *ops; screen_connector_toolkit_h toolkit_h; @@ -50,12 +57,13 @@ struct _screen_connector_toolkit_evas_h { Evas_Object *img_tbm; Evas_Object *img_file; uint32_t img_type; - struct wl_buffer *pre_buffer; + struct wl_buffer *cur_buffer; struct _screen_connector_type_evas_h *type_h; guint resuming_timer; void *data; }; +static GHashTable *__cur_buffer_table = NULL; static GHashTable *__type_table = NULL; static Ecore_Event_Handler *__visibility_listener; static int __delayed_resuming_time; @@ -73,6 +81,37 @@ static void __destroy_type_h(gpointer data) free(type_h); } +static void __cur_buffer_info_ref(cur_buffer_info_h info) +{ + info->ref_count++; +} + +static void __cur_buffer_info_unref(struct tizen_remote_surface *trs, cur_buffer_info_h info) +{ + tbm_surface_h cur_tbm_surface; + + info->ref_count--; + if (info->ref_count == 0) { + tizen_remote_surface_release(trs, info->cur_buffer); + cur_tbm_surface = (tbm_surface_h)wl_buffer_get_user_data(info->cur_buffer); + tbm_surface_internal_unref(cur_tbm_surface); + g_hash_table_remove(__cur_buffer_table, info->cur_buffer); + } +} + +static void __destroy_cur_buffer(gpointer data) +{ + cur_buffer_info_h info = (cur_buffer_info_h)data; + + if (!info) + return; + + if (info->cur_buffer) + wl_buffer_destroy(info->cur_buffer); + + free(info); +} + static void __clear_img_tbm(screen_connector_toolkit_evas_h toolkit_evas_h) { char *plug_id; @@ -130,6 +169,9 @@ EXPORT_API int screen_connector_toolkit_evas_init(Evas_Object *win, screen_conne if (__type_table == NULL) __type_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __destroy_type_h); + if (__cur_buffer_table == NULL) + __cur_buffer_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __destroy_cur_buffer); + type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h == NULL) { @@ -168,6 +210,10 @@ EXPORT_API int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e if (g_hash_table_size(__type_table) == 0) { g_hash_table_destroy(__type_table); __type_table = NULL; + + if (__cur_buffer_table) + g_hash_table_destroy(__cur_buffer_table); + __cur_buffer_table = NULL; } __delayed_resuming_time = 0; @@ -493,7 +539,7 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, char format[] = "png"; char plug_id[256]; screen_connector_toolkit_evas_h toolkit_evas_h; - tbm_surface_h pre_tbm_surface; + cur_buffer_info_h c_buf_info; toolkit_evas_h = (screen_connector_toolkit_evas_h)data; if (toolkit_evas_h->img_tbm == NULL) { @@ -572,15 +618,24 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, evas_object_image_native_surface_set(toolkit_evas_h->img_tbm, NULL); /* set null to previous object for the tbm type */ } - if (toolkit_evas_h->pre_buffer) { + if (toolkit_evas_h->cur_buffer) { if (tizen_remote_surface_get_version(trs) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION) { - tizen_remote_surface_release(trs, toolkit_evas_h->pre_buffer); - pre_tbm_surface = (tbm_surface_h)wl_buffer_get_user_data(toolkit_evas_h->pre_buffer); - tbm_surface_internal_unref(pre_tbm_surface); - wl_buffer_destroy(toolkit_evas_h->pre_buffer); + c_buf_info = g_hash_table_lookup(__cur_buffer_table, toolkit_evas_h->cur_buffer); + if (c_buf_info != NULL) + __cur_buffer_info_unref(trs, c_buf_info); } } - toolkit_evas_h->pre_buffer = tbm; + + toolkit_evas_h->cur_buffer = tbm; + c_buf_info = g_hash_table_lookup(__cur_buffer_table, toolkit_evas_h->cur_buffer); + if (c_buf_info == NULL) { + c_buf_info = (cur_buffer_info_h)calloc(1, sizeof(struct _cur_buffer_info_h)); + c_buf_info->cur_buffer = toolkit_evas_h->cur_buffer; + __cur_buffer_info_ref(c_buf_info); + g_hash_table_insert(__cur_buffer_table, toolkit_evas_h->cur_buffer, c_buf_info); + } else { + __cur_buffer_info_ref(c_buf_info); + } if (is_added) { LOGD("call added !!!! %s, type %d", appid, type); @@ -594,7 +649,6 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, __clear_img_file(toolkit_evas_h); } } else { - LOGD("call updated !!!! %s, type %d", appid, type); if (type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE) { toolkit_evas_h->ops->updated_cb(appid, instance_id, pid, toolkit_evas_h->img_file, toolkit_evas_h->data); @@ -970,7 +1024,9 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_ screen_connector_toolkit_evas_ops *evas_ops; screen_connector_toolkit_ops toolkit_ops; screen_connector_type_evas_h type_h; - char rid_str[32]; + char id_str[70]; + char uuid[37]; + uuid_t u; type_h = g_hash_table_lookup(__type_table, GINT_TO_POINTER(type)); if (type_h == NULL) { @@ -1000,9 +1056,10 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add_by_ handle->data = data; handle->type_h = type_h; - snprintf(rid_str, sizeof(rid_str), "%d", res_id); - handle->toolkit_h = screen_connector_toolkit_create_handle(rid_str, res_id, &toolkit_ops, handle); - screen_connector_toolkit_redirect_surface(handle->toolkit_h); + uuid_generate(u); + uuid_unparse(u, uuid); + snprintf(id_str, sizeof(id_str), "%s:%d", uuid, res_id); + handle->toolkit_h = screen_connector_toolkit_add_by_rid(&toolkit_ops, id_str, type, res_id, handle); return handle; } -- 2.7.4