add e_managnifier feature 44/199944/2 accepted/tizen/unified/20190219.154029 submit/tizen/20190219.095209
authorDoyoun Kang <doyoun.kang@samsung.com>
Sun, 17 Feb 2019 08:31:32 +0000 (17:31 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Tue, 19 Feb 2019 01:38:33 +0000 (01:38 +0000)
Change-Id: I6304cd76fa31f1b86414674a1ce7872a74c817b8

src/bin/Makefile.mk
src/bin/e_client.h
src/bin/e_includes.h
src/bin/e_magnifier.c [new file with mode: 0644]
src/bin/e_magnifier.h [new file with mode: 0644]
src/bin/e_main.c
src/bin/e_policy.c
src/bin/e_policy.h
src/bin/e_policy_wl.c

index eb4235f775ddc1233a766550a3900605ed5b57e9..fac7082bd37cd7e8c2e524a11c4d0de3cf7ba3a8 100644 (file)
@@ -127,6 +127,7 @@ src/bin/e_policy_visibility.h \
 src/bin/e_policy_private_data.h \
 src/bin/e_policy_wl.h \
 src/bin/e_policy_wl_display.h \
+src/bin/e_magnifier.h \
 src/bin/e_process.h \
 src/bin/e_privilege.h \
 src/bin/e_security.h \
@@ -243,6 +244,7 @@ src/bin/e_policy_stack.c  \
 src/bin/e_policy_visibility.c \
 src/bin/e_policy_wl.c \
 src/bin/e_policy_wl_display.c \
+src/bin/e_magnifier.c \
 src/bin/e_process.c \
 src/bin/e_privilege.c \
 src/bin/e_security.c \
index eef1fca1fcf897a449543c7df86667a972c7f301..7598639ba581853cda781acdf699a8b1ca54e306 100644 (file)
@@ -964,6 +964,9 @@ struct E_Client
       Eina_Bool add  : 1; // ADD / REMOVE
       Eina_Bool show : 1; // SHOW / HIDE
    } reg_ev;
+
+   Evas_Object *magnifier_proxy;   // The proxy object used by magnifier
+   Eina_Bool    is_magnifier : 1;  // The client is a magnifier client
 };
 
 #define e_client_focus_policy_click(ec) \
index 0bd76ce694f2a397a1f82f3423397a841ad9c205..c2193a2351637dce8cdbe3b1e4a3714b4f8acaa3 100644 (file)
@@ -70,6 +70,7 @@
 #include "e_policy.h"
 #include "e_policy_conformant.h"
 #include "e_policy_visibility.h"
+#include "e_magnifier.h"
 #include "e_process.h"
 #include "e_splitlayout.h"
 #include "e_slot.h"
