From 04bced5d05b295b9407d10137e8b514a26f122ff Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Wed, 8 Feb 2017 21:36:51 +0900 Subject: [PATCH 01/16] Fix memory leaks Change-Id: Idb56464495739c44b1735fea75d56a1901718d13 Signed-off-by: Hyunho Kang (cherry picked from commit e262f6dbb8bb12f2a537b620a9e90a0929f833b5) --- screen_connector_watcher_evas/src/screen_connector_watcher_evas.c | 2 ++ 1 file changed, 2 insertions(+) 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 baf1839..00657af 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -514,6 +514,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(evas_ops); return NULL; } handle->img_type = -1; @@ -727,6 +728,7 @@ EXPORT_API int screen_connector_watcher_evas_add_by_rid(screen_connector_watcher 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 -1; } watcher_evas_h->ops = evas_ops; -- 2.7.4 From dab76459986184c379ad76b299f542106d8a7143 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 10 Feb 2017 14:47:53 +0900 Subject: [PATCH 02/16] Add error return logic to watcher_evas_get_pid Sub viewer should not get pid using screen image object. Change-Id: I4f12cb2c1f8f96575a81f1e8a5665ff7f52fba09 Signed-off-by: Hyunho Kang (cherry picked from commit 29c85c12a9d6c42860fe64abf485c5beb67b6cdc) --- .../src/screen_connector_watcher_evas.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 00657af..59cf9a0 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -756,13 +756,21 @@ EXPORT_API int screen_connector_watcher_evas_get_rid(Evas_Object *obj, int *reso 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. not widget object"); return -1; } - *pid = screen_connector_watcher_get_pid(watcher_evas_h->watcher_h); + + watcher_pid = screen_connector_watcher_get_pid(watcher_evas_h->watcher_h); + if (watcher_pid == 0) { + LOGE("Invalid object"); + return -1; + } + + *pid = watcher_pid; return 0; } -- 2.7.4 From ce85a5c603da3f98957853cbe49baee03666f9bb Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 10 Feb 2017 14:18:28 +0900 Subject: [PATCH 03/16] Fix screen_connector_watcher_evas_add_by_rid bug This API was designed for other viewer but implementation was for main viewer Change-Id: I1292fb070d5a1c298e0bc8750ae864ee9407cda5 Signed-off-by: Hyunho Kang (cherry picked from commit 7dcac60b2b98387af463681e012998be9278ef64) --- .../include/screen_connector_watcher.h | 1 + .../src/screen_connector_watcher.c | 9 ++++++ .../include/screen_connector_watcher_evas.h | 30 +++++++++++++++++++- .../src/screen_connector_watcher_evas.c | 33 ++++++++-------------- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/screen_connector_watcher/include/screen_connector_watcher.h b/screen_connector_watcher/include/screen_connector_watcher.h index b1cfed7..223b850 100644 --- a/screen_connector_watcher/include/screen_connector_watcher.h +++ b/screen_connector_watcher/include/screen_connector_watcher.h @@ -44,6 +44,7 @@ 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_set_resource_id(screen_connector_watcher_h h, int rid); 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); diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index fb76e57..dfec938 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -330,6 +330,15 @@ EXPORT_API int screen_connector_watcher_get_resource_id(screen_connector_watcher return h->resource_id; } +EXPORT_API int screen_connector_watcher_set_resource_id(screen_connector_watcher_h h, int rid) +{ + if (h == NULL) + return -1; + + h->resource_id = rid; + return 0; +} + EXPORT_API struct tizen_remote_surface *screen_connector_watcher_get_trs(screen_connector_watcher_h h) { if (h == NULL) 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 117fea5..3e429cb 100644 --- a/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h +++ b/screen_connector_watcher_evas/include/screen_connector_watcher_evas.h @@ -65,8 +65,36 @@ int screen_connector_watcher_evas_freeze_visibility(Evas_Object *obj, visibility 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); -int screen_connector_watcher_evas_add_by_rid(screen_connector_watcher_evas_ops *ops, int res_id, void *data); + +/** + * @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); /** 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 59cf9a0..c44a18b 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -693,14 +693,12 @@ EXPORT_API int screen_connector_watcher_evas_send_touch_cancel(Evas_Object *obj) return 0; } -EXPORT_API int screen_connector_watcher_evas_add_by_rid(screen_connector_watcher_evas_ops *ops, int res_id, void *data) +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) { - GHashTableIter iter; - gpointer key, value; screen_connector_watcher_evas_h watcher_evas_h; - screen_connector_watcher_evas_h cur_h = NULL; screen_connector_watcher_evas_ops *evas_ops; - char *appid = NULL; + char rid_str[32]; int pid = 0; screen_connector_watcher_ops watcher_ops; @@ -708,35 +706,28 @@ EXPORT_API int screen_connector_watcher_evas_add_by_rid(screen_connector_watcher watcher_ops.missing_cb = __watcher_missing_cb; watcher_ops.update_cb = __watcher_update_cb; - g_hash_table_iter_init(&iter, __watcher_tbl); - while (g_hash_table_iter_next(&iter, &key, &value)) { - cur_h = (screen_connector_watcher_evas_h)value; - if (screen_connector_watcher_get_resource_id(cur_h->watcher_h) == res_id) { - appid = screen_connector_watcher_get_appid(cur_h->watcher_h); - pid = screen_connector_watcher_get_pid(cur_h->watcher_h); - break; - } - } - 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 -1; + 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 -1; + 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(appid, pid, &watcher_ops, watcher_evas_h); + 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 0; + return watcher_evas_h; } EXPORT_API int screen_connector_watcher_evas_get_rid(Evas_Object *obj, int *resource_id) @@ -745,7 +736,7 @@ EXPORT_API int screen_connector_watcher_evas_get_rid(Evas_Object *obj, int *reso watcher_evas_h = (screen_connector_watcher_evas_h)g_hash_table_lookup(__watcher_tbl, obj); if (!watcher_evas_h) { - LOGE("unknown object. not widget object"); + LOGE("unknown object."); return -1; } *resource_id = screen_connector_watcher_get_resource_id(watcher_evas_h->watcher_h); @@ -760,7 +751,7 @@ EXPORT_API int screen_connector_watcher_evas_get_pid(Evas_Object *obj, int *pid) watcher_evas_h = (screen_connector_watcher_evas_h)g_hash_table_lookup(__watcher_tbl, obj); if (!watcher_evas_h) { - LOGE("unknown object. not widget object"); + LOGE("unknown object."); return -1; } -- 2.7.4 From e5b1e25b77b630123639d59532267d2727d501a2 Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Fri, 13 Jan 2017 19:22:37 +0900 Subject: [PATCH 04/16] Apply tizen remote surface v4, add event filter - Some remote surface enabled applications are need to ignore some input events. - When provider applications set some input event filter, the value will be passed to the watcher application. In this case, watcher applications should check input event filter before send the input events. Change-Id: Ifd065fd2bc9ee467cdcbd7e30131a5a22ab15254 Signed-off-by: Daehyeon Jung --- .../include/screen_connector_provider.h | 21 +++++++- .../src/screen_connector_provider.c | 58 ++++++++++++++++------ .../include/screen_connector_watcher.h | 16 ++++++ .../src/screen_connector_watcher.c | 31 ++++++++++++ .../src/screen_connector_watcher_evas.c | 24 +++++++++ 5 files changed, 135 insertions(+), 15 deletions(-) diff --git a/screen_connector_provider/include/screen_connector_provider.h b/screen_connector_provider/include/screen_connector_provider.h index 05d20ed..a516a59 100644 --- a/screen_connector_provider/include/screen_connector_provider.h +++ b/screen_connector_provider/include/screen_connector_provider.h @@ -16,12 +16,31 @@ #ifndef __SCREEN_CONNECTOR_PROVIDER_H__ #define __SCREEN_CONNECTOR_PROVIDER_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 struct screen_connector_provider_s *screen_connector_provider_h; int screen_connector_provider_remote_enable(const char *id, struct wl_surface *surface); +screen_connector_provider_h screen_connector_provider_create(const char *id, struct wl_surface *surface); +int screen_connector_provider_set_event_filter(screen_connector_provider_h provider, unsigned int filter); int screen_connector_provider_init(void); int screen_connector_provider_fini(void); diff --git a/screen_connector_provider/src/screen_connector_provider.c b/screen_connector_provider/src/screen_connector_provider.c index 288804b..9213c39 100644 --- a/screen_connector_provider/src/screen_connector_provider.c +++ b/screen_connector_provider/src/screen_connector_provider.c @@ -38,7 +38,7 @@ static int __init_count; static struct tizen_remote_surface_manager *__rsm; -struct __remote_surface_s { +struct screen_connector_provider_s { struct wl_surface *surface; struct tizen_remote_surface_provider *rsp; char *id; @@ -53,7 +53,7 @@ static void __rsp_resource_id_cb(void *data, struct tizen_remote_surface_provide static void __rsp_visibility_cb(void *data, struct tizen_remote_surface_provider *provider, uint32_t visibility) { - struct __remote_surface_s *remote = (struct __remote_surface_s *)data; + struct screen_connector_provider_s *remote = (struct screen_connector_provider_s *)data; Ecore_Wl_Event_Window_Visibility_Change *ev; ev = calloc(1, sizeof(Ecore_Wl_Event_Window_Visibility_Change)); @@ -79,31 +79,31 @@ static const struct tizen_remote_surface_provider_listener __rsp_listener = { __rsp_visibility_cb, }; -EXPORT_API int screen_connector_provider_remote_enable(const char *id, struct wl_surface *surface) +EXPORT_API screen_connector_provider_h screen_connector_provider_create(const char *id, struct wl_surface *surface) { - struct __remote_surface_s *remote; + struct screen_connector_provider_s *remote; struct wl_display *display; if (!__rsm) { LOGE("__rsm is not ready"); - return -1; + return NULL; } if (!surface || !id) { LOGE("invalid parameter"); - return -1; + return NULL; } display = ecore_wl_display_get(); if (!display) { LOGE("Fail to get"); - return -1; + return NULL; } - remote = (struct __remote_surface_s *)malloc(sizeof(struct __remote_surface_s)); + remote = (struct screen_connector_provider_s *)malloc(sizeof(struct screen_connector_provider_s)); if (!remote) { LOGE("out of memory"); - return -1; + return NULL; } remote->surface = surface; @@ -111,27 +111,56 @@ EXPORT_API int screen_connector_provider_remote_enable(const char *id, struct wl if (!remote->win) { LOGE("failed to find win"); free(remote); - return -1; + return NULL; } remote->rsp = tizen_remote_surface_manager_create_provider(__rsm, surface); if (!remote->rsp) { LOGE("failed to create provider"); free(remote); - return -1; + return NULL; } remote->id = strdup(id); if (!remote->id) { free(remote); LOGE("out of memory"); - return -1; + return NULL; } tizen_remote_surface_provider_add_listener(remote->rsp, &__rsp_listener, remote); wl_display_roundtrip(display); - LOGD("%d surface remote enable"); + LOGD("surface remote enabled"); + + return remote; +} + +EXPORT_API int screen_connector_provider_remote_enable(const char *id, struct wl_surface *surface) +{ + screen_connector_provider_h handle; + + handle = screen_connector_provider_create(id, surface); + if (handle) + return 0; + + return -1; +} + +EXPORT_API int screen_connector_provider_set_event_filter(screen_connector_provider_h provider, unsigned int filter) +{ + if (!provider) { + LOGE("invalid arguments"); + return -1; + } + + if (tizen_remote_surface_provider_get_version(provider->rsp) < + TIZEN_REMOTE_SURFACE_PROVIDER_SET_INPUT_EVENT_FILTER_SINCE_VERSION) { + LOGE("unsupported operation"); + return -1; + } + + tizen_remote_surface_provider_set_input_event_filter(provider->rsp, filter); return 0; } @@ -159,7 +188,8 @@ EXPORT_API int screen_connector_provider_init(void) 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, 1); + &tizen_remote_surface_manager_interface, + global->version < 4 ? global->version : 4); } } diff --git a/screen_connector_watcher/include/screen_connector_watcher.h b/screen_connector_watcher/include/screen_connector_watcher.h index 223b850..e9a7d17 100644 --- a/screen_connector_watcher/include/screen_connector_watcher.h +++ b/screen_connector_watcher/include/screen_connector_watcher.h @@ -23,6 +23,20 @@ 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, @@ -45,6 +59,8 @@ 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_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); diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index dfec938..78cf107 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -42,6 +42,7 @@ struct _screen_connector_watcher_h { int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, void *data); void *data; struct tizen_remote_surface *surface; + unsigned int event_filter; int resource_id; }; @@ -80,10 +81,21 @@ static void __buffer_changed(void *data, struct tizen_remote_surface *trs, uint3 watcher_h->change_cb(trs, type, tbm, img_file_fd, img_file_size, time, keys, watcher_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 (watcher_h) + watcher_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, }; static void __app_removed(const char *appid, const int pid, void *data) @@ -346,3 +358,22 @@ EXPORT_API struct tizen_remote_surface *screen_connector_watcher_get_trs(screen_ return h->surface; } + +EXPORT_API unsigned int screen_connector_watcher_get_event_filter(screen_connector_watcher_h h) +{ + if (h == NULL) + return 0; + + return h->event_filter; +} + +EXPORT_API int screen_connector_watcher_check_input_disabled(screen_connector_watcher_h h, + screen_connector_input_type_e input) +{ + if (h == NULL) { + LOGE("inavlid argument"); + return -1; + } + + return ((h->event_filter & input) > 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 c44a18b..b7803f4 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -172,6 +172,12 @@ static void __rs_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *even 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"); + return; + } + surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); tizen_remote_surface_transfer_mouse_event(surface, TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN, @@ -207,6 +213,12 @@ static void __rs_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_ 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); tizen_remote_surface_transfer_mouse_event(surface, TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP, @@ -242,6 +254,12 @@ static void __rs_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *even 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); tizen_remote_surface_transfer_mouse_event(surface, TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE, @@ -271,6 +289,12 @@ static void __rs_cb_mouse_wheel(void *data, Evas *e, Evas_Object *obj, void *eve 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"); + return; + } + surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); tizen_remote_surface_transfer_mouse_wheel(surface, ev->direction, -- 2.7.4 From 1a7a5d000173a1dbefbdfc2b97dd44b4de9a382b Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 17 Feb 2017 15:26:32 +0900 Subject: [PATCH 05/16] Fix screen_connector_watcher_remove API bug Widget app died after screen watcher handle freed, viewer crashed because of freed data. Change-Id: I7aef5e6b6b2dcf09cb2bdd04c7d38d016dedc936 Signed-off-by: Hyunho Kang (cherry picked from commit 53c7ae3a7c9570341c5b22f0b65fa572422eeac4) --- .../src/screen_connector_watcher.c | 13 +++++- .../src/screen_connector_watcher_evas.c | 52 ++++++++++++++++------ 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/screen_connector_watcher/src/screen_connector_watcher.c b/screen_connector_watcher/src/screen_connector_watcher.c index 78cf107..ad29f4e 100644 --- a/screen_connector_watcher/src/screen_connector_watcher.c +++ b/screen_connector_watcher/src/screen_connector_watcher.c @@ -250,8 +250,15 @@ static void __destroy_watcher_h(screen_connector_watcher_h handle) if (!handle) return; - if (handle->appid) + 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); + handle->appid = NULL; + } free(handle); } @@ -308,6 +315,10 @@ EXPORT_API screen_connector_watcher_h screen_connector_watcher_add(screen_connec EXPORT_API int screen_connector_watcher_remove(screen_connector_watcher_h h) { + if (h == NULL) { + LOGE("screen_connector_watcher_h is NULL"); + return -1; + } __destroy_watcher_h(h); 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 b7803f4..5966e2b 100644 --- a/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_watcher_evas.c @@ -50,15 +50,6 @@ static Evas_Object *__viewer_win; static Ecore_Event_Handler *__visibility_listener; static GHashTable *__watcher_tbl; -static void __destroy_watcher_evas_handle(screen_connector_watcher_evas_h h) -{ - if (!h) - return; - free(h->ops); - free(h); - h = NULL; -} - EXPORT_API int screen_connector_watcher_evas_init(Evas_Object *win) { __viewer_win = win; @@ -179,6 +170,11 @@ static void __rs_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *even } 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, @@ -220,6 +216,11 @@ static void __rs_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_ } 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, @@ -261,6 +262,11 @@ static void __rs_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *even } 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, @@ -296,6 +302,11 @@ static void __rs_cb_mouse_wheel(void *data, Evas *e, Evas_Object *obj, void *eve } surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_h); + if (surface == NULL) { + LOGE("surface is NULL"); + return; + } + tizen_remote_surface_transfer_mouse_wheel(surface, ev->direction, ev->z, @@ -483,8 +494,10 @@ static void __free_watcher_evas_h(screen_connector_watcher_evas_h watcher_evas_h watcher_evas_h->img_tbm = NULL; } - if (watcher_evas_h->ops) + if (watcher_evas_h->ops) { free(watcher_evas_h->ops); + watcher_evas_h->ops = NULL; + } free(watcher_evas_h); } @@ -515,6 +528,7 @@ static void __watcher_missing_cb(struct tizen_remote_surface *trs, void *data) 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); } @@ -551,11 +565,11 @@ EXPORT_API screen_connector_watcher_evas_h screen_connector_watcher_evas_add(scr EXPORT_API int screen_connector_watcher_evas_remove(screen_connector_watcher_evas_h handle) { - int ret; + if (handle == NULL) + return -1; - ret = screen_connector_watcher_remove(handle->watcher_h); - __destroy_watcher_evas_handle(handle); - return ret; + __free_watcher_evas_h(handle); + return 0; } EXPORT_API int screen_connector_watcher_evas_update(const char *appid) @@ -674,6 +688,11 @@ EXPORT_API int screen_connector_watcher_evas_send_mouse_up(Evas_Object *obj) } surface = screen_connector_watcher_get_trs(watcher_evas_h->watcher_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, @@ -707,6 +726,11 @@ EXPORT_API int screen_connector_watcher_evas_send_touch_cancel(Evas_Object *obj) 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 { -- 2.7.4 From 7945614beaa50b35324e2d5d515fc5108d6e9901 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 27 Feb 2017 17:29:33 +0900 Subject: [PATCH 06/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 07/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 08/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 09/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 10/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 11/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 12/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 13/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 14/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 15/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 16/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