diff options
Diffstat (limited to 'old/libqtuitest/qinputgenerator_symbian.cpp')
-rw-r--r-- | old/libqtuitest/qinputgenerator_symbian.cpp | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/old/libqtuitest/qinputgenerator_symbian.cpp b/old/libqtuitest/qinputgenerator_symbian.cpp new file mode 100644 index 0000000..2adce33 --- /dev/null +++ b/old/libqtuitest/qinputgenerator_symbian.cpp @@ -0,0 +1,425 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of QtUiTest. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qinputgenerator_p.h" + +#include <QtCore> +#include <QtGui> + +#include <w32std.h> +#include <e32event.h> +#include <e32std.h> + +#include <coemain.h> + +#include "qtuitestnamespace.h" + +#define QINPUTGENERATOR_DEBUG() if (1); else qDebug() << "QInputGenerator:" + +QMap<int,int> qt_key_to_symbian_keycode_make() +{ + QMap<int,int> m; + + m.insert( Qt::Key_Backspace, EKeyBackspace ); + m.insert( Qt::Key_Tab, EKeyTab ); + m.insert( Qt::Key_Enter, EKeyEnter ); + m.insert( Qt::Key_Escape, EKeyEscape ); + m.insert( Qt::Key_Space, EKeySpace ); + m.insert( Qt::Key_Delete, EKeyDelete ); + m.insert( Qt::Key_SysReq, EKeyPrintScreen ); + m.insert( Qt::Key_Pause, EKeyPause ); + m.insert( Qt::Key_Home, EKeyHome ); + m.insert( Qt::Key_End, EKeyEnd ); + m.insert( Qt::Key_PageUp, EKeyPageUp ); + m.insert( Qt::Key_PageDown, EKeyPageDown ); + m.insert( Qt::Key_Insert, EKeyInsert ); + m.insert( Qt::Key_Left, EKeyLeftArrow ); + m.insert( Qt::Key_Right, EKeyRightArrow ); + m.insert( Qt::Key_Up, EKeyUpArrow ); + m.insert( Qt::Key_Down, EKeyDownArrow ); + + m.insert( Qt::Key_Shift, EKeyLeftShift ); + m.insert( Qt::Key_Control, EKeyLeftCtrl ); + m.insert( Qt::Key_Alt, EKeyLeftAlt ); + m.insert( Qt::Key_AltGr, EKeyRightAlt ); + m.insert( Qt::Key_Super_L, EKeyLeftFunc ); + m.insert( Qt::Key_Super_R, EKeyRightFunc ); + m.insert( Qt::Key_CapsLock, EKeyCapsLock ); + m.insert( Qt::Key_NumLock, EKeyNumLock ); + m.insert( Qt::Key_ScrollLock, EKeyScrollLock ); + + m.insert( Qt::Key_F1, EKeyF1 ); + m.insert( Qt::Key_F2, EKeyF2 ); + m.insert( Qt::Key_F3, EKeyF3 ); + m.insert( Qt::Key_F4, EKeyF4 ); + m.insert( Qt::Key_F5, EKeyF5 ); + m.insert( Qt::Key_F6, EKeyF6 ); + m.insert( Qt::Key_F7, EKeyF7 ); + m.insert( Qt::Key_F8, EKeyF8 ); + m.insert( Qt::Key_F9, EKeyF9 ); + m.insert( Qt::Key_F10, EKeyF10 ); + m.insert( Qt::Key_F11, EKeyF11 ); + m.insert( Qt::Key_F12, EKeyF12 ); + m.insert( Qt::Key_F13, EKeyF13 ); + m.insert( Qt::Key_F14, EKeyF14 ); + m.insert( Qt::Key_F15, EKeyF15 ); + m.insert( Qt::Key_F16, EKeyF16 ); + m.insert( Qt::Key_F17, EKeyF17 ); + m.insert( Qt::Key_F18, EKeyF18 ); + m.insert( Qt::Key_F19, EKeyF19 ); + m.insert( Qt::Key_F20, EKeyF20 ); + m.insert( Qt::Key_F21, EKeyF21 ); + m.insert( Qt::Key_F22, EKeyF22 ); + m.insert( Qt::Key_F23, EKeyF23 ); + m.insert( Qt::Key_F24, EKeyF24 ); + + m.insert( Qt::Key_Menu, EKeyMenu ); + m.insert( Qt::Key_Help, EKeyHelp ); + m.insert( Qt::Key_Call, EKeyDial ); + + m.insert( Qt::Key_Context1, EKeyDevice0 ); + m.insert( Qt::Key_Context2, EKeyDevice1 ); + m.insert( Qt::Key_Select, EKeyDevice3 ); + + m.insert( Qt::Key_Launch0, EKeyApplication0 ); + m.insert( Qt::Key_Launch1, EKeyApplication1 ); + m.insert( Qt::Key_Launch2, EKeyApplication2 ); + m.insert( Qt::Key_Launch3, EKeyApplication3 ); + m.insert( Qt::Key_Launch4, EKeyApplication4 ); + m.insert( Qt::Key_Launch5, EKeyApplication5 ); + m.insert( Qt::Key_Launch6, EKeyApplication6 ); + m.insert( Qt::Key_Launch7, EKeyApplication7 ); + m.insert( Qt::Key_Launch8, EKeyApplication8 ); + m.insert( Qt::Key_Launch9, EKeyApplication9 ); + m.insert( Qt::Key_LaunchA, EKeyApplicationA ); + m.insert( Qt::Key_LaunchB, EKeyApplicationB ); + m.insert( Qt::Key_LaunchC, EKeyApplicationC ); + m.insert( Qt::Key_LaunchD, EKeyApplicationD ); + m.insert( Qt::Key_LaunchE, EKeyApplicationE ); + m.insert( Qt::Key_LaunchF, EKeyApplicationF ); + + m.insert( Qt::Key_Yes, EKeyYes ); + m.insert( Qt::Key_No, EKeyNo ); + + m.insert( Qt::Key_Call, EKeyYes ); + m.insert( Qt::Key_Hangup, EKeyNo ); + + return m; +} + +QMap<int,uint> qt_modifier_to_symbian_modifier_make() +{ + QMap<int,uint> m; + m.insert( Qt::ShiftModifier, EModifierShift ); + m.insert( Qt::ControlModifier, EModifierCtrl ); + m.insert( Qt::AltModifier, EModifierAlt ); + return m; +} + +QMap<int,uint> qt_button_to_symbian_button_down_make() +{ + QMap<int,uint> m; + + m.insert( Qt::LeftButton, TRawEvent::EButton1Down ); + m.insert( Qt::MidButton, TRawEvent::EButton2Down ); + m.insert( Qt::RightButton, TRawEvent::EButton3Down ); + return m; +} + +QMap<int,uint> qt_button_to_symbian_button_up_make() +{ + QMap<int,uint> m; + + m.insert( Qt::LeftButton, TRawEvent::EButton1Up ); + m.insert( Qt::MidButton, TRawEvent::EButton2Up ); + m.insert( Qt::RightButton, TRawEvent::EButton3Up ); + return m; +} + +class QInputGeneratorPrivate +{ +public: + QInputGeneratorPrivate(); + QInputGenerator* q; + + void keyEvent(Qt::Key, bool); + void mouseEvent(QPoint const&, Qt::MouseButtons); + + void ensureModifiers(Qt::KeyboardModifiers); + Qt::KeyboardModifiers currentModifiers() const; + + QMap<int,int> const keyMap; + QMap<int,uint> const buttonDownMap; + QMap<int,uint> const buttonUpMap; + QMap<int,uint> const buttonDragMap; + + QPoint currentPos; + Qt::MouseButtons currentButtons; +}; + +QInputGeneratorPrivate::QInputGeneratorPrivate() + : keyMap(qt_key_to_symbian_keycode_make()), + buttonDownMap(qt_button_to_symbian_button_down_make()), + buttonUpMap(qt_button_to_symbian_button_up_make()), + currentPos(), + currentButtons(0) +{ +} + +QInputGenerator::QInputGenerator(QObject* parent) + : QObject(parent), + d(new QInputGeneratorPrivate) +{ + d->q = this; + QINPUTGENERATOR_DEBUG() << "constructor"; +} + +QInputGenerator::~QInputGenerator() +{ + QINPUTGENERATOR_DEBUG() << "destructor"; + + /* + Restore all keyboard modifiers to off. + If we don't do this, the current modifiers stay activated + even when this application is closed. + Note that there is no guarantee this code actually gets run. + */ + d->ensureModifiers(0); + if (d->currentButtons) { + d->mouseEvent(d->currentPos, 0); + } + + d->q = 0; + delete d; + d = 0; +} + +/* + Returns the Qt keyboard modifiers which are currently pressed. +*/ +Qt::KeyboardModifiers QInputGeneratorPrivate::currentModifiers() const +{ + quint32 modifiers = 0;//GetCurrentKeyModifiers(); + + int state = 0; +/* + state |= (modifiers & shiftKey ? Qt::ShiftModifier : Qt::NoModifier); + state |= (modifiers & controlKey ? Qt::ControlModifier : Qt::NoModifier); + state |= (modifiers & optionKey ? Qt::AltModifier : Qt::NoModifier); + state |= (modifiers & cmdKey ? Qt::MetaModifier : Qt::NoModifier); +*/ + return Qt::KeyboardModifier(state); +} + +void QInputGeneratorPrivate::ensureModifiers(Qt::KeyboardModifiers desiredMod) +{ + Qt::KeyboardModifiers currentMod = currentModifiers(); + + // For each modifier.. + for (unsigned i = 0; i < sizeof(q->AllModifiers)/sizeof(Qt::KeyboardModifier); ++i) { + Qt::KeyboardModifier thisMod = q->AllModifiers[i]; + // If the modifier is currently disabled but we want it enabled, or vice-versa... + if ((desiredMod & thisMod) && !(currentMod & thisMod)) { + QINPUTGENERATOR_DEBUG() << "Enabling modifier" << (void*)thisMod << "by press"; + // press to enable + keyEvent(q->modifierToKey(thisMod), true); + } else if (!(desiredMod & thisMod) && (currentMod & thisMod)) { + QINPUTGENERATOR_DEBUG() << "Disabling modifier" << (void*)thisMod << "by release"; + // release to disable + keyEvent(q->modifierToKey(thisMod), false); + } + } + + if (currentMod != desiredMod) { + currentMod = desiredMod; + for (int i = 0; + i < 1000 && QApplication::keyboardModifiers() != desiredMod; + i += 50, QtUiTest::wait(50)) + {} + + if (QApplication::keyboardModifiers() != desiredMod) + qWarning() << "QtUitest: couldn't set all modifiers to desired state! " + "Current state:" << (void*)(int)QApplication::keyboardModifiers() << + "Desired:" << (void*)(int)desiredMod; + } +} + +void QInputGeneratorPrivate::keyEvent(Qt::Key key, bool is_press) +{ + int sym = 0; + + do { + if (key >= Qt::Key_Space && key <= Qt::Key_AsciiTilde) { + sym = QChar(key).toUpper().toAscii(); + break; + } + + QMap<int,int>::const_iterator found = keyMap.find(key); + if (found != keyMap.end()) { + sym = *found; + break; + } + + qWarning() << "QInputGenerator: don't know how to translate Qt key" + << (void*)key << "into Symbian keycode"; + return; + + } while(0); + + RWsSession wsSession=CCoeEnv::Static()->WsSession(); + TRawEvent keyEvent; + keyEvent.Set(is_press ? TRawEvent::EKeyDown : TRawEvent::EKeyUp, sym); + wsSession.SimulateRawEvent(keyEvent); + wsSession.Flush(); + + QINPUTGENERATOR_DEBUG() << (is_press ? "press" : "release") << sym; +} + +void QInputGenerator::keyPress(Qt::Key key, Qt::KeyboardModifiers mod, bool autoRepeat) +{ + Q_UNUSED(autoRepeat); + d->ensureModifiers(mod); + d->keyEvent(key, true); + QtUiTest::wait(1); +} + +void QInputGenerator::keyRelease(Qt::Key key, Qt::KeyboardModifiers mod) +{ + d->ensureModifiers(mod); + d->keyEvent(key, false); + QtUiTest::wait(1); +} + +void QInputGenerator::keyClick(Qt::Key key, Qt::KeyboardModifiers mod) +{ + // Using RWsSession::SimulateKeyEvent seems to work more reliably than using + // TRawEvent but it only simulates keyclicks (press and release) + + int sym = 0; + + do { + if (key >= Qt::Key_Space && key <= Qt::Key_AsciiTilde) { + sym = QChar(key).toUpper().toAscii(); + if (mod == Qt::NoModifier) { + sym = sym = QChar(key).toLower().toAscii(); + } + break; + } + + QMap<int,int>::const_iterator found = d->keyMap.find(key); + if (found != d->keyMap.end()) { + sym = *found; + break; + } + + qWarning() << "QInputGenerator: don't know how to translate Qt key" + << (void*)key << "into Symbian keycode"; + return; + + } while(0); + + RWsSession wsSession=CCoeEnv::Static()->WsSession(); + + TKeyEvent keyEvent; + keyEvent.iCode = sym; + keyEvent.iScanCode = 0; // don't think Qt requires this + keyEvent.iModifiers = 0; // should set this + keyEvent.iRepeats = 0; + wsSession.SimulateKeyEvent(keyEvent); + wsSession.Flush(); + QtUiTest::wait(10); +} + +void QInputGeneratorPrivate::mouseEvent(QPoint const& pos, Qt::MouseButtons state) +{ + typedef QPair<uint,uint> ButtonEvent; + QList<ButtonEvent> buttonEvents; + + RWsSession wsSession=CCoeEnv::Static()->WsSession(); + + // FIXME: This doesn't handle screen orientation yet + int x = pos.x(); + int y = pos.y(); + + foreach (int button, buttonDownMap.keys()) { + bool desired = button & state; + bool current = button & currentButtons; + + // Do we need to release? + if (!desired && current) { + TRawEvent event; + event.Set(TRawEvent::EButton1Up, x, y); + wsSession.SimulateRawEvent(event); + wsSession.Flush(); + } + + // Do we need to press? + if (desired && !current) { + TRawEvent event; + event.Set(TRawEvent::EButton1Down, x, y); + wsSession.SimulateRawEvent(event); + wsSession.Flush(); + } + } + + currentButtons = state; +} + +void QInputGenerator::mousePress(QPoint const& pos, Qt::MouseButtons state) +{ + QINPUTGENERATOR_DEBUG() << "Mouse press" << pos << (void*)(int)state; + d->mouseEvent(pos, d->currentButtons | state); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); +} + +void QInputGenerator::mouseRelease(QPoint const& pos, Qt::MouseButtons state) +{ + QINPUTGENERATOR_DEBUG() << "Mouse release" << pos << (void*)(int)(d->currentButtons & ~state); + d->mouseEvent(pos, d->currentButtons & ~state); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); +} + +void QInputGenerator::mouseClick(QPoint const& pos, Qt::MouseButtons state) +{ + mousePress (pos,state); + QtUiTest::wait(20); + mouseRelease(pos,state); +} |