policy: added code to handle properties of the indicator service 09/82209/1
authorDoyoun Kang <doyoun.kang@samsung.com>
Tue, 2 Aug 2016 01:51:15 +0000 (10:51 +0900)
committerDoyoun Kang <doyoun.kang@samsung.com>
Tue, 2 Aug 2016 01:51:15 +0000 (10:51 +0900)
Change-Id: I9334f4446280ae2650991eff2cca74ac9c151235

src/bin/Makefile.mk
src/bin/e_policy.c
src/bin/e_policy_wl.c
src/bin/e_policy_wl.h
src/bin/services/e_service_indicator.c [new file with mode: 0644]
src/bin/services/e_service_indicator.h [new file with mode: 0644]

index a04a23e1e1ec4d5a1a1ac1c51d639b713b008a89..da1c006dc42daba9860bd4d45976ca90b056569b 100644 (file)
@@ -99,6 +99,7 @@ src/bin/services/e_service_lockscreen.h \
 src/bin/services/e_service_quickpanel.h \
 src/bin/services/e_service_region.h \
 src/bin/services/e_service_volume.h \
+src/bin/services/e_service_indicator.h \
 src/bin/e_policy.h \
 src/bin/e_policy_keyboard.h \
 src/bin/e_policy_private_data.h \
@@ -184,6 +185,7 @@ src/bin/services/e_service_lockscreen.c \
 src/bin/services/e_service_quickpanel.c \
 src/bin/services/e_service_region.c \
 src/bin/services/e_service_volume.c \
+src/bin/services/e_service_indicator.c \
 src/bin/e_policy.c \
 src/bin/e_policy_conformant.c \
 src/bin/e_policy_keyboard.c \
index 3e87e5dca1f0269904af5182d514acc8c76176c7..97c70953e804c5eb5eca4a49a661b059ee7daceb 100644 (file)
@@ -15,6 +15,9 @@ E_Policy_System_Info e_policy_system_info =
 static Eina_List *handlers = NULL;
 static Eina_List *hooks_ec = NULL;
 static Eina_List *hooks_cp = NULL;
+static Ecore_Idle_Enterer *_e_pol_idle_enterer = NULL;
+static Eina_Bool _e_pol_changed_vis = EINA_FALSE;
+static Eina_List *_e_pol_changed_zone = NULL;
 
 static E_Policy_Client *_e_policy_client_add(E_Client *ec);
 static void        _e_policy_client_del(E_Policy_Client *pc);
