touch: added maru_finger_processing_3 function on maru_sdl 59/35259/2
authorGiWoong Kim <giwoong.kim@samsung.com>
Tue, 30 Dec 2014 03:20:42 +0000 (12:20 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Fri, 13 Feb 2015 05:43:49 +0000 (21:43 -0800)
support symmetric multi-touch (Ctrl + Alt + Click)

Change-Id: I38395c2f968bd10b9140c4fd8f6123fc83172aa1
Signed-off-by: GiWoong Kim <giwoong.kim@samsung.com>
tizen/src/display/maru_finger.c
tizen/src/display/maru_finger.h
tizen/src/emul_state.c
tizen/src/emul_state.h
tizen/src/skin/maruskin_operation.c

index 05b7943..45dd127 100644 (file)
@@ -161,6 +161,9 @@ static void sdl_fill_circle(SDL_Surface *surface, int cx, int cy, int radius, Ui
 
 /* ==================================================================================================== */
 
+static int _grab_finger_id = 0;
+#define QEMU_MOUSE_PRESSED 1
+#define QEMU_MOUSE_RELEASEED 0
 
 void init_multi_touch_state(void)
 {
@@ -230,12 +233,17 @@ void init_multi_touch_state(void)
     mts->finger_point_surface = (void *)point;
 }
 
+int get_finger_cnt(void)
+{
+    return get_emul_multi_touch_state()->finger_cnt;
+}
+
 int add_finger_point(int origin_x, int origin_y, int x, int y)
 {
     MultiTouchState *mts = get_emul_multi_touch_state();
 
     if (mts->finger_cnt == mts->finger_cnt_max) {
-        WARN("support multi-touch up to %d fingers\n", mts->finger_cnt_max);
+        WARN("supports up to %d fingers\n", mts->finger_cnt_max);
         return -1;
     }
 
@@ -247,7 +255,31 @@ int add_finger_point(int origin_x, int origin_y, int x, int y)
     mts->finger_slot[mts->finger_cnt - 1].x = x;
     mts->finger_slot[mts->finger_cnt - 1].y = y;
 
-    INFO("%d finger touching\n", mts->finger_cnt);
+    INFO("id %d finger touching\n", mts->finger_cnt);
+
+    return mts->finger_cnt;
+}
+
+int remove_finger_point_from_slot(int index)
+{
+    _grab_finger_id = 0;
+
+    MultiTouchState *mts = get_emul_multi_touch_state();
+
+    FingerPoint *finger = get_finger_point_from_slot(index);
+    if (finger != NULL) {
+        INFO("id %d finger releasing\n", finger->id);
+
+        if (finger->id > 0) {
+            virtio_touchscreen_event(finger->x, finger->y,
+                finger->id - 1, QEMU_MOUSE_RELEASEED);
+        }
+
+        finger->id = 0;
+        finger->origin_x = finger->origin_y = finger->x = finger->y = -1;
+
+        mts->finger_cnt--;
+    }
 
     return mts->finger_cnt;
 }
@@ -287,11 +319,6 @@ FingerPoint *get_finger_point_search(int x, int y)
     return NULL;
 }
 
-
-static int _grab_finger_id = 0;
-#define QEMU_MOUSE_PRESSED 1
-#define QEMU_MOUSE_RELEASEED 0
-
 void maru_finger_processing_1(
     int touch_type, int origin_x, int origin_y, int x, int y)
 {
@@ -336,20 +363,22 @@ void maru_finger_processing_1(
         else if (mts->finger_cnt == mts->finger_cnt_max)
         { /* Let's assume that this event is last finger touch input */
 
-            finger = get_finger_point_from_slot(mts->finger_cnt_max - 1);
+            finger = get_finger_point_from_slot(mts->finger_cnt - 1);
             if (finger != NULL) {
-#if 1 /* send release event?? */
+#if 1 /* send release event */
                 virtio_touchscreen_event(finger->x, finger->y,
-                    mts->finger_cnt_max - 1, QEMU_MOUSE_RELEASEED);
+                    mts->finger_cnt - 1, QEMU_MOUSE_RELEASEED);
 #endif
 
+                /* update position */
                 finger->origin_x = origin_x;
                 finger->origin_y = origin_y;
                 finger->x = x;
                 finger->y = y;
                 if (finger->id != 0) {
+                    INFO("%d finger touching\n", finger->id);
                     virtio_touchscreen_event(x, y,
-                        mts->finger_cnt_max - 1, QEMU_MOUSE_PRESSED);
+                        mts->finger_cnt - 1, QEMU_MOUSE_PRESSED);
                 }
             }
         }
@@ -375,19 +404,19 @@ void maru_finger_processing_2(
         if (_grab_finger_id > 0) {
             finger = get_finger_point_from_slot(_grab_finger_id - 1);
             if (finger != NULL) {
-                int origin_distance_x = origin_x - finger->origin_x;
-                int origin_distance_y = origin_y - finger->origin_y;
-                int distance_x = x - finger->x;
-                int distance_y = y - finger->y;
-
-                int current_screen_w = get_emul_resolution_width();
-                int current_screen_h = get_emul_resolution_height();
-                int temp_finger_x, temp_finger_y;
+                const int origin_distance_x = origin_x - finger->origin_x;
+                const int origin_distance_y = origin_y - finger->origin_y;
+                const int distance_x = x - finger->x;
+                const int distance_y = y - finger->y;
 
                 int i = 0;
 
                 /* bounds checking */
-                for(i = 0; i < get_emul_multi_touch_state()->finger_cnt; i++) {
+                const int current_screen_w = get_emul_resolution_width();
+                const int current_screen_h = get_emul_resolution_height();
+                int temp_finger_x, temp_finger_y;
+
+                for (i = 0; i < get_emul_multi_touch_state()->finger_cnt; i++) {
                     finger = get_finger_point_from_slot(i);
                     if (finger == NULL) {
                         continue;
@@ -396,15 +425,16 @@ void maru_finger_processing_2(
                     temp_finger_x = finger->x + distance_x;
                     temp_finger_y = finger->y + distance_y;
 
-                    if (temp_finger_x > current_screen_w || temp_finger_x < 0
-                        || temp_finger_y > current_screen_h || temp_finger_y < 0) {
-                        TRACE("id %d finger is out of bounds (%d, %d)\n",
+                    if (temp_finger_x >= current_screen_w || temp_finger_x < 0
+                        || temp_finger_y >= current_screen_h || temp_finger_y < 0) {
+                        TRACE("id %d finger is out of bounds (%d, %d)\n",
                             i + 1, temp_finger_x, temp_finger_y);
                         return;
                     }
                 }
 
-                for(i = 0; i < get_emul_multi_touch_state()->finger_cnt; i++) {
+                /* move */
+                for (i = 0; i < get_emul_multi_touch_state()->finger_cnt; i++) {
                     finger = get_finger_point_from_slot(i);
                     if (finger == NULL) {
                         continue;
@@ -418,13 +448,13 @@ void maru_finger_processing_2(
                     if (finger->id != 0) {
                         virtio_touchscreen_event(finger->x, finger->y,
                             i, QEMU_MOUSE_PRESSED);
-                        TRACE("id %d finger multi-touch dragging = (%d, %d)\n",
+                        TRACE("id %d finger multi-touch dragging : (%d, %d)\n",
                             i + 1, finger->x, finger->y);
                     }
-#ifdef _WIN32
-                    Sleep(2);
+#ifdef CONFIG_WIN32
+                    Sleep(1);
 #else
-                    usleep(2000);
+                    usleep(1000);
 #endif
 
                 }
@@ -450,18 +480,133 @@ void maru_finger_processing_2(
             TRACE("id %d finger is grabbed\n", _grab_finger_id);
         }
         else if (mts->finger_cnt == mts->finger_cnt_max)
-        { /* Let's assume that this event is last finger touch input */
-
+        {
             /* do nothing */
+            return;
         }
         else /* one more finger */
         {
+            add_finger_point(origin_x, origin_y, x, y);
+            virtio_touchscreen_event(x, y,
+                mts->finger_cnt - 1, QEMU_MOUSE_PRESSED);
+        }
+
+    } else if (touch_type == MOUSE_UP) { /* released */
+        _grab_finger_id = 0;
+    }
+}
+
+void maru_finger_processing_3(
+    int touch_type, int origin_x, int origin_y, int x, int y)
+{
+    MultiTouchState *mts = get_emul_multi_touch_state();
+    FingerPoint *finger = NULL;
+
+    if (touch_type == MOUSE_DOWN || touch_type == MOUSE_DRAG) { /* pressed */
+        if (_grab_finger_id > 0 && _grab_finger_id <= 2) {
+            FingerPoint *finger1 = get_finger_point_from_slot(0);
+            FingerPoint *finger2 = get_finger_point_from_slot(1);
+            if (finger1 != NULL && finger2 != NULL) {
+                FingerPoint *co_finger = NULL;
+
+                if (_grab_finger_id == 2) {
+                    finger = finger2;
+                    co_finger = finger1;
+                } else {
+                    finger = finger1;
+                    co_finger = finger2;
+                }
+
+                const int origin_distance_x = origin_x - finger->origin_x;
+                const int origin_distance_y = origin_y - finger->origin_y;
+                const int distance_x = x - finger->x;
+                const int distance_y = y - finger->y;
 
-            add_finger_point(origin_x, origin_y, x, y) ;
-            virtio_touchscreen_event(x, y, mts->finger_cnt - 1, QEMU_MOUSE_PRESSED);
+                /* bounds checking */
+                if ((co_finger->x - distance_x) >= get_emul_resolution_width() ||
+                    (co_finger->x - distance_x) < 0 ||
+                    (co_finger->y - distance_y) >= get_emul_resolution_height() ||
+                    (co_finger->y - distance_y) < 0) {
+                    TRACE("id %d finger is out of bounds (%d, %d)\n",
+                        co_finger->id, co_finger->x - distance_x, co_finger->y - distance_y);
+                    return;
+                }
+
+                /* move */
+                finger->origin_x += origin_distance_x;
+                finger->origin_y += origin_distance_y;
+                finger->x += distance_x;
+                finger->y += distance_y;
+                if (finger->id != 0) {
+                    virtio_touchscreen_event(x, y,
+                        finger->id - 1, QEMU_MOUSE_PRESSED);
+                    TRACE("id %d finger multi-touch dragging : (%d, %d)\n",
+                        finger->id, x, y);
+                }
+
+                co_finger->origin_x -= origin_distance_x;
+                co_finger->origin_y -= origin_distance_y;
+                co_finger->x -= distance_x;
+                co_finger->y -= distance_y;
+                if (co_finger->id != 0) {
+                    virtio_touchscreen_event(x, y,
+                        co_finger->id - 1, QEMU_MOUSE_PRESSED);
+                    TRACE("id %d finger multi-touch dragging : (%d, %d)\n",
+                        co_finger->id, x, y);
+                }
+
+                return;
+            }
+        }
+
+        if (mts->finger_cnt == 0)
+        { /* first finger touch input */
+
+            if (add_finger_point(origin_x, origin_y, x, y) == -1) {
+                return;
+            }
+
+            virtio_touchscreen_event(x, y, 0, QEMU_MOUSE_PRESSED);
+        }
+        else if ((finger = get_finger_point_search(x, y)) != NULL)
+        { /* check the position of previous touch event */
+
+            /* finger point is selected */
+            _grab_finger_id = finger->id;
+            INFO("id %d finger is grabbed\n", _grab_finger_id);
+        }
+        else if (mts->finger_cnt >= 2) /* supports up to 2 fingers */
+        { /* Let's assume that this event is last finger touch input */
+
+            finger = get_finger_point_from_slot(1);
+            if (finger != NULL) {
+#if 1 /* send release event */
+                virtio_touchscreen_event(finger->x, finger->y,
+                    1, QEMU_MOUSE_RELEASEED);
+#endif
+
+                /* update position */
+                finger->origin_x = origin_x;
+                finger->origin_y = origin_y;
+                finger->x = x;
+                finger->y = y;
+                if (finger->id != 0) {
+                    INFO("id %d finger touching\n", finger->id);
+                    virtio_touchscreen_event(x, y, 1, QEMU_MOUSE_PRESSED);
+                }
+            };
+        }
+        else /* one more finger */
+        {
+            add_finger_point(origin_x, origin_y, x, y);
+            virtio_touchscreen_event(x, y,
+                mts->finger_cnt - 1, QEMU_MOUSE_PRESSED);
         }
 
     } else if (touch_type == MOUSE_UP) { /* released */
+        if (_grab_finger_id != 0) {
+            INFO("id %d finger releasing\n", _grab_finger_id);
+        }
         _grab_finger_id = 0;
     }
 }
index 3815d3a..6495779 100644 (file)
@@ -62,12 +62,15 @@ typedef struct MultiTouchState {
 
 
 void init_multi_touch_state(void);
+int get_finger_cnt(void);
+int remove_finger_point_from_slot(int index);
 FingerPoint *get_finger_point_from_slot(int index);
 FingerPoint *get_finger_point_search(int x, int y);
 int add_finger_point(int origin_x, int origin_y, int x, int y);
 
 void maru_finger_processing_1(int touch_type, int origin_x, int origin_y, int x, int y);
 void maru_finger_processing_2(int touch_type, int origin_x, int origin_y, int x, int y);
+void maru_finger_processing_3(int touch_type, int origin_x, int origin_y, int x, int y);
 int rearrange_finger_points(int lcd_w, int lcd_h, double scale_factor, int rotaton_type);
 void clear_finger_slot(bool keep_enable);
 void cleanup_multi_touch_state(void);
index 21dbe7c..e178296 100644 (file)
@@ -325,9 +325,9 @@ MultiTouchState *get_emul_multi_touch_state(void)
     return &(_emul_state.qemu_mts);
 }
 
-void set_multi_touch_enable(int enable)
+void set_multi_touch_enable(int mode)
 {
-    _emul_state.qemu_mts.multitouch_enable = enable;
+    _emul_state.qemu_mts.multitouch_enable = mode;
 }
 
 int get_multi_touch_enable(void)
index 88ef3c7..4d4ef10 100644 (file)
@@ -210,7 +210,7 @@ bool get_sdb_connection(void);
 
 /* multi-touch */
 MultiTouchState *get_emul_multi_touch_state(void);
-void set_multi_touch_enable(int enable);
+void set_multi_touch_enable(int mode);
 int get_multi_touch_enable(void);
 
 #endif /* __EMUL_STATE_H__ */
index e2ea3bf..1369f41 100644 (file)
@@ -123,16 +123,24 @@ void do_mouse_event(int button_type, int event_type,
 
 #if !defined(CONFIG_USE_SHM) && defined(CONFIG_SDL)
     /* multi-touch */
-    if (get_emul_multi_touch_state()->multitouch_enable == 1) {
+    if (get_multi_touch_enable() == 1) {
+        /* Ctrl or Shift */
         maru_finger_processing_1(event_type, origin_x, origin_y, x, y);
 
         maru_display_update();
         return;
-    } else if (get_emul_multi_touch_state()->multitouch_enable == 2) {
+    } else if (get_multi_touch_enable() == 2) {
+        /* Ctrl + Shift */
         maru_finger_processing_2(event_type, origin_x, origin_y, x, y);
 
         maru_display_update();
         return;
+    } else if (get_multi_touch_enable() == 3) {
+        /* Ctrl + Alt */
+        maru_finger_processing_3(event_type, origin_x, origin_y, x, y);
+
+        maru_display_update();
+        return;
     }
 #endif
 
@@ -207,11 +215,27 @@ static void multitouch_toggle_key_checking(int event_type,
     /* multi-touch checking */
     state_mask &= ~JAVA_KEYCODE_NO_FOCUS;
 
-    if ((keycode == JAVA_KEYCODE_BIT_SHIFT && state_mask == JAVA_KEYCODE_BIT_CTRL) ||
+    if ((keycode == JAVA_KEYCODE_BIT_CTRL && state_mask == JAVA_KEYCODE_BIT_ALT) ||
+            (keycode == JAVA_KEYCODE_BIT_ALT && state_mask == JAVA_KEYCODE_BIT_CTRL))
+    {
+        if (KEY_PRESSED == event_type) {
+            /* multi-touch mode 3 supports up to 2 fingers */
+            int i = get_finger_cnt();
+            for ( ; i > 2; i--) {
+                remove_finger_point_from_slot(i - 1);
+            }
+            maru_display_update();
+
+            set_multi_touch_enable(3);
+
+            INFO("enable multi-touch mode 3\n");
+        }
+    }
+    else if ((keycode == JAVA_KEYCODE_BIT_SHIFT && state_mask == JAVA_KEYCODE_BIT_CTRL) ||
         (keycode == JAVA_KEYCODE_BIT_CTRL && state_mask == JAVA_KEYCODE_BIT_SHIFT))
     {
         if (KEY_PRESSED == event_type) {
-            get_emul_multi_touch_state()->multitouch_enable = 2;
+            set_multi_touch_enable(2);
 
             /* Before the Emulator starts multi-touch processing,
              * add a first finger if user just switches on to the multi-touch mode
@@ -230,11 +254,10 @@ static void multitouch_toggle_key_checking(int event_type,
             INFO("enable multi-touch mode 2\n");
         }
     }
-    else if (keycode == JAVA_KEYCODE_BIT_CTRL ||
-        keycode == JAVA_KEYCODE_BIT_SHIFT)
+    else if (keycode == JAVA_KEYCODE_BIT_CTRL || keycode == JAVA_KEYCODE_BIT_SHIFT)
     {
         if (KEY_PRESSED == event_type) {
-            get_emul_multi_touch_state()->multitouch_enable = 1;
+            set_multi_touch_enable(1);
 
             /* Before the Emulator starts multi-touch processing,
              * add a first finger if user just switches on to the multi-touch mode
@@ -253,7 +276,7 @@ static void multitouch_toggle_key_checking(int event_type,
             INFO("enable multi-touch mode 1\n");
         } else if (KEY_RELEASED == event_type) {
             if (state_mask == (JAVA_KEYCODE_BIT_CTRL | JAVA_KEYCODE_BIT_SHIFT)) {
-                get_emul_multi_touch_state()->multitouch_enable = 1;
+                set_multi_touch_enable(1);
                 INFO("enable multi-touch mode 2->1\n");
             } else {
                 clear_finger_slot(false);
@@ -261,6 +284,22 @@ static void multitouch_toggle_key_checking(int event_type,
             }
 
             maru_display_update();
+        } else {
+            WARN("invalid event type : %d\n", event_type);
+        }
+    }
+    else if (keycode == JAVA_KEYCODE_BIT_ALT)
+    {
+        if (KEY_RELEASED == event_type) {
+            if (state_mask == (JAVA_KEYCODE_BIT_CTRL | JAVA_KEYCODE_BIT_ALT)) {
+                set_multi_touch_enable(1);
+                INFO("enable multi-touch mode 3->1\n");
+            } else {
+                clear_finger_slot(false);
+                INFO("disable multi-touch\n");
+            }
+
+            maru_display_update();
         }
     }
 }
@@ -271,7 +310,7 @@ void do_keyboard_key_event(int event_type,
 {
     int scancode = -1;
 
-    TRACE("Keyboard Key : event_type=%d, keycode=%d,"
+    TRACE("Keyboard Key : event_type=%d, keycode=%d, "
         "state_mask=%d, key_location=%d\n",
         event_type, keycode, state_mask, key_location);