Support for deployment of ivi-home 45/85445/2
authorMinJeong Kim <minjjj.kim@samsung.com>
Thu, 25 Aug 2016 04:27:32 +0000 (13:27 +0900)
committerMinJeong Kim <minjjj.kim@samsung.com>
Thu, 25 Aug 2016 07:32:16 +0000 (16:32 +0900)
Change-Id: Icfaee20096b087d639be1decf7713f2fc3e3b5ee
Signed-off-by: MinJeong Kim <minjjj.kim@samsung.com>
configure.ac
packaging/e-mod-tizen-wm-policy.spec
src/Makefile.am
src/e_mod_ivi_home.c [new file with mode: 0644]
src/e_mod_ivi_home.h [new file with mode: 0644]
src/e_mod_main.c

index 625e18f..bb0e86d 100644 (file)
@@ -67,6 +67,20 @@ if test "x${have_wayland_only}" != "xno"; then
   AC_DEFINE_UNQUOTED([HAVE_WAYLAND],[1],[enable wayland support])
 fi
 
+# IVI-HOME support
+enable_ivi_home=no
+AC_ARG_ENABLE([ivi-home],
+  [AS_HELP_STRING([--enable-ivi-home], [support ivi-home @<:@default=disabled@:>@])],
+  [enable_ivi_home=yes],
+  [enable_ivi_home=no])
+AC_MSG_CHECKING([whether ivi-home is enabled])
+AC_MSG_RESULT([${enable_ivi_home}])
+if test "x${enable_ivi_home}" == "xyes"; then
+  AC_DEFINE_UNQUOTED([ENABLE_IVI_HOME],[1],[enable ivi-home])
+fi
+AM_CONDITIONAL(ENABLE_IVI_HOME, [test "x${enable_ivi_home}" = xyes])
+# end of  IVI_HOME support
+
 #### WM Rotation
 want_auto_rotation=
 have_auto_rotation=
index 7e72211..afbea29 100644 (file)
@@ -33,6 +33,9 @@ The Enlightenment WM Policy Module for Tizen
 export CFLAGS+=" -DE_LOGGING=1 -Werror-implicit-function-declaration"
 %if %{with wayland}
 %reconfigure \
+%if "%{profile}" == "ivi"
+      --enable-ivi-home \
+%endif
       --enable-wayland-only \
       --enable-auto-rotation
 %else
index e2728ae..7b07435 100644 (file)
@@ -11,6 +11,12 @@ pkgdir                 = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH
 pkg_LTLIBRARIES        = module.la
 
 WL_SRC   =
+
+if ENABLE_IVI_HOME
+WL_SRC   += e_mod_ivi_home.c \
+           e_mod_ivi_home.h
+endif
+
 ROT_SRC  = rotation/e_mod_rotation.c \
            rotation/e_mod_rotation.h \
            rotation/e_mod_rotation_settings.c \
