pepper: implement subsurface protocols
authorJaehoon Jeong <jh01.j@samsung.com>
Tue, 10 Nov 2015 04:46:07 +0000 (13:46 +0900)
committer김태균 <tkq.kim@samsung.com>
Fri, 13 Nov 2015 04:43:21 +0000 (13:43 +0900)
    - Create subsurface's views that corresponding to parent surface's views

Change-Id: I6d54bd82f67c41a5b74d0bcd965394063ef0c3be

src/lib/pepper/pepper-internal.h
src/lib/pepper/subsurface.c

index 7add52a12a26fdd5874c5eae216e578ed620d6c3..2769a1cb594a39a32c3e9391a4d3c41cc5dec0ea 100644 (file)
@@ -290,6 +290,8 @@ struct pepper_subsurface
         pepper_list_t        parent_link;
     } pending;
 
+    pepper_bool_t            restacked;
+
     pepper_bool_t            synchronized;    /* commit behavior */
 
     /* In sync mode, wl_surface.commit will apply the pending state into cache.
index 4bb72e2382acb174890b73e8f4debb9d65778a0e..7a03870cada4380240659f669fd04eb759500d7c 100644 (file)
@@ -32,7 +32,7 @@ static void
 subsurface_destroy(struct wl_client     *client,
                    struct wl_resource   *resource)
 {
-    /* TODO */
+    wl_resource_destroy(resource);
 }
 
 static void
@@ -41,7 +41,39 @@ subsurface_set_position(struct wl_client    *client,
                         int32_t              x,
                         int32_t              y)
 {
-    /* TODO */
+    pepper_subsurface_t *subsurface = wl_resource_get_user_data(resource);
+
+    subsurface->pending.x = x;
+    subsurface->pending.y = y;
+}
+
+static pepper_bool_t
+subsurface_is_sibling(pepper_subsurface_t *subsurface, pepper_surface_t *sib)
+{
+    pepper_subsurface_t *sibling = sib->sub;
+
+    if (sibling)
+    {
+        if (subsurface->parent == sibling->surface)
+            return PEPPER_TRUE;
+        else if(subsurface->parent == sibling->parent)
+            return PEPPER_TRUE;
+    }
+
+    return PEPPER_FALSE;
+}
+
+static void
+subsurface_stack_above(pepper_subsurface_t *subsurface, pepper_surface_t *sib)
+{
+    pepper_subsurface_t *sibling = sib->sub;
+
+    /* TODO: sibling == parent */
+
+    pepper_list_remove(&subsurface->pending.parent_link);
+    pepper_list_insert(&sibling->pending.parent_link, &subsurface->pending.parent_link);
+
+    subsurface->restacked = PEPPER_TRUE;
 }
 
 static void
@@ -49,29 +81,103 @@ subsurface_place_above(struct wl_client     *client,
                        struct wl_resource   *resource,
                        struct wl_resource   *sibling_resource)
 {
-    /* TODO */
+    pepper_subsurface_t *sub = wl_resource_get_user_data(resource);
+    pepper_surface_t    *sibling;
+
+    if (!sibling_resource)
+    {
+        wl_resource_post_error(resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+                               "reference surface cannot be null");
+        return ;
+    }
+
+    sibling = wl_resource_get_user_data(sibling_resource);
+
+    if (sub->surface == sibling)
+    {
+        wl_resource_post_error(resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+                               "cannot place above of its own for itself");
+        return ;
+    }
+
+    if (!subsurface_is_sibling(sub, sibling))
+    {
+        wl_resource_post_error(resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+                               "reference surface is not sibling");
+        return ;
+    }
+
+    subsurface_stack_above(sub, sibling);
+}
+
+static void
+subsurface_stack_below(pepper_subsurface_t *subsurface, pepper_surface_t *sib)
+{
+    pepper_subsurface_t *sibling = sib->sub;
+
+    /* TODO: sibling == parent */
+
+    pepper_list_remove(&subsurface->pending.parent_link);
+    pepper_list_insert(sibling->pending.parent_link.prev, &subsurface->pending.parent_link);
+
+    subsurface->restacked = PEPPER_TRUE;
 }
 
 static void
 subsurface_place_below(struct wl_client     *client,
                        struct wl_resource   *resource,
-                       struct wl_resource   *sibling)
+                       struct wl_resource   *sibling_resource)
 {
-    /* TODO */
+    pepper_subsurface_t *sub = wl_resource_get_user_data(resource);
+    pepper_surface_t    *sibling;
+
+    if (!sibling_resource)
+    {
+        wl_resource_post_error(resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+                               "reference surface cannot be null");
+        return ;
+    }
+
+    sibling = wl_resource_get_user_data(sibling_resource);
+
+    if (sub->surface == sibling)
+    {
+        wl_resource_post_error(resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+                               "cannot place below of its own for itself");
+        return ;
+    }
+
+    if (!subsurface_is_sibling(sub, sibling))
+    {
+        wl_resource_post_error(resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+                               "reference surface is not sibling");
+        return ;
+    }
+
+    subsurface_stack_below(sub, sibling);
 }
 
 static void
 subsurface_set_sync(struct wl_client    *client,
                     struct wl_resource  *resource)
 {
-    /* TODO */
+    pepper_subsurface_t *subsurface = wl_resource_get_user_data(resource);
+
+    subsurface->synchronized = 1;
 }
 
 static void
 subsurface_set_desync(struct wl_client      *client,
                       struct wl_resource    *resource)
 {
-    /* TODO */
+    pepper_subsurface_t *subsurface = wl_resource_get_user_data(resource);
+
+    if (subsurface->synchronized )
+    {
+        /* TODO: subsurface_commit(subsurface);? */
+    }
+
+    subsurface->synchronized = 0;
 }
 
 static struct wl_subsurface_interface subsurface_implementation =
