video: Add ds_tizen_video_object 53/283253/1
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 15 Sep 2022 06:15:18 +0000 (15:15 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Fri, 21 Oct 2022 02:27:55 +0000 (11:27 +0900)
The ds_tizen_video_object is to support for tizen_video_object extension
protocol, and it is generated from ds_tizen_video emitting new_object
signal.

Change-Id: I2b11b3795de1dbe9dd64ce57cd84c89f7626e7c7

include/libds-tizen/video.h
src/video/meson.build
src/video/video.c

index 4e7943a..0cbf5d7 100644 (file)
@@ -2,6 +2,7 @@
 #define LIBDS_TIZEN_VIDEO_H
 
 #include <wayland-server.h>
+#include <libds/surface.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -9,13 +10,53 @@ extern "C" {
 
 struct ds_tizen_video;
 
+struct ds_tizen_video_object;
+
+struct ds_event_tizen_video_request_set_property {
+    struct ds_tizen_video_object *object;
+    const char *name;
+    int32_t value;
+};
+
 struct ds_tizen_video *ds_tizen_video_create(struct wl_display *display);
 
 void ds_tizen_video_add_format(struct ds_tizen_video *video, uint32_t format);
 
+void ds_tizen_video_add_property(struct ds_tizen_video *video,
+        const char *name, int32_t value);
+
+void ds_tizen_video_set_size_hint(struct ds_tizen_video *video,
+        int32_t min_width, int32_t min_height,
+        int32_t max_width, int32_t max_height, int32_t prefer_align);
+
 void ds_tizen_video_add_destroy_listener(struct ds_tizen_video *video,
         struct wl_listener *listener);
 
+void ds_tizen_video_add_new_object_listener(struct ds_tizen_video *video,
+        struct wl_listener *listener);
+
+struct ds_surface *ds_tizen_video_object_get_surface(
+        struct ds_tizen_video_object *object);
+
+void ds_tizen_video_object_add_destroy_listener(
+        struct ds_tizen_video_object *object, struct wl_listener *listener);
+
+/* @data: struct ds_event_tizen_video_request_set_property */
+void ds_tizen_video_object_add_request_set_property_listener(
+        struct ds_tizen_video_object *object, struct wl_listener *listener);
+
+void ds_tizen_video_object_add_request_follow_topmost_visibility_listener(
+        struct ds_tizen_video_object *object, struct wl_listener *listener);
+
+void ds_tizen_video_object_add_request_unfollow_topmost_visibility_listener(
+        struct ds_tizen_video_object *object, struct wl_listener *listener);
+
+void ds_tizen_video_object_add_request_attribute_allowed_listener(
+        struct ds_tizen_video_object *object, struct wl_listener *listener);
+
+void ds_tizen_video_object_add_request_attribute_disallowed_listener(
+        struct ds_tizen_video_object *object, struct wl_listener *listener);
+
 #ifdef __cplusplus
 }
 #endif