diff --git a/src/bin/e_magnifier.c b/src/bin/e_magnifier.c
new file mode 100644 (file)
index 0000000..5ee4271
--- /dev/null
@@ -0,0 +1,734 @@
+#include "e.h"
+
+#define E_MAGNIFIER_SMART_DATA_GET(obj, ptr)                        \
+   E_Magnifier_Smart_Data *ptr = evas_object_smart_data_get(obj);
+
+#define E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(obj, ptr)              \
+   E_MAGNIFIER_SMART_DATA_GET(obj, ptr);                            \
+   if (!ptr) return
+
+typedef struct _E_Magnifier_Smart_Data E_Magnifier_Smart_Data;
+
+struct _E_Magnifier_Smart_Data
+{
+   Evas_Object_Smart_Clipped_Data base;
+   Eina_List      *handlers;
+   E_Desk         *desk;
+
+   int stand_alone_mode;
+   E_Magnifier_Zoom_Ratio ratio;
+   struct 
+   {
+      struct
+      {
+         int x, y, w, h;
+      } user;
+      struct
+      {
+         int x, y, w, h;
+      } system;
+   } geom;
+   Eina_Bool    enabled;
+};
+
+EVAS_SMART_SUBCLASS_NEW(E_MAGNIFIER_SMART_OBJ_TYPE, _e_magnifier,
+                    Evas_Smart_Class, Evas_Smart_Class,
+                    evas_object_smart_clipped_class_get, NULL);
+
+
+static void      _e_magnifier_smart_init(void);
+static void      _e_magnifier_smart_add(Evas_Object *obj);
+static void      _e_magnifier_smart_del(Evas_Object *obj);
+static Eina_Bool _e_magnifier_proxy_ec_new(E_Client *ec);
+static void      _e_magnifier_proxy_ec_del(E_Client *ec);
+static Eina_Bool _e_magnifier_proxy_ec_all_add(E_Desk *desk);
+static Eina_Bool _e_magnifier_proxy_ec_all_remove(void);
+
+
+static Evas_Object *_e_magnifier_mgr = NULL;
+
+static void
+_e_magnifier_smart_init(void)
+{
+   E_Zone *zone;
+
+   _e_magnifier_mgr = evas_object_smart_add(e_comp->evas, _e_magnifier_smart_class_new());
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd);
+
+   ELOGF("MAGNIFIER", "INIT Magnifier (%p)", NULL, _e_magnifier_mgr);
+
+   zone = e_zone_current_get();
+
+   sd->ratio = E_MAGNIFIER_ZOOM_RATIO_150;
+
+   sd->geom.system.x = 0;
+   sd->geom.system.y = 0;
+   sd->geom.system.w = 360;
+   sd->geom.system.h = 360;
+
+   evas_object_move(_e_magnifier_mgr, zone->x, zone->y);
+   evas_object_resize(_e_magnifier_mgr, zone->w, zone->h);
+}
+
+static Eina_Bool
+_e_magnifier_proxy_ec_new(E_Client *ec)
+{
+   Eina_Bool ret;
+
+   if (!ec) return EINA_FALSE;
+   if (!ec->frame) return EINA_FALSE;
+   if (ec->is_magnifier) return EINA_FALSE;
+   if (ec->magnifier_proxy)
+     {
+        ELOGF("MAGNIFIER", "Aready magnifier proxy exist... proxy:%p", ec, ec->magnifier_proxy);
+        return EINA_FALSE;
+     }
+
+   ec->magnifier_proxy = evas_object_image_filled_add(e_comp->evas);
+   if (!ec->magnifier_proxy)
+     {
+        ELOGF("MAGNIFIER", "CAN NOT make PROXY object..", ec);
+        return EINA_FALSE;
+     }
+
+   ELOGF("MAGNIFIER", "New PROXY object.. proxy:%p", ec, ec->magnifier_proxy);
+
+   ret = evas_object_image_source_set(ec->magnifier_proxy, ec->frame);
+   if (!ret)
+     {
+        ELOGF("MAGNIFIER", "Fail to set image source to PROXY object..", ec);
+        return EINA_FALSE;
+     }
+
+   evas_object_image_source_events_set(ec->magnifier_proxy, EINA_TRUE);
+   evas_object_image_source_clip_set(ec->magnifier_proxy, EINA_FALSE);
+
+   evas_object_move(ec->magnifier_proxy, ec->x, ec->y);
+   evas_object_resize(ec->magnifier_proxy, ec->w, ec->h);
+
+   evas_object_show(ec->magnifier_proxy);
+
+   return EINA_TRUE;   
+}
+
+static void
+_e_magnifier_proxy_ec_del(E_Client *ec)
+{
+   if (!ec) return;
+   if (!ec->magnifier_proxy) return;
+
+   ELOGF("MAGNIFIER", "Delete PROXY object.. proxy:%p", ec, ec->magnifier_proxy);
+
+   evas_object_del(ec->magnifier_proxy);
+   ec->magnifier_proxy = NULL;
+}
+
+static Eina_Bool
+_e_magnifier_proxy_ec_all_add(E_Desk *desk)
+{
+   E_Client *ec = NULL;
+   Eina_Bool ret;
+
+   if (!desk) return EINA_FALSE;
+
+   E_CLIENT_FOREACH(ec)
+     {
+        if (e_client_util_ignored_get(ec)) continue;
+        if (ec->desk != desk) continue;
+        if (!ec->frame) continue;
+        if (ec->is_magnifier) continue;
+
+        ret = _e_magnifier_proxy_ec_new(ec);
+        if (!ret) continue;
+
+        e_magnifier_smart_member_add(desk, ec->magnifier_proxy);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_magnifier_proxy_ec_all_remove(void)
+{
+   E_Client *ec = NULL;
+
+   E_CLIENT_FOREACH(ec)
+     {
+        e_magnifier_smart_member_del(ec->magnifier_proxy);
+        _e_magnifier_proxy_ec_del(ec);
+     }
+
+   return EINA_TRUE;
+}
+
+static void
+_e_magnifier_smart_member_reorder(E_Desk *desk)
+{
+   E_Client *ec;
+   Evas_Object *proxy;
+   Evas_Object *smart_parent;
+
+   E_CLIENT_FOREACH(ec)
+     {
+        proxy = ec->magnifier_proxy;
+        if (!proxy) continue;
+
+        smart_parent = evas_object_smart_parent_get(proxy);
+        if (smart_parent == _e_magnifier_mgr)
+          {
+             evas_object_raise(proxy);
+          }
+     }
+}
+
+static void
+_e_magnifier_calculate_zoom_geometry(E_Magnifier_Zoom_Ratio ratio, int x, int y, int w, int h, int *nx, int *ny, int *nw, int *nh)
+{
+   if (!nx || !ny || !nw || !nh)
+     return;
+
+   switch (ratio)
+     {
+      case E_MAGNIFIER_ZOOM_RATIO_100:
+         // zoom 1.0
+         *nx = x;
+         *ny = y;
+         *nw = w;
+         *nh = h;
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_110:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_120:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_130:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_140:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_150:
+         // zoom 1.5
+         *nx = x + (w/8);
+         *ny = y + (h/8);
+         *nw = w * 0.67;
+         *nh = h * 0.67;
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_160:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_170:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_180:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_190:
+         // TODO: need to implement
+         break;
+      case E_MAGNIFIER_ZOOM_RATIO_200:
+         *nx = x + (w/4);
+         *ny = y + (h/4);
+         *nw = w/2;
+         *nh = h/2;
+         break;
+      default:
+         break;
+     }
+}
+
+static void
+_e_magnifier_apply_zoom(Evas_Object *zoom_obj)
+{
+   if (!zoom_obj) return;
+
+   E_Magnifier_Zoom_Ratio zoom_ratio;
+   int x, y, w, h;
+   int mx, my, mw, mh;
+   Evas_Map *map;
+
+   //Evas Map
+   map = evas_map_new(4);
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd);
+
+   x = sd->geom.system.x;
+   y = sd->geom.system.y;
+   w = sd->geom.system.w;
+   h = sd->geom.system.h;
+
+   mx = sd->geom.system.x;
+   my = sd->geom.system.y;
+   mw = sd->geom.system.w;
+   mh = sd->geom.system.h;
+
+   evas_map_point_coord_set(map, 0, x, y, 0);
+   evas_map_point_coord_set(map, 1, x + w, y, 0);
+   evas_map_point_coord_set(map, 2, x + w, y + h, 0);
+   evas_map_point_coord_set(map, 3, x, y + h, 0);
+
+   //ELOGF("MAGNIFIER", "zoom_obj(%p) sd->geom.system(%d,%d,%d,%d)", NULL, zoom_obj, x, y, w, h);
+
+   zoom_ratio = sd->ratio;
+   _e_magnifier_calculate_zoom_geometry(zoom_ratio, x, y, w, h, &mx, &my, &mw, &mh);
+
+   //ELOGF("MAGNIFIER", "zoom_obj(%p) uv set(%d,%d,%d,%d)", NULL, zoom_obj, mx, my, mw, mh);
+
+   evas_map_point_image_uv_set(map, 0, mx, my);
+   evas_map_point_image_uv_set(map, 1, mx+mw, my);
+   evas_map_point_image_uv_set(map, 2, mx+mw, my+mh);
+   evas_map_point_image_uv_set(map, 3, mx, my+mh);
+
+   // apply Evas Map to btn
+   evas_object_map_set(zoom_obj, map);
+   evas_object_map_enable_set(zoom_obj, EINA_TRUE);
+
+   // Remove Map
+   evas_map_free(map);
+}
+
+static void
+_e_magnifier_smart_set_user(Evas_Smart_Class *sc)
+{
+   sc->add = _e_magnifier_smart_add;
+   sc->del = _e_magnifier_smart_del;
+}
+
+static Eina_Bool
+_e_magnifier_smart_client_cb_add(void *data, int type, void *event)
+{
+   E_Event_Client *ev;
+   E_Client *ec = NULL;
+
+   if (!data) goto end;
+   if (!event) goto end;
+
+   ev = event;
+   ec = ev->ec;
+   if (!ec) goto end;
+
+   _e_magnifier_proxy_ec_new(ec);
+   e_magnifier_smart_member_add(ec->desk, ec->magnifier_proxy);
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_magnifier_smart_client_cb_remove(void *data, int type, void *event)
+{
+   E_Event_Client *ev;
+   E_Client *ec = NULL;
+
+   if (!data) goto end;
+   if (!event) goto end;
+
+   ev = event;
+   ec = ev->ec;
+   if (!ec) goto end;
+
+   if (ec->magnifier_proxy)
+     {
+        e_magnifier_smart_member_del(ec->magnifier_proxy);
+        _e_magnifier_proxy_ec_del(ec);
+     }
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_magnifier_smart_client_cb_stack(void *data, int type, void *event)
+{
+   E_Event_Client *ev;
+   E_Client *ec = NULL;
+
+   if (!data) goto end;
+   if (!event) goto end;
+
+   ev = event;
+   ec = ev->ec;
+   if (!ec) goto end;
+
+   _e_magnifier_smart_member_reorder(ec->desk);
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_magnifier_smart_client_cb_show(void *data, int type, void *event)
+{
+   E_Event_Client *ev;
+   E_Client *ec = NULL;
+
+   if (!data) goto end;
+   if (!event) goto end;
+
+   ev = event;
+   ec = ev->ec;
+   if (!ec) goto end;
+
+   if (ec->magnifier_proxy)
+     {
+        evas_object_show(ec->magnifier_proxy);
+     }
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_magnifier_smart_client_cb_hide(void *data, int type, void *event)
+{
+   E_Event_Client *ev;
+   E_Client *ec = NULL;
+
+   if (!data) goto end;
+   if (!event) goto end;
+
+   ev = event;
+   ec = ev->ec;
+   if (!ec) goto end;
+
+   if (ec->magnifier_proxy)
+     {
+        evas_object_hide(ec->magnifier_proxy);
+     }
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_e_magnifier_smart_add(Evas_Object *obj)
+{
+   EVAS_SMART_DATA_ALLOC(obj, E_Magnifier_Smart_Data);
+
+   /* to apply zoom transformation whenever the client's size is changed. */
+   E_LIST_HANDLER_APPEND(priv->handlers, E_EVENT_CLIENT_ADD, _e_magnifier_smart_client_cb_add, priv);
+   E_LIST_HANDLER_APPEND(priv->handlers, E_EVENT_CLIENT_REMOVE, _e_magnifier_smart_client_cb_remove, priv);
+   E_LIST_HANDLER_APPEND(priv->handlers, E_EVENT_CLIENT_STACK, _e_magnifier_smart_client_cb_stack, priv);
+   E_LIST_HANDLER_APPEND(priv->handlers, E_EVENT_CLIENT_SHOW, _e_magnifier_smart_client_cb_show, priv);
+   E_LIST_HANDLER_APPEND(priv->handlers, E_EVENT_CLIENT_HIDE, _e_magnifier_smart_client_cb_hide, priv);
+
+   /* FIXME hard coded, it will be laid upper than unpacked clients */
+   evas_object_layer_set(obj, E_LAYER_DESK_OBJECT_BELOW);
+
+   _e_magnifier_parent_sc->add(obj);
+}
+
+static void
+_e_magnifier_smart_del(Evas_Object *obj)
+{
+   _e_magnifier_parent_sc->del(obj);
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(obj, sd);
+
+   E_FREE_LIST(sd->handlers, ecore_event_handler_del);
+   free(sd);
+
+   evas_object_smart_data_set(obj, NULL);
+}
+
+static void
+_e_magnifier_cb_mouse_move_proxy(void *data,
+                                 Evas *e EINA_UNUSED,
+                                 Evas_Object *obj,
+                                 void *event_info)
+{
+   Evas_Event_Mouse_Move *ev = event_info;
+   Evas_Object *target_obj;
+   int w, h;
+   int nx, ny;
+
+   target_obj = _e_magnifier_mgr;
+   if (!target_obj) return;
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd);
+
+   w = sd->geom.system.w;
+   h = sd->geom.system.h;
+
+   nx = ev->cur.output.x - (w/2);
+   ny = ev->cur.output.y - (h/2);
+
+   sd->geom.system.x = nx;
+   sd->geom.system.y = ny;
+
+   _e_magnifier_apply_zoom(_e_magnifier_mgr);
+}
+
+static void
+_e_magnifier_cb_mouse_down_proxy(void *data,
+                                 Evas *e EINA_UNUSED,
+                                 Evas_Object *obj,
+                                 void *event_info)
+{
+   Evas_Object *target_obj;
+
+   target_obj = _e_magnifier_mgr;
+   if (!target_obj) return;
+
+   evas_object_event_callback_add(target_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_magnifier_cb_mouse_move_proxy, NULL);
+}
+
+static void
+_e_magnifier_cb_mouse_up_proxy(void *data,
+                               Evas *e EINA_UNUSED,
+                               Evas_Object *obj,
+                               void *event_info)
+{
+   Evas_Object *target_obj;
+
+   target_obj = _e_magnifier_mgr;
+   if (!target_obj) return;
+
+   evas_object_event_callback_del(target_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_magnifier_cb_mouse_move_proxy);
+}
+
+static void
+_e_magnifier_zoom_obj_geometry_convert_set(int angle, int x, int y, int w, int h, int tx, int ty, int tw, int th)
+{
+   int nx, ny, nw, nh;
+
+   switch (angle)
+     {
+      case 90:
+         // TODO: need to implement
+
+      case 180:
+         // TODO: need to implement
+
+      case 270:
+         // TODO: need to implement
+
+      case 0:
+      default:
+         nx = x + tx;
+         ny = y + ty;
+         nw = w;
+         nh = h;
+         break;
+     }
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd);
+
+   sd->geom.user.x = nx;
+   sd->geom.user.y = ny;
+   sd->geom.user.w = nw;
+   sd->geom.user.h = nh;
+
+   //   ELOGF("MAGNIFIER", "New position.. (%d,%d,%dx%d)", NULL, nx, ny, nw, nh);
+   _e_magnifier_apply_zoom(_e_magnifier_mgr);
+}
+
+
+
+static void
+_e_magnifier_cb_owner_move_resize(void *data EINA_UNUSED,
+                                  Evas *e EINA_UNUSED,
+                                  Evas_Object *obj,
+                                  void *event_info EINA_UNUSED)
+{
+   int x, y, w, h;
+   int nx, ny, nw, nh;
+
+   evas_object_geometry_get(obj, &x, &y, &w, &h);
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd);
+
+   // TODO: Need to check rotation...
+   nx = x + sd->geom.user.x;
+   ny = y + sd->geom.user.y;
+   nw = sd->geom.user.w;
+   nh = sd->geom.user.h;
+
+   sd->geom.system.x = nx;
+   sd->geom.system.y = ny;
+   sd->geom.system.w = nw;
+   sd->geom.system.h = nh;
+
+   //ELOGF("MAGNIFIER", "Magnifier Owner MoveResize (%,%d,%dx%d). Apply Geometry (%d,%d,%dx%d)", NULL, x, y, w, h, nx, ny, nw, nh);
+   _e_magnifier_apply_zoom(_e_magnifier_mgr);
+}
+
+
+EINTERN int
+e_magnifier_init(void)
+{
+   return 1;
+}
+
+EINTERN int
+e_magnifier_shutdown(void)
+{
+   return 1;
+}
+
+E_API Eina_Bool
+e_magnifier_new(void)
+{
+   ELOGF("MAGNIFIER", "NEW Magnifier", NULL);
+
+   _e_magnifier_smart_init();
+
+   E_Zone *zone;
+   E_Desk *desk;
+
+   zone = e_zone_current_get();
+   desk = e_desk_current_get(zone);
+
+   _e_magnifier_proxy_ec_all_add(desk);
+
+   return EINA_TRUE;
+}
+
+E_API void
+e_magnifier_del(void)
+{
+   ELOGF("MAGNIFIER", "DELETE Magnifier", NULL);
+
+   _e_magnifier_proxy_ec_all_remove();
+
+   if (_e_magnifier_mgr)
+     {
+        evas_object_del(_e_magnifier_mgr);
+        _e_magnifier_mgr = NULL;
+     }
+}
+
+E_API void
+e_magnifier_show(void)
+{
+   Evas_Object *target_obj;
+
+   ELOGF("MAGNIFIER", "SHOW Magnifier", NULL);
+   evas_object_show(_e_magnifier_mgr);
+
+   _e_magnifier_apply_zoom(_e_magnifier_mgr);
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd);
+
+   if (sd->stand_alone_mode)
+     {
+        target_obj = _e_magnifier_mgr;
+
+        evas_object_event_callback_add(target_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_magnifier_cb_mouse_down_proxy, NULL);
+        evas_object_event_callback_add(target_obj, EVAS_CALLBACK_MOUSE_UP, _e_magnifier_cb_mouse_up_proxy, NULL);
+     }
+}
+
+E_API void
+e_magnifier_hide(void)
+{
+   Evas_Object *target_obj;
+
+   ELOGF("MAGNIFIER", "HIDE Magnifier", NULL);
+   evas_object_hide(_e_magnifier_mgr);
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd);
+   if (sd->stand_alone_mode)
+     {
+        target_obj = _e_magnifier_mgr;
+
+        evas_object_event_callback_del(target_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_magnifier_cb_mouse_down_proxy);
+        evas_object_event_callback_del(target_obj, EVAS_CALLBACK_MOUSE_UP, _e_magnifier_cb_mouse_up_proxy);
+     }
+}
+
+E_API Eina_Bool
+e_magnifier_zoom_obj_ratio_set(E_Client* ec, E_Magnifier_Zoom_Ratio ratio)
+{
+   if ((ratio < E_MAGNIFIER_ZOOM_RATIO_100) ||
+       (ratio > E_MAGNIFIER_ZOOM_RATIO_200))
+     return EINA_FALSE;
+
+   E_MAGNIFIER_SMART_DATA_GET_OR_RETURN(_e_magnifier_mgr, sd) EINA_FALSE;
+   sd->ratio = ratio;
+
+   _e_magnifier_apply_zoom(_e_magnifier_mgr);
+
+   return EINA_TRUE;
+}
+
+E_API Eina_Bool
+e_magnifier_zoom_obj_geometry_set(E_Client *ec, int angle, int x, int y, int w, int h)
+{
+   if (!ec) return EINA_FALSE;
+
+   ELOGF("MAGNIFIER", "Zoom obj geometry set (%d,%d,%dx%d)", ec, x, y, w, h);
+
+   E_Desk *desk = NULL;
+   int tx, ty, tw, th;
+
+   tx = ec->zone->x;
+   ty = ec->zone->y;
+   tw = ec->zone->w;
+   th = ec->zone->h;
+
+   if (e_config->use_desk_smart_obj)
+     {
+        desk = e_desk_current_get(ec->zone);
+        if (desk)
+          {
+             tx = desk->geom.x;
+             ty = desk->geom.y;
+             tw = desk->geom.w;
+             th = desk->geom.h;
+          }
+     }
+
+   _e_magnifier_zoom_obj_geometry_convert_set(angle, x, y, w, h, tx, ty, tw, th);
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_magnifier_smart_member_add(E_Desk *desk, Evas_Object *obj)
+{
+   E_OBJECT_CHECK_RETURN(desk, EINA_FALSE);
+   E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, EINA_FALSE);
+
+   ELOGF("WAYFORU", "MAGNIFIER.... SMART MEMBER ADD... obj:%p", NULL, obj);
+   evas_object_smart_member_add(obj, _e_magnifier_mgr);
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_magnifier_smart_member_del(Evas_Object *obj)
+{
+   Evas_Object *parent = NULL;
+
+   if (!obj) return EINA_FALSE;
+   parent = evas_object_smart_parent_get(obj);
+
+   ELOGF("WAYFORU", "MAGNIFIER.... SMART MEMBER DEL... obj:%p", NULL, obj);
+
+   if (parent != _e_magnifier_mgr)
+     return EINA_FALSE;
+
+   ELOGF("WAYFORU", "MAGNIFIER.... SMART MEMBER DEL... obj:%p", NULL, obj);
+
+   evas_object_smart_member_del(obj);
+   return EINA_TRUE;
+}
+
+E_API Eina_Bool
+e_magnifier_owner_set(E_Client *ec)
+{
+   if (!ec) return EINA_FALSE;
+
+   ELOGF("MAGNIFIER", "SET Magnifier Owner", ec);
+
+   ec->is_magnifier = EINA_TRUE;
+   ec->exp_iconify.deiconify_update = EINA_FALSE;
+   evas_object_layer_set(ec->frame, E_LAYER_CLIENT_ALERT_HIGH);
+
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE, _e_magnifier_cb_owner_move_resize, NULL);
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE, _e_magnifier_cb_owner_move_resize, NULL);
+
+   return EINA_TRUE;
+}
diff --git a/src/bin/e_magnifier.h b/src/bin/e_magnifier.h
new file mode 100644 (file)
index 0000000..4cc52c1
--- /dev/null
@@ -0,0 +1,44 @@
+# ifdef E_TYPEDEFS
+typedef enum _E_Magnifier_Zoom_Ratio
+{
+   E_MAGNIFIER_ZOOM_RATIO_100 = 100,
+   E_MAGNIFIER_ZOOM_RATIO_110 = 110,
+   E_MAGNIFIER_ZOOM_RATIO_120 = 120,
+   E_MAGNIFIER_ZOOM_RATIO_130 = 130,
+   E_MAGNIFIER_ZOOM_RATIO_140 = 140,
+   E_MAGNIFIER_ZOOM_RATIO_150 = 150,
+   E_MAGNIFIER_ZOOM_RATIO_160 = 160,
+   E_MAGNIFIER_ZOOM_RATIO_170 = 170,
+   E_MAGNIFIER_ZOOM_RATIO_180 = 180,
+   E_MAGNIFIER_ZOOM_RATIO_190 = 190,
+   E_MAGNIFIER_ZOOM_RATIO_200 = 200,
+} E_Magnifier_Zoom_Ratio;
+# else
+
+# ifndef E_MAGNIFIER_H
+# define E_MAGNIFIER_H
+
+#define E_MAGNIFIER_SMART_OBJ_TYPE "E_Magnifier_Smart_Object"
+
+EINTERN int       e_magnifier_init(void);
+EINTERN int       e_magnifier_shutdown(void);
+
+E_API Eina_Bool   e_magnifier_new(void);
+E_API void        e_magnifier_del(void);
+
+E_API void        e_magnifier_show(void);
+E_API void        e_magnifier_hide(void);
+
+E_API Eina_Bool   e_magnifier_zoom_obj_ratio_set(E_Client *ec, E_Magnifier_Zoom_Ratio ratio);
+E_API Eina_Bool   e_magnifier_zoom_obj_geometry_set(E_Client *ec, int angle, int x, int y, int w, int h);
+
+EINTERN Eina_Bool e_magnifier_smart_member_add(E_Desk *desk, Evas_Object *obj);
+EINTERN Eina_Bool e_magnifier_smart_member_del(Evas_Object *obj);
+
+E_API Eina_Bool   e_magnifier_owner_set(E_Client *ec);
+
+#endif
+#endif
+
+
+
index 6d2af90fe69c01c94ff01e02bbe30747e525731e..8ea60671cdf153fada8dc02ed2cb71cd959f365f 100644 (file)
@@ -585,6 +585,7 @@ main(int argc, char **argv)
    e_zone_init();
    e_desk_init();
    e_slot_init();
