discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=00690dab17f1e1e8bd28e7579908ae422593ff8e

commit 00690dab17f1e1e8bd28e7579908ae422593ff8e
Author: Gwanglim Lee <gl77....@samsung.com>
Date:   Fri Aug 29 13:48:01 2014 -0400

    added mobile policy module
    
    Summary: mobile policy module provides user interface for small mobile 
devices like phones.
    
    Test Plan: N/A
    
    Reviewers: raster, devilhorns, zmike
    
    Subscribers: seoz, zmike, cedric
    
    Differential Revision: https://phab.enlightenment.org/D817
---
 configure.ac                                       |   1 +
 src/bin/e_module.c                                 |   1 +
 src/modules/Makefile.mk                            |   2 +
 src/modules/Makefile_policy_mobile.mk              |  21 +
 .../policy_mobile/e-module-policy-mobile.edj       | Bin 0 -> 17246 bytes
 src/modules/policy_mobile/e_mod_config.c           | 387 ++++++++++++
 src/modules/policy_mobile/e_mod_main.c             | 646 +++++++++++++++++++++
 src/modules/policy_mobile/e_mod_main.h             | 108 ++++
 src/modules/policy_mobile/e_mod_softkey.c          | 171 ++++++
 9 files changed, 1337 insertions(+)

diff --git a/configure.ac b/configure.ac
index c1ceca6..f807de6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -971,6 +971,7 @@ AC_E_OPTIONAL_MODULE([wl_x11], $have_wayland, $wl_x11)
 AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB])
 AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM])
 #AC_E_OPTIONAL_MODULE([wl_screenshot], true, [CHECK_MODULE_WL_SCREENSHOT])
+AC_E_OPTIONAL_MODULE([policy_mobile], true)
 
 HALT="/sbin/shutdown -h now"
 REBOOT="/sbin/shutdown -r now"
diff --git a/src/bin/e_module.c b/src/bin/e_module.c
index a864ef8..49b4adc 100644
--- a/src/bin/e_module.c
+++ b/src/bin/e_module.c
@@ -938,6 +938,7 @@ _e_module_whitelist_check(void)
       "music-control",
       "appmenu",
       "packagekit",
+      "policy_mobile",
       NULL   // end marker
    };
 
diff --git a/src/modules/Makefile.mk b/src/modules/Makefile.mk
index bc2d693..5b6bf8b 100644
--- a/src/modules/Makefile.mk
+++ b/src/modules/Makefile.mk
@@ -130,3 +130,5 @@ include src/modules/Makefile_wl_fb.mk
 
 #if HAVE_WAYLAND_SCREENSHOT
 #include src/modules/Makefile_wl_screenshot.mk
