support a edge_drag gesture 57/141657/2
authorJengHyun Kang <jhyuni.kang@samsung.com>
Fri, 28 Jul 2017 03:07:45 +0000 (12:07 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Tue, 1 Aug 2017 08:25:57 +0000 (17:25 +0900)
Change-Id: I87a20321e01c9c2fb56835d564ef08f9a8686a11

src/e_mod_gesture_conf.c
src/e_mod_gesture_events.c
src/e_mod_main.c
src/e_mod_main.h

index d2e74e1..837adf2 100644 (file)
@@ -19,6 +19,10 @@ _e_gesture_conf_value_check(E_Gesture_Config_Data* gconfig)
    if (conf->edge_swipe.compose_key <= 0) conf->edge_swipe.compose_key = E_GESTURE_EDGE_SWIPE_COMBINE_KEY;
    if (conf->edge_swipe.back_key <= 0) conf->edge_swipe.back_key = E_GESTURE_EDGE_SWIPE_BACK_KEY;
 
+   if (conf->edge_drag.time_begin <= 0.0) conf->edge_drag.time_begin = E_GESTURE_EDGE_DRAG_START_TIME;
+   if (conf->edge_drag.area_offset <= 0) conf->edge_drag.area_offset = E_GESTURE_EDGE_DRAG_START_AREA;
+   if (conf->edge_drag.diff_length <= 0) conf->edge_drag.diff_length = E_GESTURE_EDGE_DRAG_DIFF;
+
    if (conf->tap.repeats_max <= 0) conf->tap.repeats_max = E_GESTURE_TAP_REPEATS_MAX;
    if (conf->tap.time_start <= 0.0) conf->tap.time_start = E_GESTURE_TAP_START_TIME;
    if (conf->tap.time_done <= 0.0) conf->tap.time_done = E_GESTURE_TAP_DONE_TIME;
@@ -51,6 +55,10 @@ e_gesture_conf_init(E_Gesture_Config_Data *gconfig)
    E_CONFIG_VAL(D, T, edge_swipe.back_key, INT);
    E_CONFIG_VAL(D, T, edge_swipe.default_enable_back, CHAR);
 
+   E_CONFIG_VAL(D, T, edge_drag.time_begin, DOUBLE);
+   E_CONFIG_VAL(D, T, edge_drag.area_offset, INT);
+   E_CONFIG_VAL(D, T, edge_drag.diff_length, INT);
+
    E_CONFIG_VAL(D, T, tap.repeats_max, INT);
    E_CONFIG_VAL(D, T, tap.time_start, DOUBLE);
    E_CONFIG_VAL(D, T, tap.time_done, DOUBLE);
index 4698392..13f2b36 100644 (file)
@@ -28,6 +28,8 @@ _e_gesture_event_print(void)
 }
 #endif //_E_GESTURE_DEBUG_
 
+static void _e_gesture_send_edge_drag(int fingers, int x, int y, int edge, int mode);
+
 static void
 _e_gesture_event_queue(int type, void *event)
 {
@@ -121,6 +123,108 @@ _e_gesture_event_drop(void)
 }
 
 static void
+_e_gesture_util_center_axis_get(int num_finger, int *x, int *y)
+{
+   int i;
+   int calc_x = 0, calc_y = 0;
+
+   if (num_finger <= 0)
+     {
+        *x = 0;
+        *y = 0;
+        return;
+     }
+
+   for (i = 1; i <= num_finger; i++)
+     {
+        calc_x += gesture->gesture_events.base_point[i].axis.x;
+        calc_y += gesture->gesture_events.base_point[i].axis.y;
+     }
+
+   calc_x = (int)(calc_x / num_finger);
+   calc_y = (int)(calc_y / num_finger);
+
+   *x = calc_x;
+   *y = calc_y;
+}
+
+static double
+_e_gesture_util_distance_get(int x1, int y1, int x2, int y2)
+{
+   double distance;
+
+   distance = sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
+
+   return distance;
+}
+
+static double
+_e_gesture_util_distances_get(int num_finger)
+{
+   int i, cx = 0, cy = 0;
+   double distance = 0.0;
+
+   _e_gesture_util_center_axis_get(num_finger, &cx, &cy);
+
+   for (i = 1; i <= num_finger; i++)
+     {
+        distance +=  _e_gesture_util_distance_get(cx, cy,
+                       gesture->gesture_events.base_point[i].axis.x,
+                       gesture->gesture_events.base_point[i].axis.y);
+     }
+
+   return distance;
+}
+
+static double
+_e_gesture_util_angle_get(int x1, int y1, int x2, int y2)
+{
+   double angle, xx, yy;
+
+   xx = fabs(x2 - x1);
+   yy = fabs(y2 - y1);
+
+   angle = atan2(yy, xx);
+   if ((x1 > x2) && (y1 > y2)) angle = angle + M_PI_2;
+   else if ((x2 > x1) && (y2 > y1)) angle = angle + M_PI_2;
+
+   angle = RAD2DEG(angle);
+   return angle;
+}
+
+static void
+_e_gesture_util_rect_get(int finger, int *x1, int *y1, int *x2, int *y2)
+{
+   int i;
+
+   *x1 = *x2 = gesture->gesture_events.base_point[1].axis.x;
+   *y1 = *y2 = gesture->gesture_events.base_point[1].axis.y;
+
+   for (i = 2; i < finger + 1; i++)
+     {
+        if (gesture->gesture_events.base_point[i].axis.x < *x1)
+          *x1 = gesture->gesture_events.base_point[i].axis.x;
+        else if (gesture->gesture_events.base_point[i].axis.x > *x2)
+          *x2 = gesture->gesture_events.base_point[i].axis.x;
+
+        if (gesture->gesture_events.base_point[i].axis.y < *y1)
+          *y1 = gesture->gesture_events.base_point[i].axis.y;
+        else if (gesture->gesture_events.base_point[i].axis.y > *y2)
+          *y2 = gesture->gesture_events.base_point[i].axis.y;
+     }
+}
+
+static struct wl_resource *
+_e_gesture_util_eclient_surface_get(E_Client *ec)
+{
+   if (!ec) return NULL;
+   if (e_object_is_del(E_OBJECT(ec))) return NULL;
+   if (!ec->comp_data) return NULL;
+
+   return ec->comp_data->surface;
+}
+
+static void
 _e_gesture_edge_swipe_cancel(void)
 {
    E_Gesture_Event_Edge_Swipe *edge_swipes = &gesture->gesture_events.edge_swipes;
@@ -136,8 +240,8 @@ _e_gesture_edge_swipe_cancel(void)
         edge_swipes->done_timer = NULL;
      }
 
-   edge_swipes->enabled_finger = 0x0;
-   edge_swipes->edge = E_GESTURE_EDGE_NONE;
+   edge_swipes->base.enabled_finger = 0x0;
+   edge_swipes->base.edge = E_GESTURE_EDGE_NONE;
 
    gesture->gesture_filter |= E_GESTURE_TYPE_EDGE_SWIPE;
 }
@@ -190,7 +294,7 @@ _e_gesture_send_edge_swipe(int fingers, int x, int y, int edge)
    Ecore_Event_Mouse_Button *ev_cancel;
    E_Gesture_Conf_Edd *conf = gesture->config->conf;
    Eina_List *l;
-   E_Gesture_Event_Edge_Swipe_Finger_Edge *edata;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
    E_Gesture_Event_Edge_Swipe *edge_swipes = &gesture->gesture_events.edge_swipes;
    int bp = -1;
 
@@ -228,7 +332,7 @@ _e_gesture_send_edge_swipe(int fingers, int x, int y, int edge)
         bp = y;
      }
 
