Fix to set display overlay. 26/61826/2
authorSangkyu Park <sk1122.park@samsung.com>
Fri, 11 Mar 2016 01:21:04 +0000 (10:21 +0900)
committerSangkyu Park <sk1122.park@samsung.com>
Fri, 11 Mar 2016 07:48:27 +0000 (16:48 +0900)
- elm_win_xwindow_get API is deprecated on 3.0.

Change-Id: Iee7f0e45ec5097009e7af268a8b72fdcd00231ec
Signed-off-by: Sangkyu Park <sk1122.park@samsung.com>
packaging/libmm-wfd.spec
sink/Makefile.am
sink/include/mm_wfd_sink_wayland.h [new file with mode: 0755]
sink/mm_wfd_sink_priv.c
sink/mm_wfd_sink_wayland.c [new file with mode: 0755]

index 3b222de..f7ed680 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       libmm-wfd
 Summary:    Multimedia Framework Wifi-Display Library
-Version:    0.2.193
+Version:    0.2.194
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
@@ -17,6 +17,8 @@ BuildRequires: pkgconfig(capi-network-wifi-direct)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(evas)
+BuildRequires: pkgconfig(ecore-wayland)
+BuildRequires: pkgconfig(libtbm)
 
 BuildRoot:  %{_tmppath}/%{name}-%{version}-build
 
index d652c28..ffe263e 100755 (executable)
@@ -7,7 +7,8 @@ includelibmmfwfdsink_HEADERS = include/mm_wfd_sink.h
 libmmfwfdsink_la_SOURCES = mm_wfd_sink_util.c \
                                mm_wfd_sink.c \
                                mm_wfd_sink_manager.c \
-                               mm_wfd_sink_priv.c
+                               mm_wfd_sink_priv.c \
+                               mm_wfd_sink_wayland.c
 
 
 libmmfwfdsink_la_CFLAGS =  -I$(srcdir)/include \
@@ -26,7 +27,8 @@ libmmfwfdsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 noinst_HEADERS = include/mm_wfd_sink_priv.h \
                        include/mm_wfd_sink_util.h \
-                       include/mm_wfd_sink_manager.h
+                       include/mm_wfd_sink_manager.h \
+                       include/mm_wfd_sink_wayland.h
 
 libmmfwfdsink_la_LIBADD = $(GST_LIBS) \
                        $(GST_PLUGINS_BASE_LIBS) \
diff --git a/sink/include/mm_wfd_sink_wayland.h b/sink/include/mm_wfd_sink_wayland.h
new file mode 100755 (executable)
index 0000000..d3e6da6
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2011 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 __MM_WFD_SINK_WLCLIENT_H__
+#define __MM_WFD_SINK_WLCLIENT_H__
+#include <stdio.h>
+#include <tbm_bufmgr.h>
+#include <tizen-extension-client-protocol.h>
+#include <wayland-client.h>
+#include <mm_types.h>
+#include <mm_debug.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct
+{
+       struct wl_display *display;
+       struct wl_registry *registry;
+       struct tizen_surface *tz_surface;
+       struct tizen_resource *tz_resource;
+} wl_client;
+
+int mm_wfd_sink_wlclient_create (wl_client ** wlclient);
+int mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wl_client * wlclient, struct wl_surface *surface, struct wl_display *display);
+void mm_wfd_sink_wlclient_finalize (wl_client * wlclient);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                          /* __MM_WFD_SINK_WLCLIENT_H__ */
index 1e60abc..1363a31 100755 (executable)
@@ -29,6 +29,7 @@
 #include "mm_wfd_sink_manager.h"
 #include "mm_wfd_sink_dlog.h"
 #include "mm_wfd_sink_wfd_enum.h"
+#include "mm_wfd_sink_wayland.h"
 
 
 /* gstreamer */
