#define ZOOM_LENGTH 150
#define DRAG_INITIAL_STEPS 4
-
-enum
-{
- TAP,
- SWIPE_RIGHT,
- SWIPE_LEFT,
- SWIPE_UP,
- SWIPE_DOWN,
- ZOOM_IN,
- ZOOM_OUT,
- DRAG
-};
+#define PINCH_INITIAL_STEPS 5
int device_number_shift;
typedef struct _TouchInputSequence {
double delay;
- void (*dispatch_func)(int type, int x, int y, int device);
+ void (*dispatch_func)(int x, int y, int device);
int device;
} TouchInputSequence;
TouchInputSequence *ts;
} TouchCommand;
- typedef struct _TouchHoldThenDragCommand {
+typedef struct _TouchHoldThenDragCommand {
DragInfo drag_info;
int type;
int initial_sequence_counter;
TouchInputSequence *ts;
Eldbus_Message *reply;
Eldbus_Connection *conn;
- } TouchHoldThenDragCommand;
+} TouchHoldThenDragCommand;
+
+typedef struct _PinchCommand {
+ int right_finger_x1;
+ int right_finger_x2;
+ int left_finger_x1;
+ int left_finger_x2;
+ int y;
+ int steps;
+ int initial_sequence_counter;
+ int sequence_counter;
+ int terminal_sequence_conter;
+ TouchInputSequence *ts;
+ Eldbus_Message *reply;
+ Eldbus_Connection *conn;
+} PinchCommand;
-static TouchCommand tc;
-Eina_Bool during_drag = EINA_FALSE;
+Eina_Bool during_gesture = EINA_FALSE;
-static int _move_count = -1;
-static int _zw = 0;
-static int _zh = 0;
+static void _dispatch_mouse_in_event(int x, int y, int device);
+static void _dispatch_mouse_move_event(int x, int y, int device);
+static void _dispatch_mouse_down_event(int x, int y, int device);
+static void _dispatch_mouse_up_event(int x, int y, int device);
-static void _dispatch_mouse_in_event(int type, int x, int y, int device);
-static void _dispatch_mouse_move_event(int type, int x, int y, int device);
-static void _dispatch_mouse_down_event(int type, int x, int y, int device);
-static void _dispatch_mouse_up_event(int type, int x, int y, int device);
-static TouchInputSequence _ts_single_tap[] = {
+static TouchInputSequence _ts_drag[] = {
/* down */
{0.0, _dispatch_mouse_in_event, 0},
{0.0, _dispatch_mouse_move_event, 0},
{0.0, _dispatch_mouse_down_event, 0},
- /* up */
- {0.1, _dispatch_mouse_up_event, 0},
- {-1}
-};
-
-static TouchInputSequence _ts_swipe[] = {
- /* down */
- {0.0, _dispatch_mouse_in_event, 0},
{0.0, _dispatch_mouse_move_event, 0},
- {0.0, _dispatch_mouse_down_event, 0},
/* move */
{0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 0},
/* up */
- {0.1, _dispatch_mouse_up_event, 0},
- {-1}
+ {0.1, _dispatch_mouse_up_event, 0}
};
-static TouchInputSequence _ts_zoom[] = {
+static TouchInputSequence _ts_pinch[] = {
/* down */
{0.0, _dispatch_mouse_in_event, 0},
{0.0, _dispatch_mouse_move_event, 0},
{0.0, _dispatch_mouse_down_event, 1},
/* move */
{0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- {0.01, _dispatch_mouse_move_event, 0},
- {0.01, _dispatch_mouse_move_event, 1},
- /* up */
- {0.1, _dispatch_mouse_up_event, 0},
- {0.0, _dispatch_mouse_up_event, 1},
- {-1}
-};
-
-static TouchInputSequence _ts_drag[] = {
- /* down */
- {0.0, _dispatch_mouse_in_event, 0},
- {0.0, _dispatch_mouse_move_event, 0},
- {0.0, _dispatch_mouse_down_event, 0},
- {0.0, _dispatch_mouse_move_event, 0},
- /* move */
- {0.01, _dispatch_mouse_move_event, 0},
/* up */
{0.1, _dispatch_mouse_up_event, 0},
- {-1}
+ {0.0, _dispatch_mouse_up_event, 1}
};
static Ecore_Device * _get_device()
return NULL;
}
-static void _dispatch_mouse_in_event(int type, int x, int y, int device)
+static void _dispatch_mouse_in_event(int x, int y, int device)
{
Ecore_Event_Mouse_IO *ev;
ecore_event_add(ECORE_EVENT_MOUSE_IN, ev, NULL, NULL);
}
-static void _dispatch_mouse_move_event(int type, int x, int y, int device)
+static void _dispatch_mouse_move_event(int x, int y, int device)
{
Ecore_Event_Mouse_Move *ev;
if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) return;
- switch(type)
- {
- case TAP:
- break;
-
- case SWIPE_RIGHT:
- _move_count++;
- x += (MOVE_STEP * _move_count);
- if (x > _zw) x = _zw;
- break;
-
- case SWIPE_LEFT:
- _move_count++;
- x -= (MOVE_STEP * _move_count);
- if (x < 0) x = 0;
- break;
-
- case SWIPE_UP:
- _move_count++;
- y -= (MOVE_STEP * _move_count);
- if (y < 0) y = 0;
- break;
-
- case SWIPE_DOWN:
- _move_count++;
- y += (MOVE_STEP * _move_count);
- if (y > _zh) y = _zh;
- break;
-
- case ZOOM_IN:
- if (device == 0)
- {
- _move_count++;
- x -= (MOVE_STEP * _move_count);
- if (x < 0) x = 0;
- }
- else if (device == 1)
- {
- x += (MOVE_STEP * _move_count);
- if (x > _zw) x = _zw;
- }
- break;
-
- case ZOOM_OUT:
- if (device == 0)
- {
- _move_count++;
- x -= (ZOOM_LENGTH - (MOVE_STEP * _move_count));
- if (x < 0) x = 0;
- }
- else if (device == 1)
- {
- x += (ZOOM_LENGTH - (MOVE_STEP * _move_count));
- if (x > _zw) x = _zw;
- }
- break;
-
- default:
- break;
- }
-
ev->timestamp = (int)(ecore_time_get() * 1000.0);
ev->x = x;
ev->y = y;
ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
}
-static void _dispatch_mouse_down_event(int type, int x, int y, int device)
+static void _dispatch_mouse_down_event(int x, int y, int device)
{
Ecore_Event_Mouse_Button *ev;
if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
- switch(type)
- {
- case TAP:
- break;
-
- case SWIPE_RIGHT:
- x += (MOVE_STEP * _move_count);
- if (x > _zw) x = _zw;
- break;
-
- case SWIPE_LEFT:
- x -= (MOVE_STEP * _move_count);
- if (x < 0) x = 0;
- break;
-
- case SWIPE_UP:
- y -= (MOVE_STEP * _move_count);
- if (y < 0) y = 0;
- break;
-
- case SWIPE_DOWN:
- y += (MOVE_STEP * _move_count);
- if (y > _zh) y = _zh;
- break;
-
- case ZOOM_IN:
- if (device == 0)
- {
- x -= (MOVE_STEP * _move_count);
- if (x < 0) x = 0;
- }
- else if (device == 1)
- {
- x += (MOVE_STEP * _move_count);
- if (x > _zw) x = _zw;
- }
- break;
-
- case ZOOM_OUT:
- if (device == 0)
- {
- x -= (ZOOM_LENGTH - (MOVE_STEP * _move_count));
- if (x < 0) x = 0;
- }
- else if (device == 1)
- {
- x += (ZOOM_LENGTH - (MOVE_STEP * _move_count));
- if (x > _zw) x = _zw;
- }
- break;
-
- default:
- break;
- }
-
ev->buttons = 1;
ev->timestamp = (int)(ecore_time_get() * 1000.0);
ev->x = x;
ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
}
-static void _dispatch_mouse_up_event(int type, int x, int y, int device)
+static void _dispatch_mouse_up_event(int x, int y, int device)
{
Ecore_Event_Mouse_Button *ev;
if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
- switch(type)
- {
- case TAP:
- break;
-
- case SWIPE_RIGHT:
- x += (MOVE_STEP * _move_count);
- if (x > _zw) x = _zw;
- break;
-
- case SWIPE_LEFT:
- x -= (MOVE_STEP * _move_count);
- if (x < 0) x = 0;
- break;
-
- case SWIPE_UP:
- y -= (MOVE_STEP * _move_count);
- if (y < 0) y = 0;
- break;
-
- case SWIPE_DOWN:
- y += (MOVE_STEP * _move_count);
- if (y > _zh) y = _zh;
- break;
-
- case ZOOM_IN:
- if (device == 0)
- {
- x -= (MOVE_STEP * _move_count);
- if (x < 0) x = 0;
- }
- else if (device == 1)
- {
- x += (MOVE_STEP * _move_count);
- if (x > _zw) x = _zw;
- }
- break;
-
- case ZOOM_OUT:
- if (device == 0)
- {
- x -= (ZOOM_LENGTH - (MOVE_STEP * _move_count));
- if (x < 0) x = 0;
- }
- else if (device == 1)
- {
- x += (ZOOM_LENGTH - (MOVE_STEP * _move_count));
- if (x > _zw) x = _zw;
- }
- break;
-
- default:
- break;
- }
-
ev->buttons = 1;
ev->timestamp = (int)(ecore_time_get() * 1000.0);
ev->x = x;
ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
}
-
-Eina_Bool
-_touch_sequnece_timer(void *data)
-{
- TouchCommand *tc = data;
-
- if (tc == NULL || tc->ts->delay < 0)
- {
- _move_count = -1;
- return ECORE_CALLBACK_CANCEL;
- }
-
- tc->ts->dispatch_func(tc->type, tc->x, tc->y, tc->ts->device);
-
- tc->ts++;
- ecore_timer_add(tc->ts->delay, _touch_sequnece_timer, tc);
- return ECORE_CALLBACK_CANCEL;
-}
-
Eina_Bool
_drag_touch_sequence_timer(void *data)
{
TouchHoldThenDragCommand *cmd = data;
- if (cmd == NULL || cmd->ts->delay < 0)
+ if (cmd == NULL)
{
eldbus_connection_send(cmd->conn, cmd->reply, NULL, NULL, -1);
free(cmd);
if (cmd->initial_sequence_counter < DRAG_INITIAL_STEPS) {
cmd->initial_sequence_counter++;
- cmd->ts->dispatch_func(cmd->type, cmd->drag_info.start.x, cmd->drag_info.start.y, 0);
+ cmd->ts->dispatch_func(cmd->drag_info.start.x, cmd->drag_info.start.y, 0);
cmd->ts++;
ecore_timer_add(cmd->ts->delay, _drag_touch_sequence_timer, cmd);
int current_x = (cmd->drag_info.start.x * (cmd->drag_info.steps - cmd->sequence_counter) + cmd->drag_info.end.x * cmd->sequence_counter) / (cmd->drag_info.steps);
int current_y = (cmd->drag_info.start.y * (cmd->drag_info.steps - cmd->sequence_counter) + cmd->drag_info.end.y * cmd->sequence_counter) / (cmd->drag_info.steps);
cmd->sequence_counter++;
- cmd->ts->dispatch_func(cmd->type, current_x, current_y, 0);
+ cmd->ts->dispatch_func(current_x, current_y, 0);
ecore_timer_add(cmd->ts->delay, _drag_touch_sequence_timer, cmd);
return ECORE_CALLBACK_CANCEL;
}
cmd->ts++;
- cmd->ts->dispatch_func(cmd->type, cmd->drag_info.end.x, cmd->drag_info.end.y, 0);
+ cmd->ts->dispatch_func(cmd->drag_info.end.x, cmd->drag_info.end.y, 0);
eldbus_connection_send(cmd->conn, cmd->reply, NULL, NULL, -1);
free(cmd);
- during_drag = EINA_FALSE;
+ during_gesture = EINA_FALSE;
return ECORE_CALLBACK_CANCEL;
}
-void _e_dispatch_gesture_event(int type, int x, int y)
+Eina_Bool
+_pinch_touch_sequence_timer(void *data)
{
- E_Zone *zone;
-
- if (_move_count >= 0) return;
- _move_count++;
+ PinchCommand *cmd = data;
- zone = e_zone_current_get();
- if (zone)
+ if (cmd == NULL)
{
- _zw = zone->w;
- _zh = zone->h;
+ eldbus_connection_send(cmd->conn, cmd->reply, NULL, NULL, -1);
+ return ECORE_CALLBACK_CANCEL;
}
- else
+
+ if (cmd->initial_sequence_counter == 0)
{
- ERROR("Fail to find zone");
- _move_count = -1;
- return;
+ cmd->initial_sequence_counter++;
+ cmd->ts->dispatch_func(cmd->right_finger_x1, cmd->y, cmd->ts->device);
+ cmd->ts++;
+
+ ecore_timer_add(cmd->ts->delay, _pinch_touch_sequence_timer, cmd);
+ return ECORE_CALLBACK_CANCEL;
}
- if (x < 0 || y < 0 || x > _zw || y > _zh)
+ if (cmd->initial_sequence_counter < PINCH_INITIAL_STEPS)
{
- ERROR("Invalid value: %d, %d", x, y);
- _move_count = -1;
- return;
+ if (cmd->initial_sequence_counter % 2 == 1)
+ cmd->ts->dispatch_func(cmd->right_finger_x1, cmd->y, cmd->ts->device);
+ else
+ cmd->ts->dispatch_func(cmd->left_finger_x1, cmd->y, cmd->ts->device);
+
+ cmd->initial_sequence_counter++;
+ cmd->ts++;
+
+ ecore_timer_add(cmd->ts->delay, _pinch_touch_sequence_timer, cmd);
+ return ECORE_CALLBACK_CANCEL;
}
- tc.type = type;
- tc.x = x;
- tc.y = y;
+ if (cmd->sequence_counter <= cmd->steps)
+ {
+ int new_x = -1;
+
+ if (cmd->sequence_counter % 2 == 0)
+ new_x = (cmd->right_finger_x1 * (cmd->steps - cmd->sequence_counter) + cmd->right_finger_x2 * cmd->sequence_counter) / (cmd->steps);
+ else
+ new_x = (cmd->left_finger_x1 * (cmd->steps - cmd->sequence_counter) + cmd->left_finger_x2 * cmd->sequence_counter) / (cmd->steps);
- switch(type)
+ cmd->sequence_counter++;
+ cmd->ts->dispatch_func(new_x, cmd->y, cmd->sequence_counter % 2);
+
+ ecore_timer_add(cmd->ts->delay, _pinch_touch_sequence_timer, cmd);
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ cmd->ts++;
+ if (cmd->terminal_sequence_conter == 0)
{
- case TAP:
- tc.ts = _ts_single_tap;
- break;
-
- case SWIPE_LEFT:
- case SWIPE_RIGHT:
- case SWIPE_UP:
- case SWIPE_DOWN:
- tc.ts = _ts_swipe;
- break;
-
- case ZOOM_IN:
- case ZOOM_OUT:
- tc.ts = _ts_zoom;
- break;
-
- default:
- ERROR("Invalid type: %d", type);
- _move_count = -1;
- return;
+ cmd->ts->dispatch_func(cmd->left_finger_x2, cmd->y, 0);
+ cmd->terminal_sequence_conter++;
+ ecore_timer_add(cmd->ts->delay, _pinch_touch_sequence_timer, cmd);
+ return ECORE_CALLBACK_CANCEL;
}
- ecore_timer_add(tc.ts->delay, _touch_sequnece_timer, &tc);
+ cmd->ts->dispatch_func(cmd->right_finger_x2, cmd->y, 1);
+ eldbus_connection_send(cmd->conn, cmd->reply, NULL, NULL, -1);
+ during_gesture = EINA_FALSE;
+
+ return ECORE_CALLBACK_CANCEL;
}
void _e_dispatch_drag_event(DragInfo di, Eldbus_Connection *conn, const Eldbus_Message *msg)
{
- if (during_drag)
+ if (during_gesture)
{
Eldbus_Message *reply = eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Previous gesture is not finished yet");
eldbus_connection_send(conn, reply, NULL, NULL, -1);
}
E_Zone *zone = e_zone_current_get();
+ int zw, zh;
if (zone)
{
- _zw = zone->w;
- _zh = zone->h;
+ zw = zone->w;
+ zh = zone->h;
}
else
{
return;
}
- if (di.start.x < 0 || di.start.y < 0 || di.start.x > _zw || di.start.y > _zh || di.steps < 1)
+ if (di.start.x < 0 || di.start.y < 0 || di.start.x > zw || di.start.y > zh || di.steps < 1)
{
ERROR("Invalid value: start.x: %d, start.y: %d, steps: %d", di.start.x, di.start.y, di.steps);
Eldbus_Message * reply = eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid starting coordinates or steps number");
// Starting drag gesture from edge causes additional gesture on the screen
if (di.start.x == 0) di.start.x += 1;
- if (di.start.x == _zw) di.start.x -= 1;
+ if (di.start.x == zw) di.start.x -= 1;
if (di.start.y == 0) di.start.y += 1;
- if (di.start.y == _zh) di.start.y -= 1;
+ if (di.start.y == zh) di.start.y -= 1;
_ts_drag[3].delay = di.hold_time;
}
cmd->drag_info = di;
- cmd->type = DRAG;
cmd->initial_sequence_counter = 0;
cmd->sequence_counter = 0;
cmd->ts = _ts_drag;
cmd->conn = conn;
cmd->reply = eldbus_message_method_return_new(msg);
- during_drag = EINA_TRUE;
+ during_gesture = EINA_TRUE;
ecore_timer_add(0.0, _drag_touch_sequence_timer, cmd);
}
+
+void _e_dispatch_pinch_event(PinchInfo pi, Eldbus_Connection *conn, const Eldbus_Message *msg)
+{
+ if (during_gesture)
+ {
+ Eldbus_Message *reply = eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Previous gesture is not finished yet");
+ eldbus_connection_send(conn, reply, NULL, NULL, -1);
+ return;
+ }
+
+ E_Zone *zone = e_zone_current_get();
+ int zw, zh;
+ if (zone)
+ {
+ zw = zone->w;
+ zh = zone->h;
+ }
+ else
+ {
+ ERROR("Fail to find zone");
+ Eldbus_Message *reply = eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Fail to find zone");
+ eldbus_connection_send(conn, reply, NULL, NULL, -1);
+ return;
+ }
+
+ if (pi.point.x < 0 || pi.point.y < 0 || pi.point.x > zw || pi.point.y > zh || pi.steps < 1)
+ {
+ ERROR("Invalid value: %d, %d, %d", pi.point.x, pi.point.y, pi.steps);
+ Eldbus_Message *reply = eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid starting coordinates or steps number");
+ eldbus_connection_send(conn, reply, NULL, NULL, -1);
+ return;
+ }
+
+ PinchCommand *cmd = (PinchCommand *)malloc(sizeof(PinchCommand));
+ if (!cmd)
+ {
+ Eldbus_Message *reply = eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Malloc error");
+ eldbus_connection_send(conn, reply, NULL, NULL, -1);
+ return;
+ }
+
+ cmd->y =pi.point.y;
+
+ if (pi.pinch_out)
+ {
+ cmd->right_finger_x1 = pi.point.x + pi.length;
+ cmd->right_finger_x2 = pi.point.x;
+ cmd->left_finger_x1 = pi.point.x - pi.length;
+ cmd->left_finger_x2 = pi.point.x;
+ }
+ else
+ {
+ cmd->right_finger_x1 = pi.point.x;
+ cmd->right_finger_x2 = pi.point.x + pi.length;
+ cmd->left_finger_x1 = pi.point.x;
+ cmd->left_finger_x2 = pi.point.x - pi.length;
+ }
+
+ // Starting drag gesture from edge causes additional gesture on the screen
+ if (cmd->left_finger_x1 == 0) pi.point.x += 1;
+ if (cmd->right_finger_x1 == zw) pi.point.x -= 1;
+
+ cmd->steps = pi.steps;
+ cmd->initial_sequence_counter = 0;
+ cmd->sequence_counter = 0;
+ cmd->terminal_sequence_conter = 0;
+ cmd->ts = _ts_pinch;
+ cmd->reply = eldbus_message_method_return_new(msg);
+ cmd->conn = conn;
+
+ during_gesture = EINA_TRUE;
+ ecore_timer_add(0.0, _pinch_touch_sequence_timer, cmd);
+}