-   EINA_LIST_FOREACH(edge_swipes->fingers[fingers].edge[edge], l, edata)
+   EINA_LIST_FOREACH(edge_swipes->base.fingers[fingers].edge[edge], l, edata)
      {
         if (bp >= edata->sp && bp <= edata->ep)
           {
@@ -256,27 +360,29 @@ _e_gesture_process_device_del(void *event)
 }
 
 static Eina_Bool
-_e_gesture_event_edge_swipe_edge_check(unsigned int edge)
+_e_gesture_event_edge_check(E_Gesture_Event_Edge_Finger *fingers, int type, unsigned int edge)
 {
    E_Gesture_Event_Edge_Swipe *edge_swipes = &gesture->gesture_events.edge_swipes;
-   int idx = gesture->gesture_events.num_pressed;
    E_Gesture_Conf_Edd *conf = gesture->config->conf;
    Eina_List *l;
-   E_Gesture_Event_Edge_Swipe_Finger_Edge *edata;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
    Coords coords;
 
-   if ((conf->edge_swipe.default_enable_back) &&
-       (edge == TIZEN_GESTURE_EDGE_TOP ||
-       ((edge_swipes->combined_keycode == conf->edge_swipe.compose_key) &&
-       (edge_swipes->edge == TIZEN_GESTURE_EDGE_LEFT))))
+   if (type == E_GESTURE_TYPE_EDGE_SWIPE)
      {
-        return EINA_TRUE;
+        if ((conf->edge_swipe.default_enable_back) &&
+            (edge == TIZEN_GESTURE_EDGE_TOP ||
+            ((edge_swipes->combined_keycode == conf->edge_swipe.compose_key) &&
+            (edge_swipes->base.edge == TIZEN_GESTURE_EDGE_LEFT))))
+          {
+             return EINA_TRUE;
+          }
      }
 
-   coords.x = edge_swipes->fingers[idx].start.x;
-   coords.y = edge_swipes->fingers[idx].start.y;
+   coords.x = fingers->start.x;
+   coords.y = fingers->start.y;
 
-   EINA_LIST_FOREACH(edge_swipes->fingers[idx].edge[edge], l, edata)
+   EINA_LIST_FOREACH(fingers->edge[edge], l, edata)
      {
         if (edge == TIZEN_GESTURE_EDGE_TOP ||
             edge == TIZEN_GESTURE_EDGE_BOTTOM)
@@ -308,14 +414,14 @@ _e_gesture_timer_edge_swipe_start(void *data)
    int idx = gesture->gesture_events.num_pressed;
    int i;
 
-   GTDBG("Edge_Swipe start timer is expired. Currently alived edge_swipe fingers: 0x%x\n", edge_swipes->enabled_finger);
+   GTDBG("Edge_Swipe start timer is expired. Currently alived edge_swipe fingers: 0x%x\n", edge_swipes->base.enabled_finger);
 
    for (i = E_GESTURE_FINGER_MAX; i > idx; i--)
      {
-        edge_swipes->enabled_finger &= ~(1 << i);
+        edge_swipes->base.enabled_finger &= ~(1 << i);
      }
-   if ((edge_swipes->enabled_finger == 0x0) ||
-       (_e_gesture_event_edge_swipe_edge_check(edge_swipes->edge) == EINA_FALSE))
+   if ((edge_swipes->base.enabled_finger == 0x0) ||
+       (_e_gesture_event_edge_check(&edge_swipes->base.fingers[idx], E_GESTURE_TYPE_EDGE_SWIPE, edge_swipes->base.edge) == EINA_FALSE))
      {
         if (gesture->gesture_events.event_keep)
           _e_gesture_event_flush();
@@ -329,7 +435,7 @@ _e_gesture_timer_edge_swipe_done(void *data)
 {
    E_Gesture_Event_Edge_Swipe *edge_swipes = &gesture->gesture_events.edge_swipes;
 
-   GTDBG("Edge_Swipe done timer is expired. Currently alived edge_swipe fingers: 0x%x\n", edge_swipes->enabled_finger);
+   GTDBG("Edge_Swipe done timer is expired. Currently alived edge_swipe fingers: 0x%x\n", edge_swipes->base.enabled_finger);
 
    if (gesture->gesture_events.event_keep)
      _e_gesture_event_flush();
@@ -346,7 +452,7 @@ _e_gesture_process_edge_swipe_down(Ecore_Event_Mouse_Button *ev)
    int i;
    unsigned int idx = ev->multi.device+1;
 
-   if (!edge_swipes->activation.active) return;
+   if (!edge_swipes->base.activation.active) return;
 
    if (gesture->gesture_events.recognized_gesture)
      _e_gesture_edge_swipe_cancel();
@@ -355,28 +461,28 @@ _e_gesture_process_edge_swipe_down(Ecore_Event_Mouse_Button *ev)
      {
         for (i = 1; i < E_GESTURE_FINGER_MAX+1; i++)
           {
-             if (edge_swipes->fingers[i].enabled)
+             if (edge_swipes->base.fingers[i].enabled)
                {
-                  edge_swipes->enabled_finger |= (1 << i);
+                  edge_swipes->base.enabled_finger |= (1 << i);
                }
           }
 
         if (ev->y < conf->edge_swipe.area_offset)
-          edge_swipes->edge = E_GESTURE_EDGE_TOP;
+          edge_swipes->base.edge = E_GESTURE_EDGE_TOP;
         else if (ev->y > e_comp->h - conf->edge_swipe.area_offset)
-          edge_swipes->edge = E_GESTURE_EDGE_BOTTOM;
+          edge_swipes->base.edge = E_GESTURE_EDGE_BOTTOM;
         else if (ev->x < conf->edge_swipe.area_offset)
-          edge_swipes->edge = E_GESTURE_EDGE_LEFT;
+          edge_swipes->base.edge = E_GESTURE_EDGE_LEFT;
         else if (ev->x > e_comp->w - conf->edge_swipe.area_offset)
-          edge_swipes->edge = E_GESTURE_EDGE_RIGHT;
+          edge_swipes->base.edge = E_GESTURE_EDGE_RIGHT;
 
-        if (!((1 << (edge_swipes->edge)) & edge_swipes->enabled_edge))
-          edge_swipes->edge = E_GESTURE_EDGE_NONE;
+        if (!((1 << (edge_swipes->base.edge)) & edge_swipes->base.enabled_edge))
+          edge_swipes->base.edge = E_GESTURE_EDGE_NONE;
 
-        if (edge_swipes->edge != E_GESTURE_EDGE_NONE)
+        if (edge_swipes->base.edge != E_GESTURE_EDGE_NONE)
           {
-             edge_swipes->fingers[idx].start.x = ev->x;
-             edge_swipes->fingers[idx].start.y = ev->y;
+             edge_swipes->base.fingers[idx].start.x = ev->x;
+             edge_swipes->base.fingers[idx].start.y = ev->y;
              edge_swipes->start_timer = ecore_timer_add(conf->edge_swipe.time_begin, _e_gesture_timer_edge_swipe_start, NULL);
              edge_swipes->done_timer = ecore_timer_add(conf->edge_swipe.time_done, _e_gesture_timer_edge_swipe_done, NULL);
           }
@@ -389,7 +495,7 @@ _e_gesture_process_edge_swipe_down(Ecore_Event_Mouse_Button *ev)
      }
    else
      {
-        edge_swipes->enabled_finger &= ~(1 << (gesture->gesture_events.num_pressed - 1));
+        edge_swipes->base.enabled_finger &= ~(1 << (gesture->gesture_events.num_pressed - 1));
         if (edge_swipes->start_timer == NULL)
           {
              if (gesture->gesture_events.event_keep)
@@ -407,15 +513,15 @@ _e_gesture_process_edge_swipe_move(Ecore_Event_Mouse_Move *ev)
    Coords diff;
    unsigned int idx = ev->multi.device+1;
 
-   if (!edge_swipes->activation.active) return;
+   if (!edge_swipes->base.activation.active) return;
 
-   if (!(edge_swipes->enabled_finger & (1 << idx)))
+   if (!(edge_swipes->base.enabled_finger & (1 << idx)))
      return;
 
-   diff.x = ABS(edge_swipes->fingers[idx].start.x - ev->x);
-   diff.y = ABS(edge_swipes->fingers[idx].start.y - ev->y);
+   diff.x = ABS(edge_swipes->base.fingers[idx].start.x - ev->x);
+   diff.y = ABS(edge_swipes->base.fingers[idx].start.y - ev->y);
 
-   switch(edge_swipes->edge)
+   switch(edge_swipes->base.edge)
      {
         case E_GESTURE_EDGE_TOP:
            if (diff.x > conf->edge_swipe.min_length)
@@ -427,7 +533,7 @@ _e_gesture_process_edge_swipe_move(Ecore_Event_Mouse_Move *ev)
              }
            if (diff.y > conf->edge_swipe.max_length)
              {
-                _e_gesture_send_edge_swipe(idx, edge_swipes->fingers[idx].start.x, edge_swipes->fingers[idx].start.y, E_GESTURE_EDGE_TOP);
+                _e_gesture_send_edge_swipe(idx, edge_swipes->base.fingers[idx].start.x, edge_swipes->base.fingers[idx].start.y, E_GESTURE_EDGE_TOP);
              }
            break;
         case E_GESTURE_EDGE_LEFT:
@@ -440,7 +546,7 @@ _e_gesture_process_edge_swipe_move(Ecore_Event_Mouse_Move *ev)
              }
            if (diff.x > conf->edge_swipe.max_length)
              {
-                _e_gesture_send_edge_swipe(idx, edge_swipes->fingers[idx].start.x, edge_swipes->fingers[idx].start.y, E_GESTURE_EDGE_LEFT);
+                _e_gesture_send_edge_swipe(idx, edge_swipes->base.fingers[idx].start.x, edge_swipes->base.fingers[idx].start.y, E_GESTURE_EDGE_LEFT);
              }
            break;
         case E_GESTURE_EDGE_BOTTOM:
@@ -453,7 +559,7 @@ _e_gesture_process_edge_swipe_move(Ecore_Event_Mouse_Move *ev)
              }
            if (diff.y > conf->edge_swipe.max_length)
              {
-                _e_gesture_send_edge_swipe(idx, edge_swipes->fingers[idx].start.x, edge_swipes->fingers[idx].start.y, E_GESTURE_EDGE_BOTTOM);
+                _e_gesture_send_edge_swipe(idx, edge_swipes->base.fingers[idx].start.x, edge_swipes->base.fingers[idx].start.y, E_GESTURE_EDGE_BOTTOM);
              }
            break;
         case E_GESTURE_EDGE_RIGHT:
@@ -466,11 +572,11 @@ _e_gesture_process_edge_swipe_move(Ecore_Event_Mouse_Move *ev)
              }
            if (diff.x > conf->edge_swipe.max_length)
              {
-                _e_gesture_send_edge_swipe(idx, edge_swipes->fingers[idx].start.x, edge_swipes->fingers[idx].start.y, E_GESTURE_EDGE_RIGHT);
+                _e_gesture_send_edge_swipe(idx, edge_swipes->base.fingers[idx].start.x, edge_swipes->base.fingers[idx].start.y, E_GESTURE_EDGE_RIGHT);
              }
            break;
         default:
-           GTWRN("Invalid edge(%d)\n", edge_swipes->edge);
+           GTWRN("Invalid edge(%d)\n", edge_swipes->base.edge);
            break;
      }
 }
@@ -480,18 +586,54 @@ _e_gesture_process_edge_swipe_up(Ecore_Event_Mouse_Button *ev)
 {
    E_Gesture_Event_Edge_Swipe *edge_swipes = &gesture->gesture_events.edge_swipes;
 
-   if (!edge_swipes->activation.active) return;
+   if (!edge_swipes->base.activation.active) return;
    if (gesture->gesture_events.event_keep)
      _e_gesture_event_flush();
    _e_gesture_edge_swipe_cancel();
 }
 
 static void
-_e_gesture_pan_send(int mode, int fingers, int cx, int cy, struct wl_resource *res, struct wl_client *client)
+_e_gesture_edge_drag_cancel(void)
+{
+   E_Gesture_Event_Edge_Drag *edge_drags = &gesture->gesture_events.edge_drags;
+   Coords current_point = {0, };
+
+   if (gesture->gesture_events.recognized_gesture & E_GESTURE_TYPE_EDGE_DRAG)
+     {
+        _e_gesture_util_center_axis_get(edge_drags->idx, &current_point.x, &current_point.y);
+        _e_gesture_send_edge_drag(edge_drags->idx, current_point.x, current_point.y, edge_drags->base.edge, TIZEN_GESTURE_MODE_END);
+     }
+
+   if (edge_drags->start_timer)
+     {
+        ecore_timer_del(edge_drags->start_timer);
+        edge_drags->start_timer = NULL;
+     }
+
+   edge_drags->base.enabled_finger = 0x0;
+   edge_drags->base.edge = E_GESTURE_EDGE_NONE;
+   edge_drags->start_point.x = edge_drags->center_point.x = 0;
+   edge_drags->start_point.y = edge_drags->center_point.y = 0;
+   edge_drags->idx = 0;
+
+   gesture->gesture_filter |= E_GESTURE_TYPE_EDGE_DRAG;
+   gesture->gesture_events.recognized_gesture &= ~E_GESTURE_TYPE_EDGE_DRAG;
+}
+
+static void
+_e_gesture_send_edge_drag(int fingers, int x, int y, int edge, int mode)
 {
    Ecore_Event_Mouse_Button *ev_cancel;
+   Eina_List *l;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
+   E_Gesture_Event_Edge_Drag *edge_drags = &gesture->gesture_events.edge_drags;
+   int bp = -1;
 
-   if (mode == TIZEN_GESTURE_MODE_BEGIN)
+   if (gesture->gesture_events.event_keep)
+     {
+        _e_gesture_event_drop();
+     }
+   else
      {
         ev_cancel = E_NEW(Ecore_Event_Mouse_Button, 1);
         EINA_SAFETY_ON_NULL_RETURN(ev_cancel);
@@ -502,136 +644,211 @@ _e_gesture_pan_send(int mode, int fingers, int cx, int cy, struct wl_resource *r
         ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev_cancel, NULL, NULL);
      }
 
-   GTINF("Send pan gesture %d fingers. (%d, %d) to client: %p, mode: %d\n", fingers, cx, cy, client, mode);
+   if (edge == TIZEN_GESTURE_EDGE_TOP ||
+       edge == TIZEN_GESTURE_EDGE_BOTTOM)
+     {
+        bp = edge_drags->start_point.x;
+     }
+   else if (edge == TIZEN_GESTURE_EDGE_RIGHT ||
+       edge == TIZEN_GESTURE_EDGE_LEFT)
+     {
+        bp = edge_drags->start_point.y;
+     }
 
-   gesture->gesture_events.recognized_gesture |= E_GESTURE_TYPE_PAN;
+   EINA_LIST_FOREACH(edge_drags->base.fingers[fingers].edge[edge], l, edata)
+     {
+        if (bp >= edata->sp && bp <= edata->ep)
+          {
+             GTINF("Send edge drag gesture (fingers: %d, edge: %d) to client: %p\n", fingers, edge, edata->client);
+             tizen_gesture_send_edge_drag(edata->res, mode, fingers, x, y, edge);
+             break;
+          }
+     }
+
+   gesture->gesture_events.recognized_gesture |= E_GESTURE_TYPE_EDGE_DRAG;
 }
 
-static void
-_e_gesture_pan_cancel(void)
+static Eina_Bool
+_e_gesture_timer_edge_drag_start(void *data)
 {
-   E_Gesture_Event_Pan *pans = &gesture->gesture_events.pans;
+   E_Gesture_Event_Edge_Drag *edge_drags = &gesture->gesture_events.edge_drags;
+   int idx = gesture->gesture_events.num_pressed;
+   int i;
+   Coords start_point = {0, };
 
-   if (pans->start_timer)
+   for (i = E_GESTURE_FINGER_MAX; i > idx; i--)
      {
-        ecore_timer_del(pans->start_timer);
-        pans->start_timer = NULL;
+        edge_drags->base.enabled_finger &= ~(1 << i);
      }
-   if (pans->move_timer)
+
+   if ((edge_drags->base.enabled_finger == 0x0) ||
+       (_e_gesture_event_edge_check(&edge_drags->base.fingers[idx], E_GESTURE_TYPE_EDGE_DRAG, edge_drags->base.edge) == EINA_FALSE))
      {
-        ecore_timer_del(pans->move_timer);
-        pans->move_timer = NULL;
+        if (gesture->gesture_events.event_keep)
+          _e_gesture_event_flush();
+        _e_gesture_edge_drag_cancel();
+     }
+   else
+     {
+        _e_gesture_util_center_axis_get(idx, &start_point.x, &start_point.y);
+        edge_drags->start_point.x = edge_drags->center_point.x = start_point.x;
+        edge_drags->start_point.y = edge_drags->center_point.y = start_point.y;
+        edge_drags->idx = idx;
+        _e_gesture_send_edge_drag(edge_drags->idx, edge_drags->center_point.x, edge_drags->center_point.y, edge_drags->base.edge, TIZEN_GESTURE_MODE_BEGIN);
      }
 
-   if (pans->state == E_GESTURE_PANPINCH_STATE_MOVING)
-     _e_gesture_pan_send(TIZEN_GESTURE_MODE_END, pans->num_pan_fingers, 0, 0,
-                         pans->fingers[pans->num_pan_fingers].res,
-                         pans->fingers[pans->num_pan_fingers].client);
-
-   gesture->gesture_filter |= E_GESTURE_TYPE_PAN;
-   pans->state = E_GESTURE_PANPINCH_STATE_DONE;
+   ecore_timer_del(edge_drags->start_timer);
+   edge_drags->start_timer = NULL;
+   return ECORE_CALLBACK_CANCEL;
 }
 
 static void
-_e_gesture_util_center_axis_get(int num_finger, int *x, int *y)
+_e_gesture_process_edge_drag_down(Ecore_Event_Mouse_Button *ev)
 {
+   E_Gesture_Event_Edge_Drag *edge_drags = &gesture->gesture_events.edge_drags;
+   E_Gesture_Conf_Edd *conf = gesture->config->conf;
    int i;
-   int calc_x = 0, calc_y = 0;
+   unsigned int idx = ev->multi.device+1;
 
-   if (num_finger <= 0)
-     {
-        *x = 0;
-        *y = 0;
-        return;
-     }
+   if (!edge_drags->base.activation.active) return;
 
-   for (i = 1; i <= num_finger; i++)
+   if (gesture->gesture_events.recognized_gesture)
+     _e_gesture_edge_drag_cancel();
+
+   if (gesture->gesture_events.num_pressed == 1)
      {
-        calc_x += gesture->gesture_events.base_point[i].axis.x;
-        calc_y += gesture->gesture_events.base_point[i].axis.y;
-     }
+        for (i = 1; i < E_GESTURE_FINGER_MAX+1; i++)
+          {
+             if (edge_drags->base.fingers[i].enabled)
+               {
+                  edge_drags->base.enabled_finger |= (1 << i);
+               }
+          }
 
-   calc_x = (int)(calc_x / num_finger);
-   calc_y = (int)(calc_y / num_finger);
+        if (ev->y < conf->edge_drag.area_offset)
+          edge_drags->base.edge = E_GESTURE_EDGE_TOP;
+        else if (ev->y > e_comp->h - conf->edge_drag.area_offset)
+          edge_drags->base.edge = E_GESTURE_EDGE_BOTTOM;
+        else if (ev->x < conf->edge_drag.area_offset)
+          edge_drags->base.edge = E_GESTURE_EDGE_LEFT;
+        else if (ev->x > e_comp->w - conf->edge_drag.area_offset)
+          edge_drags->base.edge = E_GESTURE_EDGE_RIGHT;
 
-   *x = calc_x;
-   *y = calc_y;
+        if (!((1 << (edge_drags->base.edge)) & edge_drags->base.enabled_edge))
+          edge_drags->base.edge = E_GESTURE_EDGE_NONE;
+
+        if (edge_drags->base.edge != E_GESTURE_EDGE_NONE)
+          {
+             edge_drags->base.fingers[idx].start.x = ev->x;
+             edge_drags->base.fingers[idx].start.y = ev->y;
+             edge_drags->start_timer = ecore_timer_add(conf->edge_drag.time_begin, _e_gesture_timer_edge_drag_start, NULL);
+          }
+        else
+          {
+             if (gesture->gesture_events.event_keep)
+               _e_gesture_event_flush();
+             _e_gesture_edge_drag_cancel();
+          }
+     }
+   else
+     {
+        edge_drags->base.enabled_finger &= ~(1 << (gesture->gesture_events.num_pressed - 1));
+        if (edge_drags->start_timer == NULL)
+          {
+             if (gesture->gesture_events.event_keep)
+               _e_gesture_event_flush();
+             _e_gesture_edge_drag_cancel();
+          }
+     }
 }
 
-static double
-_e_gesture_util_distance_get(int x1, int y1, int x2, int y2)
+static void
+_e_gesture_process_edge_drag_move(Ecore_Event_Mouse_Move *ev)
 {
+   E_Gesture_Event_Edge_Drag *edge_drags = &gesture->gesture_events.edge_drags;
+   E_Gesture_Conf_Edd *conf = gesture->config->conf;
    double distance;
+   Coords current_point = {0, };
+   unsigned int idx = ev->multi.device+1;
 
-   distance = sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
-
-   return distance;
-}
+   if (!edge_drags->base.activation.active) return;
 
-static double
-_e_gesture_util_distances_get(int num_finger)
-{
-   int i, cx = 0, cy = 0;
-   double distance = 0.0;
+   if (!(edge_drags->base.enabled_finger & (1 << idx)))
+     return;
 
-   _e_gesture_util_center_axis_get(num_finger, &cx, &cy);
+   if (edge_drags->start_timer) return;
 
-   for (i = 1; i <= num_finger; i++)
+   _e_gesture_util_center_axis_get(gesture->gesture_events.num_pressed, &current_point.x, &current_point.y);
+   distance = _e_gesture_util_distance_get(edge_drags->center_point.x, edge_drags->center_point.y, current_point.x, current_point.y);
+   if (distance < (double)conf->edge_drag.diff_length)
      {
-        distance +=  _e_gesture_util_distance_get(cx, cy,
-                       gesture->gesture_events.base_point[i].axis.x,
-                       gesture->gesture_events.base_point[i].axis.y);
+        return;
      }
 
-   return distance;
+   edge_drags->center_point.x = current_point.x;
+   edge_drags->center_point.y = current_point.y;
+
+   _e_gesture_send_edge_drag(edge_drags->idx,
+      edge_drags->center_point.x, edge_drags->center_point.y,
+      edge_drags->base.edge, TIZEN_GESTURE_MODE_UPDATE);
 }
 
-static double
-_e_gesture_util_angle_get(int x1, int y1, int x2, int y2)
+static void
+_e_gesture_process_edge_drag_up(Ecore_Event_Mouse_Button *ev)
 {
-   double angle, xx, yy;
-
-   xx = fabs(x2 - x1);
-   yy = fabs(y2 - y1);
-
-   angle = atan2(yy, xx);
-   if ((x1 > x2) && (y1 > y2)) angle = angle + M_PI_2;
-   else if ((x2 > x1) && (y2 > y1)) angle = angle + M_PI_2;
+   E_Gesture_Event_Edge_Drag *edge_drags = &gesture->gesture_events.edge_drags;
 
-   angle = RAD2DEG(angle);
-   return angle;
+   if (!edge_drags->base.activation.active) return;
+   if (gesture->gesture_events.event_keep)
+     _e_gesture_event_flush();
+   _e_gesture_edge_drag_cancel();
 }
 
+
 static void
-_e_gesture_util_rect_get(int finger, int *x1, int *y1, int *x2, int *y2)
+_e_gesture_pan_send(int mode, int fingers, int cx, int cy, struct wl_resource *res, struct wl_client *client)
 {
-   int i;
-
-   *x1 = *x2 = gesture->gesture_events.base_point[1].axis.x;
-   *y1 = *y2 = gesture->gesture_events.base_point[1].axis.y;
+   Ecore_Event_Mouse_Button *ev_cancel;
 
-   for (i = 2; i < finger + 1; i++)
+   if (mode == TIZEN_GESTURE_MODE_BEGIN)
      {
-        if (gesture->gesture_events.base_point[i].axis.x < *x1)
-          *x1 = gesture->gesture_events.base_point[i].axis.x;
-        else if (gesture->gesture_events.base_point[i].axis.x > *x2)
-          *x2 = gesture->gesture_events.base_point[i].axis.x;
+        ev_cancel = E_NEW(Ecore_Event_Mouse_Button, 1);
+        EINA_SAFETY_ON_NULL_RETURN(ev_cancel);
 
-        if (gesture->gesture_events.base_point[i].axis.y < *y1)
-          *y1 = gesture->gesture_events.base_point[i].axis.y;
-        else if (gesture->gesture_events.base_point[i].axis.y > *y2)
-          *y2 = gesture->gesture_events.base_point[i].axis.y;
+        ev_cancel->timestamp = (int)(ecore_time_get()*1000);
+        ev_cancel->same_screen = 1;
+
+        ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev_cancel, NULL, NULL);
      }
+
+   GTINF("Send pan gesture %d fingers. (%d, %d) to client: %p, mode: %d\n", fingers, cx, cy, client, mode);
+
+   gesture->gesture_events.recognized_gesture |= E_GESTURE_TYPE_PAN;
 }
 
