From: GiWoong Kim Date: Tue, 28 Apr 2015 12:38:43 +0000 (+0900) Subject: touch: implement multi-touch tracking X-Git-Tag: TizenStudio_2.0_p3.0~214^2~36^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dcbc5035bae6ad7aab2ef48f8f1236b6e7a5ba47;p=sdk%2Femulator%2Fqemu.git touch: implement multi-touch tracking supports separated moving mode only Change-Id: If3193d7f961118fca4305744ce2114ff4d10a259 Signed-off-by: GiWoong Kim --- diff --git a/tizen/src/ui/displaybase.cpp b/tizen/src/ui/displaybase.cpp index 7b0ccb9..54fbec7 100644 --- a/tizen/src/ui/displaybase.cpp +++ b/tizen/src/ui/displaybase.cpp @@ -127,6 +127,11 @@ QPoint DisplayBase::getGuestPos(QPoint hostPos) return guestPos; } +TouchScreenHelper *DisplayBase::getTouchScreenHelper() +{ + return tsHelper; +} + void DisplayBase::handleMousePress(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { diff --git a/tizen/src/ui/displaybase.h b/tizen/src/ui/displaybase.h index 8728bd5..495a44d 100644 --- a/tizen/src/ui/displaybase.h +++ b/tizen/src/ui/displaybase.h @@ -46,7 +46,9 @@ public: void scale(qreal scaleFactor); void update(); void updateGeometry(); + QPoint getGuestPos(QPoint hostPos); + TouchScreenHelper *getTouchScreenHelper(); protected: DisplayBase(QRect rect, int angle, qreal scaleFactor, QWidget *w); diff --git a/tizen/src/ui/input/Makefile.objs b/tizen/src/ui/input/Makefile.objs index 71484d4..2b953a4 100644 --- a/tizen/src/ui/input/Makefile.objs +++ b/tizen/src/ui/input/Makefile.objs @@ -1,4 +1,5 @@ obj-$(CONFIG_QT) += touchscreenhelper.o +obj-$(CONFIG_QT) += multitouchtracker.o obj-$(CONFIG_QT) += keyboardhelper.o obj-$(CONFIG_QT) += keyboardshortcut.o moc_keyboardshortcut.o diff --git a/tizen/src/ui/input/keyboardhelper.cpp b/tizen/src/ui/input/keyboardhelper.cpp index 5c3e21f..5000f18 100644 --- a/tizen/src/ui/input/keyboardhelper.cpp +++ b/tizen/src/ui/input/keyboardhelper.cpp @@ -30,6 +30,7 @@ #include #include "keyboardhelper.h" +#include "mainwindow.h" extern "C" { #include "emul_state.h" @@ -38,13 +39,14 @@ extern "C" { void virtio_keyboard_event(int keycode); } -KeyboardHelper::KeyboardHelper() +KeyboardHelper::KeyboardHelper(QWidget *parent) { - createKeyMap(); - createKeypadMap(); - + this->parent = parent; this->numLockState = false; this->capsLockState = false; + + createKeyMap(); + createKeypadMap(); } void KeyboardHelper::createKeypadMap() @@ -205,6 +207,14 @@ void KeyboardHelper::createKeyMap() keyMap.insert(Qt::Key_F12, 88); /* f12 */ } +void KeyboardHelper::finishMtTracking() +{ + DisplayBase *display = ((MainWindow *)parent->parentWidget())->getDisplay(); + if (display != NULL) { + display->getTouchScreenHelper()->finishMtTracking(); + } +} + void KeyboardHelper::autoKeyRelease(void) { while (!keyCodeList.isEmpty()) { @@ -216,9 +226,10 @@ void KeyboardHelper::autoKeyRelease(void) /* disable multi-touch mode */ if (get_multi_touch_enable() != 0) { - set_multi_touch_enable(0); - qDebug() << "disable multi-touch"; + + set_multi_touch_enable(0); + finishMtTracking(); } } @@ -275,39 +286,42 @@ bool KeyboardHelper::isSpecialKey(int keyCode) return false; } -static void pressFilterMtChecking(QKeyEvent *event) { +void KeyboardHelper::pressFilterMtChecking(QKeyEvent *event) +{ switch(event->key()) { case Qt::Key_Alt: if (event->modifiers() == (Qt::ControlModifier | Qt::AltModifier)) { - set_multi_touch_enable(3); qDebug() << "enable multi-touch mode : 3"; + set_multi_touch_enable(3); } break; case Qt::Key_Shift: if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { - set_multi_touch_enable(2); qDebug() << "enable multi-touch mode : 2"; + set_multi_touch_enable(2); } else if (event->modifiers() == Qt::ShiftModifier) { - set_multi_touch_enable(1); qDebug() << "enable multi-touch mode : 1"; + set_multi_touch_enable(1); } break; case Qt::Key_Control: if (event->modifiers() == Qt::ControlModifier) { - set_multi_touch_enable(1); qDebug() << "enable multi-touch mode : 1"; + set_multi_touch_enable(1); } else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { - set_multi_touch_enable(2); qDebug() << "enable multi-touch mode : 2"; + set_multi_touch_enable(2); } break; default: if (get_multi_touch_enable() != 0) { - set_multi_touch_enable(0); qDebug() << "disable multi-touch"; + + set_multi_touch_enable(0); + finishMtTracking(); } break; @@ -417,35 +431,42 @@ void KeyboardHelper::keyPressed(QKeyEvent *event) } } -static void releaseFilterMtChecking(QKeyEvent *event) { +void KeyboardHelper::releaseFilterMtChecking(QKeyEvent *event) +{ switch(event->key()) { case Qt::Key_Alt: if (event->modifiers() == Qt::ControlModifier) { - set_multi_touch_enable(1); qDebug() << "enabled multi-touch mode : 3 -> 1"; + set_multi_touch_enable(1); } else { - set_multi_touch_enable(0); qDebug() << "disable multi-touch"; + + set_multi_touch_enable(0); + finishMtTracking(); } break; case Qt::Key_Shift: if (event->modifiers() == Qt::ControlModifier) { - set_multi_touch_enable(1); qDebug() << "enabled multi-touch mode : 2 -> 1"; + set_multi_touch_enable(1); } else { - set_multi_touch_enable(0); qDebug() << "disable multi-touch"; + + set_multi_touch_enable(0); + finishMtTracking(); } break; case Qt::Key_Control: if (event->modifiers() == Qt::ShiftModifier) { - set_multi_touch_enable(1); qDebug() << "enabled multi-touch mode : 2 -> 1"; + set_multi_touch_enable(1); } else { - set_multi_touch_enable(0); qDebug() << "disable multi-touch"; + + set_multi_touch_enable(0); + finishMtTracking(); } break; diff --git a/tizen/src/ui/input/keyboardhelper.h b/tizen/src/ui/input/keyboardhelper.h index 7eef329..c4afca6 100644 --- a/tizen/src/ui/input/keyboardhelper.h +++ b/tizen/src/ui/input/keyboardhelper.h @@ -40,7 +40,7 @@ enum KbdLedState { class KeyboardHelper { public: - KeyboardHelper(); + KeyboardHelper(QWidget *parent); ~KeyboardHelper(); void keyPressed(QKeyEvent *event); @@ -50,6 +50,7 @@ public: int keyCodeOperation(QKeyEvent *event, int keyCode); protected: + QWidget *parent; QList keyCodeList; QMap keyMap; QMap keypadMap; @@ -59,6 +60,10 @@ protected: private: void createKeyMap(); void createKeypadMap(); + + void finishMtTracking(); + void pressFilterMtChecking(QKeyEvent *event); + void releaseFilterMtChecking(QKeyEvent *event); }; #endif // KEYBOARDHELPER_H diff --git a/tizen/src/ui/input/multitouchtracker.cpp b/tizen/src/ui/input/multitouchtracker.cpp new file mode 100644 index 0000000..1663fe5 --- /dev/null +++ b/tizen/src/ui/input/multitouchtracker.cpp @@ -0,0 +1,231 @@ +/* + * Qt UI + * + * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * GiWoong Kim + * Sangho Park + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#include +#include + +#include "multitouchtracker.h" + +extern "C" { +void virtio_touchscreen_event(int x, int y, int z, int buttons_state); +} + +TouchPoint::TouchPoint() +{ + this->id = 0; + this->hostPos = QPoint(0, 0); + this->guestPos = QPoint(0, 0); +} + +TouchPoint::TouchPoint(int id, QPoint hostPos, QPoint guestPos) +{ + this->id = id; + this->hostPos = hostPos; + this->guestPos = guestPos; +} + +int TouchPoint::getID() +{ + return id; +} + +QPoint TouchPoint::getHostPos() +{ + return hostPos; +} + +QPoint TouchPoint::getGuestPos() +{ + return guestPos; +} + +void TouchPoint::updatePos(QPoint hostPos, QPoint guestPos) +{ + this->hostPos = hostPos; + this->guestPos = guestPos; +} + +MultiTouchTracker::MultiTouchTracker(int maxTouchPoint) +{ + this->maxTouchPoint = maxTouchPoint; + this->pointRadius = 16; // TODO: + this->grabTouchPoint = NULL; +} + +int MultiTouchTracker::getMaxTouchPoint() +{ + return maxTouchPoint; +} + +int MultiTouchTracker::addTouchPoint(QPoint hostPos, QPoint guestPos) +{ + const int touchCnt = touchPointList.count(); + + if (touchCnt >= getMaxTouchPoint()) { + qWarning() << "support multi-touch up to" << getMaxTouchPoint(); + return -1; + } + + TouchPoint *point = new TouchPoint(touchCnt + 1, hostPos, guestPos); + touchPointList.append(point); + qDebug() << "ID" << point->getID() << "point touching"; + + return touchPointList.count(); +} + +TouchPoint *MultiTouchTracker::searchTouchPoint(QPoint targetPos) +{ + TouchPoint *point = NULL; + + for (int i = 0; i < touchPointList.count(); i++) { + point = touchPointList.at(i); + if (point != NULL) { + if (targetPos.x() >= point->getHostPos().x() - pointRadius && + targetPos.x() < point->getHostPos().x() + pointRadius && + targetPos.y() >= point->getHostPos().y() - pointRadius && + targetPos.y() < point->getHostPos().y() + pointRadius) { + return point; + } + } + } + + return NULL; +} + +TouchPoint *MultiTouchTracker::searchTouchPoint(int targetID) +{ + TouchPoint *point = NULL; + + for (int i = 0; i < touchPointList.count(); i++) { + point = touchPointList.at(i); + if (point != NULL) { + if (targetID == point->getID()) { + return point; + } + } + } + + return NULL; +} + +/* separated moving mode */ +void MultiTouchTracker::touchProcessingSepa(QPoint hostPos, QPoint guestPos) +{ + TouchPoint *point = NULL; + const int touchCnt = touchPointList.count(); + + if (grabTouchPoint != NULL) { + grabTouchPoint->updatePos(hostPos, guestPos); + + virtio_touchscreen_event(guestPos.x(), guestPos.y(), + grabTouchPoint->getID() - 1, 1); + return; + } + + if (touchCnt == 0) { /* first touch input */ + qDebug("mt sepa mode processing"); + + if (addTouchPoint(hostPos, guestPos) == -1) { + return; + } + + virtio_touchscreen_event(guestPos.x(), guestPos.y(), 0, 1); + } else if ((point = searchTouchPoint(hostPos)) != NULL) { /* grab a touch */ + qDebug() << "ID" << point->getID() << "point is taken"; + grabTouchPoint = point; + } else if (touchCnt == getMaxTouchPoint()) { /* last touch */ + point = touchPointList.last(); + if (point != NULL) { + /* re-input */ + qDebug() << "ID" << point->getID() << "point re-touching"; + + virtio_touchscreen_event( + point->getGuestPos().x(), point->getGuestPos().y(), + point->getID() - 1, 0); + + point->updatePos(hostPos, guestPos); + virtio_touchscreen_event( + point->getGuestPos().x(), point->getGuestPos().y(), + point->getID() - 1, 1); + } + } else { /* additional touch */ + if (addTouchPoint(hostPos, guestPos) == -1) { + return; + } + + point = touchPointList.last(); + virtio_touchscreen_event(guestPos.x(), guestPos.y(), + point->getID() - 1, 1); + } +} + +/* parallel moving mode */ +void MultiTouchTracker::touchProcessingPara(QPoint hostPos, QPoint guestPos) +{ + //TODO: +} + +/* symmetrical moving mode */ +void MultiTouchTracker::touchProcessingSymm(QPoint hostPos, QPoint guestPos) +{ + //TODO: +} + +void MultiTouchTracker::touchReleasing() +{ + if (grabTouchPoint != NULL) { + qDebug() << "ID" << grabTouchPoint->getID() << "point let go"; + grabTouchPoint = NULL; + } +} + +void MultiTouchTracker::finishTracking() +{ + touchReleasing(); + + TouchPoint *point = NULL; + for (int i = 0; i < touchPointList.count(); i++) { + point = touchPointList.at(i); + if (point != NULL) { + virtio_touchscreen_event( + point->getGuestPos().x(), point->getGuestPos().y(), + point->getID() - 1, 0); + + delete point; + } + } + touchPointList.clear(); +} + +MultiTouchTracker::~MultiTouchTracker() +{ + qDebug("destroy multi-touch tracker"); + + finishTracking(); +} diff --git a/tizen/src/ui/input/multitouchtracker.h b/tizen/src/ui/input/multitouchtracker.h new file mode 100644 index 0000000..1032dac --- /dev/null +++ b/tizen/src/ui/input/multitouchtracker.h @@ -0,0 +1,73 @@ +/* + * Qt UI + * + * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * GiWoong Kim + * Sangho Park + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#ifndef MULTITOUCHTRACKER_H +#define MULTITOUCHTRACKER_H + +class TouchPoint +{ +public: + TouchPoint(); + TouchPoint(int id, QPoint hostPos, QPoint guestPos); + + int getID(); + QPoint getHostPos(); + QPoint getGuestPos(); + void updatePos(QPoint hostPos, QPoint guestPos); + +private: + int id; /* 1 ~ */ + QPoint hostPos; + QPoint guestPos; +}; + +class MultiTouchTracker +{ +public: + MultiTouchTracker(int maxTouchPoint); + ~MultiTouchTracker(); + + int getMaxTouchPoint(); + int addTouchPoint(QPoint hostPos, QPoint guestPos); + TouchPoint *searchTouchPoint(QPoint targetPos); + TouchPoint *searchTouchPoint(int targetID); + void touchProcessingSepa(QPoint hostPos, QPoint guestPos); + void touchProcessingPara(QPoint hostPos, QPoint guestPos); + void touchProcessingSymm(QPoint hostPos, QPoint guestPos); + void touchReleasing(); + void finishTracking(); + +private: + int maxTouchPoint; + int pointRadius; + TouchPoint *grabTouchPoint; + QList touchPointList; +}; + +#endif // MULTITOUCHTRACKER_H diff --git a/tizen/src/ui/input/touchscreenhelper.cpp b/tizen/src/ui/input/touchscreenhelper.cpp index cd11e1f..3649eaf 100644 --- a/tizen/src/ui/input/touchscreenhelper.cpp +++ b/tizen/src/ui/input/touchscreenhelper.cpp @@ -28,43 +28,76 @@ */ #include +#include #include "touchscreenhelper.h" extern "C" { #include "emul_state.h" -#include "skin/maruskin_operation.h" void virtio_touchscreen_event(int x, int y, int z, int buttons_state); } TouchScreenHelper::TouchScreenHelper() { - /* do nothing */ + this->mtTracker = new MultiTouchTracker(get_emul_max_touch_point()); } void TouchScreenHelper::mousePressed(QMouseEvent *event, QPoint guestPos) { - // TODO: multi-touch + /* multi-touch processing */ + if (get_multi_touch_enable() == 1) { + mtTracker->touchProcessingSepa(QPoint(event->x(), event->y()), guestPos); + return; + } else if (get_multi_touch_enable() == 2) { + mtTracker->touchProcessingPara(QPoint(event->x(), event->y()), guestPos); + return; + } else if (get_multi_touch_enable() == 3) { + mtTracker->touchProcessingSymm(QPoint(event->x(), event->y()), guestPos); + return; + } virtio_touchscreen_event(guestPos.x(), guestPos.y(), 0, 1); } void TouchScreenHelper::mouseReleased(QMouseEvent *event, QPoint guestPos) { - // TODO: multi-touch + if (get_multi_touch_enable() != 0) { + mtTracker->touchReleasing(); + return; + } virtio_touchscreen_event(guestPos.x(), guestPos.y(), 0, 0); } void TouchScreenHelper::mouseMoved(QMouseEvent *event, QPoint guestPos) { - // TODO: multi-touch + /* multi-touch processing */ + if (get_multi_touch_enable() == 1) { + mtTracker->touchProcessingSepa(QPoint(event->x(), event->y()), guestPos); + return; + } else if (get_multi_touch_enable() == 2) { + mtTracker->touchProcessingPara(QPoint(event->x(), event->y()), guestPos); + return; + } else if (get_multi_touch_enable() == 3) { + mtTracker->touchProcessingSymm(QPoint(event->x(), event->y()), guestPos); + return; + } virtio_touchscreen_event(guestPos.x(), guestPos.y(), 0, 1); } +void TouchScreenHelper::finishMtTracking() +{ + mtTracker->finishTracking(); +} + TouchScreenHelper::~TouchScreenHelper() { qDebug("destroy touch screen helper"); + + if (mtTracker != NULL) { + delete mtTracker; + mtTracker = NULL; + } } diff --git a/tizen/src/ui/input/touchscreenhelper.h b/tizen/src/ui/input/touchscreenhelper.h index 90745a2..ff62907 100644 --- a/tizen/src/ui/input/touchscreenhelper.h +++ b/tizen/src/ui/input/touchscreenhelper.h @@ -30,6 +30,8 @@ #ifndef TOUCHSCREENHELPER_H #define TOUCHSCREENHELPER_H +#include "multitouchtracker.h" + class TouchScreenHelper { public: @@ -40,7 +42,10 @@ public: void mouseReleased(QMouseEvent *event, QPoint guestPos); void mouseMoved(QMouseEvent *event, QPoint guestPos); + void finishMtTracking(); + private: + MultiTouchTracker *mtTracker; }; #endif // TOUCHSCREENHELPER_H diff --git a/tizen/src/ui/mainwindow.cpp b/tizen/src/ui/mainwindow.cpp index c7d55fa..3b6b612 100644 --- a/tizen/src/ui/mainwindow.cpp +++ b/tizen/src/ui/mainwindow.cpp @@ -217,6 +217,11 @@ ContextMenu *MainWindow::getPopupMenu() return popupMenu; } +DisplayBase *MainWindow::getDisplay() +{ + return display; +} + DockingController *MainWindow::getDockingCon() { return getUIState()->conState.dockingCon; diff --git a/tizen/src/ui/mainwindow.h b/tizen/src/ui/mainwindow.h index 8661f59..7c982d2 100644 --- a/tizen/src/ui/mainwindow.h +++ b/tizen/src/ui/mainwindow.h @@ -76,8 +76,10 @@ public: UIState *getUIState(void); ContextMenu *getPopupMenu(); + DisplayBase *getDisplay(); KeyboardShortcut *getKeyboardShortcut(); QLabel *getScreenWidget(); + void switchForm(int angle); void scaleForm(int scale); void capture(void); diff --git a/tizen/src/ui/skinview.cpp b/tizen/src/ui/skinview.cpp index 7b6806f..872ac66 100644 --- a/tizen/src/ui/skinview.cpp +++ b/tizen/src/ui/skinview.cpp @@ -48,7 +48,7 @@ SkinView::SkinView(QGraphicsScene *scene, QWidget *parent) : update(); - kbd = new KeyboardHelper(); + kbd = new KeyboardHelper(this); } void SkinView::createItems(MainForm *form)