diff --git a/src/e_mod_ivi_home.c b/src/e_mod_ivi_home.c
new file mode 100644 (file)
index 0000000..2f6ce93
--- /dev/null
@@ -0,0 +1,345 @@
+#include "e_mod_main.h"
+#include "e_mod_ivi_home.h"
+
+typedef enum
+{
+   IVI_HOME_SIZE_MODE_NONE,
+   IVI_HOME_SIZE_MODE_HALF,
+   IVI_HOME_SIZE_MODE_FULL,
+   IVI_HOME_SIZE_MODE_SMALL,
+} IVI_Home_Size_Mode;
+
+typedef struct
+{
+   E_Client *ec;
+   IVI_Home_Size_Mode ivi_policy_mode;
+   Eina_Bool ivi_policy_state;
+} IVI_Home_Client;
+
+typedef enum
+{
+   IVI_HOME_HINT_SIZE_MODE,
+} IVI_Home_Hint;
+
+static const char *ivi_home_hint_names[] =
+{
+   "wm.policy.ivi.win.size.mode",
+};
+
+static Eina_Hash *hash_clients = NULL;
+static Eina_List *hooks_ec = NULL;
+static E_Client *ivi_clients[2] = {NULL, NULL};
+
+static void
+_ivi_home_policy_pre(IVI_Home_Client *ic, IVI_Home_Size_Mode mode, int slot)
+{
+   E_Client *ec;
+   int zx, zy, zw, zh;
+
+   ec = ic->ec;
+
+   if (ec->desk->visible)
+     e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
+   else
+     {
+        zx = ec->zone->x;
+        zy = ec->zone->y;
+        zw = ec->zone->w;
+        zh = ec->zone->h;
+     }
+
+   ic->ivi_policy_mode = mode;
+   switch (mode)
+     {
+      case IVI_HOME_SIZE_MODE_FULL:
+         if (slot)
+           {
+              ec->x = ec->client.x = zx;
+              ec->y = ec->client.y = zy;
+              ec->w = ec->client.w = zw;
+              ec->h = ec->client.h = zh;
+           }
+         break;;
+      case IVI_HOME_SIZE_MODE_SMALL:
+         if (!!!slot)
+           {
+              ec->x = ec->client.x = zx;
+              ec->y = ec->client.y = zy;
+              ec->w = ec->client.w = zw;
+              ec->h = ec->client.h = zh * 9 / 10;
+           }
+         else
+           {
+              ec->x = ec->client.x = zx;
+              ec->y = ec->client.y = zh - zh / 10;
+              ec->w = ec->client.w = zw;
+              ec->h = ec->client.h = zh / 10;
+           }
+         break;
+      case IVI_HOME_SIZE_MODE_HALF:
+      case IVI_HOME_SIZE_MODE_NONE:
+      default:
+         ic->ivi_policy_mode = IVI_HOME_SIZE_MODE_HALF;
+         if (!!!slot)
+           {
+              ec->x = ec->client.x = zx;
+              ec->y = ec->client.y = zy;
+           }
+         else
+           {
+              ec->x = ec->client.x = zx;
+              ec->y = ec->client.y = zh / 2;
+           }
+         ec->w = ec->client.w = zw;
+         ec->h = ec->client.h = zh / 2;
+     }
+
+   EC_CHANGED(ec);
+}
+
+static void
+_ivi_home_policy_apply(IVI_Home_Client *ic, int slot)
+{
+   E_Client *ec;
+
+   if (!ic) return;
+   if (ic->ivi_policy_state) return;
+
+   ic->ivi_policy_state = EINA_TRUE;
+   ec = ic->ec;
+
+   ivi_clients[slot] = 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(ec);
+     }
+
+   _ivi_home_policy_pre(ic, ic->ivi_policy_mode, slot);
+   evas_object_move(ec->frame, ec->x, ec->y);
+   evas_object_resize(ec->frame, ec->w, ec->h);
+   ec->placed = EINA_TRUE;
+   e_client_visibility_calculate();
+
+   /* 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_user_shade = 1;
+   ec->lock_client_shade = 1;
+   ec->lock_user_maximize = 1;
+   ec->lock_client_maximize = 1;
+   ec->lock_user_fullscreen = 1;
+   ec->lock_client_fullscreen = 1;
+   ec->skip_fullscreen = 1;
+}
+
+static void
+_ivi_home_policy_change(IVI_Home_Client *ic, IVI_Home_Size_Mode mode, int slot)
+{
+   E_Client *ec;
+
+   if (!ic) return;
+   if (!ic->ec) return;
+   if (ic->ivi_policy_mode == mode);
+
+   ec = ic->ec;
+   if (!ic->ivi_policy_state)
+     {
+        _ivi_home_policy_apply(ic, slot);
+        return;
+     }
+
+   _ivi_home_policy_pre(ic, mode, slot);
+   evas_object_move(ec->frame, ec->x, ec->y);
+   evas_object_resize(ec->frame, ec->w, ec->h);
+   ec->placed = EINA_TRUE;
+   e_client_visibility_calculate();
+}
+
+static Eina_Bool
+_ivi_home_client_is_ivi_home(E_Client *ec)
+{
+   E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
+   E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
+
+   if (!e_util_strcmp("ivi-home", ec->icccm.window_role))
+     return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_ivi_home_client_is_ivi_navi(E_Client *ec)
+{
+   E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
+   E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
+
+   if (!e_util_strcmp("ivi-navi", ec->icccm.window_role))
+     return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
+static void
+_ivi_home_size_mode_set(E_Client *ec, IVI_Home_Size_Mode mode)
+{
+   IVI_Home_Client *ic;
+
+   if (!_ivi_home_client_is_ivi_home(ec)) return;
+
+   ic = eina_hash_find(hash_clients, &ec);
+   _ivi_home_policy_change(ic, mode, 1);
+
+   if (ivi_clients[0] && _ivi_home_client_is_ivi_navi(ivi_clients[0]))
+     {
+        ic = eina_hash_find(hash_clients, &ivi_clients[0]);
+        _ivi_home_policy_change(ic, mode, 0);
+     }
+}
+
+static void
+_ivi_home_cb_hook_client_new(void *d EINA_UNUSED, E_Client *ec)
+{
+   IVI_Home_Client *ic;
+
+   if (e_object_is_del(E_OBJECT(ec))) return;
+
+   ic = eina_hash_find(hash_clients, &ec);
+   if (ic) return;
+
+   ic = E_NEW(IVI_Home_Client, 1);
+   ic->ec = ec;
+
+   eina_hash_add(hash_clients, &ec, ic);
+}
+
+static void
+_ivi_home_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
+{
+   if (ivi_clients[0] == ec)
+     ivi_clients[0] = NULL;
+   else if (ivi_clients[1] == ec)
+     ivi_clients[1] = NULL;
+
+   eina_hash_del_by_key(hash_clients, &ec);
+}
+
+static void
+_ivi_home_cb_hook_aux_hint_changed(void *d EINA_UNUSED, E_Client *ec)
+{
+   E_Comp_Wl_Client_Data *cdata;
+   Eina_List *l;
+   E_Comp_Wl_Aux_Hint *hint;
+
+   if (EINA_UNLIKELY(!ec))
+     return;
+
+   cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
+   if (cdata)
+     {
+        EINA_LIST_FOREACH(cdata->aux_hint.hints, l, hint)
+          {
+             if (!strcmp(hint->hint, ivi_home_hint_names[IVI_HOME_HINT_SIZE_MODE]))
+               {
+                  if (hint->deleted)
+                    _ivi_home_size_mode_set(ec, IVI_HOME_SIZE_MODE_NONE);
+                  else if (!strcmp(hint->val, "half"))
+                    _ivi_home_size_mode_set(ec, IVI_HOME_SIZE_MODE_HALF);
+                  else if (!strcmp(hint->val, "full"))
+                    _ivi_home_size_mode_set(ec, IVI_HOME_SIZE_MODE_FULL);
+                  else if (!strcmp(hint->val, "small"))
+                    _ivi_home_size_mode_set(ec, IVI_HOME_SIZE_MODE_SMALL);
+               }
+          }
+     }
+}
+
+static void
+_ivi_home_cb_hook_role_changed(void *d EINA_UNUSED, E_Client *ec)
+{
+   if (e_object_is_del(E_OBJECT(ec))) return;
+
+   if (_ivi_home_client_is_ivi_home(ec))
+     {
+        e_policy_allow_user_geometry_set(ec, EINA_TRUE);
+        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_ABOVE);
+     }
+   else if (_ivi_home_client_is_ivi_navi(ec))
+     {
+        e_policy_allow_user_geometry_set(ec, EINA_TRUE);
+        evas_object_layer_set(ec->frame, E_LAYER_CLIENT_BELOW);
+     }
+}
+
+static void
+_ivi_home_cb_hook_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec)
+{
+   IVI_Home_Client *ic;
+
+   if (e_object_is_del(E_OBJECT(ec))) return;
+   if ((ec->new_client) && (!e_pixmap_usable_get(ec->pixmap))) return;
+
+   ic = eina_hash_find(hash_clients, &ec);
+   if (!ic) return;
+
+   if (_ivi_home_client_is_ivi_home(ec))
+     {
+        _ivi_home_policy_apply(ic, 1);
+     }
+   else if (_ivi_home_client_is_ivi_navi(ec))
+     {
+        _ivi_home_policy_apply(ic, 0);
+     }
+}
+
+static void
+e_mod_ivi_home_aux_hint_init(void)
+{
+   int i, n;
+   n = (sizeof(ivi_home_hint_names) / sizeof(char *));
+
+   for (i = 0; i < n; i++)
+     {
+        e_hints_aux_hint_supported_add(ivi_home_hint_names[i]);
+     }
+}
+
+static void
+_ivi_home_cb_client_data_free(void *data)
+{
+   free(data);
+}
+
+EINTERN void
+e_mod_ivi_home_init(void)
+{
+   hash_clients = eina_hash_pointer_new(_ivi_home_cb_client_data_free);
+
+   E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_NEW_CLIENT, _ivi_home_cb_hook_client_new, NULL);
+   E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_DEL, _ivi_home_cb_hook_client_del, NULL);
+   E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_AUX_HINT_CHANGE, _ivi_home_cb_hook_aux_hint_changed, NULL);
+   E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_WINDOW_ROLE_CHANGE, _ivi_home_cb_hook_role_changed, NULL);
+   E_CLIENT_HOOK_APPEND(hooks_ec,  E_CLIENT_HOOK_EVAL_POST_FETCH,     _ivi_home_cb_hook_eval_post_fetch, NULL);
+
+   e_mod_ivi_home_aux_hint_init();
+}
+
+EINTERN void
+e_mod_ivi_home_shutdown(void)
+{
+   E_FREE_LIST(hooks_ec, e_client_hook_del);
+   E_FREE_FUNC(hash_clients, eina_hash_free);
+}
diff --git a/src/e_mod_ivi_home.h b/src/e_mod_ivi_home.h
new file mode 100644 (file)
index 0000000..9c4a9a8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef E_MOD_IVI_HOME_H
+#define E_MOD_IVI_HOME_H
+
+EINTERN void e_mod_ivi_home_init(void);
+EINTERN void e_mod_ivi_home_shutdown(void);
+
+#endif /* end of E_MOD_IVI_HOME_H */
index a61c553..09d96d6 100644 (file)
@@ -1,5 +1,8 @@
 #include "e_mod_main.h"
 #include "e_mod_rotation.h"
+#if ENABLE_IVI_HOME
+# include "e_mod_ivi_home.h"
+#endif
 
 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Policy-Mobile" };
 
@@ -21,6 +24,9 @@ e_modapi_init(E_Module *m)
 
    e_mod_pol_conf_init(mod);
    e_mod_pol_rotation_init();
+#if ENABLE_IVI_HOME
+   e_mod_ivi_home_init();
+#endif
 
    return mod;
 }
@@ -32,6 +38,9 @@ e_modapi_shutdown(E_Module *m)
 
    e_mod_pol_rotation_shutdown();
    e_mod_pol_conf_shutdown(mod);
+#if ENABLE_IVI_HOME
+   e_mod_ivi_home_shutdown();
+#endif
    E_FREE(mod);
    _pol_mod = NULL;
    return 1;