struct wl_signal precommit_from_cache;
struct wl_signal precommit_from_pending;
struct wl_signal commit;
+ struct wl_signal new_subsurface;
} events;
};
ds_surface_add_unmap_listener(surface->ds_surface, listener);
}
+EINTERN void
+e_surface_new_subsurface_listener_add(E_Surface *surface, struct wl_listener *listener)
+{
+ wl_signal_add(&surface->events.new_subsurface, listener);
+}
+
EINTERN void
e_surface_map(E_Surface *surface)
{
return !!surface->base.buffer_ref.buffer;
}
+EINTERN Eina_Bool
+e_surface_has_subsurfaces(E_Surface *surface)
+{
+ if (!surface->ds_surface)
+ return EINA_FALSE;
+
+ return !wl_list_empty(&surface->ds_surface->current.subsurfaces_above) ||
+ !wl_list_empty(&surface->ds_surface->current.subsurfaces_below);
+}
+
EINTERN E_Subsurface *
e_subsurface_try_from_surface(E_Surface *surface)
{
wl_signal_init(&surface->events.precommit_from_cache);
wl_signal_init(&surface->events.precommit_from_pending);
wl_signal_init(&surface->events.commit);
+ wl_signal_init(&surface->events.new_subsurface);
wl_signal_init(&surface->base.destroy_signal);
wl_signal_init(&surface->base.apply_viewport_signal);
wl_signal_init(&surface->base.state_commit_signal);
{
struct ds_subsurface *ds_subsurface = data;
E_Surface *surface;
+ E_Subsurface *subsurface;
surface = wl_container_of(listener, surface, new_subsurface);
- if (!_e_subsurface_create(ds_subsurface, surface))
+ subsurface = _e_subsurface_create(ds_subsurface, surface);
+ if (!subsurface)
{
ELOGF("COMPOSITOR", "Could not create E_Subsurface", surface->ec);
return;
}
+
+ wl_signal_emit(&surface->events.new_subsurface, subsurface);
}
static void
void e_surface_commit_listener_add(E_Surface *surface, struct wl_listener *listener);
void e_surface_map_listener_add(E_Surface *surface, struct wl_listener *listener);
void e_surface_unmap_listener_add(E_Surface *surface, struct wl_listener *listener);
+void e_surface_new_subsurface_listener_add(E_Surface *surface, struct wl_listener *listener);
struct wl_listener *e_surface_destroy_listener_get(E_Surface *surface, wl_notify_func_t notify);
Eina_Bool e_surface_role_set(E_Surface *surface, const char *role_name, struct wl_resource *error_resource, uint32_t error_code);
void e_surface_role_unset(E_Surface *surface);
void e_surface_map(E_Surface *surface);
void e_surface_unmap(E_Surface *surface);
Eina_Bool e_surface_is_mapped(E_Surface *surface);
+Eina_Bool e_surface_has_subsurfaces(E_Surface *surface);
E_Subsurface *e_subsurface_create(struct wl_resource *factory_resource, uint32_t id, E_Surface *surface, E_Surface *parent);
E_Subsurface *e_subsurface_from_resource(struct wl_resource *resource);
struct wl_listener parent_unmap;
struct wl_listener source_destroy;
struct wl_listener reposition;
+ struct wl_listener new_subsurface;
Eina_Bool parent_mapped;
Eina_Bool mapped;
_viewport_border_finish(viewport);
wl_resource_set_user_data(viewport->resource, NULL);
+ wl_list_remove(&viewport->new_subsurface.link);
wl_list_remove(&viewport->parent_map.link);
wl_list_remove(&viewport->parent_unmap.link);
wl_list_remove(&viewport->precommit_from_cache.link);
_viewport_unmap(viewport);
}
+static void
+_viewport_cb_new_subsurface(struct wl_listener *listener, void *data)
+{
+ E_Video_Viewport *viewport = wl_container_of(listener, viewport, new_subsurface);
+ E_Subsurface *subsurface = data;
+
+ VS_ERR("VIEWPORT %p| The video viewport subsurface cannot have a child subsurface(%p)",
+ viewport, subsurface);
+
+ wl_resource_post_error(viewport->resource,
+ WTZ_VIDEO_EXPORTED_VIEWPORT_ERROR_CHILD_ADDED,
+ "The video viewport subsurface cannot have a child subsurface");
+}
+
static void
_viewport_state_init(E_Video_Viewport_State *state)
{
static void
_video_shell_cb_export_viewport(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *subsurface_resource)
{
+ E_Subsurface *subsurface = e_subsurface_from_resource(subsurface_resource);
+ E_Surface *surface = e_subsurface_surface_get(subsurface);
+ E_Surface *parent_surface = e_subsurface_parent_try_get(subsurface);
E_Video_Viewport *viewport;
- E_Surface *surface, *parent_surface;
+
+ if (e_surface_has_subsurfaces(surface))
+ {
+ wl_resource_post_error(resource,
+ WTZ_VIDEO_SHELL_ERROR_CHILD_EXISTS,
+ "The subsurface to export as video viewport cannot have a child subsurface");
+ return;
+ }
viewport = calloc(1, sizeof(*viewport));
if (!viewport)
_viewport_state_init(&viewport->cache);
_viewport_state_init(&viewport->current);
- viewport->subsurface = e_subsurface_from_resource(subsurface_resource);
+ viewport->subsurface = subsurface;
viewport->destroy.notify = _viewport_cb_subsurface_destroy;
- e_subsurface_destroy_listener_add(viewport->subsurface, &viewport->destroy);
+ e_subsurface_destroy_listener_add(subsurface, &viewport->destroy);
+
+ viewport->reposition.notify = _viewport_cb_reposition;
+ e_subsurface_reposition_listener_add(subsurface, &viewport->reposition);
- surface = e_subsurface_surface_get(viewport->subsurface);
viewport->precommit_to_cache.notify = _viewport_cb_precommit_to_cache;
e_surface_precommit_to_cache_listener_add(surface, &viewport->precommit_to_cache);
viewport->precommit_from_pending.notify = _viewport_cb_precommit_from_pending;
e_surface_precommit_from_pending_listener_add(surface, &viewport->precommit_from_pending);
- viewport->reposition.notify = _viewport_cb_reposition;
- e_subsurface_reposition_listener_add(viewport->subsurface, &viewport->reposition);
-
- parent_surface = e_subsurface_parent_try_get(viewport->subsurface);
+ viewport->new_subsurface.notify = _viewport_cb_new_subsurface;
+ e_surface_new_subsurface_listener_add(surface, &viewport->new_subsurface);
viewport->parent_map.notify = _viewport_cb_parent_map;
e_surface_map_listener_add(parent_surface, &viewport->parent_map);
if (border_enabled)
_viewport_border_init(viewport);
- VS_INF("VIEWPORT %p| Created with E_Subsurface(%p)", viewport, viewport->subsurface);
+ VS_INF("VIEWPORT %p| Created with E_Subsurface(%p)", viewport, subsurface);
}
static void