From: Kim Shinwoo <kimcinoo.efl@gmail.com>
authorKim Shinwoo <kimcinoo.efl@gmail.com>
Mon, 3 Sep 2012 04:06:02 +0000 (04:06 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Mon, 3 Sep 2012 04:06:02 +0000 (04:06 +0000)
i have revised the access module and attached. you can find the
following
in the patch.

  - mouse double tap and move gesture for each direction
  - two finger flicking for each direction
  - two finger panning

SVN revision: 75945

AUTHORS
src/modules/access/e_mod_main.c

diff --git a/AUTHORS b/AUTHORS
index 85ffc91..3381166 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -36,3 +36,4 @@ q66 <quaker66@gmail.com>
 Tom Hacohen (TAsn) <tom@stosb.com>
 Maxime Villard <rustyBSD@gmx.fr>
 Jeremy Zurcher <jeremy@asynk.ch>
+Shinwoo Kim <kimcinoo@gmail.com>
index 3a966b5..b12fc89 100644 (file)
@@ -1,18 +1,31 @@
 #include "e.h"
 #include "e_mod_main.h"
+#define HISTORY_MAX 8
 
 typedef struct
 {
    E_Zone         *zone;
    Ecore_X_Window  win;
    Ecore_Timer    *timer;
-   int             x, y, dx, dy;
+   Ecore_Timer    *double_down_timer;
+   int             x, y, dx, dy, mx, my;
+   int             mouse_history[HISTORY_MAX];
    unsigned int    dt;
+   Eina_Inlist    *history;
    Eina_Bool       down : 1;
+   Eina_Bool       two_finger_down : 1;
+   Eina_Bool       mouse_double_down : 1;
 } Cover;
 
+typedef struct
+{
+   EINA_INLIST;
+   int             device;
+} Multi;
+
 static Eina_List *covers = NULL;
 static Eina_List *handlers = NULL;
+static int multi_device[3];
 
 static Ecore_X_Window
 _mouse_win_in_get(Cover *cov, int x, int y)
@@ -21,7 +34,7 @@ _mouse_win_in_get(Cover *cov, int x, int y)
    Ecore_X_Window *skip, inwin;
    Cover *cov2;
    int i;
-   
+
    skip = alloca(sizeof(Ecore_X_Window) * eina_list_count(covers));
    i = 0;
    EINA_LIST_FOREACH(covers, l, cov2)
@@ -31,6 +44,7 @@ _mouse_win_in_get(Cover *cov, int x, int y)
      }
    inwin = ecore_x_window_shadow_tree_at_xy_with_skip_get
      (cov->zone->container->manager->root, x, y, skip, i);
+
    return inwin;
 }
 
@@ -39,8 +53,9 @@ _mouse_win_fake_tap(Cover *cov, Ecore_Event_Mouse_Button *ev)
 {
    Ecore_X_Window inwin;
    int x, y;
-   
+
    inwin = _mouse_win_in_get(cov, ev->root.x, ev->root.y);
+
    ecore_x_pointer_xy_get(inwin, &x, &y);
    ecore_x_mouse_in_send(inwin, x, y);
    ecore_x_mouse_move_send(inwin, x, y);
@@ -49,20 +64,59 @@ _mouse_win_fake_tap(Cover *cov, Ecore_Event_Mouse_Button *ev)
    ecore_x_mouse_out_send(inwin, x, y);
 }
 
