subsurface: implement tizen_subsurface_watcher 22/106822/3
authorBoram Park <boram1288.park@samsung.com>
Fri, 23 Dec 2016 03:14:25 +0000 (12:14 +0900)
committerBoram Park <boram1288.park@samsung.com>
Fri, 23 Dec 2016 08:54:35 +0000 (17:54 +0900)
Change-Id: Ib88db8bcfa981c291cd49eca77dc1f307b098fcc

src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_policy_wl.c

index 2d8cca8ec4dabf1f2acafedd6e31bfcaa73975ed..fe21b4bbeae392430eda6b831af5686fec602e84 100644 (file)
@@ -3765,6 +3765,24 @@ e_comp_wl_subsurface_create(E_Client *ec, E_Client *epc, uint32_t id, struct wl_
         return EINA_FALSE;
      }
 
+   if (!ec || e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return EINA_FALSE;
+
+   if (!epc || e_object_is_del(E_OBJECT(epc)))
+     {
+        if (ec->comp_data->sub.watcher)
+          tizen_subsurface_watcher_send_message(ec->comp_data->sub.watcher, TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_INVALID);
+
+        /* We have to create a subsurface resource here even though it's error case
+         * because server will send the fatal error when a client destroy a subsurface object.
+         * Otherwise, server will kill a client by the fatal error.
+         */
+        res = wl_resource_create(client, &wl_subsurface_interface, 1, id);
+        wl_resource_set_implementation(res, &_e_subsurface_interface, NULL, NULL);
+
+        ERR("tizen_policy failed: invalid parent");
+        return EINA_FALSE;
+     }
+
    // reparent remote surface provider's subsurfaces
    if (epc->comp_data->remote_surface.onscreen_parent)
      {
@@ -3884,6 +3902,22 @@ dat_err:
    return EINA_FALSE;
 }
 
+static void
+_e_comp_wl_surface_sub_list_free(Eina_List *sub_list)
+{
+   E_Client *subc;
+
+   EINA_LIST_FREE(sub_list, subc)
+     {
+        if (!subc->comp_data || !subc->comp_data->sub.data) continue;
+
+        subc->comp_data->sub.data->parent = NULL;
+
+        if (subc->comp_data->sub.watcher)
+          tizen_subsurface_watcher_send_message(subc->comp_data->sub.watcher, TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_DESTROYED);
+     }
+}
+
 static void
 _e_comp_wl_subcompositor_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
 {
@@ -4150,7 +4184,6 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
 {
    /* Eina_Rectangle *dmg; */
    struct wl_resource *cb;
-   E_Client *subc;
 
    /* make sure this is a wayland client */
    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
@@ -4175,14 +4208,13 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
 
    /* remove sub list */
    /* TODO: if parent is set by onscreen_parent of remote surface? */
-   EINA_LIST_FREE(ec->comp_data->sub.list, subc)
-     if (subc->comp_data && subc->comp_data->sub.data) subc->comp_data->sub.data->parent = NULL;
-   EINA_LIST_FREE(ec->comp_data->sub.list_pending, subc)
-     if (subc->comp_data && subc->comp_data->sub.data) subc->comp_data->sub.data->parent = NULL;
-   EINA_LIST_FREE(ec->comp_data->sub.below_list, subc)
-     if (subc->comp_data && subc->comp_data->sub.data) subc->comp_data->sub.data->parent = NULL;
-   EINA_LIST_FREE(ec->comp_data->sub.below_list_pending, subc)
-     if (subc->comp_data && subc->comp_data->sub.data) subc->comp_data->sub.data->parent = NULL;
+   _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.list);
+   _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.list_pending);
+   _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.below_list);
+   _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.below_list_pending);
+
+   if (ec->comp_data->sub.watcher)
+     wl_resource_destroy(ec->comp_data->sub.watcher);
 
    if ((ec->parent) && (ec->parent->modal == ec))
      {
index 105b1cb187a63f8eaea8ea43c01ae25ac747705a..8cc71aa66dc95b0624ed65e49dddfd436689e9ad 100644 (file)
@@ -372,6 +372,8 @@ struct _E_Comp_Wl_Client_Data
         Evas_Object *below_obj;
 
         Eina_Bool restacking : 1;
+
+        struct wl_resource *watcher;
      } sub;
 
    /* regular surface resource (wl_compositor_create_surface) */
