e_desk: Add a implementation of e_desk_zoom_set/unset. 56/101556/3
authorSeunghun Lee <shiin.lee@samsung.com>
Mon, 28 Nov 2016 08:51:17 +0000 (17:51 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Fri, 2 Dec 2016 08:20:41 +0000 (00:20 -0800)
Newly Added APIs:
E_API void         e_desk_zoom_set(E_Desk *desk, double zoomx, double zoomy, int cx, int cy);
E_API void         e_desk_zoom_unset(E_Desk *desk);
E_API void         e_desk_smart_member_add(E_Desk *desk, Evas_Object *obj);
E_API void         e_desk_smart_member_del(Evas_Object *obj);

- Test Plan:
  $ enlightenment_info -desk zoom [X's ZOOM RATIO] [Y's ZOOM RATIO] [CENTER X] [CENTER Y]

- NOTE:
  You can unset zoom state by passing values 1.0 as a X and Y zoom ratio.

Change-Id: I06860a5d1cfbc2e3fc43460cd428ea2bd894caeb

src/bin/e_client.c
src/bin/e_desk.c
src/bin/e_desk.h
src/bin/e_info_client.c
src/bin/e_info_server.c
src/bin/services/e_service_quickpanel.c
src/bin/services/e_service_volume.c

index a7535fde1b8564dcc10566c0613421379081d736..70375bd8aa14dfe27a9605134e487a8e9dc7299e 100644 (file)
@@ -932,6 +932,8 @@ _e_client_free(E_Client *ec)
 
    e_uuid_store_entry_del(ec->uuid);
 
+   e_desk_client_del(ec->desk, ec);
+
    free(ec);
 }
 
@@ -1037,8 +1039,6 @@ _e_client_del(E_Client *ec)
    ec->transform_core.result.enable = EINA_FALSE;
 
    e_client_visibility_calculate();
-
-   e_desk_client_del(ec->desk, ec);
 }
 
 ///////////////////////////////////////////
@@ -2852,7 +2852,6 @@ _e_client_visibility_zone_calculate(E_Zone *zone)
    E_Client *ec;
    E_Client *focus_ec = NULL;
    E_Client *new_focused_ec = NULL;
-   Evas_Object *o;
    Eina_Tiler *t;
    Eina_Rectangle r, *_r;
    Eina_Iterator *it;
@@ -2883,13 +2882,8 @@ _e_client_visibility_zone_calculate(E_Zone *zone)
         eina_tiler_rect_add(t, &r);
      }
 