-static struct wl_resource *
-_e_gesture_util_eclient_surface_get(E_Client *ec)
+static void
+_e_gesture_pan_cancel(void)
 {
-   if (!ec) return NULL;
-   if (e_object_is_del(E_OBJECT(ec))) return NULL;
-   if (!ec->comp_data) return NULL;
+   E_Gesture_Event_Pan *pans = &gesture->gesture_events.pans;
 
-   return ec->comp_data->surface;
+   if (pans->start_timer)
+     {
+        ecore_timer_del(pans->start_timer);
+        pans->start_timer = NULL;
+     }
+   if (pans->move_timer)
+     {
+        ecore_timer_del(pans->move_timer);
+        pans->move_timer = NULL;
+     }
+
+   if (pans->state == E_GESTURE_PANPINCH_STATE_MOVING)
+     _e_gesture_pan_send(TIZEN_GESTURE_MODE_END, pans->num_pan_fingers, 0, 0,
+                         pans->fingers[pans->num_pan_fingers].res,
+                         pans->fingers[pans->num_pan_fingers].client);
+
+   gesture->gesture_filter |= E_GESTURE_TYPE_PAN;
+   pans->state = E_GESTURE_PANPINCH_STATE_DONE;
 }
 
 static Eina_Bool
@@ -1243,6 +1460,10 @@ _e_gesture_process_mouse_button_down(void *event)
      {
         _e_gesture_process_edge_swipe_down(ev);
      }