index 8ebe3a7626e8f6ff899f8176f9272ae272d9710f..51742462cd5c31aa3f037d54fe0aa2e3b299f820 100644 (file)
@@ -2019,15 +2019,6 @@ _tzpol_iface_cb_subsurface_get(struct wl_client *client, struct wl_resource *res
 
    if (e_object_is_del(E_OBJECT(ec))) return;
 
-   epc = e_pixmap_find_client_by_res_id(parent_id);
-   if (!epc)
-     {
-        ERR("tizen_policy failed: wrong parent_id(%d)", parent_id);
-        return;
-     }
-
-   if (e_object_is_del(E_OBJECT(epc))) return;
-
    /* check if this surface is already a sub-surface */
    if ((ec->comp_data) && (ec->comp_data->sub.data))
      {
@@ -2038,10 +2029,14 @@ _tzpol_iface_cb_subsurface_get(struct wl_client *client, struct wl_resource *res
         return;
      }
 
+   epc = e_pixmap_find_client_by_res_id(parent_id);
+
    /* try to create a new subsurface */
    if (!e_comp_wl_subsurface_create(ec, epc, id, surface))
-     ERR("Failed to create subsurface for surface@%d",
-         wl_resource_get_id(surface));
+     {
+        ERR("Failed to create subsurface for surface@%d", wl_resource_get_id(surface));
+        return;
+     }
 
    /* ec's parent comes from another process */
    if (ec->comp_data)
@@ -2914,6 +2909,37 @@ _tz_dpy_pol_iface_cb_brightness_set(struct wl_client *client, struct wl_resource
       (res_tz_dpy_pol, surf, brightness, TIZEN_DISPLAY_POLICY_ERROR_STATE_NONE);
 }
 
+static void
+_tzpol_iface_cb_subsurf_watcher_destroy(struct wl_resource *resource)
+{
+   E_Client *ec;
+
+   if (!(ec = wl_resource_get_user_data(resource))) return;
+   if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return;
+
+   ec->comp_data->sub.watcher = NULL;
+}
+
+static void
+_tzpol_iface_cb_subsurf_watcher_get(struct wl_client *client, struct wl_resource *res_tzpol, uint32_t id, struct wl_resource *surface)
+{
+   E_Client *ec;
+   struct wl_resource *res;
+
+   if (!(ec = wl_resource_get_user_data(surface))) return;
+   if (e_object_is_del(E_OBJECT(ec))) return;
+
+   if (!(res = wl_resource_create(client, &tizen_subsurface_watcher_interface, 1, id)))
+     {
+        wl_resource_post_no_memory(res_tzpol);
+        return;
+     }
+
+   ec->comp_data->sub.watcher = res;
+
+   wl_resource_set_implementation(res, NULL, ec, _tzpol_iface_cb_subsurf_watcher_destroy);
+}
+
 // --------------------------------------------------------
 // tizen_policy_interface
 // --------------------------------------------------------
@@ -2953,6 +2979,7 @@ static const struct tizen_policy_interface _tzpol_iface =
    _tzpol_iface_cb_floating_mode_unset,
    _tzpol_iface_cb_stack_mode_set,
    _tzpol_iface_cb_activate_above_by_res_id,
+   _tzpol_iface_cb_subsurf_watcher_get,
 };
 
 static void
@@ -5458,7 +5485,7 @@ e_policy_wl_init(void)
    /* create globals */
    global = wl_global_create(e_comp_wl->wl.disp,
                              &tizen_policy_interface,
-                             1,
+                             2,
                              NULL,
                              _tzpol_cb_bind);
    EINA_SAFETY_ON_NULL_GOTO(global, err);