@@ -87,12 +193,15 @@ static struct wl_subsurface_interface subsurface_implementation =
 void
 pepper_subsurface_destroy(pepper_subsurface_t *subsurface)
 {
-    /* TODO */
+    pepper_view_t   *view;
 
     pepper_surface_state_fini(&subsurface->cache);
     pepper_list_remove(&subsurface->parent_link);
     pepper_list_remove(&subsurface->pending.parent_link);
 
+    pepper_list_for_each(view, &subsurface->surface->view_list, surface_link)
+        pepper_view_destroy(view);
+
     free(subsurface);
 }
 
@@ -110,6 +219,26 @@ handle_parent_destroy(pepper_event_listener_t *listener,
     /* TODO */
 }
 
+static pepper_bool_t
+pepper_subsurface_create_views(pepper_subsurface_t *subsurface)
+{
+    pepper_surface_t    *parent = subsurface->parent;
+    pepper_view_t       *parent_view;
+
+    pepper_list_for_each(parent_view, &parent->view_list, surface_link)
+    {
+        pepper_view_t *subview = pepper_compositor_add_view(parent->compositor);
+        PEPPER_CHECK(subview, return PEPPER_FALSE, "pepper_compositor_add_view() failed.\n");
+
+        pepper_view_set_surface(subview, subsurface->surface);
+        pepper_view_set_parent(subview, parent_view);
+        pepper_view_set_transform_inherit(subview, PEPPER_TRUE);
+        pepper_view_map(subview);
+    }
+
+    return PEPPER_TRUE;
+}
+
 pepper_subsurface_t *
 pepper_subsurface_create(pepper_surface_t   *surface,
                          pepper_surface_t   *parent,
@@ -118,6 +247,7 @@ pepper_subsurface_create(pepper_surface_t   *surface,
                          uint32_t            id)
 {
     pepper_subsurface_t *subsurface = NULL;
+    pepper_bool_t        ret;
 
     if (!pepper_surface_set_role(surface, "wl_subsurface"))
     {
@@ -126,6 +256,10 @@ pepper_subsurface_create(pepper_surface_t   *surface,
         return NULL;
     }
 
+    /* Make sure that subsurface has no view */
+    if (!pepper_list_empty(&surface->view_list))
+        goto error;
+
     subsurface = calloc(1, sizeof(pepper_subsurface_t));
     PEPPER_CHECK(subsurface, goto error, "calloc() failed.\n");
 
@@ -152,6 +286,10 @@ pepper_subsurface_create(pepper_surface_t   *surface,
     pepper_list_insert(&parent->subsurface_list, &subsurface->parent_link);
     pepper_list_insert(&parent->subsurface_pending_list, &subsurface->pending.parent_link);
 
+    /* create views that corresponding to parent's views */
+    ret = pepper_subsurface_create_views(subsurface);
+    PEPPER_CHECK(ret, goto error, "pepper_subsurface_create_views() failed\n");
+
     surface->sub = subsurface;
 
     return subsurface;