#include "e_screen_reader_private.h"
#include "e_dispatch_gesture_event.h"
-#define MOVE_STEP 10
-#define ZOOM_LENGTH 150
-
-#define DRAG_INITIAL_STEPS 4
-#define PINCH_INITIAL_STEPS 5
+#define STEP_DURATION 0.01
int device_number_shift;
+Eina_Bool during_gesture = EINA_FALSE;
-typedef struct _TouchInputSequence {
- double delay;
- void (*dispatch_func)(int x, int y, int device);
- int device;
-} TouchInputSequence;
-
-typedef struct _TouchCommand {
- int type;
- int x, y;
- TouchInputSequence *ts;
- } TouchCommand;
-
-typedef struct _TouchHoldThenDragCommand {
- DragInfo drag_info;
- int type;
- int initial_sequence_counter;
- int sequence_counter;
- TouchInputSequence *ts;
- Eldbus_Message *reply;
- Eldbus_Connection *conn;
-} 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;
+typedef struct _GestureCommand {
+ DragInfo drag_info[2];
+ int drag_info_size;
int sequence_counter;
- int terminal_sequence_conter;
- TouchInputSequence *ts;
Eldbus_Message *reply;
Eldbus_Connection *conn;
-} PinchCommand;
-
-Eina_Bool during_gesture = EINA_FALSE;
+} GestureCommand;
-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 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}
-};
-
-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, 0},
- {0.0, _dispatch_mouse_move_event, 1},
- {0.0, _dispatch_mouse_down_event, 1},
- /* move */
- {0.01, _dispatch_mouse_move_event, 0},
- /* up */
- {0.1, _dispatch_mouse_up_event, 0},
- {0.0, _dispatch_mouse_up_event, 1}
-};
+static void _start_gesture_sequence(GestureCommand *cmd);
+static Eina_Bool _on_hold_timer(void *data);
+static Eina_Bool _on_gesture_sequence_timer(void *data);
+static void _on_terminate_gesture_sequence(GestureCommand *cmd);
static Ecore_Device * _get_device()
{
return NULL;
}
-static void _dispatch_mouse_in_event(int x, int y, int device)
-{
- Ecore_Event_Mouse_IO *ev;
-
- if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_IO)))) return;
-
- ev->x = x;
- ev->y = y;
- ev->modifiers = 0;
- ev->timestamp = (int)(ecore_time_get() * 1000.0);
- ev->window = e_comp->ee_win;
- ev->event_window = e_comp->ee_win;
- ev->dev = _get_device();
-
- ecore_event_add(ECORE_EVENT_MOUSE_IN, ev, NULL, NULL);
-}
-
static void _dispatch_mouse_move_event(int x, int y, int device)
{
Ecore_Event_Mouse_Move *ev;
ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
}
-Eina_Bool
-_drag_touch_sequence_timer(void *data)
+static Eldbus_Message *
+_correct_coordinates(Point *point, int steps, const Eldbus_Message *msg)
{
- TouchHoldThenDragCommand *cmd = data;
-
- if (cmd == NULL)
- {
- eldbus_connection_send(cmd->conn, cmd->reply, NULL, NULL, -1);
- free(cmd);
- return ECORE_CALLBACK_CANCEL;
- }
+ if (during_gesture)
+ return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Previous gesture is not finished yet");
- if (cmd->initial_sequence_counter < DRAG_INITIAL_STEPS) {
- cmd->initial_sequence_counter++;
- cmd->ts->dispatch_func(cmd->drag_info.start.x, cmd->drag_info.start.y, 0);
- cmd->ts++;
+ E_Zone *zone = e_zone_current_get();
+ if (!zone)
+ return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Fail to find zone");
- ecore_timer_add(cmd->ts->delay, _drag_touch_sequence_timer, cmd);
- return ECORE_CALLBACK_CANCEL;
+ if (point->x < 0 || point->y < 0 || point->x > zone->w || point->y > zone->h || steps < 1)
+ {
+ ERROR("Invalid value: start.x: %d, start.y: %d, steps: %d", point->x, point->y, steps);
+ return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid starting coordinates or steps number");
}
- if (cmd->sequence_counter <= cmd->drag_info.steps) {
- 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(current_x, current_y, 0);
+ // Starting gesture from edge causes additional gesture on the screen
+ if (point->x == 0) point->x += 1;
+ if (point->x == zone->w) point->x -= 1;
+ if (point->y == 0) point->y += 1;
+ if (point->y == zone->h) point->y -= 1;
- ecore_timer_add(cmd->ts->delay, _drag_touch_sequence_timer, cmd);
- return ECORE_CALLBACK_CANCEL;
- }
-
- cmd->ts++;
- 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_gesture = EINA_FALSE;
-
- return ECORE_CALLBACK_CANCEL;
+ return NULL;
}
-Eina_Bool
-_pinch_touch_sequence_timer(void *data)
+static void
+_swap_points(Point *a, Point *b)
{
- PinchCommand *cmd = data;
-
- if (cmd == NULL)
- {
- eldbus_connection_send(cmd->conn, cmd->reply, NULL, NULL, -1);
- return ECORE_CALLBACK_CANCEL;
- }
-
- if (cmd->initial_sequence_counter == 0)
- {
- 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 (cmd->initial_sequence_counter < PINCH_INITIAL_STEPS)
- {
- 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;
- }
-
- 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);
+ Point tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
- cmd->sequence_counter++;
- cmd->ts->dispatch_func(new_x, cmd->y, cmd->sequence_counter % 2);
+Eldbus_Message *
+_e_dispatch_drag_event(DragInfo drag_info, Eldbus_Connection *conn, const Eldbus_Message *msg)
+{
+ Eldbus_Message *error_message = _correct_coordinates(&drag_info.start, drag_info.steps, msg);
+ if (error_message)
+ return error_message;
- ecore_timer_add(cmd->ts->delay, _pinch_touch_sequence_timer, cmd);
- return ECORE_CALLBACK_CANCEL;
- }
+ GestureCommand *cmd = (GestureCommand *)malloc(sizeof(GestureCommand));
+ if (!cmd)
+ return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Malloc error");
- cmd->ts++;
- if (cmd->terminal_sequence_conter == 0)
- {
- 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;
- }
+ cmd->drag_info[0] = drag_info;
+ cmd->drag_info_size = 1;
+ cmd->sequence_counter = 0;
+ cmd->conn = conn;
+ cmd->reply = eldbus_message_method_return_new(msg);
- 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;
+ during_gesture = EINA_TRUE;
+ _start_gesture_sequence(cmd);
- return ECORE_CALLBACK_CANCEL;
+ return NULL;
}
-void _e_dispatch_drag_event(DragInfo di, Eldbus_Connection *conn, const Eldbus_Message *msg)
+Eldbus_Message *
+_e_dispatch_pinch_event(PinchInfo pinch_info, 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
+ DragInfo temporary_drag_info[2];
+ for (int i = 0; i < 2; i++)
{
- 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 (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");
- eldbus_connection_send(conn, reply, NULL, NULL, -1);
- return;
- }
+ temporary_drag_info[i].hold_time = 0;
+ temporary_drag_info[i].steps = pinch_info.steps;
+ temporary_drag_info[i].start = pinch_info.point;
+ temporary_drag_info[i].end = pinch_info.point;
+ if (i == 0)
+ temporary_drag_info[i].end.x -= pinch_info.radius_change;
+ else
+ temporary_drag_info[i].end.x += pinch_info.radius_change;
- // 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.y == 0) di.start.y += 1;
- if (di.start.y == zh) di.start.y -= 1;
+ if (pinch_info.radius_change < 0)
+ _swap_points(&temporary_drag_info[i].start, &temporary_drag_info[i].end);
- _ts_drag[3].delay = di.hold_time;
+ Eldbus_Message *error_message = _correct_coordinates(&temporary_drag_info[i].start, temporary_drag_info[i].steps, msg);
+ if (error_message)
+ return error_message;
+ }
- TouchHoldThenDragCommand *cmd = (TouchHoldThenDragCommand *)malloc(sizeof(TouchHoldThenDragCommand));
+ GestureCommand *cmd = (GestureCommand *)malloc(sizeof(GestureCommand));
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;
- }
+ return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Malloc error");
- cmd->drag_info = di;
- cmd->initial_sequence_counter = 0;
+ cmd->drag_info[0] = temporary_drag_info[0];
+ cmd->drag_info[1] = temporary_drag_info[1];
+ cmd->drag_info_size = 2;
cmd->sequence_counter = 0;
- cmd->ts = _ts_drag;
cmd->conn = conn;
cmd->reply = eldbus_message_method_return_new(msg);
during_gesture = EINA_TRUE;
- ecore_timer_add(0.0, _drag_touch_sequence_timer, cmd);
+ _start_gesture_sequence(cmd);
+
+ return NULL;
}
-void _e_dispatch_pinch_event(PinchInfo pi, Eldbus_Connection *conn, const Eldbus_Message *msg)
+static void
+_start_gesture_sequence(GestureCommand *cmd)
{
- 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
+ for (int i = 0; i < cmd->drag_info_size; i++)
{
- 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;
+ _dispatch_mouse_move_event(cmd->drag_info[i].start.x, cmd->drag_info[i].start.y, i);
+ _dispatch_mouse_down_event(cmd->drag_info[i].start.x, cmd->drag_info[i].start.y, i);
}
+ ecore_timer_add(cmd->drag_info[0].hold_time, _on_hold_timer, cmd);
+}
- 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;
- }
+static Eina_Bool
+_on_hold_timer(void *data)
+{
+ GestureCommand *cmd = data;
+ for (int i = 0; i < cmd->drag_info_size; i++)
+ _dispatch_mouse_move_event(cmd->drag_info[i].start.x, cmd->drag_info[i].start.y, i);
- 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;
- }
+ ecore_timer_add(STEP_DURATION, _on_gesture_sequence_timer, cmd);
+ return ECORE_CALLBACK_CANCEL;
+}
- cmd->y =pi.point.y;
+static int
+_calculate_middle_val(int start, int end, int step, int steps)
+{
+ return (start * (steps - step) + end * step) / steps;
+}
- if (pi.pinch_out)
+static Eina_Bool
+_on_gesture_sequence_timer(void *data)
+{
+ GestureCommand *cmd = data;
+
+ if (cmd->sequence_counter > cmd->drag_info[0].steps)
{
- 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;
+ _on_terminate_gesture_sequence(cmd);
+ return ECORE_CALLBACK_CANCEL;
}
- else
+
+ for (int i = 0; i < cmd->drag_info_size; i++)
{
- 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;
+ int current_x = _calculate_middle_val(cmd->drag_info[i].start.x, cmd->drag_info[i].end.x, cmd->sequence_counter, cmd->drag_info[i].steps);
+ int current_y = _calculate_middle_val(cmd->drag_info[i].start.y, cmd->drag_info[i].end.y, cmd->sequence_counter, cmd->drag_info[i].steps);
+ _dispatch_mouse_move_event(current_x, current_y, i);
}
- // 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->sequence_counter++;
+ ecore_timer_add(STEP_DURATION, _on_gesture_sequence_timer, cmd);
+ return ECORE_CALLBACK_CANCEL;
+}
- 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;
+static void
+_on_terminate_gesture_sequence(GestureCommand *cmd)
+{
+ for (int i = 0; i < cmd->drag_info_size; i++)
+ _dispatch_mouse_up_event(cmd->drag_info[i].end.x, cmd->drag_info[i].end.y, i);
- during_gesture = EINA_TRUE;
- ecore_timer_add(0.0, _pinch_touch_sequence_timer, cmd);
-}
+ during_gesture = EINA_FALSE;
+ eldbus_connection_send(cmd->conn, cmd->reply, NULL, NULL, -1);
+ free(cmd);
+}
\ No newline at end of file