+   if (!(gesture->gesture_filter & E_GESTURE_TYPE_EDGE_DRAG))
+     {
+        _e_gesture_process_edge_drag_down(ev);
+     }
    if (!(gesture->gesture_filter & E_GESTURE_TYPE_PAN))
      {
         _e_gesture_process_pan_down(ev);
@@ -1285,6 +1506,10 @@ _e_gesture_process_mouse_button_up(void *event)
      {
         _e_gesture_process_edge_swipe_up(ev);
      }
+   if (!(gesture->gesture_filter & E_GESTURE_TYPE_EDGE_DRAG))
+     {
+        _e_gesture_process_edge_drag_up(ev);
+     }
    if (!(gesture->gesture_filter & E_GESTURE_TYPE_PAN))
      {
         _e_gesture_process_pan_up(ev);
@@ -1344,6 +1569,10 @@ _e_gesture_process_mouse_move(void *event)
      {
         _e_gesture_process_edge_swipe_move(ev);
      }
+   if (!(gesture->gesture_filter & E_GESTURE_TYPE_EDGE_DRAG))
+     {
+        _e_gesture_process_edge_drag_move(ev);
+     }
    if (!(gesture->gesture_filter & E_GESTURE_TYPE_PAN))
      {
         _e_gesture_process_pan_move(ev);
@@ -1498,7 +1727,7 @@ e_gesture_event_deactivate_check(void)
    if (gesture->gesture_filter == E_GESTURE_TYPE_ALL) return;
 
    if (!(gesture->gesture_filter & E_GESTURE_TYPE_EDGE_SWIPE) &&
-       gesture->gesture_events.edge_swipes.activation.active)
+       gesture->gesture_events.edge_swipes.base.activation.active)
      {
         _e_gesture_edge_swipe_cancel();
      }
index cdbc9bd..a351fc8 100644 (file)
@@ -12,17 +12,10 @@ static void _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data);
 static void _e_gesture_wl_surface_cb_destroy(struct wl_listener *l, void *data);
 
 static Eina_Bool
-_e_gesture_edge_swipe_boundary_check(E_Gesture_Event_Edge_Swipe_Finger *fingers, unsigned int edge, int sp, int ep)
+_e_gesture_edge_boundary_check(E_Gesture_Event_Edge_Finger *fingers, unsigned int edge, int sp, int ep)
 {
    Eina_List *l;
-   E_Gesture_Event_Edge_Swipe_Finger_Edge *edata;
-   E_Gesture_Conf_Edd *conf = gesture->config->conf;
-
-   if ((conf->edge_swipe.default_enable_back) &&
-       (edge == E_GESTURE_EDGE_TOP))
-     {
-        return EINA_FALSE;
-     }
+   E_Gesture_Event_Edge_Finger_Edge *edata;
 
    EINA_LIST_FOREACH(fingers->edge[edge], l, edata)
      {
@@ -34,11 +27,11 @@ _e_gesture_edge_swipe_boundary_check(E_Gesture_Event_Edge_Swipe_Finger *fingers,
 }
 
 static void
-_e_gesture_edge_swipe_grab_add(E_Gesture_Event_Edge_Swipe_Finger *fingers, struct wl_client *client, struct wl_resource *res, unsigned int edge, unsigned int sp, unsigned int ep)
+_e_gesture_edge_grab_add(E_Gesture_Event_Edge_Finger *fingers, struct wl_client *client, struct wl_resource *res, unsigned int edge, unsigned int sp, unsigned int ep)
 {
-   E_Gesture_Event_Edge_Swipe_Finger_Edge *edata;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
 
-   edata = E_NEW(E_Gesture_Event_Edge_Swipe_Finger_Edge, 1);
+   edata = E_NEW(E_Gesture_Event_Edge_Finger_Edge, 1);
    EINA_SAFETY_ON_NULL_RETURN(edata);
 
    edata->client = client;
@@ -55,9 +48,13 @@ _e_gesture_set_client_to_list(E_Gesture_Grabbed_Client *gclient, struct wl_clien
    switch (mode)
      {
         case E_GESTURE_TYPE_EDGE_SWIPE:
-           _e_gesture_edge_swipe_grab_add(&gclient->edge_swipe_fingers[fingers], client, NULL, edge, sp, ep);
+           _e_gesture_edge_grab_add(&gclient->edge_swipe_fingers[fingers], client, NULL, edge, sp, ep);
            gclient->edge_swipe_fingers[fingers].enabled = EINA_TRUE;
            break;
+        case E_GESTURE_TYPE_EDGE_DRAG:
+           _e_gesture_edge_grab_add(&gclient->edge_drag_fingers[fingers], client, NULL, edge, sp, ep);
+           gclient->edge_drag_fingers[fingers].enabled = EINA_TRUE;
+           break;
         case E_GESTURE_TYPE_TAP:
            gclient->tap_fingers[fingers].repeats[repeat].client = client;
            break;
@@ -130,12 +127,34 @@ _e_gesture_edge_swipe_current_list_check(void)
      {
         for (j = 0; j < E_GESTURE_EDGE_MAX+1; j++)
           {
-             if (eina_list_count(gev->edge_swipes.fingers[i].edge[j]) != 0)
+             if (eina_list_count(gev->edge_swipes.base.fingers[i].edge[j]) != 0)
                {
                   return;
                }
           }
-        gev->edge_swipes.fingers[i].enabled = EINA_FALSE;
+        gev->edge_swipes.base.fingers[i].enabled = EINA_FALSE;
+     }
+   gesture->grabbed_gesture &= ~E_GESTURE_TYPE_EDGE_SWIPE;
+   if (gev->event_keep) gesture->event_state = E_GESTURE_EVENT_STATE_PROPAGATE;
+}
+
+static void
+_e_gesture_edge_drag_current_list_check(void)
+{
+   int i, j;
+   E_Gesture_Event *gev;
+
+   gev = &gesture->gesture_events;
+   for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
+     {
+        for (j = 0; j < E_GESTURE_EDGE_MAX+1; j++)
+          {
+             if (eina_list_count(gev->edge_drags.base.fingers[i].edge[j]) != 0)
+               {
+                  return;
+               }
+          }
+        gev->edge_drags.base.fingers[i].enabled = EINA_FALSE;
      }
    gesture->grabbed_gesture &= ~E_GESTURE_TYPE_EDGE_SWIPE;
    if (gev->event_keep) gesture->event_state = E_GESTURE_EVENT_STATE_PROPAGATE;
@@ -682,7 +701,7 @@ _e_gesture_deactivate_cb_client_listener(struct wl_listener *l, void *data)
 {
    struct wl_client *client = data;
 
-   _e_gesture_deactivate_list_unset(client, NULL, &gesture->gesture_events.edge_swipes.activation, E_GESTURE_TYPE_EDGE_SWIPE);
+   _e_gesture_deactivate_list_unset(client, NULL, &gesture->gesture_events.edge_swipes.base.activation, E_GESTURE_TYPE_EDGE_SWIPE);
    _e_gesture_deactivate_list_unset(client, NULL, &gesture->gesture_events.taps.activation, E_GESTURE_TYPE_TAP);
    _e_gesture_deactivate_list_unset(client, NULL, &gesture->gesture_events.palm_covers.activation, E_GESTURE_TYPE_PALM_COVER);
    _e_gesture_deactivate_list_unset(client, NULL, &gesture->gesture_events.pans.activation, E_GESTURE_TYPE_PAN);
@@ -697,7 +716,7 @@ _e_gesture_deactivate_cb_surface_listener(struct wl_listener *l, void *data)
 {
    struct wl_resource *surface = data;
 
-   _e_gesture_deactivate_list_unset(NULL, surface, &gesture->gesture_events.edge_swipes.activation, E_GESTURE_TYPE_EDGE_SWIPE);
+   _e_gesture_deactivate_list_unset(NULL, surface, &gesture->gesture_events.edge_swipes.base.activation, E_GESTURE_TYPE_EDGE_SWIPE);
    _e_gesture_deactivate_list_unset(NULL, surface, &gesture->gesture_events.taps.activation, E_GESTURE_TYPE_TAP);
    _e_gesture_deactivate_list_unset(NULL, surface, &gesture->gesture_events.palm_covers.activation, E_GESTURE_TYPE_PALM_COVER);
    _e_gesture_deactivate_list_unset(NULL, surface, &gesture->gesture_events.pans.activation, E_GESTURE_TYPE_PAN);
@@ -774,7 +793,7 @@ _e_gesture_deactivate_set(struct wl_client *client,
 
    if (type & E_GESTURE_TYPE_EDGE_SWIPE)
      {
-        ret = _e_gesture_deactivate_list_set(client, surface, &gesture->gesture_events.edge_swipes.activation, E_GESTURE_TYPE_EDGE_SWIPE);
+        ret = _e_gesture_deactivate_list_set(client, surface, &gesture->gesture_events.edge_swipes.base.activation, E_GESTURE_TYPE_EDGE_SWIPE);
      }
    if (type & E_GESTURE_TYPE_TAP)
      {
@@ -806,7 +825,7 @@ _e_gesture_deactivate_unset(struct wl_client *client,
 
    if (type & E_GESTURE_TYPE_EDGE_SWIPE)
      {
-        _e_gesture_deactivate_list_unset(client, surface, &gesture->gesture_events.edge_swipes.activation, E_GESTURE_TYPE_EDGE_SWIPE);
+        _e_gesture_deactivate_list_unset(client, surface, &gesture->gesture_events.edge_swipes.base.activation, E_GESTURE_TYPE_EDGE_SWIPE);
      }
    if (type & E_GESTURE_TYPE_TAP)
      {
@@ -837,6 +856,7 @@ _e_gesture_cb_grab_edge_swipe(struct wl_client *client,
    E_Gesture_Event *gev;
    int sp = 0, ep = 0;
    unsigned int ret = TIZEN_GESTURE_ERROR_NONE;
+   E_Gesture_Conf_Edd *conf = gesture->config->conf;
 
    GTINF("client %p is request grab gesture, fingers: %d, edge: 0x%x, edge_size: %d, point( %d - %d)\n", client, fingers, edge, edge_size, start_point, end_point);
    if (fingers > E_GESTURE_FINGER_MAX)
@@ -881,16 +901,21 @@ _e_gesture_cb_grab_edge_swipe(struct wl_client *client,
         goto out;
      }
 
-   if (_e_gesture_edge_swipe_boundary_check(&gev->edge_swipes.fingers[fingers], edge, sp, ep))
+   if ((conf->edge_swipe.default_enable_back) &&
+       (edge == E_GESTURE_EDGE_TOP))
      {
-        _e_gesture_edge_swipe_grab_add(&gev->edge_swipes.fingers[fingers], client, resource, edge, sp, ep);
+        ret = TIZEN_GESTURE_ERROR_GRABBED_ALREADY;
+     }
+   else if (_e_gesture_edge_boundary_check(&gev->edge_swipes.base.fingers[fingers], edge, sp, ep))
+     {
+        _e_gesture_edge_grab_add(&gev->edge_swipes.base.fingers[fingers], client, resource, edge, sp, ep);
 
         e_gesture_add_client_destroy_listener(client, E_GESTURE_TYPE_EDGE_SWIPE, fingers, edge, 0, sp, ep);
 
         gesture->grabbed_gesture |= E_GESTURE_TYPE_EDGE_SWIPE;
-        gev->edge_swipes.fingers[fingers].enabled = EINA_TRUE;
+        gev->edge_swipes.base.fingers[fingers].enabled = EINA_TRUE;
         if (gev->event_keep) gesture->event_state = E_GESTURE_EVENT_STATE_KEEP;
-        gev->edge_swipes.enabled_edge |= (1 << edge);
+        gev->edge_swipes.base.enabled_edge |= (1 << edge);
 
         ret = TIZEN_GESTURE_ERROR_NONE;
      }
@@ -905,12 +930,12 @@ out:
 }
 
 static Eina_Bool
-_e_gesture_edge_swipe_grabbed_client_check(struct wl_client *client)
+_e_gesture_edge_grabbed_client_check(struct wl_client *client)
 {
    Eina_List *l;
    E_Gesture_Event *gev;
    int i, j;
-   E_Gesture_Event_Edge_Swipe_Finger_Edge *edata;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
 
    gev = &gesture->gesture_events;
 
@@ -918,7 +943,7 @@ _e_gesture_edge_swipe_grabbed_client_check(struct wl_client *client)
      {
         for (j = 1; j < E_GESTURE_EDGE_MAX + 1; j++)
           {
-             EINA_LIST_FOREACH(gev->edge_swipes.fingers[i].edge[j], l, edata)
+             EINA_LIST_FOREACH(gev->edge_swipes.base.fingers[i].edge[j], l, edata)
                {
                   if (edata->client == client) return EINA_TRUE;
                }
@@ -937,7 +962,7 @@ _e_gesture_cb_ungrab_edge_swipe(struct wl_client *client,
    int ret = TIZEN_GESTURE_ERROR_NONE;
    int i;
    Eina_List *l, *l_next;
-   E_Gesture_Event_Edge_Swipe_Finger_Edge *edata;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
    Eina_Bool flag_removed = EINA_FALSE;
    int sp = 0, ep = 0;
 
@@ -978,12 +1003,12 @@ _e_gesture_cb_ungrab_edge_swipe(struct wl_client *client,
         goto notify;
      }
 
-   EINA_LIST_FOREACH_SAFE(gev->edge_swipes.fingers[fingers].edge[edge], l, l_next, edata)
+   EINA_LIST_FOREACH_SAFE(gev->edge_swipes.base.fingers[fingers].edge[edge], l, l_next, edata)
      {
         if ((edata->client == client) && (edata->sp == sp) && (edata->ep == ep))
           {
-             gev->edge_swipes.fingers[fingers].edge[edge] = eina_list_remove_list(
-                gev->edge_swipes.fingers[fingers].edge[edge], l);
+             gev->edge_swipes.base.fingers[fingers].edge[edge] = eina_list_remove_list(
+                gev->edge_swipes.base.fingers[fingers].edge[edge], l);
              E_FREE(edata);
              flag_removed = EINA_TRUE;
           }
@@ -991,19 +1016,19 @@ _e_gesture_cb_ungrab_edge_swipe(struct wl_client *client,
 
    if (flag_removed)
      {
-        if (!_e_gesture_edge_swipe_grabbed_client_check(client))
+        if (!_e_gesture_edge_grabbed_client_check(client))
           {
              _e_gesture_remove_client_destroy_listener(client, E_GESTURE_TYPE_EDGE_SWIPE, fingers, edge, 0, sp, ep);
              _e_gesture_edge_swipe_current_list_check();
           }
      }
 
-   gev->edge_swipes.enabled_edge &= ~( 1 << edge);
+   gev->edge_swipes.base.enabled_edge &= ~( 1 << edge);
    for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
      {
-        if (eina_list_count(gev->edge_swipes.fingers[i].edge[edge]) > 0)
+        if (eina_list_count(gev->edge_swipes.base.fingers[i].edge[edge]) > 0)
           {
-             gev->edge_swipes.enabled_edge |= (1 << edge);
+             gev->edge_swipes.base.enabled_edge |= (1 << edge);
              break;
           }
      }
@@ -1013,34 +1038,193 @@ notify:
    return;
 }
 
+static int
+_e_gesture_grab_edge_drag(struct wl_client *client,
+                          struct wl_resource *resource,
+                          uint32_t fingers, uint32_t edge, uint32_t edge_size,
+                          uint32_t start_point, uint32_t end_point)
+{
+   E_Gesture_Event *gev;
+   int sp = 0, ep = 0;
+   int ret = TIZEN_GESTURE_ERROR_NONE;
+
+   GTINF("client %p is request edge_drag grab, fingers: %d, edge: 0x%x, edge_size: %d, point( %d - %d)\n", client, fingers, edge, edge_size, start_point, end_point);
+   if (fingers > E_GESTURE_FINGER_MAX)
+     {
+        GTWRN("Do not support %d fingers (max: %d)\n", fingers, E_GESTURE_FINGER_MAX);
+        ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
+        goto out;
+     }
+
+   if (edge < TIZEN_GESTURE_EDGE_TOP || edge > TIZEN_GESTURE_EDGE_LEFT)
+     {
+        GTWRN("Invalid edge(%d)\n", edge);
+        ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
+        goto out;
+     }
+
+   if (edge_size == TIZEN_GESTURE_EDGE_SIZE_PARTIAL)
+     {
+        sp = start_point;
+        ep = end_point;
+        if (((edge == TIZEN_GESTURE_EDGE_TOP) || (edge == TIZEN_GESTURE_EDGE_BOTTOM)) &&
+            (ep > e_comp->w))
+          ep = e_comp->w;
+        else if (((edge == TIZEN_GESTURE_EDGE_RIGHT) || (edge == TIZEN_GESTURE_EDGE_LEFT)) &&
+                 (ep > e_comp->h))
+          ep = e_comp->h;
+     }
+   else if (edge_size == TIZEN_GESTURE_EDGE_SIZE_FULL)
+     {
+        sp = 0;
+        if ((edge == TIZEN_GESTURE_EDGE_TOP) || (edge == TIZEN_GESTURE_EDGE_BOTTOM))
+          ep = e_comp->w;
+        else if ((edge == TIZEN_GESTURE_EDGE_RIGHT) || (edge == TIZEN_GESTURE_EDGE_LEFT))
+          ep = e_comp->h;
+     }
+   else
+     {
+        GTWRN("Invalid edge_size(%d)\n", edge_size);
+        ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
+        goto out;
+     }
+
+   gev = &gesture->gesture_events;
+
+   if (_e_gesture_edge_boundary_check(&gev->edge_drags.base.fingers[fingers], edge, sp, ep))
+     {
+        _e_gesture_edge_grab_add(&gev->edge_drags.base.fingers[fingers], client, resource, edge, sp, ep);
+
+        e_gesture_add_client_destroy_listener(client, E_GESTURE_TYPE_EDGE_DRAG, fingers, edge, 0, sp, ep);
+
+        gesture->grabbed_gesture |= E_GESTURE_TYPE_EDGE_DRAG;
+        gev->edge_drags.base.fingers[fingers].enabled = EINA_TRUE;
+        if (gev->event_keep) gesture->event_state = E_GESTURE_EVENT_STATE_KEEP;
+        gev->edge_drags.base.enabled_edge |= (1 << edge);
+
+        ret = TIZEN_GESTURE_ERROR_NONE;
+     }
+   else
+     {
+        ret = TIZEN_GESTURE_ERROR_GRABBED_ALREADY;
+     }
+
+out:
+   return ret;
+}
+
+static int
+_e_gesture_ungrab_edge_drag(struct wl_client *client,
+                       struct wl_resource *resouce,
+                       uint32_t fingers, uint32_t edge, uint32_t edge_size,
+                       uint32_t start_point, uint32_t end_point)
+{
+   E_Gesture_Event *gev;
+   int ret = TIZEN_GESTURE_ERROR_NONE;
+   int i;
+   Eina_List *l, *l_next;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
+   Eina_Bool flag_removed = EINA_FALSE;
+   int sp = 0, ep = 0;
+
+   GTINF("client %p is request ungrab edge drag gesture, fingers: %d, edge: 0x%x, edge_size: %d, (%d ~ %d)\n", client, fingers, edge, edge_size, start_point, end_point);
+
+   if (fingers > E_GESTURE_FINGER_MAX)
+     {
+        GTWRN("Do not support %d fingers (max: %d)\n", fingers, E_GESTURE_FINGER_MAX);
+        ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
+        goto out;
+     }
+
+   if (edge_size == TIZEN_GESTURE_EDGE_SIZE_PARTIAL)
+     {
+        sp = start_point;
+        ep = end_point;
+        if (((edge == TIZEN_GESTURE_EDGE_TOP) || (edge == TIZEN_GESTURE_EDGE_BOTTOM)) &&
+            (ep > e_comp->w))
+          ep = e_comp->w;
+        else if (((edge == TIZEN_GESTURE_EDGE_RIGHT) || (edge == TIZEN_GESTURE_EDGE_LEFT)) &&
+                 (ep > e_comp->h))
+          ep = e_comp->h;
+     }
+   else if (edge_size == TIZEN_GESTURE_EDGE_SIZE_FULL)
+     {
+        sp = 0;
+        if ((edge == TIZEN_GESTURE_EDGE_TOP) || (edge == TIZEN_GESTURE_EDGE_BOTTOM))
+          ep = e_comp->w;
+        else if ((edge == TIZEN_GESTURE_EDGE_RIGHT) || (edge == TIZEN_GESTURE_EDGE_LEFT))
+          ep = e_comp->h;
+     }
+   else
+     {
+        GTWRN("Invalid edge_size(%d)\n", edge_size);
+        ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
+        goto out;
+     }
+
+   gev = &gesture->gesture_events;
+
+   EINA_LIST_FOREACH_SAFE(gev->edge_drags.base.fingers[fingers].edge[edge], l, l_next, edata)
+     {
+        if ((edata->client == client) && (edata->sp == sp) && (edata->ep == ep))
+          {
+             gev->edge_drags.base.fingers[fingers].edge[edge] = eina_list_remove_list(
+                gev->edge_drags.base.fingers[fingers].edge[edge], l);
+             E_FREE(edata);
+             flag_removed = EINA_TRUE;
+          }
+     }
+
+   if (flag_removed)
+     {
+        if (!_e_gesture_edge_grabbed_client_check(client))
+          {
+             _e_gesture_remove_client_destroy_listener(client, E_GESTURE_TYPE_EDGE_DRAG, fingers, edge, 0, sp, ep);
+             _e_gesture_edge_drag_current_list_check();
+          }
+     }
+
+   gev->edge_drags.base.enabled_edge &= ~( 1 << edge);
+   for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
+     {
+        if (eina_list_count(gev->edge_drags.base.fingers[i].edge[edge]) > 0)
+          {
+             gev->edge_drags.base.enabled_edge |= (1 << edge);
+             break;
+          }
+     }
+
+out:
+   return ret;
+}
+
+
 static void
 _e_gesture_cb_grab_edge_drag(struct wl_client *client,
-                        struct wl_resource *resouce,
+                        struct wl_resource *resource,
                         uint32_t fingers, uint32_t edge, uint32_t edge_size,
                         uint32_t start_point, uint32_t end_point)
 {
    int ret = TIZEN_GESTURE_ERROR_NONE;
 
-   ret = TIZEN_GESTURE_ERROR_NOT_SUPPORTED;
+   ret = _e_gesture_grab_edge_drag(client, resource, fingers, edge, edge_size, start_point, end_point);
 
-   tizen_gesture_send_grab_edge_swipe_notify(resouce, fingers, edge, edge_size, start_point, end_point, ret);
+   tizen_gesture_send_grab_edge_swipe_notify(resource, fingers, edge, edge_size, start_point, end_point, ret);
 }
 
 static void
 _e_gesture_cb_ungrab_edge_drag(struct wl_client *client,
-                          struct wl_resource *resouce,
+                          struct wl_resource *resource,
                           uint32_t fingers, uint32_t edge, uint32_t edge_size,
                           uint32_t start_point, uint32_t end_point)
 {
    int ret = TIZEN_GESTURE_ERROR_NONE;
 
-   ret = TIZEN_GESTURE_ERROR_NOT_SUPPORTED;
+   ret = _e_gesture_ungrab_edge_drag(client, resource, fingers, edge, edge_size, start_point, end_point);
 
-   tizen_gesture_send_grab_edge_swipe_notify(resouce, fingers, edge, edge_size, start_point, end_point, ret);
+   tizen_gesture_send_grab_edge_swipe_notify(resource, fingers, edge, edge_size, start_point, end_point, ret);
 }
 
-
-
 static void
 _e_gesture_cb_grab_tap(struct wl_client *client,
                    struct wl_resource *resource,
@@ -1290,9 +1474,9 @@ _e_gesture_deactivate_surface_check(E_Client *ec)
    surface = ec->comp_data->wl_surface;
    if (!surface) return;
 
-   if (!gesture->gesture_events.edge_swipes.activation.client)
+   if (!gesture->gesture_events.edge_swipes.base.activation.client)
      {
-        _e_gesture_deactivate_surface_list_check(surface, &gesture->gesture_events.edge_swipes.activation);
+        _e_gesture_deactivate_surface_list_check(surface, &gesture->gesture_events.edge_swipes.base.activation);
      }
    if (!gesture->gesture_events.taps.activation.client)
      {
@@ -1460,13 +1644,20 @@ _e_gesture_init(E_Module *m)
 
    gesture->gesture_filter = E_GESTURE_TYPE_MAX;
 
+   gesture->gesture_events.edge_swipes.base.activation.active = EINA_TRUE;
+   gesture->gesture_events.edge_drags.base.activation.active = EINA_TRUE;
+   gesture->gesture_events.taps.activation.active = EINA_TRUE;
+   gesture->gesture_events.palm_covers.activation.active = EINA_TRUE;
+   gesture->gesture_events.pans.activation.active = EINA_TRUE;
+   gesture->gesture_events.pinchs.activation.active = EINA_TRUE;
+
    gesture->gesture_events.event_keep = gconfig->conf->event_keep;
    if (gconfig->conf->edge_swipe.default_enable_back)
      {
         gesture->grabbed_gesture |= E_GESTURE_TYPE_EDGE_SWIPE;
-        gesture->gesture_events.edge_swipes.fingers[1].enabled = EINA_TRUE;
-        _e_gesture_edge_swipe_grab_add(&gesture->gesture_events.edge_swipes.fingers[1], (void *)0x1, (void *)0x1, E_GESTURE_EDGE_TOP, 0, 0);
-        gesture->gesture_events.edge_swipes.enabled_edge |= (1 << TIZEN_GESTURE_EDGE_TOP);
+        gesture->gesture_events.edge_swipes.base.fingers[1].enabled = EINA_TRUE;
+        _e_gesture_edge_grab_add(&gesture->gesture_events.edge_swipes.base.fingers[1], (void *)0x1, (void *)0x1, E_GESTURE_EDGE_TOP, 0, 0);
+        gesture->gesture_events.edge_swipes.base.enabled_edge |= (1 << TIZEN_GESTURE_EDGE_TOP);
         if (gesture->gesture_events.event_keep)
           {
              gesture->event_state = E_GESTURE_EVENT_STATE_KEEP;
@@ -1542,7 +1733,7 @@ _e_gesture_remove_client_edge_swipe(struct wl_client *client, E_Gesture_Grabbed_
    int i, j;
    Eina_List *l, *ll;
    E_Gesture_Event_Edge_Swipe *edge_swipes = &gesture->gesture_events.edge_swipes;
-   E_Gesture_Event_Edge_Swipe_Finger_Edge *edata;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
 
    for (i = 0; i < E_GESTURE_FINGER_MAX + 1; i++)
      {
@@ -1550,11 +1741,11 @@ _e_gesture_remove_client_edge_swipe(struct wl_client *client, E_Gesture_Grabbed_
           {
              for (j = 0; j < E_GESTURE_EDGE_MAX + 1; j++)
                {
-                  EINA_LIST_FOREACH_SAFE(edge_swipes->fingers[i].edge[j], l, ll, edata)
+                  EINA_LIST_FOREACH_SAFE(edge_swipes->base.fingers[i].edge[j], l, ll, edata)
                     {
                        if (edata->client == client)
                          {
-                            edge_swipes->fingers[i].edge[j] = eina_list_remove_list(edge_swipes->fingers[i].edge[j], l);
+                            edge_swipes->base.fingers[i].edge[j] = eina_list_remove_list(edge_swipes->base.fingers[i].edge[j], l);
                             E_FREE(edata);
                          }
                     }
@@ -1572,6 +1763,42 @@ _e_gesture_remove_client_edge_swipe(struct wl_client *client, E_Gesture_Grabbed_
 }
 
 static void
+_e_gesture_remove_client_edge_drag(struct wl_client *client, E_Gesture_Grabbed_Client *gclient)
+{
+   int i, j;
+   Eina_List *l, *ll;
+   E_Gesture_Event_Edge_Drag *edge_drags = &gesture->gesture_events.edge_drags;
+   E_Gesture_Event_Edge_Finger_Edge *edata;
+
+   for (i = 0; i < E_GESTURE_FINGER_MAX + 1; i++)
+     {
+        if (gclient->edge_drag_fingers[i].enabled)
+          {
+             for (j = 0; j < E_GESTURE_EDGE_MAX + 1; j++)
+               {
+                  EINA_LIST_FOREACH_SAFE(edge_drags->base.fingers[i].edge[j], l, ll, edata)
+                    {
+                       if (edata->client == client)
+                         {
+                            edge_drags->base.fingers[i].edge[j] = eina_list_remove_list(edge_drags->base.fingers[i].edge[j], l);
+                            E_FREE(edata);
+                         }
+                    }
+                  EINA_LIST_FOREACH_SAFE(gclient->edge_drag_fingers[i].edge[j], l, ll, edata)
+                    {
+                       if (edata->client == client)
+                         {
+                            gclient->edge_drag_fingers[i].edge[j] = eina_list_remove_list(gclient->edge_drag_fingers[i].edge[j], l);
+                            E_FREE(edata);
+                         }
+                    }
+               }
+          }
+     }
+}
+
+
+static void
 _e_gesture_remove_client_tap(struct wl_client *client, E_Gesture_Grabbed_Client *gclient)
 {
    int i, j;
@@ -1654,6 +1881,11 @@ _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data)
                   _e_gesture_remove_client_edge_swipe(client, client_data);
                   removed_gesture |= E_GESTURE_TYPE_EDGE_SWIPE;
                }
+             if (client_data->grabbed_gesture & E_GESTURE_TYPE_EDGE_DRAG)
+               {
+                  _e_gesture_remove_client_edge_drag(client, client_data);
+                  removed_gesture |= E_GESTURE_TYPE_EDGE_SWIPE;
+               }
              if (client_data->grabbed_gesture & E_GESTURE_TYPE_TAP)
                {
                   _e_gesture_remove_client_tap(client, client_data);
@@ -1679,6 +1911,8 @@ _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data)
 
    if (removed_gesture & E_GESTURE_TYPE_EDGE_SWIPE)
      _e_gesture_edge_swipe_current_list_check();
+   if (removed_gesture & E_GESTURE_TYPE_EDGE_DRAG)
+     _e_gesture_edge_drag_current_list_check();
    if (removed_gesture & E_GESTURE_TYPE_TAP)
      _e_gesture_tap_current_list_check();
    if (removed_gesture & E_GESTURE_TYPE_PAN)
index fd12119..13e2510 100644 (file)
 #define E_GESTURE_EDGE_SWIPE_BACK_KEY 166
 #define E_GESTURE_EDGE_SWIPE_BACK_DEFAULT_ENABLE EINA_TRUE
 
+#define E_GESTURE_EDGE_DRAG_START_TIME 0.01
+#define E_GESTURE_EDGE_DRAG_START_AREA 50
+#define E_GESTURE_EDGE_DRAG_DIFF 10
+
 #define E_GESTURE_TAP_REPEATS_MAX 3
 #define E_GESTURE_TAP_START_TIME 0.05
 #define E_GESTURE_TAP_DONE_TIME 1.0
 typedef struct _E_Gesture E_Gesture;
 typedef struct _E_Gesture* E_GesturePtr;
 typedef struct _E_Gesture_Event E_Gesture_Event;
+typedef struct _E_Gesture_Event_Edge E_Gesture_Event_Edge;
 typedef struct _E_Gesture_Event_Edge_Swipe E_Gesture_Event_Edge_Swipe;
-typedef struct _E_Gesture_Event_Edge_Swipe_Finger E_Gesture_Event_Edge_Swipe_Finger;
-typedef struct _E_Gesture_Event_Edge_Swipe_Finger_Edge E_Gesture_Event_Edge_Swipe_Finger_Edge;
+typedef struct _E_Gesture_Event_Edge_Drag E_Gesture_Event_Edge_Drag;
+typedef struct _E_Gesture_Event_Edge_Finger E_Gesture_Event_Edge_Finger;
+typedef struct _E_Gesture_Event_Edge_Finger_Edge E_Gesture_Event_Edge_Finger_Edge;
 typedef struct _E_Gesture_Grabbed_Client E_Gesture_Grabbed_Client;
 typedef struct _E_Gesture_Conf_Edd E_Gesture_Conf_Edd;
 typedef struct _E_Gesture_Config_Data E_Gesture_Config_Data;
@@ -180,6 +186,12 @@ struct _E_Gesture_Conf_Edd
    } edge_swipe;
    struct
      {
+        double time_begin;
+        int area_offset;
+        int diff_length;
+     } edge_drag;
+   struct
+     {
         int repeats_max;
         double time_start;
         double time_done;
@@ -216,7 +228,7 @@ struct _E_Gesture_Select_Surface
    struct wl_resource *res;
 };
 
-struct _E_Gesture_Event_Edge_Swipe_Finger_Edge
+struct _E_Gesture_Event_Edge_Finger_Edge
 {
    struct wl_client *client;
    struct wl_resource *res;
@@ -224,30 +236,47 @@ struct _E_Gesture_Event_Edge_Swipe_Finger_Edge
    unsigned int ep;
 };
 
-struct _E_Gesture_Event_Edge_Swipe_Finger
+struct _E_Gesture_Event_Edge_Finger
 {
    Coords start;
    Eina_Bool enabled;
    Eina_List *edge[E_GESTURE_EDGE_MAX + 1];
 };
 
-struct _E_Gesture_Event_Edge_Swipe
+struct _E_Gesture_Event_Edge
 {
    E_Gesture_Activate_Info activation;
-   E_Gesture_Event_Edge_Swipe_Finger fingers[E_GESTURE_FINGER_MAX + 2];
+   E_Gesture_Event_Edge_Finger fingers[E_GESTURE_FINGER_MAX + 2];
 
    unsigned int edge;
 
-   unsigned int combined_keycode;
-   unsigned int back_keycode;
-
    unsigned int enabled_finger;
    unsigned int enabled_edge;
+};
+
+struct _E_Gesture_Event_Edge_Swipe
+{
+   E_Gesture_Event_Edge base;
+
+   unsigned int combined_keycode;
+   unsigned int back_keycode;
 
    Ecore_Timer *start_timer;
    Ecore_Timer *done_timer;
 };
 
+struct _E_Gesture_Event_Edge_Drag
+{
+   E_Gesture_Event_Edge base;
+
+   Ecore_Timer *start_timer;
+
+   int idx;
+
+   Coords start_point;
+   Coords center_point;
+};
+
 struct _E_Gesture_Event_Tap_Finger_Repeats
 {
    struct wl_client *client;
@@ -320,7 +349,8 @@ struct _E_Gesture_Grabbed_Client
    struct wl_listener *destroy_listener;
    unsigned int grabbed_gesture;
 
-   E_Gesture_Event_Edge_Swipe_Finger edge_swipe_fingers[E_GESTURE_FINGER_MAX + 2];
+   E_Gesture_Event_Edge_Finger edge_swipe_fingers[E_GESTURE_FINGER_MAX + 2];
+   E_Gesture_Event_Edge_Finger edge_drag_fingers[E_GESTURE_FINGER_MAX + 2];
    E_Gesture_Event_Tap_Finger tap_fingers[E_GESTURE_FINGER_MAX + 2];
    E_Gesture_Event_Client pan_fingers[E_GESTURE_FINGER_MAX + 2];
    E_Gesture_Event_Client pinch_fingers[E_GESTURE_FINGER_MAX + 2];
@@ -330,6 +360,7 @@ struct _E_Gesture_Grabbed_Client
 struct _E_Gesture_Event
 {
    E_Gesture_Event_Edge_Swipe edge_swipes;
+   E_Gesture_Event_Edge_Drag edge_drags;
    E_Gesture_Event_Tap taps;
    E_Gesture_Event_Pan pans;
    E_Gesture_Event_Pinch pinchs;