+   e_magnifier_init();
 
    TRACE_DS_BEGIN(MAIN:WAIT /dev/dri/card0);
    if (e_config->sleep_for_dri)
@@ -1104,6 +1105,7 @@ _e_main_screens_shutdown(void)
    e_comp_shutdown();
    e_client_shutdown();
 
+   e_magnifier_shutdown();
    e_slot_shutdown();
    e_desk_shutdown();
    e_zone_shutdown();
index aeaf14fb7970f9c5f2d73a33835e178ec28275ec..dc51a55f9132e1e077346d334236e66be6b92158 100644 (file)
@@ -706,6 +706,15 @@ _e_policy_cb_hook_client_eval_pre_new_client(void *d EINA_UNUSED, E_Client *ec)
      {
         ec->exp_iconify.skip_iconify = EINA_TRUE;
      }
+
+   if (e_policy_client_is_magnifier(ec))
+     {
+        if (ec->frame)
+          {
+             if (ec->layer != E_LAYER_CLIENT_ALERT_HIGH)
+               evas_object_layer_set(ec->frame, E_LAYER_CLIENT_ALERT_HIGH);
+          }
+     }
 }
 
 static void
@@ -1823,6 +1832,15 @@ e_policy_client_is_floating(E_Client *ec)
    return ec->floating;
 }
 