@@ -50,6 +53,9 @@ static Eina_Bool   _e_policy_cb_client_resize(void *data EINA_UNUSED, int type,
 static Eina_Bool   _e_policy_cb_client_stack(void *data EINA_UNUSED, int type, void *event);
 static Eina_Bool   _e_policy_cb_client_property(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
 static Eina_Bool   _e_policy_cb_client_vis_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
+static Eina_Bool   _e_policy_cb_client_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
+
+static Eina_Bool   _e_policy_cb_idle_enterer(void *data EINA_UNUSED);
 
 static void
 _e_policy_client_launcher_set(E_Policy_Client *pc)
@@ -440,6 +446,7 @@ _e_policy_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
    if (EINA_UNLIKELY(!ec))
      return;
 
+   e_tzsh_indicator_srv_ower_win_update(ec->zone);
    e_policy_wl_win_brightness_apply(ec);
    e_policy_wl_client_del(ec);
 
@@ -625,6 +632,10 @@ _e_policy_cb_hook_client_visibility(void *d EINA_UNUSED, E_Client *ec)
           }
 
         e_policy_wl_win_brightness_apply(ec);
+
+        _e_pol_changed_vis = EINA_TRUE;
+        if (!eina_list_data_find(_e_pol_changed_zone, ec->zone))
+          _e_pol_changed_zone = eina_list_append(_e_pol_changed_zone, ec->zone);
      }
    else
      {
@@ -957,6 +968,39 @@ _e_policy_cb_client_vis_change(void *data EINA_UNUSED, int type EINA_UNUSED, voi
    return ECORE_CALLBACK_PASS_ON;
 }
 
+static Eina_Bool
+_e_policy_cb_client_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+   E_Event_Client *ev;
+   E_Client *ec;
+
+   ev = event;
+   if (!ev) return ECORE_CALLBACK_PASS_ON;
+
+   ec = ev->ec;
+   e_tzsh_indicator_srv_ower_win_update(ec->zone);
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_policy_cb_idle_enterer(void *data EINA_UNUSED)
+{
+   E_Zone *zone;
+
+   if (_e_pol_changed_vis)
+     {
+        EINA_LIST_FREE(_e_pol_changed_zone, zone)
+          {
+             e_tzsh_indicator_srv_ower_win_update(zone);
+          }
+        _e_pol_changed_zone = NULL;
+     }
+   _e_pol_changed_vis = EINA_FALSE;
+
+   return ECORE_CALLBACK_RENEW;
+}
+
 void
 e_policy_allow_user_geometry_set(E_Client *ec, Eina_Bool set)
 {
@@ -1356,6 +1400,7 @@ e_policy_init(void)
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_STACK,              _e_policy_cb_client_stack,                    NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_PROPERTY,           _e_policy_cb_client_property,                 NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_VISIBILITY_CHANGE,  _e_policy_cb_client_vis_change,               NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_HIDE,               _e_policy_cb_client_hide,                     NULL);
 
    E_CLIENT_HOOK_APPEND(hooks_ec,  E_CLIENT_HOOK_NEW_CLIENT,          _e_policy_cb_hook_client_new,                 NULL);
    E_CLIENT_HOOK_APPEND(hooks_ec,  E_CLIENT_HOOK_DEL,                 _e_policy_cb_hook_client_del,                 NULL);
@@ -1371,6 +1416,8 @@ e_policy_init(void)
    E_PIXMAP_HOOK_APPEND(hooks_cp,  E_PIXMAP_HOOK_DEL,                 _e_policy_cb_hook_pixmap_del,                 NULL);
    E_PIXMAP_HOOK_APPEND(hooks_cp,  E_PIXMAP_HOOK_UNUSABLE,            _e_policy_cb_hook_pixmap_unusable,            NULL);
 
+   _e_pol_idle_enterer = ecore_idle_enterer_add(_e_policy_cb_idle_enterer, NULL);
+
    e_policy_conformant_init();
 
    return EINA_TRUE;
@@ -1383,6 +1430,7 @@ e_policy_shutdown(void)
    Eina_Inlist *l;
    E_Policy_Softkey *softkey;
 
+   eina_list_free(_e_pol_changed_zone);
    eina_list_free(pol->launchers);
    EINA_INLIST_FOREACH_SAFE(pol->softkeys, l, softkey)
      e_policy_softkey_del(softkey);
index ea1646389ee0362dd76baa9a2401617737ecaeaf..67340df1a50763c197edb64e2fb266038b6983ee 100644 (file)
@@ -3,6 +3,7 @@
 #include "services/e_service_quickpanel.h"
 #include "services/e_service_volume.h"
 #include "services/e_service_lockscreen.h"
+#include "services/e_service_indicator.h"
 #include "e_policy_wl_display.h"
 #include "e_policy_conformant.h"
 
@@ -183,6 +184,7 @@ static E_Policy_Wl *polwl = NULL;
 static Eina_List *handlers = NULL;
 static Eina_List *hooks_cw = NULL;
 static struct wl_resource *_scrsaver_mng_res = NULL; // TODO
+static struct wl_resource *_indicator_srv_res = NULL;
 
 enum _E_Policy_Hint_Type
 {
@@ -562,6 +564,20 @@ _e_policy_wl_tzsh_srv_del(E_Policy_Wl_Tzsh_Srv *tzsh_srv)
    if (tzsh_srv->name)
      eina_stringshare_del(tzsh_srv->name);
 
+   if (tzsh_srv->role == TZSH_SRV_ROLE_INDICATOR)
+     {
+        E_Client *ec;
+        ec = tzsh_srv->tzsh->ec;
+
+        if (ec && ec->internal)
+          {
+             e_pixmap_del(tzsh_srv->tzsh->cp);
+             e_object_del(E_OBJECT(ec));
+          }
+
+        _indicator_srv_res = NULL;
+     }
+
    memset(tzsh_srv, 0x0, sizeof(E_Policy_Wl_Tzsh_Srv));
    E_FREE(tzsh_srv);
 }
@@ -2905,17 +2921,39 @@ _tzsh_srv_iface_cb_region_set(struct wl_client *client, struct wl_resource *res_
      e_service_volume_region_set(type, angle, tzsh_reg->tiler);
 }
 
+static void
+_tzsh_srv_indicator_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
+{
+   _indicator_srv_res = NULL;
+   wl_resource_destroy(resource);
+}
+
+static const struct tws_service_indicator_interface _tzsh_srv_indicator_iface =
+{
+   _tzsh_srv_indicator_cb_destroy,
+};
+
 static void
 _tzsh_srv_iface_cb_indicator_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
 {
    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
+   struct wl_resource *res;
 
    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
 
    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
      return;
 
-   /* TODO: create tws_indicator_service resource. */
+   res = wl_resource_create(client, &tws_service_indicator_interface, 1, id);
+   if (!res)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+   _indicator_srv_res = res;
+
+   wl_resource_set_implementation(res, &_tzsh_srv_indicator_iface, tzsh_srv, NULL);
 }
 
 static void
@@ -3154,14 +3192,29 @@ _tzsh_iface_cb_srv_create(struct wl_client *client, struct wl_resource *res_tzsh
    cp = _e_policy_wl_e_pixmap_get_from_id(client, surf_id);
    if (!cp)
      {
-        wl_resource_post_error
-          (res_tzsh,
-           WL_DISPLAY_ERROR_INVALID_OBJECT,
-           "Invalid surface id");
-        return;
+        if (role == TZSH_SRV_ROLE_INDICATOR)
+          cp = e_pixmap_new(E_PIXMAP_TYPE_NONE, 0);
+
+        if (!cp)
+          {
+             wl_resource_post_error
+               (res_tzsh,
+                WL_DISPLAY_ERROR_INVALID_OBJECT,
+                "Invalid surface id");
+             return;
+          }
      }
 
    ec = e_pixmap_client_get(cp);
+   if (!ec)
+     {
+        if (role == TZSH_SRV_ROLE_INDICATOR)
+          {
+             ec = e_client_new(cp, 0, 1);
+             if (ec) ec->ignored = 1;
+          }
+     }
+
    if (ec)
      {
         if (!_e_policy_wl_e_client_is_valid(ec))
@@ -3214,6 +3267,8 @@ _tzsh_iface_cb_srv_create(struct wl_client *client, struct wl_resource *res_tzsh
      e_service_lockscreen_client_set(tzsh->ec);
    else if (role == TZSH_SRV_ROLE_SCREENSAVER)
      e_service_lockscreen_client_set(tzsh->ec);
+   else if (role == TZSH_SRV_ROLE_INDICATOR)
+     e_mod_indicator_client_set(tzsh->ec);
 }
 
 // --------------------------------------------------------
@@ -3357,6 +3412,101 @@ err:
    E_FREE(tzsh_reg);
 }
 
+// --------------------------------------------------------
+// tizen_ws_shell_interface::indicator
+// --------------------------------------------------------
+static E_Client *
+_e_tzsh_indicator_find_topvisible_client(E_Zone *zone)
+{
+   E_Client *ec;
+   Evas_Object *o;
+   E_Comp_Wl_Client_Data *cdata;
+
+   o = evas_object_top_get(e_comp->evas);
+   for (; o; o = evas_object_below_get(o))
+     {
+        ec = evas_object_data_get(o, "E_Client");
+
+        /* check e_client and skip e_clients not intersects with zone */
+        if (!ec) continue;
+        if (e_object_is_del(E_OBJECT(ec))) continue;
+        if (e_client_util_ignored_get(ec)) continue;
+        if (ec->zone != zone) continue;
+        if (!ec->frame) continue;
+        if (!ec->visible) continue;
+        if (ec->visibility.skip) continue;
+        if ((ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) &&
+            (ec->visibility.obscured != E_VISIBILITY_PARTIALLY_OBSCURED))
+          continue;
+
+        /* if ec is subsurface, skip this */
+        cdata = (E_Comp_Wl_Client_Data *)ec->comp_data;
+        if (cdata && cdata->sub.data) continue;
+
+        if (!E_CONTAINS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
+          continue;
+
+        return ec;
+
+     }
+
+   return NULL;
+}
+
+static void
+_e_tzsh_indicator_srv_property_change_send(E_Client *ec)
+{
+   int angle;
+   int opacity;
+
+   if (!ec) return;
+   if (!_indicator_srv_res)
+     {
+        ELOGF("TZ_IND", "NO indicator service", NULL, NULL);
+        return;
+     }
+
+   angle = ec->e.state.rot.ang.curr;
+   opacity = ec->indicator.opacity_mode;
+
+   ELOGF("TZ_IND", "SEND indicator info. angle:%d, opacity:%d", ec->pixmap, ec, angle, opacity);
+   tws_service_indicator_send_property_change(_indicator_srv_res, angle, opacity);
+}
+
+EINTERN void
+e_tzsh_indicator_srv_property_update(E_Client *ec)
+{
+   E_Client *ec_ind_owner;
+   if (!_indicator_srv_res) return;
+
+   ec_ind_owner = e_mod_indicator_owner_get();
+   if (ec != ec_ind_owner) return;
+
+   _e_tzsh_indicator_srv_property_change_send(ec);
+}
+
+EINTERN void
+e_tzsh_indicator_srv_ower_win_update(E_Zone *zone)
+{
+   E_Client *ec = NULL;
+   E_Client *ec_cur_owner = NULL;
+
+   if (!zone) return;
+   if (!_indicator_srv_res) return;
+
+   ec_cur_owner = e_mod_indicator_owner_get();
+   ec = _e_tzsh_indicator_find_topvisible_client(zone);
+
+   if (ec != ec_cur_owner)
+     {
+        ELOGF("TZ_IND", "Changed OWNER. win:%x, state:%d, opacity:%d, vtype:%d", NULL, NULL, e_client_util_win_get(ec),
+              ec ? ec->indicator.state:-1, ec ? ec->indicator.opacity_mode:-1, ec ? ec->indicator.visible_type:-1);
+        e_mod_indicator_owner_set(ec);
+
+        e_tzsh_indicator_srv_property_update(ec);
+     }
+}
+
 // --------------------------------------------------------
 // tizen_ws_shell_interface::quickpanel
 // --------------------------------------------------------
@@ -4380,7 +4530,12 @@ _tz_indicator_cb_opacity_mode_set(struct wl_client *client EINA_UNUSED, struct w
 
    ELOGF("TZ_IND", "OPACITY_MODE:%d", ec->pixmap, ec, mode);
    _e_policy_wl_tz_indicator_set_client(res_tz_indicator, ec);
+
+   if (ec->indicator.opacity_mode == mode) return;
+
    ec->indicator.opacity_mode = mode;
+   if (ec == e_mod_indicator_owner_get())
+     _e_tzsh_indicator_srv_property_change_send(ec);
 }
 
 static void
index d8a2471b4524dfd0fbb259acb36ce7398779f5a7..5d1ffdb4ba7531e2a5f2b0a05ff6c514d72acc9b 100644 (file)
@@ -39,6 +39,10 @@ EINTERN void e_tzsh_qp_state_visible_update(E_Client *ec, Eina_Bool vis);
 EINTERN void e_tzsh_qp_state_orientation_update(E_Client *ec, int ridx);
 EINTERN void e_tzsh_qp_state_scrollable_update(E_Client *ec, Eina_Bool scrollable);
 
+/* tzsh indicator */
+EINTERN void e_tzsh_indicator_srv_property_update(E_Client *ec);
+EINTERN void e_tzsh_indicator_srv_ower_win_update(E_Zone *zone);
+
 /* indicator */
 void         e_policy_wl_indicator_flick_send(E_Client *ec);
 
diff --git a/src/bin/services/e_service_indicator.c b/src/bin/services/e_service_indicator.c
new file mode 100644 (file)
index 0000000..7059297
--- /dev/null
@@ -0,0 +1,98 @@
+#include "e.h"
+#include "services/e_service_indicator.h"
+#include "e_policy_wl.h"
+
+static E_Client *_ind_server = NULL;
+static E_Client *_ind_owner = NULL;
+
+/* event handler */
+static Eina_List *_ind_handlers = NULL;
+static Eina_List *_ind_hooks = NULL;
+
+static Eina_Bool
+_indicator_cb_rot_done(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+   E_Client *ec = NULL;
+   E_Event_Client_Rotation_Change_End *ev = NULL;
+
+   ev = event;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
+
+   ec = ev->ec;
+   if (ec == _ind_owner)
+     {
+        e_tzsh_indicator_srv_property_update(ec);
+     }
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_indicator_client_unset(void)
+{
+   E_FREE_LIST(_ind_handlers, ecore_event_handler_del);
+   _ind_handlers = NULL;
+
+   E_FREE_LIST(_ind_hooks, e_client_hook_del);
+   _ind_hooks = NULL;
+
+   _ind_server = NULL;
+}
+
+static void
+_indicator_cb_client_del(void *d EINA_UNUSED, E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   if (_ind_server != ec) return;
+
+   _indicator_client_unset();
+}
+
+EINTERN Eina_Bool
+e_mod_indicator_client_set(E_Client *ec)
+{
+   if (!ec)
+     {
+        if (_ind_server)
+          _indicator_client_unset();
+
+        return EINA_TRUE;
+     }
+
+   if (_ind_server)
+     {
+        ERR("Indicater service is already registered."
+            "Multi indicator service is not supported.");
+        return EINA_FALSE;
+     }
+
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+
+   ELOGF("TZ_IND", "Set indicator service", ec->pixmap, ec);
+
+   eina_stringshare_replace(&ec->icccm.window_role, "indicator");
+
+   E_LIST_HANDLER_APPEND(_ind_handlers, E_EVENT_CLIENT_ROTATION_CHANGE_END, _indicator_cb_rot_done, NULL);
+   E_LIST_HOOK_APPEND(_ind_hooks, E_CLIENT_HOOK_DEL, _indicator_cb_client_del, NULL);
+
+   _ind_server = ec;
+   if (!_ind_owner)
+     _ind_owner = e_client_focused_get();
+
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_mod_indicator_owner_set(E_Client *ec)
+{
+   _ind_owner = ec;
+}
+
+EINTERN E_Client *
+e_mod_indicator_owner_get(void)
+{
+   return _ind_owner;
+}
+
+
diff --git a/src/bin/services/e_service_indicator.h b/src/bin/services/e_service_indicator.h
new file mode 100644 (file)
index 0000000..9cf7079
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef E_MOD_INDICATOR_H
+#define E_MOD_INDICATOR_H
+
+EINTERN Eina_Bool     e_mod_indicator_client_set(E_Client *ec);
+
+EINTERN void          e_mod_indicator_owner_set(E_Client *ec);
+EINTERN E_Client     *e_mod_indicator_owner_get(void);
+
+
+#endif