From: Pawel Kurowski Date: Tue, 19 Dec 2017 21:52:09 +0000 (+0100) Subject: Refactor of e_dispatch_gesture_event.c X-Git-Tag: submit/tizen/20180124.103314^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ba79aee4ec2c656fc8394333008759781330f7e;p=platform%2Fcore%2Fuifw%2Fe-mod-tizen-screen-reader.git Refactor of e_dispatch_gesture_event.c Change-Id: If40691685f0552da31b168c1c940ee445500ea4e --- diff --git a/src/e_dispatch_gesture_event.c b/src/e_dispatch_gesture_event.c index f4170f1..2382648 100644 --- a/src/e_dispatch_gesture_event.c +++ b/src/e_dispatch_gesture_event.c @@ -2,83 +2,27 @@ #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() { @@ -102,23 +46,6 @@ 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; @@ -221,241 +148,160 @@ static void _dispatch_mouse_up_event(int x, int y, int device) 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 diff --git a/src/e_dispatch_gesture_event.h b/src/e_dispatch_gesture_event.h index 6568a8c..402c89e 100644 --- a/src/e_dispatch_gesture_event.h +++ b/src/e_dispatch_gesture_event.h @@ -15,13 +15,11 @@ typedef struct _DragInfo { typedef struct _PinchInfo { Point point; - Eina_Bool pinch_out; - int length; + int radius_change; int steps; } PinchInfo; -void _e_dispatch_gesture_event(int type, int x, int y); -void _e_dispatch_drag_event(DragInfo di, Eldbus_Connection *conn, const Eldbus_Message *msg); -void _e_dispatch_pinch_event(PinchInfo pi, Eldbus_Connection *conn, const Eldbus_Message *msg); +Eldbus_Message * _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); #endif /* E_DISPATCH_GESTURE_EVENT_H_ */ diff --git a/src/e_mod_main.c b/src/e_mod_main.c index eec6338..0eb33a0 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -78,7 +78,7 @@ static const Eldbus_Method methods[] = { { "DispatchDragEvent", ELDBUS_ARGS({"i", "int"}, {"i", "int"}, {"i", "int"}, {"i", "int"}, {"i", "int"}, {"d", "double"}), NULL, _dispatch_drag_event }, - { "DispatchPinchEvent", ELDBUS_ARGS({"i", "int"}, {"i", "int"}, {"b", "bool"}, {"i", "int"}, {"i", "int"}), NULL, + { "DispatchPinchEvent", ELDBUS_ARGS({"i", "int"}, {"i", "int"}, {"i", "int"}, {"i", "int"}), NULL, _dispatch_pinch_event }, { "DispatchRotationEvent", ELDBUS_ARGS({"i", "int"}), NULL, @@ -421,33 +421,24 @@ _object_needs_scroll_gesture(const Eldbus_Service_Interface *iface, const Eldbus static Eldbus_Message * _dispatch_drag_event(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) { - DragInfo di; - if (eldbus_message_arguments_get(msg, "iiiiid", &di.start.x, &di.start.y, &di.end.x, &di.end.y, &di.steps, &di.hold_time)) - { - _e_dispatch_drag_event(di, conn, msg); - return NULL; - } - else - { - ERROR("eldbus_message_arguments_get() error\n"); - return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Cannot get correct arguments"); - } + DragInfo drag_info; + if (eldbus_message_arguments_get(msg, "iiiiid", &drag_info.start.x, &drag_info.start.y, &drag_info.end.x, &drag_info.end.y, &drag_info.steps, &drag_info.hold_time)) + return _e_dispatch_drag_event(drag_info, conn, msg); + + ERROR("eldbus_message_arguments_get() error\n"); + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Cannot get correct arguments"); } static Eldbus_Message * _dispatch_pinch_event(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) { - PinchInfo pi; - if (eldbus_message_arguments_get(msg, "iibii", &pi.point.x, &pi.point.y, &pi.pinch_out, &pi.length, &pi.steps)) - { - _e_dispatch_pinch_event(pi, conn, msg); - return NULL; - } - else - { - ERROR("eldbus_message_arguments_get() error\n"); - return eldbus_message_method_return_new(msg); - } + PinchInfo pinch_info; + if (eldbus_message_arguments_get(msg, "iiii", &pinch_info.point.x, &pinch_info.point.y, &pinch_info.radius_change, &pinch_info.steps)) + return _e_dispatch_pinch_event(pinch_info, conn, msg); + + ERROR("eldbus_message_arguments_get() error\n"); + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Cannot get correct arguments"); + } static Eldbus_Message *