wl: huge refactoring to resolve memory leak and corruption problems
authorGwanglim Lee <gl77.lee@samsung.com>
Sat, 1 Aug 2015 15:52:40 +0000 (00:52 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Sat, 1 Aug 2015 15:52:40 +0000 (00:52 +0900)
Change-Id: I4a4622037c180b0d16b2328df63bd07be2f80e52

src/e_mod_wl.c

index d9614e1..0e27d86 100644 (file)
 #include <wayland-server.h>
 #include <tizen-extension-server-protocol.h>
 
-typedef struct _Pol_Wayland
-{
-   E_Pixmap *cp;
-   Eina_List *visibility_list;
-   Eina_List *position_list;
-} Pol_Wayland;
-
-typedef struct _Notification_Level
-{
-   int32_t level;
-   struct wl_resource *interface;
-   struct wl_resource *surface;
-} Notification_Level;
+#undef VALIDATION
+#define VALIDATION(s, p) do { if (!_pol_wl_surf_valid_check(__func__, __LINE__, s, p)) return; } while(0)
 
-typedef struct _Policy_Conformant
+typedef struct _Pol_Wl_Surface
 {
-   struct wl_resource *interface;
-   struct wl_resource *surface;
-} Policy_Conformant;
-
-typedef struct _Window_Screen_Mode
+   struct wl_resource *surf;
+   struct wl_resource *tzpol;
+   E_Pixmap           *cp;
+   E_Client           *ec;
+   Eina_Bool           pending_notilv;
+   int32_t             notilv;
+   uint32_t            scrmode;
+   Eina_List          *vislist; /* list of tizen_visibility_interface resources */
+   Eina_List          *poslist; /* list of tizen_position_inteface resources */
+} Pol_Wl_Surface;
+
+typedef struct _Pol_Wl
 {
-   uint32_t mode;
-   struct wl_resource *surface;
-   struct wl_resource *interface;
-} Window_Screen_Mode;
+   Eina_List *resources; /* list of tizen_policy_interface resources */
+   Eina_Hash *surfaces; /* hash for Pol_Wl_Surface */
+} Pol_Wl;
 
-static Eina_Hash *hash_pol_wayland = NULL;
-static Eina_Hash *hash_notification_levels = NULL;
-static Eina_Hash *hash_policy_conformants = NULL;
-static Eina_Hash *hash_window_screen_modes = NULL;
-static Eina_List *_window_screen_modes = NULL;
+static Pol_Wl *polwl = NULL;
 
-static Pol_Wayland*
-_pol_wayland_get_info(E_Pixmap *cp)
+// --------------------------------------------------------
+// Pol_Wl_Surface
+// --------------------------------------------------------
+static Pol_Wl_Surface *
+_pol_wl_surf_add(E_Pixmap *cp, struct wl_resource *tzpol)
 {
-   Pol_Wayland *pn;
+   Pol_Wl_Surface *psurf = NULL;
    E_Comp_Client_Data *cdata = NULL;
-   struct wl_resource *surface = NULL;
+   struct wl_resource *surf = NULL;
+   struct wl_resource *res;
+   Eina_List *l;
+   Eina_Bool found = EINA_FALSE;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(hash_pol_wayland, NULL);
+   psurf = eina_hash_find(polwl->surfaces, &cp);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(psurf, psurf);
 
-   pn = eina_hash_find(hash_pol_wayland, &cp);
-   if (!pn)
+   EINA_LIST_FOREACH(polwl->resources, l, res)
      {
-        pn = E_NEW(Pol_Wayland, 1);
-        EINA_SAFETY_ON_NULL_RETURN_VAL(pn, NULL);
-
-        pn->cp = cp;
-        eina_hash_add(hash_pol_wayland, &cp, pn);
+        if (res == tzpol)
+          {
+             found = EINA_TRUE;
+             break;
+          }
+     }
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(found, NULL);
 
-        cdata = e_pixmap_cdata_get(cp);
-        if (cdata)
-          surface = cdata->wl_surface;
+   psurf = E_NEW(Pol_Wl_Surface, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(psurf, NULL);
 
-        PLOGF("POL",
-              "HASH_ADD |s:0x%08x|pn:0x%08x",
-              cp, e_pixmap_client_get(cp),
-              (unsigned int)surface, (unsigned int)pn);
-     }
+   eina_hash_add(hash_surfaces, &cp, psurf);
 
-   return pn;
+   cdata = e_pixmap_cdata_get(cp);
+   if (cdata)
+     surf = cdata->wl_surface;
+
+   psurf->surf = surf;
+   psurf->tzpol = tzpol;
+   psurf->cp = cp;
+   psurf->ec = e_pixmap_client_get(cp);
+
+   PLOGF("POLSURF",
+         "HASH_ADD |s:0x%08x|tzpol:0x%08x|ps:0x%08x",
+         psurf->cp,
+         psurf->ec,
+         (unsigned int)surf,
+         (unsigned int)tzpol,
+         (unsigned int)psurf);
+
+   return psurf;
 }
 
 static void
-_pol_wayland_role_handle(E_Client *ec, const char* role)
+_pol_wl_surf_del(Pol_Wl_Surface *psurf)
 {
-   /* TODO: support multiple roles */
+   PLOGF("POLSURF",
+         "HASH_DEL |s:0x%08x|ps:0x%08x|tzpol:0x%08x",
+         psurf->cp,
+         psurf->ec,
+         (unsigned int)psurf->surf,
+         (unsigned int)psurf->tzpol,
+         (unsigned int)psurf);
+
+   eina_list_free(psurf->vislist);
+   eina_list_free(psurf->poslist);
+
+   memset(psurf, 0x0, sizeof(Pol_Wl_Surface));
+   E_FREE(psurf);
+}
 
-   EINA_SAFETY_ON_NULL_RETURN(ec->frame);
-   EINA_SAFETY_ON_NULL_RETURN(role);
+static Pol_Wl_Surface *
+_pol_wl_surf_get(E_Pixmap *cp)
+{
+   return (Pol_Wl_Surface *)eina_hash_find(polwl->surfaces, &cp);
+}
 
-   if (!e_util_strcmp("notification-low", role))
-     {
-        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_LOW);
-     }
-   else if (!e_util_strcmp("notification-normal", role))
-     {
-        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_NORMAL);
-     }
-   else if (!e_util_strcmp("notification-high", role))
-     {
-        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_HIGH);
-     }
-   else if (!e_util_strcmp("alert", role))
+static Eina_Bool
+_pol_wl_surf_valid_check(const char *func, unsigned int line, Pol_Wl_Surface *psurf, struct wl_resource *tzpol)
+{
+   Eina_List *l;
+   struct wl_resource *res;
+   Eina_Bool found_psurf = EINA_FALSE;
+   Eina_Bool found_tzpol = EINA_FALSE;
+
+   EINA_LIST_FOREACH(polwl->resources, l, res)
      {
-        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_ALERT);
+        if (res == psurf->tzpol) found_psurf = EINA_TRUE;
+        if (res == tzpol) found_tzpol = EINA_TRUE;
+        if ((found_psurf) && (found_tzpol)) break;
      }