index 00aaea0..e091554 100644 (file)
@@ -5,6 +5,7 @@ libds_tizen_video_files = [
 libds_tizen_video_deps = [
   dep_libshared,
   deps_libds_tizen,
+  dependency('libtdm', required: true),
   dependency('tizen-extension-server', required: true),
 ]
 
index b4f2796..db8bd26 100644 (file)
@@ -1,9 +1,15 @@
 #include <stdlib.h>
+#include <string.h>
+
+#include <tdm_types.h>
 #include <tbm_type.h>
 #include <wayland-server.h>
 #include <tizen-extension-server-protocol.h>
+
 #include <libds/log.h>
+#include <libds/surface.h>
 
+#include "libds-tizen/video.h"
 #include "shared/pixel_format.h"
 
 #define TIZEN_VIDEO_VERSION 1
@@ -12,23 +18,65 @@ struct ds_tizen_video
 {
     struct wl_global *global;
     struct wl_list resources;
+    struct wl_list objects;
+
     struct wl_array formats;
+    struct wl_array properties;
 
     struct wl_listener display_destroy;
 
+    int32_t min_width, min_height;
+    int32_t max_width, max_height;
+    int32_t prefer_align;
+
+    struct {
+        struct wl_signal destroy;
+        struct wl_signal new_object;
+    } events;
+};
+
+struct ds_tizen_video_object
+{
+    struct wl_resource *resource;
+    struct ds_surface *surface;
+
+    struct wl_list link; // ds_tizen_video::objects
+
+    struct wl_listener surface_destroy;
+
     struct {
         struct wl_signal destroy;
+        struct wl_signal request_set_property;
+        struct wl_signal request_follow_topmost_visibility;
+        struct wl_signal request_unfollow_topmost_visibility;
+        struct wl_signal request_attribute_allowed;
+        struct wl_signal request_attribute_disallowed;
     } events;
 };
 
+struct video_property
+{
+    char name[TDM_NAME_LEN];
+    int32_t value;
+};
+
 static void video_handle_display_destroy(struct wl_listener *listener,
         void *data);
 static void video_bind(struct wl_client *client, void *data, uint32_t version,
         uint32_t id);
 static void video_send_format(struct ds_tizen_video *video,
         tbm_format format);
+static void video_send_size(struct ds_tizen_video *video);
+static void video_send_property(struct ds_tizen_video *video,
+        struct video_property *prop);
+static struct video_property *video_get_property(struct ds_tizen_video *video,
+        const char *name);
 static void video_resource_send_formats(struct wl_resource *resource,
         struct wl_array *formats);
+static struct ds_tizen_video_object *
+create_video_object(struct wl_client *client, uint32_t id, int version,
+        struct wl_resource *surface_resource);
+static void video_object_destroy(struct ds_tizen_video_object *object);
 
 WL_EXPORT struct ds_tizen_video *
 ds_tizen_video_create(struct wl_display *display)
@@ -48,9 +96,13 @@ ds_tizen_video_create(struct wl_display *display)
     }
 
     wl_list_init(&video->resources);
+    wl_list_init(&video->objects);
+
     wl_array_init(&video->formats);
+    wl_array_init(&video->properties);
 
     wl_signal_init(&video->events.destroy);
+    wl_signal_init(&video->events.new_object);
 
     video->display_destroy.notify = video_handle_display_destroy;
     wl_display_add_destroy_listener(display, &video->display_destroy);
@@ -77,12 +129,115 @@ ds_tizen_video_add_format(struct ds_tizen_video *video, uint32_t format)
 }
 
 WL_EXPORT void
+ds_tizen_video_set_size_hint(struct ds_tizen_video *video,
+        int32_t min_width, int32_t min_height,
+        int32_t max_width, int32_t max_height, int32_t prefer_align)
+{
+    if (video->min_width == min_width && video->min_height == min_height &&
+            video->max_width == max_width && video->max_height == max_height &&
+            video->prefer_align == prefer_align)
+        return;
+
+    video->min_width = min_width;
+    video->min_height = min_height;
+    video->max_width = max_width;
+    video->max_height = max_height;
+    video->prefer_align = prefer_align;
+
+    video_send_size(video);
+}
+
+WL_EXPORT void
+ds_tizen_video_add_property(struct ds_tizen_video *video, const char *name,
+        int32_t value)
+{
+    struct video_property *prop;
+
+    prop = video_get_property(video, name);
+    if (!prop) {
+        prop = wl_array_add(&video->properties, sizeof *prop);
+        if (!prop) {
+            ds_err("Failed wl_array_add()");
+            return;
+        }
+
+        memset(prop, 0, sizeof(*prop));
+        strncpy(prop->name, name, sizeof(prop->name) - 1);
+    }
+    prop->value = value;
+
+    video_send_property(video, prop);
+}
+
+WL_EXPORT void
 ds_tizen_video_add_destroy_listener(struct ds_tizen_video *video,
         struct wl_listener *listener)
 {
     wl_signal_add(&video->events.destroy, listener);
 }
 