+Eina_Bool
+e_policy_client_is_magnifier(E_Client *ec)
+{
+   E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
+   E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
+
+   return ec->is_magnifier;
+}
+
 Eina_Bool
 e_policy_client_is_cursor(E_Client *ec)
 {
index f26edb185f01ba8bc82395c444fca6195244596a..d4d27df062fdc9988ff1c79320c783f21427c4fc 100644 (file)
@@ -183,6 +183,7 @@ E_API Eina_Bool        e_policy_client_is_volume(E_Client *ec);
 E_API Eina_Bool        e_policy_client_is_volume_tv(E_Client *ec);
 E_API Eina_Bool        e_policy_client_is_noti(E_Client *ec);
 E_API Eina_Bool        e_policy_client_is_floating(E_Client *ec);
+E_API Eina_Bool        e_policy_client_is_magnifier(E_Client *ec);
 E_API Eina_Bool        e_policy_client_is_cursor(E_Client *ec);
 E_API Eina_Bool        e_policy_client_is_subsurface(E_Client *ec);
 E_API Eina_Bool        e_policy_client_is_cbhm(E_Client *ec);
index 22c763cfd37c6572596793330f1171818f8065a3..c425f3586f6bef2e1dadfc8b6bed80cb80328dcf 100644 (file)
@@ -33,6 +33,7 @@ typedef enum _Tzsh_Srv_Role
    TZSH_SRV_ROLE_SCREENSAVER,
    TZSH_SRV_ROLE_CBHM,
    TZSH_SRV_ROLE_SOFTKEY,
+   TZSH_SRV_ROLE_MAGNIFIER,
    TZSH_SRV_ROLE_MAX
 } Tzsh_Srv_Role;
 