-   else if (!e_util_strcmp("tv-volume-popup", role))
+
+   if ((!found_psurf) ||
+       (!found_tzpol) ||
+       (psurf->tzpol != tzpol))
      {
-        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_LOW);
-        ec->lock_client_location = 1;
+        PLOGF("POLSURF",
+              "INVALID!!|s:0x%08x|tzpol:0x%08x|ps:0x%08x|tzpol2:0x%08x|%d|%d",
+              psurf->cp,
+              psurf->ec,
+              (unsigned int)psurf->surf,
+              (unsigned int)psurf->tzpol,
+              (unsigned int)psurf,
+              (unsigned int)tzpol,
+              found_psurf,
+              found_tzpol);
+
+        return EINA_FALSE;
      }
+
+   return EINA_TRUE;
 }
 
-static void
-_pol_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource)
+// --------------------------------------------------------
+// util funcs
+// --------------------------------------------------------
+static const char*
+_pol_wl_pname_print(pid_t pid)
 {
-   E_Pixmap *pp;
-   E_Client *pc = NULL;
-   Ecore_Window pwin = 0;
+   FILE *h;
+   char proc[512], pname[512];
+   size_t len;
 
-   if (parent_resource)
-     {
-        if (!(pp = wl_resource_get_user_data(parent_resource)))
-          {
-             ERR("Could not get parent resource pixmap");
-             return;
-          }
+   sprintf(proc, "/proc/%d/cmdline", pid);
 
-        pwin = e_pixmap_window_get(pp);
+   h = fopen(proc, "r");
+   if (!h) return;
 
-        /* find the parent client */
-        if (!(pc = e_pixmap_client_get(pp)))
-          pc = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pwin);
+   len = fread(pname, sizeof(char), 512, h);
+   if (len > 0)
+     {
+        if ('\n' == pname[len - 1])
+          pname[len - 1] = '\0';
      }
 
-   e_mod_pol_stack_transient_for_set(ec, pc);
+   fclose(h);
+
+   PLOGF("TZPOL", "         |%s", NULL, NULL, pname);
+}
+
+// --------------------------------------------------------
+// visibility
+// --------------------------------------------------------
+static void
+_tzvis_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *tzvis)
+{
+   wl_resource_destroy(tzvis);
 }
 
+static const struct tizen_visibility_interface _tzvis_iface =
+{
+   _tzvis_iface_cb_destroy
+};
+
 static void
-_e_tizen_visibility_destroy(struct wl_resource *resource)
+_tzvis_iface_cb_vis_destroy(struct wl_resource *tzvis)
 {
    E_Pixmap *cp;
-   Pol_Wayland *pn;
+   Pol_Wl_Surface *psurf;
 
-   cp = wl_resource_get_user_data(resource);
+   cp = wl_resource_get_user_data(tzvis);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
-   pn = _pol_wayland_get_info(cp);
-   EINA_SAFETY_ON_NULL_RETURN(pn);
+   psurf = _pol_wl_surf_get(cp);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
 
-   pn->visibility_list = eina_list_remove(pn->visibility_list, resource);
+   psurf->vislist = eina_list_remove(psurf->vislist, tzvis);
 }
 
 static void
-_e_tizen_visibility_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+_tzpol_iface_cb_vis_get(struct wl_client *client, struct wl_resource *tzpol, uint32_t id, struct wl_resource *surf)
 {
-   wl_resource_destroy(resource);
-}
+   E_Pixmap *cp;
+   Pol_Wl_Surface *psurf;
+   struct wl_resource *tzvis;
 
-static const struct tizen_visibility_interface _e_tizen_visibility_interface =
-{
-   _e_tizen_visibility_cb_destroy
-};
+   cp = wl_resource_get_user_data(surf);
+   EINA_SAFETY_ON_NULL_RETURN(cp);
 
-static void
-_e_tizen_position_destroy(struct wl_resource *resource)
+   psurf = _pol_wl_surf_get(cp);
+   if (psurf)
+     VALIDATION(psurf, tzpol);
+   else
+     psurf = _pol_wl_surf_add(cp, tzpol);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
+
+   tzvis = wl_resource_create(client,
+                              &tizen_visibility_interface,
+                              wl_resource_get_version(tzpol),
+                              id);
+   if (!tzvis)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   wl_resource_set_implementation(tzvis,
+                                  &_tzvis_iface,
+                                  cp,
+                                  _tzvis_iface_cb_vis_destroy);
+
+   psurf->vislist = eina_list_append(psurf->vislist, tzvis);
+}
+
+void
+e_mod_pol_wl_visibility_send(E_Client *ec, int vis)
 {
+   Pol_Wl_Surface *psurf;
    E_Pixmap *cp;
-   Pol_Wayland *pn;
+   struct wl_resource *tzvis;
+   Eina_List *l;
 
-   cp = wl_resource_get_user_data(resource);
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   cp = ec->pixmap;
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
-   pn = _pol_wayland_get_info(cp);
-   EINA_SAFETY_ON_NULL_RETURN(pn);
+   psurf = _pol_wl_surf_get(cp);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
 
-   pn->position_list = eina_list_remove(pn->position_list, resource);
+   EINA_LIST_FOREACH(psurf->vislist, l, tzvis)
+     {
+        tizen_visibility_send_notify(tzvis, vis);
+     }
 }
 
+// --------------------------------------------------------
+// position
+// --------------------------------------------------------
 static void
-_e_tizen_position_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+_tzpos_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpos)
 {
-   wl_resource_destroy(resource);
+   wl_resource_destroy(tzpos);
 }
 
 static void
-_e_tizen_position_cb_set(struct wl_client *client,
-                         struct wl_resource *tizen_position,
-                         int32_t x, int32_t y)
+_tzpos_iface_cb_set(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpos, int32_t x, int32_t y)
 {
    E_Pixmap *cp;
    E_Client *ec;
 
-   cp = wl_resource_get_user_data(tizen_position);
+   cp = wl_resource_get_user_data(tzpos);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
    ec = e_pixmap_client_get(cp);
@@ -192,78 +280,96 @@ _e_tizen_position_cb_set(struct wl_client *client,
         ec->x = ec->client.x = x;
         ec->y = ec->client.y = y;
      }
-   //e_client_util_move_without_frame(ec, x, y);
 }
 