+WL_EXPORT void
+ds_tizen_video_add_new_object_listener(struct ds_tizen_video *video,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&video->events.new_object, listener);
+}
+
+WL_EXPORT struct ds_surface *
+ds_tizen_video_object_get_surface(struct ds_tizen_video_object *object)
+{
+    return object->surface;
+}
+
+WL_EXPORT void
+ds_tizen_video_object_add_destroy_listener(
+        struct ds_tizen_video_object *object,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&object->events.destroy, listener);
+}
+
+WL_EXPORT void
+ds_tizen_video_object_add_request_set_property_listener(
+        struct ds_tizen_video_object *object,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&object->events.request_set_property, listener);
+}
+
+WL_EXPORT void
+ds_tizen_video_object_add_request_follow_topmost_visibility_listener(
+        struct ds_tizen_video_object *object,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&object->events.request_follow_topmost_visibility, listener);
+}
+
+WL_EXPORT void
+ds_tizen_video_object_add_request_unfollow_topmost_visibility_listener(
+        struct ds_tizen_video_object *object,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&object->events.request_unfollow_topmost_visibility,
+            listener);
+}
+
+WL_EXPORT void
+ds_tizen_video_object_add_request_attribute_allowed_listener(
+        struct ds_tizen_video_object *object,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&object->events.request_attribute_allowed, listener);
+}
+
+WL_EXPORT void
+ds_tizen_video_object_add_request_attribute_disallowed_listener(
+        struct ds_tizen_video_object *object,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&object->events.request_attribute_disallowed, listener);
+}
+
 static void
 video_handle_display_destroy(struct wl_listener *listener, void *data)
 {
@@ -95,6 +250,7 @@ video_handle_display_destroy(struct wl_listener *listener, void *data)
     wl_signal_emit(&video->events.destroy, video);
 
     wl_array_release(&video->formats);
+    wl_array_release(&video->properties);
 
     wl_list_remove(&video->display_destroy.link);
     wl_global_destroy(video->global);
@@ -105,7 +261,32 @@ static void
 video_handle_get_object(struct wl_client *client, struct wl_resource *resource,
         uint32_t id, struct wl_resource *surface_resource)
 {
+    struct ds_tizen_video *video;
+    struct ds_tizen_video_object *object;
+    struct video_property *prop;
+    int version;
+
+    video = wl_resource_get_user_data(resource);
+
+    version = wl_resource_get_version(resource);
+    object = create_video_object(client, id, version, surface_resource);
+    if (!object) {
+        wl_resource_post_no_memory(resource);
+        return;
+    }
+
+    wl_list_insert(&video->objects, &object->link);
 
+    tizen_video_object_send_size(object->resource,
+            video->min_width, video->min_height,
+            video->max_width, video->max_height, video->prefer_align);
+
+    wl_array_for_each(prop, &video->properties) {
+        tizen_video_object_send_attribute(object->resource,
+                prop->name, prop->value);
+    }
+
+    wl_signal_emit(&video->events.new_object, object);
 }
 
 static void
@@ -113,7 +294,7 @@ video_handle_get_viewport(struct wl_client *client,
         struct wl_resource *resource, uint32_t id,
         struct wl_resource *surface_resource)
 {
-
+    // TODO
 }
 
 static void
@@ -163,6 +344,42 @@ video_send_format(struct ds_tizen_video *video, tbm_format format)
 }
 
 static void