@@ -2962,27 +2963,66 @@ static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *
                        break;
 
                case MM_DISPLAY_SURFACE_OVERLAY: {
-                               void *object = NULL;
+                               int wl_window_x = 0;
+                               int wl_window_y = 0;
+                               int wl_window_width = 0;
+                               int wl_window_height = 0;
+                               unsigned int wl_surface_id = 0;
+                               struct wl_surface *wl_surface = NULL;
+                               struct wl_display *wl_display = NULL;
+                               Ecore_Wl_Window *wl_window = NULL;
+                               wl_client *wlclient = NULL;
                                Evas_Object *obj = NULL;
+                               void *object = NULL;
                                const char *object_type = NULL;
-                               unsigned int g_xwin = 0;
+                               int ret = 0;
 
-                               /* x surface */
                                mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
 
                                if (object != NULL) {
                                        obj = (Evas_Object *)object;
                                        object_type = evas_object_type_get(obj);
-
                                        wfd_sink_debug("window object type : %s", object_type);
 
-                                       if (!strcmp(object_type, "elm_win"))
-                                               g_xwin = elm_win_xwindow_get(obj);
+                                       /* wayland overlay surface */
+                                       LOGI("Wayland overlay surface type");
+                                       evas_object_geometry_get(obj, &wl_window_x, &wl_window_y, &wl_window_width, &wl_window_height);
+
+                                       wfd_sink_debug ("x[%d] y[%d] width[%d] height[%d]", wl_window_x, wl_window_y,
+                                               wl_window_width, wl_window_height);
+
+                                       wl_window = elm_win_wl_window_get(obj);
+                                       wl_surface = (struct wl_surface *) ecore_wl_window_surface_get(wl_window);
+
+                                       /* get wl_display */
+                                       wl_display = (struct wl_display *) ecore_wl_display_get();
+
+                                       ret = mm_wfd_sink_wlclient_create(&wlclient);
+                                       if ( ret != MM_ERROR_NONE) {
+                                               wfd_sink_error("Wayland client create failure");
+                                               return ret;
                                }
 
-                               wfd_sink_debug("xid = %lu", g_xwin);
-                               gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink), g_xwin);
+                                       if (wl_surface && wl_display){
+                                               wfd_sink_debug ("surface = %p, wl_display = %p", wl_surface, wl_display);
+                                               wl_surface_id = mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wlclient, wl_surface, wl_display);
+                                               wfd_sink_debug ("wl_surface_id = %d", wl_surface_id);
+                                       }
+                                       if (wlclient) {
+                                               g_free(wlclient);
+                                               wlclient = NULL;
+                                       }
 
+                                       wfd_sink_debug("set video param : surface_id %d", wl_surface_id);
+                                       gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink),
+                                               wl_surface_id);
+                                       /* After setting window handle, set render rectangle */
+                                       gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(video_sink),
+                                               wl_window_x, wl_window_y, wl_window_width, wl_window_height);
+                               } else {
+                                       wfd_sink_debug ("display object is NULL!");
+                                       return MM_ERROR_WFD_INTERNAL;
+                               }
                        }
                        break;
 