@@ -612,6 +613,16 @@ _e_policy_wl_tzsh_srv_del(E_Policy_Wl_Tzsh_Srv *tzsh_srv)
              e_service_softkey_client_unset(softkey_ec);
           }
      }
+   else if (tzsh_srv->role == TZSH_SRV_ROLE_MAGNIFIER)
+     {
+        E_Client *magnifier_ec = NULL;
+
+        magnifier_ec = tzsh_srv->tzsh->ec;
+        if (magnifier_ec)
+          {
+             e_magnifier_del();
+          }
+     }
 
    memset(tzsh_srv, 0x0, sizeof(E_Policy_Wl_Tzsh_Srv));
    E_FREE(tzsh_srv);
@@ -633,6 +644,7 @@ _e_policy_wl_tzsh_srv_role_get(const char *name)
    else if (!e_util_strcmp(name, "screensaver"              )) role = TZSH_SRV_ROLE_SCREENSAVER;
    else if (!e_util_strcmp(name, "cbhm"                     )) role = TZSH_SRV_ROLE_CBHM;
    else if (!e_util_strcmp(name, "softkey"                  )) role = TZSH_SRV_ROLE_SOFTKEY;
+   else if (!e_util_strcmp(name, "magnifier"                )) role = TZSH_SRV_ROLE_MAGNIFIER;
 
    return role;
 }