+video_send_size(struct ds_tizen_video *video)
+{
+    struct ds_tizen_video_object *object;
+
+    wl_list_for_each(object, &video->objects, link) {
+        tizen_video_object_send_size(object->resource,
+                video->min_width, video->min_height,
+                video->max_width, video->max_height, video->prefer_align);
+    }
+}
+
+static void
+video_send_property(struct ds_tizen_video *video, struct video_property *prop)
+{
+    struct ds_tizen_video_object *object;
+
+    wl_list_for_each(object, &video->objects, link) {
+        tizen_video_object_send_attribute(object->resource,
+                prop->name, prop->value);
+    }
+}
+
+static struct video_property *
+video_get_property(struct ds_tizen_video *video, const char *name)
+{
+    struct video_property *prop;
+
+    wl_array_for_each(prop, &video->properties) {
+        if (strcmp(prop->name, name) == 0)
+            return prop;
+    }
+
+    return NULL;
+}
+
+static void
 video_resource_send_formats(struct wl_resource *resource,
         struct wl_array *formats)
 {
@@ -171,3 +388,159 @@ video_resource_send_formats(struct wl_resource *resource,
     wl_array_for_each(p, formats)
         tizen_video_send_format(resource, *p);
 }
+
+static void
+video_object_handle_destroy(struct wl_client *client,
+        struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
+
+static void
+video_object_handle_set_attribute(struct wl_client *client,
+        struct wl_resource *resource, const char *name, int32_t value)
+{
+    struct ds_tizen_video_object *object;
+
+    object = wl_resource_get_user_data(resource);
+    if (!object)
+        return;
+
+    struct ds_event_tizen_video_request_set_property event = {
+        .object = object,
+        .name = name,
+        .value = value,
+    };
+    wl_signal_emit(&object->events.request_set_property, &event);
+}
+
+static void
+video_object_handle_follow_topmost_visibility(struct wl_client *client,
+        struct wl_resource *resource)
+{
+    struct ds_tizen_video_object *object;
+
+    object = wl_resource_get_user_data(resource);
+    if (!object)
+        return;
+
+    wl_signal_emit(&object->events.request_follow_topmost_visibility, object);
+}
+
+static void
+video_object_handle_unfollow_topmost_visibility(struct wl_client *client,
+        struct wl_resource *resource)
+{
+    struct ds_tizen_video_object *object;
+
+    object = wl_resource_get_user_data(resource);
+    if (!object)
+        return;
+
+    wl_signal_emit(&object->events.request_unfollow_topmost_visibility, object);
+}
+
+static void
+video_object_handle_allowed_attribute(struct wl_client *client,
+        struct wl_resource *resource)
+{
+    struct ds_tizen_video_object *object;
+
+    object = wl_resource_get_user_data(resource);
+    if (!object)
+        return;
+
+    wl_signal_emit(&object->events.request_attribute_allowed, object);
+}
+
+static void
+video_object_handle_disallowed_attribute(struct wl_client *client,
+        struct wl_resource *resource)
+{
+    struct ds_tizen_video_object *object;
+
+    object = wl_resource_get_user_data(resource);
+    if (!object)
+        return;
+
+    wl_signal_emit(&object->events.request_attribute_disallowed, object);
+}
+
+static const struct tizen_video_object_interface video_object_impl = {
+    .destroy = video_object_handle_destroy,
+    .set_attribute = video_object_handle_set_attribute,
+    .follow_topmost_visibility = video_object_handle_follow_topmost_visibility,
+    .unfollow_topmost_visibility =
+        video_object_handle_unfollow_topmost_visibility,
+    .allowed_attribute = video_object_handle_allowed_attribute,
+    .disallowed_attribute = video_object_handle_disallowed_attribute,
+};
+
+static void
+video_object_handle_resource_destroy(struct wl_resource *resource)
+{
+    struct ds_tizen_video_object *object;
+
+    object = wl_resource_get_user_data(resource);
+    if (object)
+        video_object_destroy(object);
+}
+
+static void
+video_object_handle_surface_destroy(struct wl_listener *listener, void *data)
+{
+    struct ds_tizen_video_object *object;
+
+    object = wl_container_of(listener, object, surface_destroy);
+    video_object_destroy(object);
+}
+
+static struct ds_tizen_video_object *
+create_video_object(struct wl_client *client, uint32_t id, int version,
+        struct wl_resource *surface_resource)
+{
+    struct ds_tizen_video_object *object;
+
+    object = calloc(1, sizeof *object);
+    if (!object)
+        return NULL;
+
+    object->resource = wl_resource_create(client,
+            &tizen_video_object_interface, version, id);
+    if (!object->resource) {
+        free(object);
+        return NULL;
+    }
+    wl_resource_set_implementation(object->resource, &video_object_impl,
+            object, video_object_handle_resource_destroy);
+
+    wl_signal_init(&object->events.destroy);
+    wl_signal_init(&object->events.request_set_property);
+    wl_signal_init(&object->events.request_follow_topmost_visibility);
+    wl_signal_init(&object->events.request_unfollow_topmost_visibility);
+    wl_signal_init(&object->events.request_attribute_allowed);
+    wl_signal_init(&object->events.request_attribute_disallowed);
+
+    object->surface = ds_surface_from_resource(surface_resource);
+
+    object->surface_destroy.notify = video_object_handle_surface_destroy;
+    ds_surface_add_destroy_listener(object->surface, &object->surface_destroy);
+
+    ds_inf("Create ds_tizen_video_object(%p)", object);
+
+    return object;
+}
+
+static void
+video_object_destroy(struct ds_tizen_video_object *object)
+{
+    ds_inf("Destroy ds_tizen_video_object(%p)", object);
+
+    wl_signal_emit(&object->events.destroy, object);
+
+    wl_resource_set_user_data(object->resource, NULL);
+
+    wl_list_remove(&object->surface_destroy.link);
+    wl_list_remove(&object->link);
+    free(object);
+}