-static const struct tizen_position_interface _e_tizen_position_interface =
+static const struct tizen_position_interface _tzpos_iface =
 {
-   _e_tizen_position_cb_destroy,
-   _e_tizen_position_cb_set,
+   _tzpos_iface_cb_destroy,
+   _tzpos_iface_cb_set,
 };
 
 static void
-_e_tizen_policy_cb_visibility_get(struct wl_client *client, struct wl_resource *policy, uint32_t id, struct wl_resource *surface_resource)
+_tzpol_iface_cb_pos_destroy(struct wl_resource *tzpos)
 {
-   int version = wl_resource_get_version(policy);
-   struct wl_resource *res;
    E_Pixmap *cp;
-   Pol_Wayland *pn;
+   Pol_Wl_Surface *psurf;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(tzpos);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
-   pn = _pol_wayland_get_info(cp);
-   EINA_SAFETY_ON_NULL_RETURN(pn);
+   psurf = _pol_wl_surf_get(cp);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
+
+   psurf->poslist = eina_list_remove(psurf->poslist, tzpos);
+}
+
+static void
+_tzpol_iface_cb_pos_get(struct wl_client *client, struct wl_resource *tzpol, uint32_t id, struct wl_resource *surf)
+{
+   E_Pixmap *cp;
+   Pol_Wl_Surface *psurf;
+   struct wl_resource *tzpos;
+
+   cp = wl_resource_get_user_data(surf);
+   EINA_SAFETY_ON_NULL_RETURN(cp);
 
-   res = wl_resource_create(client, &tizen_visibility_interface, version, id);
-   if (res == NULL)
+   psurf = _pol_wl_surf_get(cp);
+   if (psurf)
+     VALIDATION(psurf, tzpol);
+   else
+     psurf = _pol_wl_surf_add(cp, tzpol);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
+
+   tzpos = wl_resource_create(client,
+                              &tizen_position_interface,
+                              wl_resource_get_version(tzpol),
+                              id);
+   if (!tzpos)
      {
         wl_client_post_no_memory(client);
         return;
      }
 
-   pn->visibility_list = eina_list_append(pn->visibility_list, res);
+   wl_resource_set_implementation(tzpos,
+                                  &_tzpos_iface,
+                                  cp,
+                                  _tzpol_iface_cb_pos_destroy);
 
-   wl_resource_set_implementation(res, &_e_tizen_visibility_interface,
-                                  cp, _e_tizen_visibility_destroy);
+   psurf->poslist = eina_list_append(psurf->poslist, tzpos);
 }
 
-static void
-_e_tizen_policy_cb_position_get(struct wl_client *client, struct wl_resource *tizen_policy, uint32_t id, struct wl_resource *surface_resource)
+void
+e_mod_pol_wl_position_send(E_Client *ec)
 {
-   int version = wl_resource_get_version(tizen_policy);
-   struct wl_resource *res;
+   Pol_Wl_Surface *psurf;
    E_Pixmap *cp;
-   Pol_Wayland *pn;
+   struct wl_resource *tzpos;
+   Eina_List *l;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = ec->pixmap;
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
-   pn = _pol_wayland_get_info(cp);
-   EINA_SAFETY_ON_NULL_RETURN(pn);
+   psurf = _pol_wl_surf_get(cp);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
 
-   res = wl_resource_create(client, &tizen_position_interface, version, id);
-   if (!res)
+   EINA_LIST_FOREACH(psurf->poslist, l, tzpos)
      {
-        wl_client_post_no_memory(client);
-        return;
+        tizen_position_send_changed(tzpos, ec->x, ec->y);
      }
-
-   pn->position_list = eina_list_append(pn->position_list, res);
-   wl_resource_set_implementation(res,
-                                  &_e_tizen_position_interface,
-                                  cp,
-                                  _e_tizen_position_destroy);
-
 }
 
+// --------------------------------------------------------
+// stack: activate, raise, lower
+// --------------------------------------------------------
 static void