+static void
+_record_mouse_history(Cover *cov, void *event)
+{
+   Ecore_Event_Mouse_Move *ev = event;
+   int i = 0;
+
+   for (i = 0; i < HISTORY_MAX; i++)
+     {
+        if (cov->mouse_history[i] == -1)
+          {
+             cov->mouse_history[i] = ev->multi.device;
+             break;
+          }
+     }
+
+   // if there is not enough space to save device number, shift!
+   if (i == HISTORY_MAX)
+     {
+        for (i = 0; i < (HISTORY_MAX - 1); i++)
+          cov->mouse_history[i] = cov->mouse_history[i + 1];
+        cov->mouse_history[HISTORY_MAX - 1] = ev->multi.device;
+     }
+}
+
+static Eina_Bool
+_check_mouse_history(Cover *cov)
+{
+   int i = 0;
+   
+   for (i = 0; i < HISTORY_MAX; i++)
+     {
+        if ((cov->mouse_history[i] != multi_device[0]) && 
+            (cov->mouse_history[i] != -1))
+          return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
 static Eina_Bool
 _mouse_longpress(void *data)
 {
    Cover *cov = data;
    int distance = 40;
    int dx, dy;
-   
+
    cov->timer = NULL;
    dx = cov->x - cov->dx;
    dy = cov->y - cov->dy;
    if (((dx * dx) + (dy * dy)) < (distance * distance))
      {
         E_Border *bd = e_border_focused_get();
-        
+
         cov->down = EINA_FALSE;
         printf("longpress\n");
         if (bd)
@@ -71,18 +125,76 @@ _mouse_longpress(void *data)
    return EINA_FALSE;
 }
 
+static Eina_Bool
+_mouse_double_down(void *data)
+{
+   Cover *cov = data;
+   
+   ecore_timer_del(cov->double_down_timer);
+   cov->double_down_timer = NULL;
+   return EINA_FALSE;
+}
+
+static void
+_mouse_double_down_timeout(Cover *cov)
+{
+   double short_time = 0.3;
+   int distance = 40;
+   int dx, dy;
+
+   dx = cov->x - cov->dx;
+   dy = cov->y - cov->dy;
+
+   if ((cov->double_down_timer) &&
+       (((dx * dx) + (dy * dy)) < (distance * distance)))
+     {
+        // start double tap and move from here
+        cov->mouse_double_down = EINA_TRUE;
+
+        if (cov->timer)
+          {
+             ecore_timer_del(cov->timer);
+             cov->timer = NULL;
+          }
+     }
+
+   if (cov->double_down_timer)
+     {
+        ecore_timer_del(cov->double_down_timer);
+        cov->double_down_timer = NULL;
+        return;
+     }
+
+   cov->double_down_timer = ecore_timer_add(short_time, _mouse_double_down,
+                                            cov);
+}
+
 static void
 _mouse_down(Cover *cov, Ecore_Event_Mouse_Button *ev)
 {
+   int x, y;
+   E_Border *bd;
    double longtime = 0.5;
-   
+
    cov->dx = ev->x;
    cov->dy = ev->y;
+   cov->mx = ev->x;
+   cov->my = ev->y;
    cov->x = ev->x;
    cov->y = ev->y;
    cov->dt = ev->timestamp;
    cov->down = EINA_TRUE;
    cov->timer = ecore_timer_add(longtime, _mouse_longpress, cov);
+
+   // 2nd finger comes...
+   _mouse_double_down_timeout(cov);
+
+   // mouse in should be here
+   bd = e_border_focused_get();
+   if (!bd) return;
+
+   ecore_x_pointer_xy_get(bd->client.win, &x, &y);
+   ecore_x_mouse_in_send(bd->client.win, x, y);
 }
 
 static void
@@ -91,8 +203,22 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
    double timeout = 0.15;
    int distance = 40;
    int dx, dy;
+   int x, y;
+
    E_Border *bd = e_border_focused_get();
-   
+
+   // for two finger panning
+   if (cov->two_finger_down)
+     {
+        ecore_x_pointer_xy_get(bd->client.win, &x, &y);
+        ecore_x_mouse_up_send(bd->client.win, x, y, 1);
+        cov->two_finger_down = EINA_FALSE;
+        ecore_x_mouse_out_send(bd->client.win, x, y);
+     }
+
+   // reset double down and moving
+   cov->mouse_double_down = EINA_FALSE;
+
    if (cov->timer)
      {
         ecore_timer_del(cov->timer);
@@ -115,19 +241,26 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
                ecore_x_e_illume_access_action_activate_send(bd->client.win);
           }
      }
-   else
+   else if (((dx * dx) + (dy * dy)) > (4 * distance * distance)
+            && ((ev->timestamp - cov->dt) < (timeout * 1000)))
      {
         if (abs(dx) > abs(dy)) // left or right
           {
              if (dx > 0) // right
                {
-                  printf("right\n");
+                  if (_check_mouse_history(cov))
+                    printf("single flick right\n");
+                  else
+                    printf("double flick right\n");
                   if (bd)
                     ecore_x_e_illume_access_action_read_next_send(bd->client.win);
                }
              else // left
                {
-                  printf("left\n");
+                  if (_check_mouse_history(cov))
+                    printf("single flick left\n");
+                  else
+                    printf("double flick left\n");
                   if (bd)
                     ecore_x_e_illume_access_action_read_prev_send(bd->client.win);
                }
@@ -136,13 +269,20 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
           {
              if (dy > 0) // down
                {
-                  printf("down\n");
+                  if (_check_mouse_history(cov))
+                    printf("single flick down\n");
+                  else
+                    printf("double flick down\n");
+
                   if (bd)
                     ecore_x_e_illume_access_action_next_send(bd->client.win);
                }
              else // up
                {
-                  printf("up\n");
+                  if (_check_mouse_history(cov))
+                    printf("single flick up\n");
+                  else
+                    printf("double flick up\n");
                   if (bd)
                     ecore_x_e_illume_access_action_prev_send(bd->client.win);
                }
@@ -154,9 +294,50 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
 static void
 _mouse_move(Cover *cov, Ecore_Event_Mouse_Move *ev)
 {
-   if (!cov->down) return;
+   int distance = 5;
+   int x, y;
+   int dx, dy;
+   E_Border *bd;
+
+   //FIXME: why here.. after long press you cannot go below..
+   //if (!cov->down) return;
    cov->x = ev->x;
    cov->y = ev->y;
+
+   bd = e_border_focused_get();
+   if (!bd) return;
+
+   _record_mouse_history(cov, ev);
+
+   ecore_x_pointer_xy_get(bd->client.win, &x, &y);
+   ecore_x_mouse_move_send(bd->client.win, x, y);
+
+   // for panning, without check two_finger_down, there will be several  down_send()
+   if ((ev->multi.device == multi_device[0]) && (cov->mouse_double_down))
+     {
+        dx = ev->x - cov->mx;
+        dy = ev->y - cov->my;
+        if (((dx * dx) + (dy * dy)) > (distance * distance))
+          {
+
+             if (abs(dx) > abs(dy)) // left or right
+               {
+                  if (dx > 0) // right
+                    printf("mouse double down and moving - right\n");
+                  else // left
+                    printf("mouse double down and moving - left\n");
+               }
+             else // up or down
+               {
+                  if (dy > 0) // down
+                    printf("mouse double down and moving - down\n");
+                  else // up
+                    printf("mouse double down and moving - up\n");
+                }
+             cov->mx = ev->x;
+             cov->my = ev->y;
+          }
+     }
 }
 
 static void
@@ -173,13 +354,38 @@ _cb_mouse_down(void    *data __UNUSED__,
    Ecore_Event_Mouse_Button *ev = event;
    Eina_List *l;
    Cover *cov;
-   
+   int i = 0;
+   E_Border *bd;
+   int x, y;
+
+   for (i = 0; i < 3; i++)
+     {
+        if (multi_device[i] == -1)
+          {
+             multi_device[i] = ev->multi.device;
+             break;
+          }
+        else if (multi_device[i] == ev->multi.device) break;
+     }
+
    EINA_LIST_FOREACH(covers, l, cov)
      {
         if (ev->window == cov->win)
           {
-             if ((ev->buttons == 1) && (ev->multi.device == 0))
+             // XXX change specific number
+             if (ev->multi.device == multi_device[0])
                _mouse_down(cov, ev);
+
+             if ((ev->multi.device == multi_device[1]) && 
+                 (!cov->two_finger_down))
+               {
+                  bd = e_border_focused_get();
+                  if (!bd) return ECORE_CALLBACK_PASS_ON;
+                  ecore_x_pointer_xy_get(bd->client.win, &x, &y);
+                  ecore_x_mouse_move_send(bd->client.win, x, y);
+                  ecore_x_mouse_down_send(bd->client.win, x, y, 1);
+                  cov->two_finger_down = EINA_TRUE;
+               }
              return ECORE_CALLBACK_PASS_ON;
           }
      }
@@ -194,12 +400,12 @@ _cb_mouse_up(void    *data __UNUSED__,
    Ecore_Event_Mouse_Button *ev = event;
    Eina_List *l;
    Cover *cov;
-   
+
    EINA_LIST_FOREACH(covers, l, cov)
      {
         if (ev->window == cov->win)
           {
-             if ((ev->buttons == 1) && (ev->multi.device == 0))
+             if (ev->buttons == 1)
                _mouse_up(cov, ev);
              return ECORE_CALLBACK_PASS_ON;
           }
@@ -215,12 +421,12 @@ _cb_mouse_move(void    *data __UNUSED__,
    Ecore_Event_Mouse_Move *ev = event;
    Eina_List *l;
    Cover *cov;
-   
    EINA_LIST_FOREACH(covers, l, cov)
      {
         if (ev->window == cov->win)
           {
-             if (ev->multi.device == 0)
+             if ((ev->multi.device == multi_device[0]) || 
+                 (ev->multi.device == multi_device[1]))
                _mouse_move(cov, ev);
              return ECORE_CALLBACK_PASS_ON;
           }
@@ -236,7 +442,7 @@ _cb_mouse_wheel(void    *data __UNUSED__,
    Ecore_Event_Mouse_Wheel *ev = event;
    Eina_List *l;
    Cover *cov;
-   
+
    EINA_LIST_FOREACH(covers, l, cov)
      {
         if (ev->window == cov->win)
@@ -252,7 +458,7 @@ static Cover *
 _cover_new(E_Zone *zone)
 {
    Cover *cov;
-   
+
    cov = E_NEW(Cover, 1);
    if (!cov) return NULL;
    cov->zone = zone;
@@ -260,6 +466,9 @@ _cover_new(E_Zone *zone)
                                        zone->container->x + zone->x,
                                        zone->container->y + zone->y,
                                        zone->w, zone->h);
+
+   ecore_x_input_multi_select(cov->win);
+
    ecore_x_window_ignore_set(cov->win, 1);
    ecore_x_window_configure(cov->win,
                             ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
@@ -268,6 +477,8 @@ _cover_new(E_Zone *zone)
                             zone->container->layers[8].win,
                             ECORE_X_WINDOW_STACK_ABOVE);
    ecore_x_window_show(cov->win);
+   ecore_x_window_raise(cov->win);
+
    return cov;
 }
 
@@ -276,19 +487,23 @@ _covers_init(void)
 {
    Eina_List *l, *l2, *l3;
    E_Manager *man;
+   int i = 0;
 
    EINA_LIST_FOREACH(e_manager_list(), l, man)
      {
         E_Container *con;
-     
         EINA_LIST_FOREACH(man->containers, l2, con)
           {
              E_Zone *zone;
-             
              EINA_LIST_FOREACH(con->zones, l3, zone)
                {
                   Cover *cov = _cover_new(zone);
-                  if (cov) covers = eina_list_append(covers, cov);
+                  if (cov)
+                    {
+                       covers = eina_list_append(covers, cov);
+                       for (i = 0; i < HISTORY_MAX; i++)
+                         cov->mouse_history[i] = -1;
+                    }
                }
           }
      }
@@ -298,7 +513,7 @@ static void
 _covers_shutdown(void)
 {
    Cover *cov;
-   
+
    EINA_LIST_FREE(covers, cov)
      {
         ecore_x_window_ignore_set(cov->win, 0);
@@ -345,6 +560,8 @@ _cb_zone_move_resize(void    *data __UNUSED__,
 static void
 _events_init(void)
 {
+   int i = 0;
+
    handlers = eina_list_append
      (handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
                                         _cb_mouse_down, NULL));
@@ -366,6 +583,8 @@ _events_init(void)
    handlers = eina_list_append
      (handlers, ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,
                                         _cb_zone_move_resize, NULL));
+
+   for (i = 0; i < 3; i++) multi_device[i] = -1;
 }
 
 static void