-   o = evas_object_top_get(e_comp->evas);
-   for (; o; o = evas_object_below_get(o))
+   E_CLIENT_REVERSE_FOREACH(ec)
      {
-        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;
index 4eb02a9c1205f38889fab6e79c11e6e92d6c0065..f66e8e693bcdae1af2cfc06171fd8e72f2b5d64d 100644 (file)
@@ -5,8 +5,6 @@
  * number of desktops.
  */
 
-#define E_DESK_SMART_OBJ_TYPE "E_Desk_Smart_Object"
-
 #define E_DESK_SMART_DATA_GET(obj, ptr)                        \
    E_Desk_Smart_Data *ptr = evas_object_smart_data_get(obj);
 
@@ -19,8 +17,15 @@ typedef struct _E_Desk_Smart_Data E_Desk_Smart_Data;
 struct _E_Desk_Smart_Data
 {
    Evas_Object_Smart_Clipped_Data base;
-
-   Eina_List   *clients;
+   Eina_List      *clients;
+   Eina_List      *handlers;
+
+   struct
+   {
+      double       ratio_x, ratio_y;
+      int          center_x, center_y;
+      Eina_Bool    enabled;
+   } zoom;
 };
 
 static void      _e_desk_free(E_Desk *desk);
@@ -37,6 +42,9 @@ static void      _e_desk_smart_add(Evas_Object *obj);
 static void      _e_desk_smart_del(Evas_Object *obj);
 static void      _e_desk_smart_client_add(Evas_Object *obj, E_Client *ec);
 static void      _e_desk_smart_client_del(Evas_Object *obj, E_Client *ec);
+static void      _e_desk_object_zoom(Evas_Object *obj, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
+static void      _e_desk_client_zoom(E_Client *ec, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
+static void      _e_desk_util_comp_hwc_disable_set(Eina_Bool enable);
 
 EVAS_SMART_SUBCLASS_NEW(E_DESK_SMART_OBJ_TYPE, _e_desk,
                         Evas_Smart_Class, Evas_Smart_Class,
@@ -89,6 +97,10 @@ e_desk_new(E_Zone *zone, int x, int y)
    desk->smart_obj = evas_object_smart_add(e_comp->evas, _e_desk_smart_class_new());
    e_desk_geometry_set(desk, zone->x, zone->y, zone->w, zone->h);
 
+   /* FIXME indicator object won't be work, if remove this code.
+    * I have no idea why this code is necessary, so I just let it be. */
+   e_desk_zoom_set(desk, 1.0, 1.0, 0, 0);
+
    desk->zone = zone;
    desk->x = x;
    desk->y = y;
@@ -774,6 +786,90 @@ e_desk_geometry_set(E_Desk *desk, int x, int y, int w, int h)
    e_comp_render_queue();
 }
 
+E_API void
+e_desk_zoom_set(E_Desk *desk, double zoomx, double zoomy, int cx, int cy)
+{
+   E_Client *ec;
+   Eina_List *l;
+
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
+
+   if ((sd->zoom.ratio_x != zoomx) || (sd->zoom.ratio_y != zoomy) ||
+       (sd->zoom.center_x != cx) || (sd->zoom.center_y != cy))
+     {
+        sd->zoom.ratio_x = zoomx;
+        sd->zoom.ratio_y = zoomy;
+        sd->zoom.center_x = cx;
+        sd->zoom.center_y = cy;
+
+        _e_desk_object_zoom(desk->smart_obj, zoomx, zoomy, cx, cy);
+        EINA_LIST_FOREACH(sd->clients, l, ec)
+           _e_desk_client_zoom(ec, zoomx, zoomy, cx, cy);
+     }
+
+   if (!sd->zoom.enabled)
+     {
+        sd->zoom.enabled = EINA_TRUE;
+
+        evas_object_map_enable_set(desk->smart_obj, EINA_TRUE);
+        EINA_LIST_FOREACH(sd->clients, l, ec)
+           evas_object_map_enable_set(ec->frame, EINA_TRUE);
+
+        /* FIXME TEMP disable hwc */
+        _e_desk_util_comp_hwc_disable_set(EINA_TRUE);
+     }
+}
+
+E_API void
+e_desk_zoom_unset(E_Desk *desk)
+{
+   E_Client *ec;
+   Eina_List *l;
+
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
+
+   if (!sd->zoom.enabled)
+     return;
+
+   sd->zoom.ratio_x = 1.0;
+   sd->zoom.ratio_y = 1.0;
+   sd->zoom.enabled = EINA_FALSE;
+
+   evas_object_map_enable_set(desk->smart_obj, EINA_FALSE);
+   EINA_LIST_FOREACH(sd->clients, l, ec)
+     {
+        /* NOTE Is it really necessary?
+         * Why isn't it enough to just call evas_object_map_enable_set(false)? */
+        _e_desk_client_zoom(ec, sd->zoom.ratio_x, sd->zoom.ratio_y,
+                            sd->zoom.center_x, sd->zoom.center_y);
+        evas_object_map_enable_set(ec->frame, EINA_FALSE);
+     }
+
+   /* FIXME TEMP enable hwc */
+   _e_desk_util_comp_hwc_disable_set(EINA_FALSE);
+}
+
+E_API void
+e_desk_smart_member_add(E_Desk *desk, Evas_Object *obj)
+{
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   evas_object_smart_member_add(obj, desk->smart_obj);
+}
+
+E_API void
+e_desk_smart_member_del(Evas_Object *obj)
+{
+   evas_object_smart_member_del(obj);
+}
+
 static void
 _e_desk_free(E_Desk *desk)
 {
@@ -940,11 +1036,35 @@ _e_desk_hide_begin(E_Desk *desk, int dx, int dy)
      }
 }
 
+static Eina_Bool
+_e_desk_smart_client_cb_resize(void *data, int type, void *event)
+{
+   E_Event_Client *ev;
+   E_Desk_Smart_Data *sd;
+
+   ev = event;
+   sd = data;
+   if (!eina_list_data_find(sd->clients, ev->ec))
+     goto end;
+
+   _e_desk_client_zoom(ev->ec,
+                       sd->zoom.ratio_x, sd->zoom.ratio_y,
+                       sd->zoom.center_x, sd->zoom.center_y);
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
 static void
 _e_desk_smart_add(Evas_Object *obj)
 {
    EVAS_SMART_DATA_ALLOC(obj, E_Desk_Smart_Data);
 
+   /* to apply zoom transformation whenever the client's size is changed. */
+   E_LIST_HANDLER_APPEND(priv->handlers, E_EVENT_CLIENT_RESIZE, _e_desk_smart_client_cb_resize, priv);
+
+   /* FIXME hard coded, it will be laid upper than unpacked clients */
+   evas_object_layer_set(obj, EVAS_LAYER_MAX - 2);
+
    _e_desk_parent_sc->add(obj);
 }
 
@@ -955,6 +1075,7 @@ _e_desk_smart_del(Evas_Object *obj)
 
    E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
 
+   E_FREE_LIST(sd->handlers, ecore_event_handler_del);
    eina_list_free(sd->clients);
    free(sd);
 
@@ -973,8 +1094,13 @@ _e_desk_smart_client_add(Evas_Object *obj, E_Client *ec)
 {
    E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
 
+   if (eina_list_data_find(sd->clients, ec))
+     return;
+
+   _e_desk_client_zoom(ec,
+                       sd->zoom.ratio_x, sd->zoom.ratio_y,
+                       sd->zoom.center_x, sd->zoom.center_y);
    sd->clients = eina_list_append(sd->clients, ec);
-   evas_object_smart_member_add(ec->frame, obj);
    evas_object_smart_changed(obj);
 }
 
@@ -983,7 +1109,40 @@ _e_desk_smart_client_del(Evas_Object *obj, E_Client *ec)
 {
    E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
 
+   if (!eina_list_data_find(sd->clients, ec))
+     return;
+
+   evas_object_map_enable_set(ec->frame, EINA_FALSE);
    sd->clients = eina_list_remove(sd->clients, ec);
-   evas_object_smart_member_del(ec->frame);
    evas_object_smart_changed(obj);
 }
+
+static void
+_e_desk_util_comp_hwc_disable_set(Eina_Bool disable)
+{
+   if (disable)
+     e_comp_hwc_end("in runtime by e_desk");
+   e_comp->hwc_deactive = disable;
+}
+
+static void
+_e_desk_object_zoom(Evas_Object *obj, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy)
+{
+   Evas_Map *map;
+   Eina_Bool enabled;
+
+   map = evas_map_new(4);
+   evas_map_util_object_move_sync_set(map, EINA_TRUE);
+   evas_map_util_points_populate_from_object(map, obj);
+   evas_map_util_zoom(map, zoomx, zoomy, cx, cy);
+   evas_object_map_set(obj, map);
+   enabled = ((zoomx != 1.0) || (zoomy != 1.0));
+   evas_object_map_enable_set(obj, enabled);
+   evas_map_free(map);
+}
+
+static void
+_e_desk_client_zoom(E_Client *ec, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy)
+{
+   _e_desk_object_zoom(ec->frame, zoomx, zoomy, cx, cy);
+}
index 24cda2a14a6f67feb841af8a1568245a885136fd..b54d29ad034fa71919c7203e213c804f6938990b 100644 (file)
@@ -14,6 +14,7 @@ typedef void (*E_Desk_Flip_Cb)(void *data, E_Desk *desk, int dx, int dy, Eina_Bo
 #define E_DESK_H
 
 #define E_DESK_TYPE 0xE0b01005
+#define E_DESK_SMART_OBJ_TYPE "E_Desk_Smart_Object"
 
 typedef enum
 {
@@ -100,6 +101,11 @@ E_API void         e_desk_flip_end(E_Desk *desk);
 E_API unsigned int e_desks_count(void);
 
 E_API void         e_desk_geometry_set(E_Desk *desk, int x, int y, int w, int h);
+E_API void         e_desk_zoom_set(E_Desk *desk, double zoomx, double zoomy, int cx, int cy);
+E_API void         e_desk_zoom_unset(E_Desk *desk);
+
+E_API void         e_desk_smart_member_add(E_Desk *desk, Evas_Object *obj);
+E_API void         e_desk_smart_member_del(Evas_Object *obj);
 E_API void         e_desk_client_add(E_Desk *desk, E_Client *ec);
 E_API void         e_desk_client_del(E_Desk *desk, E_Client *ec);
 
index 5b8ec040b5077d2ddbfa9f2d326e0ce7799bc986..a4a8380226649f34d14238097d1078fd2660a933 100644 (file)
@@ -1726,32 +1726,62 @@ _e_info_client_proc_slot_set(int argc, char **argv)
 }
 
 static void
-_e_info_client_proc_desktop_geometry_set(int argc, char **argv)
+_e_info_client_proc_desk(int argc, char **argv)
 {
-   int x, y, w, h;
+   const int offset = 2, cmd_len = 1;
+   Eina_Bool res = EINA_FALSE;
+
+   if (argc < offset + cmd_len)
+     goto arg_err;
 
-   if (argc != 6)
+   if (eina_streq(argv[offset], "geometry"))
      {
-        printf("Error Check Args: enlightenment_info -desktop_geometry_set [X] [Y] [W] [H]\n");
-        return;
-     }
+        const int narg = 4;
+        int geom[narg];
+        int i;
 
-   x = atoi(argv[2]);
-   y = atoi(argv[3]);
-   w = atoi(argv[4]);
-   h = atoi(argv[5]);
+        if (argc < offset + cmd_len + narg)
+          goto arg_err;
+
+        for (i = 0; i < narg; i++)
+          geom[i] = atoi(argv[offset + cmd_len + i]);
+
+        if ((geom[2] < 0) || (geom[3] < 0))
+          {
+             printf("Error Check Args: Width(%d) and Height(%d) must not be less than 1.\n", geom[2], geom[3]);
+             return;
+          }
 
-   if ((w < 0) || (h < 0))
+        res = _e_info_client_eldbus_message_with_args("desktop_geometry_set", NULL, "iiii",
+                                                      geom[0], geom[1], geom[2], geom[3]);
+     }
+   else if (eina_streq(argv[offset], "zoom"))
      {
-        printf("Error Check Args: Width(%d) and Height(%d) must not be less than 1.\n", w, h);
-        return;
+        const int narg = 4;
+        double zx, zy;
+        int cx, cy;
+
+        if (argc < offset + cmd_len + narg)
+          goto arg_err;
+
+        zx = atof(argv[offset + cmd_len]);
+        zy = atof(argv[offset + cmd_len + 1]);
+        cx = atoi(argv[offset + cmd_len + 2]);
+        cy = atoi(argv[offset + cmd_len + 3]);
+
+        res = _e_info_client_eldbus_message_with_args("desk_zoom", NULL, "ddii",
+                                                      zx, zy, cx, cy);
      }
 
-   if (!_e_info_client_eldbus_message_with_args("desktop_geometry_set", NULL, "iiii", x, y, w, h))
+   if (!res)
      {
         printf("_e_info_client_eldbus_message_with_args error");
         return;
      }
+
+   return;
+arg_err:
+   printf("Usage: enlightenment_info -desk\n");
 }
 
 static void
@@ -2400,10 +2430,10 @@ static struct
       _e_info_client_proc_slot_set
    },
    {
-      "desktop_geometry_set",
-      "[X Y W H]",
-      "Set geometry of current desktop",
-      _e_info_client_proc_desktop_geometry_set
+      "desk",
+      NULL,
+      "current desktop",
+      _e_info_client_proc_desk
    }
 };
 
index 96f38afb1011e1294195f282776f73983d3a7156..f54a9f1798b408c8e5f331112d924635e228043b 100644 (file)
@@ -2322,6 +2322,32 @@ _e_info_server_cb_desktop_geometry_set(const Eldbus_Service_Interface *iface EIN
    return reply;
 }
 
+static Eldbus_Message *
+_e_info_server_cb_desk_zoom(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+   Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+   E_Zone *zone;
+   E_Desk *desk;
+   double zx, zy;
+   int cx, cy;
+
+   if (!eldbus_message_arguments_get(msg, "ddii", &zx, &zy, &cx, &cy))
+     {
+        ERR("Error getting arguments.");
+        return reply;
+     }
+
+   zone = e_zone_current_get();
+   desk = e_desk_current_get(zone);
+
+   if ((zx != 1.0) || (zy != 1.0))
+     e_desk_zoom_set(desk, zx, zy, cx, cy);
+   else
+     e_desk_zoom_unset(desk);
+
+   return reply;
+}
+
 static Eina_Bool
 _e_info_server_cb_buffer_change(void *data, int type, void *event)
 {
@@ -2797,6 +2823,7 @@ static const Eldbus_Method methods[] = {
    { "scrsaver", ELDBUS_ARGS({SIGNATURE_SCRSAVER_CLIENT, "scrsaver_params"}), ELDBUS_ARGS({SIGNATURE_SCRSAVER_SERVER, "scrsaver_result"}), _e_info_server_cb_scrsaver, 0},
    { "slot_message", ELDBUS_ARGS({"iiiiii", "slot_message"}), ELDBUS_ARGS({"a(ss)", "array of ec"}), e_info_server_cb_slot_message, 0},
    { "desktop_geometry_set", ELDBUS_ARGS({"iiii", "Geometry"}), NULL, _e_info_server_cb_desktop_geometry_set, 0},
+   { "desk_zoom", ELDBUS_ARGS({"ddii", "Zoom"}), NULL, _e_info_server_cb_desk_zoom, 0},
    { NULL, NULL, NULL, NULL, 0 }
 };
 
index 625959131c2d51f5114e737c8f7b5ab11afaf1c4..27b87bc3171b5da5afcbf726b9f75450aee346e2 100644 (file)
@@ -163,6 +163,9 @@ _mover_intercept_show(void *data, Evas_Object *obj)
    e_comp_object_dirty(ec->frame);
    e_comp_object_render(ec->frame);
 
+   e_desk_client_del(ec->desk, ec);
+   e_layout_pack(md->qp_layout_obj, ec->frame);
+
   // create base_clip
    e = evas_object_evas_get(obj);
    md->base_clip = evas_object_rectangle_add(e);
@@ -190,6 +193,7 @@ _mover_intercept_show(void *data, Evas_Object *obj)
    evas_object_clip_set(md->handler_mirror_obj, md->handler_clip);
 
    evas_object_show(obj);
+   e_desk_smart_member_add(ec->desk, obj);
 }
 
 static void
@@ -245,7 +249,19 @@ _mover_smart_del(Evas_Object *obj)
 
    e_comp_override_del();
 
+   /* workaround:
+    * if remove this evas_object_map_enable_set() passing false and true,
+    * we can see the afterimage of move object.
+    * to avoid this probelm, we need it. */
+   evas_object_map_enable_set(ec->desk->smart_obj, EINA_FALSE);
+   evas_object_map_enable_set(ec->desk->smart_obj, EINA_TRUE);
+
+   e_layout_unpack(ec->frame);
+   e_desk_client_add(ec->desk, ec);
+
    free(md);
+   evas_object_hide(obj);
+   e_desk_smart_member_del(obj);
 }
 
 static void
@@ -1252,6 +1268,7 @@ _quickpanel_indicator_object_new(E_Policy_Quickpanel *qp)
                                 _region_obj_cb_gesture_end, qp);
 
    evas_object_show(indi_obj);
+   e_desk_smart_member_add(qp->ec->desk, indi_obj);
 
    return indi_obj;
 }
index 9c79e2a03c3b1dc1e70f7279c29bf79a12d63947..4c22a895e7d92026401b1662d018a34039e0ee27 100644 (file)
@@ -355,6 +355,7 @@ _region_objs_tile_set(E_Policy_Angle_Map angle_map, Eina_Tiler *tiler)
           {
              obj = _volume_content_region_obj_new();
              _volume_region_objs[angle_map] = eina_list_append(_volume_region_objs[angle_map], obj);
+             e_desk_smart_member_add(_volume_ec->desk, obj);
           }
 
         INF("\t@@@@@ Region Set: %d %d %d %d", r->x, r->y, r->w, r->h);