--- /dev/null
+#include "tc_main.h"
+#include "mockclient.h"
+#include "mockcompositor.h"
+
+#include <vector>
+#include <cstring>
+#include <drm_fourcc.h>
+#include <libds/log.h>
+#include <libds-tizen/video.h>
+#include <tizen-extension-client-protocol.h>
+
+TEST(ScalerSimpleTest, CreateScaler)
+{
+ struct wl_display *display = wl_display_create();
+
+ struct ds_tizen_video *video = ds_tizen_video_create(display);
+ ASSERT_NE(video, nullptr);
+
+ wl_display_destroy(display);
+}
+
+class VideoCompositor : public MockCompositor, public ::testing::Test
+{
+public:
+ VideoCompositor() :
+ MockCompositor(&VideoCompositor::SetUpComp, this)
+ {
+ /* We are only interested in test results. Let's silence libds log. */
+ ds_log_init(DS_SILENT, nullptr);
+
+ this->video = nullptr;
+ }
+
+ static void SetUpComp(void *data)
+ {
+ VideoCompositor *comp = static_cast<VideoCompositor*>(data);
+
+ comp->video = ds_tizen_video_create(comp->GetWlDisplay());
+ ASSERT_NE(comp->video, nullptr);
+ }
+
+ struct ds_tizen_video *video;
+};
+
+static void handle_global(void *data, struct wl_registry *registry,
+ uint32_t name, const char *interface, uint32_t version);
+static void handle_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name);
+
+static const struct wl_registry_listener registry_listener = {
+ .global = handle_global,
+ .global_remove = handle_global_remove,
+};
+
+class MockVideoClient : public MockClient
+{
+public:
+ MockVideoClient() : MockClient(®istry_listener, this)
+ {
+ EXPECT_NE(this->compositor, nullptr);
+ EXPECT_NE(this->video, nullptr);
+
+ surface = wl_compositor_create_surface(this->compositor);
+ EXPECT_NE(this->surface, nullptr);
+ }
+
+ ~MockVideoClient()
+ {
+ wl_surface_destroy(this->surface);
+ tizen_video_destroy(this->video);
+ wl_compositor_destroy(this->compositor);
+ }
+
+ struct wl_compositor *compositor;
+ struct tizen_video *video;
+ struct wl_surface *surface;
+};
+
+static void
+handle_global(void *data, struct wl_registry *registry,
+ uint32_t name, const char *interface, uint32_t version)
+{
+ MockVideoClient *client = static_cast<MockVideoClient*>(data);
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ client->compositor = static_cast<struct wl_compositor*>(
+ wl_registry_bind(registry, name, &wl_compositor_interface, 4));
+ } else if (strcmp(interface, "tizen_video") == 0) {
+ client->video = static_cast<struct tizen_video*>(
+ wl_registry_bind(registry, name, &tizen_video_interface, 1));
+ }
+}
+
+static void
+handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+}
+
+static void
+video_handle_format(void *data, struct tizen_video *video, uint32_t format)
+{
+ std::vector<uint32_t> *ret_formats =
+ static_cast<std::vector<uint32_t>*>(data);
+
+ ret_formats->push_back(format);
+}
+
+static const struct
+tizen_video_listener video_listener = {
+ .format = video_handle_format,
+};
+
+TEST_F(VideoCompositor, AddFormats)
+{
+ std::vector<uint32_t> supported_format {
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888,
+ };
+
+ for (uint32_t format : supported_format)
+ ds_tizen_video_add_format(this->video, format);
+
+ std::vector<uint32_t> ret_formats;
+ MockVideoClient *client = new MockVideoClient();
+ tizen_video_add_listener(client->video, &video_listener,
+ static_cast<void*>(&ret_formats));
+ client->RoundTrip();
+
+ ASSERT_EQ(supported_format.size(), ret_formats.size());
+
+ bool found;
+ for (uint32_t supported_format : supported_format) {
+ found = false;
+ for (uint32_t ret_format : ret_formats) {
+ if (supported_format == ret_format) {
+ found = true;
+ break;
+ }
+ }
+ ASSERT_EQ(found, true);
+ }
+
+ delete client;
+}
+
+TEST_F(VideoCompositor, CreateObject)
+{
+ MockVideoClient *client = new MockVideoClient();
+
+ struct tizen_video_object *object = tizen_video_get_object(client->video,
+ client->surface);
+ client->ExpectNoError();
+
+ tizen_video_object_destroy(object);
+ delete client;
+}
+
+struct size_hint {
+ struct { int32_t width, height; } min;
+ struct { int32_t width, height; } max;
+ int32_t prefer_align;
+};
+
+static void
+video_object_handle_size(void *data, struct tizen_video_object *object,
+ int32_t min_w, int32_t min_h, int32_t max_w, int32_t max_h,
+ int32_t prefer_align)
+{
+ size_hint *ret_size = static_cast<size_hint*>(data);
+ ret_size->min.width = min_w;
+ ret_size->min.height = min_h;
+ ret_size->max.width = max_w;
+ ret_size->max.height = max_h;
+ ret_size->prefer_align = prefer_align;
+}
+
+static const struct
+tizen_video_object_listener object_size_hint_listener = {
+ .attribute = NULL,
+ .size = video_object_handle_size,
+};
+
+TEST_F(VideoCompositor, SetSizeHint)
+{
+ size_hint hint = { 100, 50, 1000, 500, 777 };
+
+ ds_tizen_video_set_size_hint(this->video,
+ hint.min.width, hint.min.height,
+ hint.max.width, hint.max.height,
+ hint.prefer_align);
+
+ MockVideoClient *client = new MockVideoClient();
+
+ struct tizen_video_object *object =
+ tizen_video_get_object(client->video, client->surface);
+
+ size_hint ret_hint;
+ tizen_video_object_add_listener(object, &object_size_hint_listener,
+ static_cast<void*>(&ret_hint));
+ client->RoundTrip();
+
+ ASSERT_EQ(hint.min.width, ret_hint.min.width);
+ ASSERT_EQ(hint.min.height, ret_hint.min.height);
+ ASSERT_EQ(hint.max.width, ret_hint.max.width);
+ ASSERT_EQ(hint.max.height, ret_hint.max.height);
+ ASSERT_EQ(hint.prefer_align, ret_hint.prefer_align);
+
+ tizen_video_object_destroy(object);
+ delete client;
+}
+
+struct property {
+ std::string name;
+ uint32_t value;
+
+ property(std::string name, uint32_t value) : name(name), value(value) {}
+};
+
+static void
+video_object_handle_attribute(void *data, struct tizen_video_object *object,
+ const char *name, uint32_t value)
+{
+ std::vector<property*> *ret_properties =
+ static_cast<std::vector<property*>*>(data);
+
+ ret_properties->push_back(new property(std::string(name), value));
+}
+
+static void
+video_object_dummy_handle_size(void *data, struct tizen_video_object *object,
+ int32_t min_w, int32_t min_h, int32_t max_w, int32_t max_h,
+ int32_t prefer_align)
+{
+ // This left blank intentionally.
+}
+
+static const struct
+tizen_video_object_listener object_attribute_listener = {
+ .attribute = video_object_handle_attribute,
+ .size = video_object_dummy_handle_size,
+};
+
+TEST_F(VideoCompositor, AddProperties)
+{
+ std::vector<property> properties {
+ { "property0", 123 },
+ { "property1", 987 },
+ { "property2", 345 },
+ { "property3", 777 },
+ };
+
+ for (struct property prop : properties)
+ ds_tizen_video_add_property(this->video, prop.name.c_str(), prop.value);
+
+ MockVideoClient *client = new MockVideoClient();
+
+ struct tizen_video_object *object =
+ tizen_video_get_object(client->video, client->surface);
+
+ std::vector<property*> ret_properties;
+ tizen_video_object_add_listener(object, &object_attribute_listener,
+ static_cast<void*>(&ret_properties));
+ client->RoundTrip();
+
+ ASSERT_EQ(properties.size(), ret_properties.size());
+
+ bool found;
+ for (property prop : properties) {
+ found = false;
+ for (property *ret_prop : ret_properties) {
+ if (prop.name == ret_prop->name &&
+ prop.value == ret_prop->value) {
+ found = true;
+ break;
+ }
+ }
+ ASSERT_EQ(found, true);
+ }
+
+ for (property *prop : ret_properties)
+ delete prop;
+ ret_properties.clear();
+ tizen_video_object_destroy(object);
+ delete client;
+}