+
+include src/modules/Makefile_policy_mobile.mk
diff --git a/src/modules/Makefile_policy_mobile.mk 
b/src/modules/Makefile_policy_mobile.mk
new file mode 100644
index 0000000..59ca422
--- /dev/null
+++ b/src/modules/Makefile_policy_mobile.mk
@@ -0,0 +1,21 @@
+EXTRA_DIST += src/modules/policy_mobile/e-module-policy-mobile.edj
+if USE_MODULE_POLICY_MOBILE
+policy_mobiledir = $(MDIR)/policy_mobile
+policy_mobile_DATA = src/modules/policy_mobile/e-module-policy-mobile.edj
+
+policy_mobilepkgdir = $(MDIR)/policy_mobile/$(MODULE_ARCH)
+policy_mobilepkg_LTLIBRARIES = src/modules/policy_mobile/module.la
+
+src_modules_policy_mobile_module_la_LIBADD = $(MOD_LIBS)
+src_modules_policy_mobile_module_la_CPPFLAGS = $(MOD_CPPFLAGS)
+src_modules_policy_mobile_module_la_LDFLAGS = $(MOD_LDFLAGS)
+src_modules_policy_mobile_module_la_SOURCES = \
+src/modules/policy_mobile/e_mod_main.h \
+src/modules/policy_mobile/e_mod_config.c \
+src/modules/policy_mobile/e_mod_softkey.c \
+src/modules/policy_mobile/e_mod_main.c
+
+PHONIES += policy_mobile install-policy_mobile
+policy_mobile: $(policy_mobilepkg_LTLIBRARIES) $(policy_mobile_DATA)
+install-policy_mobile: install-policy_mobileDATA 
install-policy_mobilepkgLTLIBRARIES
+endif
diff --git a/src/modules/policy_mobile/e-module-policy-mobile.edj 
b/src/modules/policy_mobile/e-module-policy-mobile.edj
new file mode 100644
index 0000000..1a1c81c
Binary files /dev/null and 
b/src/modules/policy_mobile/e-module-policy-mobile.edj differ
diff --git a/src/modules/policy_mobile/e_mod_config.c 
b/src/modules/policy_mobile/e_mod_config.c
new file mode 100644
index 0000000..6df66f0
--- /dev/null
+++ b/src/modules/policy_mobile/e_mod_config.c
@@ -0,0 +1,387 @@
+#include "e_mod_main.h"
+
+static void         _pol_conf_desk_add(Config *conf, E_Desk *desk);
+static void         _pol_conf_desk_del(Config *conf, Config_Desk *d);
+static Config_Desk *_pol_conf_desk_get(Config *conf, Config_Desk *d);
+
+static void        *_pol_cfd_data_create(E_Config_Dialog *cfd);
+static void         _pol_cfd_data_free(E_Config_Dialog *cfd EINA_UNUSED, 
E_Config_Dialog_Data *cfdata);
+static int          _pol_cfd_data_basic_apply(E_Config_Dialog *cfd 
EINA_UNUSED, E_Config_Dialog_Data *cfdata);
+static void         _pol_cfd_desk_list_update(E_Config_Dialog_Data *cfdata, 
E_Zone *zone);
+static void         _pol_cfd_hook_zone_change(void *data, Evas_Object *obj);
+static Evas_Object *_pol_cfd_data_basic_widgets_create(E_Config_Dialog *cfd 
EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata);
+
+static void
+_pol_conf_desk_add(Config *conf, E_Desk *desk)
+{
+   Config_Desk *d;
+
+   d = E_NEW(Config_Desk, 1);
+   d->comp_num = desk->zone->comp->num;
+   d->zone_num = desk->zone->num;
+   d->x = desk->x;
+   d->y = desk->y;
+   d->enable = 1;
+
+   conf->desks = eina_list_append(conf->desks, d);
+}
+
+static void
+_pol_conf_desk_del(Config *conf, Config_Desk *d)
+{
+   conf->desks = eina_list_remove(conf->desks, d);
+   free(d);
+}
+
+static Config_Desk *
+_pol_conf_desk_get(Config *conf, Config_Desk *d)
+{
+   Eina_List *l;
+   Config_Desk *d2;
+
+   EINA_LIST_FOREACH(conf->desks, l, d2)
+     {
+        if ((d2->comp_num == d->comp_num) &&
+            (d2->zone_num == d->zone_num) &&
+            (d2->x == d->x) && (d2->y == d->y))
+          {
+             return d2;
+          }
+     }
+
+   return NULL;
+}
+
+static void *
+_pol_cfd_data_create(E_Config_Dialog *cfd)
+{
+   E_Config_Dialog_Data *cfdata = NULL;
+
+   cfdata = E_NEW(E_Config_Dialog_Data, 1);
+   cfdata->conf = E_NEW(Config, 1);
+   cfdata->conf->launcher.title = 
eina_stringshare_ref(_pol_mod->conf->launcher.title);
+   cfdata->conf->launcher.clas = 
eina_stringshare_ref(_pol_mod->conf->launcher.clas);
+   cfdata->conf->launcher.type = _pol_mod->conf->launcher.type;
+   cfdata->conf->use_softkey = _pol_mod->conf->use_softkey;
+   cfdata->conf->softkey_size = _pol_mod->conf->softkey_size;
+
+   _pol_mod->conf_dialog = cfd;
+
+   return cfdata;
+}
+
+static void
+_pol_cfd_data_free(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data 
*cfdata)
+{
+   _pol_mod->conf_dialog = NULL;
+   E_FREE_LIST(cfdata->conf->desks, free);
+   eina_stringshare_del(cfdata->conf->launcher.title);
+   eina_stringshare_del(cfdata->conf->launcher.clas);
+   free(cfdata->conf);
+   free(cfdata);
+}
+
+static int
+_pol_cfd_data_basic_apply(E_Config_Dialog *cfd EINA_UNUSED, 
E_Config_Dialog_Data *cfdata)
+{
+   E_Comp *comp;
+   E_Zone *zone;
+   E_Desk *desk;
+   Pol_Softkey *softkey;
+   Pol_Desk *pd;
+   Config_Desk *d, *d2;
+   Eina_Bool changed = EINA_FALSE;
+   const Eina_List *l;
+   Eina_Inlist *il;
+   Eina_Iterator *it;
+
+   if (_pol_mod->conf->use_softkey != cfdata->conf->use_softkey)
+     {
+        _pol_mod->conf->use_softkey = cfdata->conf->use_softkey;
+        if (_pol_mod->conf->use_softkey)
+          {
+             it = eina_hash_iterator_data_new(hash_pol_desks);
+             while (eina_iterator_next(it, (void **)&pd))
+               {
+                  softkey = e_mod_pol_softkey_get(pd->zone);
+                  if (!softkey)
+                    softkey = e_mod_pol_softkey_add(pd->zone);
+                  if (e_desk_current_get(pd->zone) == pd->desk)
+                    e_mod_pol_softkey_show(softkey);
+               }
+             eina_iterator_free(it);
+          }
+        else
+          {
+             EINA_INLIST_FOREACH_SAFE(_pol_mod->softkeys, il, softkey)
+               e_mod_pol_softkey_del(softkey);
+          }
+
+        changed = EINA_TRUE;
+     }
+
+   if (_pol_mod->conf->softkey_size != cfdata->conf->softkey_size)
+     {
+        _pol_mod->conf->softkey_size = cfdata->conf->softkey_size;
+        if (_pol_mod->conf->use_softkey)
+          {
+             EINA_INLIST_FOREACH(_pol_mod->softkeys, softkey)
+               e_mod_pol_softkey_update(softkey);
+          }
+        changed = EINA_TRUE;
+     }
+
+   EINA_LIST_FOREACH(cfdata->conf->desks, l, d)
+     {
+        comp = e_comp_number_get(d->comp_num);
+        zone = e_comp_zone_number_get(comp, d->zone_num);
+        desk = e_desk_at_xy_get(zone, d->x, d->y);
+        if (!desk) continue;
+
+        d2 = _pol_conf_desk_get(_pol_mod->conf, d);
+        if (d2)
+          {
+             /* disable policy for this desktop */
+             if (d2->enable != d->enable)
+               {
+                  pd = eina_hash_find(hash_pol_desks, &desk);
+                  if (pd) e_mod_pol_desk_del(pd);
+                  _pol_conf_desk_del(_pol_mod->conf, d2);
+                  changed = EINA_TRUE;
+               }
+          }
+        else
+          {
+             /* apply policy for all clients in this desk,
+              * and add desk to configuration list and desk hash */
+             if (d->enable)
+               {
+                  e_mod_pol_desk_add(desk);
+                  _pol_conf_desk_add(_pol_mod->conf, desk);
+                  changed = EINA_TRUE;
+               }
+          }
+     }
+
+   if (changed)
+     e_config_save_queue();
+
+   return 1;
+}
+
+static void
+_pol_cfd_desk_list_update(E_Config_Dialog_Data *cfdata, E_Zone *zone)
+{
+   Evas_Object *o, *ch;
+   Evas *evas;
+   E_Desk *desk;
+   Config_Desk *d, *d2;
+   int i, n;
+
+   evas = evas_object_evas_get(cfdata->o_list);
+   evas_object_del(cfdata->o_desks);
+   E_FREE_LIST(cfdata->conf->desks, free);
+
+   o = e_widget_list_add(evas, 1, 0);
+   cfdata->o_desks = o;
+
+   n = zone->desk_y_count * zone->desk_x_count;
+   for (i = 0; i < n; i++)
+     {
+        desk = zone->desks[i];
+
+        d = E_NEW(Config_Desk, 1);
+        d->comp_num = zone->comp->num;
+        d->zone_num = zone->num;
+        d->x = desk->x;
+        d->y = desk->y;
+        d->enable = 0;
+
+        d2 = _pol_conf_desk_get(_pol_mod->conf, d);
+        if (d2)
+          d->enable = d2->enable;
+
+        ch = e_widget_check_add(evas, desk->name, &d->enable);
+        e_widget_list_object_append(o, ch, 1, 1, 0.5);
+
+        cfdata->conf->desks = eina_list_append(cfdata->conf->desks, d);
+     }
+
+   e_widget_list_object_append(cfdata->o_list, o, 1, 1, 0.5);
+}
+
+static void
+_pol_cfd_hook_zone_change(void *data, Evas_Object *obj)
+{
+   E_Config_Dialog_Data *cfdata;
+   E_Zone *zone;
+   int n;
+
+   cfdata = data;
+   n = e_widget_ilist_selected_get(obj);
+   zone = e_widget_ilist_nth_data_get(obj, n);
+   if (zone)
+     _pol_cfd_desk_list_update(cfdata, zone);
+}
+
+static Evas_Object *
+_pol_cfd_data_basic_widgets_create(E_Config_Dialog *cfd EINA_UNUSED, Evas 
*evas, E_Config_Dialog_Data *cfdata)
+{
+   Evas_Object *base, *fl, *lb, *lo, *o;
+   E_Comp *comp;
+   E_Zone *zone;
+   Eina_List *l;
+
+   comp = e_comp_get(NULL);
+
+   base = e_widget_list_add(evas, 0, 0);
+
+   fl = e_widget_framelist_add(evas, _("Softkey"), 0);
+   o = e_widget_check_add(evas, _("Use softkey for navigation among the 
windows"),
+                          &cfdata->conf->use_softkey);
+   e_widget_framelist_object_append(fl, o);
+   o = e_widget_label_add(evas, _("Icon Size"));
+   e_widget_framelist_object_append(fl, o);
+   o = e_widget_slider_add(evas, 1, 0, "%1.0f", 32, 256, 1, 0, NULL,
+                           &(cfdata->conf->softkey_size), 150);
+   e_widget_framelist_object_append(fl, o);
+   e_widget_list_object_append(base, fl, 1, 1, 0.5);
+
+   fl = e_widget_framelist_add(evas, _("Virtual Desktops"), 0);
+   lb = e_widget_label_add(evas, _("Enable mobile policy per desktop"));
+   e_widget_framelist_object_append(fl, lb);
+
+   lo = e_widget_list_add(evas, 0, 1);
+   cfdata->o_list = lo;
+   o = e_widget_ilist_add(evas, 0, 0, NULL);
+   e_widget_ilist_multi_select_set(o, EINA_FALSE);
+   e_widget_size_min_set(o, 100, 100);
+   e_widget_on_change_hook_set(o, _pol_cfd_hook_zone_change, cfdata);
+   EINA_LIST_REVERSE_FOREACH(comp->zones, l, zone)
+     e_widget_ilist_append(o, NULL, zone->name, NULL, zone, NULL);
+   e_widget_ilist_go(o);
+   e_widget_ilist_selected_set(o, 0);
+   e_widget_list_object_append(lo, o, 1, 1, 0.5);
+
+   /* update virtual desktops of first zone */
+   zone = eina_list_data_get(comp->zones);
+   _pol_cfd_desk_list_update(cfdata, zone);
+
+   e_widget_framelist_object_append(fl, lo);
+   e_widget_list_object_append(base, fl, 1, 1, 0.5);
+
+   return base;
+}
+
+void
+e_mod_pol_conf_init(Mod *mod)
+{
+   E_Comp *comp;
+   E_Zone *zone;
+   E_Desk *desk;
+   Config *conf;
+
+   mod->conf_desk_edd = E_CONFIG_DD_NEW("Policy_Mobile_Config_Desk", 
Config_Desk);
+#undef T
+#undef D
+#define T Config_Desk
+#define D mod->conf_desk_edd
+   E_CONFIG_VAL(D, T, comp_num, INT);
+   E_CONFIG_VAL(D, T, zone_num, UINT);
+   E_CONFIG_VAL(D, T, x, INT);
+   E_CONFIG_VAL(D, T, y, INT);
+   E_CONFIG_VAL(D, T, enable, INT);
+
+   mod->conf_edd = E_CONFIG_DD_NEW("Policy_Mobile_Config", Config);
+#undef T
+#undef D
+#define T Config
+#define D mod->conf_edd
+   E_CONFIG_VAL(D, T, launcher.title, STR);
+   E_CONFIG_VAL(D, T, launcher.clas, STR);
+   E_CONFIG_VAL(D, T, launcher.type, UINT);
+   E_CONFIG_LIST(D, T, desks, mod->conf_desk_edd);
+   E_CONFIG_VAL(D, T, use_softkey, INT);
+   E_CONFIG_VAL(D, T, softkey_size, INT);
+
+#undef T
+#undef D
+
+   mod->conf = e_config_domain_load("module.policy-mobile", mod->conf_edd);
+   if (!mod->conf)
+     {
+        conf = E_NEW(Config, 1);
+        mod->conf = conf;
+        conf->launcher.title = eina_stringshare_add("Illume Home");
+        conf->launcher.clas = eina_stringshare_add("Illume-Home");
+        conf->launcher.type = E_WINDOW_TYPE_NORMAL;
+        conf->use_softkey = 1;
+        conf->softkey_size = 42;
+
+        comp = e_comp_get(NULL);
+        zone = e_zone_current_get(comp);
+        desk = e_desk_current_get(zone);
+        _pol_conf_desk_add(conf, desk);
+     }
+}
+
+void
+e_mod_pol_conf_shutdown(Mod *mod)
+{
+   Config *conf;
+
+   if (mod->conf)
+     {
+        conf = mod->conf;
+        E_FREE_LIST(conf->desks, free);
+        eina_stringshare_del(conf->launcher.title);
+        eina_stringshare_del(conf->launcher.clas);
+        free(mod->conf);
+     }
+
+   E_CONFIG_DD_FREE(mod->conf_desk_edd);
+   E_CONFIG_DD_FREE(mod->conf_edd);
+}
+
+Config_Desk *
+e_mod_pol_conf_desk_get_by_nums(Config *conf, unsigned int comp_num, unsigned 
int zone_num, int x, int y)
+{
+   Eina_List *l;
+   Config_Desk *d2;
+
+   EINA_LIST_FOREACH(conf->desks, l, d2)
+     {
+        if ((d2->comp_num == comp_num) &&
+            (d2->zone_num == zone_num) &&
+            (d2->x == x) && (d2->y == y))
+          {
+             return d2;
+          }
+     }
+
+   return NULL;
+}
+
+E_Config_Dialog *
+e_int_config_pol_mobile(E_Comp *comp, const char *params EINA_UNUSED)
+{
+   E_Config_Dialog *cfd;
+   E_Config_Dialog_View *v;
+   char buf[PATH_MAX];
+
+   if (e_config_dialog_find("E", "windows/policy-mobile"))
+     return NULL;
+
+   v = E_NEW(E_Config_Dialog_View, 1);
+   v->create_cfdata = _pol_cfd_data_create;
+   v->free_cfdata = _pol_cfd_data_free;
+   v->basic.apply_cfdata = _pol_cfd_data_basic_apply;
+   v->basic.create_widgets = _pol_cfd_data_basic_widgets_create;
+
+   snprintf(buf, sizeof(buf), "%s/e-module-policy-mobile.edj",
+            e_module_dir_get(_pol_mod->module));
+
+   cfd = e_config_dialog_new(comp, _("Mobile Policy Configuration"), "E",
+                             "windows/policy-mobile", buf, 0, v, NULL);
+   return cfd;
+}
diff --git a/src/modules/policy_mobile/e_mod_main.c 
b/src/modules/policy_mobile/e_mod_main.c
new file mode 100644
index 0000000..2d8b86e
--- /dev/null
+++ b/src/modules/policy_mobile/e_mod_main.c
@@ -0,0 +1,646 @@
+#include "e_mod_main.h"
+
+EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Policy-Mobile" };
+
+Mod *_pol_mod = NULL;
+Eina_Hash *hash_pol_desks = NULL;
+Eina_Hash *hash_pol_clients = NULL;
+
+static Eina_List *handlers = NULL;
+static Eina_List *hooks = NULL;
+
+static Pol_Client *_pol_client_add(E_Client *ec);
+static void        _pol_client_del(Pol_Client *pc);
+static Eina_Bool   _pol_client_normal_check(E_Client *ec);
+static void        _pol_client_update(Pol_Client *pc);
+static void        _pol_client_launcher_set(Pol_Client *pc);
+
+static void        _pol_hook_client_eval_post_fetch(void *d EINA_UNUSED, 
E_Client *ec);
+static void        _pol_hook_client_desk_set(void *d EINA_UNUSED, E_Client 
*ec);
+static void        _pol_cb_desk_data_free(void *data);
+static void        _pol_cb_client_data_free(void *data);
+static Eina_Bool   _pol_cb_zone_add(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event);
+static Eina_Bool   _pol_cb_zone_del(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event);
+static Eina_Bool   _pol_cb_zone_move_resize(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event);
+static Eina_Bool   _pol_cb_zone_desk_count_set(void *data EINA_UNUSED, int 
type EINA_UNUSED, void *event);
+static Eina_Bool   _pol_cb_desk_show(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event);
+static Eina_Bool   _pol_cb_client_remove(void *data EINA_UNUSED, int type, 
void *event);
+
+static void
+_pol_client_launcher_set(Pol_Client *pc)
+{
+   Pol_Client *pc2;
+
+   pc2 = e_mod_pol_client_launcher_get(pc->ec->zone);
+   if (pc2) return;
+
+   if (pc->ec->netwm.type != _pol_mod->conf->launcher.type)
+     return;
+
+   if (e_util_strcmp(pc->ec->icccm.class,
+                     _pol_mod->conf->launcher.clas))
+     return;
+
+
+   if (e_util_strcmp(pc->ec->icccm.title,
+                     _pol_mod->conf->launcher.title))
+     {
+        /* check netwm name instead, because comp_x had ignored
+         * icccm name when fetching */
+        if (e_util_strcmp(pc->ec->netwm.name,
+                          _pol_mod->conf->launcher.title))
+          {
+             return;
+          }
+     }
+
+   _pol_mod->launchers = eina_list_append(_pol_mod->launchers, pc);
+}
+
+static Pol_Client *
+_pol_client_add(E_Client *ec)
+{
+   Pol_Client *pc;
+   Pol_Desk *pd;
+
+   if (e_object_is_del(E_OBJECT(ec))) return NULL;
+   if (!_pol_client_normal_check(ec)) return NULL;
+
+   pc = eina_hash_find(hash_pol_clients, &ec);
+   if (pc) return NULL;
+
+   pd = eina_hash_find(hash_pol_desks, &ec->desk);
+   if (!pd) return NULL;
+
+   pc = E_NEW(Pol_Client, 1);
+   pc->ec = ec;
+
+#undef _SET
+# define _SET(a) pc->orig.a = ec->a
+   _SET(borderless);
+   _SET(fullscreen);
+   _SET(maximized);
+   _SET(lock_user_location);
+   _SET(lock_client_location);
+   _SET(lock_user_size);
+   _SET(lock_client_size);
+   _SET(lock_client_stacking);
+   _SET(lock_user_shade);
+   _SET(lock_client_shade);
+   _SET(lock_user_maximize);
+   _SET(lock_client_maximize);
+#undef _SET
+
+   _pol_client_launcher_set(pc);
+
+   eina_hash_add(hash_pol_clients, &ec, pc);
+
+   _pol_client_update(pc);
+
+   return pc;
+}
+
+static void
+_pol_client_del(Pol_Client *pc)
+{
+   E_Client *ec;
+   Eina_Bool changed = EINA_FALSE;
+
+   ec = pc->ec;
+
+   if (pc->orig.borderless != ec->borderless)
+     {
+        ec->border.changed = 1;
+        changed = EINA_TRUE;
+     }
+
+   if ((pc->orig.fullscreen != ec->fullscreen) &&
+       (pc->orig.fullscreen))
+     {
+        ec->need_fullscreen = 1;
+        changed = EINA_TRUE;
+     }
+
+   if (pc->orig.maximized != ec->maximized)
+     {
+        if (pc->orig.maximized)
+          ec->changes.need_maximize = 1;
+        else
+          ec->changes.need_unmaximize = 1;
+        changed = EINA_TRUE;
+     }
+
+#undef _SET
+# define _SET(a) ec->a = pc->orig.a
+   _SET(borderless);
+   _SET(fullscreen);
+   _SET(maximized);
+   _SET(lock_user_location);
+   _SET(lock_client_location);
+   _SET(lock_user_size);
+   _SET(lock_client_size);
+   _SET(lock_client_stacking);
+   _SET(lock_user_shade);
+   _SET(lock_client_shade);
+   _SET(lock_user_maximize);
+   _SET(lock_client_maximize);
+#undef _SET
+
+   /* only set it if the border is changed or fullscreen/maximize has changed 
*/
+   if (changed)
+     EC_CHANGED(pc->ec);
+
+   _pol_mod->launchers = eina_list_remove(_pol_mod->launchers, pc);
+
+   eina_hash_del_by_key(hash_pol_clients, &pc->ec);
+}
+
+static Eina_Bool
+_pol_client_normal_check(E_Client *ec)
+{
+   if ((e_client_util_ignored_get(ec)) ||
+       (!ec->pixmap))
+     {
+        return EINA_FALSE;
+     }
+
+   if ((ec->netwm.type == E_WINDOW_TYPE_NORMAL) ||
+       (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN))
+     {
+        return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
+
+static void
+_pol_client_update(Pol_Client *pc)
+{
+   E_Client *ec;
+
+   ec = pc->ec;
+
+   if (ec->remember)
+     {
+        e_remember_del(ec->remember);
+        ec->remember = NULL;
+     }
+
+   /* skip hooks of e_remeber for eval_pre_post_fetch and eval_post_new_client 
*/
+   ec->internal_no_remember = 1;
+
+   if (!ec->borderless)
+     {
+        ec->borderless = 1;
+        ec->border.changed = 1;
+        EC_CHANGED(pc->ec);
+     }
+
+   if (!ec->maximized)
+     e_client_maximize(ec, E_MAXIMIZE_EXPAND | E_MAXIMIZE_BOTH);
+
+   /* do not allow client to change these properties */
+   ec->lock_user_location = 1;
+   ec->lock_client_location = 1;
+   ec->lock_user_size = 1;
+   ec->lock_client_size = 1;
+   ec->lock_client_stacking = 1;
+   ec->lock_user_shade = 1;
+   ec->lock_client_shade = 1;
+   ec->lock_user_maximize = 1;
+   ec->lock_client_maximize = 1;
+}
+
+static void
+_pol_hook_client_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec)
+{
+   Pol_Client *pc;
+   Pol_Desk *pd;
+
+   if (e_object_is_del(E_OBJECT(ec))) return;
+   if (!_pol_client_normal_check(ec)) return;
+   if (ec->new_client) return;
+
+   pd = eina_hash_find(hash_pol_desks, &ec->desk);
+   if (!pd) return;
+
+   pc = eina_hash_find(hash_pol_clients, &ec);
+   if (pc)
+     {
+        _pol_client_launcher_set(pc);
+        return;
+     }
+
+   _pol_client_add(ec);
+}
+
+static void
+_pol_hook_client_desk_set(void *d EINA_UNUSED, E_Client *ec)
+{
+   Pol_Client *pc;
+   Pol_Desk *pd;
+
+   if (e_object_is_del(E_OBJECT(ec))) return;
+   if (!_pol_client_normal_check(ec)) return;
+
+   pc = eina_hash_find(hash_pol_clients, &ec);
+   pd = eina_hash_find(hash_pol_desks, &ec->desk);
+
+   if ((!pc) && (pd))
+     _pol_client_add(ec);
+   else if ((pc) && (!pd))
+     _pol_client_del(pc);
+}
+
+static void
+_pol_cb_desk_data_free(void *data)
+{
+   free(data);
+}
+
+static void
+_pol_cb_client_data_free(void *data)
+{
+   free(data);
+}
+
+static Eina_Bool
+_pol_cb_zone_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+   E_Event_Zone_Add *ev;
+   E_Zone *zone;
+   Config_Desk *d;
+   int i, n;
+
+   ev = event;
+   zone = ev->zone;
+   n = zone->desk_y_count * zone->desk_x_count;
+   for (i = 0; i < n; i++)
+     {
+        d = e_mod_pol_conf_desk_get_by_nums(_pol_mod->conf,
+                                            zone->comp->num,
+                                            zone->num,
+                                            zone->desks[i]->x,
+                                            zone->desks[i]->y);
+        if (d)
+          e_mod_pol_desk_add(zone->desks[i]);
+     }
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_pol_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+   E_Event_Zone_Del *ev;
+   E_Zone *zone;
+   Pol_Desk *pd;
+   int i, n;
+
+   ev = event;
+   zone = ev->zone;
+   n = zone->desk_y_count * zone->desk_x_count;
+   for (i = 0; i < n; i++)
+     {
+        pd = eina_hash_find(hash_pol_desks, &zone->desks[i]);
+        if (pd) e_mod_pol_desk_del(pd);
+     }
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_pol_cb_zone_move_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void 
*event)
+{
+   E_Event_Zone_Move_Resize *ev;
+   Pol_Softkey *softkey;
+
+   ev = event;
+
+   if (_pol_mod->conf->use_softkey)
+     {
+        softkey = e_mod_pol_softkey_get(ev->zone);
+        e_mod_pol_softkey_update(softkey);
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_pol_cb_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, void 
*event)
+{
+   E_Event_Zone_Desk_Count_Set *ev;
+   E_Zone *zone;
+   E_Desk *desk;
+   Eina_Iterator *it;
+   Pol_Desk *pd;
+   Config_Desk *d;
+   int i, n;
+   Eina_Bool found;
+   Eina_List *desks_del = NULL;
+
+   ev = event;
+   zone = ev->zone;
+
+   /* remove deleted desk from hash */
+   it = eina_hash_iterator_data_new(hash_pol_desks);
+   while (eina_iterator_next(it, (void **)&pd))
+     {
+        if (pd->zone != zone) continue;
+
+        found = EINA_FALSE;
+        n = zone->desk_y_count * zone->desk_x_count;
+        for (i = 0; i < n; i++)
+          {
+             if (pd->desk == zone->desks[i])
+               {
+                  found = EINA_TRUE;
+                  break;
+               }
+          }
+        if (!found)
+          desks_del = eina_list_append(desks_del, pd->desk);
+     }
+   eina_iterator_free(it);
+
+   EINA_LIST_FREE(desks_del, desk)
+     {
+        pd = eina_hash_find(hash_pol_desks, &desk);
+        if (pd) e_mod_pol_desk_del(pd);
+     }
+
+   /* add newly added desk to hash */
+   n = zone->desk_y_count * zone->desk_x_count;
+   for (i = 0; i < n; i++)
+     {
+        d = e_mod_pol_conf_desk_get_by_nums(_pol_mod->conf,
+                                            zone->comp->num,
+                                            zone->num,
+                                            zone->desks[i]->x,
+                                            zone->desks[i]->y);
+        if (d)
+          e_mod_pol_desk_add(zone->desks[i]);
+     }
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_pol_cb_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+   E_Event_Desk_Show *ev;
+   Pol_Softkey *softkey;
+
+   ev = event;
+
+   if (_pol_mod->conf->use_softkey)
+     {
+        softkey = e_mod_pol_softkey_get(ev->desk->zone);
+        if (eina_hash_find(hash_pol_desks, &ev->desk))
+          e_mod_pol_softkey_show(softkey);
+        else
+          e_mod_pol_softkey_hide(softkey);
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_pol_cb_client_remove(void *data EINA_UNUSED, int type EINA_UNUSED, void 
*event)
+{
+   E_Event_Client *ev;
+   Pol_Client *pc;
+
+   ev = event;
+   pc = eina_hash_find(hash_pol_clients, &ev->ec);
+   if (!pc) return ECORE_CALLBACK_PASS_ON;
+
+   eina_hash_del_by_key(hash_pol_clients, &ev->ec);
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+void
+e_mod_pol_desk_add(E_Desk *desk)
+{
+   Pol_Desk *pd;
+   E_Comp *comp;
+   E_Client *ec;
+   Pol_Softkey *softkey;
+   const Eina_List *l;
+
+   pd = eina_hash_find(hash_pol_desks, &desk);
+   if (pd) return;
+
+   pd = E_NEW(Pol_Desk, 1);
+   pd->desk = desk;
+   pd->zone = desk->zone;
+
+   eina_hash_add(hash_pol_desks, &desk, pd);
+
+   /* add clients */
+   EINA_LIST_FOREACH(e_comp_list(), l, comp)
+     E_CLIENT_FOREACH(comp, ec)
+       {
+          if (pd->desk == ec->desk)
+            _pol_client_add(ec);
+       }
+
+   /* add and show softkey */
+   if (_pol_mod->conf->use_softkey)
+     {
+        softkey = e_mod_pol_softkey_get(desk->zone);
+        if (!softkey)
+          softkey = e_mod_pol_softkey_add(desk->zone);
+        if (e_desk_current_get(desk->zone) == desk)
+          e_mod_pol_softkey_show(softkey);
+     }
+}
+
+void
+e_mod_pol_desk_del(Pol_Desk *pd)
+{
+   Eina_Iterator *it;
+   Pol_Client *pc;
+   E_Client *ec;
+   Eina_List *clients_del = NULL;
+   Pol_Softkey *softkey;
+   Eina_Bool keep = EINA_FALSE;
+   int i, n;
+
+   /* hide and delete softkey */
+   if (_pol_mod->conf->use_softkey)
+     {
+        softkey = e_mod_pol_softkey_get(pd->zone);
+        if (e_desk_current_get(pd->zone) == pd->desk)
+          e_mod_pol_softkey_hide(softkey);
+
+        n = pd->zone->desk_y_count * pd->zone->desk_x_count;
+        for (i = 0; i < n; i++)
+          {
+             if (eina_hash_find(hash_pol_desks, &pd->zone->desks[i]))
+               {
+                  keep = EINA_TRUE;
+                  break;
+               }
+          }
+
+        if (!keep)
+          e_mod_pol_softkey_del(softkey);
+     }
+
+   /* remove clients */
+   it = eina_hash_iterator_data_new(hash_pol_clients);
+   while (eina_iterator_next(it, (void **)&pc))
+     {
+        if (pc->ec->desk == pd->desk)
+          clients_del = eina_list_append(clients_del, pc->ec);
+     }
+   eina_iterator_free(it);
+
+   EINA_LIST_FREE(clients_del, ec)
+     {
+        pc = eina_hash_find(hash_pol_clients, &ec);
+        if (pc) _pol_client_del(pc);
+     }
+
+   eina_hash_del_by_key(hash_pol_desks, &pd->desk);
+}
+
+Pol_Client *
+e_mod_pol_client_launcher_get(E_Zone *zone)
+{
+   Pol_Client *pc;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(_pol_mod->launchers, l, pc)
+     {
+        if (pc->ec->zone == zone)
+          return pc;
+     }
+   return NULL;
+}
+
+#undef E_CLIENT_HOOK_APPEND
+#define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
+  do                                      \
+    {                                     \
+       E_Client_Hook *_h;                 \
+       _h = e_client_hook_add(t, cb, d);  \
+       assert(_h);                        \
+       l = eina_list_append(l, _h);       \
+    }                                     \
+  while (0)
+
+EAPI void *
+e_modapi_init(E_Module *m)
+{
+   Mod *mod;
+   E_Comp *comp;
+   E_Zone *zone;
+   Config_Desk *d;
+   const Eina_List *l, *ll;
+   int i, n;
+   char buf[PATH_MAX];
+
+   mod = E_NEW(Mod, 1);
+   mod->module = m;
+   _pol_mod = mod;
+
+   hash_pol_clients = eina_hash_pointer_new(_pol_cb_client_data_free);
+   hash_pol_desks = eina_hash_pointer_new(_pol_cb_desk_data_free);
+
+   /* initialize configure and config data type */
+   snprintf(buf, sizeof(buf), "%s/e-module-policy-mobile.edj",
+            e_module_dir_get(m));
+
+   e_configure_registry_category_add("windows", 50, _("Windows"), NULL,
+                                     "preferences-system-windows");
+   e_configure_registry_item_add("windows/policy-mobile", 150,
+                                 _("Mobile Policy"), NULL, buf,
+                                 e_int_config_pol_mobile);
+
+   e_mod_pol_conf_init(mod);
+
+   EINA_LIST_FOREACH(e_comp_list(), l, comp)
+     EINA_LIST_FOREACH(comp->zones, ll, zone)
+       {
+          //Eina_Bool home_add = EINA_FALSE;
+          n = zone->desk_y_count * zone->desk_x_count;
+          for (i = 0; i < n; i++)
+            {
+               d = e_mod_pol_conf_desk_get_by_nums(_pol_mod->conf,
+                                                   comp->num,
+                                                   zone->num,
+                                                   zone->desks[i]->x,
+                                                   zone->desks[i]->y);
+               if (d)
+                 {
+                    e_mod_pol_desk_add(zone->desks[i]);
+                    //home_add = EINA_TRUE;
+                 }
+            }
+
+          /* FIXME: should consider the case that illume-home module
+           * is not loaded yet and make it configurable.
+           * and also, this code will be enabled when e_policy stuff lands in 
e.
+           */
+          //if (home_add)
+          //  e_policy_zone_home_add_request(zone);
+       }
+
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _pol_cb_zone_add, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _pol_cb_zone_del, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_MOVE_RESIZE, 
_pol_cb_zone_move_resize, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DESK_COUNT_SET, 
_pol_cb_zone_desk_count_set, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_DESK_SHOW, _pol_cb_desk_show, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_REMOVE, 
_pol_cb_client_remove, NULL);
+
+   E_CLIENT_HOOK_APPEND(hooks, E_CLIENT_HOOK_EVAL_POST_FETCH,
+                        _pol_hook_client_eval_post_fetch, NULL);
+   E_CLIENT_HOOK_APPEND(hooks, E_CLIENT_HOOK_DESK_SET,
+                        _pol_hook_client_desk_set, NULL);
+
+   return mod;
+}
+
+EAPI int
+e_modapi_shutdown(E_Module *m)
+{
+   Mod *mod = m->data;
+   Eina_Inlist *l;
+   Pol_Softkey *softkey;
+
+   eina_list_free(mod->launchers);
+   EINA_INLIST_FOREACH_SAFE(mod->softkeys, l, softkey)
+     e_mod_pol_softkey_del(softkey);
+   E_FREE_LIST(hooks, e_client_hook_del);
+   E_FREE_LIST(handlers, ecore_event_handler_del);
+   E_FREE_FUNC(hash_pol_desks, eina_hash_free);
+   E_FREE_FUNC(hash_pol_clients, eina_hash_free);
+
+   e_configure_registry_item_del("windows/policy-mobile");
+   e_configure_registry_category_del("windows");
+
+   if (mod->conf_dialog)
+     {
+        e_object_del(E_OBJECT(mod->conf_dialog));
+        mod->conf_dialog = NULL;
+     }
+
+   e_mod_pol_conf_shutdown(mod);
+
+   E_FREE(mod);
+
+   _pol_mod = NULL;
+
+   return 1;
+}
+
+EAPI int
+e_modapi_save(E_Module *m)
+{
+   Mod *mod = m->data;
+   e_config_domain_save("module.policy-mobile",
+                        mod->conf_edd,
+                        mod->conf);
+   return 1;
+}
diff --git a/src/modules/policy_mobile/e_mod_main.h 
b/src/modules/policy_mobile/e_mod_main.h
new file mode 100644
index 0000000..3e98508
--- /dev/null
+++ b/src/modules/policy_mobile/e_mod_main.h
@@ -0,0 +1,108 @@
+#ifndef E_MOD_MAIN_H
+#define E_MOD_MAIN_H
+#include <e.h>
+
+typedef struct _Pol_Desk     Pol_Desk;
+typedef struct _Pol_Client   Pol_Client;
+typedef struct _Pol_Softkey  Pol_Softkey;
+typedef struct _Config_Match Config_Match;
+typedef struct _Config_Desk  Config_Desk;
+typedef struct _Config       Config;
+typedef struct _Mod          Mod;
+
+struct _Pol_Desk
+{
+   E_Desk          *desk;
+   E_Zone          *zone;
+};
+
+struct _Pol_Client
+{
+   E_Client        *ec;
+   struct
+   {
+      E_Maximize    maximized;
+      unsigned int  fullscreen : 1;
+      unsigned char borderless : 1;
+      unsigned int  lock_user_location : 1;
+      unsigned int  lock_client_location : 1;
+      unsigned int  lock_user_size : 1;
+      unsigned int  lock_client_size : 1;
+      unsigned int  lock_client_stacking : 1;
+      unsigned int  lock_user_shade : 1;
+      unsigned int  lock_client_shade : 1;
+      unsigned int  lock_user_maximize : 1;
+      unsigned int  lock_client_maximize : 1;
+   } orig;
+};
+
+struct _Pol_Softkey
+{
+   EINA_INLIST;
+
+   E_Zone          *zone;
+   Evas_Object     *home;
+   Evas_Object     *back;
+};
+
+struct _Config_Match
+{
+   const char      *title; /* icccm.title or netwm.name */
+   const char      *clas;  /* icccm.class */
+   unsigned int     type;  /* netwm.type  */
+};
+
+struct _Config_Desk
+{
+   unsigned int     comp_num;
+   unsigned int     zone_num;
+   int              x, y;
+   int              enable;
+};
+
+struct _Config
+{
+   Config_Match     launcher;
+   Eina_List       *desks;
+   int              use_softkey;
+   int              softkey_size;
+};
+
+struct _Mod
+{
+   E_Module        *module;
+   E_Config_DD     *conf_edd;
+   E_Config_DD     *conf_desk_edd;
+   Config          *conf;
+   E_Config_Dialog *conf_dialog;
+   Eina_List       *launchers; /* launcher window per zone */
+   Eina_Inlist     *softkeys; /* softkey ui object per zone */
+};
+
+struct _E_Config_Dialog_Data
+{
+   Config          *conf;
+   Evas_Object     *o_list;
+   Evas_Object     *o_desks;
+};
+
+extern Mod *_pol_mod;
+extern Eina_Hash *hash_pol_desks;
+extern Eina_Hash *hash_pol_clients;
+
+EINTERN void             e_mod_pol_conf_init(Mod *mod);
+EINTERN void             e_mod_pol_conf_shutdown(Mod *mod);
+EINTERN Config_Desk     *e_mod_pol_conf_desk_get_by_nums(Config *conf, 
unsigned int comp_num, unsigned int zone_num, int x, int y);
+EINTERN E_Config_Dialog *e_int_config_pol_mobile(E_Comp *comp, const char 
*params EINA_UNUSED);
+EINTERN void             e_mod_pol_desk_add(E_Desk *desk);
+EINTERN void             e_mod_pol_desk_del(Pol_Desk *pd);
+EINTERN Pol_Client      *e_mod_pol_client_launcher_get(E_Zone *zone);
+
+EINTERN Pol_Softkey     *e_mod_pol_softkey_add(E_Zone *zone);
+EINTERN void             e_mod_pol_softkey_del(Pol_Softkey *softkey);
+EINTERN void             e_mod_pol_softkey_show(Pol_Softkey *softkey);
+EINTERN void             e_mod_pol_softkey_hide(Pol_Softkey *softkey);
+EINTERN void             e_mod_pol_softkey_update(Pol_Softkey *softkey);
+EINTERN Pol_Softkey     *e_mod_pol_softkey_get(E_Zone *zone);
+
+#endif
diff --git a/src/modules/policy_mobile/e_mod_softkey.c 
b/src/modules/policy_mobile/e_mod_softkey.c
new file mode 100644
index 0000000..11bca2f
--- /dev/null
+++ b/src/modules/policy_mobile/e_mod_softkey.c
@@ -0,0 +1,171 @@
+#include "e_mod_main.h"
+
+static void         _pol_cb_softkey(void *data, Evas_Object *obj EINA_UNUSED, 
const char *emission, const char *source EINA_UNUSED);
+static void         _pol_softkey_iconify(E_Zone *zone, Eina_Bool all);
+static Evas_Object *_pol_softkey_icon_add(E_Zone *zone, const char *name);
+static void         _pol_softkey_icon_del(Evas_Object *comp_obj);
+
+static void
+_pol_cb_softkey(void *data, Evas_Object *obj EINA_UNUSED, const char 
*emission, const char *source EINA_UNUSED)
+{
+   E_Zone *zone;
+   Eina_Bool all;
+
+   zone = data;
+
+   if (!e_util_strcmp(emission, "e,action,softkey,home"))
+     all = EINA_TRUE;
+   else if (!e_util_strcmp(emission, "e,action,softkey,back"))
+     all = EINA_FALSE;
+   else
+     return;
+
+   _pol_softkey_iconify(zone, all);
+}
+
+static void
+_pol_softkey_iconify(E_Zone *zone, Eina_Bool all)
+{
+   E_Desk *desk;
+   E_Client *ec;
+   Pol_Client *launcher;
+
+   desk = e_desk_current_get(zone);
+   launcher = e_mod_pol_client_launcher_get(zone);
+
+   E_CLIENT_REVERSE_FOREACH(e_comp_get(desk), ec)
+     {
+        if (e_client_util_ignored_get(ec)) continue;
+        if (!e_client_util_desk_visible(ec, desk)) continue;
+        if (!evas_object_visible_get(ec->frame)) continue;
+
+        if ((launcher) && (launcher->ec == ec))
+          return;
+
+        e_client_iconify(ec);
+
+        if (!all) return;
+     }
+}
+
+static Evas_Object *
+_pol_softkey_icon_add(E_Zone *zone, const char *name)
+{
+   Evas_Object *obj, *comp_obj;
+   char path[PATH_MAX], group[PATH_MAX];
+
+   obj = edje_object_add(e_comp_get(NULL)->evas);
+
+   snprintf(group, sizeof(group), "e/modules/policy-mobile/softkey/%s", name);
+   snprintf(path, sizeof(path), "%s/e-module-policy-mobile.edj",
+            e_module_dir_get(_pol_mod->module));
+
+   if (!e_theme_edje_object_set(obj, NULL, group))
+     edje_object_file_set(obj, path, group);
+
+   edje_object_signal_callback_add(obj, "e,action,softkey,*", "e",
+                                   _pol_cb_softkey, zone);
+
+   /* use TYPE_NONE to disable shadow for softkey object */
+   comp_obj = e_comp_object_util_add(obj, E_COMP_OBJECT_TYPE_NONE);
+   evas_object_layer_set(comp_obj, E_LAYER_POPUP);
+
+   evas_object_data_set(comp_obj, "policy_mobile_obj", obj);
+
+   return comp_obj;
+}
+
+static void
+_pol_softkey_icon_del(Evas_Object *comp_obj)
+{
+   Evas_Object *obj;
+
+   obj = evas_object_data_get(comp_obj, "policy_mobile_obj");
+
+   edje_object_signal_callback_del(obj, "e,action,softkey,*",
+                                   "e", _pol_cb_softkey);
+   evas_object_hide(comp_obj);
+   evas_object_del(comp_obj);
+}
+
+Pol_Softkey *
+e_mod_pol_softkey_add(E_Zone *zone)
+{
+   Pol_Softkey *softkey;
+
+   softkey = E_NEW(Pol_Softkey, 1);
+
+   softkey->zone = zone;
+   softkey->home = _pol_softkey_icon_add(zone, "home");
+   softkey->back = _pol_softkey_icon_add(zone, "back");
+
+   _pol_mod->softkeys = eina_inlist_append(_pol_mod->softkeys, 
EINA_INLIST_GET(softkey));
+
+   return softkey;
+}
+
+void
+e_mod_pol_softkey_del(Pol_Softkey *softkey)
+{
+   if (!softkey) return;
+
+   _pol_softkey_icon_del(softkey->home);
+   _pol_softkey_icon_del(softkey->back);
+
+   _pol_mod->softkeys = eina_inlist_remove(_pol_mod->softkeys, 
EINA_INLIST_GET(softkey));
+
+   free(softkey);
+}
+
+void
+e_mod_pol_softkey_show(Pol_Softkey *softkey)
+{
+   if (!softkey) return;
+
+   e_mod_pol_softkey_update(softkey);
+
+   evas_object_show(softkey->home);
+   evas_object_show(softkey->back);
+}
+
+void
+e_mod_pol_softkey_hide(Pol_Softkey *softkey)
+{
+   if (!softkey) return;
+
+   evas_object_hide(softkey->home);
+   evas_object_hide(softkey->back);
+}
+
+void
+e_mod_pol_softkey_update(Pol_Softkey *softkey)
+{
+   int x, y, w, h, ow, oh, space;
+
+   if (!softkey) return;
+
+   e_zone_useful_geometry_get(softkey->zone, &x, &y, &w, &h);
+
+   ow = oh = _pol_mod->conf->softkey_size;
+
+   x = x + (w - ow) / 2;
+   y = h - oh;
+   space = ow * 4;
+
+   evas_object_geometry_set(softkey->home, x - space, y, ow, oh);
+   evas_object_geometry_set(softkey->back, x + space, y, ow, oh);
+}
+
+Pol_Softkey *
+e_mod_pol_softkey_get(E_Zone *zone)
+{
+   Pol_Softkey *softkey;
+
+   EINA_INLIST_FOREACH(_pol_mod->softkeys, softkey)
+     {
+        if (softkey->zone == zone)
+          return softkey;
+     }
+
+   return NULL;
+}

-- 


Reply via email to