-_e_tizen_policy_cb_activate(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_activate(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *surf)
 {
    E_Pixmap *cp;
    E_Client *ec;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
    ec = e_pixmap_client_get(cp);
@@ -277,12 +383,12 @@ _e_tizen_policy_cb_activate(struct wl_client *client, struct wl_resource *policy
 }
 
 static void
-_e_tizen_policy_cb_raise(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_raise(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *surf)
 {
    E_Pixmap *cp;
-   E_Client *ec = NULL;
+   E_Client *ec;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
    ec = e_pixmap_client_get(cp);
@@ -296,12 +402,12 @@ _e_tizen_policy_cb_raise(struct wl_client *client, struct wl_resource *policy, s
 }
 
 static void
-_e_tizen_policy_cb_lower(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_lower(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *surf)
 {
    E_Pixmap *cp;
    E_Client *ec, *below = NULL;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
    ec = e_pixmap_client_get(cp);
@@ -312,7 +418,8 @@ _e_tizen_policy_cb_lower(struct wl_client *client, struct wl_resource *policy, s
    while ((below = e_client_below_get(below)))
      {
         if ((e_client_util_ignored_get(below)) ||
-            (below->iconic)) continue;
+            (below->iconic))
+          continue;
 
         break;
      }
@@ -320,17 +427,21 @@ _e_tizen_policy_cb_lower(struct wl_client *client, struct wl_resource *policy, s
    evas_object_lower(ec->frame);
 
    if ((!below) || (!ec->focused)) return;
+
    evas_object_focus_set(below->frame, 1);
 }
 
+// --------------------------------------------------------
+// focus
+// --------------------------------------------------------
 static void
-_e_tizen_policy_cb_focus_skip_set(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_focus_skip_set(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *surf)
 {
    E_Pixmap *cp;
    E_Client *ec;
    E_Comp_Wl_Client_Data *cdata;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
    ec = e_pixmap_client_get(cp);
@@ -351,13 +462,13 @@ _e_tizen_policy_cb_focus_skip_set(struct wl_client *client, struct wl_resource *
 }
 
 static void
-_e_tizen_policy_cb_focus_skip_unset(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_focus_skip_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *surf)
 {
    E_Pixmap *cp;
    E_Client *ec;
    E_Comp_Wl_Client_Data *cdata;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
    ec = e_pixmap_client_get(cp);
@@ -377,33 +488,71 @@ _e_tizen_policy_cb_focus_skip_unset(struct wl_client *client, struct wl_resource
      }
 }
 
+// --------------------------------------------------------
+// role
+// --------------------------------------------------------
 static void
-_e_tizen_policy_cb_role_set(struct wl_client *client EINA_UNUSED, struct wl_resource *tizen_policy EINA_UNUSED, struct wl_resource *surface_resource, const char *role)
+_tzpol_iface_cb_role_set(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *surf, const char *role)
 {
    E_Pixmap *cp;
    E_Client *ec;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   EINA_SAFETY_ON_NULL_RETURN(role);
+
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
    ec = e_pixmap_client_get(cp);
    EINA_SAFETY_ON_NULL_RETURN(ec);
+   EINA_SAFETY_ON_NULL_RETURN(ec->frame);
 
    eina_stringshare_replace(&ec->icccm.window_role, role);
-   _pol_wayland_role_handle(ec, role);
+
+   /* TODO: support multiple roles */
+   if (!e_util_strcmp("notification-low", role))
+     {
+        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_LOW);
+     }
+   else if (!e_util_strcmp("notification-normal", role))
+     {
+        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_NORMAL);
+     }
+   else if (!e_util_strcmp("notification-high", role))
+     {
+        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_HIGH);
+     }
+   else if (!e_util_strcmp("alert", role))
+     {
+        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_ALERT);
+     }
+   else if (!e_util_strcmp("tv-volume-popup", role))
+     {
+        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NOTIFICATION_LOW);
+        ec->lock_client_location = 1;
+     }
 }
 
+// --------------------------------------------------------
+// conformant
+// --------------------------------------------------------
 static void
-_e_tizen_policy_cb_conformant_set(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_conformant_set(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol, struct wl_resource *surf)
 {
    E_Pixmap *cp;
    E_Client *ec;
    E_Comp_Wl_Client_Data *cdata;
-   Policy_Conformant *pn;
+   Pol_Wl_Surface *psurf;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
+   psurf = _pol_wl_surf_get(cp);
+   if (psurf)
+     VALIDATION(psurf, tzpol);
+   else
+     psurf = _pol_wl_surf_add(cp, tzpol);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
+
    ec = e_pixmap_client_get(cp);
    if (ec)
      {
@@ -419,30 +568,26 @@ _e_tizen_policy_cb_conformant_set(struct wl_client *client, struct wl_resource *
         EINA_SAFETY_ON_NULL_RETURN(cdata);
         cdata->conformant = 1;
      }
-
-   pn = eina_hash_find(hash_policy_conformants, &surface_resource);
-   if (!pn)
-     {
-        pn = E_NEW(Policy_Conformant, 1);
-        EINA_SAFETY_ON_NULL_RETURN(pn);
-        eina_hash_add(hash_policy_conformants, &surface_resource, pn);
-     }
-
-   pn->interface = policy;
-   pn->surface = surface_resource;
 }
 
 static void
-_e_tizen_policy_cb_conformant_unset(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_conformant_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *surf)
 {
    E_Pixmap *cp;
    E_Client *ec;
    E_Comp_Wl_Client_Data *cdata;
-   Policy_Conformant *pn;
+   Pol_Wl_Surface *psurf;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
+   psurf = _pol_wl_surf_get(cp);
+   if (psurf)
+     VALIDATION(psurf, tzpol);
+   else
+     psurf = _pol_wl_surf_add(cp, tzpol);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
+
    ec = e_pixmap_client_get(cp);
    if (ec)
      {
@@ -458,118 +603,227 @@ _e_tizen_policy_cb_conformant_unset(struct wl_client *client, struct wl_resource
         EINA_SAFETY_ON_NULL_RETURN(cdata);
         cdata->conformant = 0;
      }
-
-   pn = eina_hash_find(hash_policy_conformants, &surface_resource);
-   if (pn)
-     eina_hash_del_by_key(hash_policy_conformants, &surface_resource);
 }
 
 static void
-_e_tizen_policy_cb_conformant_get(struct wl_client *client, struct wl_resource *policy, struct wl_resource *surface_resource)
+_tzpol_iface_cb_conformant_get(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol, struct wl_resource *surf)
 {
    E_Pixmap *cp;
    E_Client *ec;
    E_Comp_Wl_Client_Data *cdata;
-   Policy_Conformant *pn;
+   Pol_Wl_Surface *psurf;
+   unsigned char conformant;
 
-   cp = wl_resource_get_user_data(surface_resource);
+   cp = wl_resource_get_user_data(surf);
    EINA_SAFETY_ON_NULL_RETURN(cp);
 
-   pn = eina_hash_find(hash_policy_conformants, &surface_resource);
-   if (pn)
+   psurf = _pol_wl_surf_get(cp);
+   if (psurf)
+     VALIDATION(psurf, tzpol);
+   else
+     psurf = _pol_wl_surf_add(cp, tzpol);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
+
+   ec = e_pixmap_client_get(cp);
+   if (ec)
+     conformant = ec->comp_data->conformant;
+   else
+     {
+        cdata = e_pixmap_cdata_get(cp);
+        EINA_SAFETY_ON_NULL_RETURN(cdata);
+
+        conformant = cdata->conformant;
+     }
+
+   tizen_policy_send_conformant(tzpol, surf, conformant);
+}
+
+void
+e_mod_pol_wl_keyboard_geom_broadcast(E_Client *ec)
+{
+   E_Client *ec2;
+   Pol_Wl_Surface *psurf;
+   Eina_Bool r;
+   struct wl_resource *res;
+   Eina_List *l;
+   Eina_Bool found;
+
+   E_CLIENT_REVERSE_FOREACH(e_comp, ec2)
      {
-        ec = e_pixmap_client_get(cp);
-        if (ec)
-          tizen_policy_send_conformant(pn->interface, surface_resource, ec->comp_data->conformant);
-        else
+        r = e_client_util_ignored_get(ec2);
+        if (r) continue;
+
+        r = e_mod_pol_client_is_conformant(ec2);
+        if (!r) continue;
+
+        psurf = eina_hash_find(polwl->surfaces, &ec2->pixmap);
+        if (!psurf) continue;
+
+        found = EINA_FALSE;
+        EINA_LIST_FOREACH(polwl->resources, l, res)
+          {
+             if (res == psurf->tzpol)
+               {
+                  found = EINA_TRUE;
+                  break;
+               }
+          }
+
+        if (!found)
           {
-             cdata = e_pixmap_cdata_get(cp);
-             EINA_SAFETY_ON_NULL_RETURN(cdata);
-             tizen_policy_send_conformant(pn->interface, surface_resource, cdata->conformant);
+             PLOGF("TZPOL",
+                   "CONF ERR |s:0x%08x|tzpol:0x%08x|ps:0x%08x",
+                   psurf->cp, psurf->ec,
+                   psurf->surf, psurf->tzpol, psurf);
+             continue;
           }
+
+        tizen_policy_send_conformant_area
+           (psurf->tzpol, psurf->surf,
+            TIZEN_POLICY_CONFORMANT_PART_KEYBOARD,
+            ec->visible, ec->x, ec->y,
+            ec->client.w, ec->client.h);
      }
 }
 
+// --------------------------------------------------------
+// notification level
+// --------------------------------------------------------
 static void
-_e_tizen_policy_cb_notification_level_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, int32_t level)
+_tzpol_iface_cb_notilv_set(struct wl_client *client, struct wl_resource *tzpol, struct wl_resource *surf, int32_t lv)
 {
-   E_Pixmap *cp = NULL;
-   E_Client *ec = NULL;
-   Notification_Level *nl = NULL;
+   E_Pixmap *cp;
+   E_Client *ec;
+   Pol_Wl_Surface *psurf;
 
-   /* get the pixmap from this surface so we can find the client */
-   if (!(cp = wl_resource_get_user_data(surface)))
-     {
-        wl_resource_post_error(surface,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Pixmap Set On Surface");
-        return;
-     }
+   cp = wl_resource_get_user_data(surf);
+   EINA_SAFETY_ON_NULL_RETURN(cp);
+
+   psurf = _pol_wl_surf_get(cp);
+   if (psurf)
+     VALIDATION(psurf, tzpol);
+   else
+     psurf = _pol_wl_surf_add(cp, tzpol);
+   EINA_SAFETY_ON_NULL_RETURN(psurf);
 
-   /* find the client for this pixmap */
    ec = e_pixmap_client_get(cp);
    if (ec)
      {
-        /* remove not processed level set */
-        nl = eina_hash_find(hash_notification_levels, &surface);
-        if (nl)
-          {
-             PLOGF("NOTI",
-                   "HASH_DEL1|s:0x%08x|nl:0x%08x",
-                   cp, ec, (unsigned int)surface,
-                   (unsigned int)nl);
+        e_mod_pol_notification_level_apply(ec, lv);
 
-             eina_hash_del_by_key(hash_notification_levels, &surface);
-          }
-
-        e_mod_pol_notification_level_apply(ec, level);
+        PLOGF("TZPOL",
+              "NOTISEND1|s:0x%08x|tzpol:0x%08x|psurf:0x%08x|lv%d",
+              cp, ec, (unsigned int)surf, (unsigned int)tzpol,
+              (unsigned int)psurf, lv);
 
-        PLOGF("NOTI",
-              "SEND1    |s:0x%08x|lv%d",
-              cp, ec, (unsigned int)surface,
-              (unsigned int)level);
+        tizen_policy_send_notification_done
+           (tzpol, surf, lv,
+            TIZEN_POLICY_ERROR_STATE_NONE);
 
-        /* Add other error handling code on notification send done. */
-        tizen_policy_send_notification_done(resource,
-                                            surface,
-                                            level,
-                                            TIZEN_POLICY_ERROR_STATE_NONE);
+        psurf->pending_notilv = EINA_FALSE;
      }
    else
      {
-        nl = eina_hash_find(hash_notification_levels, &surface);
-        if (!nl)
+        PLOGF("TZPOL",
+              "NOTIPEND |s:0x%08x|tzpol:0x%08x|psurf:0x%08x|lv%d",
+              cp, ec, (unsigned int)surf, (unsigned int)tzpol,
+              (unsigned int)psurf, lv);
+
+        psurf->pending_notilv = EINA_TRUE;
+        psurf->notilv = lv;
+     }
+}
+
+void
+e_mod_pol_wl_notification_level_fetch(E_Client *ec)
+{
+   E_Pixmap *cp;
+   Pol_Wl_Surface *psurf;
+   struct wl_resource *res;
+   Eina_List *l;
+   Eina_Bool found;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   cp = ec->pixmap;
+   EINA_SAFETY_ON_NULL_RETURN(cp);
+
+   psurf = _pol_wl_surf_get(cp);
+   if (!psurf) return;
+
+   if (!psurf->pending_notilv) return;
+
+   psurf->pending_notilv = EINA_FALSE;
+
+   e_mod_pol_notification_level_apply(ec, psurf->notilv);
+
+   PLOGF("TZPOL",
+         "NOTISEND2|s:0x%08x|tzpol:0x%08x|ps:0x%08x|lv%d",
+         ec->pixmap, ec, (unsigned int)psurf->surf,
+         (unsigned int)psurf->tzpol, (unsigned int)psurf,
+         psurf->notilv);
+
+   found = EINA_FALSE;
+   EINA_LIST_FOREACH(polwl->resources, l, res)
+     {
+        if (res == psurf->tzpol)
+          {
+             found = EINA_TRUE;
+             break;
+          }
+     }
+
+   if (!found)
+     {
+        PLOGF("TZPOL",
+              "NOTI ERR |s:0x%08x|tzpol:0x%08x|ps:0x%08x",
+              psurf->cp, psurf->ec,
+              psurf->surf, psurf->tzpol, psurf);
+        return;
+     }
+
+   tizen_policy_send_notification_done
+      (psurf->tzpol, psurf->surf, psurf->notilv,
+       TIZEN_POLICY_ERROR_STATE_NONE);
+}
+
+// --------------------------------------------------------
+// transient for
+// --------------------------------------------------------
+static void
+_pol_wl_parent_surf_set(E_Client *ec, struct wl_resource *parent_surf)
+{
+   E_Pixmap *pp;
+   E_Client *pc = NULL;
+   Ecore_Window pwin = 0;
+
+   if (parent_surf)
+     {
+        if (!(pp = wl_resource_get_user_data(parent_surf)))
           {
-             nl = E_NEW(Notification_Level, 1);
-             EINA_SAFETY_ON_NULL_RETURN(nl);
-             eina_hash_add(hash_notification_levels, &surface, nl);
+             ERR("Could not get parent res pixmap");
+             return;
+          }
 
-             PLOGF("NOTI",
-                   "HASH_ADD |s:0x%08x|nl:0x%08x|lv%d",
-                   cp, ec, (unsigned int)surface,
-                   (unsigned int)nl, level);
-           }
-         else
-           {
-             PLOGF("NOTI",
-                   "         |s:0x%08x|nl:0x%08x|lv%d",
-                   cp, ec, (unsigned int)surface,
-                   (unsigned int)nl, level);
-           }
+        pwin = e_pixmap_window_get(pp);
 
-         nl->level = level;
-         nl->interface = resource;
-         nl->surface = surface;
+        /* find the parent client */
+        if (!(pc = e_pixmap_client_get(pp)))
+          pc = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pwin);
      }
+
+   e_mod_pol_stack_transient_for_set(ec, pc);
 }
 
 static void
-_e_tizen_policy_cb_transient_for_set(struct wl_client *client, struct wl_resource *resource, uint32_t child_id, uint32_t parent_id)
+_tzpol_iface_cb_transient_for_set(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol, uint32_t child_id, uint32_t parent_id)
 {
    E_Client *ec, *pc;
-   struct wl_resource *parent_res;
+   struct wl_resource *parent_surf;
 
-   DBG("chid_id: %" PRIu32 ", parent_id: %" PRIu32, child_id, parent_id);
+   PLOGF("TZPOL",
+         "TF_SET   |tzpol:0x%08x|parent:%d|child:%d",
+         NULL, NULL, (unsigned int)tzpol, parent_id, child_id);
 
    ec = e_pixmap_find_client_by_res_id(child_id);
    EINA_SAFETY_ON_NULL_RETURN(ec);
@@ -578,85 +832,83 @@ _e_tizen_policy_cb_transient_for_set(struct wl_client *client, struct wl_resourc
    EINA_SAFETY_ON_NULL_RETURN(pc);
    EINA_SAFETY_ON_NULL_RETURN(pc->comp_data);
 
-   parent_res = pc->comp_data->surface;
-   _pol_surface_parent_set(ec, parent_res);
-   tizen_policy_send_transient_for_done(resource, child_id);
+   parent_surf = pc->comp_data->surf;
+
+   _pol_wl_parent_surf_set(ec, parent_surf);
+
+   PLOGF("TZPOL",
+         "         |parent|s:0x%08x",
+         pc->pixmap, pc, (unsigned int)parent_surf);
+
+   PLOGF("TZPOL",
+         "         |child |s:0x%08x",
+         ec->pixmap, ec,
+         (unsigned int)(ec->comp_data ? ec->comp_data->surf : NULL));
+
+   tizen_policy_send_transient_for_done(tzpol, child_id);
 
    EC_CHANGED(ec);
 }
 
 static void
-_e_tizen_policy_cb_transient_for_unset(struct wl_client *client, struct wl_resource *resource, uint32_t child_id)
+_tzpol_iface_cb_transient_for_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol, uint32_t child_id)
 {
    E_Client *ec;
 
-   DBG("chid_id: %" PRIu32, child_id);
+   PLOGF("TZPOL",
+         "TF_UNSET |tzpol:0x%08x|child:%d",
+         NULL, NULL, (unsigned int)tzpol, child_id);
 
    ec = e_pixmap_find_client_by_res_id(child_id);
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   _pol_surface_parent_set(ec, NULL);
-   tizen_policy_send_transient_for_done(resource, child_id);
+   _pol_wl_parent_surf_set(ec, NULL);
+
+   tizen_policy_send_transient_for_done(tzpol, child_id);
 
    EC_CHANGED(ec);
 }
 
+// --------------------------------------------------------
+// window screen mode
+// --------------------------------------------------------
 static void
-_e_tizen_policy_cb_window_screen_mode_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t mode)
+_tzpol_iface_cb_win_scrmode_set(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol, struct wl_resource *surf, uint32_t mode)
 {
    E_Pixmap *cp;
-   Window_Screen_Mode *wsm;
-
-   /* get the pixmap from this surface so we can find the client */
-   if (!(cp = wl_resource_get_user_data(surface)))
-     {
-        wl_resource_post_error(surface,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Pixmap Set On Surface");
-        return;
-     }
 
-   wsm = eina_hash_find(hash_window_screen_modes, &surface);
-   if (!wsm)
-     {
-        wsm = E_NEW(Window_Screen_Mode, 1);
-        EINA_SAFETY_ON_NULL_RETURN(wsm);
-        eina_hash_add(hash_window_screen_modes, &surface, wsm);
-        _window_screen_modes = eina_list_append(_window_screen_modes, wsm);
-     }
-
-   wsm->mode = mode;
-   wsm->surface = surface;
-   wsm->interface = resource;
+   cp = wl_resource_get_user_data(surf);
+   EINA_SAFETY_ON_NULL_RETURN(cp);
 
    e_mod_pol_wl_win_scrmode_apply();
 
-   /* Add other error handling code on window_screen send done. */
-   tizen_policy_send_window_screen_mode_done(resource, surface, mode, TIZEN_POLICY_ERROR_STATE_NONE);
+   tizen_policy_send_window_screen_mode_done
+      (tzpol, surf, mode, TIZEN_POLICY_ERROR_STATE_NONE);
+}
+
+void
+e_mod_pol_wl_win_scrmode_apply(void)
+{
+   // TODO: update screen mode for ec which was changed to be visible
+   ;
 }
 
+// --------------------------------------------------------
+// subsurface
+// --------------------------------------------------------
 static void
-_e_tizen_policy_cb_subsurface_place_below_parent(struct wl_client *client, struct wl_resource *resource, struct wl_resource *subsurface)
+_tzpol_iface_cb_subsurf_place_below_parent(struct wl_client *client EINA_UNUSED, struct wl_resource *tzpol EINA_UNUSED, struct wl_resource *subsurf)
 {
    E_Client *ec;
    E_Client *epc;
    E_Comp_Wl_Subsurf_Data *sdata;
 
-   /* try to get the client from resource data */
-   if (!(ec = wl_resource_get_user_data(subsurface)))
-     {
-        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Invalid subsurface");
-        return;
-     }
+   ec = wl_resource_get_user_data(subsurf);
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+   EINA_SAFETY_ON_NULL_RETURN(ec->comp_data);
 
    sdata = ec->comp_data->sub.data;
-   if (!sdata)
-     {
-        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Not subsurface");
-        return;
-     }
+   EINA_SAFETY_ON_NULL_RETURN(sdata);
 
    epc = sdata->parent;
    EINA_SAFETY_ON_NULL_RETURN(epc);
@@ -670,295 +922,146 @@ _e_tizen_policy_cb_subsurface_place_below_parent(struct wl_client *client, struc
    epc->comp_data->sub.list_changed = EINA_TRUE;
 }
 
-static const struct tizen_policy_interface _e_tizen_policy_interface =
-{
-   _e_tizen_policy_cb_visibility_get,
-   _e_tizen_policy_cb_position_get,
-   _e_tizen_policy_cb_activate,
-   _e_tizen_policy_cb_raise,
-   _e_tizen_policy_cb_lower,
-   _e_tizen_policy_cb_focus_skip_set,
-   _e_tizen_policy_cb_focus_skip_unset,
-   _e_tizen_policy_cb_role_set,
-   _e_tizen_policy_cb_conformant_set,
-   _e_tizen_policy_cb_conformant_unset,
-   _e_tizen_policy_cb_conformant_get,
-   _e_tizen_policy_cb_notification_level_set,
-   _e_tizen_policy_cb_transient_for_set,
-   _e_tizen_policy_cb_transient_for_unset,
-   _e_tizen_policy_cb_window_screen_mode_set,
-   _e_tizen_policy_cb_subsurface_place_below_parent,
+
+static const struct tizen_policy_interface _tzpol_iface =
+{
+   _tzpol_iface_cb_vis_get,
+   _tzpol_iface_cb_pos_get,
+   _tzpol_iface_cb_activate,
+   _tzpol_iface_cb_raise,
+   _tzpol_iface_cb_lower,
+   _tzpol_iface_cb_focus_skip_set,
+   _tzpol_iface_cb_focus_skip_unset,
+   _tzpol_iface_cb_role_set,
+   _tzpol_iface_cb_conformant_set,
+   _tzpol_iface_cb_conformant_unset,
+   _tzpol_iface_cb_conformant_get,
+   _tzpol_iface_cb_notilv_set,
+   _tzpol_iface_cb_transient_for_set,
+   _tzpol_iface_cb_transient_for_unset,
+   _tzpol_iface_cb_win_scrmode_set,
+   _tzpol_iface_cb_subsurf_place_below_parent
 };
 
 static void
-_e_tizen_policy_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+_tzpol_cb_unbind(struct wl_resource *res)
 {
-   E_Comp_Data *cdata;
-   struct wl_resource *res;
+   struct wl_client *client;
+   pid_t pid = 0;
+   uid_t uid = 0;
+   gid_t gid = 0;
 
-   if (!(cdata = data))
-     {
-        wl_client_post_no_memory(client);
-        return;
-     }
+   if (!polwl) return;
+   if (!polwl->resources) return;
 
-   if (!(res = wl_resource_create(client, &tizen_policy_interface, version, id)))
-     {
-        ERR("Could not create scaler resource: %m");
-        wl_client_post_no_memory(client);
-        return;
-     }
+   client = wl_resource_get_client(res);
+   if (client) wl_client_get_credentials(client, &pid, &uid, &gid);
 
-   wl_resource_set_implementation(res, &_e_tizen_policy_interface, cdata, NULL);
-}
+   PLOGF("TZPOL",
+         "UNBIND   |tzpol:0x%08x|client:0x%08x|%d|%d|%d",
+         NULL, NULL,
+         (unsigned int)res,
+         (unsigned int)client,
+         pid, uid, gid);
 
-void
-e_mod_pol_wl_win_scrmode_apply(void)
-{
-   // TODO: update screen mode for ec which was changed to be visible
-   ;
+   polwl->resources = eina_list_remove(polwl->resources, res);
 }
 
-Eina_Bool
-e_mod_pol_wl_init(void)
+static void
+_tzpol_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
 {
-   E_Comp_Data *cdata;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
+   struct wl_resource *res;
+   pid_t pid = 0;
+   uid_t uid = 0;
+   gid_t gid = 0;
 
-   cdata = e_comp->wl_comp_data;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cdata, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cdata->wl.disp, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_GOTO(polwl, err);
 
-   if (!wl_global_create(cdata->wl.disp,
-                         &tizen_policy_interface,
-                         1,
-                         cdata,
-                         _e_tizen_policy_cb_bind))
+   if (!(res = wl_resource_create(client,
+                                  &tizen_policy_interface,
+                                  ver,
+                                  id)))
      {
-        ERR("Could not add tizen_policy to wayland globals: %m");
-        return EINA_FALSE;
+        goto err;
      }
 
-   hash_pol_wayland = eina_hash_pointer_new(free);
-   hash_notification_levels = eina_hash_pointer_new(free);
-   hash_policy_conformants = eina_hash_pointer_new(free);
-   hash_window_screen_modes = eina_hash_pointer_new(free);
+   wl_resource_set_implementation(res,
+                                  &_tzpol_iface,
+                                  NULL,
+                                  _tzpol_cb_unbind);
 
-   return EINA_TRUE;
-}
+   polwl->resources = eina_list_append(polwl->resources, res);
 
-void
-e_mod_pol_wl_shutdown(void)
-{
-   E_FREE_FUNC(hash_pol_wayland, eina_hash_free);
-   E_FREE_FUNC(hash_notification_levels, eina_hash_free);
-   E_FREE_FUNC(hash_policy_conformants, eina_hash_free);
+   wl_client_get_credentials(client, &pid, &uid, &gid);
 
-   eina_list_free(_window_screen_modes);
-   E_FREE_FUNC(hash_window_screen_modes, eina_hash_free);
+   PLOGF("TZPOL",
+         "BIND     |tzpol:0x%08x|client:0x%08x|%d|%d|%d",
+         NULL, NULL,
+         (unsigned int)res,
+         (unsigned int)client,
+         pid, uid, gid);
+
+   _pol_wl_pname_print(pid);
+   return;
+
+err:
+   ERR("Could not create tizen_policy_interface res: %m");
+   wl_client_post_no_memory(client);
 }
 
 void
 e_mod_pol_wl_client_del(E_Client *ec)
 {
-   Pol_Wayland *pn;
-   E_Comp_Client_Data *cdata = NULL;
-   struct wl_resource *surface = NULL;
-
    EINA_SAFETY_ON_NULL_RETURN(ec);
-   EINA_SAFETY_ON_NULL_RETURN(hash_pol_wayland);
-
    if (!ec->pixmap) return;
 
-   pn = eina_hash_find(hash_pol_wayland, &ec->pixmap);
-   if (!pn) return;
-
-   cdata = e_pixmap_cdata_get(ec->pixmap);
-   if (cdata)
-     surface = cdata->wl_surface;
-
-   PLOGF("POL",
-         "HASH_DEL1|s:0x%08x|pn:0x%08x",
-         ec->pixmap, ec, (unsigned int)surface,
-         (unsigned int)pn);
-
-   eina_hash_del_by_key(hash_pol_wayland, &ec->pixmap);
+   e_mod_pol_wl_pixmap_del(ec->pixmap);
 }
 
 void
 e_mod_pol_wl_pixmap_del(E_Pixmap *cp)
 {
-   E_Comp_Client_Data *cdata = NULL;
-   struct wl_resource *surface = NULL;
-   Notification_Level *nl;
-   Pol_Wayland *pn;
-   Policy_Conformant *pc;
-   Window_Screen_Mode *wsm;
-
-   cdata = e_pixmap_cdata_get(cp);
-   if (cdata)
-     surface = cdata->wl_surface;
-
-   PLOGF("POL",
-         "SURF_DEL |s:0x%08x|cdata:0x%08x",
-         cp, e_pixmap_client_get(cp),
-         (unsigned int)surface, (unsigned int)cdata);
-
-   if (surface)
-     {
-        nl = eina_hash_find(hash_notification_levels, &surface);
-        if (nl)
-          {
-             PLOGF("NOTI",
-                   "HASH_DEL2|s:0x%08x|nl:0x%08x",
-                   cp, e_pixmap_client_get(cp),
-                   (unsigned int)surface, (unsigned int)nl);
-
-             eina_hash_del_by_key(hash_notification_levels, &surface);
-          }
-     }
-
-   pn = eina_hash_find(hash_pol_wayland, &cp);
-   if (pn)
-     {
-        PLOGF("POL",
-              "HASH_DEL2|s:0x%08x|pn:0x%08x",
-              cp, e_pixmap_client_get(cp),
-              (unsigned int)surface, (unsigned int)pn);
-
-        eina_hash_del_by_key(hash_pol_wayland, &cp);
-     }
-
-   if (surface)
-     {
-        pc = eina_hash_find(hash_policy_conformants, &surface);
-        if (pc)
-          eina_hash_del_by_key(hash_policy_conformants, &surface);
-     }
-
-   if (surface)
-     {
-        wsm = eina_hash_find(hash_window_screen_modes, &surface);
-        if (wsm)
-          {
-             _window_screen_modes = eina_list_remove(_window_screen_modes, wsm);
-             eina_hash_del_by_key(hash_window_screen_modes, &surface);
-          }
-     }
-}
-
-void
-e_mod_pol_wl_visibility_send(E_Client *ec, int visibility)
-{
-   Pol_Wayland *pn;
-   Eina_List *l;
-   struct wl_resource *resource;
-
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-   EINA_SAFETY_ON_NULL_RETURN(ec->pixmap);
-   EINA_SAFETY_ON_NULL_RETURN(hash_pol_wayland);
+   Pol_Wl_Surface *psurf = NULL;
 
-   pn = eina_hash_find(hash_pol_wayland, &ec->pixmap);
-   if (!pn) return;
-
-   EINA_LIST_FOREACH(pn->visibility_list, l, resource)
-     {
-        tizen_visibility_send_notify(resource, visibility);
-     }
+   psurf = eina_hash_find(polwl->surfaces, &cp);
+   if (psurf)
+     eina_hash_del_by_key(polwl->surfaces, &cp);
 }
 
-void
-e_mod_pol_wl_position_send(E_Client *ec)
+Eina_Bool
+e_mod_pol_wl_init(void)
 {
-   Pol_Wayland *pn;
-   Eina_List *l;
-   struct wl_resource *resource;
+   E_Comp_Data *cdata;
 
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-   EINA_SAFETY_ON_NULL_RETURN(ec->pixmap);
-   EINA_SAFETY_ON_NULL_RETURN(hash_pol_wayland);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
 
-   pn = eina_hash_find(hash_pol_wayland, &ec->pixmap);
-   if (!pn) return;
+   cdata = e_comp->wl_comp_data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cdata, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cdata->wl.disp, EINA_FALSE);
 
-   EINA_LIST_FOREACH(pn->position_list, l, resource)
+   if (!wl_global_create(cdata->wl.disp,
+                         &tizen_policy_interface,
+                         1,
+                         NULL,
+                         _tzpol_cb_bind))
      {
-        tizen_position_send_changed(resource, ec->x, ec->y);
+        ERR("Could not add tizen_policy to wayland globals: %m");
+        return EINA_FALSE;
      }
-}
-
-void
-e_mod_pol_wl_notification_level_fetch(E_Client *ec)
-{
-   Notification_Level *nl;
-   E_Comp_Client_Data *cdata;
-   struct wl_resource *surface;
 
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-   cdata = e_pixmap_cdata_get(ec->pixmap);
-   EINA_SAFETY_ON_NULL_RETURN(cdata);
-   surface = cdata->wl_surface;
-   EINA_SAFETY_ON_NULL_RETURN(surface);
-
-   nl = eina_hash_find(hash_notification_levels, &surface);
-   if (nl)
-     {
-        e_mod_pol_notification_level_apply(ec, nl->level);
+   polwl = E_NEW(Pol_Wl, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(polwl, EINA_FALSE);
 
-        PLOGF("NOTI",
-              "SEND2    |s:0x%08x|nl:0x%08x|lv%d",
-              ec->pixmap, ec, (unsigned int)surface,
-              (unsigned int)nl, nl->level);
+   polwl->surfaces = eina_hash_pointer_new(_pol_wl_surf_del);
 
-        // Add other error handling code on notification send done.
-        tizen_policy_send_notification_done(nl->interface,
-                                            nl->surface,
-                                            nl->level,
-                                            TIZEN_POLICY_ERROR_STATE_NONE);
-
-        PLOGF("NOTI",
-              "HASH_DEL3|s:0x%08x|nl:0x%08x",
-              ec->pixmap, ec, (unsigned int)surface,
-              (unsigned int)nl);
-
-        eina_hash_del_by_key(hash_notification_levels, &surface);
-     }
+   return EINA_TRUE;
 }
 
 void
-e_mod_pol_wl_keyboard_geom_broadcast(E_Client *ec)
+e_mod_pol_wl_shutdown(void)
 {
-   E_Client *ec2;
-   E_Comp_Client_Data *cdata;
-   struct wl_resource *surface;
-   Policy_Conformant *pn;
-   Eina_Bool res;
-
-   E_CLIENT_REVERSE_FOREACH(e_comp, ec2)
-     {
-        res = e_client_util_ignored_get(ec2);
-        if (res) continue;
-
-        res = e_mod_pol_client_is_conformant(ec2);
-        if (!res) continue;
-
-        cdata = e_pixmap_cdata_get(ec2->pixmap);
-        if (!cdata) continue;
+   EINA_SAFETY_ON_NULL_RETURN(polwl);
 
-        surface = cdata->wl_surface;
-        if (!surface) continue;
-
-        pn = eina_hash_find(hash_policy_conformants, &surface);
-        if (!pn) continue;
-
-        tizen_policy_send_conformant_area(pn->interface,
-                                          pn->surface,
-                                          TIZEN_POLICY_CONFORMANT_PART_KEYBOARD,
-                                          ec->visible,
-                                          ec->x,
-                                          ec->y,
-                                          ec->client.w,
-                                          ec->client.h);
-     }
+   E_FREE_FUNC(polwl->surfaces, eina_hash_free);
+   E_FREE(polwl);
 }