--- /dev/null
+/*
+ * 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.
+ */
+
+
+#include <glib.h>
+#include <bundle.h>
+#include <Ecore_Wayland.h>
+#include <tizen-remote-surface-client-protocol.h>
+#include <tbm_surface.h>
+#include "aul_util.h"
+#include "aul_app_com.h"
+#include "aul_api.h"
+#include "aul_rsm_provider.h"
+#include "aul_rsm_viewer.h"
+
+struct __remote_surface_s {
+ struct wl_surface *surface;
+ struct tizen_remote_surface_provider *rsp;
+ char *id;
+};
+
+struct __surface_s {
+ char *id;
+ 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 *data;
+ struct tizen_remote_surface *surface;
+};
+
+static struct tizen_remote_surface_manager *__rsm;
+static struct wayland_tbm_client *__tbm_client;
+static struct wl_tbm *__tbm;
+static int __init_count;
+static GHashTable *__viewer_tbl;
+static aul_app_com_connection_h __conn;
+
+int aul_rsm_init()
+{
+ struct wl_registry *registry;
+ Ecore_Wl_Global *global;
+ Eina_Inlist *globals;
+
+ if (__init_count > 0) {
+ return 0;
+ }
+
+ ecore_wl_init(NULL);
+
+ registry = ecore_wl_registry_get();
+ globals = ecore_wl_globals_get();
+
+ if (!registry || !globals) {
+ _E("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, 1);
+ }
+ }
+
+ if (!__rsm) {
+ _E("could not get remote surface manager");
+ return -1;
+ }
+
+ __init_count++;
+ return 0;
+}
+
+
+int aul_rsm_fini()
+{
+ if (__init_count > 1)
+ return 0;
+
+ if (__tbm_client)
+ wayland_tbm_client_deinit(__tbm_client);
+
+ if (__rsm)
+ tizen_remote_surface_manager_destroy(__rsm);
+
+ ecore_wl_shutdown();
+
+ __init_count--;
+
+ return 0;
+}
+
+API int aul_rsm_provider_init()
+{
+ aul_rsm_init();
+
+ return 0;
+}
+
+API int aul_rsm_provider_fini()
+{
+ aul_rsm_fini();
+
+ return 0;
+}
+
+static void __rsp_resource_id_cb(void *data, struct tizen_remote_surface_provider *provider, uint32_t res_id)
+{
+ struct __remote_surface_s *remote = (struct __remote_surface_s *)data;
+ bundle *envelope = bundle_create();
+
+ if (envelope == NULL) {
+ _E("failed to create envelope");
+ return;
+ }
+
+ bundle_add_str(envelope, "__AUL_RSP_RESOURCE_ID__", remote->id);
+ bundle_add_byte(envelope, "__AUL_RSP_SURFACE_ID__", &res_id, sizeof(uint32_t));
+
+ if (aul_app_com_send("tbm_surface_notify", envelope) < 0) {
+ _E("failed to send surface notify");
+ }
+
+ bundle_free(envelope);
+}
+
+static void __rsp_visibility_cb(void *data, struct tizen_remote_surface_provider *provider, uint32_t visibility)
+{
+ _D("visibility changed:%d", visibility);
+}
+
+static const struct tizen_remote_surface_provider_listener __rsp_listener = {
+ __rsp_resource_id_cb,
+ __rsp_visibility_cb,
+};
+
+API int aul_rsm_provider_remote_enable(const char *id, struct wl_surface *surface)
+{
+ struct __remote_surface_s *remote;
+
+ if (!__rsm) {
+ _E("__rsm is not ready");
+ return -1;
+ }
+
+ if (!surface || !id) {
+ _E("invalid parameter");
+ return -1;
+ }
+
+ remote = (struct __remote_surface_s *)malloc(sizeof(struct __remote_surface_s));
+ if (!remote) {
+ _E("out of memory");
+ return -1;
+ }
+
+ remote->rsp = tizen_remote_surface_manager_create_provider(__rsm, surface);
+ if (!remote->rsp) {
+ _E("failed to create provider");
+ return -1;
+ }
+
+ remote->id = strdup(id);
+ if (!remote->id) {
+ _E("out of memory");
+ return -1;
+ }
+
+ tizen_remote_surface_provider_add_listener(remote->rsp, &__rsp_listener, remote);
+
+ wl_display_roundtrip(ecore_wl_display_get());
+ _D("%d surface remote enable");
+
+ return 0;
+}
+
+static void __rs_buffer_update_cb(void *data, struct tizen_remote_surface *trs,
+ struct wl_buffer *buffer, uint32_t time)
+{
+ struct __surface_s *surface = data;
+ if (surface)
+ surface->update_cb(trs, buffer, time, surface->data);
+}
+
+static void __rs_missing_cb(void *data, struct tizen_remote_surface *trs)
+{
+ struct __surface_s *surface = data;
+ if (surface)
+ surface->missing_cb(trs, surface->data);
+}
+
+static const struct tizen_remote_surface_listener __rs_listener = {
+ __rs_buffer_update_cb,
+ __rs_missing_cb,
+};
+
+static int __tbm_handler(const char *endpoint, aul_app_com_result_e e,
+ bundle *envelope, void *user_data)
+{
+ char *id = NULL;
+ uint32_t *res_id = NULL;
+ size_t sz;
+ struct __surface_s *surface = NULL;
+
+ bundle_get_str(envelope, "__AUL_RSP_RESOURCE_ID__", &id);
+ bundle_get_byte(envelope, "__AUL_RSP_SURFACE_ID__", (void **)&res_id, &sz);
+
+ if (id && res_id) {
+ surface = g_hash_table_lookup(__viewer_tbl, id);
+ if (!surface) {
+ _E("unknown surface");
+ return 0;
+ }
+ }
+
+ surface->surface = tizen_remote_surface_manager_create_surface(__rsm, *res_id, __tbm);
+ tizen_remote_surface_add_listener(surface->surface, &__rs_listener, surface);
+ tizen_remote_surface_redirect(surface->surface);
+
+ return 0;
+}
+
+API int aul_rsm_viewer_init()
+{
+ aul_rsm_init();
+
+ __tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get());
+ if (!__tbm_client) {
+ _E("could not get tbm client");
+ return -1;
+ }
+
+ __tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(__tbm_client);
+ if (!__tbm) {
+ _E("could not get tbm");
+ return -1;
+ }
+
+ aul_app_com_create("tbm_surface_notify", NULL, __tbm_handler, NULL, &__conn);
+ if (!__conn) {
+ _E("failed to create app com");
+ return -1;
+ }
+
+ return 0;
+}
+
+API int aul_rsm_viewer_fini()
+{
+ aul_rsm_fini();
+
+ return 0;
+}
+
+API int aul_rsm_viewer_set_surface_handler(const char *id, aul_rsm_handler *cbs, void *data)
+{
+ struct __surface_s *surface;
+
+ if (!id || !cbs) {
+ _E("invalid parameter");
+ return -1;
+ }
+
+ if (!__viewer_tbl) {
+ __viewer_tbl = g_hash_table_new(g_str_hash, g_str_equal);
+ if (!__viewer_tbl) {
+ _E("unable to create hashtable");
+ return -1;
+ }
+ }
+
+ surface = (struct __surface_s *)malloc(sizeof(struct __surface_s));
+ if (!surface) {
+ _E("out of memory");
+ return -1;
+ }
+
+ surface->id = strdup(id);
+ if (!surface->id) {
+ _E("out of memory");
+ free(surface);
+ return -1;
+ }
+
+ surface->data = data;
+ surface->update_cb = cbs->aul_rsm_surface_update_cb;
+ surface->missing_cb = cbs->aul_rsm_surface_missing_cb;
+
+ g_hash_table_insert(__viewer_tbl, surface->id, surface);
+
+ return 0;
+}