@@ -3662,6 +3674,99 @@ _tzsh_srv_iface_cb_softkey_get(struct wl_client *client, struct wl_resource *res
    wl_resource_set_implementation(res, &_tzsh_srv_softkey_iface, tzsh_srv, NULL);
 }
 
+static void
+_tzsh_srv_magnifier_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_tzsh_srv_magnifier_cb_zoom_geometry_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t angle, int32_t x, int32_t y, uint32_t w, uint32_t h)
+{
+   E_Policy_Wl_Tzsh_Srv *tzsh_srv;
+   E_Client *ec;
+
+   tzsh_srv = wl_resource_get_user_data(resource);
+
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh->ec);
+
+   ELOGF("TZSH", "[MAGNIFIER] Set Geometry. angle:%d, geo:%d,%d,%dx%d", tzsh_srv->tzsh->ec, angle, x, y, w, h);
+
+   ec = tzsh_srv->tzsh->ec;
+   // angle: 0, 90, 180, 270
+   e_magnifier_zoom_obj_geometry_set(ec, angle, x, y, w, h);
+}
+
+static void
+_tzsh_srv_magnifier_cb_ratio_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t ratio)
+{
+   E_Policy_Wl_Tzsh_Srv *tzsh_srv;
+   E_Client *ec;
+
+   tzsh_srv = wl_resource_get_user_data(resource);
+
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh->ec);
+
+   ELOGF("TZSH", "[MAGNIFIER] Set Ratio. ratio:%d", tzsh_srv->tzsh->ec, ratio);
+
+   ec = tzsh_srv->tzsh->ec;
+   // ratio : 100 ~ 200 (each 10)
+   e_magnifier_zoom_obj_ratio_set(ec, ratio);
+}
+
+static void
+_tzsh_srv_magnifier_cb_enable_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t enable)
+{
+   E_Policy_Wl_Tzsh_Srv *tzsh_srv;
+
+   tzsh_srv = wl_resource_get_user_data(resource);
+
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
+   EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh->ec);
+
+   ELOGF("TZSH", "[MAGNIFIER] Set Enable. enable:%d", tzsh_srv->tzsh->ec, enable);
+
+   if (enable)
+     e_magnifier_show();
+   else
+     e_magnifier_hide();
+}
+
+static const struct tws_service_magnifier_interface _tzsh_srv_magnifier_iface =
+{
+   _tzsh_srv_magnifier_cb_destroy,
+   _tzsh_srv_magnifier_cb_zoom_geometry_set,
+   _tzsh_srv_magnifier_cb_ratio_set,
+   _tzsh_srv_magnifier_cb_enable_set,
+};
+
+static void
+_tzsh_srv_iface_cb_magnifier_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;
+
+   res = wl_resource_create(client, &tws_service_magnifier_interface, 1, id);
+   if (!res)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   ELOGF("TZSH", "[MAGNIFIER] resource created. res:%p, res_tzsh_srv:%p, id:%d", NULL, res, res_tzsh_srv, id);
+   wl_resource_set_implementation(res, &_tzsh_srv_magnifier_iface, tzsh_srv, NULL);
+}
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 static void
@@ -3893,6 +3998,7 @@ static const struct tws_service_interface _tzsh_srv_iface =
    _tzsh_srv_iface_cb_scrsaver_get,
    _tzsh_srv_iface_cb_cbhm_get,
    _tzsh_srv_iface_cb_softkey_get,
+   _tzsh_srv_iface_cb_magnifier_get,
 };
 
 static void
@@ -4025,6 +4131,11 @@ _tzsh_iface_cb_srv_create(struct wl_client *client, struct wl_resource *res_tzsh
      e_service_cbhm_client_set(tzsh->ec);
    else if (role == TZSH_SRV_ROLE_SOFTKEY)
      e_service_softkey_client_set(tzsh->ec);
+   else if (role == TZSH_SRV_ROLE_MAGNIFIER)
+     {
+        e_magnifier_new();
+        e_magnifier_owner_set(tzsh->ec);
+     }
 }
 
 // --------------------------------------------------------