2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <Ecore_Wayland.h>
22 #include <tizen-remote-surface-client-protocol.h>
23 #include <tbm_surface.h>
25 #include "aul_app_com.h"
27 #include "aul_rsm_provider.h"
28 #include "aul_rsm_viewer.h"
30 struct __remote_surface_s {
31 struct wl_surface *surface;
32 struct tizen_remote_surface_provider *rsp;
40 void (*update_cb)(struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time, void *data);
41 void (*missing_cb)(struct tizen_remote_surface *trs, void *data);
43 struct tizen_remote_surface *surface;
47 static struct tizen_remote_surface_manager *__rsm;
48 static struct wayland_tbm_client *__tbm_client;
49 static struct wl_tbm *__tbm;
50 static int __init_count;
51 static GHashTable *__viewer_tbl;
52 static aul_app_com_connection_h __conn;
56 struct wl_registry *registry;
57 Ecore_Wl_Global *global;
60 if (__init_count > 0) {
66 registry = ecore_wl_registry_get();
67 globals = ecore_wl_globals_get();
69 if (!registry || !globals) {
70 _E("could not get registry(%p) or global list(%p)", registry,
75 EINA_INLIST_FOREACH(globals, global) {
76 if (!strcmp(global->interface, "tizen_remote_surface_manager")) {
77 __rsm = wl_registry_bind(registry, global->id,
78 &tizen_remote_surface_manager_interface, 1);
83 _E("could not get remote surface manager");
98 wayland_tbm_client_deinit(__tbm_client);
101 tizen_remote_surface_manager_destroy(__rsm);
110 API int aul_rsm_provider_init()
117 API int aul_rsm_provider_fini()
124 static void __rsp_resource_id_cb(void *data, struct tizen_remote_surface_provider *provider, uint32_t res_id)
126 struct __remote_surface_s *remote = (struct __remote_surface_s *)data;
127 bundle *envelope = bundle_create();
130 if (envelope == NULL) {
131 _E("failed to create envelope");
135 bundle_add_str(envelope, "__AUL_RSP_RESOURCE_ID__", remote->id);
136 bundle_add_byte(envelope, "__AUL_RSP_SURFACE_ID__", &res_id, sizeof(uint32_t));
137 bundle_add_byte(envelope, "__AUL_RSP_SURFACE_CREATOR_PID__", &pid, sizeof(int));
139 if (aul_app_com_send("tbm_surface_notify", envelope) < 0) {
140 _E("failed to send surface notify");
143 bundle_free(envelope);
146 static void __rsp_visibility_cb(void *data, struct tizen_remote_surface_provider *provider, uint32_t visibility)
148 struct __remote_surface_s *remote = (struct __remote_surface_s *)data;
149 Ecore_Wl_Event_Window_Visibility_Change *ev;
151 ev = calloc(1, sizeof(Ecore_Wl_Event_Window_Visibility_Change));
157 ev->win = ecore_wl_window_id_get(remote->win);
159 if (visibility == TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE)
160 ev->fully_obscured = 0;
162 ev->fully_obscured = 1;
164 _D("visibility changed:%d", visibility);
166 ecore_event_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, ev, NULL, NULL);
169 static const struct tizen_remote_surface_provider_listener __rsp_listener = {
170 __rsp_resource_id_cb,
174 API int aul_rsm_provider_remote_enable(const char *id, struct wl_surface *surface)
176 struct __remote_surface_s *remote;
179 _E("__rsm is not ready");
183 if (!surface || !id) {
184 _E("invalid parameter");
188 remote = (struct __remote_surface_s *)malloc(sizeof(struct __remote_surface_s));
194 remote->surface = surface;
195 remote->win = ecore_wl_window_surface_find(surface);
197 _E("failed to find win");
201 remote->rsp = tizen_remote_surface_manager_create_provider(__rsm, surface);
203 _E("failed to create provider");
207 remote->id = strdup(id);
213 tizen_remote_surface_provider_add_listener(remote->rsp, &__rsp_listener, remote);
215 wl_display_roundtrip(ecore_wl_display_get());
216 _D("%d surface remote enable");
221 static void __rs_buffer_update_cb(void *data, struct tizen_remote_surface *trs,
222 struct wl_buffer *buffer, uint32_t time)
224 struct __surface_s *surface = data;
226 surface->update_cb(trs, buffer, time, surface->data);
229 static void __rs_missing_cb(void *data, struct tizen_remote_surface *trs)
231 struct __surface_s *surface = data;
233 surface->missing_cb(trs, surface->data);
236 static const struct tizen_remote_surface_listener __rs_listener = {
237 __rs_buffer_update_cb,
241 static void __redirect_surface(struct __surface_s *surface)
243 tizen_remote_surface_add_listener(surface->surface, &__rs_listener,
245 tizen_remote_surface_redirect(surface->surface);
248 static int __tbm_handler(const char *endpoint, aul_app_com_result_e e,
249 bundle *envelope, void *user_data)
252 uint32_t *res_id = NULL;
255 struct __surface_s *surface = NULL;
257 bundle_get_str(envelope, "__AUL_RSP_RESOURCE_ID__", &id);
258 bundle_get_byte(envelope, "__AUL_RSP_SURFACE_ID__", (void **)&res_id, &sz);
259 bundle_get_byte(envelope, "__AUL_RSP_SURFACE_CREATOR_PID__", (void **)&pid, &sz);
261 surface = g_hash_table_lookup(__viewer_tbl, id);
263 _E("unknown surface");
269 surface->pid = (int)*pid;
271 surface->resource_id = *res_id;
272 surface->surface = tizen_remote_surface_manager_create_surface(__rsm,
273 (uint32_t)*res_id, __tbm);
275 _D("__tbm_handler %d, %d, %s", *pid, *res_id, id);
278 __redirect_surface(surface);
280 _E("bad tbm message received. missing arguments");
285 API int aul_rsm_viewer_init()
289 __tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get());
291 _E("could not get tbm client");
295 __tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(__tbm_client);
297 _E("could not get tbm");
301 aul_app_com_create("tbm_surface_notify", NULL, __tbm_handler, NULL, &__conn);
303 _E("failed to create app com");
310 API int aul_rsm_viewer_fini()
317 API int aul_rsm_viewer_set_surface_handler(const char *id, aul_rsm_handler *cbs, void *data)
319 struct __surface_s *surface;
322 _E("invalid parameter");
327 __viewer_tbl = g_hash_table_new(g_str_hash, g_str_equal);
329 _E("unable to create hashtable");
334 surface = (struct __surface_s *)malloc(sizeof(struct __surface_s));
340 surface->id = strdup(id);
347 surface->resource_id = -1;
348 surface->data = data;
349 surface->update_cb = cbs->aul_rsm_surface_update_cb;
350 surface->missing_cb = cbs->aul_rsm_surface_missing_cb;
352 g_hash_table_insert(__viewer_tbl, surface->id, surface);
357 API int aul_rsm_viewer_set_surface_handler_by_rid(int resource_id, aul_rsm_handler *cbs, void *data)
360 struct __surface_s *surface;
362 snprintf(buf, sizeof(buf), "%d", resource_id);
363 aul_rsm_viewer_set_surface_handler(buf, cbs, data);
364 surface = g_hash_table_lookup(__viewer_tbl, buf);
365 __redirect_surface(surface);
370 API int aul_rsm_viewer_get_surface_rid(const char *id, int *resource_id)
372 struct __surface_s *surface;
374 if (!id || !resource_id) {
375 _E("illegal arguments");
379 surface = g_hash_table_lookup(__viewer_tbl, id);
381 _E("unknown surface");
385 if (surface->resource_id < 0) {
386 _E("resource id not yet initialized");
390 *resource_id = surface->resource_id;
394 API int aul_rsm_viewer_get_surface_pid(const char *id, int *pid)
396 struct __surface_s *surface;
399 _E("illegal arguments");
403 surface = g_hash_table_lookup(__viewer_tbl, id);
405 _E("unknown surface");
409 if (surface->pid < 1) {
410 _E("resource id not yet initialized");