diff --git a/sink/mm_wfd_sink_wayland.c b/sink/mm_wfd_sink_wayland.c
new file mode 100755 (executable)
index 0000000..787dea8
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+* Copyright (c) 2011 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 <string.h>
+#include <mm_error.h>
+#include <wayland-client.h>
+#include <tizen-extension-client-protocol.h>
+
+#include "mm_wfd_sink_dlog.h"
+#include "mm_wfd_sink_wayland.h"
+
+#define goto_if_fail(expr,label)       \
+{      \
+       if (!(expr)) {  \
+               wfd_sink_error(" failed [%s]\n", #expr);        \
+               goto label;     \
+       }       \
+}
+
+void mm_wfd_sink_handle_resource_id(void *data, struct tizen_resource *tizen_resource, uint32_t id)
+{
+       unsigned int *wl_surface_id = data;
+
+       *wl_surface_id = id;
+
+       wfd_sink_debug("[CLIENT] got wl_surface_id(%d) from server\n", id);
+}
+
+static const struct tizen_resource_listener tz_resource_listener =
+{
+       mm_wfd_sink_handle_resource_id,
+};
+
+static void
+mm_wfd_sink_handle_global(void *data, struct wl_registry *registry,
+              uint32_t name, const char *interface, uint32_t version)
+{
+       return_if_fail (data != NULL);
+       wl_client *wlclient = data;
+
+       if (strcmp(interface, "tizen_surface") == 0)
+       {
+               wfd_sink_debug("binding tizen_surface");
+               wlclient->tz_surface = wl_registry_bind(registry, name, &tizen_surface_interface, version);
+               return_if_fail (wlclient->tz_surface != NULL);
+       }
+}
+
+static void mm_wfd_sink_handle_global_remove(void* data, struct wl_registry* registry, uint32_t name)
+{
+       wfd_sink_debug("wl_registry_handle_global_remove");
+}
+
+static const struct wl_registry_listener registry_listener =
+{
+       mm_wfd_sink_handle_global,
+       mm_wfd_sink_handle_global_remove
+};
+
+int mm_wfd_sink_wlclient_create (wl_client ** wlclient)
+{
+       wl_client *ptr = NULL;
+
+       ptr = g_malloc0 (sizeof (wl_client));
+       if (!ptr) {
+               wfd_sink_error ("Cannot allocate memory for wlclient\n");
+               goto ERROR;
+       } else {
+               *wlclient = ptr;
+               wfd_sink_debug ("Success create wlclient(%p)", *wlclient);
+       }
+       return MM_ERROR_NONE;
+
+ERROR:
+       *wlclient = NULL;
+       return MM_ERROR_WFD_NO_FREE_SPACE;
+}
+
+
+int mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wl_client * wlclient, struct wl_surface *surface, struct wl_display *display)
+{
+       goto_if_fail (wlclient != NULL, failed);
+       goto_if_fail (surface != NULL, failed);
+       goto_if_fail (display != NULL, failed);
+
+       unsigned int wl_surface_id = 0;
+
+       wlclient->display = display;
+       goto_if_fail (wlclient->display != NULL, failed);
+
+       wlclient->registry = wl_display_get_registry(wlclient->display);
+       goto_if_fail (wlclient->registry != NULL, failed);
+
+       wl_registry_add_listener(wlclient->registry, &registry_listener, wlclient);
+       wl_display_dispatch(wlclient->display);
+       wl_display_roundtrip(wlclient->display);
+
+       /* check global objects */
+       goto_if_fail (wlclient->tz_surface != NULL, failed);
+
+       /* Get wl_surface_id which is unique in a entire systemw. */
+       wlclient->tz_resource = tizen_surface_get_tizen_resource(wlclient->tz_surface, surface);
+       goto_if_fail (wlclient->tz_resource != NULL, failed);
+
+       tizen_resource_add_listener(wlclient->tz_resource, &tz_resource_listener, &wl_surface_id);
+       wl_display_roundtrip(wlclient->display);
+       goto_if_fail (wl_surface_id > 0, failed);
+
+       mm_wfd_sink_wlclient_finalize(wlclient);
+
+       return wl_surface_id;
+
+failed:
+       wfd_sink_error ("Failed to get wl_surface_id");
+
+       return 0;
+}
+
+void mm_wfd_sink_wlclient_finalize (wl_client * wlclient)
+{
+       wfd_sink_debug ("start finalize wlclient");
+       return_if_fail (wlclient != NULL)
+
+       if (wlclient->tz_surface)
+               tizen_surface_destroy(wlclient->tz_surface);
+
+       if (wlclient->tz_resource)
+               tizen_resource_destroy(wlclient->tz_resource);
+
+    /* destroy registry */
+       if (wlclient->registry)
+               wl_registry_destroy(wlclient->registry);
+       return;
+}