diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-08-04 13:58:20 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-08-04 13:58:20 (GMT) |
commit | 82a18deee74bef3e545bf6426164dbe12548e5d9 (patch) | |
tree | 3ee31f4755292a0077e10d723804491f2ba794d3 | |
parent | 920ce5ed71bc456e429b887801a8d8bea7a3db0d (diff) | |
parent | 0857745f8cb6a26528cecd6e07f0d9267fc75ac6 (diff) | |
download | Qt-82a18deee74bef3e545bf6426164dbe12548e5d9.zip Qt-82a18deee74bef3e545bf6426164dbe12548e5d9.tar.gz Qt-82a18deee74bef3e545bf6426164dbe12548e5d9.tar.bz2 |
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-symbian-staging into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/qt-symbian-staging:
runonphone: fix failure to terminate
Fix license headers in new files from coda patch
runonphone: command line args improperly passed to TRK after CODA patch
Preventing QSoftkeyManager giving false positive memory leaks
Fixed memory leak in QMessageBox::setInformativeText in Symbian
Memory leak fix in Symbian open file dialog
Runonphone with CODA support
Memory leak fix for Symbian menus
Eabi DEF file sync between Qt 4.7 and 4.8
Winscw DEF file sync between Qt 4.7 and 4.8
44 files changed, 4943 insertions, 1953 deletions
diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp index 16ef5b6..cd020f6 100644 --- a/src/gui/dialogs/qfiledialog_symbian.cpp +++ b/src/gui/dialogs/qfiledialog_symbian.cpp @@ -59,7 +59,7 @@ extern QStringList qt_clean_filter_list(const QString &filter); // defined in qf enum DialogMode { DialogOpen, DialogSave, DialogFolder }; #if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) -class CExtensionFilter : public MAknFileFilter +class CExtensionFilter : public CBase, public MAknFileFilter { public: void setFilter(const QString filter) @@ -127,7 +127,7 @@ static QString launchSymbianDialog(const QString dialogCaption, const QString st extensionFilter->setFilter(filter); select = AknCommonDialogsDynMem::RunSelectDlgLD(types, target, startFolder, 0, 0, titlePtr, extensionFilter); - CleanupStack::Pop(extensionFilter); + CleanupStack::PopAndDestroy(extensionFilter); } else if (dialogMode == DialogSave) { QString defaultFileName = QFileDialogPrivate::initialSelection(startDirectory); target = qt_QString2TPtrC(defaultFileName); diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index a2f086b..66e7216 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -2486,7 +2486,7 @@ void QMessageBox::setInformativeText(const QString &text) } if (!d->informativeLabel) { - QLabel *label = new QLabel; + QLabel *label = new QLabel(this); label->setObjectName(QLatin1String("qt_msgbox_informativelabel")); label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this))); label->setAlignment(Qt::AlignTop | Qt::AlignLeft); diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index a866da3..500bcff 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -54,7 +54,7 @@ #ifndef QT_NO_SOFTKEYMANAGER QT_BEGIN_NAMESPACE -QSoftKeyManager *QSoftKeyManagerPrivate::self = 0; +QScopedPointer<QSoftKeyManager> QSoftKeyManagerPrivate::self(0); QString QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey) { @@ -85,9 +85,9 @@ QString QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey) QSoftKeyManager *QSoftKeyManager::instance() { if (!QSoftKeyManagerPrivate::self) - QSoftKeyManagerPrivate::self = new QSoftKeyManager; + QSoftKeyManagerPrivate::self.reset(new QSoftKeyManager); - return QSoftKeyManagerPrivate::self; + return QSoftKeyManagerPrivate::self.data(); } QSoftKeyManager::QSoftKeyManager() : diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h index 5b76e60..e9cbd7d 100644 --- a/src/gui/kernel/qsoftkeymanager_common_p.h +++ b/src/gui/kernel/qsoftkeymanager_common_p.h @@ -67,7 +67,7 @@ public: virtual void updateSoftKeys_sys() {}; protected: - static QSoftKeyManager *self; + static QScopedPointer<QSoftKeyManager> self; QHash<QAction*, Qt::Key> keyedActions; QMultiHash<int, QAction*> requestedSoftKeyActions; QWidget *initialSoftKeySource; diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index 56eca9a..c9dbff5 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -357,7 +357,7 @@ QMenuPrivate::QSymbianMenuPrivate::QSymbianMenuPrivate() QMenuPrivate::QSymbianMenuPrivate::~QSymbianMenuPrivate() { - + qDeleteAll(actionItems); } void QMenuPrivate::QSymbianMenuPrivate::addAction(QAction *a, QSymbianMenuAction *before) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 58c1c4a..ff29c0a 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4486,9 +4486,9 @@ EXPORTS ?objectNameChanged@QAbstractDeclarativeData@@2P6AXPAV1@PAVQObject@@@ZA @ 4485 NONAME ; void (*QAbstractDeclarativeData::objectNameChanged)(class QAbstractDeclarativeData *, class QObject *) ?queueDeferredActiveObjectsCompletion@QEventDispatcherSymbian@@QAEXXZ @ 4486 NONAME ABSENT ; void QEventDispatcherSymbian::queueDeferredActiveObjectsCompletion(void) ?reactivateDeferredActiveObjects@QEventDispatcherSymbian@@UAEXXZ @ 4487 NONAME ABSENT ; void QEventDispatcherSymbian::reactivateDeferredActiveObjects(void) - ?contains@QString@@QBE?AVQBool@@ABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4488 NONAME ; class QBool QString::contains(class QStringRef const &, enum Qt::CaseSensitivity) const - ?swap@QRegExp@@QAEXAAV1@@Z @ 4489 NONAME ; void QRegExp::swap(class QRegExp &) - ?indexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4490 NONAME ; int QStringRef::indexOf(class QString const &, int, enum Qt::CaseSensitivity) const + ?symbianCommandLine@QCoreApplicationPrivate@@SAPAVCApaCommandLine@@XZ @ 4488 NONAME ; class CApaCommandLine * QCoreApplicationPrivate::symbianCommandLine(void) + ?revision@QMetaProperty@@QBEHXZ @ 4489 NONAME ; int QMetaProperty::revision(void) const + ?revision@QMetaMethod@@QBEHXZ @ 4490 NONAME ; int QMetaMethod::revision(void) const ?indexOf@QStringRef@@QBEHABV1@HW4CaseSensitivity@Qt@@@Z @ 4491 NONAME ; int QStringRef::indexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const ?count@QString@@QBEHABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4492 NONAME ; int QString::count(class QStringRef const &, enum Qt::CaseSensitivity) const ?swap@QString@@QAEXAAV1@@Z @ 4493 NONAME ; void QString::swap(class QString &) @@ -4598,13 +4598,13 @@ EXPORTS ?open@QFile@@QAE_NABVRFile@@V?$QFlags@W4OpenModeFlag@QIODevice@@@@V?$QFlags@W4FileHandleFlag@QFile@@@@@Z @ 4597 NONAME ; bool QFile::open(class RFile const &, class QFlags<enum QIODevice::OpenModeFlag>, class QFlags<enum QFile::FileHandleFlag>) ?open@QFile@@QAE_NHV?$QFlags@W4OpenModeFlag@QIODevice@@@@V?$QFlags@W4FileHandleFlag@QFile@@@@@Z @ 4598 NONAME ; bool QFile::open(int, class QFlags<enum QIODevice::OpenModeFlag>, class QFlags<enum QFile::FileHandleFlag>) ?open@QFile@@QAE_NPAU__sFILE@@V?$QFlags@W4OpenModeFlag@QIODevice@@@@V?$QFlags@W4FileHandleFlag@QFile@@@@@Z @ 4599 NONAME ; bool QFile::open(struct __sFILE *, class QFlags<enum QIODevice::OpenModeFlag>, class QFlags<enum QFile::FileHandleFlag>) - ?symbianCommandLine@QCoreApplicationPrivate@@SAPAVCApaCommandLine@@XZ @ 4600 NONAME ; class CApaCommandLine * QCoreApplicationPrivate::symbianCommandLine(void) + ?contains@QString@@QBE?AVQBool@@ABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4600 NONAME ; class QBool QString::contains(class QStringRef const &, enum Qt::CaseSensitivity) const ?nsecsElapsed@QElapsedTimer@@QBE_JXZ @ 4601 NONAME ; long long QElapsedTimer::nsecsElapsed(void) const ??XQPoint@@QAEAAV0@N@Z @ 4602 NONAME ; class QPoint & QPoint::operator*=(double) ??XQPoint@@QAEAAV0@H@Z @ 4603 NONAME ; class QPoint & QPoint::operator*=(int) ?hasError@QXmlStreamWriter@@QBE_NXZ @ 4604 NONAME ; bool QXmlStreamWriter::hasError(void) const - ?revision@QMetaProperty@@QBEHXZ @ 4605 NONAME ; int QMetaProperty::revision(void) const - ?revision@QMetaMethod@@QBEHXZ @ 4606 NONAME ; int QMetaMethod::revision(void) const + ?swap@QRegExp@@QAEXAAV1@@Z @ 4605 NONAME ; void QRegExp::swap(class QRegExp &) + ?indexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4606 NONAME ; int QStringRef::indexOf(class QString const &, int, enum Qt::CaseSensitivity) const gzungetc @ 4607 NONAME ?addSocket@QSymbianSocketManager@@QAEHABVRSocket@@@Z @ 4608 NONAME ; int QSymbianSocketManager::addSocket(class RSocket const &) ??0QActiveObject@@QAE@HPAVQEventDispatcherSymbian@@@Z @ 4609 NONAME ; QActiveObject::QActiveObject(int, class QEventDispatcherSymbian *) @@ -4881,4 +4881,5 @@ EXPORTS ?resume@QFutureWatcherBase@@QAEXXZ @ 4880 NONAME ; void QFutureWatcherBase::resume(void) ?resultsReadyAt@QFutureWatcherBase@@IAEXHH@Z @ 4881 NONAME ; void QFutureWatcherBase::resultsReadyAt(int, int) ?started@QFutureWatcherBase@@IAEXXZ @ 4882 NONAME ; void QFutureWatcherBase::started(void) + ?resetInternalData@QAbstractItemModel@@IAEXXZ @ 4883 NONAME ; void QAbstractItemModel::resetInternalData(void) diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def index a976e3f..c39ff18 100644 --- a/src/s60installs/bwins/QtDeclarativeu.def +++ b/src/s60installs/bwins/QtDeclarativeu.def @@ -1954,4 +1954,5 @@ EXPORTS ?trUtf8@QDeclarativeInspectorService@@SA?AVQString@@PBD0H@Z @ 1953 NONAME ; class QString QDeclarativeInspectorService::trUtf8(char const *, char const *, int) ??1QDeclarativeInspectorInterface@@UAE@XZ @ 1954 NONAME ; QDeclarativeInspectorInterface::~QDeclarativeInspectorInterface(void) ?qt_metacall@QDeclarativeInspectorService@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1955 NONAME ; int QDeclarativeInspectorService::qt_metacall(enum QMetaObject::Call, int, void * *) + ?updateStatus@QDeclarativeInspectorService@@AAEXXZ @ 1956 NONAME ; void QDeclarativeInspectorService::updateStatus(void) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index d4b39e4..b763848 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12981,139 +12981,139 @@ EXPORTS ?depth@QVolatileImage@@QBEHXZ @ 12980 NONAME ; int QVolatileImage::depth(void) const ?releaseCachedResources@QGraphicsSystem@@UAEXXZ @ 12981 NONAME ABSENT ; void QGraphicsSystem::releaseCachedResources(void) ?qt_s60_setPartialScreenInputMode@@YAX_N@Z @ 12982 NONAME ; void qt_s60_setPartialScreenInputMode(bool) - png_access_version_number @ 12983 NONAME - png_benign_error @ 12984 NONAME - png_build_grayscale_palette @ 12985 NONAME - png_calloc @ 12986 NONAME - png_chunk_benign_error @ 12987 NONAME - png_chunk_error @ 12988 NONAME - png_chunk_warning @ 12989 NONAME - png_convert_from_struct_tm @ 12990 NONAME - png_convert_from_time_t @ 12991 NONAME - png_convert_to_rfc1123 @ 12992 NONAME - png_create_info_struct @ 12993 NONAME - png_create_read_struct @ 12994 NONAME - png_create_read_struct_2 @ 12995 NONAME - png_create_write_struct @ 12996 NONAME - png_create_write_struct_2 @ 12997 NONAME - png_data_freer @ 12998 NONAME - png_destroy_info_struct @ 12999 NONAME - png_destroy_read_struct @ 13000 NONAME - png_destroy_write_struct @ 13001 NONAME - png_error @ 13002 NONAME - png_free @ 13003 NONAME - png_free_data @ 13004 NONAME - png_free_default @ 13005 NONAME - png_get_IHDR @ 13006 NONAME - png_get_PLTE @ 13007 NONAME - png_get_bKGD @ 13008 NONAME - png_get_bit_depth @ 13009 NONAME - png_get_cHRM @ 13010 NONAME - png_get_cHRM_fixed @ 13011 NONAME - png_get_channels @ 13012 NONAME - png_get_chunk_cache_max @ 13013 NONAME - png_get_chunk_malloc_max @ 13014 NONAME - png_get_color_type @ 13015 NONAME - png_get_compression_buffer_size @ 13016 NONAME - png_get_compression_type @ 13017 NONAME - png_get_copyright @ 13018 NONAME - png_get_current_pass_number @ 13019 NONAME - png_get_current_row_number @ 13020 NONAME - png_get_error_ptr @ 13021 NONAME - png_get_filter_type @ 13022 NONAME - png_get_gAMA @ 13023 NONAME - png_get_gAMA_fixed @ 13024 NONAME - png_get_hIST @ 13025 NONAME - png_get_header_ver @ 13026 NONAME - png_get_header_version @ 13027 NONAME - png_get_iCCP @ 13028 NONAME - png_get_image_height @ 13029 NONAME - png_get_image_width @ 13030 NONAME - png_get_int_32 @ 13031 NONAME - png_get_interlace_type @ 13032 NONAME - png_get_io_chunk_name @ 13033 NONAME - png_get_io_chunk_type @ 13034 NONAME - png_get_io_ptr @ 13035 NONAME - png_get_io_state @ 13036 NONAME - png_get_libpng_ver @ 13037 NONAME - png_get_mem_ptr @ 13038 NONAME - png_get_oFFs @ 13039 NONAME - png_get_pCAL @ 13040 NONAME - png_get_pHYs @ 13041 NONAME - png_get_pHYs_dpi @ 13042 NONAME - png_get_pixel_aspect_ratio @ 13043 NONAME - png_get_pixel_aspect_ratio_fixed @ 13044 NONAME - png_get_pixels_per_inch @ 13045 NONAME - png_get_pixels_per_meter @ 13046 NONAME - png_get_progressive_ptr @ 13047 NONAME - png_get_rgb_to_gray_status @ 13048 NONAME - png_get_rowbytes @ 13049 NONAME - png_get_rows @ 13050 NONAME - png_get_sBIT @ 13051 NONAME - png_get_sCAL @ 13052 NONAME - png_get_sCAL_fixed @ 13053 NONAME - png_get_sCAL_s @ 13054 NONAME - png_get_sPLT @ 13055 NONAME - png_get_sRGB @ 13056 NONAME - png_get_signature @ 13057 NONAME - png_get_tIME @ 13058 NONAME - png_get_tRNS @ 13059 NONAME - png_get_text @ 13060 NONAME - png_get_uint_16 @ 13061 NONAME - png_get_uint_31 @ 13062 NONAME - png_get_uint_32 @ 13063 NONAME - png_get_unknown_chunks @ 13064 NONAME - png_get_user_chunk_ptr @ 13065 NONAME - png_get_user_height_max @ 13066 NONAME - png_get_user_transform_ptr @ 13067 NONAME - png_get_user_width_max @ 13068 NONAME - png_get_valid @ 13069 NONAME - png_get_x_offset_inches @ 13070 NONAME - png_get_x_offset_inches_fixed @ 13071 NONAME - png_get_x_offset_microns @ 13072 NONAME - png_get_x_offset_pixels @ 13073 NONAME - png_get_x_pixels_per_inch @ 13074 NONAME - png_get_x_pixels_per_meter @ 13075 NONAME - png_get_y_offset_inches @ 13076 NONAME - png_get_y_offset_inches_fixed @ 13077 NONAME - png_get_y_offset_microns @ 13078 NONAME - png_get_y_offset_pixels @ 13079 NONAME - png_get_y_pixels_per_inch @ 13080 NONAME - png_get_y_pixels_per_meter @ 13081 NONAME - png_handle_as_unknown @ 13082 NONAME - png_info_init_3 @ 13083 NONAME - png_init_io @ 13084 NONAME - png_longjmp @ 13085 NONAME - png_malloc @ 13086 NONAME - png_malloc_default @ 13087 NONAME - png_malloc_warn @ 13088 NONAME - png_permit_mng_features @ 13089 NONAME - png_process_data @ 13090 NONAME - png_process_data_pause @ 13091 NONAME - png_process_data_skip @ 13092 NONAME - png_progressive_combine_row @ 13093 NONAME - png_read_end @ 13094 NONAME - png_read_image @ 13095 NONAME - png_read_info @ 13096 NONAME - png_read_png @ 13097 NONAME - png_read_row @ 13098 NONAME - png_read_rows @ 13099 NONAME - png_read_update_info @ 13100 NONAME - png_reset_zstream @ 13101 NONAME - png_save_int_32 @ 13102 NONAME - png_save_uint_16 @ 13103 NONAME - png_save_uint_32 @ 13104 NONAME - png_set_IHDR @ 13105 NONAME - png_set_PLTE @ 13106 NONAME - png_set_add_alpha @ 13107 NONAME - png_set_bKGD @ 13108 NONAME - png_set_background @ 13109 NONAME - png_set_background_fixed @ 13110 NONAME - png_set_benign_errors @ 13111 NONAME - png_set_bgr @ 13112 NONAME - png_set_cHRM @ 13113 NONAME - png_set_cHRM_fixed @ 13114 NONAME - png_set_chunk_cache_max @ 13115 NONAME + ?paintingActive@QVolatileImage@@QBE_NXZ @ 12983 NONAME ; bool QVolatileImage::paintingActive(void) const + ??_EQFontPrivate@@QAE@I@Z @ 12984 NONAME ABSENT ; QFontPrivate::~QFontPrivate(unsigned int) + ??0QMimeSource@@QAE@XZ @ 12985 NONAME ABSENT ; QMimeSource::QMimeSource(void) + ??0QStyleFactoryInterface@@QAE@XZ @ 12986 NONAME ABSENT ; QStyleFactoryInterface::QStyleFactoryInterface(void) + ??0QFileOpenEvent@@QAE@ABV0@@Z @ 12987 NONAME ABSENT ; QFileOpenEvent::QFileOpenEvent(class QFileOpenEvent const &) + ??4QStyleOptionViewItemV2@@QAEAAV0@ABV0@@Z @ 12988 NONAME ABSENT ; class QStyleOptionViewItemV2 & QStyleOptionViewItemV2::operator=(class QStyleOptionViewItemV2 const &) + ??0QShowEvent@@QAE@ABV0@@Z @ 12989 NONAME ABSENT ; QShowEvent::QShowEvent(class QShowEvent const &) + ??0QMouseEvent@@QAE@ABV0@@Z @ 12990 NONAME ABSENT ; QMouseEvent::QMouseEvent(class QMouseEvent const &) + ??0QActionEvent@@QAE@ABV0@@Z @ 12991 NONAME ABSENT ; QActionEvent::QActionEvent(class QActionEvent const &) + ??0QTouchEvent@@QAE@ABV0@@Z @ 12992 NONAME ABSENT ; QTouchEvent::QTouchEvent(class QTouchEvent const &) + ??_EQImageData@@QAE@I@Z @ 12993 NONAME ABSENT ; QImageData::~QImageData(unsigned int) + ??4QBezier@@QAEAAV0@ABV0@@Z @ 12994 NONAME ABSENT ; class QBezier & QBezier::operator=(class QBezier const &) + ??0QIconEngineV2@@QAE@XZ @ 12995 NONAME ABSENT ; QIconEngineV2::QIconEngineV2(void) + ??4iterator@QTextBlock@@QAEAAV01@ABV01@@Z @ 12996 NONAME ABSENT ; class QTextBlock::iterator & QTextBlock::iterator::operator=(class QTextBlock::iterator const &) + ??0QIconEngineV2@@QAE@ABV0@@Z @ 12997 NONAME ABSENT ; QIconEngineV2::QIconEngineV2(class QIconEngineV2 const &) + ??0QIconEngineFactoryInterfaceV2@@QAE@XZ @ 12998 NONAME ABSENT ; QIconEngineFactoryInterfaceV2::QIconEngineFactoryInterfaceV2(void) + ??4QTextLine@@QAEAAV0@ABV0@@Z @ 12999 NONAME ABSENT ; class QTextLine & QTextLine::operator=(class QTextLine const &) + ??0QToolBarChangeEvent@@QAE@ABV0@@Z @ 13000 NONAME ABSENT ; QToolBarChangeEvent::QToolBarChangeEvent(class QToolBarChangeEvent const &) + ??0QResizeEvent@@QAE@ABV0@@Z @ 13001 NONAME ABSENT ; QResizeEvent::QResizeEvent(class QResizeEvent const &) + ??0QIconEngineFactoryInterface@@QAE@XZ @ 13002 NONAME ABSENT ; QIconEngineFactoryInterface::QIconEngineFactoryInterface(void) + ??0QPictureFormatInterface@@QAE@XZ @ 13003 NONAME ABSENT ; QPictureFormatInterface::QPictureFormatInterface(void) + ??_EQPolygon@@QAE@I@Z @ 13004 NONAME ABSENT ; QPolygon::~QPolygon(unsigned int) + ??_EQImageReader@@QAE@I@Z @ 13005 NONAME ABSENT ; QImageReader::~QImageReader(unsigned int) + ??4QStyleOptionGraphicsItem@@QAEAAV0@ABV0@@Z @ 13006 NONAME ABSENT ; class QStyleOptionGraphicsItem & QStyleOptionGraphicsItem::operator=(class QStyleOptionGraphicsItem const &) + ??4QStyleOptionProgressBarV2@@QAEAAV0@ABV0@@Z @ 13007 NONAME ABSENT ; class QStyleOptionProgressBarV2 & QStyleOptionProgressBarV2::operator=(class QStyleOptionProgressBarV2 const &) + ??0QDragEnterEvent@@QAE@ABV0@@Z @ 13008 NONAME ABSENT ; QDragEnterEvent::QDragEnterEvent(class QDragEnterEvent const &) + ??_EKey@QPixmapCache@@QAE@I@Z @ 13009 NONAME ABSENT ; QPixmapCache::Key::~Key(unsigned int) + ??_EQCursor@@QAE@I@Z @ 13010 NONAME ABSENT ; QCursor::~QCursor(unsigned int) + ??0QShortcutEvent@@QAE@ABV0@@Z @ 13011 NONAME ABSENT ; QShortcutEvent::QShortcutEvent(class QShortcutEvent const &) + ??_EQTextCursor@@QAE@I@Z @ 13012 NONAME ABSENT ; QTextCursor::~QTextCursor(unsigned int) + ??0QGradient@@QAE@ABV0@@Z @ 13013 NONAME ABSENT ; QGradient::QGradient(class QGradient const &) + ??4QInputMethodEvent@@QAEAAV0@ABV0@@Z @ 13014 NONAME ABSENT ; class QInputMethodEvent & QInputMethodEvent::operator=(class QInputMethodEvent const &) + ??0QVector2D@@QAE@ABV0@@Z @ 13015 NONAME ABSENT ; QVector2D::QVector2D(class QVector2D const &) + ??4QStyleOptionFocusRect@@QAEAAV0@ABV0@@Z @ 13016 NONAME ABSENT ; class QStyleOptionFocusRect & QStyleOptionFocusRect::operator=(class QStyleOptionFocusRect const &) + ??_EQPen@@QAE@I@Z @ 13017 NONAME ABSENT ; QPen::~QPen(unsigned int) + ??_EQKeySequence@@QAE@I@Z @ 13018 NONAME ABSENT ; QKeySequence::~QKeySequence(unsigned int) + ??4QGradient@@QAEAAV0@ABV0@@Z @ 13019 NONAME ABSENT ; class QGradient & QGradient::operator=(class QGradient const &) + ??0QTextTableFormat@@QAE@ABV0@@Z @ 13020 NONAME ABSENT ; QTextTableFormat::QTextTableFormat(class QTextTableFormat const &) + ??_EQImagePixmapCleanupHooks@@QAE@I@Z @ 13021 NONAME ABSENT ; QImagePixmapCleanupHooks::~QImagePixmapCleanupHooks(unsigned int) + ??0QStatusTipEvent@@QAE@ABV0@@Z @ 13022 NONAME ABSENT ; QStatusTipEvent::QStatusTipEvent(class QStatusTipEvent const &) + ??0Value@QCss@@QAE@ABU01@@Z @ 13023 NONAME ABSENT ; QCss::Value::Value(struct QCss::Value const &) + ??4QSizePolicy@@QAEAAV0@ABV0@@Z @ 13024 NONAME ABSENT ; class QSizePolicy & QSizePolicy::operator=(class QSizePolicy const &) + ??_ETouchPoint@QTouchEvent@@QAE@I@Z @ 13025 NONAME ABSENT ; QTouchEvent::TouchPoint::~TouchPoint(unsigned int) + ??4QItemSelection@@QAEAAV0@ABV0@@Z @ 13026 NONAME ABSENT ; class QItemSelection & QItemSelection::operator=(class QItemSelection const &) + ??4QStyleOptionQ3ListView@@QAEAAV0@ABV0@@Z @ 13027 NONAME ABSENT ; class QStyleOptionQ3ListView & QStyleOptionQ3ListView::operator=(class QStyleOptionQ3ListView const &) + ??0QSizePolicy@@QAE@ABV0@@Z @ 13028 NONAME ABSENT ; QSizePolicy::QSizePolicy(class QSizePolicy const &) + ??4QStyleOptionFrameV2@@QAEAAV0@ABV0@@Z @ 13029 NONAME ABSENT ; class QStyleOptionFrameV2 & QStyleOptionFrameV2::operator=(class QStyleOptionFrameV2 const &) + ??4QVector3D@@QAEAAV0@ABV0@@Z @ 13030 NONAME ABSENT ; class QVector3D & QVector3D::operator=(class QVector3D const &) + ??4QStyleOptionQ3DockWindow@@QAEAAV0@ABV0@@Z @ 13031 NONAME ABSENT ; class QStyleOptionQ3DockWindow & QStyleOptionQ3DockWindow::operator=(class QStyleOptionQ3DockWindow const &) + ??_EQFont@@QAE@I@Z @ 13032 NONAME ABSENT ; QFont::~QFont(unsigned int) + ??4QStyleOptionDockWidget@@QAEAAV0@ABV0@@Z @ 13033 NONAME ABSENT ; class QStyleOptionDockWidget & QStyleOptionDockWidget::operator=(class QStyleOptionDockWidget const &) + ??0QPainterState@@QAE@ABV0@@Z @ 13034 NONAME ABSENT ; QPainterState::QPainterState(class QPainterState const &) + ??4QStyleOptionFrame@@QAEAAV0@ABV0@@Z @ 13035 NONAME ABSENT ; class QStyleOptionFrame & QStyleOptionFrame::operator=(class QStyleOptionFrame const &) + ?qt_draw_decoration_for_glyphs@@YAXPAVQPainter@@PBIPBUQFixedPoint@@HPAVQFontEngine@@ABVQFont@@ABVQTextCharFormat@@@Z @ 13036 NONAME ; void qt_draw_decoration_for_glyphs(class QPainter *, unsigned int const *, struct QFixedPoint const *, int, class QFontEngine *, class QFont const &, class QTextCharFormat const &) + ??4QTextLength@@QAEAAV0@ABV0@@Z @ 13037 NONAME ABSENT ; class QTextLength & QTextLength::operator=(class QTextLength const &) + ??0QHelpEvent@@QAE@ABV0@@Z @ 13038 NONAME ABSENT ; QHelpEvent::QHelpEvent(class QHelpEvent const &) + ??0QContextMenuEvent@@QAE@ABV0@@Z @ 13039 NONAME ABSENT ; QContextMenuEvent::QContextMenuEvent(class QContextMenuEvent const &) + ??0QWhatsThisClickedEvent@@QAE@ABV0@@Z @ 13040 NONAME ABSENT ; QWhatsThisClickedEvent::QWhatsThisClickedEvent(class QWhatsThisClickedEvent const &) + ??4QStyleOptionTab@@QAEAAV0@ABV0@@Z @ 13041 NONAME ABSENT ; class QStyleOptionTab & QStyleOptionTab::operator=(class QStyleOptionTab const &) + ??0QTabletEvent@@QAE@ABV0@@Z @ 13042 NONAME ABSENT ; QTabletEvent::QTabletEvent(class QTabletEvent const &) + ??4QItemSelectionRange@@QAEAAV0@ABV0@@Z @ 13043 NONAME ABSENT ; class QItemSelectionRange & QItemSelectionRange::operator=(class QItemSelectionRange const &) + ??_EQStyleOptionViewItemV4@@QAE@I@Z @ 13044 NONAME ABSENT ; QStyleOptionViewItemV4::~QStyleOptionViewItemV4(unsigned int) + ??0QSymbianGraphicsSystemEx@@QAE@XZ @ 13045 NONAME ABSENT ; QSymbianGraphicsSystemEx::QSymbianGraphicsSystemEx(void) + ??4QEglProperties@@QAEAAV0@ABV0@@Z @ 13046 NONAME ABSENT ; class QEglProperties & QEglProperties::operator=(class QEglProperties const &) + ??0QHoverEvent@@QAE@ABV0@@Z @ 13047 NONAME ABSENT ; QHoverEvent::QHoverEvent(class QHoverEvent const &) + ??0QPaintEngineState@@QAE@XZ @ 13048 NONAME ABSENT ; QPaintEngineState::QPaintEngineState(void) + ??0QKeyEvent@@QAE@ABV0@@Z @ 13049 NONAME ABSENT ; QKeyEvent::QKeyEvent(class QKeyEvent const &) + ??0QIconEngine@@QAE@ABV0@@Z @ 13050 NONAME ABSENT ; QIconEngine::QIconEngine(class QIconEngine const &) + ??4QStyleOptionToolBoxV2@@QAEAAV0@ABV0@@Z @ 13051 NONAME ABSENT ; class QStyleOptionToolBoxV2 & QStyleOptionToolBoxV2::operator=(class QStyleOptionToolBoxV2 const &) + ??0QImageIOHandlerFactoryInterface@@QAE@XZ @ 13052 NONAME ABSENT ; QImageIOHandlerFactoryInterface::QImageIOHandlerFactoryInterface(void) + ??_EQRegion@@QAE@I@Z @ 13053 NONAME ABSENT ; QRegion::~QRegion(unsigned int) + ??4QStyleOptionComplex@@QAEAAV0@ABV0@@Z @ 13054 NONAME ABSENT ; class QStyleOptionComplex & QStyleOptionComplex::operator=(class QStyleOptionComplex const &) + ??_EFileInfo@QZipReader@@QAE@I@Z @ 13055 NONAME ABSENT ; QZipReader::FileInfo::~FileInfo(unsigned int) + ??0QBitmap@@QAE@ABV0@@Z @ 13056 NONAME ABSENT ; QBitmap::QBitmap(class QBitmap const &) + ?forceToRaster@QSymbianGraphicsSystemEx@@UAEXPAVQWidget@@@Z @ 13057 NONAME ; void QSymbianGraphicsSystemEx::forceToRaster(class QWidget *) + ?leadingSpaceWidth@QTextEngine@@QAE?AUQFixed@@ABUQScriptLine@@@Z @ 13058 NONAME ; struct QFixed QTextEngine::leadingSpaceWidth(struct QScriptLine const &) + ?releaseCachedGpuResources@QSymbianGraphicsSystemEx@@UAEXXZ @ 13059 NONAME ; void QSymbianGraphicsSystemEx::releaseCachedGpuResources(void) + ??_EQTextFormat@@QAE@I@Z @ 13060 NONAME ABSENT ; QTextFormat::~QTextFormat(unsigned int) + ??4QStyleOptionTabWidgetFrame@@QAEAAV0@ABV0@@Z @ 13061 NONAME ABSENT ; class QStyleOptionTabWidgetFrame & QStyleOptionTabWidgetFrame::operator=(class QStyleOptionTabWidgetFrame const &) + ??4QMouseEvent@@QAEAAV0@ABV0@@Z @ 13062 NONAME ABSENT ; class QMouseEvent & QMouseEvent::operator=(class QMouseEvent const &) + ??_EQPainter@@QAE@I@Z @ 13063 NONAME ABSENT ; QPainter::~QPainter(unsigned int) + ??4QStyleOptionTabBarBaseV2@@QAEAAV0@ABV0@@Z @ 13064 NONAME ABSENT ; class QStyleOptionTabBarBaseV2 & QStyleOptionTabBarBaseV2::operator=(class QStyleOptionTabBarBaseV2 const &) + ??4QInputEvent@@QAEAAV0@ABV0@@Z @ 13065 NONAME ABSENT ; class QInputEvent & QInputEvent::operator=(class QInputEvent const &) + ??_EQPainterPath@@QAE@I@Z @ 13066 NONAME ABSENT ; QPainterPath::~QPainterPath(unsigned int) + ??4QQuaternion@@QAEAAV0@ABV0@@Z @ 13067 NONAME ABSENT ; class QQuaternion & QQuaternion::operator=(class QQuaternion const &) + ??4Symbol@QCss@@QAEAAU01@ABU01@@Z @ 13068 NONAME ABSENT ; struct QCss::Symbol & QCss::Symbol::operator=(struct QCss::Symbol const &) + ??0QIconDragEvent@@QAE@ABV0@@Z @ 13069 NONAME ABSENT ; QIconDragEvent::QIconDragEvent(class QIconDragEvent const &) + ??0QTextImageFormat@@QAE@ABV0@@Z @ 13070 NONAME ABSENT ; QTextImageFormat::QTextImageFormat(class QTextImageFormat const &) + ??0QMoveEvent@@QAE@ABV0@@Z @ 13071 NONAME ABSENT ; QMoveEvent::QMoveEvent(class QMoveEvent const &) + ??0QInputContextFactoryInterface@@QAE@XZ @ 13072 NONAME ABSENT ; QInputContextFactoryInterface::QInputContextFactoryInterface(void) + ??0QTextFrameFormat@@QAE@ABV0@@Z @ 13073 NONAME ABSENT ; QTextFrameFormat::QTextFrameFormat(class QTextFrameFormat const &) + ??0Symbol@QCss@@QAE@ABU01@@Z @ 13074 NONAME ABSENT ; QCss::Symbol::Symbol(struct QCss::Symbol const &) + ??4QStyleOptionFrameV3@@QAEAAV0@ABV0@@Z @ 13075 NONAME ABSENT ; class QStyleOptionFrameV3 & QStyleOptionFrameV3::operator=(class QStyleOptionFrameV3 const &) + ??0QGraphicsSystem@@QAE@XZ @ 13076 NONAME ABSENT ; QGraphicsSystem::QGraphicsSystem(void) + ??4QStyleOptionViewItem@@QAEAAV0@ABV0@@Z @ 13077 NONAME ABSENT ; class QStyleOptionViewItem & QStyleOptionViewItem::operator=(class QStyleOptionViewItem const &) + ??4QStyleOptionProgressBar@@QAEAAV0@ABV0@@Z @ 13078 NONAME ABSENT ; class QStyleOptionProgressBar & QStyleOptionProgressBar::operator=(class QStyleOptionProgressBar const &) + ??4QStyleOptionRubberBand@@QAEAAV0@ABV0@@Z @ 13079 NONAME ABSENT ; class QStyleOptionRubberBand & QStyleOptionRubberBand::operator=(class QStyleOptionRubberBand const &) + ??0QDragResponseEvent@@QAE@ABV0@@Z @ 13080 NONAME ABSENT ; QDragResponseEvent::QDragResponseEvent(class QDragResponseEvent const &) + ??0QIconEngine@@QAE@XZ @ 13081 NONAME ABSENT ; QIconEngine::QIconEngine(void) + ??_EQBrush@@QAE@I@Z @ 13082 NONAME ABSENT ; QBrush::~QBrush(unsigned int) + ??_EQTableWidgetSelectionRange@@QAE@I@Z @ 13083 NONAME ABSENT ; QTableWidgetSelectionRange::~QTableWidgetSelectionRange(unsigned int) + ??4QStyleOptionTabBarBase@@QAEAAV0@ABV0@@Z @ 13084 NONAME ABSENT ; class QStyleOptionTabBarBase & QStyleOptionTabBarBase::operator=(class QStyleOptionTabBarBase const &) + ??0QTextObjectInterface@@QAE@XZ @ 13085 NONAME ABSENT ; QTextObjectInterface::QTextObjectInterface(void) + ??0QHideEvent@@QAE@ABV0@@Z @ 13086 NONAME ABSENT ; QHideEvent::QHideEvent(class QHideEvent const &) + ??0QCloseEvent@@QAE@ABV0@@Z @ 13087 NONAME ABSENT ; QCloseEvent::QCloseEvent(class QCloseEvent const &) + ??0QTextFrameLayoutData@@QAE@XZ @ 13088 NONAME ABSENT ; QTextFrameLayoutData::QTextFrameLayoutData(void) + ??4QStyleOptionTabWidgetFrameV2@@QAEAAV0@ABV0@@Z @ 13089 NONAME ABSENT ; class QStyleOptionTabWidgetFrameV2 & QStyleOptionTabWidgetFrameV2::operator=(class QStyleOptionTabWidgetFrameV2 const &) + ??4QStyleOptionTabV2@@QAEAAV0@ABV0@@Z @ 13090 NONAME ABSENT ; class QStyleOptionTabV2 & QStyleOptionTabV2::operator=(class QStyleOptionTabV2 const &) + ?platformExtension@QGraphicsSystem@@UAEPAVQGraphicsSystemEx@@XZ @ 13091 NONAME ; class QGraphicsSystemEx * QGraphicsSystem::platformExtension(void) + ??4QTextListFormat@@QAEAAV0@ABV0@@Z @ 13092 NONAME ABSENT ; class QTextListFormat & QTextListFormat::operator=(class QTextListFormat const &) + ??_EQPalette@@QAE@I@Z @ 13093 NONAME ABSENT ; QPalette::~QPalette(unsigned int) + ?releaseAllGpuResources@QSymbianGraphicsSystemEx@@UAEXXZ @ 13094 NONAME ; void QSymbianGraphicsSystemEx::releaseAllGpuResources(void) + ??0QFocusEvent@@QAE@ABV0@@Z @ 13095 NONAME ABSENT ; QFocusEvent::QFocusEvent(class QFocusEvent const &) + ??4QStyleOptionQ3ListViewItem@@QAEAAV0@ABV0@@Z @ 13096 NONAME ABSENT ; class QStyleOptionQ3ListViewItem & QStyleOptionQ3ListViewItem::operator=(class QStyleOptionQ3ListViewItem const &) + ??_EQIcon@@QAE@I@Z @ 13097 NONAME ABSENT ; QIcon::~QIcon(unsigned int) + ??0QTextListFormat@@QAE@ABV0@@Z @ 13098 NONAME ABSENT ; QTextListFormat::QTextListFormat(class QTextListFormat const &) + ??0QGuiPlatformPluginInterface@@QAE@XZ @ 13099 NONAME ABSENT ; QGuiPlatformPluginInterface::QGuiPlatformPluginInterface(void) + ??_EQTextLayout@@QAE@I@Z @ 13100 NONAME ABSENT ; QTextLayout::~QTextLayout(unsigned int) + ??0QWheelEvent@@QAE@ABV0@@Z @ 13101 NONAME ABSENT ; QWheelEvent::QWheelEvent(class QWheelEvent const &) + ??0QWindowStateChangeEvent@@QAE@ABV0@@Z @ 13102 NONAME ABSENT ; QWindowStateChangeEvent::QWindowStateChangeEvent(class QWindowStateChangeEvent const &) + ??_EQTextEngine@@QAE@I@Z @ 13103 NONAME ABSENT ; QTextEngine::~QTextEngine(unsigned int) + ??4QStyleOptionTitleBar@@QAEAAV0@ABV0@@Z @ 13104 NONAME ABSENT ; class QStyleOptionTitleBar & QStyleOptionTitleBar::operator=(class QStyleOptionTitleBar const &) + ??4Value@QCss@@QAEAAU01@ABU01@@Z @ 13105 NONAME ABSENT ; struct QCss::Value & QCss::Value::operator=(struct QCss::Value const &) + ??0QDragLeaveEvent@@QAE@ABV0@@Z @ 13106 NONAME ABSENT ; QDragLeaveEvent::QDragLeaveEvent(class QDragLeaveEvent const &) + ??4QBitmap@@QAEAAV0@ABV0@@Z @ 13107 NONAME ABSENT ; class QBitmap & QBitmap::operator=(class QBitmap const &) + ??0QItemSelection@@QAE@ABV0@@Z @ 13108 NONAME ABSENT ; QItemSelection::QItemSelection(class QItemSelection const &) + ??4QTextFrameFormat@@QAEAAV0@ABV0@@Z @ 13109 NONAME ABSENT ; class QTextFrameFormat & QTextFrameFormat::operator=(class QTextFrameFormat const &) + ?setInstantInvalidatePropagation@QGraphicsLayout@@SAX_N@Z @ 13110 NONAME ; void QGraphicsLayout::setInstantInvalidatePropagation(bool) + ?instantInvalidatePropagation@QGraphicsLayout@@SA_NXZ @ 13111 NONAME ; bool QGraphicsLayout::instantInvalidatePropagation(void) + ?hasBCM2727@QSymbianGraphicsSystemEx@@SA_NXZ @ 13112 NONAME ; bool QSymbianGraphicsSystemEx::hasBCM2727(void) + ?constImageRef@QVolatileImage@@QBEABVQImage@@XZ @ 13113 NONAME ; class QImage const & QVolatileImage::constImageRef(void) const + ?toVolatileImage@QPixmapData@@UBE?AVQVolatileImage@@XZ @ 13114 NONAME ; class QVolatileImage QPixmapData::toVolatileImage(void) const + ?qt_s60_setPartialScreenAutomaticTranslation@@YAX_N@Z @ 13115 NONAME ; void qt_s60_setPartialScreenAutomaticTranslation(bool) png_set_chunk_malloc_max @ 13116 NONAME png_set_compression_buffer_size @ 13117 NONAME png_set_compression_level @ 13118 NONAME @@ -13202,12 +13202,12 @@ EXPORTS ?clipEnabledChanged@QBlitterPaintEngine@@UAEXXZ @ 13201 NONAME ; void QBlitterPaintEngine::clipEnabledChanged(void) ?supportsSubPixelPositions@QFontEngine@@UBE_NXZ @ 13202 NONAME ; bool QFontEngine::supportsSubPixelPositions(void) const ??_EQScrollerProperties@@UAE@I@Z @ 13203 NONAME ABSENT ; QScrollerProperties::~QScrollerProperties(unsigned int) - ??_EQFontPrivate@@QAE@I@Z @ 13204 NONAME ABSENT ; QFontPrivate::~QFontPrivate(unsigned int) - ??0QMimeSource@@QAE@XZ @ 13205 NONAME ABSENT ; QMimeSource::QMimeSource(void) - ??0QStyleFactoryInterface@@QAE@XZ @ 13206 NONAME ABSENT ; QStyleFactoryInterface::QStyleFactoryInterface(void) + png_benign_error @ 13204 NONAME + png_build_grayscale_palette @ 13205 NONAME + png_calloc @ 13206 NONAME ?d_func@QScrollEvent@@AAEPAVQScrollEventPrivate@@XZ @ 13207 NONAME ABSENT ; class QScrollEventPrivate * QScrollEvent::d_func(void) - ??0QFileOpenEvent@@QAE@ABV0@@Z @ 13208 NONAME ABSENT ; QFileOpenEvent::QFileOpenEvent(class QFileOpenEvent const &) - ??4QStyleOptionViewItemV2@@QAEAAV0@ABV0@@Z @ 13209 NONAME ABSENT ; class QStyleOptionViewItemV2 & QStyleOptionViewItemV2::operator=(class QStyleOptionViewItemV2 const &) + png_chunk_benign_error @ 13208 NONAME + png_chunk_error @ 13209 NONAME ?heightForWidth@QTabWidget@@UBEHH@Z @ 13210 NONAME ; int QTabWidget::heightForWidth(int) const ??1QFlickGesture@@UAE@XZ @ 13211 NONAME ABSENT ; QFlickGesture::~QFlickGesture(void) ??0QRasterWindowSurface@@QAE@PAVQWidget@@_N@Z @ 13212 NONAME ; QRasterWindowSurface::QRasterWindowSurface(class QWidget *, bool) @@ -13215,14 +13215,14 @@ EXPORTS ?clip@QBlitterPaintEngine@@UAEXABVQRect@@W4ClipOperation@Qt@@@Z @ 13214 NONAME ; void QBlitterPaintEngine::clip(class QRect const &, enum Qt::ClipOperation) ?detach@QGlyphs@@AAEXXZ @ 13215 NONAME ABSENT ; void QGlyphs::detach(void) ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0@Z @ 13216 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *) - ??0QShowEvent@@QAE@ABV0@@Z @ 13217 NONAME ABSENT ; QShowEvent::QShowEvent(class QShowEvent const &) - ??0QMouseEvent@@QAE@ABV0@@Z @ 13218 NONAME ABSENT ; QMouseEvent::QMouseEvent(class QMouseEvent const &) + png_chunk_warning @ 13217 NONAME + png_convert_from_struct_tm @ 13218 NONAME ?setHintingPreference@QFont@@QAEXW4HintingPreference@1@@Z @ 13219 NONAME ; void QFont::setHintingPreference(enum QFont::HintingPreference) - ??0QActionEvent@@QAE@ABV0@@Z @ 13220 NONAME ABSENT ; QActionEvent::QActionEvent(class QActionEvent const &) - ??0QTouchEvent@@QAE@ABV0@@Z @ 13221 NONAME ABSENT ; QTouchEvent::QTouchEvent(class QTouchEvent const &) + png_convert_from_time_t @ 13220 NONAME + png_convert_to_rfc1123 @ 13221 NONAME ?capabilities@QBlittable@@QBE?AV?$QFlags@W4Capability@QBlittable@@@@XZ @ 13222 NONAME ; class QFlags<enum QBlittable::Capability> QBlittable::capabilities(void) const ?setContentPosRange@QScrollPrepareEvent@@QAEXABVQRectF@@@Z @ 13223 NONAME ABSENT ; void QScrollPrepareEvent::setContentPosRange(class QRectF const &) - ??_EQImageData@@QAE@I@Z @ 13224 NONAME ABSENT ; QImageData::~QImageData(unsigned int) + png_create_info_struct @ 13224 NONAME ?swap@QBrush@@QAEXAAV1@@Z @ 13225 NONAME ; void QBrush::swap(class QBrush &) ?trUtf8@QFlickGesture@@SA?AVQString@@PBD0H@Z @ 13226 NONAME ABSENT ; class QString QFlickGesture::trUtf8(char const *, char const *, int) ?fontHintingPreference@QTextCharFormat@@QBE?AW4HintingPreference@QFont@@XZ @ 13227 NONAME ; enum QFont::HintingPreference QTextCharFormat::fontHintingPreference(void) const @@ -13233,30 +13233,30 @@ EXPORTS ?scroller@QScroller@@SAPBV1@PBVQObject@@@Z @ 13232 NONAME ABSENT ; class QScroller const * QScroller::scroller(class QObject const *) ?qt_metacall@QScroller@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 13233 NONAME ABSENT ; int QScroller::qt_metacall(enum QMetaObject::Call, int, void * *) ?tr@QFlickGesture@@SA?AVQString@@PBD0@Z @ 13234 NONAME ABSENT ; class QString QFlickGesture::tr(char const *, char const *) - ??4QBezier@@QAEAAV0@ABV0@@Z @ 13235 NONAME ABSENT ; class QBezier & QBezier::operator=(class QBezier const &) + png_create_read_struct @ 13235 NONAME ?setScrollerProperties@QScroller@@QAEXABVQScrollerProperties@@@Z @ 13236 NONAME ABSENT ; void QScroller::setScrollerProperties(class QScrollerProperties const &) - ??0QIconEngineV2@@QAE@XZ @ 13237 NONAME ABSENT ; QIconEngineV2::QIconEngineV2(void) - ??4iterator@QTextBlock@@QAEAAV01@ABV01@@Z @ 13238 NONAME ABSENT ; class QTextBlock::iterator & QTextBlock::iterator::operator=(class QTextBlock::iterator const &) + png_create_read_struct_2 @ 13237 NONAME + png_create_write_struct @ 13238 NONAME ??MQItemSelectionRange@@QBE_NABV0@@Z @ 13239 NONAME ; bool QItemSelectionRange::operator<(class QItemSelectionRange const &) const ?setWidthForHeight@QSizePolicy@@QAEX_N@Z @ 13240 NONAME ; void QSizePolicy::setWidthForHeight(bool) ?qt_fontdata_from_index@@YA?AVQByteArray@@H@Z @ 13241 NONAME ; class QByteArray qt_fontdata_from_index(int) - ??0QIconEngineV2@@QAE@ABV0@@Z @ 13242 NONAME ABSENT ; QIconEngineV2::QIconEngineV2(class QIconEngineV2 const &) + png_create_write_struct_2 @ 13242 NONAME ?swap@QImage@@QAEXAAV1@@Z @ 13243 NONAME ; void QImage::swap(class QImage &) - ??0QIconEngineFactoryInterfaceV2@@QAE@XZ @ 13244 NONAME ABSENT ; QIconEngineFactoryInterfaceV2::QIconEngineFactoryInterfaceV2(void) + png_data_freer @ 13244 NONAME ??0QScroller@@AAE@PAVQObject@@@Z @ 13245 NONAME ABSENT ; QScroller::QScroller(class QObject *) ?compositionModeChanged@QBlitterPaintEngine@@UAEXXZ @ 13246 NONAME ; void QBlitterPaintEngine::compositionModeChanged(void) ?contentPosRange@QScrollPrepareEvent@@QBE?AVQRectF@@XZ @ 13247 NONAME ABSENT ; class QRectF QScrollPrepareEvent::contentPosRange(void) const ?grabGesture@QScroller@@SA?AW4GestureType@Qt@@PAVQObject@@W4ScrollerGestureType@1@@Z @ 13248 NONAME ABSENT ; enum Qt::GestureType QScroller::grabGesture(class QObject *, enum QScroller::ScrollerGestureType) ??_EQFlickGesture@@UAE@I@Z @ 13249 NONAME ABSENT ; QFlickGesture::~QFlickGesture(unsigned int) ?drawRects@QBlitterPaintEngine@@UAEXPBVQRectF@@H@Z @ 13250 NONAME ; void QBlitterPaintEngine::drawRects(class QRectF const *, int) - ??4QTextLine@@QAEAAV0@ABV0@@Z @ 13251 NONAME ABSENT ; class QTextLine & QTextLine::operator=(class QTextLine const &) - ??0QToolBarChangeEvent@@QAE@ABV0@@Z @ 13252 NONAME ABSENT ; QToolBarChangeEvent::QToolBarChangeEvent(class QToolBarChangeEvent const &) + png_destroy_info_struct @ 13251 NONAME + png_destroy_read_struct @ 13252 NONAME ??1QBlitterPaintEngine@@UAE@XZ @ 13253 NONAME ; QBlitterPaintEngine::~QBlitterPaintEngine(void) ?markRasterOverlay@QBlittablePixmapData@@QAEXPBVQRectF@@H@Z @ 13254 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QRectF const *, int) - ??0QResizeEvent@@QAE@ABV0@@Z @ 13255 NONAME ABSENT ; QResizeEvent::QResizeEvent(class QResizeEvent const &) - ??0QIconEngineFactoryInterface@@QAE@XZ @ 13256 NONAME ABSENT ; QIconEngineFactoryInterface::QIconEngineFactoryInterface(void) + png_destroy_write_struct @ 13255 NONAME + png_error @ 13256 NONAME ?drawTextItem@QBlitterPaintEngine@@UAEXABVQPointF@@ABVQTextItem@@@Z @ 13257 NONAME ; void QBlitterPaintEngine::drawTextItem(class QPointF const &, class QTextItem const &) - ??0QPictureFormatInterface@@QAE@XZ @ 13258 NONAME ABSENT ; QPictureFormatInterface::QPictureFormatInterface(void) + png_free @ 13258 NONAME ?trUtf8@QFlickGesture@@SA?AVQString@@PBD0@Z @ 13259 NONAME ABSENT ; class QString QFlickGesture::trUtf8(char const *, char const *) ?stop@QScroller@@QAEXXZ @ 13260 NONAME ABSENT ; void QScroller::stop(void) ?retrieveData@QInternalMimeData@@MBE?AVQVariant@@ABVQString@@W4Type@2@@Z @ 13261 NONAME ; class QVariant QInternalMimeData::retrieveData(class QString const &, enum QVariant::Type) const @@ -13273,18 +13273,18 @@ EXPORTS ?sort@QAbstractProxyModel@@UAEXHW4SortOrder@Qt@@@Z @ 13272 NONAME ; void QAbstractProxyModel::sort(int, enum Qt::SortOrder) ?d_func@QBlittable@@AAEPAVQBlittablePrivate@@XZ @ 13273 NONAME ; class QBlittablePrivate * QBlittable::d_func(void) ?setDefaultScrollerProperties@QScrollerProperties@@SAXABV1@@Z @ 13274 NONAME ABSENT ; void QScrollerProperties::setDefaultScrollerProperties(class QScrollerProperties const &) - ??_EQPolygon@@QAE@I@Z @ 13275 NONAME ABSENT ; QPolygon::~QPolygon(unsigned int) + png_free_data @ 13275 NONAME ?type@QBlitterPaintEngine@@UBE?AW4Type@QPaintEngine@@XZ @ 13276 NONAME ; enum QPaintEngine::Type QBlitterPaintEngine::type(void) const ?qt_metacast@QScroller@@UAEPAXPBD@Z @ 13277 NONAME ABSENT ; void * QScroller::qt_metacast(char const *) - ??_EQImageReader@@QAE@I@Z @ 13278 NONAME ABSENT ; QImageReader::~QImageReader(unsigned int) + png_free_default @ 13278 NONAME ?buddy@QAbstractProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 13279 NONAME ; class QModelIndex QAbstractProxyModel::buddy(class QModelIndex const &) const ?tr@QScroller@@SA?AVQString@@PBD0H@Z @ 13280 NONAME ABSENT ; class QString QScroller::tr(char const *, char const *, int) ?fill@QImage@@QAEXABVQColor@@@Z @ 13281 NONAME ; void QImage::fill(class QColor const &) ?scrollMetric@QScrollerProperties@@QBE?AVQVariant@@W4ScrollMetric@1@@Z @ 13282 NONAME ABSENT ; class QVariant QScrollerProperties::scrollMetric(enum QScrollerProperties::ScrollMetric) const ?fill@QImage@@QAEXW4GlobalColor@Qt@@@Z @ 13283 NONAME ; void QImage::fill(enum Qt::GlobalColor) - ??4QStyleOptionGraphicsItem@@QAEAAV0@ABV0@@Z @ 13284 NONAME ABSENT ; class QStyleOptionGraphicsItem & QStyleOptionGraphicsItem::operator=(class QStyleOptionGraphicsItem const &) + png_get_IHDR @ 13284 NONAME ?canFetchMore@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 13285 NONAME ; bool QAbstractProxyModel::canFetchMore(class QModelIndex const &) const - ??4QStyleOptionProgressBarV2@@QAEAAV0@ABV0@@Z @ 13286 NONAME ABSENT ; class QStyleOptionProgressBarV2 & QStyleOptionProgressBarV2::operator=(class QStyleOptionProgressBarV2 const &) + png_get_PLTE @ 13286 NONAME ??1QScroller@@EAE@XZ @ 13287 NONAME ABSENT ; QScroller::~QScroller(void) ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 13288 NONAME ABSENT ; void QGlyphs::setFont(class QFont const &) ?startPos@QScrollPrepareEvent@@QBE?AVQPointF@@XZ @ 13289 NONAME ABSENT ; class QPointF QScrollPrepareEvent::startPos(void) const @@ -13294,16 +13294,16 @@ EXPORTS ?getText@QInputDialog@@SA?AVQString@@PAVQWidget@@ABV2@1W4EchoMode@QLineEdit@@1PA_NV?$QFlags@W4WindowType@Qt@@@@V?$QFlags@W4InputMethodHint@Qt@@@@@Z @ 13293 NONAME ; class QString QInputDialog::getText(class QWidget *, class QString const &, class QString const &, enum QLineEdit::EchoMode, class QString const &, bool *, class QFlags<enum Qt::WindowType>, class QFlags<enum Qt::InputMethodHint>) ?hasWidthForHeight@QSizePolicy@@QBE_NXZ @ 13294 NONAME ; bool QSizePolicy::hasWidthForHeight(void) const ?transformChanged@QBlitterPaintEngine@@UAEXXZ @ 13295 NONAME ; void QBlitterPaintEngine::transformChanged(void) - ??0QDragEnterEvent@@QAE@ABV0@@Z @ 13296 NONAME ABSENT ; QDragEnterEvent::QDragEnterEvent(class QDragEnterEvent const &) + png_get_bKGD @ 13296 NONAME ??0QBlittablePixmapData@@QAE@XZ @ 13297 NONAME ; QBlittablePixmapData::QBlittablePixmapData(void) - ??_EKey@QPixmapCache@@QAE@I@Z @ 13298 NONAME ABSENT ; QPixmapCache::Key::~Key(unsigned int) - ??_EQCursor@@QAE@I@Z @ 13299 NONAME ABSENT ; QCursor::~QCursor(unsigned int) + png_get_bit_depth @ 13298 NONAME + png_get_cHRM @ 13299 NONAME ?size@QBlittable@@QBE?AVQSize@@XZ @ 13300 NONAME ; class QSize QBlittable::size(void) const - ??0QShortcutEvent@@QAE@ABV0@@Z @ 13301 NONAME ABSENT ; QShortcutEvent::QShortcutEvent(class QShortcutEvent const &) + png_get_cHRM_fixed @ 13301 NONAME ?setBlittable@QBlittablePixmapData@@QAEXPAVQBlittable@@@Z @ 13302 NONAME ; void QBlittablePixmapData::setBlittable(class QBlittable *) ?opacityChanged@QBlitterPaintEngine@@UAEXXZ @ 13303 NONAME ; void QBlitterPaintEngine::opacityChanged(void) ?tr@QFlickGesture@@SA?AVQString@@PBD0H@Z @ 13304 NONAME ABSENT ; class QString QFlickGesture::tr(char const *, char const *, int) - ??_EQTextCursor@@QAE@I@Z @ 13305 NONAME ABSENT ; QTextCursor::~QTextCursor(unsigned int) + png_get_channels @ 13305 NONAME ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 13306 NONAME ABSENT ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const ?setState@QBlitterPaintEngine@@UAEXPAVQPainterState@@@Z @ 13307 NONAME ; void QBlitterPaintEngine::setState(class QPainterState *) ?clip@QBlitterPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 13308 NONAME ; void QBlitterPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation) @@ -13312,9 +13312,9 @@ EXPORTS ?setSnapPositionsX@QScroller@@QAEXABV?$QList@M@@@Z @ 13311 NONAME ABSENT ; void QScroller::setSnapPositionsX(class QList<float> const &) ?numberSuffix@QTextListFormat@@QBE?AVQString@@XZ @ 13312 NONAME ; class QString QTextListFormat::numberSuffix(void) const ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 13313 NONAME ABSENT ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const - ??0QGradient@@QAE@ABV0@@Z @ 13314 NONAME ABSENT ; QGradient::QGradient(class QGradient const &) + png_get_chunk_cache_max @ 13314 NONAME ?tabsMovable@QMdiArea@@QBE_NXZ @ 13315 NONAME ; bool QMdiArea::tabsMovable(void) const - ??4QInputMethodEvent@@QAEAAV0@ABV0@@Z @ 13316 NONAME ABSENT ; class QInputMethodEvent & QInputMethodEvent::operator=(class QInputMethodEvent const &) + png_get_chunk_malloc_max @ 13316 NONAME ?contentPos@QScrollPrepareEvent@@QBE?AVQPointF@@XZ @ 13317 NONAME ABSENT ; class QPointF QScrollPrepareEvent::contentPos(void) const ?getStaticMetaObject@QScroller@@SAABUQMetaObject@@XZ @ 13318 NONAME ABSENT ; struct QMetaObject const & QScroller::getStaticMetaObject(void) ?end@QBlitterPaintEngine@@UAE_NXZ @ 13319 NONAME ; bool QBlitterPaintEngine::end(void) @@ -13322,62 +13322,62 @@ EXPORTS ??0QFlickGesture@@QAE@PAVQObject@@W4MouseButton@Qt@@0@Z @ 13321 NONAME ABSENT ; QFlickGesture::QFlickGesture(class QObject *, enum Qt::MouseButton, class QObject *) ?fill@QBlitterPaintEngine@@UAEXABVQVectorPath@@ABVQBrush@@@Z @ 13322 NONAME ; void QBlitterPaintEngine::fill(class QVectorPath const &, class QBrush const &) ?drawPixmap@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQPixmap@@0@Z @ 13323 NONAME ; void QBlitterPaintEngine::drawPixmap(class QRectF const &, class QPixmap const &, class QRectF const &) - ??0QVector2D@@QAE@ABV0@@Z @ 13324 NONAME ABSENT ; QVector2D::QVector2D(class QVector2D const &) + png_get_color_type @ 13324 NONAME ?setSnapPositionsY@QScroller@@QAEXABV?$QList@M@@@Z @ 13325 NONAME ABSENT ; void QScroller::setSnapPositionsY(class QList<float> const &) - ??4QStyleOptionFocusRect@@QAEAAV0@ABV0@@Z @ 13326 NONAME ABSENT ; class QStyleOptionFocusRect & QStyleOptionFocusRect::operator=(class QStyleOptionFocusRect const &) - ??_EQPen@@QAE@I@Z @ 13327 NONAME ABSENT ; QPen::~QPen(unsigned int) - ??_EQKeySequence@@QAE@I@Z @ 13328 NONAME ABSENT ; QKeySequence::~QKeySequence(unsigned int) + png_get_compression_buffer_size @ 13326 NONAME + png_get_compression_type @ 13327 NONAME + png_get_copyright @ 13328 NONAME ?tr@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13329 NONAME ; class QString QInternalMimeData::tr(char const *, char const *, int) ?velocity@QScroller@@QBE?AVQPointF@@XZ @ 13330 NONAME ABSENT ; class QPointF QScroller::velocity(void) const ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 13331 NONAME ABSENT ; class QVector<unsigned int> QGlyphs::glyphIndexes(void) const ?get@QFontPrivate@@SAPAV1@ABVQFont@@@Z @ 13332 NONAME ; class QFontPrivate * QFontPrivate::get(class QFont const &) ?setScrollMetric@QScrollerProperties@@QAEXW4ScrollMetric@1@ABVQVariant@@@Z @ 13333 NONAME ABSENT ; void QScrollerProperties::setScrollMetric(enum QScrollerProperties::ScrollMetric, class QVariant const &) - ??4QGradient@@QAEAAV0@ABV0@@Z @ 13334 NONAME ABSENT ; class QGradient & QGradient::operator=(class QGradient const &) + png_get_current_pass_number @ 13334 NONAME ??0QScrollEvent@@QAE@ABVQPointF@@0W4ScrollState@0@@Z @ 13335 NONAME ABSENT ; QScrollEvent::QScrollEvent(class QPointF const &, class QPointF const &, enum QScrollEvent::ScrollState) ?d_func@QFlickGesture@@AAEPAVQFlickGesturePrivate@@XZ @ 13336 NONAME ABSENT ; class QFlickGesturePrivate * QFlickGesture::d_func(void) ?scrollState@QScrollEvent@@QBE?AW4ScrollState@1@XZ @ 13337 NONAME ABSENT ; enum QScrollEvent::ScrollState QScrollEvent::scrollState(void) const - ??0QTextTableFormat@@QAE@ABV0@@Z @ 13338 NONAME ABSENT ; QTextTableFormat::QTextTableFormat(class QTextTableFormat const &) - ??_EQImagePixmapCleanupHooks@@QAE@I@Z @ 13339 NONAME ABSENT ; QImagePixmapCleanupHooks::~QImagePixmapCleanupHooks(unsigned int) + png_get_current_row_number @ 13338 NONAME + png_get_error_ptr @ 13339 NONAME ?fetchMore@QAbstractProxyModel@@UAEXABVQModelIndex@@@Z @ 13340 NONAME ; void QAbstractProxyModel::fetchMore(class QModelIndex const &) ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 13341 NONAME ABSENT ; class QList<class QGlyphs> QTextLine::glyphs(int, int) const ?getStaticMetaObject@QFlickGesture@@SAABUQMetaObject@@XZ @ 13342 NONAME ABSENT ; struct QMetaObject const & QFlickGesture::getStaticMetaObject(void) ?setViewportSize@QScrollPrepareEvent@@QAEXABVQSizeF@@@Z @ 13343 NONAME ABSENT ; void QScrollPrepareEvent::setViewportSize(class QSizeF const &) - ??0QStatusTipEvent@@QAE@ABV0@@Z @ 13344 NONAME ABSENT ; QStatusTipEvent::QStatusTipEvent(class QStatusTipEvent const &) - ??0Value@QCss@@QAE@ABU01@@Z @ 13345 NONAME ABSENT ; QCss::Value::Value(struct QCss::Value const &) + png_get_filter_type @ 13344 NONAME + png_get_gAMA @ 13345 NONAME ?d_func@QScrollPrepareEvent@@AAEPAVQScrollPrepareEventPrivate@@XZ @ 13346 NONAME ABSENT ; class QScrollPrepareEventPrivate * QScrollPrepareEvent::d_func(void) ?overshootDistance@QScrollEvent@@QBE?AVQPointF@@XZ @ 13347 NONAME ABSENT ; class QPointF QScrollEvent::overshootDistance(void) const ?resolveFontFamilyAlias@QFontDatabase@@CA?AVQString@@ABV2@@Z @ 13348 NONAME ; class QString QFontDatabase::resolveFontFamilyAlias(class QString const &) ?alphaRGBMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@HABVQTransform@@@Z @ 13349 NONAME ; class QImage QFontEngine::alphaRGBMapForGlyph(unsigned int, struct QFixed, int, class QTransform const &) - ??4QSizePolicy@@QAEAAV0@ABV0@@Z @ 13350 NONAME ABSENT ; class QSizePolicy & QSizePolicy::operator=(class QSizePolicy const &) + png_get_gAMA_fixed @ 13350 NONAME ?swap@QBitmap@@QAEXAAV1@@Z @ 13351 NONAME ; void QBitmap::swap(class QBitmap &) ?hasFormat@QInternalMimeData@@UBE_NABVQString@@@Z @ 13352 NONAME ; bool QInternalMimeData::hasFormat(class QString const &) const ?renderDataHelper@QInternalMimeData@@SA?AVQByteArray@@ABVQString@@PBVQMimeData@@@Z @ 13353 NONAME ; class QByteArray QInternalMimeData::renderDataHelper(class QString const &, class QMimeData const *) - ??_ETouchPoint@QTouchEvent@@QAE@I@Z @ 13354 NONAME ABSENT ; QTouchEvent::TouchPoint::~TouchPoint(unsigned int) + png_get_hIST @ 13354 NONAME ??0QWindowSurface@@QAE@PAVQWidget@@_N@Z @ 13355 NONAME ; QWindowSurface::QWindowSurface(class QWidget *, bool) ?fill@QBlittablePixmapData@@UAEXABVQColor@@@Z @ 13356 NONAME ; void QBlittablePixmapData::fill(class QColor const &) ?metric@QBlittablePixmapData@@UBEHW4PaintDeviceMetric@QPaintDevice@@@Z @ 13357 NONAME ; int QBlittablePixmapData::metric(enum QPaintDevice::PaintDeviceMetric) const - ??4QItemSelection@@QAEAAV0@ABV0@@Z @ 13358 NONAME ABSENT ; class QItemSelection & QItemSelection::operator=(class QItemSelection const &) + png_get_header_ver @ 13358 NONAME ?fillRect@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQColor@@@Z @ 13359 NONAME ; void QBlitterPaintEngine::fillRect(class QRectF const &, class QColor const &) - ??4QStyleOptionQ3ListView@@QAEAAV0@ABV0@@Z @ 13360 NONAME ABSENT ; class QStyleOptionQ3ListView & QStyleOptionQ3ListView::operator=(class QStyleOptionQ3ListView const &) + png_get_header_version @ 13360 NONAME ??6@YA?AVQDebug@@V0@PBVQSymbianEvent@@@Z @ 13361 NONAME ; class QDebug operator<<(class QDebug, class QSymbianEvent const *) - ??0QSizePolicy@@QAE@ABV0@@Z @ 13362 NONAME ABSENT ; QSizePolicy::QSizePolicy(class QSizePolicy const &) + png_get_iCCP @ 13362 NONAME ?ProcessCommandParametersL@QS60MainAppUi@@UAEHW4TApaCommand@@AAV?$TBuf@$0BAA@@@ABVTDesC8@@@Z @ 13363 NONAME ; int QS60MainAppUi::ProcessCommandParametersL(enum TApaCommand, class TBuf<256> &, class TDesC8 const &) ?scrollerProperties@QScroller@@QBE?AVQScrollerProperties@@XZ @ 13364 NONAME ABSENT ; class QScrollerProperties QScroller::scrollerProperties(void) const ??_EQBlittablePixmapData@@UAE@I@Z @ 13365 NONAME ; QBlittablePixmapData::~QBlittablePixmapData(unsigned int) ?mimeData@QAbstractProxyModel@@UBEPAVQMimeData@@ABV?$QList@VQModelIndex@@@@@Z @ 13366 NONAME ; class QMimeData * QAbstractProxyModel::mimeData(class QList<class QModelIndex> const &) const - ??4QStyleOptionFrameV2@@QAEAAV0@ABV0@@Z @ 13367 NONAME ABSENT ; class QStyleOptionFrameV2 & QStyleOptionFrameV2::operator=(class QStyleOptionFrameV2 const &) + png_get_image_height @ 13367 NONAME ??_EQScroller@@UAE@I@Z @ 13368 NONAME ABSENT ; QScroller::~QScroller(unsigned int) ??1QScrollPrepareEvent@@UAE@XZ @ 13369 NONAME ABSENT ; QScrollPrepareEvent::~QScrollPrepareEvent(void) - ??4QVector3D@@QAEAAV0@ABV0@@Z @ 13370 NONAME ABSENT ; class QVector3D & QVector3D::operator=(class QVector3D const &) + png_get_image_width @ 13370 NONAME ?setTabsMovable@QMdiArea@@QAEX_N@Z @ 13371 NONAME ; void QMdiArea::setTabsMovable(bool) ?minimumSizeHint@QRadioButton@@UBE?AVQSize@@XZ @ 13372 NONAME ; class QSize QRadioButton::minimumSizeHint(void) const - ??4QStyleOptionQ3DockWindow@@QAEAAV0@ABV0@@Z @ 13373 NONAME ABSENT ; class QStyleOptionQ3DockWindow & QStyleOptionQ3DockWindow::operator=(class QStyleOptionQ3DockWindow const &) + png_get_int_32 @ 13373 NONAME ?qt_metacast@QFlickGesture@@UAEPAXPBD@Z @ 13374 NONAME ABSENT ; void * QFlickGesture::qt_metacast(char const *) - ??_EQFont@@QAE@I@Z @ 13375 NONAME ABSENT ; QFont::~QFont(unsigned int) + png_get_interlace_type @ 13375 NONAME ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 13376 NONAME ABSENT ; void QGlyphs::setPositions(class QVector<class QPointF> const &) - ??4QStyleOptionDockWidget@@QAEAAV0@ABV0@@Z @ 13377 NONAME ABSENT ; class QStyleOptionDockWidget & QStyleOptionDockWidget::operator=(class QStyleOptionDockWidget const &) - ??0QPainterState@@QAE@ABV0@@Z @ 13378 NONAME ABSENT ; QPainterState::QPainterState(class QPainterState const &) - ??4QStyleOptionFrame@@QAEAAV0@ABV0@@Z @ 13379 NONAME ABSENT ; class QStyleOptionFrame & QStyleOptionFrame::operator=(class QStyleOptionFrame const &) + png_get_io_chunk_name @ 13377 NONAME + png_get_io_chunk_type @ 13378 NONAME + png_get_io_ptr @ 13379 NONAME ?drawRects@QBlitterPaintEngine@@UAEXPBVQRect@@H@Z @ 13380 NONAME ; void QBlitterPaintEngine::drawRects(class QRect const *, int) ?fillInPendingGlyphs@QTextureGlyphCache@@QAEXXZ @ 13381 NONAME ; void QTextureGlyphCache::fillInPendingGlyphs(void) ?metaObject@QFlickGesture@@UBEPBUQMetaObject@@XZ @ 13382 NONAME ABSENT ; struct QMetaObject const * QFlickGesture::metaObject(void) const @@ -13387,20 +13387,20 @@ EXPORTS ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 13386 NONAME ABSENT ; void QGlyphs::setGlyphIndexes(class QVector<unsigned int> const &) ?alphaMapBoundingBox@QFontEngine@@UAE?AUglyph_metrics_t@@IABVQTransform@@W4GlyphFormat@1@@Z @ 13387 NONAME ABSENT ; struct glyph_metrics_t QFontEngine::alphaMapBoundingBox(unsigned int, class QTransform const &, enum QFontEngine::GlyphFormat) ?resendPrepareEvent@QScroller@@QAEXXZ @ 13388 NONAME ABSENT ; void QScroller::resendPrepareEvent(void) - ??4QTextLength@@QAEAAV0@ABV0@@Z @ 13389 NONAME ABSENT ; class QTextLength & QTextLength::operator=(class QTextLength const &) - ??0QHelpEvent@@QAE@ABV0@@Z @ 13390 NONAME ABSENT ; QHelpEvent::QHelpEvent(class QHelpEvent const &) - ??0QContextMenuEvent@@QAE@ABV0@@Z @ 13391 NONAME ABSENT ; QContextMenuEvent::QContextMenuEvent(class QContextMenuEvent const &) + png_get_libpng_ver @ 13389 NONAME + png_get_mem_ptr @ 13390 NONAME + png_get_oFFs @ 13391 NONAME ?d_func@QBlittable@@ABEPBVQBlittablePrivate@@XZ @ 13392 NONAME ; class QBlittablePrivate const * QBlittable::d_func(void) const ?state@QBlitterPaintEngine@@QBEPBVQPainterState@@XZ @ 13393 NONAME ; class QPainterState const * QBlitterPaintEngine::state(void) const ??0QScrollPrepareEvent@@QAE@ABVQPointF@@@Z @ 13394 NONAME ABSENT ; QScrollPrepareEvent::QScrollPrepareEvent(class QPointF const &) - ??0QWhatsThisClickedEvent@@QAE@ABV0@@Z @ 13395 NONAME ABSENT ; QWhatsThisClickedEvent::QWhatsThisClickedEvent(class QWhatsThisClickedEvent const &) - ??4QStyleOptionTab@@QAEAAV0@ABV0@@Z @ 13396 NONAME ABSENT ; class QStyleOptionTab & QStyleOptionTab::operator=(class QStyleOptionTab const &) - ??0QTabletEvent@@QAE@ABV0@@Z @ 13397 NONAME ABSENT ; QTabletEvent::QTabletEvent(class QTabletEvent const &) + png_get_pCAL @ 13395 NONAME + png_get_pHYs @ 13396 NONAME + png_get_pHYs_dpi @ 13397 NONAME ?scrollTo@QScroller@@QAEXABVQPointF@@H@Z @ 13398 NONAME ABSENT ; void QScroller::scrollTo(class QPointF const &, int) ?ungrabGesture@QScroller@@SAXPAVQObject@@@Z @ 13399 NONAME ABSENT ; void QScroller::ungrabGesture(class QObject *) - ??4QItemSelectionRange@@QAEAAV0@ABV0@@Z @ 13400 NONAME ABSENT ; class QItemSelectionRange & QItemSelectionRange::operator=(class QItemSelectionRange const &) + png_get_pixel_aspect_ratio @ 13400 NONAME ?clear@QGlyphs@@QAEXXZ @ 13401 NONAME ABSENT ; void QGlyphs::clear(void) - ??_EQStyleOptionViewItemV4@@QAE@I@Z @ 13402 NONAME ABSENT ; QStyleOptionViewItemV4::~QStyleOptionViewItemV4(unsigned int) + png_get_pixel_aspect_ratio_fixed @ 13402 NONAME ??1QBlittablePixmapData@@UAE@XZ @ 13403 NONAME ; QBlittablePixmapData::~QBlittablePixmapData(void) ?formatsHelper@QInternalMimeData@@SA?AVQStringList@@PBVQMimeData@@@Z @ 13404 NONAME ; class QStringList QInternalMimeData::formatsHelper(class QMimeData const *) ?qt_metacast@QInternalMimeData@@UAEPAXPBD@Z @ 13405 NONAME ; void * QInternalMimeData::qt_metacast(char const *) @@ -13410,22 +13410,22 @@ EXPORTS ?hasChildren@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 13409 NONAME ; bool QAbstractProxyModel::hasChildren(class QModelIndex const &) const ?swap@QPen@@QAEXAAV1@@Z @ 13410 NONAME ; void QPen::swap(class QPen &) ?span@QAbstractProxyModel@@UBE?AVQSize@@ABVQModelIndex@@@Z @ 13411 NONAME ; class QSize QAbstractProxyModel::span(class QModelIndex const &) const - ??4QEglProperties@@QAEAAV0@ABV0@@Z @ 13412 NONAME ABSENT ; class QEglProperties & QEglProperties::operator=(class QEglProperties const &) - ??0QHoverEvent@@QAE@ABV0@@Z @ 13413 NONAME ABSENT ; QHoverEvent::QHoverEvent(class QHoverEvent const &) - ??0QPaintEngineState@@QAE@XZ @ 13414 NONAME ABSENT ; QPaintEngineState::QPaintEngineState(void) + png_get_pixels_per_meter @ 13412 NONAME + png_get_progressive_ptr @ 13413 NONAME + png_get_rgb_to_gray_status @ 13414 NONAME ?setSnapPositionsY@QScroller@@QAEXMM@Z @ 13415 NONAME ABSENT ; void QScroller::setSnapPositionsY(float, float) ?d_func@QScrollPrepareEvent@@ABEPBVQScrollPrepareEventPrivate@@XZ @ 13416 NONAME ABSENT ; class QScrollPrepareEventPrivate const * QScrollPrepareEvent::d_func(void) const ?textureMapForGlyph@QTextureGlyphCache@@QBE?AVQImage@@IUQFixed@@@Z @ 13417 NONAME ; class QImage QTextureGlyphCache::textureMapForGlyph(unsigned int, struct QFixed) const - ??0QKeyEvent@@QAE@ABV0@@Z @ 13418 NONAME ABSENT ; QKeyEvent::QKeyEvent(class QKeyEvent const &) - ??0QIconEngine@@QAE@ABV0@@Z @ 13419 NONAME ABSENT ; QIconEngine::QIconEngine(class QIconEngine const &) - ??4QStyleOptionToolBoxV2@@QAEAAV0@ABV0@@Z @ 13420 NONAME ABSENT ; class QStyleOptionToolBoxV2 & QStyleOptionToolBoxV2::operator=(class QStyleOptionToolBoxV2 const &) + png_get_rowbytes @ 13418 NONAME + png_get_rows @ 13419 NONAME + png_get_sBIT @ 13420 NONAME ?qt_metacall@QInternalMimeData@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 13421 NONAME ; int QInternalMimeData::qt_metacall(enum QMetaObject::Call, int, void * *) ?lineHeightType@QTextBlockFormat@@QBEHXZ @ 13422 NONAME ; int QTextBlockFormat::lineHeightType(void) const ?hintingPreference@QFont@@QBE?AW4HintingPreference@1@XZ @ 13423 NONAME ; enum QFont::HintingPreference QFont::hintingPreference(void) const ??0QGlyphs@@QAE@XZ @ 13424 NONAME ABSENT ; QGlyphs::QGlyphs(void) ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13425 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *, int) - ??0QImageIOHandlerFactoryInterface@@QAE@XZ @ 13426 NONAME ABSENT ; QImageIOHandlerFactoryInterface::QImageIOHandlerFactoryInterface(void) - ??_EQRegion@@QAE@I@Z @ 13427 NONAME ABSENT ; QRegion::~QRegion(unsigned int) + png_get_sCAL @ 13426 NONAME + png_get_sCAL_fixed @ 13427 NONAME ?begin@QBlitterPaintEngine@@UAE_NPAVQPaintDevice@@@Z @ 13428 NONAME ; bool QBlitterPaintEngine::begin(class QPaintDevice *) ?inFontUcs4@QFontMetricsF@@QBE_NI@Z @ 13429 NONAME ; bool QFontMetricsF::inFontUcs4(unsigned int) const ?viewportSize@QScrollPrepareEvent@@QBE?AVQSizeF@@XZ @ 13430 NONAME ABSENT ; class QSizeF QScrollPrepareEvent::viewportSize(void) const @@ -13433,12 +13433,12 @@ EXPORTS ?d_func@QBlitterPaintEngine@@AAEPAVQBlitterPaintEnginePrivate@@XZ @ 13432 NONAME ; class QBlitterPaintEnginePrivate * QBlitterPaintEngine::d_func(void) ?setNumberPrefix@QTextListFormat@@QAEXABVQString@@@Z @ 13433 NONAME ; void QTextListFormat::setNumberPrefix(class QString const &) ?lineHeight@QTextBlockFormat@@QBEMMM@Z @ 13434 NONAME ; float QTextBlockFormat::lineHeight(float, float) const - ??4QStyleOptionComplex@@QAEAAV0@ABV0@@Z @ 13435 NONAME ABSENT ; class QStyleOptionComplex & QStyleOptionComplex::operator=(class QStyleOptionComplex const &) + png_get_sCAL_s @ 13435 NONAME ?getItem@QInputDialog@@SA?AVQString@@PAVQWidget@@ABV2@1ABVQStringList@@H_NPA_NV?$QFlags@W4WindowType@Qt@@@@V?$QFlags@W4InputMethodHint@Qt@@@@@Z @ 13436 NONAME ; class QString QInputDialog::getItem(class QWidget *, class QString const &, class QString const &, class QStringList const &, int, bool, bool *, class QFlags<enum Qt::WindowType>, class QFlags<enum Qt::InputMethodHint>) - ??_EFileInfo@QZipReader@@QAE@I@Z @ 13437 NONAME ABSENT ; QZipReader::FileInfo::~FileInfo(unsigned int) + png_get_sPLT @ 13437 NONAME ?hasFeature@QWindowSurface@@QBE_NW4WindowSurfaceFeature@1@@Z @ 13438 NONAME ; bool QWindowSurface::hasFeature(enum QWindowSurface::WindowSurfaceFeature) const ?qGamma_correct_back_to_linear_cs@@YAXPAVQImage@@@Z @ 13439 NONAME ; void qGamma_correct_back_to_linear_cs(class QImage *) - ??0QBitmap@@QAE@ABV0@@Z @ 13440 NONAME ABSENT ; QBitmap::QBitmap(class QBitmap const &) + png_get_sRGB @ 13440 NONAME ?clip@QBlitterPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 13441 NONAME ; void QBlitterPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation) ??1QScrollEvent@@UAE@XZ @ 13442 NONAME ABSENT ; QScrollEvent::~QScrollEvent(void) ?state@QScroller@@QBE?AW4State@1@XZ @ 13443 NONAME ABSENT ; enum QScroller::State QScroller::state(void) const @@ -13446,28 +13446,28 @@ EXPORTS ?tr@QScroller@@SA?AVQString@@PBD0@Z @ 13445 NONAME ABSENT ; class QString QScroller::tr(char const *, char const *) ?canReadData@QInternalMimeData@@SA_NABVQString@@@Z @ 13446 NONAME ; bool QInternalMimeData::canReadData(class QString const &) ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13447 NONAME ABSENT ; class QList<class QGlyphs> QTextLayout::glyphs(void) const - ?leadingSpaceWidth@QTextEngine@@QAE?AUQFixed@@ABUQScriptLine@@@Z @ 13448 NONAME ; struct QFixed QTextEngine::leadingSpaceWidth(struct QScriptLine const &) - ??_EQTextFormat@@QAE@I@Z @ 13449 NONAME ABSENT ; QTextFormat::~QTextFormat(unsigned int) - ??4QStyleOptionTabWidgetFrame@@QAEAAV0@ABV0@@Z @ 13450 NONAME ABSENT ; class QStyleOptionTabWidgetFrame & QStyleOptionTabWidgetFrame::operator=(class QStyleOptionTabWidgetFrame const &) + png_get_tIME @ 13448 NONAME + png_get_tRNS @ 13449 NONAME + png_get_text @ 13450 NONAME ?trUtf8@QScroller@@SA?AVQString@@PBD0H@Z @ 13451 NONAME ABSENT ; class QString QScroller::trUtf8(char const *, char const *, int) ?d_func@QFlickGesture@@ABEPBVQFlickGesturePrivate@@XZ @ 13452 NONAME ABSENT ; class QFlickGesturePrivate const * QFlickGesture::d_func(void) const - ??4QMouseEvent@@QAEAAV0@ABV0@@Z @ 13453 NONAME ABSENT ; class QMouseEvent & QMouseEvent::operator=(class QMouseEvent const &) - ??_EQPainter@@QAE@I@Z @ 13454 NONAME ABSENT ; QPainter::~QPainter(unsigned int) - ??4QStyleOptionTabBarBaseV2@@QAEAAV0@ABV0@@Z @ 13455 NONAME ABSENT ; class QStyleOptionTabBarBaseV2 & QStyleOptionTabBarBaseV2::operator=(class QStyleOptionTabBarBaseV2 const &) - ??4QInputEvent@@QAEAAV0@ABV0@@Z @ 13456 NONAME ABSENT ; class QInputEvent & QInputEvent::operator=(class QInputEvent const &) + png_get_uint_16 @ 13453 NONAME + png_get_uint_31 @ 13454 NONAME + png_get_uint_32 @ 13455 NONAME + png_get_unknown_chunks @ 13456 NONAME ?hasScroller@QScroller@@SA_NPAVQObject@@@Z @ 13457 NONAME ABSENT ; bool QScroller::hasScroller(class QObject *) ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@ABVQTransform@@@Z @ 13458 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int, struct QFixed, class QTransform const &) - ??_EQPainterPath@@QAE@I@Z @ 13459 NONAME ABSENT ; QPainterPath::~QPainterPath(unsigned int) + png_get_user_chunk_ptr @ 13459 NONAME ??_EQGlyphs@@QAE@I@Z @ 13460 NONAME ABSENT ; QGlyphs::~QGlyphs(unsigned int) ?fromImage@QBlittablePixmapData@@UAEXABVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 13461 NONAME ; void QBlittablePixmapData::fromImage(class QImage const &, class QFlags<enum Qt::ImageConversionFlag>) ??0QInternalMimeData@@QAE@XZ @ 13462 NONAME ; QInternalMimeData::QInternalMimeData(void) ??_EQScrollEvent@@UAE@I@Z @ 13463 NONAME ABSENT ; QScrollEvent::~QScrollEvent(unsigned int) ?features@QRasterWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 13464 NONAME ; class QFlags<enum QWindowSurface::WindowSurfaceFeature> QRasterWindowSurface::features(void) const ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 13465 NONAME ABSENT ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) - ??4QQuaternion@@QAEAAV0@ABV0@@Z @ 13466 NONAME ABSENT ; class QQuaternion & QQuaternion::operator=(class QQuaternion const &) - ??4Symbol@QCss@@QAEAAU01@ABU01@@Z @ 13467 NONAME ABSENT ; struct QCss::Symbol & QCss::Symbol::operator=(struct QCss::Symbol const &) + png_get_user_height_max @ 13466 NONAME + png_get_user_transform_ptr @ 13467 NONAME ??0QBlittable@@QAE@ABVQSize@@V?$QFlags@W4Capability@QBlittable@@@@@Z @ 13468 NONAME ; QBlittable::QBlittable(class QSize const &, class QFlags<enum QBlittable::Capability>) - ??0QIconDragEvent@@QAE@ABV0@@Z @ 13469 NONAME ABSENT ; QIconDragEvent::QIconDragEvent(class QIconDragEvent const &) + png_get_user_width_max @ 13469 NONAME ?scroller@QScroller@@SAPAV1@PAVQObject@@@Z @ 13470 NONAME ABSENT ; class QScroller * QScroller::scroller(class QObject *) ??4QScrollerProperties@@QAEAAV0@ABV0@@Z @ 13471 NONAME ABSENT ; class QScrollerProperties & QScrollerProperties::operator=(class QScrollerProperties const &) ?d_func@QScroller@@AAEPAVQScrollerPrivate@@XZ @ 13472 NONAME ABSENT ; class QScrollerPrivate * QScroller::d_func(void) @@ -13478,49 +13478,49 @@ EXPORTS ??0QScrollerProperties@@QAE@XZ @ 13477 NONAME ABSENT ; QScrollerProperties::QScrollerProperties(void) ?setLineHeight@QTextBlockFormat@@QAEXMH@Z @ 13478 NONAME ; void QTextBlockFormat::setLineHeight(float, int) ?calculateSubPixelPositionCount@QTextureGlyphCache@@IBEHI@Z @ 13479 NONAME ; int QTextureGlyphCache::calculateSubPixelPositionCount(unsigned int) const - ??0QTextImageFormat@@QAE@ABV0@@Z @ 13480 NONAME ABSENT ; QTextImageFormat::QTextImageFormat(class QTextImageFormat const &) - ??0QMoveEvent@@QAE@ABV0@@Z @ 13481 NONAME ABSENT ; QMoveEvent::QMoveEvent(class QMoveEvent const &) + png_get_valid @ 13480 NONAME + png_get_x_offset_inches @ 13481 NONAME ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13482 NONAME ABSENT ; class QList<class QGlyphs> QTextFragment::glyphs(void) const - ??0QInputContextFactoryInterface@@QAE@XZ @ 13483 NONAME ABSENT ; QInputContextFactoryInterface::QInputContextFactoryInterface(void) - ??0QTextFrameFormat@@QAE@ABV0@@Z @ 13484 NONAME ABSENT ; QTextFrameFormat::QTextFrameFormat(class QTextFrameFormat const &) + png_get_x_offset_inches_fixed @ 13483 NONAME + png_get_x_offset_microns @ 13484 NONAME ?resetInternalData@QAbstractProxyModel@@IAEXXZ @ 13485 NONAME ABSENT ; void QAbstractProxyModel::resetInternalData(void) - ??0Symbol@QCss@@QAE@ABU01@@Z @ 13486 NONAME ABSENT ; QCss::Symbol::Symbol(struct QCss::Symbol const &) + png_get_x_offset_pixels @ 13486 NONAME ?features@QWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 13487 NONAME ; class QFlags<enum QWindowSurface::WindowSurfaceFeature> QWindowSurface::features(void) const ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQVectorPath@@@Z @ 13488 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QVectorPath const &) - ??4QStyleOptionFrameV3@@QAEAAV0@ABV0@@Z @ 13489 NONAME ABSENT ; class QStyleOptionFrameV3 & QStyleOptionFrameV3::operator=(class QStyleOptionFrameV3 const &) + png_get_x_pixels_per_inch @ 13489 NONAME ?scrollTo@QScroller@@QAEXABVQPointF@@@Z @ 13490 NONAME ABSENT ; void QScroller::scrollTo(class QPointF const &) - ??0QGraphicsSystem@@QAE@XZ @ 13491 NONAME ABSENT ; QGraphicsSystem::QGraphicsSystem(void) - ??4QStyleOptionViewItem@@QAEAAV0@ABV0@@Z @ 13492 NONAME ABSENT ; class QStyleOptionViewItem & QStyleOptionViewItem::operator=(class QStyleOptionViewItem const &) - ??4QStyleOptionProgressBar@@QAEAAV0@ABV0@@Z @ 13493 NONAME ABSENT ; class QStyleOptionProgressBar & QStyleOptionProgressBar::operator=(class QStyleOptionProgressBar const &) + png_get_x_pixels_per_meter @ 13491 NONAME + png_get_y_offset_inches @ 13492 NONAME + png_get_y_offset_inches_fixed @ 13493 NONAME ?clip@QBlitterPaintEngine@@QAEPBVQClipData@@XZ @ 13494 NONAME ; class QClipData const * QBlitterPaintEngine::clip(void) ?d_func@QScroller@@ABEPBVQScrollerPrivate@@XZ @ 13495 NONAME ABSENT ; class QScrollerPrivate const * QScroller::d_func(void) const ?setNumberSuffix@QTextListFormat@@QAEXABVQString@@@Z @ 13496 NONAME ; void QTextListFormat::setNumberSuffix(class QString const &) ?swap@QPicture@@QAEXAAV1@@Z @ 13497 NONAME ; void QPicture::swap(class QPicture &) ?swap@QPainterPath@@QAEXAAV1@@Z @ 13498 NONAME ; void QPainterPath::swap(class QPainterPath &) - ??4QStyleOptionRubberBand@@QAEAAV0@ABV0@@Z @ 13499 NONAME ABSENT ; class QStyleOptionRubberBand & QStyleOptionRubberBand::operator=(class QStyleOptionRubberBand const &) + png_get_y_offset_microns @ 13499 NONAME ?minimumSizeHint@QCheckBox@@UBE?AVQSize@@XZ @ 13500 NONAME ; class QSize QCheckBox::minimumSizeHint(void) const ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 13501 NONAME ABSENT ; class QFont QFontEngine::createExplicitFont(void) const ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@@Z @ 13502 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int, struct QFixed) ?fillTexture@QImageTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@IUQFixed@@@Z @ 13503 NONAME ; void QImageTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int, struct QFixed) ?swap@QIcon@@QAEXAAV1@@Z @ 13504 NONAME ; void QIcon::swap(class QIcon &) ?unmarkRasterOverlay@QBlittablePixmapData@@QAEXABVQRectF@@@Z @ 13505 NONAME ; void QBlittablePixmapData::unmarkRasterOverlay(class QRectF const &) - ??0QDragResponseEvent@@QAE@ABV0@@Z @ 13506 NONAME ABSENT ; QDragResponseEvent::QDragResponseEvent(class QDragResponseEvent const &) - ??0QIconEngine@@QAE@XZ @ 13507 NONAME ABSENT ; QIconEngine::QIconEngine(void) + png_get_y_offset_pixels @ 13506 NONAME + png_get_y_pixels_per_inch @ 13507 NONAME ?brushOriginChanged@QBlitterPaintEngine@@UAEXXZ @ 13508 NONAME ; void QBlitterPaintEngine::brushOriginChanged(void) ?openFile@QFileOpenEvent@@QBE_NAAVQFile@@V?$QFlags@W4OpenModeFlag@QIODevice@@@@@Z @ 13509 NONAME ; bool QFileOpenEvent::openFile(class QFile &, class QFlags<enum QIODevice::OpenModeFlag>) const - ??_EQBrush@@QAE@I@Z @ 13510 NONAME ABSENT ; QBrush::~QBrush(unsigned int) + png_get_y_pixels_per_meter @ 13510 NONAME ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@H@Z @ 13511 NONAME ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type, int) ?handleInput@QScroller@@QAE_NW4Input@1@ABVQPointF@@_J@Z @ 13512 NONAME ABSENT ; bool QScroller::handleInput(enum QScroller::Input, class QPointF const &, long long) ??8QScrollerProperties@@QBE_NABV0@@Z @ 13513 NONAME ABSENT ; bool QScrollerProperties::operator==(class QScrollerProperties const &) const ?inFontUcs4@QFontMetrics@@QBE_NI@Z @ 13514 NONAME ; bool QFontMetrics::inFontUcs4(unsigned int) const - ??_EQTableWidgetSelectionRange@@QAE@I@Z @ 13515 NONAME ABSENT ; QTableWidgetSelectionRange::~QTableWidgetSelectionRange(unsigned int) - ??4QStyleOptionTabBarBase@@QAEAAV0@ABV0@@Z @ 13516 NONAME ABSENT ; class QStyleOptionTabBarBase & QStyleOptionTabBarBase::operator=(class QStyleOptionTabBarBase const &) - ??0QTextObjectInterface@@QAE@XZ @ 13517 NONAME ABSENT ; QTextObjectInterface::QTextObjectInterface(void) + png_handle_as_unknown @ 13515 NONAME + png_info_init_3 @ 13516 NONAME + png_init_io @ 13517 NONAME ?unlock@QBlittable@@QAEXXZ @ 13518 NONAME ; void QBlittable::unlock(void) ?metaObject@QScroller@@UBEPBUQMetaObject@@XZ @ 13519 NONAME ABSENT ; struct QMetaObject const * QScroller::metaObject(void) const ?d_func@QScrollEvent@@ABEPBVQScrollEventPrivate@@XZ @ 13520 NONAME ABSENT ; class QScrollEventPrivate const * QScrollEvent::d_func(void) const ?swap@QRegion@@QAEXAAV1@@Z @ 13521 NONAME ; void QRegion::swap(class QRegion &) - ??0QHideEvent@@QAE@ABV0@@Z @ 13522 NONAME ABSENT ; QHideEvent::QHideEvent(class QHideEvent const &) + png_longjmp @ 13522 NONAME ?ensureVisible@QScroller@@QAEXABVQRectF@@MMH@Z @ 13523 NONAME ABSENT ; void QScroller::ensureVisible(class QRectF const &, float, float, int) ?qt_metacall@QFlickGesture@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 13524 NONAME ABSENT ; int QFlickGesture::qt_metacall(enum QMetaObject::Call, int, void * *) ?setItemData@QAbstractProxyModel@@UAE_NABVQModelIndex@@ABV?$QMap@HVQVariant@@@@@Z @ 13525 NONAME ; bool QAbstractProxyModel::setItemData(class QModelIndex const &, class QMap<int, class QVariant> const &) @@ -13539,59 +13539,59 @@ EXPORTS ??9QGlyphs@@QBE_NABV0@@Z @ 13538 NONAME ABSENT ; bool QGlyphs::operator!=(class QGlyphs const &) const ??1QBlittable@@UAE@XZ @ 13539 NONAME ; QBlittable::~QBlittable(void) ??_EQBlitterPaintEngine@@UAE@I@Z @ 13540 NONAME ; QBlitterPaintEngine::~QBlitterPaintEngine(unsigned int) - ??0QCloseEvent@@QAE@ABV0@@Z @ 13541 NONAME ABSENT ; QCloseEvent::QCloseEvent(class QCloseEvent const &) + png_malloc_default @ 13541 NONAME ?grabbedGesture@QScroller@@SA?AW4GestureType@Qt@@PAVQObject@@@Z @ 13542 NONAME ABSENT ; enum Qt::GestureType QScroller::grabbedGesture(class QObject *) ?buffer@QBlittablePixmapData@@UAEPAVQImage@@XZ @ 13543 NONAME ; class QImage * QBlittablePixmapData::buffer(void) - ??0QTextFrameLayoutData@@QAE@XZ @ 13544 NONAME ABSENT ; QTextFrameLayoutData::QTextFrameLayoutData(void) + png_malloc_warn @ 13544 NONAME ?staticMetaObject@QFlickGesture@@2UQMetaObject@@B @ 13545 NONAME ABSENT ; struct QMetaObject const QFlickGesture::staticMetaObject ?finalPosition@QScroller@@QBE?AVQPointF@@XZ @ 13546 NONAME ABSENT ; class QPointF QScroller::finalPosition(void) const - ??4QStyleOptionTabWidgetFrameV2@@QAEAAV0@ABV0@@Z @ 13547 NONAME ABSENT ; class QStyleOptionTabWidgetFrameV2 & QStyleOptionTabWidgetFrameV2::operator=(class QStyleOptionTabWidgetFrameV2 const &) + png_permit_mng_features @ 13547 NONAME ?drawStaticTextItem@QBlitterPaintEngine@@UAEXPAVQStaticTextItem@@@Z @ 13548 NONAME ; void QBlitterPaintEngine::drawStaticTextItem(class QStaticTextItem *) ??0QGlyphs@@QAE@ABV0@@Z @ 13549 NONAME ABSENT ; QGlyphs::QGlyphs(class QGlyphs const &) ?lock@QBlittable@@QAEPAVQImage@@XZ @ 13550 NONAME ; class QImage * QBlittable::lock(void) ?setFontHintingPreference@QTextCharFormat@@QAEXW4HintingPreference@QFont@@@Z @ 13551 NONAME ; void QTextCharFormat::setFontHintingPreference(enum QFont::HintingPreference) - ??4QStyleOptionTabV2@@QAEAAV0@ABV0@@Z @ 13552 NONAME ABSENT ; class QStyleOptionTabV2 & QStyleOptionTabV2::operator=(class QStyleOptionTabV2 const &) + png_process_data @ 13552 NONAME ??_EQInternalMimeData@@UAE@I@Z @ 13553 NONAME ; QInternalMimeData::~QInternalMimeData(unsigned int) - ??4QTextListFormat@@QAEAAV0@ABV0@@Z @ 13554 NONAME ABSENT ; class QTextListFormat & QTextListFormat::operator=(class QTextListFormat const &) - ??_EQPalette@@QAE@I@Z @ 13555 NONAME ABSENT ; QPalette::~QPalette(unsigned int) - ??0QFocusEvent@@QAE@ABV0@@Z @ 13556 NONAME ABSENT ; QFocusEvent::QFocusEvent(class QFocusEvent const &) - ??4QStyleOptionQ3ListViewItem@@QAEAAV0@ABV0@@Z @ 13557 NONAME ABSENT ; class QStyleOptionQ3ListViewItem & QStyleOptionQ3ListViewItem::operator=(class QStyleOptionQ3ListViewItem const &) + png_process_data_skip @ 13554 NONAME + png_progressive_combine_row @ 13555 NONAME + png_read_image @ 13556 NONAME + png_read_info @ 13557 NONAME ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQPointF@@ABVQTextItem@@@Z @ 13558 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QPointF const &, class QTextItem const &) ?trUtf8@QScroller@@SA?AVQString@@PBD0@Z @ 13559 NONAME ABSENT ; class QString QScroller::trUtf8(char const *, char const *) - ??_EQIcon@@QAE@I@Z @ 13560 NONAME ABSENT ; QIcon::~QIcon(unsigned int) + png_read_png @ 13560 NONAME ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 13561 NONAME ABSENT ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) ??9QScrollerProperties@@QBE_NABV0@@Z @ 13562 NONAME ABSENT ; bool QScrollerProperties::operator!=(class QScrollerProperties const &) const - ??0QTextListFormat@@QAE@ABV0@@Z @ 13563 NONAME ABSENT ; QTextListFormat::QTextListFormat(class QTextListFormat const &) + png_read_row @ 13563 NONAME ?drawEllipse@QBlitterPaintEngine@@UAEXABVQRectF@@@Z @ 13564 NONAME ; void QBlitterPaintEngine::drawEllipse(class QRectF const &) - ??0QGuiPlatformPluginInterface@@QAE@XZ @ 13565 NONAME ABSENT ; QGuiPlatformPluginInterface::QGuiPlatformPluginInterface(void) - ??_EQTextLayout@@QAE@I@Z @ 13566 NONAME ABSENT ; QTextLayout::~QTextLayout(unsigned int) - ??0QWheelEvent@@QAE@ABV0@@Z @ 13567 NONAME ABSENT ; QWheelEvent::QWheelEvent(class QWheelEvent const &) + png_read_rows @ 13565 NONAME + png_read_update_info @ 13566 NONAME + png_reset_zstream @ 13567 NONAME ?blittable@QBlittablePixmapData@@QBEPAVQBlittable@@XZ @ 13568 NONAME ; class QBlittable * QBlittablePixmapData::blittable(void) const ?resizeCache@QTextureGlyphCache@@QAEXHH@Z @ 13569 NONAME ; void QTextureGlyphCache::resizeCache(int, int) ??0QScrollerProperties@@QAE@ABV0@@Z @ 13570 NONAME ABSENT ; QScrollerProperties::QScrollerProperties(class QScrollerProperties const &) - ??0QWindowStateChangeEvent@@QAE@ABV0@@Z @ 13571 NONAME ABSENT ; QWindowStateChangeEvent::QWindowStateChangeEvent(class QWindowStateChangeEvent const &) + png_save_int_32 @ 13571 NONAME ?metaObject@QInternalMimeData@@UBEPBUQMetaObject@@XZ @ 13572 NONAME ; struct QMetaObject const * QInternalMimeData::metaObject(void) const ?setContentPos@QScrollPrepareEvent@@QAEXABVQPointF@@@Z @ 13573 NONAME ABSENT ; void QScrollPrepareEvent::setContentPos(class QPointF const &) - ??_EQTextEngine@@QAE@I@Z @ 13574 NONAME ABSENT ; QTextEngine::~QTextEngine(unsigned int) - ??4QStyleOptionTitleBar@@QAEAAV0@ABV0@@Z @ 13575 NONAME ABSENT ; class QStyleOptionTitleBar & QStyleOptionTitleBar::operator=(class QStyleOptionTitleBar const &) - ??4Value@QCss@@QAEAAU01@ABU01@@Z @ 13576 NONAME ABSENT ; struct QCss::Value & QCss::Value::operator=(struct QCss::Value const &) + png_save_uint_16 @ 13574 NONAME + png_save_uint_32 @ 13575 NONAME + png_set_IHDR @ 13576 NONAME ?staticMetaObject@QScroller@@2UQMetaObject@@B @ 13577 NONAME ABSENT ; struct QMetaObject const QScroller::staticMetaObject ?hasFormatHelper@QInternalMimeData@@SA_NABVQString@@PBVQMimeData@@@Z @ 13578 NONAME ; bool QInternalMimeData::hasFormatHelper(class QString const &, class QMimeData const *) ?state@QBlitterPaintEngine@@QAEPAVQPainterState@@XZ @ 13579 NONAME ; class QPainterState * QBlitterPaintEngine::state(void) ?penChanged@QBlitterPaintEngine@@UAEXXZ @ 13580 NONAME ; void QBlitterPaintEngine::penChanged(void) ??0QFileOpenEvent@@QAE@ABVRFile@@@Z @ 13581 NONAME ; QFileOpenEvent::QFileOpenEvent(class RFile const &) ?hasHeightForWidth@QWidgetPrivate@@UBE_NXZ @ 13582 NONAME ; bool QWidgetPrivate::hasHeightForWidth(void) const - ??0QDragLeaveEvent@@QAE@ABV0@@Z @ 13583 NONAME ABSENT ; QDragLeaveEvent::QDragLeaveEvent(class QDragLeaveEvent const &) + png_set_PLTE @ 13583 NONAME ?toImage@QBlittablePixmapData@@UBE?AVQImage@@XZ @ 13584 NONAME ; class QImage QBlittablePixmapData::toImage(void) const ??_EQBlittable@@UAE@I@Z @ 13585 NONAME ; QBlittable::~QBlittable(unsigned int) - ??4QBitmap@@QAEAAV0@ABV0@@Z @ 13586 NONAME ABSENT ; class QBitmap & QBitmap::operator=(class QBitmap const &) + png_set_add_alpha @ 13586 NONAME ??1QInternalMimeData@@UAE@XZ @ 13587 NONAME ; QInternalMimeData::~QInternalMimeData(void) - ??0QItemSelection@@QAE@ABV0@@Z @ 13588 NONAME ABSENT ; QItemSelection::QItemSelection(class QItemSelection const &) + png_set_bKGD @ 13588 NONAME ?qt_addBitmapToPath@@YAXMMPBEHHHPAVQPainterPath@@@Z @ 13589 NONAME ; void qt_addBitmapToPath(float, float, unsigned char const *, int, int, int, class QPainterPath *) ?staticMetaObject@QInternalMimeData@@2UQMetaObject@@B @ 13590 NONAME ; struct QMetaObject const QInternalMimeData::staticMetaObject ?activeScrollers@QScroller@@SA?AV?$QList@PAVQScroller@@@@XZ @ 13591 NONAME ABSENT ; class QList<class QScroller *> QScroller::activeScrollers(void) ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 13592 NONAME ABSENT ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) - ??4QTextFrameFormat@@QAEAAV0@ABV0@@Z @ 13593 NONAME ABSENT ; class QTextFrameFormat & QTextFrameFormat::operator=(class QTextFrameFormat const &) + png_set_background @ 13593 NONAME ?staticMetaObjectExtraData@QStylePlugin@@0UQMetaObjectExtraData@@B @ 13594 NONAME ; struct QMetaObjectExtraData const QStylePlugin::staticMetaObjectExtraData ?staticMetaObjectExtraData@QToolBar@@0UQMetaObjectExtraData@@B @ 13595 NONAME ; struct QMetaObjectExtraData const QToolBar::staticMetaObjectExtraData ?staticMetaObjectExtraData@QTableView@@0UQMetaObjectExtraData@@B @ 13596 NONAME ; struct QMetaObjectExtraData const QTableView::staticMetaObjectExtraData @@ -13969,7 +13969,7 @@ EXPORTS ?cursorMoveStyle@QLineControl@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13968 NONAME ABSENT ; enum QTextCursor::MoveStyle QLineControl::cursorMoveStyle(void) const ?removeColumns@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 13969 NONAME ; bool QIdentityProxyModel::removeColumns(int, int, class QModelIndex const &) ?alignLine@QTextEngine@@QAE?AUQFixed@@ABUQScriptLine@@@Z @ 13970 NONAME ; struct QFixed QTextEngine::alignLine(struct QScriptLine const &) - ?qt_s60_setPartialScreenAutomaticTranslation@@YAX_N@Z @ 13971 NONAME ; void qt_s60_setPartialScreenAutomaticTranslation(bool) + png_set_chunk_cache_max @ 13971 NONAME ?parent@QIdentityProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 13972 NONAME ; class QModelIndex QIdentityProxyModel::parent(class QModelIndex const &) const ?insertColumns@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 13973 NONAME ; bool QIdentityProxyModel::insertColumns(int, int, class QModelIndex const &) ?dropMimeData@QIdentityProxyModel@@UAE_NPBVQMimeData@@W4DropAction@Qt@@HHABVQModelIndex@@@Z @ 13974 NONAME ; bool QIdentityProxyModel::dropMimeData(class QMimeData const *, enum Qt::DropAction, int, int, class QModelIndex const &) @@ -13978,15 +13978,15 @@ EXPORTS ?setSourceModel@QIdentityProxyModel@@UAEXPAVQAbstractItemModel@@@Z @ 13977 NONAME ; void QIdentityProxyModel::setSourceModel(class QAbstractItemModel *) ?getStaticMetaObject@QIdentityProxyModel@@SAABUQMetaObject@@XZ @ 13978 NONAME ; struct QMetaObject const & QIdentityProxyModel::getStaticMetaObject(void) ?index@QIdentityProxyModel@@UBE?AVQModelIndex@@HHABV2@@Z @ 13979 NONAME ; class QModelIndex QIdentityProxyModel::index(int, int, class QModelIndex const &) const - ?setInstantInvalidatePropagation@QGraphicsLayout@@SAX_N@Z @ 13980 NONAME ; void QGraphicsLayout::setInstantInvalidatePropagation(bool) - ?paintingActive@QVolatileImage@@QBE_NXZ @ 13981 NONAME ; bool QVolatileImage::paintingActive(void) const + png_set_background_fixed @ 13980 NONAME + png_access_version_number @ 13981 NONAME ?insertRows@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 13982 NONAME ; bool QIdentityProxyModel::insertRows(int, int, class QModelIndex const &) ?positionAfterVisualMovement@QTextEngine@@QAEHHW4MoveOperation@QTextCursor@@@Z @ 13983 NONAME ; int QTextEngine::positionAfterVisualMovement(int, enum QTextCursor::MoveOperation) ?setCenterRadius@QRadialGradient@@QAEXM@Z @ 13984 NONAME ; void QRadialGradient::setCenterRadius(float) ?leftCursorPosition@QTextLayout@@QBEHH@Z @ 13985 NONAME ; int QTextLayout::leftCursorPosition(int) const ?focalRadius@QRadialGradient@@QBEMXZ @ 13986 NONAME ; float QRadialGradient::focalRadius(void) const ?qt_metacast@QIdentityProxyModel@@UAEPAXPBD@Z @ 13987 NONAME ; void * QIdentityProxyModel::qt_metacast(char const *) - ?qt_draw_decoration_for_glyphs@@YAXPAVQPainter@@PBIPBUQFixedPoint@@HPAVQFontEngine@@ABVQFont@@ABVQTextCharFormat@@@Z @ 13988 NONAME ; void qt_draw_decoration_for_glyphs(class QPainter *, unsigned int const *, struct QFixedPoint const *, int, class QFontEngine *, class QFont const &, class QTextCharFormat const &) + png_get_io_state @ 13988 NONAME ??0QRadialGradient@@QAE@ABVQPointF@@M0M@Z @ 13989 NONAME ; QRadialGradient::QRadialGradient(class QPointF const &, float, class QPointF const &, float) ?centerRadius@QRadialGradient@@QBEMXZ @ 13990 NONAME ; float QRadialGradient::centerRadius(void) const ?qt_isExtendedRadialGradient@@YA_NABVQBrush@@@Z @ 13991 NONAME ; bool qt_isExtendedRadialGradient(class QBrush const &) @@ -13997,7 +13997,7 @@ EXPORTS ?setCursorMoveStyle@QLineEdit@@QAEXW4MoveStyle@QTextCursor@@@Z @ 13996 NONAME ABSENT ; void QLineEdit::setCursorMoveStyle(enum QTextCursor::MoveStyle) ??0QIdentityProxyModel@@IAE@AAVQIdentityProxyModelPrivate@@PAVQObject@@@Z @ 13997 NONAME ; QIdentityProxyModel::QIdentityProxyModel(class QIdentityProxyModelPrivate &, class QObject *) ?lineNumberForTextPosition@QTextEngine@@QAEHH@Z @ 13998 NONAME ; int QTextEngine::lineNumberForTextPosition(int) - ?instantInvalidatePropagation@QGraphicsLayout@@SA_NXZ @ 13999 NONAME ; bool QGraphicsLayout::instantInvalidatePropagation(void) + png_set_benign_errors @ 13999 NONAME ?beginningOfLine@QTextEngine@@AAEHH@Z @ 14000 NONAME ; int QTextEngine::beginningOfLine(int) ??0QIdentityProxyModel@@QAE@PAVQObject@@@Z @ 14001 NONAME ; QIdentityProxyModel::QIdentityProxyModel(class QObject *) ?rightCursorPosition@QTextLayout@@QBEHH@Z @ 14002 NONAME ; int QTextLayout::rightCursorPosition(int) const @@ -14027,18 +14027,22 @@ EXPORTS ?setDefaultCursorMoveStyle@QTextDocument@@QAEXW4CursorMoveStyle@Qt@@@Z @ 14026 NONAME ; void QTextDocument::setDefaultCursorMoveStyle(enum Qt::CursorMoveStyle) ?setCursorMoveStyle@QLineControl@@QAEXW4CursorMoveStyle@Qt@@@Z @ 14027 NONAME ; void QLineControl::setCursorMoveStyle(enum Qt::CursorMoveStyle) ?cursorMoveStyle@QLineEdit@@QBE?AW4CursorMoveStyle@Qt@@XZ @ 14028 NONAME ; enum Qt::CursorMoveStyle QLineEdit::cursorMoveStyle(void) const - ?forceToRaster@QSymbianGraphicsSystemEx@@UAEXPAVQWidget@@@Z @ 14029 NONAME ; void QSymbianGraphicsSystemEx::forceToRaster(class QWidget *) - ?releaseCachedGpuResources@QSymbianGraphicsSystemEx@@UAEXXZ @ 14030 NONAME ; void QSymbianGraphicsSystemEx::releaseCachedGpuResources(void) + png_get_signature @ 14029 NONAME + png_malloc @ 14030 NONAME ?setCursorMoveStyle@QLineEdit@@QAEXW4CursorMoveStyle@Qt@@@Z @ 14031 NONAME ; void QLineEdit::setCursorMoveStyle(enum Qt::CursorMoveStyle) - ?platformExtension@QGraphicsSystem@@UAEPAVQGraphicsSystemEx@@XZ @ 14032 NONAME ; class QGraphicsSystemEx * QGraphicsSystem::platformExtension(void) - ?releaseAllGpuResources@QSymbianGraphicsSystemEx@@UAEXXZ @ 14033 NONAME ; void QSymbianGraphicsSystemEx::releaseAllGpuResources(void) + png_process_data_pause @ 14032 NONAME + png_read_end @ 14033 NONAME ?cursorMoveStyle@QLineControl@@QBE?AW4CursorMoveStyle@Qt@@XZ @ 14034 NONAME ; enum Qt::CursorMoveStyle QLineControl::cursorMoveStyle(void) const ?hasBCM2727@QSymbianGraphicsSystemEx@@UAE_NXZ @ 14035 NONAME ABSENT ; bool QSymbianGraphicsSystemEx::hasBCM2727(void) - ??0QSymbianGraphicsSystemEx@@QAE@XZ @ 14036 NONAME ABSENT ; QSymbianGraphicsSystemEx::QSymbianGraphicsSystemEx(void) - ?hasBCM2727@QSymbianGraphicsSystemEx@@SA_NXZ @ 14037 NONAME ; bool QSymbianGraphicsSystemEx::hasBCM2727(void) + png_get_pixels_per_inch @ 14036 NONAME + png_set_bgr @ 14037 NONAME ?getClusterLength@QTextEngine@@AAEHPAGPBUHB_CharAttributes@@HHHPAH@Z @ 14038 NONAME ; int QTextEngine::getClusterLength(unsigned short *, struct HB_CharAttributes const *, int, int, int, int *) ?positionInLigature@QTextEngine@@QAEHPBUQScriptItem@@HUQFixed@@1H_N@Z @ 14039 NONAME ; int QTextEngine::positionInLigature(struct QScriptItem const *, int, struct QFixed, struct QFixed, int, bool) ?supportsTransformations@QPaintEngineEx@@UBE_NMABVQTransform@@@Z @ 14040 NONAME ; bool QPaintEngineEx::supportsTransformations(float, class QTransform const &) const ?drawStaticTextItem@QPaintEngineEx@@UAEXPAVQStaticTextItem@@@Z @ 14041 NONAME ; void QPaintEngineEx::drawStaticTextItem(class QStaticTextItem *) - ?constImageRef@QVolatileImage@@QBEABVQImage@@XZ @ 14042 NONAME ; class QImage const & QVolatileImage::constImageRef(void) const - ?toVolatileImage@QPixmapData@@UBE?AVQVolatileImage@@XZ @ 14043 NONAME ; class QVolatileImage QPixmapData::toVolatileImage(void) const + png_set_cHRM @ 14042 NONAME + png_set_cHRM_fixed @ 14043 NONAME + ?setStyleName@QFont@@QAEXABVQString@@@Z @ 14044 NONAME ; void QFont::setStyleName(class QString const &) + ?styleName@QFont@@QBE?AVQString@@XZ @ 14045 NONAME ; class QString QFont::styleName(void) const + ?styleName@QFontInfo@@QBE?AVQString@@XZ @ 14046 NONAME ; class QString QFontInfo::styleName(void) const + diff --git a/src/s60installs/bwins/QtNetworku.def b/src/s60installs/bwins/QtNetworku.def index 5bc8403..5d0df03 100644 --- a/src/s60installs/bwins/QtNetworku.def +++ b/src/s60installs/bwins/QtNetworku.def @@ -1242,4 +1242,6 @@ EXPORTS ?networkConfiguration@QNetworkProxyQuery@@QBE?AVQNetworkConfiguration@@XZ @ 1241 NONAME ; class QNetworkConfiguration QNetworkProxyQuery::networkConfiguration(void) const ?setNetworkConfiguration@QNetworkProxyQuery@@QAEXABVQNetworkConfiguration@@@Z @ 1242 NONAME ; void QNetworkProxyQuery::setNetworkConfiguration(class QNetworkConfiguration const &) ??0QNetworkProxyQuery@@QAE@ABVQNetworkConfiguration@@GABVQString@@W4QueryType@0@@Z @ 1243 NONAME ; QNetworkProxyQuery::QNetworkProxyQuery(class QNetworkConfiguration const &, unsigned short, class QString const &, enum QNetworkProxyQuery::QueryType) + ?cleanup@QNetworkConfigurationManagerPrivate@@QAEXXZ @ 1244 NONAME ; void QNetworkConfigurationManagerPrivate::cleanup(void) + ?initialize@QNetworkConfigurationManagerPrivate@@QAEXXZ @ 1245 NONAME ; void QNetworkConfigurationManagerPrivate::initialize(void) diff --git a/src/s60installs/bwins/QtOpenGLu.def b/src/s60installs/bwins/QtOpenGLu.def index 22ba8f3..1a9525d 100644 --- a/src/s60installs/bwins/QtOpenGLu.def +++ b/src/s60installs/bwins/QtOpenGLu.def @@ -722,9 +722,9 @@ EXPORTS ?releaseNativeImageHandle@QGLPixmapData@@QAEXXZ @ 721 NONAME ; void QGLPixmapData::releaseNativeImageHandle(void) ?createFromNativeImageHandleProvider@QGLPixmapData@@QAEXXZ @ 722 NONAME ; void QGLPixmapData::createFromNativeImageHandleProvider(void) ?initFromNativeImageHandle@QGLPixmapData@@QAE_NPAXABVQString@@@Z @ 723 NONAME ; bool QGLPixmapData::initFromNativeImageHandle(void *, class QString const &) - ?glVertexAttrib3f@QGLFunctions@@QAEXIMMM@Z @ 724 NONAME ; void QGLFunctions::glVertexAttrib3f(unsigned int, float, float, float) - ?glVertexAttrib1fv@QGLFunctions@@QAEXIPBM@Z @ 725 NONAME ; void QGLFunctions::glVertexAttrib1fv(unsigned int, float const *) - ?glIsBuffer@QGLFunctions@@QAEEI@Z @ 726 NONAME ; unsigned char QGLFunctions::glIsBuffer(unsigned int) + ?platformExtension@QGLGraphicsSystem@@UAEPAVQGraphicsSystemEx@@XZ @ 724 NONAME ; class QGraphicsSystemEx * QGLGraphicsSystem::platformExtension(void) + ?releaseCachedGpuResources@QGLGraphicsSystem@@UAEXXZ @ 725 NONAME ; void QGLGraphicsSystem::releaseCachedGpuResources(void) + ?toVolatileImage@QGLPixmapData@@UBE?AVQVolatileImage@@XZ @ 726 NONAME ; class QVolatileImage QGLPixmapData::toVolatileImage(void) const ?glGetActiveAttrib@QGLFunctions@@QAEXIIHPAH0PAIPAD@Z @ 727 NONAME ; void QGLFunctions::glGetActiveAttrib(unsigned int, unsigned int, int, int *, int *, unsigned int *, char *) ?glBindFramebuffer@QGLFunctions@@QAEXII@Z @ 728 NONAME ; void QGLFunctions::glBindFramebuffer(unsigned int, unsigned int) ?glBufferData@QGLFunctions@@QAEXIHPBXI@Z @ 729 NONAME ; void QGLFunctions::glBufferData(unsigned int, int, void const *, unsigned int) @@ -874,6 +874,6 @@ EXPORTS ?staticMetaObjectExtraData@QGraphicsShaderEffect@@0UQMetaObjectExtraData@@B @ 873 NONAME ; struct QMetaObjectExtraData const QGraphicsShaderEffect::staticMetaObjectExtraData ?staticMetaObjectExtraData@QGLEngineShaderManager@@0UQMetaObjectExtraData@@B @ 874 NONAME ; struct QMetaObjectExtraData const QGLEngineShaderManager::staticMetaObjectExtraData ?qt_static_metacall@QGLShaderProgram@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 875 NONAME ; void QGLShaderProgram::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) - ?platformExtension@QGLGraphicsSystem@@UAEPAVQGraphicsSystemEx@@XZ @ 876 NONAME ; class QGraphicsSystemEx * QGLGraphicsSystem::platformExtension(void) - ?releaseCachedGpuResources@QGLGraphicsSystem@@UAEXXZ @ 877 NONAME ; void QGLGraphicsSystem::releaseCachedGpuResources(void) - ?toVolatileImage@QGLPixmapData@@UBE?AVQVolatileImage@@XZ @ 878 NONAME ; class QVolatileImage QGLPixmapData::toVolatileImage(void) const + ?glVertexAttrib3f@QGLFunctions@@QAEXIMMM@Z @ 876 NONAME ; void QGLFunctions::glVertexAttrib3f(unsigned int, float, float, float) + ?glVertexAttrib1fv@QGLFunctions@@QAEXIPBM@Z @ 877 NONAME ; void QGLFunctions::glVertexAttrib1fv(unsigned int, float const *) + ?glIsBuffer@QGLFunctions@@QAEEI@Z @ 878 NONAME ; unsigned char QGLFunctions::glIsBuffer(unsigned int) diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def index 811f863..afd7143 100644 --- a/src/s60installs/bwins/QtOpenVGu.def +++ b/src/s60installs/bwins/QtOpenVGu.def @@ -184,6 +184,6 @@ EXPORTS ?createFromNativeImageHandleProvider@QVGPixmapData@@QAEXXZ @ 183 NONAME ; void QVGPixmapData::createFromNativeImageHandleProvider(void) ?releaseNativeImageHandle@QVGPixmapData@@QAEXXZ @ 184 NONAME ; void QVGPixmapData::releaseNativeImageHandle(void) ?forceToImage@QVGPixmapData@@IAEX_N@Z @ 185 NONAME ; void QVGPixmapData::forceToImage(bool) - ?features@QVGWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 186 NONAME ; class QFlags<enum QWindowSurface::WindowSurfaceFeature> QVGWindowSurface::features(void) const + ?toVolatileImage@QVGPixmapData@@UBE?AVQVolatileImage@@XZ @ 186 NONAME ; class QVolatileImage QVGPixmapData::toVolatileImage(void) const ?supportsTransformations@QVGPaintEngine@@UBE_NMABVQTransform@@@Z @ 187 NONAME ; bool QVGPaintEngine::supportsTransformations(float, class QTransform const &) const - ?toVolatileImage@QVGPixmapData@@UBE?AVQVolatileImage@@XZ @ 188 NONAME ; class QVolatileImage QVGPixmapData::toVolatileImage(void) const + ?features@QVGWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 188 NONAME ; class QFlags<enum QWindowSurface::WindowSurfaceFeature> QVGWindowSurface::features(void) const diff --git a/src/s60installs/bwins/QtTestu.def b/src/s60installs/bwins/QtTestu.def index 6b7cb9a..486984a 100644 --- a/src/s60installs/bwins/QtTestu.def +++ b/src/s60installs/bwins/QtTestu.def @@ -77,95 +77,97 @@ EXPORTS ?staticMetaObject@QTestEventLoop@@2UQMetaObject@@B @ 76 NONAME ; struct QMetaObject const QTestEventLoop::staticMetaObject ?setBenchmarkResult@QTest@@YAXMW4QBenchmarkMetric@1@@Z @ 77 NONAME ; void QTest::setBenchmarkResult(float, enum QTest::QBenchmarkMetric) ?endBenchmarkMeasurement@QTest@@YA_KXZ @ 78 NONAME ; unsigned long long QTest::endBenchmarkMeasurement(void) - ?addXFail@QTestLog@@SAXPBD0H@Z @ 79 NONAME ; void QTestLog::addXFail(char const *, char const *, int) - ?leaveTestFunction@QTestLog@@SAXXZ @ 80 NONAME ; void QTestLog::leaveTestFunction(void) - ?setCurrentTestFunction@QTestResult@@SAXPBD@Z @ 81 NONAME ; void QTestResult::setCurrentTestFunction(char const *) - ?currentTestObjectName@QTestResult@@SAPBDXZ @ 82 NONAME ; char const * QTestResult::currentTestObjectName(void) - ?allDataPassed@QTestResult@@SA_NXZ @ 83 NONAME ; bool QTestResult::allDataPassed(void) - ?redirectOutput@QTestLog@@SAXPBD@Z @ 84 NONAME ; void QTestLog::redirectOutput(char const *) - ?testData@QTestTable@@QBEPAVQTestData@@H@Z @ 85 NONAME ; class QTestData * QTestTable::testData(int) const - ?isEmpty@QTestTable@@QBE_NXZ @ 86 NONAME ; bool QTestTable::isEmpty(void) const - ?logMode@QTestLog@@SA?AW4LogMode@1@XZ @ 87 NONAME ; enum QTestLog::LogMode QTestLog::logMode(void) - ?dataCount@QTestTable@@QBEHXZ @ 88 NONAME ; int QTestTable::dataCount(void) const - ?addFailure@QTestResult@@SAXPBD0H@Z @ 89 NONAME ; void QTestResult::addFailure(char const *, char const *, int) - ?setCurrentTestData@QTestResult@@SAXPAVQTestData@@@Z @ 90 NONAME ; void QTestResult::setCurrentTestData(class QTestData *) - ?setMode@QBenchmarkGlobalData@@QAEXW4Mode@1@@Z @ 91 NONAME ; void QBenchmarkGlobalData::setMode(enum QBenchmarkGlobalData::Mode) - ??1QTestTable@@QAE@XZ @ 92 NONAME ; QTestTable::~QTestTable(void) - ?setLogMode@QTestLog@@SAXW4LogMode@1@@Z @ 93 NONAME ; void QTestLog::setLogMode(enum QTestLog::LogMode) - ?addBenchmarkResult@QTestLog@@SAXABVQBenchmarkResult@@@Z @ 94 NONAME ; void QTestLog::addBenchmarkResult(class QBenchmarkResult const &) - ?setVerboseLevel@QTestLog@@SAXH@Z @ 95 NONAME ; void QTestLog::setVerboseLevel(int) - ??0QBenchmarkGlobalData@@QAE@XZ @ 96 NONAME ; QBenchmarkGlobalData::QBenchmarkGlobalData(void) - ?stopLogging@QTestLog@@SAXXZ @ 97 NONAME ; void QTestLog::stopLogging(void) - ?setCurrentGlobalTestData@QTestResult@@SAXPAVQTestData@@@Z @ 98 NONAME ; void QTestResult::setCurrentGlobalTestData(class QTestData *) - ?currentTestLocation@QTestResult@@SA?AW4TestLocation@1@XZ @ 99 NONAME ; enum QTestResult::TestLocation QTestResult::currentTestLocation(void) - ?currentTestFunction@QTestResult@@SAPBDXZ @ 100 NONAME ; char const * QTestResult::currentTestFunction(void) - ?dataTag@QTestTable@@QBEPBDH@Z @ 101 NONAME ; char const * QTestTable::dataTag(int) const - ?expectFail@QTestResult@@SA_NPBD0W4TestFailMode@QTest@@0H@Z @ 102 NONAME ; bool QTestResult::expectFail(char const *, char const *, enum QTest::TestFailMode, char const *, int) - ?currentDataTag@QTestResult@@SAPBDXZ @ 103 NONAME ; char const * QTestResult::currentDataTag(void) - ??0QTestTable@@QAE@XZ @ 104 NONAME ; QTestTable::QTestTable(void) - ?setFlushMode@QTestLog@@SAXW4FlushMode@1@@Z @ 105 NONAME ; void QTestLog::setFlushMode(enum QTestLog::FlushMode) - ?setCurrentTestObject@QTestResult@@SAXPBD@Z @ 106 NONAME ; void QTestResult::setCurrentTestObject(char const *) - ?beginDataRun@QBenchmarkTestMethodData@@QAEXXZ @ 107 NONAME ; void QBenchmarkTestMethodData::beginDataRun(void) - ?qtest_qParseArgs@QTest@@YAXHQAPAD_N@Z @ 108 NONAME ; void QTest::qtest_qParseArgs(int, char * * const, bool) - ?enterTestFunction@QTestLog@@SAXPBD@Z @ 109 NONAME ; void QTestLog::enterTestFunction(char const *) - ?clearGlobalTestTable@QTestTable@@SAXXZ @ 110 NONAME ; void QTestTable::clearGlobalTestTable(void) - ?addPass@QTestLog@@SAXPBD@Z @ 111 NONAME ; void QTestLog::addPass(char const *) - ?printUnhandledIgnoreMessages@QTestLog@@SAXXZ @ 112 NONAME ; void QTestLog::printUnhandledIgnoreMessages(void) - ?addColumn@QTestTable@@QAEXHPBD@Z @ 113 NONAME ; void QTestTable::addColumn(int, char const *) - ?setSkipCurrentTest@QTestResult@@SAX_N@Z @ 114 NONAME ; void QTestResult::setSkipCurrentTest(bool) - ?currentTestFailed@QTestResult@@SA_NXZ @ 115 NONAME ; bool QTestResult::currentTestFailed(void) - ?createMeasurer@QBenchmarkGlobalData@@QAEPAVQBenchmarkMeasurerBase@@XZ @ 116 NONAME ; class QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer(void) - ?startLogging@QTestLog@@SAXXZ @ 117 NONAME ; void QTestLog::startLogging(void) - ?printAvailableFunctions@QTest@@3_NA @ 118 NONAME ; bool QTest::printAvailableFunctions - ?testFailed@QTestResult@@SA_NXZ @ 119 NONAME ; bool QTestResult::testFailed(void) - ?current@QBenchmarkTestMethodData@@2PAV1@A @ 120 NONAME ; class QBenchmarkTestMethodData * QBenchmarkTestMethodData::current - ?currentGlobalDataTag@QTestResult@@SAPBDXZ @ 121 NONAME ; char const * QTestResult::currentGlobalDataTag(void) - ?adjustIterationCount@QBenchmarkTestMethodData@@QAEHH@Z @ 122 NONAME ; int QBenchmarkTestMethodData::adjustIterationCount(int) - ?current@QBenchmarkGlobalData@@2PAV1@A @ 123 NONAME ; class QBenchmarkGlobalData * QBenchmarkGlobalData::current - ?warn@QTestLog@@SAXPBD@Z @ 124 NONAME ; void QTestLog::warn(char const *) - ?testFunctions@QTest@@3VQStringList@@A @ 125 NONAME ; class QStringList QTest::testFunctions - ?elementTypeId@QTestTable@@QBEHH@Z @ 126 NONAME ; int QTestTable::elementTypeId(int) const - ?ignoreMessage@QTestResult@@SAXW4QtMsgType@@PBD@Z @ 127 NONAME ; void QTestResult::ignoreMessage(enum QtMsgType, char const *) - ?globalTestTable@QTestTable@@SAPAV1@XZ @ 128 NONAME ; class QTestTable * QTestTable::globalTestTable(void) - ??0QBenchmarkTestMethodData@@QAE@XZ @ 129 NONAME ; QBenchmarkTestMethodData::QBenchmarkTestMethodData(void) - ?currentTestTable@QTestTable@@SAPAV1@XZ @ 130 NONAME ; class QTestTable * QTestTable::currentTestTable(void) - ?addFail@QTestLog@@SAXPBD0H@Z @ 131 NONAME ; void QTestLog::addFail(char const *, char const *, int) - ?endDataRun@QBenchmarkTestMethodData@@QAEXXZ @ 132 NONAME ; void QBenchmarkTestMethodData::endDataRun(void) - ?resultsAccepted@QBenchmarkTestMethodData@@QBE_NXZ @ 133 NONAME ; bool QBenchmarkTestMethodData::resultsAccepted(void) const - ?verify@QTestResult@@SA_N_NPBD11H@Z @ 134 NONAME ; bool QTestResult::verify(bool, char const *, char const *, char const *, int) - ??1QBenchmarkTestMethodData@@QAE@XZ @ 135 NONAME ; QBenchmarkTestMethodData::~QBenchmarkTestMethodData(void) - ?addIgnoreMessage@QTestLog@@SAXW4QtMsgType@@PBD@Z @ 136 NONAME ; void QTestLog::addIgnoreMessage(enum QtMsgType, char const *) - ?newData@QTestTable@@QAEPAVQTestData@@PBD@Z @ 137 NONAME ; class QTestData * QTestTable::newData(char const *) - ?reset@QTestResult@@SAXXZ @ 138 NONAME ; void QTestResult::reset(void) - ?currentTestData@QTestResult@@SAPAVQTestData@@XZ @ 139 NONAME ; class QTestData * QTestResult::currentTestData(void) - ?skipCurrentTest@QTestResult@@SA_NXZ @ 140 NONAME ; bool QTestResult::skipCurrentTest(void) - ?outputFileName@QTestLog@@SAPBDXZ @ 141 NONAME ; char const * QTestLog::outputFileName(void) - ?adjustMedianIterationCount@QBenchmarkGlobalData@@QAEHXZ @ 142 NONAME ; int QBenchmarkGlobalData::adjustMedianIterationCount(void) - ??0QTestLog@@AAE@XZ @ 143 NONAME ; QTestLog::QTestLog(void) - ?compare@QTestResult@@SA_N_NPBDPAD2111H@Z @ 144 NONAME ; bool QTestResult::compare(bool, char const *, char *, char *, char const *, char const *, char const *, int) - ?elementCount@QTestTable@@QBEHXZ @ 145 NONAME ; int QTestTable::elementCount(void) const - ?setResult@QBenchmarkTestMethodData@@QAEXMW4QBenchmarkMetric@QTest@@_N@Z @ 146 NONAME ; void QBenchmarkTestMethodData::setResult(float, enum QTest::QBenchmarkMetric, bool) - ?finishedCurrentTestFunction@QTestResult@@SAXXZ @ 147 NONAME ; void QTestResult::finishedCurrentTestFunction(void) - ?setCurrentTestLocation@QTestResult@@SAXW4TestLocation@1@@Z @ 148 NONAME ; void QTestResult::setCurrentTestLocation(enum QTestResult::TestLocation) - ?currentGlobalTestData@QTestResult@@SAPAVQTestData@@XZ @ 149 NONAME ; class QTestData * QTestResult::currentGlobalTestData(void) - ?mode@QBenchmarkGlobalData@@QBE?AW4Mode@1@XZ @ 150 NONAME ; enum QBenchmarkGlobalData::Mode QBenchmarkGlobalData::mode(void) const - ?setMaxWarnings@QTestLog@@SAXH@Z @ 151 NONAME ; void QTestLog::setMaxWarnings(int) - ?failCount@QTestResult@@SAHXZ @ 152 NONAME ; int QTestResult::failCount(void) + ?addBenchmarkResult@QTestLog@@SAXABVQBenchmarkResult@@@Z @ 79 NONAME ; void QTestLog::addBenchmarkResult(class QBenchmarkResult const &) + ?currentTestLocation@QTestResult@@SA?AW4TestLocation@1@XZ @ 80 NONAME ; enum QTestResult::TestLocation QTestResult::currentTestLocation(void) + ?setCurrentTestLocation@QTestResult@@SAXW4TestLocation@1@@Z @ 81 NONAME ; void QTestResult::setCurrentTestLocation(enum QTestResult::TestLocation) + ?testFailed@QTestResult@@SA_NXZ @ 82 NONAME ; bool QTestResult::testFailed(void) + ?setVerboseLevel@QTestLog@@SAXH@Z @ 83 NONAME ; void QTestLog::setVerboseLevel(int) + ?setCurrentTestObject@QTestResult@@SAXPBD@Z @ 84 NONAME ; void QTestResult::setCurrentTestObject(char const *) + ?isEmpty@QTestTable@@QBE_NXZ @ 85 NONAME ; bool QTestTable::isEmpty(void) const + ?reset@QTestResult@@SAXXZ @ 86 NONAME ; void QTestResult::reset(void) + ?info@QTestLog@@SAXPBD0H@Z @ 87 NONAME ; void QTestLog::info(char const *, char const *, int) + ?adjustMedianIterationCount@QBenchmarkGlobalData@@QAEHXZ @ 88 NONAME ; int QBenchmarkGlobalData::adjustMedianIterationCount(void) + ?addColumn@QTestTable@@QAEXHPBD@Z @ 89 NONAME ; void QTestTable::addColumn(int, char const *) + ?setMode@QBenchmarkGlobalData@@QAEXW4Mode@1@@Z @ 90 NONAME ; void QBenchmarkGlobalData::setMode(enum QBenchmarkGlobalData::Mode) + ?addFailure@QTestResult@@SAXPBD0H@Z @ 91 NONAME ; void QTestResult::addFailure(char const *, char const *, int) + ?indexOf@QTestTable@@QBEHPBD@Z @ 92 NONAME ; int QTestTable::indexOf(char const *) const + ?warn@QTestLog@@SAXPBD@Z @ 93 NONAME ; void QTestLog::warn(char const *) + ?currentTestData@QTestResult@@SAPAVQTestData@@XZ @ 94 NONAME ; class QTestData * QTestResult::currentTestData(void) + ?endDataRun@QBenchmarkTestMethodData@@QAEXXZ @ 95 NONAME ; void QBenchmarkTestMethodData::endDataRun(void) + ?globalTestTable@QTestTable@@SAPAV1@XZ @ 96 NONAME ; class QTestTable * QTestTable::globalTestTable(void) + ?elementCount@QTestTable@@QBEHXZ @ 97 NONAME ; int QTestTable::elementCount(void) const + ??0QTestLog@@AAE@XZ @ 98 NONAME ; QTestLog::QTestLog(void) + ?allDataPassed@QTestResult@@SA_NXZ @ 99 NONAME ; bool QTestResult::allDataPassed(void) + ??0QBenchmarkTestMethodData@@QAE@XZ @ 100 NONAME ; QBenchmarkTestMethodData::QBenchmarkTestMethodData(void) + ?qtest_qParseArgs@QTest@@YAXHQAPAD_N@Z @ 101 NONAME ; void QTest::qtest_qParseArgs(int, char * * const, bool) + ?unhandledIgnoreMessages@QTestLog@@SAHXZ @ 102 NONAME ; int QTestLog::unhandledIgnoreMessages(void) + ?setCurrentTestFunction@QTestResult@@SAXPBD@Z @ 103 NONAME ; void QTestResult::setCurrentTestFunction(char const *) + ?enterTestFunction@QTestLog@@SAXPBD@Z @ 104 NONAME ; void QTestLog::enterTestFunction(char const *) + ?testFunctions@QTest@@3VQStringList@@A @ 105 NONAME ; class QStringList QTest::testFunctions + ?addSkip@QTestResult@@SAXPBDW4SkipMode@QTest@@0H@Z @ 106 NONAME ; void QTestResult::addSkip(char const *, enum QTest::SkipMode, char const *, int) + ?currentGlobalDataTag@QTestResult@@SAPBDXZ @ 107 NONAME ; char const * QTestResult::currentGlobalDataTag(void) + ?stopLogging@QTestLog@@SAXXZ @ 108 NONAME ; void QTestLog::stopLogging(void) + ??_EQTestData@@QAE@I@Z @ 109 NONAME ABSENT ; QTestData::~QTestData(unsigned int) + ??1QTestLog@@AAE@XZ @ 110 NONAME ; QTestLog::~QTestLog(void) + ?skipCount@QTestResult@@SAHXZ @ 111 NONAME ; int QTestResult::skipCount(void) + ?setCurrentGlobalTestData@QTestResult@@SAXPAVQTestData@@@Z @ 112 NONAME ; void QTestResult::setCurrentGlobalTestData(class QTestData *) + ?elementTypeId@QTestTable@@QBEHH@Z @ 113 NONAME ; int QTestTable::elementTypeId(int) const + ?dataTag@QTestTable@@QBEPBDH@Z @ 114 NONAME ; char const * QTestTable::dataTag(int) const + ?dataCount@QTestTable@@QBEHXZ @ 115 NONAME ; int QTestTable::dataCount(void) const + ?printUnhandledIgnoreMessages@QTestLog@@SAXXZ @ 116 NONAME ; void QTestLog::printUnhandledIgnoreMessages(void) + ??1QBenchmarkTestMethodData@@QAE@XZ @ 117 NONAME ; QBenchmarkTestMethodData::~QBenchmarkTestMethodData(void) + ??1QTestTable@@QAE@XZ @ 118 NONAME ; QTestTable::~QTestTable(void) + ?current@QBenchmarkGlobalData@@2PAV1@A @ 119 NONAME ; class QBenchmarkGlobalData * QBenchmarkGlobalData::current + ?setFlushMode@QTestLog@@SAXW4FlushMode@1@@Z @ 120 NONAME ; void QTestLog::setFlushMode(enum QTestLog::FlushMode) + ?ignoreMessage@QTestResult@@SAXW4QtMsgType@@PBD@Z @ 121 NONAME ; void QTestResult::ignoreMessage(enum QtMsgType, char const *) + ?failCount@QTestResult@@SAHXZ @ 122 NONAME ; int QTestResult::failCount(void) + ?mode@QBenchmarkGlobalData@@QBE?AW4Mode@1@XZ @ 123 NONAME ; enum QBenchmarkGlobalData::Mode QBenchmarkGlobalData::mode(void) const + ?addSkip@QTestLog@@SAXPBDW4SkipMode@QTest@@0H@Z @ 124 NONAME ; void QTestLog::addSkip(char const *, enum QTest::SkipMode, char const *, int) + ?outputFileName@QTestLog@@SAPBDXZ @ 125 NONAME ; char const * QTestLog::outputFileName(void) + ?expectFail@QTestResult@@SA_NPBD0W4TestFailMode@QTest@@0H@Z @ 126 NONAME ; bool QTestResult::expectFail(char const *, char const *, enum QTest::TestFailMode, char const *, int) + ?passCount@QTestResult@@SAHXZ @ 127 NONAME ; int QTestResult::passCount(void) + ?logMode@QTestLog@@SA?AW4LogMode@1@XZ @ 128 NONAME ; enum QTestLog::LogMode QTestLog::logMode(void) + ?skipCurrentTest@QTestResult@@SA_NXZ @ 129 NONAME ; bool QTestResult::skipCurrentTest(void) + ?addXPass@QTestLog@@SAXPBD0H@Z @ 130 NONAME ; void QTestLog::addXPass(char const *, char const *, int) + ?testTags@QTest@@3VQStringList@@A @ 131 NONAME ; class QStringList QTest::testTags + ?isBenchmark@QBenchmarkTestMethodData@@QBE_NXZ @ 132 NONAME ; bool QBenchmarkTestMethodData::isBenchmark(void) const + ?adjustIterationCount@QBenchmarkTestMethodData@@QAEHH@Z @ 133 NONAME ; int QBenchmarkTestMethodData::adjustIterationCount(int) + ??1QBenchmarkGlobalData@@QAE@XZ @ 134 NONAME ; QBenchmarkGlobalData::~QBenchmarkGlobalData(void) + ?printAvailableFunctions@QTest@@3_NA @ 135 NONAME ; bool QTest::printAvailableFunctions + ?testData@QTestTable@@QBEPAVQTestData@@H@Z @ 136 NONAME ; class QTestData * QTestTable::testData(int) const + ?setCurrentTestData@QTestResult@@SAXPAVQTestData@@@Z @ 137 NONAME ; void QTestResult::setCurrentTestData(class QTestData *) + ?compare@QTestResult@@SA_N_NPBD1H@Z @ 138 NONAME ; bool QTestResult::compare(bool, char const *, char const *, int) + ?currentTestFailed@QTestResult@@SA_NXZ @ 139 NONAME ; bool QTestResult::currentTestFailed(void) + ?compare@QTestResult@@SA_N_NPBDPAD2111H@Z @ 140 NONAME ; bool QTestResult::compare(bool, char const *, char *, char *, char const *, char const *, char const *, int) + ?addXFail@QTestLog@@SAXPBD0H@Z @ 141 NONAME ; void QTestLog::addXFail(char const *, char const *, int) + ??_EQTestTable@@QAE@I@Z @ 142 NONAME ABSENT ; QTestTable::~QTestTable(unsigned int) + ??0QBenchmarkGlobalData@@QAE@XZ @ 143 NONAME ; QBenchmarkGlobalData::QBenchmarkGlobalData(void) + ?beginDataRun@QBenchmarkTestMethodData@@QAEXXZ @ 144 NONAME ; void QBenchmarkTestMethodData::beginDataRun(void) + ?resultsAccepted@QBenchmarkTestMethodData@@QBE_NXZ @ 145 NONAME ; bool QBenchmarkTestMethodData::resultsAccepted(void) const + ?addIgnoreMessage@QTestLog@@SAXW4QtMsgType@@PBD@Z @ 146 NONAME ; void QTestLog::addIgnoreMessage(enum QtMsgType, char const *) + ?startLogging@QTestLog@@SAXXZ @ 147 NONAME ; void QTestLog::startLogging(void) + ?currentDataTag@QTestResult@@SAPBDXZ @ 148 NONAME ; char const * QTestResult::currentDataTag(void) + ?redirectOutput@QTestLog@@SAXPBD@Z @ 149 NONAME ; void QTestLog::redirectOutput(char const *) + ?currentTestObjectName@QTestResult@@SAPBDXZ @ 150 NONAME ; char const * QTestResult::currentTestObjectName(void) + ?newData@QTestTable@@QAEPAVQTestData@@PBD@Z @ 151 NONAME ; class QTestData * QTestTable::newData(char const *) + ?addPass@QTestLog@@SAXPBD@Z @ 152 NONAME ; void QTestLog::addPass(char const *) ?verboseLevel@QTestLog@@SAHXZ @ 153 NONAME ; int QTestLog::verboseLevel(void) - ?passCount@QTestResult@@SAHXZ @ 154 NONAME ; int QTestResult::passCount(void) - ?indexOf@QTestTable@@QBEHPBD@Z @ 155 NONAME ; int QTestTable::indexOf(char const *) const - ?compare@QTestResult@@SA_N_NPBD1H@Z @ 156 NONAME ; bool QTestResult::compare(bool, char const *, char const *, int) - ?startLogging@QTestLog@@SAXI@Z @ 157 NONAME ; void QTestLog::startLogging(unsigned int) - ?addSkip@QTestLog@@SAXPBDW4SkipMode@QTest@@0H@Z @ 158 NONAME ; void QTestLog::addSkip(char const *, enum QTest::SkipMode, char const *, int) - ?testTags@QTest@@3VQStringList@@A @ 159 NONAME ; class QStringList QTest::testTags - ??1QTestLog@@AAE@XZ @ 160 NONAME ; QTestLog::~QTestLog(void) - ?unhandledIgnoreMessages@QTestLog@@SAHXZ @ 161 NONAME ; int QTestLog::unhandledIgnoreMessages(void) - ?info@QTestLog@@SAXPBD0H@Z @ 162 NONAME ; void QTestLog::info(char const *, char const *, int) - ??1QBenchmarkGlobalData@@QAE@XZ @ 163 NONAME ; QBenchmarkGlobalData::~QBenchmarkGlobalData(void) - ?isBenchmark@QBenchmarkTestMethodData@@QBE_NXZ @ 164 NONAME ; bool QBenchmarkTestMethodData::isBenchmark(void) const - ?addSkip@QTestResult@@SAXPBDW4SkipMode@QTest@@0H@Z @ 165 NONAME ; void QTestResult::addSkip(char const *, enum QTest::SkipMode, char const *, int) - ?skipCount@QTestResult@@SAHXZ @ 166 NONAME ; int QTestResult::skipCount(void) - ?addXPass@QTestLog@@SAXPBD0H@Z @ 167 NONAME ; void QTestLog::addXPass(char const *, char const *, int) - ?qt_static_metacall@QTestEventLoop@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 168 NONAME ; void QTestEventLoop::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) - ?staticMetaObjectExtraData@QTestEventLoop@@0UQMetaObjectExtraData@@B @ 169 NONAME ; struct QMetaObjectExtraData const QTestEventLoop::staticMetaObjectExtraData + ?createMeasurer@QBenchmarkGlobalData@@QAEPAVQBenchmarkMeasurerBase@@XZ @ 154 NONAME ; class QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer(void) + ?currentGlobalTestData@QTestResult@@SAPAVQTestData@@XZ @ 155 NONAME ; class QTestData * QTestResult::currentGlobalTestData(void) + ?setSkipCurrentTest@QTestResult@@SAX_N@Z @ 156 NONAME ; void QTestResult::setSkipCurrentTest(bool) + ?setResult@QBenchmarkTestMethodData@@QAEXMW4QBenchmarkMetric@QTest@@_N@Z @ 157 NONAME ; void QBenchmarkTestMethodData::setResult(float, enum QTest::QBenchmarkMetric, bool) + ?verify@QTestResult@@SA_N_NPBD11H@Z @ 158 NONAME ; bool QTestResult::verify(bool, char const *, char const *, char const *, int) + ?leaveTestFunction@QTestLog@@SAXXZ @ 159 NONAME ; void QTestLog::leaveTestFunction(void) + ?finishedCurrentTestFunction@QTestResult@@SAXXZ @ 160 NONAME ; void QTestResult::finishedCurrentTestFunction(void) + ?currentTestTable@QTestTable@@SAPAV1@XZ @ 161 NONAME ; class QTestTable * QTestTable::currentTestTable(void) + ?currentTestFunction@QTestResult@@SAPBDXZ @ 162 NONAME ; char const * QTestResult::currentTestFunction(void) + ?setLogMode@QTestLog@@SAXW4LogMode@1@@Z @ 163 NONAME ; void QTestLog::setLogMode(enum QTestLog::LogMode) + ?clearGlobalTestTable@QTestTable@@SAXXZ @ 164 NONAME ; void QTestTable::clearGlobalTestTable(void) + ?addFail@QTestLog@@SAXPBD0H@Z @ 165 NONAME ; void QTestLog::addFail(char const *, char const *, int) + ??0QTestTable@@QAE@XZ @ 166 NONAME ; QTestTable::QTestTable(void) + ?setMaxWarnings@QTestLog@@SAXH@Z @ 167 NONAME ; void QTestLog::setMaxWarnings(int) + ?current@QBenchmarkTestMethodData@@2PAV1@A @ 168 NONAME ; class QBenchmarkTestMethodData * QBenchmarkTestMethodData::current + ?qt_static_metacall@QTestEventLoop@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 169 NONAME ; void QTestEventLoop::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ?startLogging@QTestLog@@SAXI@Z @ 170 NONAME ; void QTestLog::startLogging(unsigned int) + ?staticMetaObjectExtraData@QTestEventLoop@@0UQMetaObjectExtraData@@B @ 171 NONAME ; struct QMetaObjectExtraData const QTestEventLoop::staticMetaObjectExtraData diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index c754d91..f0bf9fc 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -4162,4 +4162,5 @@ EXPORTS _ZNK4QUrl14topLevelDomainEv @ 4161 NONAME _ZNK5QUuid11toByteArrayEv @ 4162 NONAME _ZNK5QUuid9toRfc4122Ev @ 4163 NONAME + _ZN18QAbstractItemModel17resetInternalDataEv @ 4164 NONAME diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index b40ac38..85030cd 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -2007,4 +2007,5 @@ EXPORTS _ZNK28QDeclarativeInspectorService10metaObjectEv @ 2006 NONAME _ZTI28QDeclarativeInspectorService @ 2007 NONAME _ZTV28QDeclarativeInspectorService @ 2008 NONAME + _ZN28QDeclarativeInspectorService12updateStatusEv @ 2009 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 95a5dbd..01b3772 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12182,24 +12182,24 @@ EXPORTS _ZNK14QVolatileImage9constBitsEv @ 12181 NONAME _ZN15QGraphicsSystem22releaseCachedResourcesEv @ 12182 NONAME ABSENT _Z32qt_s60_setPartialScreenInputModeb @ 12183 NONAME - _Z18qt_addBitmapToPathffPKhiiiP12QPainterPath @ 12184 NONAME - _Z22qt_fontdata_from_indexi @ 12185 NONAME - _Z32qGamma_correct_back_to_linear_csP6QImage @ 12186 NONAME - _ZN10QBlittable4lockEv @ 12187 NONAME - _ZN10QBlittable6unlockEv @ 12188 NONAME - _ZN10QBlittableC2ERK5QSize6QFlagsINS_10CapabilityEE @ 12189 NONAME - _ZN10QBlittableD0Ev @ 12190 NONAME - _ZN10QBlittableD1Ev @ 12191 NONAME - _ZN10QBlittableD2Ev @ 12192 NONAME - _ZN11QFontEngine16alphaMapForGlyphEj6QFixed @ 12193 NONAME - _ZN11QFontEngine16alphaMapForGlyphEj6QFixedRK10QTransform @ 12194 NONAME - _ZN11QFontEngine19alphaRGBMapForGlyphEj6QFixediRK10QTransform @ 12195 NONAME - _ZN12QInputDialog7getItemEP7QWidgetRK7QStringS4_RK11QStringListibPb6QFlagsIN2Qt10WindowTypeEES9_INSA_15InputMethodHintEE @ 12196 NONAME - _ZN12QInputDialog7getTextEP7QWidgetRK7QStringS4_N9QLineEdit8EchoModeES4_Pb6QFlagsIN2Qt10WindowTypeEES8_INS9_15InputMethodHintEE @ 12197 NONAME - _Z27qt_isExtendedRadialGradientRK6QBrush @ 12198 NONAME - _Z28qt_painterPathFromVectorPathRK11QVectorPath @ 12199 NONAME - _Z29qt_draw_decoration_for_glyphsP8QPainterPKjPK11QFixedPointiP11QFontEngineRK5QFontRK15QTextCharFormat @ 12200 NONAME - _Z43qt_s60_setPartialScreenAutomaticTranslationb @ 12201 NONAME + _Z29qt_draw_decoration_for_glyphsP8QPainterPKjPK11QFixedPointiP11QFontEngineRK5QFontRK15QTextCharFormat @ 12184 NONAME + _ZNK14QVolatileImage14paintingActiveEv @ 12185 NONAME + _ZN11QTextEngine17leadingSpaceWidthERK11QScriptLine @ 12186 NONAME + _ZN15QGraphicsLayout28instantInvalidatePropagationEv @ 12187 NONAME + _ZN15QGraphicsLayout31setInstantInvalidatePropagationEb @ 12188 NONAME + _ZN15QGraphicsSystem17platformExtensionEv @ 12189 NONAME + _ZN24QSymbianGraphicsSystemEx10hasBCM2727Ev @ 12190 NONAME + _ZN24QSymbianGraphicsSystemEx13forceToRasterEP7QWidget @ 12191 NONAME + _ZN24QSymbianGraphicsSystemEx22releaseAllGpuResourcesEv @ 12192 NONAME + _ZN24QSymbianGraphicsSystemEx25releaseCachedGpuResourcesEv @ 12193 NONAME + _ZTI17QGraphicsSystemEx @ 12194 NONAME + _ZTI24QSymbianGraphicsSystemEx @ 12195 NONAME + _ZTV24QSymbianGraphicsSystemEx @ 12196 NONAME + _ZNK11QPixmapData15toVolatileImageEv @ 12197 NONAME + _ZNK14QVolatileImage13constImageRefEv @ 12198 NONAME + _Z43qt_s60_setPartialScreenAutomaticTranslationb @ 12199 NONAME + _Z18qt_addBitmapToPathffPKhiiiP12QPainterPath @ 12200 NONAME + _Z28qt_painterPathFromVectorPathRK11QVectorPath @ 12201 NONAME _ZN10QBoxLayout18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 12202 NONAME _ZN10QBoxLayout25staticMetaObjectExtraDataE @ 12203 NONAME DATA 8 _ZN10QClipboard18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 12204 NONAME @@ -12282,7 +12282,7 @@ EXPORTS _ZN11QTapGesture25staticMetaObjectExtraDataE @ 12281 NONAME DATA 8 _ZN11QTextEngine15beginningOfLineEi @ 12282 NONAME _ZN11QTextEngine16offsetInLigatureEPK11QScriptItemiii @ 12283 NONAME - _ZN11QTextEngine17leadingSpaceWidthERK11QScriptLine @ 12284 NONAME + _Z32qGamma_correct_back_to_linear_csP6QImage @ 12284 NONAME _ZN11QTextEngine22insertionPointsForLineEiR7QVectorIiE @ 12285 NONAME _ZN11QTextEngine25lineNumberForTextPositionEi @ 12286 NONAME _ZN11QTextEngine27positionAfterVisualMovementEiN11QTextCursor13MoveOperationE @ 12287 NONAME @@ -12387,8 +12387,8 @@ EXPORTS _ZN15QGraphicsAnchor25staticMetaObjectExtraDataE @ 12386 NONAME DATA 8 _ZN15QGraphicsEffect18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 12387 NONAME _ZN15QGraphicsEffect25staticMetaObjectExtraDataE @ 12388 NONAME DATA 8 - _ZN15QGraphicsLayout28instantInvalidatePropagationEv @ 12389 NONAME - _ZN15QGraphicsLayout31setInstantInvalidatePropagationEb @ 12390 NONAME + _ZN10QBlittable4lockEv @ 12389 NONAME + _ZN10QBlittable6unlockEv @ 12390 NONAME _ZN15QGraphicsObject18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 12391 NONAME _ZN15QGraphicsObject25staticMetaObjectExtraDataE @ 12392 NONAME DATA 8 _ZN15QGraphicsWidget18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 12393 NONAME @@ -12684,7 +12684,7 @@ EXPORTS _ZNK13QFontMetricsF10inFontUcs4Ej @ 12683 NONAME _ZNK13QTextDocument22defaultCursorMoveStyleEv @ 12684 NONAME _ZNK14QFileOpenEvent8openFileER5QFile6QFlagsIN9QIODevice12OpenModeFlagEE @ 12685 NONAME - _ZNK14QVolatileImage14paintingActiveEv @ 12686 NONAME + _Z22qt_fontdata_from_indexi @ 12686 NONAME _ZNK14QWidgetPrivate17hasHeightForWidthEv @ 12687 NONAME _ZNK14QWindowSurface8featuresEv @ 12688 NONAME _ZNK15QRadialGradient11focalRadiusEv @ 12689 NONAME @@ -12740,18 +12740,22 @@ EXPORTS _Zls6QDebugPK13QSymbianEvent @ 12739 NONAME _ZN11QTextLayout18setCursorMoveStyleEN2Qt15CursorMoveStyleE @ 12740 NONAME _ZN13QTextDocument25setDefaultCursorMoveStyleEN2Qt15CursorMoveStyleE @ 12741 NONAME - _ZN15QGraphicsSystem17platformExtensionEv @ 12742 NONAME - _ZN24QSymbianGraphicsSystemEx10hasBCM2727Ev @ 12743 NONAME - _ZN24QSymbianGraphicsSystemEx13forceToRasterEP7QWidget @ 12744 NONAME - _ZN24QSymbianGraphicsSystemEx22releaseAllGpuResourcesEv @ 12745 NONAME - _ZN24QSymbianGraphicsSystemEx25releaseCachedGpuResourcesEv @ 12746 NONAME + _ZN10QBlittableC2ERK5QSize6QFlagsINS_10CapabilityEE @ 12742 NONAME + _ZN10QBlittableD0Ev @ 12743 NONAME + _ZN10QBlittableD1Ev @ 12744 NONAME + _ZN10QBlittableD2Ev @ 12745 NONAME + _ZN11QFontEngine16alphaMapForGlyphEj6QFixed @ 12746 NONAME _ZN9QLineEdit18setCursorMoveStyleEN2Qt15CursorMoveStyleE @ 12747 NONAME - _ZTI17QGraphicsSystemEx @ 12748 NONAME - _ZTI24QSymbianGraphicsSystemEx @ 12749 NONAME - _ZTV24QSymbianGraphicsSystemEx @ 12750 NONAME + _ZN11QFontEngine16alphaMapForGlyphEj6QFixedRK10QTransform @ 12748 NONAME + _ZN11QFontEngine19alphaRGBMapForGlyphEj6QFixediRK10QTransform @ 12749 NONAME + _ZN12QInputDialog7getItemEP7QWidgetRK7QStringS4_RK11QStringListibPb6QFlagsIN2Qt10WindowTypeEES9_INSA_15InputMethodHintEE @ 12750 NONAME _ZN11QTextEngine16getClusterLengthEPtPK17HB_CharAttributesiiiPi @ 12751 NONAME _ZN11QTextEngine18positionInLigatureEPK11QScriptItemi6QFixedS3_ib @ 12752 NONAME _ZN14QPaintEngineEx18drawStaticTextItemEP15QStaticTextItem @ 12753 NONAME _ZNK14QPaintEngineEx23supportsTransformationsEfRK10QTransform @ 12754 NONAME - _ZNK11QPixmapData15toVolatileImageEv @ 12755 NONAME - _ZNK14QVolatileImage13constImageRefEv @ 12756 NONAME + _ZN12QInputDialog7getTextEP7QWidgetRK7QStringS4_N9QLineEdit8EchoModeES4_Pb6QFlagsIN2Qt10WindowTypeEES8_INS9_15InputMethodHintEE @ 12755 NONAME + _Z27qt_isExtendedRadialGradientRK6QBrush @ 12756 NONAME + _ZN5QFont12setStyleNameERK7QString @ 12757 NONAME + _ZNK5QFont9styleNameEv @ 12758 NONAME + _ZNK9QFontInfo9styleNameEv @ 12759 NONAME + diff --git a/src/s60installs/eabi/QtNetworku.def b/src/s60installs/eabi/QtNetworku.def index 8e29c2d..32c1b97 100644 --- a/src/s60installs/eabi/QtNetworku.def +++ b/src/s60installs/eabi/QtNetworku.def @@ -1268,4 +1268,6 @@ EXPORTS _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationRK7QStringiS5_NS_9QueryTypeE @ 1267 NONAME _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationtRK7QStringNS_9QueryTypeE @ 1268 NONAME _ZNK18QNetworkProxyQuery20networkConfigurationEv @ 1269 NONAME + _ZN35QNetworkConfigurationManagerPrivate10initializeEv @ 1270 NONAME + _ZN35QNetworkConfigurationManagerPrivate7cleanupEv @ 1271 NONAME diff --git a/src/s60installs/eabi/QtOpenGLu.def b/src/s60installs/eabi/QtOpenGLu.def index 695829c..ad33f9c 100644 --- a/src/s60installs/eabi/QtOpenGLu.def +++ b/src/s60installs/eabi/QtOpenGLu.def @@ -724,9 +724,9 @@ EXPORTS _ZN13QGLPixmapData24releaseNativeImageHandleEv @ 723 NONAME _ZN13QGLPixmapData25initFromNativeImageHandleEPvRK7QString @ 724 NONAME _ZN13QGLPixmapData35createFromNativeImageHandleProviderEv @ 725 NONAME - _Z28qt_resolve_buffer_extensionsP10QGLContext @ 726 NONAME - _ZN12QGLFunctions21initializeGLFunctionsEPK10QGLContext @ 727 NONAME - _ZN12QGLFunctionsC1EPK10QGLContext @ 728 NONAME + _ZN17QGLGraphicsSystem17platformExtensionEv @ 726 NONAME + _ZN17QGLGraphicsSystem25releaseCachedGpuResourcesEv @ 727 NONAME + _ZThn4_N17QGLGraphicsSystem25releaseCachedGpuResourcesEv @ 728 NONAME _ZN12QGLFunctionsC1Ev @ 729 NONAME _ZN12QGLFunctionsC2EPK10QGLContext @ 730 NONAME _ZN12QGLFunctionsC2Ev @ 731 NONAME @@ -780,7 +780,7 @@ EXPORTS _ZN9QGLShader25staticMetaObjectExtraDataE @ 779 NONAME DATA 8 _ZN9QGLWidget18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 780 NONAME _ZN9QGLWidget25staticMetaObjectExtraDataE @ 781 NONAME DATA 8 - _ZN17QGLGraphicsSystem17platformExtensionEv @ 782 NONAME - _ZN17QGLGraphicsSystem25releaseCachedGpuResourcesEv @ 783 NONAME - _ZThn4_N17QGLGraphicsSystem25releaseCachedGpuResourcesEv @ 784 NONAME + _Z28qt_resolve_buffer_extensionsP10QGLContext @ 782 NONAME + _ZN12QGLFunctions21initializeGLFunctionsEPK10QGLContext @ 783 NONAME + _ZN12QGLFunctionsC1EPK10QGLContext @ 784 NONAME diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def index e2cdbcf..7e1d7fa 100644 --- a/src/s60installs/eabi/QtOpenVGu.def +++ b/src/s60installs/eabi/QtOpenVGu.def @@ -214,5 +214,5 @@ EXPORTS _ZN13QVGPixmapData25initFromNativeImageHandleEPvRK7QString @ 213 NONAME _ZN13QVGPixmapData35createFromNativeImageHandleProviderEv @ 214 NONAME _ZN13QVGPixmapData12forceToImageEb @ 215 NONAME - _ZNK16QVGWindowSurface8featuresEv @ 216 NONAME - _ZNK13QVGPixmapData15toVolatileImageEv @ 217 NONAME + _ZNK13QVGPixmapData15toVolatileImageEv @ 216 NONAME + _ZNK16QVGWindowSurface8featuresEv @ 217 NONAME diff --git a/src/s60installs/eabi/QtTestu.def b/src/s60installs/eabi/QtTestu.def index 3a4cd73..ce98aa6 100644 --- a/src/s60installs/eabi/QtTestu.def +++ b/src/s60installs/eabi/QtTestu.def @@ -132,38 +132,38 @@ EXPORTS _ZN8QTestLog10setLogModeENS_7LogModeE @ 131 NONAME _ZN8QTestLog11stopLoggingEv @ 132 NONAME _ZN8QTestLog12setFlushModeENS_9FlushModeE @ 133 NONAME - _ZN8QTestLog12startLoggingEj @ 134 NONAME - _ZN8QTestLog12startLoggingEv @ 135 NONAME - _ZN8QTestLog12verboseLevelEv @ 136 NONAME - _ZN8QTestLog14outputFileNameEv @ 137 NONAME - _ZN8QTestLog14redirectOutputEPKc @ 138 NONAME - _ZN8QTestLog14setMaxWarningsEi @ 139 NONAME - _ZN8QTestLog15setVerboseLevelEi @ 140 NONAME - _ZN8QTestLog16addIgnoreMessageE9QtMsgTypePKc @ 141 NONAME - _ZN8QTestLog17enterTestFunctionEPKc @ 142 NONAME - _ZN8QTestLog17leaveTestFunctionEv @ 143 NONAME - _ZN8QTestLog18addBenchmarkResultERK16QBenchmarkResult @ 144 NONAME - _ZN8QTestLog23unhandledIgnoreMessagesEv @ 145 NONAME - _ZN8QTestLog28printUnhandledIgnoreMessagesEv @ 146 NONAME - _ZN8QTestLog4infoEPKcS1_i @ 147 NONAME - _ZN8QTestLog4warnEPKc @ 148 NONAME - _ZN8QTestLog7addFailEPKcS1_i @ 149 NONAME - _ZN8QTestLog7addPassEPKc @ 150 NONAME - _ZN8QTestLog7addSkipEPKcN5QTest8SkipModeES1_i @ 151 NONAME - _ZN8QTestLog7logModeEv @ 152 NONAME - _ZN8QTestLog8addXFailEPKcS1_i @ 153 NONAME - _ZN8QTestLog8addXPassEPKcS1_i @ 154 NONAME - _ZN8QTestLogC1Ev @ 155 NONAME - _ZN8QTestLogC2Ev @ 156 NONAME - _ZN8QTestLogD1Ev @ 157 NONAME - _ZN8QTestLogD2Ev @ 158 NONAME - _ZNK10QTestTable12elementCountEv @ 159 NONAME - _ZNK10QTestTable13elementTypeIdEi @ 160 NONAME - _ZNK10QTestTable7dataTagEi @ 161 NONAME - _ZNK10QTestTable7indexOfEPKc @ 162 NONAME - _ZNK10QTestTable7isEmptyEv @ 163 NONAME - _ZNK10QTestTable8testDataEi @ 164 NONAME - _ZNK10QTestTable9dataCountEv @ 165 NONAME + _ZN8QTestLog12startLoggingEv @ 134 NONAME + _ZN8QTestLog12verboseLevelEv @ 135 NONAME + _ZN8QTestLog14outputFileNameEv @ 136 NONAME + _ZN8QTestLog14redirectOutputEPKc @ 137 NONAME + _ZN8QTestLog14setMaxWarningsEi @ 138 NONAME + _ZN8QTestLog15setVerboseLevelEi @ 139 NONAME + _ZN8QTestLog16addIgnoreMessageE9QtMsgTypePKc @ 140 NONAME + _ZN8QTestLog17enterTestFunctionEPKc @ 141 NONAME + _ZN8QTestLog17leaveTestFunctionEv @ 142 NONAME + _ZN8QTestLog18addBenchmarkResultERK16QBenchmarkResult @ 143 NONAME + _ZN8QTestLog23unhandledIgnoreMessagesEv @ 144 NONAME + _ZN8QTestLog28printUnhandledIgnoreMessagesEv @ 145 NONAME + _ZN8QTestLog4infoEPKcS1_i @ 146 NONAME + _ZN8QTestLog4warnEPKc @ 147 NONAME + _ZN8QTestLog7addFailEPKcS1_i @ 148 NONAME + _ZN8QTestLog7addPassEPKc @ 149 NONAME + _ZN8QTestLog7addSkipEPKcN5QTest8SkipModeES1_i @ 150 NONAME + _ZN8QTestLog7logModeEv @ 151 NONAME + _ZN8QTestLog8addXFailEPKcS1_i @ 152 NONAME + _ZN8QTestLog8addXPassEPKcS1_i @ 153 NONAME + _ZN8QTestLogC1Ev @ 154 NONAME + _ZN8QTestLogC2Ev @ 155 NONAME + _ZN8QTestLogD1Ev @ 156 NONAME + _ZN8QTestLogD2Ev @ 157 NONAME + _ZNK10QTestTable12elementCountEv @ 158 NONAME + _ZNK10QTestTable13elementTypeIdEi @ 159 NONAME + _ZNK10QTestTable7dataTagEi @ 160 NONAME + _ZNK10QTestTable7indexOfEPKc @ 161 NONAME + _ZNK10QTestTable7isEmptyEv @ 162 NONAME + _ZNK10QTestTable8testDataEi @ 163 NONAME + _ZNK10QTestTable9dataCountEv @ 164 NONAME + _ZN8QTestLog12startLoggingEj @ 165 NONAME _ZN14QTestEventLoop18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 166 NONAME _ZN14QTestEventLoop25staticMetaObjectExtraDataE @ 167 NONAME DATA 8 diff --git a/tools/runonphone/codasignalhandler.cpp b/tools/runonphone/codasignalhandler.cpp new file mode 100644 index 0000000..0d086b5 --- /dev/null +++ b/tools/runonphone/codasignalhandler.cpp @@ -0,0 +1,579 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QDebug> +#include <QDir> +#include <QFile> +#include <QObject> +#include <QTimer> +#include "codasignalhandler.h" + +static const quint64 DEFAULT_CHUNK_SIZE = 40000; + +class CodaSignalHandlerPrivate +{ + friend class CodaSignalHandler; +public: + CodaSignalHandlerPrivate(); + ~CodaSignalHandlerPrivate(); +private: + SymbianUtils::CodaDevicePtr codaDevice; + QEventLoop *eventLoop; + QTextStream out; + QTextStream err; + int loglevel; + int timeout; + int result; + CodaAction action; + QString copySrcFileName; + QString copyDstFileName; + QString dlSrcFileName; + QString dlDstFileName; + QString appFileName; + QString commandLineArgs; + QString serialPortName; + QString appID; + QByteArray remoteFileHandle; + QScopedPointer<QFile> localFile; + QScopedPointer<QFile> remoteFile; + quint64 putChunkSize; + quint64 putLastChunkSize; + quint64 remoteBytesLeft; + quint64 remoteFileSize; + bool putWriteOk; + bool connected; + bool debugSessionControl; +}; + +CodaSignalHandlerPrivate::CodaSignalHandlerPrivate() + : eventLoop(0), + out(stdout), + err(stderr), + loglevel(0), + timeout(0), + result(0), + action(ActionPingOnly), + putChunkSize(DEFAULT_CHUNK_SIZE), + putLastChunkSize(0), + remoteBytesLeft(0), + remoteFileSize(0), + putWriteOk(false), + connected(false), + debugSessionControl(false) +{ +} + +CodaSignalHandlerPrivate::~CodaSignalHandlerPrivate() +{ + delete eventLoop; + out.flush(); + err.flush(); +} + +void CodaSignalHandler::error(const QString &errorMessage) +{ + reportError(tr("CODA error: %1").arg(errorMessage)); +} + +void CodaSignalHandler::logMessage(const QString &logMessage) +{ + reportMessage(tr("CODA log: %1").arg(logMessage)); +} + +void CodaSignalHandler::serialPong(const QString &codaVersion) +{ + reportMessage(tr("CODA version: %1").arg(codaVersion)); +} + +void CodaSignalHandler::tcfEvent(const Coda::CodaEvent &event) +{ + reportMessage(tr("CODA event: Type: %1 Message: %2").arg(event.type()).arg(event.toString())); + + switch (event.type()) { + case Coda::CodaEvent::LocatorHello: + handleConnected(event); + break; + case Coda::CodaEvent::ProcessExitedEvent: + handleAppExited(event); + break; + default: + reportMessage(tr("CODA unhandled event: Type: %1 Message: %2").arg(event.type()).arg(event.toString())); + break; + } +} + +void CodaSignalHandler::terminate() +{ + if (d->codaDevice) { + disconnect(d->codaDevice.data(), 0, this, 0); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(d->codaDevice); + } +} + +void CodaSignalHandler::finished() +{ + if (d->eventLoop) + d->eventLoop->exit(); +} + +void CodaSignalHandler::timeout() +{ + reportError(tr("Unable to connect to CODA device. Operation timed out.")); +} + +int CodaSignalHandler::run() +{ + d->codaDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(d->serialPortName); + bool ok = d->codaDevice && d->codaDevice->device()->isOpen(); + if (!ok) { + QString deviceError = "No such port"; + if (d->codaDevice) + deviceError = d->codaDevice->device()->errorString(); + reportError(tr("Could not open serial device: ").arg(deviceError)); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(d->codaDevice); + return 1; + } + + if (d->loglevel > 1) { + d->codaDevice->setVerbose(1); + } + + connect(d->codaDevice.data(), SIGNAL(error(const QString &)), this, SLOT(error(const QString &))); + connect(d->codaDevice.data(), SIGNAL(logMessage(const QString &)), this, SLOT(logMessage(const QString &))); + connect(d->codaDevice.data(), SIGNAL(serialPong(const QString &)), this, SLOT(serialPong(const QString &))); + connect(d->codaDevice.data(), SIGNAL(tcfEvent(const Coda::CodaEvent &)), this, SLOT(tcfEvent(const Coda::CodaEvent &))); + connect(this, SIGNAL(done()), this, SLOT(finished())); + + d->codaDevice->sendSerialPing(false); + if (d->timeout > 0) + QTimer::singleShot(d->timeout, this, SLOT(timeout())); + d->eventLoop = new QEventLoop(); + d->eventLoop->exec(); + int result = d->result; + reportMessage(tr("Done.")); + disconnect(d->codaDevice.data(), 0, this, 0); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(d->codaDevice); + + QCoreApplication::quit(); + return result; +} + +void CodaSignalHandler::setActionType(CodaAction action) +{ + d->action = CodaAction(d->action | action); +} + +void CodaSignalHandler::setAppFileName(const QString &fileName) +{ + d->appFileName = fileName; +} + +void CodaSignalHandler::setCodaDevice(SymbianUtils::CodaDevicePtr &codaDevice) +{ + d->codaDevice = codaDevice; +} + +void CodaSignalHandler::setCommandLineArgs(const QString &args) +{ + d->commandLineArgs = args; +} + +void CodaSignalHandler::setCopyFileName(const QString &srcName, const QString &dstName) +{ + d->copySrcFileName = srcName; + d->copyDstFileName = dstName; +} + +void CodaSignalHandler::setDownloadFileName(const QString &srcName, const QString &dstName) +{ + d->dlSrcFileName = srcName; + d->dlDstFileName = dstName; +} + +void CodaSignalHandler::setLogLevel(int level) +{ + d->loglevel = level; +} + +void CodaSignalHandler::setSerialPortName(const QString &serialPortName) +{ + d->serialPortName = serialPortName; +} + +void CodaSignalHandler::setTimeout(const int msec) +{ + d->timeout = msec; +} + +void CodaSignalHandler::closeFile() +{ + d->remoteFile.reset(); + if (!d->codaDevice) { + emit done(); + return; + } + + d->codaDevice->sendFileSystemCloseCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleFileSystemClose), + d->remoteFileHandle); +} + +void CodaSignalHandler::handleConnected(const Coda::CodaEvent &event) +{ + if (d->connected) + return; + + const Coda::CodaLocatorHelloEvent &hEvent = static_cast<const Coda::CodaLocatorHelloEvent &>(event); + QStringList services = hEvent.services(); + if (services.contains("DebugSessionControl")) { + d->debugSessionControl = true; + } + d->connected = true; + handleActions(); +} + +void CodaSignalHandler::handleActions() +{ + if (d->action & ActionCopy) { + initFileSending(); + } else if (d->action & ActionInstall) { + initFileInstallation(); + } else if (d->action & ActionRun) { + initAppRunning(); + } else if (d->action & ActionDownload) { + initFileDownloading(); + } else { + emit done(); + } +} + +void CodaSignalHandler::handleAppExited(const Coda::CodaEvent &event) +{ + const Coda::CodaProcessExitedEvent &pEvent = static_cast<const Coda::CodaProcessExitedEvent &>(event); + QString id = pEvent.idString(); + if (!id.compare(d->appID, Qt::CaseInsensitive)) { + d->codaDevice->sendDebugSessionControlSessionEndCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleDebugSessionControlEnd)); + d->action = static_cast<CodaAction>(d->action & ~ActionRun); + handleActions(); + } +} + +void CodaSignalHandler::handleAppRunning(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply) { + reportMessage(tr("Running...")); + + Coda::JsonValue value = result.values.at(0); + readAppId(value); + } else { + reportError(tr("Launch failed: %1").arg(result.toString())); + } +} + +void CodaSignalHandler::handleDebugSessionControlEnd(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply) { + // nothing to do + } +} + +void CodaSignalHandler::handleDebugSessionControlStart(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply) { + d->codaDevice->sendRunProcessCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleAppRunning), + d->appFileName.toAscii(), + d->commandLineArgs.split(' ')); + reportMessage(tr("Launching %1...").arg(QFileInfo(d->appFileName).fileName())); + } else { + reportError(tr("Failed to start CODA debug session control.")); + } +} + +void CodaSignalHandler::handleFileSystemClose(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply) { + reportMessage(tr("File closed.")); + if (d->action & ActionCopy) { + d->action = static_cast<CodaAction>(d->action & ~ActionCopy); + } else if (d->action & ActionDownload) { + d->action = static_cast<CodaAction>(d->action & ~ActionDownload); + } + handleActions(); + } else { + reportError(tr("Failed to close the remote file: %1").arg(result.toString())); + } +} + +void CodaSignalHandler::handleFileSystemOpen(const Coda::CodaCommandResult &result) +{ + if (result.type != Coda::CodaCommandResult::SuccessReply) { + reportError(tr("Could not open remote file: %1").arg(result.errorString())); + return; + } + + if (result.values.size() < 1 || result.values.at(0).data().isEmpty()) { + reportError(tr("Internal error: No filehandle obtained")); + return; + } + + if (d->action & ActionCopy) { + d->remoteFileHandle = result.values.at(0).data(); + d->remoteFile.reset(new QFile(d->copySrcFileName)); + if (!d->remoteFile->open(QIODevice::ReadOnly)) { // Should not fail, was checked before + reportError(tr("Could not open local file %1").arg(d->copySrcFileName)); + return; + } + putSendNextChunk(); + } else if (d->action & ActionDownload) { + d->remoteFileHandle = result.values.at(0).data(); + d->localFile.reset(new QFile(d->dlDstFileName)); + // remove any existing file with the same name + if (d->localFile->exists() && !d->localFile->remove()) { + reportError(tr("Could not create host file: %1 due to error: %2").arg(d->localFile->fileName(), d->localFile->errorString())); + return; + } + // open local file in write-only mode + if (!d->localFile->open(QFile::WriteOnly)) { + reportError(tr("Could not open host file for writing: %1 due to error: %2").arg(d->localFile->fileName(), d->localFile->errorString())); + return; + } + d->codaDevice->sendFileSystemFstatCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleFileSystemStart), + d->remoteFileHandle); + } +} + +void CodaSignalHandler::handleFileSystemRead(const Coda::CodaCommandResult &result) +{ + if (result.type != Coda::CodaCommandResult::SuccessReply || result.values.size() != 2) { + reportError(tr("Could not read remote file: %1").arg(result.errorString())); + return; + } + + QByteArray data = QByteArray::fromBase64(result.values.at(0).data()); + bool eof = result.values.at(1).toVariant().toBool(); + qint64 written = d->localFile->write(data); + if (written < 0) { + reportError(tr("Could not write data to host file: %1 due to error: %2").arg(d->localFile->fileName(), d->localFile->errorString())); + return; + } + + d->remoteBytesLeft -= written; + if (!eof && d->remoteBytesLeft > 0) { + readNextChunk(); + } + else { + d->localFile->flush(); + d->localFile->close(); + closeFile(); + } +} + +void CodaSignalHandler::handleFileSystemStart(const Coda::CodaCommandResult &result) +{ + if (result.type != Coda::CodaCommandResult::SuccessReply) { + reportError(tr("Could not open remote file: %1").arg(result.errorString())); + return; + } + + if (result.values.size() < 1 || result.values.at(0).children().isEmpty()) { + reportError(tr("Could not get file attributes")); + return; + } + + Coda::JsonValue val = result.values.at(0).findChild("Size"); + d->remoteFileSize = val.isValid() ? val.data().toLong() : -1L; + if (d->remoteFileSize < 0) { + reportError(tr("Could not get file size")); + return; + } + + d->remoteBytesLeft = d->remoteFileSize; + readNextChunk(); +} + +void CodaSignalHandler::handleFileSystemWrite(const Coda::CodaCommandResult &result) +{ + // Close remote file even if copy fails + d->putWriteOk = result; + if (!d->putWriteOk) { + QString fileName = QFileInfo(d->copyDstFileName).fileName(); + reportError(tr("Could not write to file %1 on device: %2").arg(fileName).arg(result.errorString())); + } + + if (!d->putWriteOk || d->putLastChunkSize < d->putChunkSize) { + closeFile(); + } else { + putSendNextChunk(); + } +} + +void CodaSignalHandler::handleSymbianInstall(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply) { + reportMessage(tr("Installation has finished.")); + d->action = static_cast<CodaAction>(d->action & ~ActionInstall); + handleActions(); + } else { + reportError(tr("Installation failed: %1").arg(result.errorString())); + } +} + +void CodaSignalHandler::initAppRunning() +{ + if (!d->codaDevice || d->appFileName.isEmpty()) { + emit done(); + return; + } + + if (!d->debugSessionControl) { + reportError(tr("CODA DebugSessionControl service not found, please update to CODA v4.0.23 or later.")); + } + + d->codaDevice->sendDebugSessionControlSessionStartCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleDebugSessionControlStart)); +} + +void CodaSignalHandler::initFileDownloading() +{ + if (!d->codaDevice || d->dlSrcFileName.isEmpty()) { + emit done(); + return; + } + + d->codaDevice->sendFileSystemOpenCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleFileSystemOpen), + d->dlSrcFileName.toAscii(), Coda::CodaDevice::FileSystem_TCF_O_READ); + reportMessage(tr("Downloading %1...").arg(QFileInfo(d->dlSrcFileName).fileName())); +} + +void CodaSignalHandler::initFileInstallation() +{ + if (!d->codaDevice || d->copyDstFileName.isEmpty()) { + emit done(); + return; + } + + QString installationDrive = "C"; + d->codaDevice->sendSymbianInstallSilentInstallCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleSymbianInstall), + d->copyDstFileName.toAscii(), + installationDrive.toAscii()); + reportMessage(tr("Installing package \"%1\" on drive %2...").arg(QFileInfo(d->copyDstFileName).fileName(), installationDrive)); +} + +void CodaSignalHandler::initFileSending() +{ + if (!d->codaDevice || d->copySrcFileName.isEmpty()) { + emit done(); + return; + } + + const unsigned flags = + Coda::CodaDevice::FileSystem_TCF_O_WRITE + |Coda::CodaDevice::FileSystem_TCF_O_CREAT + |Coda::CodaDevice::FileSystem_TCF_O_TRUNC; + d->putWriteOk = false; + d->codaDevice->sendFileSystemOpenCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleFileSystemOpen), + d->copyDstFileName.toAscii(), flags); + reportMessage(tr("Copying %1...").arg(QFileInfo(d->copyDstFileName).fileName())); +} + +void CodaSignalHandler::putSendNextChunk() +{ + if (!d->codaDevice || !d->remoteFile) { + emit done(); + return; + } + + // Read and send off next chunk + const quint64 pos = d->remoteFile->pos(); + const QByteArray data = d->remoteFile->read(d->putChunkSize); + if (data.isEmpty()) { + d->putWriteOk = true; + closeFile(); + } else { + d->putLastChunkSize = data.size(); + d->codaDevice->sendFileSystemWriteCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleFileSystemWrite), + d->remoteFileHandle, data, unsigned(pos)); + } +} + +void CodaSignalHandler::readNextChunk() +{ + const quint64 pos = d->remoteFileSize - d->remoteBytesLeft; + const quint64 size = qMin(d->remoteBytesLeft, DEFAULT_CHUNK_SIZE); + d->codaDevice->sendFileSystemReadCommand(Coda::CodaCallback(this, &CodaSignalHandler::handleFileSystemRead), + d->remoteFileHandle, pos, size); +} + +void CodaSignalHandler::readAppId(Coda::JsonValue value) +{ + if (value.isObject()) { + Coda::JsonValue idValue = value.findChild("ID"); + if (idValue.isString()) { + d->appID = idValue.data(); + return; + } + } + + reportError(tr("Could not get process ID of %1.").arg(QFileInfo(d->appFileName).fileName())); +} + +void CodaSignalHandler::reportError(const QString &message) +{ + d->err << message << endl; + d->result = 1; + emit done(); +} + +void CodaSignalHandler::reportMessage(const QString &message) +{ + if (d->loglevel > 0) + d->out << message << endl; +} + +CodaSignalHandler::CodaSignalHandler() + : d(new CodaSignalHandlerPrivate()) +{ +} + +CodaSignalHandler::~CodaSignalHandler() +{ + delete d; +} + diff --git a/tools/runonphone/codasignalhandler.h b/tools/runonphone/codasignalhandler.h new file mode 100644 index 0000000..a978bfa --- /dev/null +++ b/tools/runonphone/codasignalhandler.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CODASIGNALHANDLER_H +#define CODASIGNALHANDLER_H + +#include "symbianutils/codamessage.h" +#include "symbianutils/symbiandevicemanager.h" + +#include "symbianutils/codadevice.h" + +enum CodaAction { + ActionPingOnly = 0x0, + ActionCopy = 0x1, + ActionInstall = 0x2, + ActionCopyInstall = ActionCopy | ActionInstall, + ActionRun = 0x4, + ActionDownload = 0x8, + ActionCopyRun = ActionCopy | ActionRun, + ActionInstallRun = ActionInstall | ActionRun, + ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun +}; + +class CodaSignalHandlerPrivate; +class CodaSignalHandler : public QObject +{ + Q_OBJECT +public slots: + void error(const QString &errorMessage); + void logMessage(const QString &logMessage); + void serialPong(const QString &codaVersion); + void tcfEvent(const Coda::CodaEvent &event); + void terminate(); +private slots: + void finished(); + void timeout(); +signals: + void done(); +public: + CodaSignalHandler(); + ~CodaSignalHandler(); + void init(); + int run(); + void setActionType(CodaAction action); + void setAppFileName(const QString &fileName); + void setCodaDevice(SymbianUtils::CodaDevicePtr &codeDevice); + void setCommandLineArgs(const QString &args); + void setCopyFileName(const QString &srcName, const QString &dstName); + void setDownloadFileName(const QString &srcName, const QString &dstName); + void setLogLevel(int level); + void setSerialPortName(const QString &serialPortName); + void setTimeout(const int msec); +private: + void closeFile(); + void handleConnected(const Coda::CodaEvent &event); + void handleActions(); + void handleAppExited(const Coda::CodaEvent &event); + void handleAppRunning(const Coda::CodaCommandResult &result); + void handleDebugSessionControlEnd(const Coda::CodaCommandResult &result); + void handleDebugSessionControlStart(const Coda::CodaCommandResult &result); + void handleFileSystemClose(const Coda::CodaCommandResult &result); + void handleFileSystemOpen(const Coda::CodaCommandResult &result); + void handleFileSystemRead(const Coda::CodaCommandResult &result); + void handleFileSystemStart(const Coda::CodaCommandResult &result); + void handleFileSystemWrite(const Coda::CodaCommandResult &result); + void handleSymbianInstall(const Coda::CodaCommandResult &result); + void initAppRunning(); + void initFileDownloading(); + void initFileInstallation(); + void initFileSending(); + void putSendNextChunk(); + void readNextChunk(); + void readAppId(Coda::JsonValue value); + void reportError(const QString &message); + void reportMessage(const QString &message); + + CodaSignalHandlerPrivate *d; +}; + +#endif // CODESIGNALHANDLER_H diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index d749106..868a2a8 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -45,10 +45,13 @@ #include <QScopedPointer> #include <QTimer> #include <QFileInfo> +#include "symbianutils/codadevice.h" #include "symbianutils/trkutils.h" #include "symbianutils/trkdevice.h" #include "symbianutils/launcher.h" +#include "symbianutils/symbiandevicemanager.h" +#include "codasignalhandler.h" #include "trksignalhandler.h" #include "serenum.h" #include "ossignalconverter.h" @@ -62,14 +65,16 @@ void printUsage(QTextStream& outstream, QString exeName) << "-t, --timeout <milliseconds> terminate test if timeout occurs" << endl << "-v, --verbose show debugging output" << endl << "-q, --quiet hide progress messages" << endl - << "-u, --upload <local file> <remote file> upload file to phone" << endl + << "-u, --upload <local file> upload executable file to phone" << endl << "-d, --download <remote file> <local file> copy file from phone to PC after running test" << endl << "--nocrashlog Don't capture call stack if test crashes" << endl << "--crashlogpath <dir> Path to save crash logs (default=working dir)" << endl + << "--coda Use CODA instead of TRK (default agent)" << endl << endl << "USB COM ports can usually be autodetected, use -p or -f to force a specific port." << endl + << "TRK is the default debugging agent, use --coda option when using CODA instead of TRK." << endl << "If using System TRK, it is possible to copy the program directly to sys/bin on the phone." << endl - << "-s can be used with both System and Application TRK to install the program" << endl; + << "-s can be used with both System and Application TRK/CODA to install the program" << endl; } #define CHECK_PARAMETER_EXISTS if(!it.hasNext()) { printUsage(outstream, args[0]); return 1; } @@ -86,12 +91,12 @@ int main(int argc, char *argv[]) QTextStream outstream(stdout); QTextStream errstream(stderr); QString uploadLocalFile; - QString uploadRemoteFile; QString downloadRemoteFile; QString downloadLocalFile; int loglevel=1; int timeout=0; bool crashlog = true; + bool coda = false; QString crashlogpath; QListIterator<QString> it(args); it.next(); //skip name of program @@ -122,14 +127,21 @@ int main(int argc, char *argv[]) errstream << "Executable file (" << uploadLocalFile << ") doesn't exist" << endl; return 1; } - CHECK_PARAMETER_EXISTS - uploadRemoteFile = it.next(); + if (!(QFileInfo(uploadLocalFile).suffix() == "exe")) { + errstream << "File (" << uploadLocalFile << ") must be an executable" << endl; + return 1; + } } else if (arg == "--download" || arg == "-d") { CHECK_PARAMETER_EXISTS downloadRemoteFile = it.next(); CHECK_PARAMETER_EXISTS downloadLocalFile = it.next(); + QFileInfo downloadInfo(downloadLocalFile); + if (downloadInfo.exists() && !downloadInfo.isFile()) { + errstream << downloadLocalFile << " is not a file." << endl; + return 1; + } } else if (arg == "--timeout" || arg == "-t") { CHECK_PARAMETER_EXISTS @@ -140,6 +152,8 @@ int main(int argc, char *argv[]) return 1; } } + else if (arg == "--coda") + coda = true; else if (arg == "--verbose" || arg == "-v") loglevel=2; else if (arg == "--quiet" || arg == "-q") @@ -160,8 +174,7 @@ int main(int argc, char *argv[]) } } - if (exeFile.isEmpty() && sisFile.isEmpty() && - (uploadLocalFile.isEmpty() || uploadRemoteFile.isEmpty()) && + if (exeFile.isEmpty() && sisFile.isEmpty() && uploadLocalFile.isEmpty() && (downloadLocalFile.isEmpty() || downloadRemoteFile.isEmpty())) { printUsage(outstream, args[0]); return 1; @@ -200,76 +213,117 @@ int main(int argc, char *argv[]) } } + CodaSignalHandler codaHandler; QScopedPointer<trk::Launcher> launcher; - launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly)); - QFileInfo exeInfo(exeFile); + TrkSignalHandler trkHandler; + QFileInfo info(exeFile); QFileInfo uploadInfo(uploadLocalFile); - if (!sisFile.isEmpty()) { - launcher->addStartupActions(trk::Launcher::ActionCopyInstall); - launcher->setCopyFileName(sisFile, "c:\\data\\testtemp.sis"); - launcher->setInstallFileName("c:\\data\\testtemp.sis"); - } - else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) { - launcher->addStartupActions(trk::Launcher::ActionCopy); - launcher->setCopyFileName(uploadLocalFile, uploadRemoteFile); - } - if (!exeFile.isEmpty()) { - launcher->addStartupActions(trk::Launcher::ActionRun); - launcher->setFileName(QString("c:\\sys\\bin\\") + exeInfo.fileName()); - launcher->setCommandLineArgs(cmdLine); - } - if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) { - launcher->addStartupActions(trk::Launcher::ActionDownload); - launcher->setDownloadFileName(downloadRemoteFile, downloadLocalFile); - } - if (loglevel > 0) - outstream << "Connecting to target via " << serialPortName << endl; - launcher->setTrkServerName(serialPortName); - if (loglevel > 1) - launcher->setVerbose(1); + if (coda) { + codaHandler.setSerialPortName(serialPortName); + codaHandler.setLogLevel(loglevel); - TrkSignalHandler handler; - handler.setLogLevel(loglevel); - handler.setCrashLogging(crashlog); - handler.setCrashLogPath(crashlogpath); + if (!sisFile.isEmpty()) { + codaHandler.setActionType(ActionCopyInstall); + QString dstName = "c:\\data\\testtemp.sis"; + codaHandler.setCopyFileName(sisFile, dstName); + } + else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) { + codaHandler.setActionType(ActionCopy); + QString dstName = QString("c:\\sys\\bin\\") + uploadInfo.fileName(); + codaHandler.setCopyFileName(uploadLocalFile, dstName); + } + if (!exeFile.isEmpty()) { + codaHandler.setActionType(ActionRun); + codaHandler.setAppFileName(QString("c:\\sys\\bin\\") + info.fileName()); + codaHandler.setCommandLineArgs(cmdLine.join(QLatin1String(", "))); + } + if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) { + codaHandler.setActionType(ActionDownload); + codaHandler.setDownloadFileName(downloadRemoteFile, downloadLocalFile); + } - QObject::connect(launcher.data(), SIGNAL(copyingStarted()), &handler, SLOT(copyingStarted())); - QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &handler, SLOT(canNotConnect(const QString &))); - QObject::connect(launcher.data(), SIGNAL(canNotCreateFile(const QString &, const QString &)), &handler, SLOT(canNotCreateFile(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(canNotWriteFile(const QString &, const QString &)), &handler, SLOT(canNotWriteFile(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(canNotCloseFile(const QString &, const QString &)), &handler, SLOT(canNotCloseFile(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(installingStarted()), &handler, SLOT(installingStarted())); - QObject::connect(launcher.data(), SIGNAL(canNotInstall(const QString &, const QString &)), &handler, SLOT(canNotInstall(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(installingFinished()), &handler, SLOT(installingFinished())); - QObject::connect(launcher.data(), SIGNAL(startingApplication()), &handler, SLOT(startingApplication())); - QObject::connect(launcher.data(), SIGNAL(applicationRunning(uint)), &handler, SLOT(applicationRunning(uint))); - QObject::connect(launcher.data(), SIGNAL(canNotRun(const QString &)), &handler, SLOT(canNotRun(const QString &))); - QObject::connect(launcher.data(), SIGNAL(applicationOutputReceived(const QString &)), &handler, SLOT(applicationOutputReceived(const QString &))); - QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &handler, SLOT(copyProgress(int))); - QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &handler, SLOT(stateChanged(int))); - QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &handler, SLOT(stopped(uint,uint,uint,QString))); - QObject::connect(launcher.data(), SIGNAL(libraryLoaded(trk::Library)), &handler, SLOT(libraryLoaded(trk::Library))); - QObject::connect(launcher.data(), SIGNAL(libraryUnloaded(trk::Library)), &handler, SLOT(libraryUnloaded(trk::Library))); - QObject::connect(launcher.data(), SIGNAL(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)), &handler, SLOT(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &))); - QObject::connect(&handler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint))); - QObject::connect(&handler, SIGNAL(terminate()), launcher.data(), SLOT(terminate())); - QObject::connect(&handler, SIGNAL(getRegistersAndCallStack(uint,uint)), launcher.data(), SLOT(getRegistersAndCallStack(uint,uint))); - QObject::connect(launcher.data(), SIGNAL(finished()), &handler, SLOT(finished())); + if (loglevel > 0) + outstream << "Connecting to target via " << serialPortName << endl; - QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), launcher.data(), SLOT(terminate()), Qt::QueuedConnection); + if (timeout > 0) + codaHandler.setTimeout(timeout); - QTimer timer; - timer.setSingleShot(true); - QObject::connect(&timer, SIGNAL(timeout()), &handler, SLOT(timeout())); - if (timeout > 0) { - timer.start(timeout); - } + QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), &codaHandler, SLOT(terminate()), Qt::QueuedConnection); + return codaHandler.run(); - QString errorMessage; - if (!launcher->startServer(&errorMessage)) { - errstream << errorMessage << endl; - return 1; + } else { + launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly)); + if (!sisFile.isEmpty()) { + launcher->addStartupActions(trk::Launcher::ActionCopyInstall); + QStringList srcName(sisFile); + QStringList dstName("c:\\data\\testtemp.sis"); + launcher->setCopyFileNames(srcName, dstName); + launcher->setInstallFileNames(dstName); + } + else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) { + launcher->addStartupActions(trk::Launcher::ActionCopy); + QStringList srcName(uploadLocalFile); + QStringList dstName(QString("c:\\sys\\bin\\") + uploadInfo.fileName()); + launcher->setCopyFileNames(srcName, dstName); + } + if (!exeFile.isEmpty()) { + launcher->addStartupActions(trk::Launcher::ActionRun); + launcher->setFileName(QString("c:\\sys\\bin\\") + info.fileName()); + launcher->setCommandLineArgs(cmdLine.join(QLatin1String(" "))); + } + if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) { + launcher->addStartupActions(trk::Launcher::ActionDownload); + launcher->setDownloadFileName(downloadRemoteFile, downloadLocalFile); + } + if (loglevel > 0) + outstream << "Connecting to target via " << serialPortName << endl; + launcher->setTrkServerName(serialPortName); + + if (loglevel > 1) + launcher->setVerbose(1); + + trkHandler.setLogLevel(loglevel); + trkHandler.setCrashLogging(crashlog); + trkHandler.setCrashLogPath(crashlogpath); + + QObject::connect(launcher.data(), SIGNAL(copyingStarted(const QString &)), &trkHandler, SLOT(copyingStarted(const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &trkHandler, SLOT(canNotConnect(const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotCreateFile(const QString &, const QString &)), &trkHandler, SLOT(canNotCreateFile(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotWriteFile(const QString &, const QString &)), &trkHandler, SLOT(canNotWriteFile(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotCloseFile(const QString &, const QString &)), &trkHandler, SLOT(canNotCloseFile(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(installingStarted(const QString &)), &trkHandler, SLOT(installingStarted(const QString &))); + QObject::connect(launcher.data(), SIGNAL(canNotInstall(const QString &, const QString &)), &trkHandler, SLOT(canNotInstall(const QString &, const QString &))); + QObject::connect(launcher.data(), SIGNAL(installingFinished()), &trkHandler, SLOT(installingFinished())); + QObject::connect(launcher.data(), SIGNAL(startingApplication()), &trkHandler, SLOT(startingApplication())); + QObject::connect(launcher.data(), SIGNAL(applicationRunning(uint)), &trkHandler, SLOT(applicationRunning(uint))); + QObject::connect(launcher.data(), SIGNAL(canNotRun(const QString &)), &trkHandler, SLOT(canNotRun(const QString &))); + QObject::connect(launcher.data(), SIGNAL(applicationOutputReceived(const QString &)), &trkHandler, SLOT(applicationOutputReceived(const QString &))); + QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &trkHandler, SLOT(copyProgress(int))); + QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &trkHandler, SLOT(stateChanged(int))); + QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &trkHandler, SLOT(stopped(uint,uint,uint,QString))); + QObject::connect(launcher.data(), SIGNAL(libraryLoaded(trk::Library)), &trkHandler, SLOT(libraryLoaded(trk::Library))); + QObject::connect(launcher.data(), SIGNAL(libraryUnloaded(trk::Library)), &trkHandler, SLOT(libraryUnloaded(trk::Library))); + QObject::connect(launcher.data(), SIGNAL(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)), &trkHandler, SLOT(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &))); + QObject::connect(&trkHandler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint))); + QObject::connect(&trkHandler, SIGNAL(terminate()), launcher.data(), SLOT(terminate())); + QObject::connect(&trkHandler, SIGNAL(getRegistersAndCallStack(uint,uint)), launcher.data(), SLOT(getRegistersAndCallStack(uint,uint))); + QObject::connect(launcher.data(), SIGNAL(finished()), &trkHandler, SLOT(finished())); + + QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), launcher.data(), SLOT(terminate()), Qt::QueuedConnection); + + QTimer timer; + timer.setSingleShot(true); + QObject::connect(&timer, SIGNAL(timeout()), &trkHandler, SLOT(timeout())); + if (timeout > 0) { + timer.start(timeout); + } + + QString errorMessage; + if (!launcher->startServer(&errorMessage)) { + errstream << errorMessage << endl; + return 1; + } } return a.exec(); diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro index 7ff361c..d006a05 100644 --- a/tools/runonphone/runonphone.pro +++ b/tools/runonphone/runonphone.pro @@ -1,27 +1,29 @@ TEMPLATE = app QT -= gui -CONFIG += console +CONFIG += console static CONFIG -= app_bundle include(symbianutils/symbianutils.pri) SOURCES += main.cpp \ trksignalhandler.cpp \ - ossignalconverter.cpp + ossignalconverter.cpp \ + codasignalhandler.cpp HEADERS += trksignalhandler.h \ serenum.h \ ossignalconverter.h \ - ossignalconverter_p.h + ossignalconverter_p.h \ + codasignalhandler.h DEFINES += SYMBIANUTILS_INCLUDE_PRI windows { SOURCES += serenum_win.cpp LIBS += -lsetupapi \ - -luuid \ - -ladvapi32 + -luuid \ + -ladvapi32 } else:unix:!symbian { SOURCES += serenum_unix.cpp diff --git a/tools/runonphone/symbianutils/codadevice.cpp b/tools/runonphone/symbianutils/codadevice.cpp new file mode 100644 index 0000000..751f84e --- /dev/null +++ b/tools/runonphone/symbianutils/codadevice.cpp @@ -0,0 +1,1501 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "codadevice.h" +#include "json.h" +#include "trkutils.h" + +#include <QtNetwork/QAbstractSocket> +#include <QtCore/QDebug> +#include <QtCore/QVector> +#include <QtCore/QQueue> +#include <QtCore/QTextStream> +#include <QtCore/QDateTime> +#include <QtCore/QFileInfo> + +enum { debug = 0 }; + +static const char tcpMessageTerminatorC[] = "\003\001"; + +// Serial Ping: 0xfc,0x1f +static const char serialPingC[] = "\xfc\x1f"; +// Serial Pong: 0xfc,0xf1, followed by version info +static const char serialPongC[] = "\xfc\xf1"; + +static const char locatorAnswerC[] = "E\0Locator\0Hello\0[\"Locator\"]"; + +/* Serial messages > (1K - 2) have to chunked in order to pass the USB + * router as '0xfe char(chunkCount - 1) data' ... '0x0 char(chunkCount - 2) data' + * ... '0x0 0x0 last-data' */ +static const unsigned serialChunkLength = 0x400; // 1K max USB router +static const int maxSerialMessageLength = 0x10000; // given chunking scheme + +static const char validProtocolIdStart = (char)0x90; +static const char validProtocolIdEnd = (char)0x95; +static const char codaProtocolId = (char)0x92; +static const unsigned char serialChunkingStart = 0xfe; +static const unsigned char serialChunkingContinuation = 0x0; +enum { SerialChunkHeaderSize = 2 }; + +// Create USB router frame +static inline void encodeSerialFrame(const QByteArray &data, QByteArray *target, char protocolId) +{ + target->append(char(0x01)); + target->append(protocolId); + appendShort(target, ushort(data.size()), trk::BigEndian); + target->append(data); +} + +// Split in chunks of 1K according to CODA protocol chunking +static inline QByteArray encodeUsbSerialMessage(const QByteArray &dataIn) +{ + // Reserve 2 header bytes + static const int chunkSize = serialChunkLength - SerialChunkHeaderSize; + const int size = dataIn.size(); + QByteArray frame; + // Do we need to split? + if (size < chunkSize) { // Nope, all happy. + frame.reserve(size + 4); + encodeSerialFrame(dataIn, &frame, codaProtocolId); + return frame; + } + // Split. + unsigned chunkCount = size / chunkSize; + if (size % chunkSize) + chunkCount++; + if (debug) + qDebug("Serial: Splitting message of %d bytes into %u chunks of %d", size, chunkCount, chunkSize); + + frame.reserve((4 + serialChunkLength) * chunkCount); + int pos = 0; + for (unsigned c = chunkCount - 1; pos < size ; c--) { + QByteArray chunk; // chunk with long message start/continuation code + chunk.reserve(serialChunkLength); + chunk.append(pos ? serialChunkingContinuation : serialChunkingStart); + chunk.append(char(static_cast<unsigned char>(c))); // Avoid any signedness issues. + const int chunkEnd = qMin(pos + chunkSize, size); + chunk.append(dataIn.mid(pos, chunkEnd - pos)); + encodeSerialFrame(chunk, &frame, codaProtocolId); + pos = chunkEnd; + } + if (debug > 1) + qDebug("Serial chunked:\n%s", qPrintable(Coda::formatData(frame))); + return frame; +} + +namespace Coda { +// ------------- CodaCommandError + +CodaCommandError::CodaCommandError() : timeMS(0), code(0), alternativeCode(0) +{ +} + +void CodaCommandError::clear() +{ + timeMS = 0; + code = alternativeCode = 0; + format.clear(); + alternativeOrganization.clear(); +} + +QDateTime CodaCommandResult::tcfTimeToQDateTime(quint64 tcfTimeMS) +{ + const QDateTime time(QDate(1970, 1, 1)); + return time.addMSecs(tcfTimeMS); +} + +void CodaCommandError::write(QTextStream &str) const +{ + if (isError()) { + if (debug && timeMS) + str << CodaCommandResult::tcfTimeToQDateTime(timeMS).toString(Qt::ISODate) << ": "; + str << "'" << format << '\'' //for symbian the format is the real error message + << " Code: " << code; + if (!alternativeOrganization.isEmpty()) + str << " ('" << alternativeOrganization << "', code: " << alternativeCode << ')'; + } else{ + str << "<No error>"; + } +} + +QString CodaCommandError::toString() const +{ + QString rc; + QTextStream str(&rc); + write(str); + return rc; +} + +bool CodaCommandError::isError() const +{ + return timeMS != 0 || code != 0 || !format.isEmpty() || alternativeCode != 0; +} + +/* {"Time":1277459762255,"Code":1,"AltCode":-6,"AltOrg":"POSIX","Format":"Unknown error: -6"} */ +bool CodaCommandError::parse(const QVector<JsonValue> &values) +{ + // Parse an arbitrary hash (that could as well be a command response) + // and check for error elements. It looks like sometimes errors are appended + // to other values. + unsigned errorKeyCount = 0; + clear(); + do { + if (values.isEmpty()) + break; + // Errors are mostly appended, except for FileSystem::open, in which case + // a string "null" file handle (sic!) follows the error. + const int last = values.size() - 1; + const int checkIndex = last == 1 && values.at(last).data() == "null" ? + last - 1 : last; + if (values.at(checkIndex).type() != JsonValue::Object) + break; + foreach (const JsonValue &c, values.at(checkIndex).children()) { + if (c.name() == "Time") { + timeMS = c.data().toULongLong(); + errorKeyCount++; + } else if (c.name() == "Code") { + code = c.data().toLongLong(); + errorKeyCount++; + } else if (c.name() == "Format") { + format = c.data(); + errorKeyCount++; + } else if (c.name() == "AltCode") { + alternativeCode = c.data().toULongLong(); + errorKeyCount++; + } else if (c.name() == "AltOrg") { + alternativeOrganization = c.data(); + errorKeyCount++; + } + } + } while (false); + const bool errorFound = errorKeyCount >= 2u; // Should be at least 'Time', 'Code'. + if (!errorFound) + clear(); + if (debug) { + qDebug("CodaCommandError::parse: Found error %d (%u): ", errorFound, errorKeyCount); + if (!values.isEmpty()) + qDebug() << values.back().toString(); + } + return errorFound; +} + +// ------------ CodaCommandResult + +CodaCommandResult::CodaCommandResult(Type t) : + type(t), service(LocatorService) +{ +} + +CodaCommandResult::CodaCommandResult(char typeChar, Services s, + const QByteArray &r, + const QVector<JsonValue> &v, + const QVariant &ck) : + type(FailReply), service(s), request(r), values(v), cookie(ck) +{ + switch (typeChar) { + case 'N': + type = FailReply; + break; + case 'P': + type = ProgressReply; + break; + case 'R': + type = commandError.parse(values) ? CommandErrorReply : SuccessReply; + break; + default: + qWarning("Unknown TCF reply type '%c'", typeChar); + } +} + +QString CodaCommandResult::errorString() const +{ + QString rc; + QTextStream str(&rc); + + switch (type) { + case SuccessReply: + case ProgressReply: + str << "<No error>"; + return rc; + case FailReply: + str << "NAK"; + return rc; + case CommandErrorReply: + commandError.write(str); + break; + } + if (debug) { + // Append the failed command for reference + str << " (Command was: '"; + QByteArray printableRequest = request; + printableRequest.replace('\0', '|'); + str << printableRequest << "')"; + } + return rc; +} + +QString CodaCommandResult::toString() const +{ + QString rc; + QTextStream str(&rc); + str << "Command answer "; + switch (type) { + case SuccessReply: + str << "[success]"; + break; + case CommandErrorReply: + str << "[command error]"; + break; + case FailReply: + str << "[fail (NAK)]"; + break; + case ProgressReply: + str << "[progress]"; + break; + } + str << ", " << values.size() << " values(s) to request: '"; + QByteArray printableRequest = request; + printableRequest.replace('\0', '|'); + str << printableRequest << "' "; + if (cookie.isValid()) + str << " cookie: " << cookie.toString(); + str << '\n'; + for (int i = 0, count = values.size(); i < count; i++) + str << '#' << i << ' ' << values.at(i).toString() << '\n'; + if (type == CommandErrorReply) + str << "Error: " << errorString(); + return rc; +} + +CodaStatResponse::CodaStatResponse() : size(0) +{ +} + +struct CodaSendQueueEntry +{ + typedef CodaDevice::MessageType MessageType; + + explicit CodaSendQueueEntry(MessageType mt, + int tok, + Services s, + const QByteArray &d, + const CodaCallback &cb= CodaCallback(), + const QVariant &ck = QVariant()) : + messageType(mt), service(s), data(d), token(tok), cookie(ck), callback(cb) {} + + MessageType messageType; + Services service; + QByteArray data; + int token; + QVariant cookie; + CodaCallback callback; + unsigned specialHandling; +}; + +struct CodaDevicePrivate { + typedef CodaDevice::IODevicePtr IODevicePtr; + typedef QHash<int, CodaSendQueueEntry> TokenWrittenMessageMap; + + CodaDevicePrivate(); + + const QByteArray m_tcpMessageTerminator; + + IODevicePtr m_device; + unsigned m_verbose; + QByteArray m_readBuffer; + QByteArray m_serialBuffer; // for chunked messages + int m_token; + QQueue<CodaSendQueueEntry> m_sendQueue; + TokenWrittenMessageMap m_writtenMessages; + QVector<QByteArray> m_registerNames; + QVector<QByteArray> m_fakeGetMRegisterValues; + bool m_serialFrame; + bool m_serialPingOnly; +}; + +CodaDevicePrivate::CodaDevicePrivate() : + m_tcpMessageTerminator(tcpMessageTerminatorC), + m_verbose(0), m_token(0), m_serialFrame(false), m_serialPingOnly(false) +{ +} + +CodaDevice::CodaDevice(QObject *parent) : + QObject(parent), d(new CodaDevicePrivate) +{ + if (debug) setVerbose(true); +} + +CodaDevice::~CodaDevice() +{ + delete d; +} + +QVector<QByteArray> CodaDevice::registerNames() const +{ + return d->m_registerNames; +} + +void CodaDevice::setRegisterNames(const QVector<QByteArray>& n) +{ + d->m_registerNames = n; + if (d->m_verbose) { + QString msg; + QTextStream str(&msg); + const int count = n.size(); + str << "Registers (" << count << "): "; + for (int i = 0; i < count; i++) + str << '#' << i << '=' << n.at(i) << ' '; + emitLogMessage(msg); + } +} + +CodaDevice::IODevicePtr CodaDevice::device() const +{ + return d->m_device; +} + +CodaDevice::IODevicePtr CodaDevice::takeDevice() +{ + const IODevicePtr old = d->m_device; + if (!old.isNull()) { + old.data()->disconnect(this); + d->m_device = IODevicePtr(); + } + d->m_readBuffer.clear(); + d->m_token = 0; + d->m_sendQueue.clear(); + return old; +} + +void CodaDevice::setDevice(const IODevicePtr &dp) +{ + if (dp.data() == d->m_device.data()) + return; + if (dp.isNull()) { + emitLogMessage(QLatin1String("Internal error: Attempt to set NULL device.")); + return; + } + takeDevice(); + d->m_device = dp; + connect(dp.data(), SIGNAL(readyRead()), this, SLOT(slotDeviceReadyRead())); + if (QAbstractSocket *s = qobject_cast<QAbstractSocket *>(dp.data())) { + connect(s, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotDeviceError())); + connect(s, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(slotDeviceSocketStateChanged())); + } +} + +void CodaDevice::slotDeviceError() +{ + const QString message = d->m_device->errorString(); + emitLogMessage(message); + emit error(message); +} + +void CodaDevice::slotDeviceSocketStateChanged() +{ + if (const QAbstractSocket *s = qobject_cast<const QAbstractSocket *>(d->m_device.data())) { + const QAbstractSocket::SocketState st = s->state(); + switch (st) { + case QAbstractSocket::UnconnectedState: + emitLogMessage(QLatin1String("Unconnected")); + break; + case QAbstractSocket::HostLookupState: + emitLogMessage(QLatin1String("HostLookupState")); + break; + case QAbstractSocket::ConnectingState: + emitLogMessage(QLatin1String("Connecting")); + break; + case QAbstractSocket::ConnectedState: + emitLogMessage(QLatin1String("Connected")); + break; + case QAbstractSocket::ClosingState: + emitLogMessage(QLatin1String("Closing")); + break; + default: + emitLogMessage(QString::fromLatin1("State %1").arg(st)); + break; + } + } +} + +static inline QString debugMessage(QByteArray message, const char *prefix = 0) +{ + const bool isBinary = !message.isEmpty() && message.at(0) < 0; + if (isBinary) { + message = message.toHex(); // Some serial special message + } else { + message.replace('\0', '|'); + } + const QString messageS = QString::fromLatin1(message); + return prefix ? + (QLatin1String(prefix) + messageS) : messageS; +} + +void CodaDevice::slotDeviceReadyRead() +{ + const QByteArray newData = d->m_device->readAll(); + d->m_readBuffer += newData; + if (debug) + qDebug("ReadBuffer: %s", qPrintable(trk::stringFromArray(newData))); + if (d->m_serialFrame) { + deviceReadyReadSerial(); + } else { + deviceReadyReadTcp(); + } +} + +// Find a serial header in input stream '0x1', '0x92', 'lenH', 'lenL' +// and return message position and size. +QPair<int, int> CodaDevice::findSerialHeader(QByteArray &in) +{ + static const char header1 = 0x1; + // Header should in theory always be at beginning of + // buffer. Warn if there are bogus data in-between. + + while (in.size() >= 4) { + if (in.at(0) == header1 && in.at(1) == codaProtocolId) { + // Good packet + const int length = trk::extractShort(in.constData() + 2); + return QPair<int, int>(4, length); + } else if (in.at(0) == header1 && in.at(1) >= validProtocolIdStart && in.at(1) <= validProtocolIdEnd) { + // We recognise it but it's not a TCF message - emit it for any interested party to handle + const int length = trk::extractShort(in.constData() + 2); + if (4 + length <= in.size()) { + // We have all the data + QByteArray data(in.mid(4, length)); + emit unknownEvent(in.at(1), data); + in.remove(0, 4+length); + // and continue + } else { + // If we don't have all this packet, there can't be any data following it, so return now + // and wait for more data + return QPair<int, int>(-1, -1); + } + } else { + // Bad data - log it, remove it, and go round again + int nextHeader = in.indexOf(header1, 1); + QByteArray bad = in.mid(0, nextHeader); + qWarning("Bogus data received on serial line: %s\n" + "Frame Header at: %d", qPrintable(trk::stringFromArray(bad)), nextHeader); + in.remove(0, bad.length()); + // and continue + } + } + return QPair<int, int>(-1, -1); // No more data, or not enough for a complete header +} + +void CodaDevice::deviceReadyReadSerial() +{ + do { + // Extract message (pos,len) + const QPair<int, int> messagePos = findSerialHeader(d->m_readBuffer); + if (messagePos.first < 0) + break; + // Do we have the complete message? + const int messageEnd = messagePos.first + messagePos.second; + if (messageEnd > d->m_readBuffer.size()) + break; + processSerialMessage(d->m_readBuffer.mid(messagePos.first, messagePos.second)); + d->m_readBuffer.remove(0, messageEnd); + } while (!d->m_readBuffer.isEmpty()); + checkSendQueue(); // Send off further messages +} + +void CodaDevice::processSerialMessage(const QByteArray &message) +{ + if (debug > 1) + qDebug("Serial message: %s",qPrintable(trk::stringFromArray(message))); + if (message.isEmpty()) + return; + // Is thing a ping/pong response + const int size = message.size(); + if (message.startsWith(serialPongC)) { + const QString version = QString::fromLatin1(message.mid(sizeof(serialPongC) - 1)); + emitLogMessage(QString::fromLatin1("Serial connection from '%1'").arg(version)); + emit serialPong(version); + // Answer with locator. + if (!d->m_serialPingOnly) + writeMessage(QByteArray(locatorAnswerC, sizeof(locatorAnswerC))); + return; + } + // Check for long message (see top, '0xfe #number, data' or '0x0 #number, data') + // TODO: This is currently untested. + const unsigned char *dataU = reinterpret_cast<const unsigned char *>(message.constData()); + const bool isLongMessageStart = size > SerialChunkHeaderSize + && *dataU == serialChunkingStart; + const bool isLongMessageContinuation = size > SerialChunkHeaderSize + && *dataU == serialChunkingContinuation; + if (isLongMessageStart || isLongMessageContinuation) { + const unsigned chunkNumber = *++dataU; + if (isLongMessageStart) { // Start new buffer + d->m_serialBuffer.clear(); + d->m_serialBuffer.reserve( (chunkNumber + 1) * serialChunkLength); + } + d->m_serialBuffer.append(message.mid(SerialChunkHeaderSize, size - SerialChunkHeaderSize)); + // Last chunk? - Process + if (!chunkNumber) { + processMessage(d->m_serialBuffer); + d->m_serialBuffer.clear(); + d->m_serialBuffer.squeeze(); + } + } else { + processMessage(message); // Normal, unchunked message + } +} + +void CodaDevice::deviceReadyReadTcp() +{ + // Take complete message off front of readbuffer. + do { + const int messageEndPos = d->m_readBuffer.indexOf(d->m_tcpMessageTerminator); + if (messageEndPos == -1) + break; + if (messageEndPos == 0) { + // TCF TRK 4.0.5 emits empty messages on errors. + emitLogMessage(QString::fromLatin1("An empty TCF TRK message has been received.")); + } else { + processMessage(d->m_readBuffer.left(messageEndPos)); + } + d->m_readBuffer.remove(0, messageEndPos + d->m_tcpMessageTerminator.size()); + } while (!d->m_readBuffer.isEmpty()); + checkSendQueue(); // Send off further messages +} + +void CodaDevice::processMessage(const QByteArray &message) +{ + if (debug) + qDebug("Read %d bytes:\n%s", message.size(), qPrintable(formatData(message))); + if (const int errorCode = parseMessage(message)) { + emitLogMessage(QString::fromLatin1("Parse error %1 : %2"). + arg(errorCode).arg(debugMessage(message))); + if (debug) + qDebug("Parse error %d for %d bytes:\n%s", errorCode, + message.size(), qPrintable(formatData(message))); + } +} + +// Split \0-terminated message into tokens, skipping the initial type character +static inline QVector<QByteArray> splitMessage(const QByteArray &message) +{ + QVector<QByteArray> tokens; + tokens.reserve(7); + const int messageSize = message.size(); + for (int pos = 2; pos < messageSize; ) { + const int nextPos = message.indexOf('\0', pos); + if (nextPos == -1) + break; + tokens.push_back(message.mid(pos, nextPos - pos)); + pos = nextPos + 1; + } + return tokens; +} + +int CodaDevice::parseMessage(const QByteArray &message) +{ + if (d->m_verbose) + emitLogMessage(debugMessage(message, "TCF ->")); + // Special JSON parse error message or protocol format error. + // The port is usually closed after receiving it. + // "\3\2{"Time":1276096098255,"Code":3,"Format": "Protocol format error"}" + if (message.startsWith("\003\002")) { + QByteArray text = message.mid(2); + const QString errorMessage = QString::fromLatin1("Parse error received: %1").arg(QString::fromAscii(text)); + emit error(errorMessage); + return 0; + } + if (message.size() < 4 || message.at(1) != '\0') + return 1; + // Split into tokens + const char type = message.at(0); + const QVector<QByteArray> tokens = splitMessage(message); + switch (type) { + case 'E': + return parseTcfEvent(tokens); + case 'R': // Command replies + case 'N': + case 'P': + return parseTcfCommandReply(type, tokens); + default: + emitLogMessage(QString::fromLatin1("Unhandled message type: %1").arg(debugMessage(message))); + return 756; + } + return 0; +} + +int CodaDevice::parseTcfCommandReply(char type, const QVector<QByteArray> &tokens) +{ + typedef CodaDevicePrivate::TokenWrittenMessageMap::iterator TokenWrittenMessageMapIterator; + // Find the corresponding entry in the written messages hash. + const int tokenCount = tokens.size(); + if (tokenCount < 1) + return 234; + bool tokenOk; + const int token = tokens.at(0).toInt(&tokenOk); + if (!tokenOk) + return 235; + const TokenWrittenMessageMapIterator it = d->m_writtenMessages.find(token); + if (it == d->m_writtenMessages.end()) { + qWarning("CodaDevice: Internal error: token %d not found for '%s'", + token, qPrintable(joinByteArrays(tokens))); + return 236; + } + // No callback: remove entry from map, happy + const unsigned specialHandling = it.value().specialHandling; + if (!it.value().callback && specialHandling == 0u) { + d->m_writtenMessages.erase(it); + return 0; + } + // Parse values into JSON + QVector<JsonValue> values; + values.reserve(tokenCount); + for (int i = 1; i < tokenCount; i++) { + if (!tokens.at(i).isEmpty()) { // Strange: Empty tokens occur. + const JsonValue value(tokens.at(i)); + if (value.isValid()) { + values.push_back(value); + } else { + qWarning("JSON parse error for reply to command token %d: #%d '%s'", + token, i, tokens.at(i).constData()); + d->m_writtenMessages.erase(it); + return -1; + } + } + } + // Construct result and invoke callback, remove entry from map. + CodaCommandResult result(type, it.value().service, it.value().data, + values, it.value().cookie); + + if (it.value().callback) + it.value().callback(result); + d->m_writtenMessages.erase(it); + return 0; +} + +int CodaDevice::parseTcfEvent(const QVector<QByteArray> &tokens) +{ + // Event: Ignore the periodical heartbeat event, answer 'Hello', + // emit signal for the rest + if (tokens.size() < 3) + return 433; + const Services service = serviceFromName(tokens.at(0).constData()); + if (service == LocatorService && tokens.at(1) == "peerHeartBeat") + return 0; + QVector<JsonValue> values; + for (int i = 2; i < tokens.size(); i++) { + const JsonValue value(tokens.at(i)); + if (!value.isValid()) + return 434; + values.push_back(value); + } + // Parse known events, emit signals + QScopedPointer<CodaEvent> knownEvent(CodaEvent::parseEvent(service, tokens.at(1), values)); + if (!knownEvent.isNull()) { + // Answer hello event (WLAN) + if (knownEvent->type() == CodaEvent::LocatorHello) + if (!d->m_serialFrame) + writeMessage(QByteArray(locatorAnswerC, sizeof(locatorAnswerC))); + emit tcfEvent(*knownEvent); + } + emit genericTcfEvent(service, tokens.at(1), values); + + if (debug || d->m_verbose) { + QString msg; + QTextStream str(&msg); + if (knownEvent.isNull()) { + str << "Event: " << tokens.at(0) << ' ' << tokens.at(1) << '\n'; + foreach(const JsonValue &val, values) + str << " " << val.toString() << '\n'; + } else { + str << knownEvent->toString(); + } + emitLogMessage(msg); + } + + return 0; +} + +unsigned CodaDevice::verbose() const +{ + return d->m_verbose; +} + +bool CodaDevice::serialFrame() const +{ + return d->m_serialFrame; +} + +void CodaDevice::setSerialFrame(bool s) +{ + d->m_serialFrame = s; +} + +void CodaDevice::setVerbose(unsigned v) +{ + d->m_verbose = v; +} + +void CodaDevice::emitLogMessage(const QString &m) +{ + if (debug) + qWarning("%s", qPrintable(m)); + emit logMessage(m); +} + +bool CodaDevice::checkOpen() +{ + if (d->m_device.isNull()) { + emitLogMessage(QLatin1String("Internal error: No device set on CodaDevice.")); + return false; + } + if (!d->m_device->isOpen()) { + emitLogMessage(QLatin1String("Internal error: Device not open in CodaDevice.")); + return false; + } + return true; +} + +void CodaDevice::sendSerialPing(bool pingOnly) +{ + if (!checkOpen()) + return; + + d->m_serialPingOnly = pingOnly; + setSerialFrame(true); + writeMessage(QByteArray(serialPingC, qstrlen(serialPingC)), false); + if (d->m_verbose) + emitLogMessage(QLatin1String("Ping...")); +} + +void CodaDevice::sendCodaMessage(MessageType mt, Services service, const char *command, + const char *commandParameters, // may contain '\0' + int commandParametersLength, + const CodaCallback &callBack, + const QVariant &cookie) + +{ + if (!checkOpen()) + return; + // Format the message + const int token = d->m_token++; + QByteArray data; + data.reserve(30 + commandParametersLength); + data.append('C'); + data.append('\0'); + data.append(QByteArray::number(token)); + data.append('\0'); + data.append(serviceName(service)); + data.append('\0'); + data.append(command); + data.append('\0'); + if (commandParametersLength) + data.append(commandParameters, commandParametersLength); + const CodaSendQueueEntry entry(mt, token, service, data, callBack, cookie); + d->m_sendQueue.enqueue(entry); + checkSendQueue(); +} + +void CodaDevice::sendCodaMessage(MessageType mt, Services service, const char *command, + const QByteArray &commandParameters, + const CodaCallback &callBack, + const QVariant &cookie) +{ + sendCodaMessage(mt, service, command, commandParameters.constData(), commandParameters.size(), + callBack, cookie); +} + +// Enclose in message frame and write. +void CodaDevice::writeMessage(QByteArray data, bool ensureTerminating0) +{ + if (!checkOpen()) + return; + + if (d->m_serialFrame && data.size() > maxSerialMessageLength) { + qCritical("Attempt to send large message (%d bytes) exceeding the " + "limit of %d bytes over serial channel. Skipping.", + data.size(), maxSerialMessageLength); + return; + } + + if (d->m_verbose) + emitLogMessage(debugMessage(data, "TCF <-")); + + // Ensure \0-termination which easily gets lost in QByteArray CT. + if (ensureTerminating0 && !data.endsWith('\0')) + data.append('\0'); + if (d->m_serialFrame) { + data = encodeUsbSerialMessage(data); + } else { + data += d->m_tcpMessageTerminator; + } + + if (debug > 1) + qDebug("Writing:\n%s", qPrintable(formatData(data))); + + int result = d->m_device->write(data); + if (result < data.length()) + qWarning("Failed to write all data! result=%d", result); + if (QAbstractSocket *as = qobject_cast<QAbstractSocket *>(d->m_device.data())) + as->flush(); +} + +void CodaDevice::writeCustomData(char protocolId, const QByteArray &data) +{ + if (!checkOpen()) + return; + + if (!d->m_serialFrame) { + qWarning("Ignoring request to send data to non-serial CodaDevice"); + return; + } + if (data.length() > 0xFFFF) { + qWarning("Ignoring request to send too large packet, of size %d", data.length()); + return; + } + QByteArray framedData; + encodeSerialFrame(data, &framedData, protocolId); + device()->write(framedData); +} + +void CodaDevice::checkSendQueue() +{ + // Fire off messages or invoke noops until a message with reply is found + // and an entry to writtenMessages is made. + while (d->m_writtenMessages.empty()) { + if (d->m_sendQueue.isEmpty()) + break; + CodaSendQueueEntry entry = d->m_sendQueue.dequeue(); + switch (entry.messageType) { + case MessageWithReply: + d->m_writtenMessages.insert(entry.token, entry); + writeMessage(entry.data); + break; + case MessageWithoutReply: + writeMessage(entry.data); + break; + case NoopMessage: // Invoke the noop-callback for synchronization + if (entry.callback) { + CodaCommandResult noopResult(CodaCommandResult::SuccessReply); + noopResult.cookie = entry.cookie; + entry.callback(noopResult); + } + break; + } + } +} + +// Fix slashes +static inline QString fixFileName(QString in) +{ + in.replace(QLatin1Char('/'), QLatin1Char('\\')); + return in; +} + +// Start a process (consisting of a non-reply setSettings and start). +void CodaDevice::sendProcessStartCommand(const CodaCallback &callBack, + const QString &binaryIn, + unsigned uid, + QStringList arguments, + QString workingDirectory, + bool debugControl, + const QStringList &additionalLibraries, + const QVariant &cookie) +{ + // Obtain the bin directory, expand by c:/sys/bin if missing + const QChar backSlash('\\'); + int slashPos = binaryIn.lastIndexOf(QLatin1Char('/')); + if (slashPos == -1) + slashPos = binaryIn.lastIndexOf(backSlash); + const QString sysBin = QLatin1String("c:/sys/bin"); + const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1); + + if (workingDirectory.isEmpty()) + workingDirectory = sysBin; + + // Format settings with empty dummy parameter + QByteArray setData; + JsonInputStream setStr(setData); + setStr << "" << '\0' + << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ',' << "logUserTraces" << ']' + << '\0' << '[' + << binaryFileName << ',' + << '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ',' + << additionalLibraries << ',' << true + << ']'; + sendCodaMessage( +#if 1 + MessageWithReply, // TCF TRK 4.0.5 onwards +#else + MessageWithoutReply, // TCF TRK 4.0.2 +#endif + SettingsService, "set", setData); + + QByteArray startData; + JsonInputStream startStr(startData); + startStr << "" //We don't really know the drive of the working dir + << '\0' << binaryFileName << '\0' << arguments << '\0' + << QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard) + << debugControl; + sendCodaMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie); +} + +void CodaDevice::sendRunProcessCommand(const CodaCallback &callBack, + const QString &processName, + QStringList arguments, + const QVariant &cookie) +{ + QByteArray startData; + JsonInputStream startStr(startData); + startStr << "" //We don't really know the drive of the working dir + << '\0' << processName << '\0' << arguments << '\0' + << QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard) + << false; // Don't attach debugger + sendCodaMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie); +} + +void CodaDevice::sendSettingsEnableLogCommand() +{ + + QByteArray setData; + JsonInputStream setStr(setData); + setStr << "" << '\0' + << '[' << "logUserTraces" << ']' + << '\0' << '[' + << true + << ']'; + sendCodaMessage( +#if 1 + MessageWithReply, // TCF TRK 4.0.5 onwards +#else + MessageWithoutReply, // TCF TRK 4.0.2 +#endif + SettingsService, "set", setData); +} + +void CodaDevice::sendProcessTerminateCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << id; + sendCodaMessage(MessageWithReply, ProcessesService, "terminate", data, callBack, cookie); +} + +void CodaDevice::sendRunControlTerminateCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << id; + sendCodaMessage(MessageWithReply, RunControlService, "terminate", data, callBack, cookie); +} + +// Non-standard: Remove executable from settings +void CodaDevice::sendSettingsRemoveExecutableCommand(const QString &binaryIn, + unsigned uid, + const QStringList &additionalLibraries, + const QVariant &cookie) +{ + QByteArray setData; + JsonInputStream setStr(setData); + setStr << "" << '\0' + << '[' << "removedExecutables" << ',' << "removedLibraries" << ']' + << '\0' << '[' + << '{' << QFileInfo(binaryIn).fileName() << ':' << QString::number(uid, 16) << '}' << ',' + << additionalLibraries + << ']'; + sendCodaMessage(MessageWithoutReply, SettingsService, "set", setData, CodaCallback(), cookie); +} + +void CodaDevice::sendRunControlResumeCommand(const CodaCallback &callBack, + const QByteArray &id, + RunControlResumeMode mode, + unsigned count, + quint64 rangeStart, + quint64 rangeEnd, + const QVariant &cookie) +{ + QByteArray resumeData; + JsonInputStream str(resumeData); + str << id << '\0' << int(mode) << '\0' << count; + switch (mode) { + case RM_STEP_OVER_RANGE: + case RM_STEP_INTO_RANGE: + case RM_REVERSE_STEP_OVER_RANGE: + case RM_REVERSE_STEP_INTO_RANGE: + str << '\0' << '{' << "RANGE_START" << ':' << rangeStart + << ',' << "RANGE_END" << ':' << rangeEnd << '}'; + break; + default: + break; + } + sendCodaMessage(MessageWithReply, RunControlService, "resume", resumeData, callBack, cookie); +} + +void CodaDevice::sendRunControlSuspendCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << id; + sendCodaMessage(MessageWithReply, RunControlService, "suspend", data, callBack, cookie); +} + +void CodaDevice::sendRunControlResumeCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie) +{ + sendRunControlResumeCommand(callBack, id, RM_RESUME, 1, 0, 0, cookie); +} + +void CodaDevice::sendBreakpointsAddCommand(const CodaCallback &callBack, + const Breakpoint &bp, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << bp; + sendCodaMessage(MessageWithReply, BreakpointsService, "add", data, callBack, cookie); +} + +void CodaDevice::sendBreakpointsRemoveCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie) +{ + sendBreakpointsRemoveCommand(callBack, QVector<QByteArray>(1, id), cookie); +} + +void CodaDevice::sendBreakpointsRemoveCommand(const CodaCallback &callBack, + const QVector<QByteArray> &ids, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << ids; + sendCodaMessage(MessageWithReply, BreakpointsService, "remove", data, callBack, cookie); +} + +void CodaDevice::sendBreakpointsEnableCommand(const CodaCallback &callBack, + const QByteArray &id, + bool enable, + const QVariant &cookie) +{ + sendBreakpointsEnableCommand(callBack, QVector<QByteArray>(1, id), enable, cookie); +} + +void CodaDevice::sendBreakpointsEnableCommand(const CodaCallback &callBack, + const QVector<QByteArray> &ids, + bool enable, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << ids; + sendCodaMessage(MessageWithReply, BreakpointsService, + enable ? "enable" : "disable", + data, callBack, cookie); +} + +void CodaDevice::sendMemorySetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + quint64 start, const QByteArray& data, + const QVariant &cookie) +{ + QByteArray getData; + JsonInputStream str(getData); + // start/word size/mode. Mode should ideally be 1 (continue on error?) + str << contextId << '\0' << start << '\0' << 1 << '\0' << data.size() << '\0' << 1 + << '\0' << data.toBase64(); + sendCodaMessage(MessageWithReply, MemoryService, "set", getData, callBack, cookie); +} + +void CodaDevice::sendMemoryGetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + quint64 start, quint64 size, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + // start/word size/mode. Mode should ideally be 1 (continue on error?) + str << contextId << '\0' << start << '\0' << 1 << '\0' << size << '\0' << 1; + sendCodaMessage(MessageWithReply, MemoryService, "get", data, callBack, cookie); +} + +QByteArray CodaDevice::parseMemoryGet(const CodaCommandResult &r) +{ + if (r.type != CodaCommandResult::SuccessReply || r.values.size() < 1) + return QByteArray(); + const JsonValue &memoryV = r.values.front(); + + if (memoryV.type() != JsonValue::String || memoryV.data().size() < 2 + || !memoryV.data().endsWith('=')) + return QByteArray(); + // Catch errors reported as hash: + // R.4."TlVMTA==".{"Time":1276786871255,"Code":1,"AltCode":-38,"AltOrg":"POSIX","Format":"BadDescriptor"} + // Not sure what to make of it. + if (r.values.size() >= 2 && r.values.at(1).type() == JsonValue::Object) + qWarning("CodaDevice::parseMemoryGet(): Error retrieving memory: %s", r.values.at(1).toString(false).constData()); + // decode + const QByteArray memory = QByteArray::fromBase64(memoryV.data()); + if (memory.isEmpty()) + qWarning("Base64 decoding of %s failed.", memoryV.data().constData()); + if (debug) + qDebug("CodaDevice::parseMemoryGet: received %d bytes", memory.size()); + return memory; +} + +// Parse register children (array of names) +QVector<QByteArray> CodaDevice::parseRegisterGetChildren(const CodaCommandResult &r) +{ + QVector<QByteArray> rc; + if (!r || r.values.size() < 1 || r.values.front().type() != JsonValue::Array) + return rc; + const JsonValue &front = r.values.front(); + rc.reserve(front.childCount()); + foreach(const JsonValue &v, front.children()) + rc.push_back(v.data()); + return rc; +} + +CodaStatResponse CodaDevice::parseStat(const CodaCommandResult &r) +{ + CodaStatResponse rc; + if (!r || r.values.size() < 1 || r.values.front().type() != JsonValue::Object) + return rc; + foreach(const JsonValue &v, r.values.front().children()) { + if (v.name() == "Size") { + rc.size = v.data().toULongLong(); + } else if (v.name() == "ATime") { + if (const quint64 atime = v.data().toULongLong()) + rc.accessTime = CodaCommandResult::tcfTimeToQDateTime(atime); + } else if (v.name() == "MTime") { + if (const quint64 mtime = v.data().toULongLong()) + rc.modTime = CodaCommandResult::tcfTimeToQDateTime(mtime); + } + } + return rc; +} + +void CodaDevice::sendRegistersGetChildrenCommand(const CodaCallback &callBack, + const QByteArray &contextId, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << contextId; + sendCodaMessage(MessageWithReply, RegistersService, "getChildren", data, callBack, cookie); +} + +// Format id of register get request (needs contextId containing process and thread) +static inline QByteArray registerId(const QByteArray &contextId, QByteArray id) +{ + QByteArray completeId = contextId; + if (!completeId.isEmpty()) + completeId.append('.'); + completeId.append(id); + return completeId; +} + +// Format parameters of register get request +static inline QByteArray registerGetData(const QByteArray &contextId, QByteArray id) +{ + QByteArray data; + JsonInputStream str(data); + str << registerId(contextId, id); + return data; +} + +void CodaDevice::sendRegistersGetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + QByteArray id, + const QVariant &cookie) +{ + sendCodaMessage(MessageWithReply, RegistersService, "get", + registerGetData(contextId, id), callBack, cookie); +} + +void CodaDevice::sendRegistersGetMCommand(const CodaCallback &callBack, + const QByteArray &contextId, + const QVector<QByteArray> &ids, + const QVariant &cookie) +{ + // Format the register ids as a JSON list + QByteArray data; + JsonInputStream str(data); + str << '['; + const int count = ids.size(); + for (int r = 0; r < count; r++) { + if (r) + str << ','; + // TODO: When 8-byte floating-point registers are supported, query for register length based on register id + str << '[' << registerId(contextId, ids.at(r)) << ',' << '0' << ',' << '4' << ']'; + } + str << ']'; + sendCodaMessage(MessageWithReply, RegistersService, "getm", data, callBack, cookie); +} + +void CodaDevice::sendRegistersGetMRangeCommand(const CodaCallback &callBack, + const QByteArray &contextId, + unsigned start, unsigned count) +{ + const unsigned end = start + count; + if (end > (unsigned)d->m_registerNames.size()) { + qWarning("CodaDevice: No register name set for index %u (size: %d).", end, d->m_registerNames.size()); + return; + } + + QVector<QByteArray> ids; + ids.reserve(count); + for (unsigned i = start; i < end; ++i) + ids.push_back(d->m_registerNames.at(i)); + sendRegistersGetMCommand(callBack, contextId, ids, QVariant(start)); +} + +// Set register +void CodaDevice::sendRegistersSetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + QByteArray id, + const QByteArray &value, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + if (!contextId.isEmpty()) { + id.prepend('.'); + id.prepend(contextId); + } + str << id << '\0' << value.toBase64(); + sendCodaMessage(MessageWithReply, RegistersService, "set", data, callBack, cookie); +} + +// Set register +void CodaDevice::sendRegistersSetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + unsigned registerNumber, + const QByteArray &value, + const QVariant &cookie) +{ + if (registerNumber >= (unsigned)d->m_registerNames.size()) { + qWarning("CodaDevice: No register name set for index %u (size: %d).", registerNumber, d->m_registerNames.size()); + return; + } + sendRegistersSetCommand(callBack, contextId, + d->m_registerNames[registerNumber], + value, cookie); +} + +static const char outputListenerIDC[] = "ProgramOutputConsoleLogger"; + +void CodaDevice::sendLoggingAddListenerCommand(const CodaCallback &callBack, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << outputListenerIDC; + sendCodaMessage(MessageWithReply, LoggingService, "addListener", data, callBack, cookie); +} + +void CodaDevice::sendSymbianUninstallCommand(const Coda::CodaCallback &callBack, + const quint32 package, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + QString string = QString::number(package, 16); + str << string; + sendCodaMessage(MessageWithReply, SymbianInstallService, "uninstall", data, callBack, cookie); +} + +void CodaDevice::sendSymbianOsDataGetThreadsCommand(const CodaCallback &callBack, + const QVariant &cookie) +{ + QByteArray data; + sendCodaMessage(MessageWithReply, SymbianOSData, "getThreads", data, callBack, cookie); +} + +void CodaDevice::sendSymbianOsDataFindProcessesCommand(const CodaCallback &callBack, + const QByteArray &processName, + const QByteArray &uid, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << processName << '\0' << uid; + sendCodaMessage(MessageWithReply, SymbianOSData, "findRunningProcesses", data, callBack, cookie); +} + +void CodaDevice::sendSymbianOsDataGetQtVersionCommand(const CodaCallback &callBack, + const QVariant &cookie) +{ + sendCodaMessage(MessageWithReply, SymbianOSData, "getQtVersion", QByteArray(), callBack, cookie); +} + +void CodaDevice::sendSymbianOsDataGetRomInfoCommand(const CodaCallback &callBack, + const QVariant &cookie) +{ + sendCodaMessage(MessageWithReply, SymbianOSData, "getRomInfo", QByteArray(), callBack, cookie); +} + +void CodaDevice::sendSymbianOsDataGetHalInfoCommand(const CodaCallback &callBack, + const QStringList &keys, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << '['; + for (int i = 0; i < keys.count(); ++i) { + if (i) + str << ','; + str << keys[i]; + } + str << ']'; + sendCodaMessage(MessageWithReply, SymbianOSData, "getHalInfo", data, callBack, cookie); +} + +void Coda::CodaDevice::sendFileSystemOpenCommand(const Coda::CodaCallback &callBack, + const QByteArray &name, + unsigned flags, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << name << '\0' << flags << '\0' << '{' << '}'; + sendCodaMessage(MessageWithReply, FileSystemService, "open", data, callBack, cookie); +} + +void Coda::CodaDevice::sendFileSystemFstatCommand(const CodaCallback &callBack, + const QByteArray &handle, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << handle; + sendCodaMessage(MessageWithReply, FileSystemService, "fstat", data, callBack, cookie); +} + +void Coda::CodaDevice::sendFileSystemReadCommand(const Coda::CodaCallback &callBack, + const QByteArray &handle, + unsigned int offset, + unsigned int size, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << handle << '\0' << offset << '\0' << size; + sendCodaMessage(MessageWithReply, FileSystemService, "read", data, callBack, cookie); +} + +void Coda::CodaDevice::sendFileSystemWriteCommand(const Coda::CodaCallback &callBack, + const QByteArray &handle, + const QByteArray &dataIn, + unsigned offset, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << handle << '\0' << offset << '\0' << dataIn.toBase64(); + sendCodaMessage(MessageWithReply, FileSystemService, "write", data, callBack, cookie); +} + +void Coda::CodaDevice::sendFileSystemCloseCommand(const Coda::CodaCallback &callBack, + const QByteArray &handle, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << handle; + sendCodaMessage(MessageWithReply, FileSystemService, "close", data, callBack, cookie); +} + +void Coda::CodaDevice::sendSymbianInstallSilentInstallCommand(const Coda::CodaCallback &callBack, + const QByteArray &file, + const QByteArray &targetDrive, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << file << '\0' << targetDrive; + sendCodaMessage(MessageWithReply, SymbianInstallService, "install", data, callBack, cookie); +} + +void Coda::CodaDevice::sendSymbianInstallUIInstallCommand(const Coda::CodaCallback &callBack, + const QByteArray &file, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << file; + sendCodaMessage(MessageWithReply, SymbianInstallService, "installWithUI", data, callBack, cookie); +} + +void Coda::CodaDevice::sendSymbianInstallGetPackageInfoCommand(const Coda::CodaCallback &callBack, + const QList<quint32> &packages, + const QVariant &cookie) +{ + QByteArray data; + JsonInputStream str(data); + str << '['; + for (int i = 0; i < packages.count(); ++i) { + if (i) + str << ','; + QString pkgString; + pkgString.setNum(packages[i], 16); + str << pkgString; + } + str << ']'; + sendCodaMessage(MessageWithReply, SymbianInstallService, "getPackageInfo", data, callBack, cookie); +} + +void Coda::CodaDevice::sendDebugSessionControlSessionStartCommand(const Coda::CodaCallback &callBack, + const QVariant &cookie) +{ + sendCodaMessage(MessageWithReply, DebugSessionControl, "sessionStart", QByteArray(), callBack, cookie); +} + +void Coda::CodaDevice::sendDebugSessionControlSessionEndCommand(const Coda::CodaCallback &callBack, + const QVariant &cookie) +{ + sendCodaMessage(MessageWithReply, DebugSessionControl, "sessionEnd ", QByteArray(), callBack, cookie); +} + +} // namespace Coda diff --git a/tools/runonphone/symbianutils/codadevice.h b/tools/runonphone/symbianutils/codadevice.h new file mode 100644 index 0000000..253e8b2 --- /dev/null +++ b/tools/runonphone/symbianutils/codadevice.h @@ -0,0 +1,447 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CODAENGINE_H +#define CODAENGINE_H + +#include "symbianutils_global.h" +#include "codamessage.h" +#include "callback.h" +#include "json.h" + +#include <QtCore/QObject> +#include <QtCore/QSharedPointer> +#include <QtCore/QVector> +#include <QtCore/QVariant> +#include <QtCore/QStringList> +#include <QtCore/QDateTime> + +QT_BEGIN_NAMESPACE +class QIODevice; +class QTextStream; +QT_END_NAMESPACE + +namespace Coda { + +struct CodaDevicePrivate; +struct Breakpoint; + +/* Command error handling in TCF: + * 1) 'Severe' errors (JSON format, parameter format): Trk emits a + * nonstandard message (\3\2 error parameters) and closes the connection. + * 2) Protocol errors: 'N' without error message is returned. + * 3) Errors in command execution: 'R' with a TCF error hash is returned + * (see CodaCommandError). */ + +/* Error code return in 'R' reply to command + * (see top of 'Services' documentation). */ +struct SYMBIANUTILS_EXPORT CodaCommandError { + CodaCommandError(); + void clear(); + bool isError() const; + operator bool() const { return isError(); } + QString toString() const; + void write(QTextStream &str) const; + bool parse(const QVector<JsonValue> &values); + + quint64 timeMS; // Since 1.1.1970 + qint64 code; + QByteArray format; // message + // 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno> + QByteArray alternativeOrganization; + qint64 alternativeCode; +}; + +/* Answer to a Tcf command passed to the callback. */ +struct SYMBIANUTILS_EXPORT CodaCommandResult { + enum Type + { + SuccessReply, // 'R' and no error -> all happy. + CommandErrorReply, // 'R' with CodaCommandError received + ProgressReply, // 'P', progress indicator + FailReply // 'N' Protocol NAK, severe error + }; + + explicit CodaCommandResult(Type t = SuccessReply); + explicit CodaCommandResult(char typeChar, Services service, + const QByteArray &request, + const QVector<JsonValue> &values, + const QVariant &cookie); + + QString toString() const; + QString errorString() const; + operator bool() const { return type == SuccessReply || type == ProgressReply; } + + static QDateTime tcfTimeToQDateTime(quint64 tcfTimeMS); + + Type type; + Services service; + QByteArray request; + CodaCommandError commandError; + QVector<JsonValue> values; + QVariant cookie; +}; + +// Response to stat/fstat +struct SYMBIANUTILS_EXPORT CodaStatResponse +{ + CodaStatResponse(); + + quint64 size; + QDateTime modTime; + QDateTime accessTime; +}; + +typedef trk::Callback<const CodaCommandResult &> CodaCallback; + +/* CodaDevice: TCF communication helper using an asynchronous QIODevice + * implementing the TCF protocol according to: +http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specification.html +http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html + * Commands can be sent along with callbacks that are passed a + * CodaCommandResult and an opaque QVariant cookie. In addition, events are emitted. + * + * CODA notes: + * - Commands are accepted only after receiving the Locator Hello event + * - Serial communication initiation sequence: + * Send serial ping from host sendSerialPing() -> receive pong response with + * version information -> Send Locator Hello Event -> Receive Locator Hello Event + * -> Commands are accepted. + * - WLAN communication initiation sequence: + * Receive Locator Hello Event from CODA -> Commands are accepted. + */ + +class SYMBIANUTILS_EXPORT CodaDevice : public QObject +{ + Q_PROPERTY(unsigned verbose READ verbose WRITE setVerbose) + Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) + Q_OBJECT +public: + // Flags for FileSystem:open + enum FileSystemOpenFlags + { + FileSystem_TCF_O_READ = 0x00000001, + FileSystem_TCF_O_WRITE = 0x00000002, + FileSystem_TCF_O_APPEND = 0x00000004, + FileSystem_TCF_O_CREAT = 0x00000008, + FileSystem_TCF_O_TRUNC = 0x00000010, + FileSystem_TCF_O_EXCL = 0x00000020 + }; + + enum MessageType + { + MessageWithReply, + MessageWithoutReply, /* Non-standard: "Settings:set" command does not reply */ + NoopMessage + }; + + typedef QSharedPointer<QIODevice> IODevicePtr; + + explicit CodaDevice(QObject *parent = 0); + virtual ~CodaDevice(); + + unsigned verbose() const; + bool serialFrame() const; + void setSerialFrame(bool); + + // Mapping of register names to indices for multi-requests. + // Register names can be retrieved via 'Registers:getChildren' (requires + // context id to be stripped). + QVector<QByteArray> registerNames() const; + void setRegisterNames(const QVector<QByteArray>& n); + + IODevicePtr device() const; + IODevicePtr takeDevice(); + void setDevice(const IODevicePtr &dp); + + // Serial Only: Initiate communication. Will emit serialPong() signal with version. + void sendSerialPing(bool pingOnly = false); + + // Send with parameters from string (which may contain '\0'). + void sendCodaMessage(MessageType mt, Services service, const char *command, + const char *commandParameters, int commandParametersLength, + const CodaCallback &callBack = CodaCallback(), + const QVariant &cookie = QVariant()); + + void sendCodaMessage(MessageType mt, Services service, const char *command, + const QByteArray &commandParameters, + const CodaCallback &callBack = CodaCallback(), + const QVariant &cookie = QVariant()); + + // Convenience messages: Start a process + void sendProcessStartCommand(const CodaCallback &callBack, + const QString &binary, + unsigned uid, + QStringList arguments = QStringList(), + QString workingDirectory = QString(), + bool debugControl = true, + const QStringList &additionalLibraries = QStringList(), + const QVariant &cookie = QVariant()); + + // Just launch a process, don't attempt to attach the debugger to it + void sendRunProcessCommand(const CodaCallback &callBack, + const QString &processName, + QStringList arguments = QStringList(), + const QVariant &cookie = QVariant()); + + // Preferred over Processes:Terminate by TCF TRK. + void sendRunControlTerminateCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie = QVariant()); + + void sendProcessTerminateCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie = QVariant()); + + // Non-standard: Remove executable from settings. + // Probably needs to be called after stopping. This command has no response. + void sendSettingsRemoveExecutableCommand(const QString &binaryIn, + unsigned uid, + const QStringList &additionalLibraries = QStringList(), + const QVariant &cookie = QVariant()); + + void sendRunControlSuspendCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie = QVariant()); + + // Resume / Step (see RunControlResumeMode). + void sendRunControlResumeCommand(const CodaCallback &callBack, + const QByteArray &id, + RunControlResumeMode mode, + unsigned count /* = 1, currently ignored. */, + quint64 rangeStart, quint64 rangeEnd, + const QVariant &cookie = QVariant()); + + // Convenience to resume a suspended process + void sendRunControlResumeCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie = QVariant()); + + void sendBreakpointsAddCommand(const CodaCallback &callBack, + const Breakpoint &b, + const QVariant &cookie = QVariant()); + + void sendBreakpointsRemoveCommand(const CodaCallback &callBack, + const QByteArray &id, + const QVariant &cookie = QVariant()); + + void sendBreakpointsRemoveCommand(const CodaCallback &callBack, + const QVector<QByteArray> &id, + const QVariant &cookie = QVariant()); + + void sendBreakpointsEnableCommand(const CodaCallback &callBack, + const QByteArray &id, + bool enable, + const QVariant &cookie = QVariant()); + + void sendBreakpointsEnableCommand(const CodaCallback &callBack, + const QVector<QByteArray> &id, + bool enable, + const QVariant &cookie = QVariant()); + + + void sendMemoryGetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + quint64 start, quint64 size, + const QVariant &cookie = QVariant()); + + void sendMemorySetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + quint64 start, const QByteArray& data, + const QVariant &cookie = QVariant()); + + // Get register names (children of context). + // It is possible to recurse from thread id down to single registers. + void sendRegistersGetChildrenCommand(const CodaCallback &callBack, + const QByteArray &contextId, + const QVariant &cookie = QVariant()); + + // Register get + void sendRegistersGetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + QByteArray id, + const QVariant &cookie); + + void sendRegistersGetMCommand(const CodaCallback &callBack, + const QByteArray &contextId, + const QVector<QByteArray> &ids, + const QVariant &cookie = QVariant()); + + // Convenience to get a range of register "R0" .. "R<n>". + // Cookie will be an int containing "start". + void sendRegistersGetMRangeCommand(const CodaCallback &callBack, + const QByteArray &contextId, + unsigned start, unsigned count); + + // Set register + void sendRegistersSetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + QByteArray ids, + const QByteArray &value, // binary value + const QVariant &cookie = QVariant()); + // Set register + void sendRegistersSetCommand(const CodaCallback &callBack, + const QByteArray &contextId, + unsigned registerNumber, + const QByteArray &value, // binary value + const QVariant &cookie = QVariant()); + + // File System + void sendFileSystemOpenCommand(const CodaCallback &callBack, + const QByteArray &name, + unsigned flags = FileSystem_TCF_O_READ, + const QVariant &cookie = QVariant()); + + void sendFileSystemFstatCommand(const CodaCallback &callBack, + const QByteArray &handle, + const QVariant &cookie = QVariant()); + + void sendFileSystemReadCommand(const Coda::CodaCallback &callBack, + const QByteArray &handle, + unsigned int offset, + unsigned int size, + const QVariant &cookie = QVariant()); + + void sendFileSystemWriteCommand(const CodaCallback &callBack, + const QByteArray &handle, + const QByteArray &data, + unsigned offset = 0, + const QVariant &cookie = QVariant()); + + void sendFileSystemCloseCommand(const CodaCallback &callBack, + const QByteArray &handle, + const QVariant &cookie = QVariant()); + + // Symbian Install + void sendSymbianInstallSilentInstallCommand(const CodaCallback &callBack, + const QByteArray &file, + const QByteArray &targetDrive, + const QVariant &cookie = QVariant()); + + void sendSymbianInstallUIInstallCommand(const CodaCallback &callBack, + const QByteArray &file, + const QVariant &cookie = QVariant()); + + void sendSymbianInstallGetPackageInfoCommand(const Coda::CodaCallback &callBack, + const QList<quint32> &packages, + const QVariant &cookie = QVariant()); + + void sendLoggingAddListenerCommand(const CodaCallback &callBack, + const QVariant &cookie = QVariant()); + + void sendSymbianUninstallCommand(const Coda::CodaCallback &callBack, + const quint32 package, + const QVariant &cookie = QVariant()); + + // SymbianOs Data + void sendSymbianOsDataGetThreadsCommand(const CodaCallback &callBack, + const QVariant &cookie = QVariant()); + + void sendSymbianOsDataFindProcessesCommand(const CodaCallback &callBack, + const QByteArray &processName, + const QByteArray &uid, + const QVariant &cookie = QVariant()); + + void sendSymbianOsDataGetQtVersionCommand(const CodaCallback &callBack, + const QVariant &cookie = QVariant()); + + void sendSymbianOsDataGetRomInfoCommand(const CodaCallback &callBack, + const QVariant &cookie = QVariant()); + + void sendSymbianOsDataGetHalInfoCommand(const CodaCallback &callBack, + const QStringList &keys = QStringList(), + const QVariant &cookie = QVariant()); + + // DebugSessionControl + void sendDebugSessionControlSessionStartCommand(const CodaCallback &callBack, + const QVariant &cookie = QVariant()); + + void sendDebugSessionControlSessionEndCommand(const CodaCallback &callBack, + const QVariant &cookie = QVariant()); + + // Settings + void sendSettingsEnableLogCommand(); + + void writeCustomData(char protocolId, const QByteArray &aData); + + static QByteArray parseMemoryGet(const CodaCommandResult &r); + static QVector<QByteArray> parseRegisterGetChildren(const CodaCommandResult &r); + static CodaStatResponse parseStat(const CodaCommandResult &r); + +signals: + void genericTcfEvent(int service, const QByteArray &name, const QVector<JsonValue> &value); + void tcfEvent(const Coda::CodaEvent &knownEvent); + void unknownEvent(uchar protocolId, const QByteArray& data); + void serialPong(const QString &codaVersion); + + void logMessage(const QString &); + void error(const QString &); + +public slots: + void setVerbose(unsigned v); + +private slots: + void slotDeviceError(); + void slotDeviceSocketStateChanged(); + void slotDeviceReadyRead(); + +private: + void deviceReadyReadSerial(); + void deviceReadyReadTcp(); + + bool checkOpen(); + void checkSendQueue(); + void writeMessage(QByteArray data, bool ensureTerminating0 = true); + void emitLogMessage(const QString &); + inline int parseMessage(const QByteArray &); + void processMessage(const QByteArray &message); + inline void processSerialMessage(const QByteArray &message); + int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens); + int parseTcfEvent(const QVector<QByteArray> &tokens); + +private: + QPair<int, int> findSerialHeader(QByteArray &in); + CodaDevicePrivate *d; +}; + +} // namespace Coda + +#endif // CODAENGINE_H diff --git a/tools/runonphone/symbianutils/tcftrkmessage.cpp b/tools/runonphone/symbianutils/codamessage.cpp index 9e9c16c..13fbcf2 100644 --- a/tools/runonphone/symbianutils/tcftrkmessage.cpp +++ b/tools/runonphone/symbianutils/codamessage.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "tcftrkmessage.h" +#include "codamessage.h" #include "json.h" #include <QtCore/QString> @@ -48,10 +48,11 @@ // Names matching the enum static const char *serviceNamesC[] = { "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints", - "Registers", "SimpleRegisters", + "Registers", "Logging", "FileSystem", "SymbianInstall", "SymbianOSData", + "DebugSessionControl", "UnknownService"}; -namespace tcftrk { +namespace Coda { SYMBIANUTILS_EXPORT QString joinByteArrays(const QVector<QByteArray> &a, char sep) { @@ -341,7 +342,7 @@ QString Breakpoint::toString() const JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b) { if (b.contextIds.isEmpty()) - qWarning("tcftrk::Breakpoint: No context ids specified"); + qWarning("Coda::Breakpoint: No context ids specified"); str << '{' << "ID" << ':' << QString::fromUtf8(b.id) << ',' << "BreakpointType" << ':' << breakPointTypesC[b.type] << ',' @@ -356,27 +357,27 @@ JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b) } // --- Events -TcfTrkEvent::TcfTrkEvent(Type type) : m_type(type) +CodaEvent::CodaEvent(Type type) : m_type(type) { } -TcfTrkEvent::~TcfTrkEvent() +CodaEvent::~CodaEvent() { } -TcfTrkEvent::Type TcfTrkEvent::type() const +CodaEvent::Type CodaEvent::type() const { return m_type; } -QString TcfTrkEvent::toString() const +QString CodaEvent::toString() const { return QString(); } static const char sharedLibrarySuspendReasonC[] = "Shared Library"; -TcfTrkEvent *TcfTrkEvent::parseEvent(Services s, const QByteArray &nameBA, const QVector<JsonValue> &values) +CodaEvent *CodaEvent::parseEvent(Services s, const QByteArray &nameBA, const QVector<JsonValue> &values) { switch (s) { case LocatorService: @@ -384,7 +385,7 @@ TcfTrkEvent *TcfTrkEvent::parseEvent(Services s, const QByteArray &nameBA, const QStringList services; foreach (const JsonValue &jv, values.front().children()) services.push_back(QString::fromUtf8(jv.data())); - return new TcfTrkLocatorHelloEvent(services); + return new CodaLocatorHelloEvent(services); } break; case RunControlService: @@ -395,67 +396,96 @@ TcfTrkEvent *TcfTrkEvent::parseEvent(Services s, const QByteArray &nameBA, const const QByteArray idBA = values.at(0).data(); const quint64 pc = values.at(1).data().toULongLong(); const QByteArray reasonBA = values.at(2).data(); + QByteArray messageBA; // Module load: Special if (reasonBA == sharedLibrarySuspendReasonC) { ModuleLoadEventInfo info; if (!info.parse(values.at(3))) return 0; - return new TcfTrkRunControlModuleLoadContextSuspendedEvent(idBA, reasonBA, pc, info); + return new CodaRunControlModuleLoadContextSuspendedEvent(idBA, reasonBA, pc, info); + } else { + // hash containing a 'message'-key with a verbose crash message. + if (values.at(3).type() == JsonValue::Object && values.at(3).childCount() + && values.at(3).children().at(0).type() == JsonValue::String) + messageBA = values.at(3).children().at(0).data(); } - return new TcfTrkRunControlContextSuspendedEvent(idBA, reasonBA, pc); + return new CodaRunControlContextSuspendedEvent(idBA, reasonBA, messageBA, pc); } // "contextSuspended" if (nameBA == "contextAdded") - return TcfTrkRunControlContextAddedEvent::parseEvent(values); + return CodaRunControlContextAddedEvent::parseEvent(values); if (nameBA == "contextRemoved" && values.front().type() == JsonValue::Array) { QVector<QByteArray> ids; foreach(const JsonValue &c, values.front().children()) ids.push_back(c.data()); - return new TcfTrkRunControlContextRemovedEvent(ids); + return new CodaRunControlContextRemovedEvent(ids); } break; + case LoggingService: + if ((nameBA == "writeln" || nameBA == "write" /*not yet used*/) && values.size() >= 2) + return new CodaLoggingWriteEvent(values.at(0).data(), values.at(1).data()); + break; + case ProcessesService: + if (nameBA == "exited" && values.size() >= 2) + return new CodaProcessExitedEvent(values.at(0).data()); + break; default: break; } return 0; } -// -------------- TcfTrkServiceHelloEvent -TcfTrkLocatorHelloEvent::TcfTrkLocatorHelloEvent(const QStringList &s) : - TcfTrkEvent(LocatorHello), +// -------------- CodaServiceHelloEvent +CodaLocatorHelloEvent::CodaLocatorHelloEvent(const QStringList &s) : + CodaEvent(LocatorHello), m_services(s) { } -QString TcfTrkLocatorHelloEvent::toString() const +QString CodaLocatorHelloEvent::toString() const { return QLatin1String("ServiceHello: ") + m_services.join(QLatin1String(", ")); } -// -------------- TcfTrkIdEvent -TcfTrkIdEvent::TcfTrkIdEvent(Type t, const QByteArray &id) : - TcfTrkEvent(t), m_id(id) +// -------------- Logging event + +CodaLoggingWriteEvent::CodaLoggingWriteEvent(const QByteArray &console, const QByteArray &message) : + CodaEvent(LoggingWriteEvent), m_console(console), m_message(message) +{ +} + +QString CodaLoggingWriteEvent::toString() const +{ + QByteArray msgBA = m_console; + msgBA += ": "; + msgBA += m_message; + return QString::fromUtf8(msgBA); +} + +// -------------- CodaIdEvent +CodaIdEvent::CodaIdEvent(Type t, const QByteArray &id) : + CodaEvent(t), m_id(id) { } -// ---------- TcfTrkIdsEvent -TcfTrkIdsEvent::TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids) : - TcfTrkEvent(t), m_ids(ids) +// ---------- CodaIdsEvent +CodaIdsEvent::CodaIdsEvent(Type t, const QVector<QByteArray> &ids) : + CodaEvent(t), m_ids(ids) { } -QString TcfTrkIdsEvent::joinedIdString(const char sep) const +QString CodaIdsEvent::joinedIdString(const char sep) const { return joinByteArrays(m_ids, sep); } -// ---------------- TcfTrkRunControlContextAddedEvent -TcfTrkRunControlContextAddedEvent::TcfTrkRunControlContextAddedEvent(const RunControlContexts &c) : - TcfTrkEvent(RunControlContextAdded), m_contexts(c) +// ---------------- CodaRunControlContextAddedEvent +CodaRunControlContextAddedEvent::CodaRunControlContextAddedEvent(const RunControlContexts &c) : + CodaEvent(RunControlContextAdded), m_contexts(c) { } -TcfTrkRunControlContextAddedEvent - *TcfTrkRunControlContextAddedEvent::parseEvent(const QVector<JsonValue> &values) +CodaRunControlContextAddedEvent + *CodaRunControlContextAddedEvent::parseEvent(const QVector<JsonValue> &values) { // Parse array of contexts if (values.size() < 1 || values.front().type() != JsonValue::Array) @@ -467,10 +497,10 @@ TcfTrkRunControlContextAddedEvent if (context.parse(v)) contexts.push_back(context); } - return new TcfTrkRunControlContextAddedEvent(contexts); + return new CodaRunControlContextAddedEvent(contexts); } -QString TcfTrkRunControlContextAddedEvent::toString() const +QString CodaRunControlContextAddedEvent::toString() const { QString rc; QTextStream str(&rc); @@ -484,42 +514,45 @@ QString TcfTrkRunControlContextAddedEvent::toString() const return rc; } -// --------------- TcfTrkRunControlContextRemovedEvent -TcfTrkRunControlContextRemovedEvent::TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &ids) : - TcfTrkIdsEvent(RunControlContextRemoved, ids) +// --------------- CodaRunControlContextRemovedEvent +CodaRunControlContextRemovedEvent::CodaRunControlContextRemovedEvent(const QVector<QByteArray> &ids) : + CodaIdsEvent(RunControlContextRemoved, ids) { } -QString TcfTrkRunControlContextRemovedEvent::toString() const +QString CodaRunControlContextRemovedEvent::toString() const { return QLatin1String("RunControl: Removed contexts '") + joinedIdString() + ("'."); } -// --------------- TcfTrkRunControlContextSuspendedEvent -TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(const QByteArray &id, +// --------------- CodaRunControlContextSuspendedEvent +CodaRunControlContextSuspendedEvent::CodaRunControlContextSuspendedEvent(const QByteArray &id, const QByteArray &reason, + const QByteArray &message, quint64 pc) : - TcfTrkIdEvent(RunControlSuspended, id), m_pc(pc), m_reason(reason) + CodaIdEvent(RunControlSuspended, id), m_pc(pc), m_reason(reason), m_message(message) { } -TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(Type t, +CodaRunControlContextSuspendedEvent::CodaRunControlContextSuspendedEvent(Type t, const QByteArray &id, const QByteArray &reason, quint64 pc) : - TcfTrkIdEvent(t, id), m_pc(pc), m_reason(reason) + CodaIdEvent(t, id), m_pc(pc), m_reason(reason) { } -void TcfTrkRunControlContextSuspendedEvent::format(QTextStream &str) const +void CodaRunControlContextSuspendedEvent::format(QTextStream &str) const { str.setIntegerBase(16); str << "RunControl: '" << idString() << "' suspended at 0x" << m_pc << ": '" << m_reason << "'."; str.setIntegerBase(10); + if (!m_message.isEmpty()) + str << " (" <<m_message << ')'; } -QString TcfTrkRunControlContextSuspendedEvent::toString() const +QString CodaRunControlContextSuspendedEvent::toString() const { QString rc; QTextStream str(&rc); @@ -527,36 +560,46 @@ QString TcfTrkRunControlContextSuspendedEvent::toString() const return rc; } -TcfTrkRunControlContextSuspendedEvent::Reason TcfTrkRunControlContextSuspendedEvent::reason() const +CodaRunControlContextSuspendedEvent::Reason CodaRunControlContextSuspendedEvent::reason() const { if (m_reason == sharedLibrarySuspendReasonC) return ModuleLoad; if (m_reason == "Breakpoint") return BreakPoint; // 'Data abort exception'/'Thread has panicked' ... unfortunately somewhat unspecific. - if (m_reason.contains("exception") || m_reason.contains("panick")) + if (m_reason.contains("Exception") || m_reason.contains("panick")) return Crash; return Other; } -TcfTrkRunControlModuleLoadContextSuspendedEvent::TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id, +CodaRunControlModuleLoadContextSuspendedEvent::CodaRunControlModuleLoadContextSuspendedEvent(const QByteArray &id, const QByteArray &reason, quint64 pc, const ModuleLoadEventInfo &mi) : - TcfTrkRunControlContextSuspendedEvent(RunControlModuleLoadSuspended, id, reason, pc), + CodaRunControlContextSuspendedEvent(RunControlModuleLoadSuspended, id, reason, pc), m_mi(mi) { } -QString TcfTrkRunControlModuleLoadContextSuspendedEvent::toString() const +QString CodaRunControlModuleLoadContextSuspendedEvent::toString() const { QString rc; QTextStream str(&rc); - TcfTrkRunControlContextSuspendedEvent::format(str); + CodaRunControlContextSuspendedEvent::format(str); str << ' '; m_mi.format(str); return rc; } +// -------------- CodaIdEvent +CodaProcessExitedEvent::CodaProcessExitedEvent(const QByteArray &id) : + CodaEvent(ProcessExitedEvent), m_id(id) +{ +} + +QString CodaProcessExitedEvent::toString() const +{ + return QString("Process \"%1\" exited").arg(idString()); +} -} // namespace tcftrk +} // namespace Coda diff --git a/tools/runonphone/symbianutils/tcftrkmessage.h b/tools/runonphone/symbianutils/codamessage.h index cee8584..68347cb 100644 --- a/tools/runonphone/symbianutils/tcftrkmessage.h +++ b/tools/runonphone/symbianutils/codamessage.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef TRCFTRKMESSAGE_H -#define TRCFTRKMESSAGE_H +#ifndef CODAMESSAGE_H +#define CODAMESSAGE_H #include "symbianutils_global.h" @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QTextStream; QT_END_NAMESPACE -namespace tcftrk { +namespace Coda { class JsonValue; class JsonInputStream; @@ -61,10 +61,14 @@ enum Services { RunControlService, ProcessesService, MemoryService, - SettingsService, // non-standard, trk specific + SettingsService, // non-standard, CODA specific BreakpointsService, RegistersService, - SimpleRegistersService, // non-standard, trk specific + LoggingService, // non-standard, CODA specific + FileSystemService, + SymbianInstallService, // non-standard, CODA specific + SymbianOSData, // non-standard, CODA specific + DebugSessionControl, // non-standard, CODA specific UnknownService }; // Note: Check string array 'serviceNamesC' of same size when modifying this. @@ -138,7 +142,7 @@ struct SYMBIANUTILS_EXPORT ModuleLoadEventInfo { bool requireResume; }; -// Breakpoint as supported by TcfTrk source June 2010 +// Breakpoint as supported by Coda source June 2010 // TODO: Add watchpoints,etc once they are implemented struct SYMBIANUTILS_EXPORT Breakpoint { enum Type { Software, Hardware, Auto }; @@ -162,8 +166,8 @@ struct SYMBIANUTILS_EXPORT Breakpoint { SYMBIANUTILS_EXPORT JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b); // Event hierarchy -class SYMBIANUTILS_EXPORT TcfTrkEvent { - Q_DISABLE_COPY(TcfTrkEvent) +class SYMBIANUTILS_EXPORT CodaEvent { + Q_DISABLE_COPY(CodaEvent) public: enum Type { None, LocatorHello, @@ -172,40 +176,57 @@ public: RunControlSuspended, RunControlBreakpointSuspended, RunControlModuleLoadSuspended, - RunControlResumed + RunControlResumed, + LoggingWriteEvent, // Non-standard + ProcessExitedEvent // Non-standard }; - virtual ~TcfTrkEvent(); + virtual ~CodaEvent(); Type type() const; virtual QString toString() const; - static TcfTrkEvent *parseEvent(Services s, const QByteArray &name, const QVector<JsonValue> &val); + static CodaEvent *parseEvent(Services s, const QByteArray &name, const QVector<JsonValue> &val); protected: - explicit TcfTrkEvent(Type type = None); + explicit CodaEvent(Type type = None); private: const Type m_type; }; // ServiceHello -class SYMBIANUTILS_EXPORT TcfTrkLocatorHelloEvent : public TcfTrkEvent { +class SYMBIANUTILS_EXPORT CodaLocatorHelloEvent : public CodaEvent { public: - explicit TcfTrkLocatorHelloEvent(const QStringList &); + explicit CodaLocatorHelloEvent(const QStringList &); - const QStringList &services() { return m_services; } + const QStringList &services() const { return m_services; } virtual QString toString() const; private: QStringList m_services; }; +// Logging event (non-standard, CODA specific) +class SYMBIANUTILS_EXPORT CodaLoggingWriteEvent : public CodaEvent { +public: + explicit CodaLoggingWriteEvent(const QByteArray &console, const QByteArray &message); + + QByteArray message() const { return m_message; } + QByteArray console() const { return m_console; } + + virtual QString toString() const; + +private: + const QByteArray m_console; + const QByteArray m_message; +}; + // Base for events that just have one id as parameter // (simple suspend) -class SYMBIANUTILS_EXPORT TcfTrkIdEvent : public TcfTrkEvent { +class SYMBIANUTILS_EXPORT CodaIdEvent : public CodaEvent { protected: - explicit TcfTrkIdEvent(Type t, const QByteArray &id); + explicit CodaIdEvent(Type t, const QByteArray &id); public: QByteArray id() const { return m_id; } QString idString() const { return QString::fromUtf8(m_id); } @@ -216,9 +237,9 @@ private: // Base for events that just have some ids as parameter // (context removed) -class SYMBIANUTILS_EXPORT TcfTrkIdsEvent : public TcfTrkEvent { +class SYMBIANUTILS_EXPORT CodaIdsEvent : public CodaEvent { protected: - explicit TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids); + explicit CodaIdsEvent(Type t, const QVector<QByteArray> &ids); public: QVector<QByteArray> ids() const { return m_ids; } @@ -229,44 +250,46 @@ private: }; // RunControlContextAdded -class SYMBIANUTILS_EXPORT TcfTrkRunControlContextAddedEvent : public TcfTrkEvent { +class SYMBIANUTILS_EXPORT CodaRunControlContextAddedEvent : public CodaEvent { public: typedef QVector<RunControlContext> RunControlContexts; - explicit TcfTrkRunControlContextAddedEvent(const RunControlContexts &c); + explicit CodaRunControlContextAddedEvent(const RunControlContexts &c); const RunControlContexts &contexts() const { return m_contexts; } virtual QString toString() const; - static TcfTrkRunControlContextAddedEvent *parseEvent(const QVector<JsonValue> &val); + static CodaRunControlContextAddedEvent *parseEvent(const QVector<JsonValue> &val); private: const RunControlContexts m_contexts; }; // RunControlContextRemoved -class SYMBIANUTILS_EXPORT TcfTrkRunControlContextRemovedEvent : public TcfTrkIdsEvent { +class SYMBIANUTILS_EXPORT CodaRunControlContextRemovedEvent : public CodaIdsEvent { public: - explicit TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &id); + explicit CodaRunControlContextRemovedEvent(const QVector<QByteArray> &id); virtual QString toString() const; }; // Simple RunControlContextSuspended (process/thread) -class SYMBIANUTILS_EXPORT TcfTrkRunControlContextSuspendedEvent : public TcfTrkIdEvent { +class SYMBIANUTILS_EXPORT CodaRunControlContextSuspendedEvent : public CodaIdEvent { public: enum Reason { BreakPoint, ModuleLoad, Crash, Other } ; - explicit TcfTrkRunControlContextSuspendedEvent(const QByteArray &id, + explicit CodaRunControlContextSuspendedEvent(const QByteArray &id, const QByteArray &reason, + const QByteArray &message, quint64 pc = 0); virtual QString toString() const; quint64 pc() const { return m_pc; } QByteArray reasonID() const { return m_reason; } Reason reason() const; + QByteArray message() const { return m_message; } protected: - explicit TcfTrkRunControlContextSuspendedEvent(Type t, + explicit CodaRunControlContextSuspendedEvent(Type t, const QByteArray &id, const QByteArray &reason, quint64 pc = 0); @@ -275,12 +298,13 @@ protected: private: const quint64 m_pc; const QByteArray m_reason; + const QByteArray m_message; }; // RunControlContextSuspended due to module load -class SYMBIANUTILS_EXPORT TcfTrkRunControlModuleLoadContextSuspendedEvent : public TcfTrkRunControlContextSuspendedEvent { +class SYMBIANUTILS_EXPORT CodaRunControlModuleLoadContextSuspendedEvent : public CodaRunControlContextSuspendedEvent { public: - explicit TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id, + explicit CodaRunControlModuleLoadContextSuspendedEvent(const QByteArray &id, const QByteArray &reason, quint64 pc, const ModuleLoadEventInfo &mi); @@ -292,5 +316,18 @@ private: const ModuleLoadEventInfo m_mi; }; -} // namespace tcftrk -#endif // TRCFTRKMESSAGE_H +// Process exited event +class SYMBIANUTILS_EXPORT CodaProcessExitedEvent : public CodaEvent { +public: + explicit CodaProcessExitedEvent(const QByteArray &id); + + QByteArray id() const { return m_id; } + QString idString() const { return QString::fromUtf8(m_id); } + virtual QString toString() const; + +private: + const QByteArray m_id; +}; + +} // namespace Coda +#endif // CODAMESSAGE_H diff --git a/tools/runonphone/symbianutils/json.cpp b/tools/runonphone/symbianutils/json.cpp index a2d53ce..93f9395 100644 --- a/tools/runonphone/symbianutils/json.cpp +++ b/tools/runonphone/symbianutils/json.cpp @@ -49,6 +49,7 @@ #include <QtCore/QTextStream> #include <QtCore/QDebug> #include <QtCore/QStringList> +#include <QtCore/QVariant> #include <ctype.h> @@ -59,7 +60,7 @@ #define JDEBUG(s) #endif -namespace tcftrk { +namespace Coda { static void skipSpaces(const char *&from, const char *to) { @@ -100,6 +101,7 @@ QByteArray JsonValue::parseNumber(const char *&from, const char *to) QByteArray JsonValue::parseCString(const char *&from, const char *to) { QByteArray result; + const char * const fromSaved = from; JDEBUG("parseCString: " << QByteArray(from, to - from)); if (*from != '"') { qDebug() << "JSON Parse Error, double quote expected"; @@ -117,7 +119,8 @@ QByteArray JsonValue::parseCString(const char *&from, const char *to) if (*ptr == '\\') { ++ptr; if (ptr == to) { - qDebug() << "JSON Parse Error, unterminated backslash escape"; + qWarning("JSON Parse Error, unterminated backslash escape in '%s'", + QByteArray(fromSaved, to - fromSaved).constData()); from = ptr; // So we don't hang return QByteArray(); } @@ -142,8 +145,24 @@ QByteArray JsonValue::parseCString(const char *&from, const char *to) case 'v': *dst++ = '\v'; break; case '"': *dst++ = '"'; break; case '\\': *dst++ = '\\'; break; - default: - { + case 'u': { // 4 digit hex escape as in '\u000a' + if (end - src < 4) { + qWarning("JSON Parse Error, too few hex digits in \\u-escape in '%s' obtained from '%s'", + result.constData(), QByteArray(fromSaved, to - fromSaved).constData()); + return QByteArray(); + } + bool ok; + const uchar prod = QByteArray(src, 4).toUInt(&ok, 16); + if (!ok) { + qWarning("JSON Parse Error, invalid hex digits in \\u-escape in '%s' obtained from '%s'", + result.constData(), QByteArray(fromSaved, to - fromSaved).constData()); + return QByteArray(); + } + *dst++ = prod; + src += 4; + } + break; + default: { // Up to 3 decimal digits: Not sure if this is supported in JSON? int chars = 0; uchar prod = 0; forever { @@ -157,7 +176,8 @@ QByteArray JsonValue::parseCString(const char *&from, const char *to) c = *src++; } if (!chars) { - qDebug() << "JSON Parse Error, unrecognized backslash escape"; + qWarning("JSON Parse Error, unrecognized backslash escape in string '%s' obtained from '%s'", + result.constData(), QByteArray(fromSaved, to - fromSaved).constData()); return QByteArray(); } *dst++ = prod; @@ -360,7 +380,7 @@ QByteArray JsonValue::toString(bool multiline, int indent) const break; case String: if (!m_name.isEmpty()) - result += m_name + "="; + result += m_name + '='; result += '"' + escapeCString(m_data) + '"'; break; case Number: @@ -380,30 +400,69 @@ QByteArray JsonValue::toString(bool multiline, int indent) const if (multiline) { result += "{\n"; dumpChildren(&result, multiline, indent + 1); - result += '\n' + ind(indent) + "}"; + result += '\n' + ind(indent) + '}'; } else { - result += "{"; + result += '{'; dumpChildren(&result, multiline, indent + 1); - result += "}"; + result += '}'; } break; case Array: if (!m_name.isEmpty()) - result += m_name + "="; + result += m_name + '='; if (multiline) { result += "[\n"; dumpChildren(&result, multiline, indent + 1); - result += '\n' + ind(indent) + "]"; + result += '\n' + ind(indent) + ']'; } else { - result += "["; + result += '['; dumpChildren(&result, multiline, indent + 1); - result += "]"; + result += ']'; } break; } return result; } + +QVariant JsonValue::toVariant() const +{ + switch (m_type) { + case String: + return QString(m_data); + case Number: { + bool ok; + qint64 val = QString(m_data).toLongLong(&ok); + if (ok) + return val; + return QVariant(); + } + case Object: { + QHash<QString, QVariant> hash; + for (int i = 0; i < m_children.size(); ++i) { + QString name(m_children[i].name()); + QVariant val = m_children[i].toVariant(); + hash.insert(name, val); + } + return hash; + } + case Array: { + QList<QVariant> list; + for (int i = 0; i < m_children.size(); ++i) { + list.append(m_children[i].toVariant()); + } + return list; + } + case Boolean: + return data() == QByteArray("true"); + case Invalid: + case NullObject: + default: + return QVariant(); + } +} + + void JsonValue::fromString(const QByteArray &ba) { const char *from = ba.constBegin(); @@ -486,5 +545,5 @@ JsonInputStream &JsonInputStream::operator<<(bool b) return *this; } -} // namespace tcftrk +} // namespace Coda diff --git a/tools/runonphone/symbianutils/json.h b/tools/runonphone/symbianutils/json.h index ca9aebf..11273e0 100644 --- a/tools/runonphone/symbianutils/json.h +++ b/tools/runonphone/symbianutils/json.h @@ -48,7 +48,7 @@ #include <QtCore/QStringList> #include <QtCore/QVector> -namespace tcftrk { +namespace Coda { class SYMBIANUTILS_EXPORT JsonValue { @@ -67,7 +67,7 @@ public: Boolean, Object, NullObject, - Array, + Array }; Type m_type; @@ -95,6 +95,8 @@ public: void fromString(const QByteArray &str); void setStreamOutput(const QByteArray &name, const QByteArray &content); + QVariant toVariant() const; + private: static QByteArray parseCString(const char *&from, const char *to); static QByteArray parseNumber(const char *&from, const char *to); @@ -144,6 +146,6 @@ private: QByteArray &m_target; }; -} // namespace tcftrk +} // namespace Coda #endif // SYMBIANUTILS_JSON_H diff --git a/tools/runonphone/symbianutils/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp index e52cf28..ff67881 100644 --- a/tools/runonphone/symbianutils/launcher.cpp +++ b/tools/runonphone/symbianutils/launcher.cpp @@ -52,6 +52,7 @@ #include <QtCore/QDebug> #include <QtCore/QQueue> #include <QtCore/QFile> +#include <QtCore/QFileInfo> #include <QtCore/QScopedPointer> #include <cstdio> @@ -86,15 +87,24 @@ void CrashReportState::clear() } struct LauncherPrivate { - struct CopyState { - QString sourceFileName; - QString destinationFileName; + struct TransferState { + int currentFileName; uint copyFileHandle; QScopedPointer<QByteArray> data; qint64 position; QScopedPointer<QFile> localFile; }; + struct CopyState : public TransferState { + QStringList sourceFileNames; + QStringList destinationFileNames; + }; + + struct DownloadState : public TransferState { + QString sourceFileName; + QString destinationFileName; + }; + explicit LauncherPrivate(const TrkDevicePtr &d); TrkDevicePtr m_device; @@ -106,21 +116,28 @@ struct LauncherPrivate { Session m_session; // global-ish data (process id, target information) CopyState m_copyState; - CopyState m_downloadState; + DownloadState m_downloadState; QString m_fileName; - QStringList m_commandLineArgs; - QString m_installFileName; + QString m_commandLineArgs; + QStringList m_installFileNames; + int m_currentInstallFileName; int m_verbose; Launcher::Actions m_startupActions; bool m_closeDevice; CrashReportState m_crashReportState; + Launcher::InstallationMode m_installationMode; + Launcher::InstallationMode m_currentInstallationStep; + char m_installationDrive; }; LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) : m_device(d), m_state(Launcher::Disconnected), m_verbose(0), - m_closeDevice(true) + m_closeDevice(true), + m_installationMode(Launcher::InstallationModeSilentAndUser), + m_currentInstallationStep(Launcher::InstallationModeSilent), + m_installationDrive('C') { if (m_device.isNull()) m_device = TrkDevicePtr(new TrkDevice); @@ -159,6 +176,16 @@ void Launcher::setState(State s) } } +void Launcher::setInstallationMode(InstallationMode installation) +{ + d->m_installationMode = installation; +} + +void Launcher::setInstallationDrive(char drive) +{ + d->m_installationDrive = drive; +} + void Launcher::addStartupActions(trk::Launcher::Actions startupActions) { d->m_startupActions = Actions(d->m_startupActions | startupActions); @@ -184,10 +211,11 @@ void Launcher::setFileName(const QString &name) d->m_fileName = name; } -void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) +void Launcher::setCopyFileNames(const QStringList &srcNames, const QStringList &dstNames) { - d->m_copyState.sourceFileName = srcName; - d->m_copyState.destinationFileName = dstName; + d->m_copyState.sourceFileNames = srcNames; + d->m_copyState.destinationFileNames = dstNames; + d->m_copyState.currentFileName = 0; } void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName) @@ -196,12 +224,13 @@ void Launcher::setDownloadFileName(const QString &srcName, const QString &dstNam d->m_downloadState.destinationFileName = dstName; } -void Launcher::setInstallFileName(const QString &name) +void Launcher::setInstallFileNames(const QStringList &names) { - d->m_installFileName = name; + d->m_installFileNames = names; + d->m_currentInstallFileName = 0; } -void Launcher::setCommandLineArgs(const QStringList &args) +void Launcher::setCommandLineArgs(const QString &args) { d->m_commandLineArgs = args; } @@ -227,6 +256,16 @@ void Launcher::setCloseDevice(bool c) d->m_closeDevice = c; } +Launcher::InstallationMode Launcher::installationMode() const +{ + return d->m_installationMode; +} + +char Launcher::installationDrive() const +{ + return d->m_installationDrive; +} + bool Launcher::startServer(QString *errorMessage) { errorMessage->clear(); @@ -241,29 +280,30 @@ bool Launcher::startServer(QString *errorMessage) if (!d->m_fileName.isEmpty()) str << " Executable=" << d->m_fileName; if (!d->m_commandLineArgs.isEmpty()) - str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' '))); - if (!d->m_copyState.sourceFileName.isEmpty()) - str << " Package/Source=" << d->m_copyState.sourceFileName; - if (!d->m_copyState.destinationFileName.isEmpty()) - str << " Remote Package/Destination=" << d->m_copyState.destinationFileName; + str << " Arguments= " << d->m_commandLineArgs; + for (int i = 0; i < d->m_copyState.sourceFileNames.size(); ++i) { + str << " Package/Source=" << d->m_copyState.sourceFileNames.at(i); + str << " Remote Package/Destination=" << d->m_copyState.destinationFileNames.at(i); + } if (!d->m_downloadState.sourceFileName.isEmpty()) str << " Source=" << d->m_downloadState.sourceFileName; if (!d->m_downloadState.destinationFileName.isEmpty()) str << " Destination=" << d->m_downloadState.destinationFileName; - if (!d->m_installFileName.isEmpty()) - str << " Install file=" << d->m_installFileName; + if (!d->m_installFileNames.isEmpty()) + foreach (const QString &installFileName, d->m_installFileNames) + str << " Install file=" << installFileName; logMessage(msg); } if (d->m_startupActions & ActionCopy) { - if (d->m_copyState.sourceFileName.isEmpty()) { + if (d->m_copyState.sourceFileNames.isEmpty()) { qWarning("No local filename given for copying package."); return false; - } else if (d->m_copyState.destinationFileName.isEmpty()) { + } else if (d->m_copyState.destinationFileNames.isEmpty()) { qWarning("No remote filename given for copying package."); return false; } } - if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) { + if (d->m_startupActions & ActionInstall && d->m_installFileNames.isEmpty()) { qWarning("No package name given for installing."); return false; } @@ -303,7 +343,7 @@ void Launcher::handleConnect(const TrkResult &result) if (d->m_startupActions & ActionCopy) copyFileToRemote(); else if (d->m_startupActions & ActionInstall) - installRemotePackageSilently(); + installRemotePackage(); else if (d->m_startupActions & ActionRun) startInferiorIfNeeded(); else if (d->m_startupActions & ActionDownload) @@ -416,9 +456,9 @@ void Launcher::handleResult(const TrkResult &result) case TrkNotifyAck: break; case TrkNotifyNak: { // NAK - logMessage(prefix + "NAK: " + str); + logMessage(prefix + QLatin1String("NAK: ") + str); //logMessage(prefix << "TOKEN: " << result.token); - logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0))); + logMessage(prefix + QLatin1String("ERROR: ") + errorMessage(result.data.at(0))); break; } case TrkNotifyStopped: { // Notified Stopped @@ -433,12 +473,12 @@ void Launcher::handleResult(const TrkResult &result) break; } case TrkNotifyException: { // Notify Exception (obsolete) - logMessage(prefix + "NOTE: EXCEPTION " + str); + logMessage(prefix + QLatin1String("NOTE: EXCEPTION ") + str); d->m_device->sendTrkAck(result.token); break; } case TrkNotifyInternalError: { // - logMessage(prefix + "NOTE: INTERNAL ERROR: " + str); + logMessage(prefix + QLatin1String("NOTE: INTERNAL ERROR: ") + str); d->m_device->sendTrkAck(result.token); break; } @@ -497,22 +537,22 @@ void Launcher::handleResult(const TrkResult &result) break; } case TrkNotifyProcessorStarted: { // NotifyProcessorStarted - logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str); + logMessage(prefix + QLatin1String("NOTE: PROCESSOR STARTED: ") + str); d->m_device->sendTrkAck(result.token); break; } case TrkNotifyProcessorStandBy: { // NotifyProcessorStandby - logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str); + logMessage(prefix + QLatin1String("NOTE: PROCESSOR STANDBY: ") + str); d->m_device->sendTrkAck(result.token); break; } case TrkNotifyProcessorReset: { // NotifyProcessorReset - logMessage(prefix + "NOTE: PROCESSOR RESET: " + str); + logMessage(prefix + QLatin1String("NOTE: PROCESSOR RESET: ") + str); d->m_device->sendTrkAck(result.token); break; } default: { - logMessage(prefix + "INVALID: " + str); + logMessage(prefix + QLatin1String("INVALID: ") + str); break; } } @@ -560,15 +600,15 @@ static inline QString msgCannotOpenLocalFile(const QString &fileName, const QStr void Launcher::handleFileCreation(const TrkResult &result) { if (result.errorCode() || result.data.size() < 6) { - const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileName, result.errorString()); + const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), result.errorString()); logMessage(msg); - emit canNotCreateFile(d->m_copyState.destinationFileName, msg); + emit canNotCreateFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), msg); disconnectTrk(); return; } const char *data = result.data.data(); d->m_copyState.copyFileHandle = extractInt(data + 2); - const QString localFileName = d->m_copyState.sourceFileName; + const QString localFileName = d->m_copyState.sourceFileNames.at(d->m_copyState.currentFileName); QFile file(localFileName); d->m_copyState.position = 0; if (!file.open(QIODevice::ReadOnly)) { @@ -644,7 +684,7 @@ void Launcher::handleCopy(const TrkResult &result) { if (result.errorCode() || result.data.size() < 4) { closeRemoteFile(true); - emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString()); + emit canNotWriteFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), result.errorString()); disconnectTrk(); } else { continueCopying(extractShort(result.data.data() + 2)); @@ -680,7 +720,7 @@ void Launcher::closeRemoteFile(bool failed) d->m_device->sendTrkMessage(TrkCloseFile, failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied), ba); - d->m_copyState.data.reset(); + d->m_copyState.data.reset(0); d->m_copyState.copyFileHandle = 0; d->m_copyState.position = 0; } @@ -688,15 +728,21 @@ void Launcher::closeRemoteFile(bool failed) void Launcher::handleFileCopied(const TrkResult &result) { if (result.errorCode()) - emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString()); - if (d->m_startupActions & ActionInstall) - installRemotePackageSilently(); - else if (d->m_startupActions & ActionRun) + emit canNotCloseFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), result.errorString()); + + ++d->m_copyState.currentFileName; + + if (d->m_startupActions & ActionInstall && d->m_copyState.currentFileName < d->m_copyState.sourceFileNames.size()) { + copyFileToRemote(); + } else if (d->m_startupActions & ActionInstall) { + installRemotePackage(); + } else if (d->m_startupActions & ActionRun) { startInferiorIfNeeded(); - else if (d->m_startupActions & ActionDownload) + } else if (d->m_startupActions & ActionDownload) { copyFileFromRemote(); - else + } else { disconnectTrk(); + } } void Launcher::handleCpuType(const TrkResult &result) @@ -840,16 +886,18 @@ void Launcher::disconnectTrk() void Launcher::copyFileToRemote() { - emit copyingStarted(); + QFileInfo fileInfo(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName)); + emit copyingStarted(fileInfo.fileName()); QByteArray ba; ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary - appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); + appendString(&ba, d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName).toLocal8Bit(), TargetByteOrder, false); d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); } void Launcher::copyFileFromRemote() { - emit copyingStarted(); + QFileInfo fileInfo(d->m_downloadState.sourceFileName); + emit copyingStarted(fileInfo.fileName()); QByteArray ba; ba.append(char(9)); //kDSFileOpenRead | kDSFileOpenBinary appendString(&ba, d->m_downloadState.sourceFileName.toLocal8Bit(), TargetByteOrder, false); @@ -858,23 +906,59 @@ void Launcher::copyFileFromRemote() void Launcher::installRemotePackageSilently() { - emit installingStarted(); + emit installingStarted(d->m_installFileNames.at(d->m_currentInstallFileName)); + d->m_currentInstallationStep = InstallationModeSilent; QByteArray ba; - ba.append('C'); - appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); + ba.append(static_cast<char>(QChar::toUpper((ushort)d->m_installationDrive))); + appendString(&ba, d->m_installFileNames.at(d->m_currentInstallFileName).toLocal8Bit(), TargetByteOrder, false); d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); } +void Launcher::installRemotePackageByUser() +{ + emit installingStarted(d->m_installFileNames.at(d->m_currentInstallFileName)); + d->m_currentInstallationStep = InstallationModeUser; + QByteArray ba; + appendString(&ba, d->m_installFileNames.at(d->m_currentInstallFileName).toLocal8Bit(), TargetByteOrder, false); + d->m_device->sendTrkMessage(TrkInstallFile2, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); +} + +void Launcher::installRemotePackage() +{ + switch (installationMode()) { + case InstallationModeSilent: + case InstallationModeSilentAndUser: + installRemotePackageSilently(); + break; + case InstallationModeUser: + installRemotePackageByUser(); + break; + default: + break; + } +} + void Launcher::handleInstallPackageFinished(const TrkResult &result) { if (result.errorCode()) { - emit canNotInstall(d->m_installFileName, result.errorString()); + if (installationMode() == InstallationModeSilentAndUser + && d->m_currentInstallationStep & InstallationModeSilent) { + installRemotePackageByUser(); + return; + } + emit canNotInstall(d->m_installFileNames.at(d->m_currentInstallFileName), result.errorString()); disconnectTrk(); return; - } else { - emit installingFinished(); } - if (d->m_startupActions & ActionRun) { + + ++d->m_currentInstallFileName; + + if (d->m_currentInstallFileName == d->m_installFileNames.size()) + emit installingFinished(); + + if (d->m_startupActions & ActionInstall && d->m_currentInstallFileName < d->m_installFileNames.size()) { + installRemotePackage(); + } else if (d->m_startupActions & ActionRun) { startInferiorIfNeeded(); } else if (d->m_startupActions & ActionDownload) { copyFileFromRemote(); @@ -884,7 +968,7 @@ void Launcher::handleInstallPackageFinished(const TrkResult &result) } QByteArray Launcher::startProcessMessage(const QString &executable, - const QStringList &arguments) + const QString &arguments) { // It's not started yet QByteArray ba; @@ -894,7 +978,7 @@ QByteArray Launcher::startProcessMessage(const QString &executable, QByteArray commandLineBa = executable.toLocal8Bit(); commandLineBa.append(char(0)); if (!arguments.isEmpty()) - commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit()); + commandLineBa.append(arguments.toLocal8Bit()); appendString(&ba, commandLineBa, TargetByteOrder, true); return ba; } @@ -930,6 +1014,7 @@ void Launcher::startInferiorIfNeeded() logMessage("Process already 'started'"); return; } + d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item } @@ -950,7 +1035,10 @@ Launcher *Launcher::acquireFromDeviceManager(const QString &serverName, SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); const QSharedPointer<trk::TrkDevice> device = sdm->acquireDevice(serverName); if (device.isNull()) { - *errorMessage = tr("Unable to acquire a device for port '%1'. It appears to be in use.").arg(serverName); + if (serverName.isEmpty()) + *errorMessage = tr("No device is connected. Please connect a device and try again."); + else + *errorMessage = tr("Unable to acquire a device for port '%1'. It appears to be in use.").arg(serverName); return 0; } // Wire release signal. @@ -964,6 +1052,8 @@ Launcher *Launcher::acquireFromDeviceManager(const QString &serverName, // Preliminary release of device, disconnecting the signal. void Launcher::releaseToDeviceManager(Launcher *launcher) { + Q_ASSERT(launcher); + SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); // Disentangle launcher and its device, remove connection from destroyed launcher->setCloseDevice(false); diff --git a/tools/runonphone/symbianutils/launcher.h b/tools/runonphone/symbianutils/launcher.h index 63189f1..2f674af 100644 --- a/tools/runonphone/symbianutils/launcher.h +++ b/tools/runonphone/symbianutils/launcher.h @@ -64,6 +64,13 @@ class SYMBIANUTILS_EXPORT Launcher : public QObject public: typedef void (Launcher::*TrkCallBack)(const TrkResult &); + enum InstallationMode { + InstallationModeSilent = 0x1, + InstallationModeUser = 0x2, + InstallationModeSilentAndUser = InstallationModeSilent|InstallationModeUser + //first attempt is silent and if it fails then the user installation is launched + }; + enum Actions { ActionPingOnly = 0x0, ActionCopy = 0x1, @@ -95,13 +102,19 @@ public: void setTrkServerName(const QString &name); QString trkServerName() const; void setFileName(const QString &name); - void setCopyFileName(const QString &srcName, const QString &dstName); + void setCopyFileNames(const QStringList &srcName, const QStringList &dstName); void setDownloadFileName(const QString &srcName, const QString &dstName); - void setInstallFileName(const QString &name); - void setCommandLineArgs(const QStringList &args); + void setInstallFileNames(const QStringList &names); + void setCommandLineArgs(const QString &args); bool startServer(QString *errorMessage); + void setInstallationMode(InstallationMode installation); + void setInstallationDrive(char drive); void setVerbose(int v); void setSerialFrame(bool b); + + InstallationMode installationMode() const; + char installationDrive() const; + bool serialFrame() const; // Close device or leave it open bool closeDevice() const; @@ -122,7 +135,7 @@ public: // Create Trk message to start a process. static QByteArray startProcessMessage(const QString &executable, - const QStringList &arguments); + const QString &arguments); // Create Trk message to read memory static QByteArray readMemoryMessage(uint pid, uint tid, uint from, uint len); static QByteArray readRegistersMessage(uint pid, uint tid); @@ -135,14 +148,14 @@ public: signals: void deviceDescriptionReceived(const QString &port, const QString &description); - void copyingStarted(); + void copyingStarted(const QString &fileName); void canNotConnect(const QString &errorMessage); void canNotCreateFile(const QString &filename, const QString &errorMessage); void canNotOpenFile(const QString &filename, const QString &errorMessage); void canNotOpenLocalFile(const QString &filename, const QString &errorMessage); void canNotWriteFile(const QString &filename, const QString &errorMessage); void canNotCloseFile(const QString &filename, const QString &errorMessage); - void installingStarted(); + void installingStarted(const QString &packageName); void canNotInstall(const QString &packageFilename, const QString &errorMessage); void installingFinished(); void startingApplication(); @@ -152,7 +165,7 @@ signals: void applicationOutputReceived(const QString &output); void copyProgress(int percent); void stateChanged(int); - void processStopped(uint pc, uint pid, uint tid, const QString& reason); + void processStopped(uint pc, uint pid, uint tid, const QString &reason); void processResumed(uint pid, uint tid); void libraryLoaded(const trk::Library &lib); void libraryUnloaded(const trk::Library &lib); @@ -198,6 +211,8 @@ private: void copyFileToRemote(); void copyFileFromRemote(); void installRemotePackageSilently(); + void installRemotePackageByUser(); + void installRemotePackage(); void startInferiorIfNeeded(); void handleFinished(); diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.cpp b/tools/runonphone/symbianutils/symbiandevicemanager.cpp index 02727d7..23f5348 100644 --- a/tools/runonphone/symbianutils/symbiandevicemanager.cpp +++ b/tools/runonphone/symbianutils/symbiandevicemanager.cpp @@ -41,7 +41,11 @@ #include "symbiandevicemanager.h" #include "trkdevice.h" +#include "codadevice.h" +#include "virtualserialdevice.h" +#include <QtCore/QCoreApplication> +#include <QtCore/QEvent> #include <QtCore/QSettings> #include <QtCore/QStringList> #include <QtCore/QFileInfo> @@ -50,6 +54,9 @@ #include <QtCore/QSharedData> #include <QtCore/QScopedPointer> #include <QtCore/QSignalMapper> +#include <QtCore/QThread> +#include <QtCore/QWaitCondition> +#include <QtCore/QTimer> namespace SymbianUtils { @@ -66,7 +73,7 @@ public: SymbianDeviceData(); ~SymbianDeviceData(); - inline bool isOpen() const { return !device.isNull() && device->isOpen(); } + bool isOpen() const; void forcedClose(); QString portName; @@ -77,15 +84,25 @@ public: DeviceCommunicationType type; QSharedPointer<trk::TrkDevice> device; - bool deviceAcquired; + QSharedPointer<Coda::CodaDevice> codaDevice; + int deviceAcquired; }; SymbianDeviceData::SymbianDeviceData() : type(SerialPortCommunication), - deviceAcquired(false) + deviceAcquired(0) { } +bool SymbianDeviceData::isOpen() const +{ + if (device) + return device->isOpen(); + if (codaDevice) + return codaDevice->device()->isOpen(); + return false; +} + SymbianDeviceData::~SymbianDeviceData() { forcedClose(); @@ -101,7 +118,10 @@ void SymbianDeviceData::forcedClose() if (deviceAcquired) qWarning("Device on '%s' unplugged while an operation is in progress.", qPrintable(portName)); - device->close(); + if (device) + device->close(); + else + codaDevice->device()->close(); } } @@ -167,7 +187,7 @@ SymbianDevice::TrkDevicePtr SymbianDevice::acquireDevice() m_data->device->setPort(m_data->portName); m_data->device->setSerialFrame(m_data->type == SerialPortCommunication); } - m_data->deviceAcquired = true; + m_data->deviceAcquired = 1; return m_data->device; } @@ -184,7 +204,7 @@ void SymbianDevice::releaseDevice(TrkDevicePtr *ptr /* = 0 */) ptr->data()->disconnect(); *ptr = TrkDevicePtr(); } - m_data->deviceAcquired = false; + m_data->deviceAcquired = 0; } else { qWarning("Internal error: Attempt to release device that is not acquired."); } @@ -255,17 +275,34 @@ SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &cd) // ------------- SymbianDeviceManagerPrivate struct SymbianDeviceManagerPrivate { - SymbianDeviceManagerPrivate() : m_initialized(false), m_destroyReleaseMapper(0) {} + SymbianDeviceManagerPrivate() : m_initialized(false), m_devicesLock(QMutex::Recursive) {} bool m_initialized; SymbianDeviceManager::SymbianDeviceList m_devices; - QSignalMapper *m_destroyReleaseMapper; + QMutex m_devicesLock; // Used for protecting access to m_devices and serialising getCodaDevice/delayedClosePort + // The following 2 variables are needed to manage requests for a TCF port not coming from the main thread + int m_constructTcfPortEventType; + QMutex m_codaPortWaitMutex; +}; + +class QConstructTcfPortEvent : public QEvent +{ +public: + QConstructTcfPortEvent(QEvent::Type eventId, const QString &portName, CodaDevicePtr *device, QWaitCondition *waiter) : + QEvent(eventId), m_portName(portName), m_device(device), m_waiter(waiter) + {} + + QString m_portName; + CodaDevicePtr* m_device; + QWaitCondition *m_waiter; }; + SymbianDeviceManager::SymbianDeviceManager(QObject *parent) : QObject(parent), d(new SymbianDeviceManagerPrivate) { + d->m_constructTcfPortEventType = QEvent::registerEventType(); } SymbianDeviceManager::~SymbianDeviceManager() @@ -276,11 +313,13 @@ SymbianDeviceManager::~SymbianDeviceManager() SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const { ensureInitialized(); + QMutexLocker lock(&d->m_devicesLock); return d->m_devices; } QString SymbianDeviceManager::toString() const { + QMutexLocker lock(&d->m_devicesLock); QString rc; QTextStream str(&rc); str << d->m_devices.size() << " devices:\n"; @@ -305,6 +344,7 @@ int SymbianDeviceManager::findByPortName(const QString &p) const QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const { + QMutexLocker lock(&d->m_devicesLock); const int idx = findByPortName(port); return idx == -1 ? QString() : d->m_devices.at(idx).friendlyName(); } @@ -326,6 +366,106 @@ SymbianDeviceManager::TrkDevicePtr return rc; } +CodaDevicePtr SymbianDeviceManager::getCodaDevice(const QString &port) +{ + ensureInitialized(); + QMutexLocker lock(&d->m_devicesLock); + const int idx = findByPortName(port); + if (idx == -1) { + qWarning("Attempt to acquire device '%s' that does not exist.", qPrintable(port)); + if (debug) + qDebug() << *this; + return CodaDevicePtr(); + } + SymbianDevice& device = d->m_devices[idx]; + if (device.m_data->device && device.m_data->device.data()->isOpen()) { + qWarning("Attempting to open a port '%s' that is configured for TRK!", qPrintable(port)); + return CodaDevicePtr(); + } + CodaDevicePtr& devicePtr = device.m_data->codaDevice; + if (devicePtr.isNull() || !devicePtr->device()->isOpen()) { + // Check we instanciate in the correct thread - we can't afford to create the CodaDevice (and more specifically, open the VirtualSerialDevice) in a thread that isn't guaranteed to be long-lived. + // Therefore, if we're not in SymbianDeviceManager's thread, rejig things so it's opened in the main thread + if (QThread::currentThread() != thread()) { + // SymbianDeviceManager is owned by the main thread + d->m_codaPortWaitMutex.lock(); + QWaitCondition waiter; + QCoreApplication::postEvent(this, new QConstructTcfPortEvent((QEvent::Type)d->m_constructTcfPortEventType, port, &devicePtr, &waiter)); + waiter.wait(&d->m_codaPortWaitMutex); + // When the wait returns (due to the wakeAll in SymbianDeviceManager::customEvent), the CodaDevice will be fully set up + d->m_codaPortWaitMutex.unlock(); + } else { + // We're in the main thread, just set it up directly + constructCodaPort(devicePtr, port); + } + // We still carry on in the case we failed to open so the client can access the IODevice's errorString() + } + if (devicePtr->device()->isOpen()) + device.m_data->deviceAcquired++; + return devicePtr; +} + +void SymbianDeviceManager::constructCodaPort(CodaDevicePtr& device, const QString& portName) +{ + QMutexLocker locker(&d->m_codaPortWaitMutex); + if (device.isNull()) { + device = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice); + const QSharedPointer<SymbianUtils::VirtualSerialDevice> serialDevice(new SymbianUtils::VirtualSerialDevice(portName)); + device->setSerialFrame(true); + device->setDevice(serialDevice); + } + if (!device->device()->isOpen()) { + bool ok = device->device().staticCast<SymbianUtils::VirtualSerialDevice>()->open(QIODevice::ReadWrite); + if (!ok && debug) { + qDebug("SymbianDeviceManager: Failed to open port %s", qPrintable(portName)); + } + } +} + +void SymbianDeviceManager::customEvent(QEvent *event) +{ + if (event->type() == d->m_constructTcfPortEventType) { + QConstructTcfPortEvent* constructEvent = static_cast<QConstructTcfPortEvent*>(event); + constructCodaPort(*constructEvent->m_device, constructEvent->m_portName); + constructEvent->m_waiter->wakeAll(); // Should only ever be one thing waiting on this + } +} + +void SymbianDeviceManager::releaseCodaDevice(CodaDevicePtr &port) +{ + if (port) { + QMutexLocker(&d->m_devicesLock); + // Check if this was the last reference to the port, if so close it after a short delay + foreach (const SymbianDevice& device, d->m_devices) { + if (device.m_data->codaDevice.data() == port.data()) { + if (device.m_data->deviceAcquired > 0) + device.m_data->deviceAcquired--; + if (device.m_data->deviceAcquired == 0) { + if (debug) + qDebug("Starting timer to close port %s", qPrintable(device.m_data->portName)); + QTimer::singleShot(1000, this, SLOT(delayedClosePort())); + } + break; + } + } + port.clear(); + } +} + +void SymbianDeviceManager::delayedClosePort() +{ + // Find any coda ports that are still open but have a reference count of zero, and delete them + QMutexLocker(&d->m_devicesLock); + foreach (const SymbianDevice& device, d->m_devices) { + Coda::CodaDevice* codaDevice = device.m_data->codaDevice.data(); + if (codaDevice && device.m_data->deviceAcquired == 0 && codaDevice->device()->isOpen()) { + if (debug) + qDebug("Closing device %s", qPrintable(device.m_data->portName)); + device.m_data->codaDevice->device()->close(); + } + } +} + void SymbianDeviceManager::update() { update(true); @@ -336,11 +476,10 @@ void SymbianDeviceManager::releaseDevice(const QString &port) const int idx = findByPortName(port); if (debug) qDebug() << "SymbianDeviceManager::releaseDevice" << port << idx << sender(); - if (idx != -1) { + if (idx != -1) d->m_devices[idx].releaseDevice(); - } else { + else qWarning("Attempt to release non-existing device %s.", qPrintable(port)); - } } void SymbianDeviceManager::setAdditionalInformation(const QString &port, const QString &ai) @@ -358,6 +497,8 @@ void SymbianDeviceManager::ensureInitialized() const void SymbianDeviceManager::update(bool emitSignals) { + QMutexLocker lock(&d->m_devicesLock); + static int n = 0; typedef SymbianDeviceList::iterator SymbianDeviceListIterator; @@ -377,6 +518,7 @@ void SymbianDeviceManager::update(bool emitSignals) } // Merge the lists and emit the respective added/removed signals, assuming // no one can plug a different device on the same port at the speed of lightning + SymbianDeviceList removedDevices; if (!d->m_devices.isEmpty()) { // Find deleted devices for (SymbianDeviceListIterator oldIt = d->m_devices.begin(); oldIt != d->m_devices.end(); ) { @@ -386,25 +528,33 @@ void SymbianDeviceManager::update(bool emitSignals) SymbianDevice toBeDeleted = *oldIt; toBeDeleted.forcedClose(); oldIt = d->m_devices.erase(oldIt); - if (emitSignals) - emit deviceRemoved(toBeDeleted); + removedDevices.append(toBeDeleted); } } } + SymbianDeviceList addedDevices; if (!newDevices.isEmpty()) { // Find new devices and insert in order foreach(const SymbianDevice &newDevice, newDevices) { if (!d->m_devices.contains(newDevice)) { d->m_devices.append(newDevice); - if (emitSignals) - emit deviceAdded(newDevice); + addedDevices.append(newDevice); } } if (d->m_devices.size() > 1) qStableSort(d->m_devices.begin(), d->m_devices.end()); } - if (emitSignals) + + lock.unlock(); + if (emitSignals) { + foreach (const SymbianDevice &device, removedDevices) { + emit deviceRemoved(device); + } + foreach (const SymbianDevice &device, addedDevices) { + emit deviceAdded(device); + } emit updated(); + } if (debug) qDebug("<SerialDeviceLister::update\n%s\n", qPrintable(toString())); @@ -457,7 +607,9 @@ SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() } // New kernel versions support /dev/ttyUSB0, /dev/ttyUSB1. Trk responds // on the latter (usually), try first. - static const char *usbTtyDevices[] = { "/dev/ttyUSB1", "/dev/ttyUSB0" }; + static const char *usbTtyDevices[] = { + "/dev/ttyUSB3", "/dev/ttyUSB2", "/dev/ttyUSB1", "/dev/ttyUSB0", + "/dev/ttyACM3", "/dev/ttyACM2", "/dev/ttyACM1", "/dev/ttyACM0"}; const int usbTtyCount = sizeof(usbTtyDevices)/sizeof(const char *); for (int d = 0; d < usbTtyCount; d++) { const QString ttyUSBDevice = QLatin1String(usbTtyDevices[d]); @@ -486,4 +638,106 @@ SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm) return d; } -} // namespace SymbianUtilsInternal +OstChannel *SymbianDeviceManager::getOstChannel(const QString &port, uchar channelId) +{ + CodaDevicePtr coda = getCodaDevice(port); + if (coda.isNull() || !coda->device()->isOpen()) + return 0; + return new OstChannel(coda, channelId); +} + +struct OstChannelPrivate +{ + CodaDevicePtr m_codaPtr; + QByteArray m_dataBuffer; + uchar m_channelId; + bool m_hasReceivedData; +}; + +OstChannel::OstChannel(const CodaDevicePtr &codaPtr, uchar channelId) + : d(new OstChannelPrivate) +{ + d->m_codaPtr = codaPtr; + d->m_channelId = channelId; + d->m_hasReceivedData = false; + connect(codaPtr.data(), SIGNAL(unknownEvent(uchar, QByteArray)), this, SLOT(ostDataReceived(uchar,QByteArray))); + connect(codaPtr->device().data(), SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose())); + QIODevice::open(ReadWrite|Unbuffered); +} + +void OstChannel::close() +{ + QIODevice::close(); + if (d && d->m_codaPtr.data()) { + disconnect(d->m_codaPtr.data(), 0, this, 0); + SymbianDeviceManager::instance()->releaseCodaDevice(d->m_codaPtr); + } +} + +OstChannel::~OstChannel() +{ + close(); + delete d; +} + +void OstChannel::flush() +{ + //TODO d->m_codaPtr->device()- +} + +qint64 OstChannel::bytesAvailable() const +{ + return d->m_dataBuffer.size(); +} + +bool OstChannel::isSequential() const +{ + return true; +} + +qint64 OstChannel::readData(char *data, qint64 maxSize) +{ + qint64 amount = qMin(maxSize, (qint64)d->m_dataBuffer.size()); + qMemCopy(data, d->m_dataBuffer.constData(), amount); + d->m_dataBuffer.remove(0, amount); + return amount; +} + +qint64 OstChannel::writeData(const char *data, qint64 maxSize) +{ + static const qint64 KMaxOstPayload = 1024; + // If necessary, split the packet up + while (maxSize) { + QByteArray dataBuf = QByteArray::fromRawData(data, qMin(KMaxOstPayload, maxSize)); + d->m_codaPtr->writeCustomData(d->m_channelId, dataBuf); + data += dataBuf.length(); + maxSize -= dataBuf.length(); + } + return maxSize; +} + +void OstChannel::ostDataReceived(uchar channelId, const QByteArray &aData) +{ + if (channelId == d->m_channelId) { + d->m_hasReceivedData = true; + d->m_dataBuffer.append(aData); + emit readyRead(); + } +} + +Coda::CodaDevice& OstChannel::codaDevice() const +{ + return *d->m_codaPtr; +} + +bool OstChannel::hasReceivedData() const +{ + return isOpen() && d->m_hasReceivedData; +} + +void OstChannel::deviceAboutToClose() +{ + close(); +} + +} // namespace SymbianUtils diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.h b/tools/runonphone/symbianutils/symbiandevicemanager.h index d65b5b0..366963c 100644 --- a/tools/runonphone/symbianutils/symbiandevicemanager.h +++ b/tools/runonphone/symbianutils/symbiandevicemanager.h @@ -44,7 +44,7 @@ #include "symbianutils_global.h" -#include <QtCore/QObject> +#include <QtCore/QIODevice> #include <QtCore/QExplicitlySharedDataPointer> #include <QtCore/QSharedPointer> @@ -56,17 +56,23 @@ QT_END_NAMESPACE namespace trk { class TrkDevice; } +namespace Coda { + class CodaDevice; +} namespace SymbianUtils { struct SymbianDeviceManagerPrivate; class SymbianDeviceData; +class OstChannel; enum DeviceCommunicationType { SerialPortCommunication = 0, BlueToothCommunication = 1 }; +typedef QSharedPointer<Coda::CodaDevice> CodaDevicePtr; + // SymbianDevice: Explicitly shared device data and a TrkDevice // instance that can be acquired (exclusively) for use. // A device removal from the manager will result in the @@ -90,13 +96,6 @@ public: QString additionalInformation() const; void setAdditionalInformation(const QString &); - // Acquire: Mark the device as 'out' and return a shared pointer - // unless it is already in use by another owner. The result should not - // be passed on further. - TrkDevicePtr acquireDevice(); - // Give back a device and mark it as 'free'. - void releaseDevice(TrkDevicePtr *ptr = 0); - bool isOpen() const; // Windows only. @@ -107,6 +106,14 @@ public: QString toString() const; private: + // Acquire: Mark the device as 'out' and return a shared pointer + // unless it is already in use by another owner. The result should not + // be passed on further. + // TRK only + TrkDevicePtr acquireDevice(); + // Give back a device and mark it as 'free'. TRK only. + void releaseDevice(TrkDevicePtr *ptr = 0); + void forcedClose(); QExplicitlySharedDataPointer<SymbianDeviceData> m_data; @@ -145,9 +152,25 @@ public: SymbianDeviceList devices() const; QString toString() const; - // Acquire a device for use. See releaseDevice(). + // Acquire a TRK device for use. Assuming the port is found, equivalent to devices()[findByPortName(port)].acquireDevice(). See also releaseDevice(). TrkDevicePtr acquireDevice(const QString &port); + //// The TCF code prefers to set up the CodaDevice object itself, so we let it and just handle opening the underlying QIODevice and keeping track of the CodaDevice + //// Returns true if port was opened successfully. + + // Gets the CodaDevice, which may or may not be open depending on what other clients have already acquired it. + // Therefore once clients have set up any signals and slots they required, they should check CodaDevice::device()->isOpen() + // and if false, the open failed and they should check device()->errorString() if required. + // Caller should call releaseCodaDevice if they want the port to auto-close itself + CodaDevicePtr getCodaDevice(const QString &port); + + // Note this function makes no guarantee that someone else isn't already listening on this channel id, or that there is anything on the other end + // Returns NULL if the port couldn't be opened + OstChannel *getOstChannel(const QString &port, uchar channelId); + + // Caller is responsible for disconnecting any signals from aPort - do not assume the CodaDevice will be deleted as a result of this call. On return aPort will be clear()ed. + void releaseCodaDevice(CodaDevicePtr &aPort); + int findByPortName(const QString &p) const; QString friendlyNameForPort(const QString &port) const; @@ -162,17 +185,54 @@ signals: void deviceAdded(const SymbianUtils::SymbianDevice &d); void updated(); +private slots: + void delayedClosePort(); + private: void ensureInitialized() const; void update(bool emitSignals); SymbianDeviceList serialPorts() const; SymbianDeviceList blueToothDevices() const; + void customEvent(QEvent *event); + void constructCodaPort(CodaDevicePtr& device, const QString& portName); SymbianDeviceManagerPrivate *d; }; SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &); +struct OstChannelPrivate; + +class SYMBIANUTILS_EXPORT OstChannel : public QIODevice +{ + Q_OBJECT + +public: + void close(); + ~OstChannel(); + void flush(); + + qint64 bytesAvailable() const; + bool isSequential() const; + bool hasReceivedData() const; + + Coda::CodaDevice &codaDevice() const; + +private slots: + void ostDataReceived(uchar channelId, const QByteArray &aData); + void deviceAboutToClose(); + +private: + OstChannel(const CodaDevicePtr &codaPtr, uchar channelId); + Q_DISABLE_COPY(OstChannel) + qint64 readData(char *data, qint64 maxSize); + qint64 writeData(const char *data, qint64 maxSize); + +private: + OstChannelPrivate *d; + friend class SymbianDeviceManager; +}; + } // namespace SymbianUtils #endif // SYMBIANDEVICEMANAGER_H diff --git a/tools/runonphone/symbianutils/symbianutils.pri b/tools/runonphone/symbianutils/symbianutils.pri index f07e494..2d32680 100644 --- a/tools/runonphone/symbianutils/symbianutils.pri +++ b/tools/runonphone/symbianutils/symbianutils.pri @@ -12,9 +12,10 @@ HEADERS += $$PWD/symbianutils_global.h \ $$PWD/bluetoothlistener.h \ $$PWD/communicationstarter.h \ $$PWD/symbiandevicemanager.h \ - $$PWD/tcftrkdevice.h \ - $$PWD/tcftrkmessage.h \ - $$PWD/json.h + $$PWD/codadevice.h \ + $$PWD/codamessage.h \ + $$PWD/json.h \ + $$PWD/virtualserialdevice.h SOURCES += $$PWD/trkutils.cpp \ $$PWD/trkdevice.cpp \ @@ -22,9 +23,14 @@ SOURCES += $$PWD/trkutils.cpp \ $$PWD/bluetoothlistener.cpp \ $$PWD/communicationstarter.cpp \ $$PWD/symbiandevicemanager.cpp \ - $$PWD/tcftrkdevice.cpp \ - $$PWD/tcftrkmessage.cpp \ - $$PWD/json.cpp + $$PWD/codadevice.cpp \ + $$PWD/codamessage.cpp \ + $$PWD/json.cpp \ + $$PWD/virtualserialdevice.cpp + +DEFINES += HAS_SERIALPORT +win32:SOURCES += $$PWD/virtualserialdevice_win.cpp +unix:SOURCES += $$PWD/virtualserialdevice_posix.cpp # Tests/trklauncher is a console application contains(QT, gui) { diff --git a/tools/runonphone/symbianutils/tcftrkdevice.cpp b/tools/runonphone/symbianutils/tcftrkdevice.cpp deleted file mode 100644 index 219f673..0000000 --- a/tools/runonphone/symbianutils/tcftrkdevice.cpp +++ /dev/null @@ -1,929 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "tcftrkdevice.h" -#include "json.h" - -#include <QtNetwork/QAbstractSocket> -#include <QtCore/QDebug> -#include <QtCore/QVector> -#include <QtCore/QQueue> -#include <QtCore/QTextStream> -#include <QtCore/QDateTime> -#include <QtCore/QFileInfo> - -enum { debug = 0 }; - -static const char messageTerminatorC[] = "\003\001"; - -namespace tcftrk { -// ------------- TcfTrkCommandError - -TcfTrkCommandError::TcfTrkCommandError() : timeMS(0), code(0), alternativeCode(0) -{ -} - -void TcfTrkCommandError::clear() -{ - timeMS = 0; - code = alternativeCode = 0; - format.clear(); - alternativeOrganization.clear(); -} - -void TcfTrkCommandError::write(QTextStream &str) const -{ - if (timeMS) { - const QDateTime time(QDate(1970, 1, 1)); - str << time.addMSecs(timeMS).toString(Qt::ISODate) << ": Error code: " << code - << " '" << format << '\''; - if (!alternativeOrganization.isEmpty()) - str << " ('" << alternativeOrganization << "', code: " << alternativeCode << ')'; - } else{ - str << "<No error>"; - } -} - -QString TcfTrkCommandError::toString() const -{ - QString rc; - QTextStream str(&rc); - write(str); - return rc; -} - -/* {"Time":1277459762255,"Code":1,"AltCode":-6,"AltOrg":"POSIX","Format":"Unknown error: -6"} */ -bool TcfTrkCommandError::parse(const QVector<JsonValue> &values) -{ - // Parse an arbitrary hash (that could as well be a command response) - // and check for error elements. - unsigned errorKeyCount = 0; - clear(); - do { - if (values.isEmpty() || values.front().type() != JsonValue::Object) - break; - foreach (const JsonValue &c, values.front().children()) { - if (c.name() == "Time") { - timeMS = c.data().toULongLong(); - errorKeyCount++; - } else if (c.name() == "Code") { - code = c.data().toInt(); - errorKeyCount++; - } else if (c.name() == "Format") { - format = c.data(); - errorKeyCount++; - } else if (c.name() == "AltCode") { - alternativeCode = c.data().toInt(); - errorKeyCount++; - } else if (c.name() == "AltOrg") { - alternativeOrganization = c.data(); - errorKeyCount++; - } - } - } while (false); - const bool errorFound = errorKeyCount >= 2u; // Should be at least 'Time', 'Code'. - if (!errorFound) - clear(); - if (debug) { - qDebug() << "TcfTrkCommandError::parse: Found error: " << errorFound; - if (!values.isEmpty()) - qDebug() << values.front().toString(); - } - return errorFound; -} - -// ------------ TcfTrkCommandResult - -TcfTrkCommandResult::TcfTrkCommandResult(Type t) : - type(t), service(LocatorService) -{ -} - -TcfTrkCommandResult::TcfTrkCommandResult(char typeChar, Services s, - const QByteArray &r, - const QVector<JsonValue> &v, - const QVariant &ck) : - type(FailReply), service(s), request(r), values(v), cookie(ck) -{ - switch (typeChar) { - case 'N': - type = FailReply; - break; - case 'P': - type = ProgressReply; - break; - case 'R': - type = commandError.parse(values) ? CommandErrorReply : SuccessReply; - break; - default: - qWarning("Unknown TCF reply type '%c'", typeChar); - } -} - -QString TcfTrkCommandResult::errorString() const -{ - QString rc; - QTextStream str(&rc); - - switch (type) { - case SuccessReply: - case ProgressReply: - str << "<No error>"; - return rc; - case FailReply: - str << "NAK"; - case CommandErrorReply: - commandError.write(str); - break; - } - // Append the failed command for reference - str << " (Command was: '"; - QByteArray printableRequest = request; - printableRequest.replace('\0', '|'); - str << printableRequest << "')"; - return rc; -} - -QString TcfTrkCommandResult::toString() const -{ - QString rc; - QTextStream str(&rc); - str << "Command answer "; - switch (type) { - case SuccessReply: - str << "[success]"; - break; - case CommandErrorReply: - str << "[command error]"; - break; - case FailReply: - str << "[fail (NAK)]"; - break; - case ProgressReply: - str << "[progress]"; - break; - } - str << ", " << values.size() << " values(s) to request: '"; - QByteArray printableRequest = request; - printableRequest.replace('\0', '|'); - str << printableRequest << "' "; - if (cookie.isValid()) - str << " cookie: " << cookie.toString(); - str << '\n'; - for (int i = 0, count = values.size(); i < count; i++) - str << '#' << i << ' ' << values.at(i).toString() << '\n'; - if (type == CommandErrorReply) - str << "Error: " << errorString(); - return rc; -} - -struct TcfTrkSendQueueEntry -{ - typedef TcfTrkDevice::MessageType MessageType; - - explicit TcfTrkSendQueueEntry(MessageType mt, - int tok, - Services s, - const QByteArray &d, - const TcfTrkCallback &cb= TcfTrkCallback(), - const QVariant &ck = QVariant()) : - messageType(mt), service(s), data(d), token(tok), cookie(ck), callback(cb) {} - - MessageType messageType; - Services service; - QByteArray data; - int token; - QVariant cookie; - TcfTrkCallback callback; -}; - -struct TcfTrkDevicePrivate { - typedef TcfTrkDevice::IODevicePtr IODevicePtr; - typedef QHash<int, TcfTrkSendQueueEntry> TokenWrittenMessageMap; - - TcfTrkDevicePrivate(); - - const QByteArray m_messageTerminator; - - IODevicePtr m_device; - unsigned m_verbose; - QByteArray m_readBuffer; - int m_token; - QQueue<TcfTrkSendQueueEntry> m_sendQueue; - TokenWrittenMessageMap m_writtenMessages; - QVector<QByteArray> m_registerNames; -}; - -TcfTrkDevicePrivate::TcfTrkDevicePrivate() : - m_messageTerminator(messageTerminatorC), - m_verbose(0), m_token(0) -{ -} - -TcfTrkDevice::TcfTrkDevice(QObject *parent) : - QObject(parent), d(new TcfTrkDevicePrivate) -{ -} - -TcfTrkDevice::~TcfTrkDevice() -{ - delete d; -} - -QVector<QByteArray> TcfTrkDevice::registerNames() const -{ - return d->m_registerNames; -} - -void TcfTrkDevice::setRegisterNames(const QVector<QByteArray>& n) -{ - d->m_registerNames = n; - if (d->m_verbose) { - QString msg; - QTextStream str(&msg); - const int count = n.size(); - str << "Registers (" << count << "): "; - for (int i = 0; i < count; i++) - str << '#' << i << '=' << n.at(i) << ' '; - emitLogMessage(msg); - } -} - -TcfTrkDevice::IODevicePtr TcfTrkDevice::device() const -{ - return d->m_device; -} - -TcfTrkDevice::IODevicePtr TcfTrkDevice::takeDevice() -{ - const IODevicePtr old = d->m_device; - if (!old.isNull()) { - old.data()->disconnect(this); - d->m_device = IODevicePtr(); - } - d->m_readBuffer.clear(); - d->m_token = 0; - d->m_sendQueue.clear(); - return old; -} - -void TcfTrkDevice::setDevice(const IODevicePtr &dp) -{ - if (dp.data() == d->m_device.data()) - return; - if (dp.isNull()) { - emitLogMessage(QLatin1String("Internal error: Attempt to set NULL device.")); - return; - } - takeDevice(); - d->m_device = dp; - connect(dp.data(), SIGNAL(readyRead()), this, SLOT(slotDeviceReadyRead())); - if (QAbstractSocket *s = qobject_cast<QAbstractSocket *>(dp.data())) { - connect(s, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotDeviceError())); - connect(s, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(slotDeviceSocketStateChanged())); - } -} - -void TcfTrkDevice::slotDeviceError() -{ - const QString message = d->m_device->errorString(); - emitLogMessage(message); - emit error(message); -} - -void TcfTrkDevice::slotDeviceSocketStateChanged() -{ - if (const QAbstractSocket *s = qobject_cast<const QAbstractSocket *>(d->m_device.data())) { - const QAbstractSocket::SocketState st = s->state(); - switch (st) { - case QAbstractSocket::UnconnectedState: - emitLogMessage(QLatin1String("Unconnected")); - break; - case QAbstractSocket::HostLookupState: - emitLogMessage(QLatin1String("HostLookupState")); - break; - case QAbstractSocket::ConnectingState: - emitLogMessage(QLatin1String("Connecting")); - break; - case QAbstractSocket::ConnectedState: - emitLogMessage(QLatin1String("Connected")); - break; - case QAbstractSocket::ClosingState: - emitLogMessage(QLatin1String("Closing")); - break; - default: - emitLogMessage(QString::fromLatin1("State %1").arg(st)); - break; - } - } -} - -static inline QString debugMessage(QByteArray message, const char *prefix = 0) -{ - message.replace('\0', '|'); - const QString messageS = QString::fromLatin1(message); - return prefix ? - (QLatin1String(prefix) + messageS) : messageS; -} - -void TcfTrkDevice::slotDeviceReadyRead() -{ - d->m_readBuffer += d->m_device->readAll(); - // Take complete message off front of readbuffer. - do { - const int messageEndPos = d->m_readBuffer.indexOf(d->m_messageTerminator); - if (messageEndPos == -1) - break; - const QByteArray message = d->m_readBuffer.left(messageEndPos); - if (debug) - qDebug("Read:\n%s", qPrintable(formatData(message))); - if (const int errorCode = parseMessage(message)) { - emitLogMessage(QString::fromLatin1("Parse error %1 for: %2").arg(errorCode).arg(debugMessage(message))); - } - d->m_readBuffer.remove(0, messageEndPos + d->m_messageTerminator.size()); - } while (!d->m_readBuffer.isEmpty()); - checkSendQueue(); // Send off further message -} - -// Split \0-terminated message into tokens, skipping the initial type character -static inline QVector<QByteArray> splitMessage(const QByteArray &message) -{ - QVector<QByteArray> tokens; - tokens.reserve(7); - const int messageSize = message.size(); - for (int pos = 2; pos < messageSize; ) { - const int nextPos = message.indexOf('\0', pos); - if (nextPos == -1) - break; - tokens.push_back(message.mid(pos, nextPos - pos)); - pos = nextPos + 1; - } - return tokens; -} - -int TcfTrkDevice::parseMessage(const QByteArray &message) -{ - if (d->m_verbose) - emitLogMessage(debugMessage(message, "TCF ->")); - // Special JSON parse error message or protocol format error. - // The port is usually closed after receiving it. - // "\3\2{"Time":1276096098255,"Code":3,"Format": "Protocol format error"}" - if (message.startsWith("\003\002")) { - QByteArray text = message.mid(2); - const QString errorMessage = QString::fromLatin1("Parse error received: %1").arg(QString::fromAscii(text)); - emit error(errorMessage); - return 0; - } - if (message.size() < 4 || message.at(1) != '\0') - return 1; - // Split into tokens - const char type = message.at(0); - const QVector<QByteArray> tokens = splitMessage(message); - switch (type) { - case 'E': - return parseTcfEvent(tokens); - case 'R': // Command replies - case 'N': - case 'P': - return parseTcfCommandReply(type, tokens); - default: - emitLogMessage(QString::fromLatin1("Unhandled message type: %1").arg(debugMessage(message))); - return 756; - } - return 0; -} - -int TcfTrkDevice::parseTcfCommandReply(char type, const QVector<QByteArray> &tokens) -{ - typedef TcfTrkDevicePrivate::TokenWrittenMessageMap::iterator TokenWrittenMessageMapIterator; - // Find the corresponding entry in the written messages hash. - const int tokenCount = tokens.size(); - if (tokenCount < 1) - return 234; - bool tokenOk; - const int token = tokens.at(0).toInt(&tokenOk); - if (!tokenOk) - return 235; - const TokenWrittenMessageMapIterator it = d->m_writtenMessages.find(token); - if (it == d->m_writtenMessages.end()) { - qWarning("TcfTrkDevice: Internal error: token %d not found for '%s'", - token, qPrintable(joinByteArrays(tokens))); - return 236; - } - // No callback: remove entry from map, happy - if (!it.value().callback) { - d->m_writtenMessages.erase(it); - return 0; - } - // Parse values into JSON - QVector<JsonValue> values; - values.reserve(tokenCount); - for (int i = 1; i < tokenCount; i++) { - if (!tokens.at(i).isEmpty()) { // Strange: Empty tokens occur. - const JsonValue value(tokens.at(i)); - if (value.isValid()) { - values.push_back(value); - } else { - qWarning("JSON parse error for reply to command token %d: #%d '%s'", - token, i, tokens.at(i).constData()); - d->m_writtenMessages.erase(it); - return -1; - } - } - } - - // Construct result and invoke callback, remove entry from map. - TcfTrkCallback callback = it.value().callback; - TcfTrkCommandResult result(type, it.value().service, it.value().data, - values, it.value().cookie); - d->m_writtenMessages.erase(it); - callback(result); - return 0; -} - -static const char locatorAnswerC[] = "E\0Locator\0Hello\0[\"Locator\"]"; - -int TcfTrkDevice::parseTcfEvent(const QVector<QByteArray> &tokens) -{ - // Event: Ignore the periodical heartbeat event, answer 'Hello', - // emit signal for the rest - if (tokens.size() < 3) - return 433; - const Services service = serviceFromName(tokens.at(0).constData()); - if (service == LocatorService && tokens.at(1) == "peerHeartBeat") - return 0; - QVector<JsonValue> values; - for (int i = 2; i < tokens.size(); i++) { - const JsonValue value(tokens.at(i)); - if (!value.isValid()) - return 434; - values.push_back(value); - } - // Parse known events, emit signals - QScopedPointer<TcfTrkEvent> knownEvent(TcfTrkEvent::parseEvent(service, tokens.at(1), values)); - if (!knownEvent.isNull()) { - // Answer hello event. - if (knownEvent->type() == TcfTrkEvent::LocatorHello) - writeMessage(QByteArray(locatorAnswerC, sizeof(locatorAnswerC))); - emit tcfEvent(*knownEvent); - } - emit genericTcfEvent(service, tokens.at(1), values); - - if (debug || d->m_verbose) { - QString msg; - QTextStream str(&msg); - if (knownEvent.isNull()) { - str << "Event: " << tokens.at(0) << ' ' << tokens.at(1) << '\n'; - foreach(const JsonValue &val, values) - str << " " << val.toString() << '\n'; - } else { - str << knownEvent->toString(); - } - emitLogMessage(msg); - } - - return 0; -} - -unsigned TcfTrkDevice::verbose() const -{ - return d->m_verbose; -} - -void TcfTrkDevice::setVerbose(unsigned v) -{ - d->m_verbose = v; -} - -void TcfTrkDevice::emitLogMessage(const QString &m) -{ - if (debug) - qWarning("%s", qPrintable(m)); - emit logMessage(m); -} - -bool TcfTrkDevice::checkOpen() -{ - if (d->m_device.isNull()) { - emitLogMessage(QLatin1String("Internal error: No device set on TcfTrkDevice.")); - return false; - } - if (!d->m_device->isOpen()) { - emitLogMessage(QLatin1String("Internal error: Device not open in TcfTrkDevice.")); - return false; - } - return true; -} - -void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command, - const char *commandParameters, int commandParametersLength, - const TcfTrkCallback &callBack, - const QVariant &cookie) - -{ - if (!checkOpen()) - return; - // Format the message - const int token = d->m_token++; - QByteArray data; - data.reserve(30 + commandParametersLength); - data.append('C'); - data.append('\0'); - data.append(QByteArray::number(token)); - data.append('\0'); - data.append(serviceName(service)); - data.append('\0'); - data.append(command); - data.append('\0'); - if (commandParametersLength) - data.append(commandParameters, commandParametersLength); - const TcfTrkSendQueueEntry entry(mt, token, service, data, callBack, cookie); - d->m_sendQueue.enqueue(entry); - checkSendQueue(); -} - -void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command, - const QByteArray &commandParameters, - const TcfTrkCallback &callBack, - const QVariant &cookie) -{ - sendTcfTrkMessage(mt, service, command, commandParameters.constData(), commandParameters.size(), - callBack, cookie); -} - -// Enclose in message frame and write. -void TcfTrkDevice::writeMessage(QByteArray data) -{ - if (!checkOpen()) - return; - - if (d->m_verbose) - emitLogMessage(debugMessage(data, "TCF <-")); - - // Ensure \0-termination which easily gets lost in QByteArray CT. - if (!data.endsWith('\0')) - data.append('\0'); - data += d->m_messageTerminator; - - if (debug > 1) - qDebug("Writing:\n%s", qPrintable(formatData(data))); - - d->m_device->write(data); - if (QAbstractSocket *as = qobject_cast<QAbstractSocket *>(d->m_device.data())) - as->flush(); -} - -void TcfTrkDevice::checkSendQueue() -{ - // Fire off messages or invoke noops until a message with reply is found - // and an entry to writtenMessages is made. - while (d->m_writtenMessages.empty()) { - if (d->m_sendQueue.isEmpty()) - break; - TcfTrkSendQueueEntry entry = d->m_sendQueue.dequeue(); - switch (entry.messageType) { - case MessageWithReply: - d->m_writtenMessages.insert(entry.token, entry); - writeMessage(entry.data); - break; - case MessageWithoutReply: - writeMessage(entry.data); - break; - case NoopMessage: // Invoke the noop-callback for synchronization - if (entry.callback) { - TcfTrkCommandResult noopResult(TcfTrkCommandResult::SuccessReply); - noopResult.cookie = entry.cookie; - entry.callback(noopResult); - } - break; - } - } -} - -// Fix slashes -static inline QString fixFileName(QString in) -{ - in.replace(QLatin1Char('/'), QLatin1Char('\\')); - return in; -} - -// Start a process (consisting of a non-reply setSettings and start). -void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack, - const QString &binaryIn, - unsigned uid, - QStringList arguments, - QString workingDirectory, - bool debugControl, - const QStringList &additionalLibraries, - const QVariant &cookie) -{ - // Obtain the bin directory, expand by c:/sys/bin if missing - const QChar backSlash('\\'); - int slashPos = binaryIn.lastIndexOf(QLatin1Char('/')); - if (slashPos == -1) - slashPos = binaryIn.lastIndexOf(backSlash); - const QString sysBin = QLatin1String("c:/sys/bin"); - const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1); - const QString binaryDirectory = slashPos == -1 ? sysBin : binaryIn.left(slashPos); - const QString binary = fixFileName(binaryDirectory + QLatin1Char('/') + binaryFileName); - - // Fixup: Does argv[0] convention exist on Symbian? - arguments.push_front(binary); - if (workingDirectory.isEmpty()) - workingDirectory = sysBin; - - // Format settings with empty dummy parameter - QByteArray setData; - JsonInputStream setStr(setData); - setStr << "" << '\0' - << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ']' - << '\0' << '[' - << binary << ',' - << '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ',' - << additionalLibraries - << ']'; - sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData); - - QByteArray startData; - JsonInputStream startStr(startData); - startStr << fixFileName(workingDirectory) - << '\0' << binary << '\0' << arguments << '\0' - << QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard) - << debugControl; - sendTcfTrkMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie); -} - -void TcfTrkDevice::sendProcessTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << id; - sendTcfTrkMessage(MessageWithReply, ProcessesService, "terminate", data, callBack, cookie); -} - -void TcfTrkDevice::sendRunControlTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << id; - sendTcfTrkMessage(MessageWithReply, RunControlService, "terminate", data, callBack, cookie); -} - -// Non-standard: Remove executable from settings -void TcfTrkDevice::sendSettingsRemoveExecutableCommand(const QString &binaryIn, - unsigned uid, - const QStringList &additionalLibraries, - const QVariant &cookie) -{ - QByteArray setData; - JsonInputStream setStr(setData); - setStr << "" << '\0' - << '[' << "removedExecutables" << ',' << "removedLibraries" << ']' - << '\0' << '[' - << '{' << QFileInfo(binaryIn).fileName() << ':' << QString::number(uid, 16) << '}' << ',' - << additionalLibraries - << ']'; - sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData, TcfTrkCallback(), cookie); -} - -void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - RunControlResumeMode mode, - unsigned count, - quint64 rangeStart, - quint64 rangeEnd, - const QVariant &cookie) -{ - QByteArray resumeData; - JsonInputStream str(resumeData); - str << id << '\0' << int(mode) << '\0' << count; - switch (mode) { - case RM_STEP_OVER_RANGE: - case RM_STEP_INTO_RANGE: - case RM_REVERSE_STEP_OVER_RANGE: - case RM_REVERSE_STEP_INTO_RANGE: - str << '\0' << '{' << "RANGE_START" << ':' << rangeStart - << ',' << "RANGE_END" << ':' << rangeEnd << '}'; - break; - default: - break; - } - sendTcfTrkMessage(MessageWithReply, RunControlService, "resume", resumeData, callBack, cookie); -} - -void TcfTrkDevice::sendRunControlSuspendCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << id; - sendTcfTrkMessage(MessageWithReply, RunControlService, "suspend", data, callBack, cookie); -} - -void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - sendRunControlResumeCommand(callBack, id, RM_RESUME, 1, 0, 0, cookie); -} - -void TcfTrkDevice::sendBreakpointsAddCommand(const TcfTrkCallback &callBack, - const Breakpoint &bp, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << bp; - sendTcfTrkMessage(MessageWithReply, BreakpointsService, "add", data, callBack, cookie); -} - -void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - sendBreakpointsRemoveCommand(callBack, QVector<QByteArray>(1, id), cookie); -} - -void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &ids, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << ids; - sendTcfTrkMessage(MessageWithReply, BreakpointsService, "remove", data, callBack, cookie); -} - -void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - bool enable, - const QVariant &cookie) -{ - sendBreakpointsEnableCommand(callBack, QVector<QByteArray>(1, id), enable, cookie); -} - -void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &ids, - bool enable, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << ids; - sendTcfTrkMessage(MessageWithReply, BreakpointsService, - enable ? "enable" : "disable", - data, callBack, cookie); -} - -void TcfTrkDevice::sendMemorySetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, const QByteArray& data, - const QVariant &cookie) -{ - QByteArray getData; - JsonInputStream str(getData); - // start/word size/mode. Mode should ideally be 1 (continue on error?) - str << contextId << '\0' << start << '\0' << 1 << '\0' << data.size() << '\0' << 1 - << '\0' << data.toBase64(); - sendTcfTrkMessage(MessageWithReply, MemoryService, "set", getData, callBack, cookie); -} - -void TcfTrkDevice::sendMemoryGetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, quint64 size, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - // start/word size/mode. Mode should ideally be 1 (continue on error?) - str << contextId << '\0' << start << '\0' << 1 << '\0' << size << '\0' << 1; - sendTcfTrkMessage(MessageWithReply, MemoryService, "get", data, callBack, cookie); -} - -QByteArray TcfTrkDevice::parseMemoryGet(const TcfTrkCommandResult &r) -{ - if (r.type != TcfTrkCommandResult::SuccessReply || r.values.size() < 1) - return QByteArray(); - const JsonValue &memoryV = r.values.front(); - - if (memoryV.type() != JsonValue::String || memoryV.data().size() < 2 - || !memoryV.data().endsWith('=')) - return QByteArray(); - // Catch errors reported as hash: - // R.4."TlVMTA==".{"Time":1276786871255,"Code":1,"AltCode":-38,"AltOrg":"POSIX","Format":"BadDescriptor"} - // Not sure what to make of it. - if (r.values.size() >= 2 && r.values.at(1).type() == JsonValue::Object) - qWarning("Error retrieving memory: %s", r.values.at(1).toString(false).constData()); - // decode - const QByteArray memory = QByteArray::fromBase64(memoryV.data()); - if (memory.isEmpty()) - qWarning("Base64 decoding of %s failed.", memoryV.data().constData()); - if (debug) - qDebug("TcfTrkDevice::parseMemoryGet: received %d bytes", memory.size()); - return memory; -} - -void TcfTrkDevice::sendRegistersGetMCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QVector<QByteArray> &ids, - const QVariant &cookie) -{ - // TODO: use "Registers" (which uses base64-encoded values) - QByteArray data; - JsonInputStream str(data); - str << contextId << '\0' << ids; - sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "get", data, callBack, cookie); -} - -void TcfTrkDevice::sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned start, unsigned count) -{ - const unsigned end = start + count; - if (end > (unsigned)d->m_registerNames.size()) { - qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", end, d->m_registerNames.size()); - return; - } - - QVector<QByteArray> ids; - ids.reserve(count); - for (unsigned i = start; i < end; i++) - ids.push_back(d->m_registerNames.at(i)); - sendRegistersGetMCommand(callBack, contextId, ids, QVariant(start)); -} - -// Set register -void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QByteArray &id, - unsigned value, - const QVariant &cookie) -{ - // TODO: use "Registers" (which uses base64-encoded values) - QByteArray data; - JsonInputStream str(data); - str << contextId << '\0' << QVector<QByteArray>(1, id) - << '\0' << QVector<QByteArray>(1, QByteArray::number(value, 16)); - sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "set", data, callBack, cookie); -} - -// Set register -void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned registerNumber, - unsigned value, - const QVariant &cookie) -{ - if (registerNumber >= (unsigned)d->m_registerNames.size()) { - qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", registerNumber, d->m_registerNames.size()); - return; - } - sendRegistersSetCommand(callBack, contextId, - d->m_registerNames[registerNumber], - value, cookie); -} - -} // namespace tcftrk diff --git a/tools/runonphone/symbianutils/tcftrkdevice.h b/tools/runonphone/symbianutils/tcftrkdevice.h deleted file mode 100644 index 8f754e8..0000000 --- a/tools/runonphone/symbianutils/tcftrkdevice.h +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TCFTRKENGINE_H -#define TCFTRKENGINE_H - -#include "symbianutils_global.h" -#include "tcftrkmessage.h" -#include "callback.h" -#include "json.h" - -#include <QtCore/QObject> -#include <QtCore/QSharedPointer> -#include <QtCore/QVector> -#include <QtCore/QVariant> -#include <QtCore/QStringList> - -QT_BEGIN_NAMESPACE -class QIODevice; -class QTextStream; -QT_END_NAMESPACE - -namespace tcftrk { - -struct TcfTrkDevicePrivate; -struct Breakpoint; - -/* Command error handling in TCF: - * 1) 'Severe' errors (JSON format, parameter format): Trk emits a - * nonstandard message (\3\2 error parameters) and closes the connection. - * 2) Protocol errors: 'N' without error message is returned. - * 3) Errors in command execution: 'R' with a TCF error hash is returned - * (see TcfTrkCommandError). */ - -/* Error code return in 'R' reply to command - * (see top of 'Services' documentation). */ -struct SYMBIANUTILS_EXPORT TcfTrkCommandError { - TcfTrkCommandError(); - void clear(); - operator bool() const { return timeMS != 0; } - QString toString() const; - void write(QTextStream &str) const; - bool parse(const QVector<JsonValue> &values); - - quint64 timeMS; // Since 1.1.1970 - int code; - QByteArray format; // message - // 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno> - QByteArray alternativeOrganization; - int alternativeCode; -}; - -/* Answer to a Tcf command passed to the callback. */ -struct SYMBIANUTILS_EXPORT TcfTrkCommandResult { - enum Type { - SuccessReply, // 'R' and no error -> all happy. - CommandErrorReply, // 'R' with TcfTrkCommandError received - ProgressReply, // 'P', progress indicator - FailReply // 'N' Protocol NAK, severe error - }; - - explicit TcfTrkCommandResult(Type t = SuccessReply); - explicit TcfTrkCommandResult(char typeChar, Services service, - const QByteArray &request, - const QVector<JsonValue> &values, - const QVariant &cookie); - - QString toString() const; - QString errorString() const; - operator bool() const { return type == SuccessReply || type == ProgressReply; } - - Type type; - Services service; - QByteArray request; - TcfTrkCommandError commandError; - QVector<JsonValue> values; - QVariant cookie; -}; - -typedef trk::Callback<const TcfTrkCommandResult &> TcfTrkCallback; - -/* TcfTrkDevice: TCF communication helper using an asynchronous QIODevice - * implementing the TCF protocol according to: -http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specification.html -http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html - * Commands can be sent along with callbacks that are passed a - * TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted. -*/ - -class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject -{ - Q_PROPERTY(unsigned verbose READ verbose WRITE setVerbose) - Q_OBJECT -public: - enum MessageType { MessageWithReply, - MessageWithoutReply, /* Non-standard: "Settings:set" command does not reply */ - NoopMessage }; - - typedef QSharedPointer<QIODevice> IODevicePtr; - - explicit TcfTrkDevice(QObject *parent = 0); - virtual ~TcfTrkDevice(); - - unsigned verbose() const; - - // Mapping of register names for indices - QVector<QByteArray> registerNames() const; - void setRegisterNames(const QVector<QByteArray>& n); - - IODevicePtr device() const; - IODevicePtr takeDevice(); - void setDevice(const IODevicePtr &dp); - - void sendTcfTrkMessage(MessageType mt, Services service, - const char *command, - const char *commandParameters, int commandParametersLength, - const TcfTrkCallback &callBack = TcfTrkCallback(), - const QVariant &cookie = QVariant()); - - void sendTcfTrkMessage(MessageType mt, Services service, const char *command, - const QByteArray &commandParameters, - const TcfTrkCallback &callBack = TcfTrkCallback(), - const QVariant &cookie = QVariant()); - - // Convenience messages: Start a process - void sendProcessStartCommand(const TcfTrkCallback &callBack, - const QString &binary, - unsigned uid, - QStringList arguments = QStringList(), - QString workingDirectory = QString(), - bool debugControl = true, - const QStringList &additionalLibraries = QStringList(), - const QVariant &cookie = QVariant()); - - // Preferred over Processes:Terminate by TCF TRK. - void sendRunControlTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - void sendProcessTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - // Non-standard: Remove executable from settings. - // Probably needs to be called after stopping. This command has no response. - void sendSettingsRemoveExecutableCommand(const QString &binaryIn, - unsigned uid, - const QStringList &additionalLibraries = QStringList(), - const QVariant &cookie = QVariant()); - - void sendRunControlSuspendCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - // Resume / Step (see RunControlResumeMode). - void sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - RunControlResumeMode mode, - unsigned count /* = 1, currently ignored. */, - quint64 rangeStart, quint64 rangeEnd, - const QVariant &cookie = QVariant()); - - // Convenience to resume a suspended process - void sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - void sendBreakpointsAddCommand(const TcfTrkCallback &callBack, - const Breakpoint &b, - const QVariant &cookie = QVariant()); - - void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &id, - const QVariant &cookie = QVariant()); - - void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - bool enable, - const QVariant &cookie = QVariant()); - - void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &id, - bool enable, - const QVariant &cookie = QVariant()); - - - void sendMemoryGetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, quint64 size, - const QVariant &cookie = QVariant()); - - void sendMemorySetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, const QByteArray& data, - const QVariant &cookie = QVariant()); - - // Reply is an array of hexvalues - void sendRegistersGetMCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QVector<QByteArray> &ids, - const QVariant &cookie = QVariant()); - - // Convenience to get a range of register "R0" .. "R<n>". - // Cookie will be an int containing "start". - void sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned start, unsigned count); - - // Set register - void sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QByteArray &ids, - unsigned value, - const QVariant &cookie = QVariant()); - // Set register - void sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned registerNumber, - unsigned value, - const QVariant &cookie = QVariant()); - - static QByteArray parseMemoryGet(const TcfTrkCommandResult &r); - -signals: - void genericTcfEvent(int service, const QByteArray &name, const QVector<tcftrk::JsonValue> &value); - void tcfEvent(const tcftrk::TcfTrkEvent &knownEvent); - - void logMessage(const QString &); - void error(const QString &); - -public slots: - void setVerbose(unsigned v); - -private slots: - void slotDeviceError(); - void slotDeviceSocketStateChanged(); - void slotDeviceReadyRead(); - -private: - bool checkOpen(); - void checkSendQueue(); - void writeMessage(QByteArray data); - void emitLogMessage(const QString &); - int parseMessage(const QByteArray &); - int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens); - int parseTcfEvent(const QVector<QByteArray> &tokens); - - TcfTrkDevicePrivate *d; -}; - -} // namespace tcftrk - -#endif // TCFTRKENGINE_H diff --git a/tools/runonphone/symbianutils/trkdevice.cpp b/tools/runonphone/symbianutils/trkdevice.cpp index c6dc0a4..e28e70e 100644 --- a/tools/runonphone/symbianutils/trkdevice.cpp +++ b/tools/runonphone/symbianutils/trkdevice.cpp @@ -694,7 +694,7 @@ public slots: void terminate(); private: - enum Handles { FileHandle, TerminateEventHandle, HandleCount }; + enum Handles { TerminateEventHandle, FileHandle, HandleCount }; inline int tryRead(); @@ -727,7 +727,7 @@ int WinReaderThread::tryRead() const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize))); // Trigger read DWORD bytesRead = 0; - if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped)) { + if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped) && bytesRead > 0) { if (bytesRead == 1) { processData(buffer[0]); } else { @@ -736,7 +736,7 @@ int WinReaderThread::tryRead() return 0; } const DWORD readError = GetLastError(); - if (readError != ERROR_IO_PENDING) { + if (readError != ERROR_IO_PENDING && readError != 0) { emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError))); return -1; } diff --git a/tools/runonphone/symbianutils/trkutils.h b/tools/runonphone/symbianutils/trkutils.h index 663dc38..a4f5453 100644 --- a/tools/runonphone/symbianutils/trkutils.h +++ b/tools/runonphone/symbianutils/trkutils.h @@ -145,7 +145,7 @@ enum DSOSItemTypes { kDSOSProcAttachItem = 0x0005, kDSOSThreadAttachItem = 0x0006, kDSOSProcAttach2Item = 0x0007, - kDSOSProcRunItem = 0x0008, + kDSOSProcRunItem = 0x0008 /* 0x0009 - 0x00ff reserved for general expansion */ /* 0x0100 - 0xffff available for target-specific use */ }; @@ -170,7 +170,7 @@ enum Endianness { LittleEndian, BigEndian, - TargetByteOrder = BigEndian, + TargetByteOrder = BigEndian }; SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); diff --git a/tools/runonphone/symbianutils/virtualserialdevice.cpp b/tools/runonphone/symbianutils/virtualserialdevice.cpp new file mode 100644 index 0000000..4a8b354 --- /dev/null +++ b/tools/runonphone/symbianutils/virtualserialdevice.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "virtualserialdevice.h" +#include <QtCore/QThread> +#include <QtCore/QWaitCondition> + +namespace SymbianUtils { + +bool VirtualSerialDevice::isSequential() const +{ + return true; +} + +VirtualSerialDevice::VirtualSerialDevice(const QString &aPortName, QObject *parent) : + QIODevice(parent), portName(aPortName), lock(QMutex::NonRecursive), emittingBytesWritten(false), waiterForBytesWritten(NULL) +{ + platInit(); +} + +const QString& VirtualSerialDevice::getPortName() const +{ + return portName; +} + +void VirtualSerialDevice::close() +{ + if (isOpen()) { + QMutexLocker locker(&lock); + delete waiterForBytesWritten; + waiterForBytesWritten = NULL; + QIODevice::close(); + platClose(); + } +} + +void VirtualSerialDevice::emitBytesWrittenIfNeeded(QMutexLocker& locker, qint64 len) +{ + if (waiterForBytesWritten) { + waiterForBytesWritten->wakeAll(); + } + if (!emittingBytesWritten) { + emittingBytesWritten = true; + locker.unlock(); + emit bytesWritten(len); + locker.relock(); + emittingBytesWritten = false; + } +} + +} // namespace SymbianUtils diff --git a/tools/runonphone/symbianutils/virtualserialdevice.h b/tools/runonphone/symbianutils/virtualserialdevice.h new file mode 100644 index 0000000..9b65eef --- /dev/null +++ b/tools/runonphone/symbianutils/virtualserialdevice.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIRTUALSERIALPORT_H +#define VIRTUALSERIALPORT_H + +#include <QtCore/QIODevice> +#include <QtCore/QString> +#include <QtCore/QMutex> + +QT_BEGIN_NAMESPACE +class QWaitCondition; +QT_END_NAMESPACE + +#include "symbianutils_global.h" + +namespace SymbianUtils { + +class VirtualSerialDevicePrivate; + +class SYMBIANUTILS_EXPORT VirtualSerialDevice : public QIODevice +{ + Q_OBJECT +public: + explicit VirtualSerialDevice(const QString &name, QObject *parent = 0); + ~VirtualSerialDevice(); + + bool open(OpenMode mode); + void close(); + const QString &getPortName() const; + void flush(); + + qint64 bytesAvailable() const; + bool isSequential() const; + bool waitForBytesWritten(int msecs); + bool waitForReadyRead(int msecs); + +protected: + qint64 readData(char *data, qint64 maxSize); + qint64 writeData(const char *data, qint64 maxSize); + +private: + Q_DISABLE_COPY(VirtualSerialDevice) + void platInit(); + void platClose(); + void emitBytesWrittenIfNeeded(QMutexLocker &locker, qint64 len); + +private: + QString portName; + mutable QMutex lock; + QList<QByteArray> pendingWrites; + bool emittingBytesWritten; + QWaitCondition* waiterForBytesWritten; + VirtualSerialDevicePrivate *d; + +// Platform-specific stuff +#ifdef Q_OS_WIN +private: + qint64 writeNextBuffer(QMutexLocker &locker); + void doWriteCompleted(QMutexLocker &locker); +private slots: + void writeCompleted(); + void commEventOccurred(); +#endif + +#ifdef Q_OS_UNIX +private: + bool tryWrite(const char *data, qint64 maxSize, qint64 &bytesWritten); + enum FlushPendingOption { + NothingSpecial = 0, + StopAfterWritingOneBuffer = 1, + EmitBytesWrittenAsync = 2, // Needed so we don't emit bytesWritten signal directly from writeBytes + }; + Q_DECLARE_FLAGS(FlushPendingOptions, FlushPendingOption) + bool tryFlushPendingBuffers(QMutexLocker& locker, FlushPendingOptions flags = NothingSpecial); + +private slots: + void writeHasUnblocked(int fileHandle); + +signals: + void AsyncCall_emitBytesWrittenIfNeeded(qint64 len); + +#endif + +}; + +} // namespace SymbianUtils + +#endif // VIRTUALSERIALPORT_H diff --git a/tools/runonphone/symbianutils/virtualserialdevice_posix.cpp b/tools/runonphone/symbianutils/virtualserialdevice_posix.cpp new file mode 100644 index 0000000..4e389fc --- /dev/null +++ b/tools/runonphone/symbianutils/virtualserialdevice_posix.cpp @@ -0,0 +1,344 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <termios.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <QtCore/QSocketNotifier> +#include <QtCore/QTimer> +#include <QtCore/QThread> +#include <QtCore/QWaitCondition> +#include "virtualserialdevice.h" + +namespace SymbianUtils { + +class VirtualSerialDevicePrivate +{ +public: + int portHandle; + QSocketNotifier* readNotifier; + QSocketNotifier* writeUnblockedNotifier; +}; + +void VirtualSerialDevice::platInit() +{ + d = new VirtualSerialDevicePrivate; + d->portHandle = -1; + d->readNotifier = NULL; + d->writeUnblockedNotifier = NULL; + connect(this, SIGNAL(AsyncCall_emitBytesWrittenIfNeeded(qint64)), this, SIGNAL(bytesWritten(qint64)), Qt::QueuedConnection); +} + +bool VirtualSerialDevice::open(OpenMode mode) +{ + if (isOpen()) return true; + + d->portHandle = ::open(portName.toAscii().constData(), O_RDWR | O_NONBLOCK | O_NOCTTY); + if (d->portHandle == -1) { + setErrorString(tr("The port %1 could not be opened: %2 (POSIX error %3)"). + arg(portName, QString::fromLocal8Bit(strerror(errno))).arg(errno)); + return false; + } + + struct termios termInfo; + if (tcgetattr(d->portHandle, &termInfo) < 0) { + setErrorString(tr("Unable to retrieve terminal settings of port %1: %2 (POSIX error %3)"). + arg(portName, QString::fromLocal8Bit(strerror(errno))).arg(errno)); + close(); + return false; + } + cfmakeraw(&termInfo); + // Turn off terminal echo as not get messages back, among other things + termInfo.c_cflag |= CREAD|CLOCAL; + termInfo.c_cc[VTIME] = 0; + termInfo.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); + termInfo.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY|IXON|IXOFF)); + termInfo.c_oflag &= (~OPOST); + termInfo.c_cc[VMIN] = 0; + termInfo.c_cc[VINTR] = _POSIX_VDISABLE; + termInfo.c_cc[VQUIT] = _POSIX_VDISABLE; + termInfo.c_cc[VSTART] = _POSIX_VDISABLE; + termInfo.c_cc[VSTOP] = _POSIX_VDISABLE; + termInfo.c_cc[VSUSP] = _POSIX_VDISABLE; + + if (tcsetattr(d->portHandle, TCSAFLUSH, &termInfo) < 0) { + setErrorString(tr("Unable to apply terminal settings to port %1: %2 (POSIX error %3)"). + arg(portName, QString::fromLocal8Bit(strerror(errno))).arg(errno)); + close(); + return false; + } + + d->readNotifier = new QSocketNotifier(d->portHandle, QSocketNotifier::Read); + connect(d->readNotifier, SIGNAL(activated(int)), this, SIGNAL(readyRead())); + + d->writeUnblockedNotifier = new QSocketNotifier(d->portHandle, QSocketNotifier::Write); + d->writeUnblockedNotifier->setEnabled(false); + connect(d->writeUnblockedNotifier, SIGNAL(activated(int)), this, SLOT(writeHasUnblocked(int))); + + bool ok = QIODevice::open(mode | QIODevice::Unbuffered); + if (!ok) close(); + return ok; +} + +void VirtualSerialDevice::platClose() +{ + delete d->readNotifier; + d->readNotifier = NULL; + + delete d->writeUnblockedNotifier; + d->writeUnblockedNotifier = NULL; + + ::close(d->portHandle); + d->portHandle = -1; +} + +VirtualSerialDevice::~VirtualSerialDevice() +{ + close(); + delete d; +} + +qint64 VirtualSerialDevice::bytesAvailable() const +{ + QMutexLocker locker(&lock); + if (!isOpen()) return 0; + + int avail = 0; + if (ioctl(d->portHandle, FIONREAD, &avail) == -1) { + return 0; + } + return (qint64)avail + QIODevice::bytesAvailable(); +} + +qint64 VirtualSerialDevice::readData(char *data, qint64 maxSize) +{ + QMutexLocker locker(&lock); + int result = ::read(d->portHandle, data, maxSize); + if (result == -1 && errno == EAGAIN) + result = 0; // To Qt, 0 here means nothing ready right now, and -1 is reserved for permanent errors + return result; +} + +qint64 VirtualSerialDevice::writeData(const char *data, qint64 maxSize) +{ + QMutexLocker locker(&lock); + qint64 bytesWritten; + bool needToWait = tryFlushPendingBuffers(locker, EmitBytesWrittenAsync); + if (!needToWait) { + needToWait = tryWrite(data, maxSize, bytesWritten); + if (needToWait && bytesWritten > 0) { + // Wrote some of the buffer, adjust pointers to point to the remainder that needs queueing + data += bytesWritten; + maxSize -= bytesWritten; + } + } + + if (needToWait) { + pendingWrites.append(QByteArray(data, maxSize)); + d->writeUnblockedNotifier->setEnabled(true); + // Now wait for the writeUnblocked signal or for a call to waitForBytesWritten + return bytesWritten + maxSize; + } else { + //emitBytesWrittenIfNeeded(locker, bytesWritten); + // Can't emit bytesWritten directly from writeData - means clients end up recursing + emit AsyncCall_emitBytesWrittenIfNeeded(bytesWritten); + return bytesWritten; + } +} + +/* Returns true if EAGAIN encountered. + * if error occurred (other than EAGAIN) returns -1 in bytesWritten + * lock must be held. Doesn't emit signals or set notifiers. + */ +bool VirtualSerialDevice::tryWrite(const char *data, qint64 maxSize, qint64& bytesWritten) +{ + // Must be locked + bytesWritten = 0; + while (maxSize > 0) { + int result = ::write(d->portHandle, data, maxSize); + if (result == -1) { + if (errno == EAGAIN) + return true; // Need to wait + setErrorString(tr("Cannot write to port %1: %2 (POSIX error %3)"). + arg(portName, QString::fromLocal8Bit(strerror(errno))).arg(errno)); + + bytesWritten = -1; + return false; + } else { + if (result == 0) + qWarning("%s: Zero bytes written to port %s!", Q_FUNC_INFO, qPrintable(portName)); + bytesWritten += result; + maxSize -= result; + data += result; + } + } + return false; // If we reach here we've successfully written all the data without blocking +} + +/* Returns true if EAGAIN encountered. Emits (or queues) bytesWritten for any buffers written. + * If stopAfterWritingOneBuffer is true, return immediately if a single buffer is written, rather than + * attempting to drain the whole queue. + * Doesn't modify notifier. + */ +bool VirtualSerialDevice::tryFlushPendingBuffers(QMutexLocker& locker, FlushPendingOptions flags) +{ + while (pendingWrites.count() > 0) { + // Try writing everything we've got, until we hit EAGAIN + const QByteArray& data = pendingWrites[0]; + qint64 bytesWritten; + bool needToWait = tryWrite(data.constData(), data.size(), bytesWritten); + if (needToWait) { + if (bytesWritten > 0) { + // We wrote some of the data, update the pending queue + QByteArray remainder = data.mid(bytesWritten); + pendingWrites.removeFirst(); + pendingWrites.insert(0, remainder); + } + return needToWait; + } else { + pendingWrites.removeFirst(); + if (flags & EmitBytesWrittenAsync) { + emit AsyncCall_emitBytesWrittenIfNeeded(bytesWritten); + } else { + emitBytesWrittenIfNeeded(locker, bytesWritten); + } + if (flags & StopAfterWritingOneBuffer) return false; + // Otherwise go round loop again + } + } + return false; // no EAGAIN encountered +} + +void VirtualSerialDevice::writeHasUnblocked(int fileHandle) +{ + Q_ASSERT(fileHandle == d->portHandle); + (void)fileHandle; // Compiler shutter-upper + d->writeUnblockedNotifier->setEnabled(false); + + QMutexLocker locker(&lock); + bool needToWait = tryFlushPendingBuffers(locker); + if (needToWait) d->writeUnblockedNotifier->setEnabled(true); +} + +// Copy of qt_safe_select from /qt/src/corelib/kernel/qeventdispatcher_unix.cpp +// But without the timeout correction +int safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timeval *orig_timeout) +{ + if (!orig_timeout) { + // no timeout -> block forever + register int ret; + do { + ret = select(nfds, fdread, fdwrite, fdexcept, 0); + } while (ret == -1 && errno == EINTR); + return ret; + } + + timeval timeout = *orig_timeout; + + int ret; + forever { + ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeout); + if (ret != -1 || errno != EINTR) + return ret; + } +} + +bool VirtualSerialDevice::waitForBytesWritten(int msecs) +{ + QMutexLocker locker(&lock); + if (pendingWrites.count() == 0) return false; + + if (QThread::currentThread() != thread()) { + // Wait for signal from main thread + unsigned long timeout = msecs; + if (msecs == -1) timeout = ULONG_MAX; + if (waiterForBytesWritten == NULL) + waiterForBytesWritten = new QWaitCondition; + return waiterForBytesWritten->wait(&lock, timeout); + } + + d->writeUnblockedNotifier->setEnabled(false); + forever { + fd_set writeSet; + FD_ZERO(&writeSet); + FD_SET(d->portHandle, &writeSet); + + struct timeval timeout; + if (msecs != -1) { + timeout.tv_sec = msecs / 1000; + timeout.tv_usec = (msecs % 1000) * 1000; + } + int ret = safe_select(d->portHandle+1, NULL, &writeSet, NULL, msecs == -1 ? NULL : &timeout); + + if (ret == 0) { + // Timeout + return false; + } else if (ret < 0) { + setErrorString(tr("The function select() returned an error on port %1: %2 (POSIX error %3)"). + arg(portName, QString::fromLocal8Bit(strerror(errno))).arg(errno)); + return false; + } else { + bool needToWait = tryFlushPendingBuffers(locker, StopAfterWritingOneBuffer); + if (needToWait) { + // go round the select again + } else { + return true; + } + } + } +} + +void VirtualSerialDevice::flush() +{ + while (waitForBytesWritten(-1)) { /* loop */ } + tcflush(d->portHandle, TCIOFLUSH); +} + +bool VirtualSerialDevice::waitForReadyRead(int msecs) +{ + return QIODevice::waitForReadyRead(msecs); //TODO +} + +} // namespace SymbianUtils diff --git a/tools/runonphone/symbianutils/virtualserialdevice_win.cpp b/tools/runonphone/symbianutils/virtualserialdevice_win.cpp new file mode 100644 index 0000000..d9f4588 --- /dev/null +++ b/tools/runonphone/symbianutils/virtualserialdevice_win.cpp @@ -0,0 +1,369 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "virtualserialdevice.h" +#include <windows.h> +#include <QtCore/private/qwineventnotifier_p.h> +#include <QtCore/QThread> +#include <QtCore/QWaitCondition> + +namespace SymbianUtils { + +class VirtualSerialDevicePrivate +{ +public: + HANDLE portHandle; + OVERLAPPED writeOverlapped; + OVERLAPPED commEventOverlapped; + DWORD commEventMask; + QWinEventNotifier *writeCompleteNotifier; + QWinEventNotifier *commEventNotifier; +}; + +void VirtualSerialDevice::platInit() +{ + d = new VirtualSerialDevicePrivate; + d->portHandle = INVALID_HANDLE_VALUE; + d->writeCompleteNotifier = NULL; + memset(&d->writeOverlapped, 0, sizeof(OVERLAPPED)); + d->commEventNotifier = NULL; + memset(&d->commEventOverlapped, 0, sizeof(OVERLAPPED)); +} + +QString windowsPortName(const QString& port) +{ + // Add the \\.\ to the name if it's a COM port and doesn't already have it + QString winPortName(port); + if (winPortName.startsWith(QLatin1String("COM"))) { + winPortName.prepend("\\\\.\\"); + } + return winPortName; +} + +// Copied from \creator\src\libs\utils\winutils.cpp +QString winErrorMessage(unsigned long error) +{ + // Some of the windows error messages are a bit too obscure + switch (error) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_NOT_FOUND: + return VirtualSerialDevice::tr("Port not found"); + break; + case ERROR_ACCESS_DENIED: + return VirtualSerialDevice::tr("Port in use"); + case ERROR_SEM_TIMEOUT: // Bluetooth ports sometimes return this + return VirtualSerialDevice::tr("Timed out"); + case ERROR_NETWORK_UNREACHABLE: + return VirtualSerialDevice::tr("Port unreachable"); // I don't know what this error indicates... from observation, that the windows Bluetooth stack has got itself into a state and needs resetting + default: + break; + } + + QString rc = QString::fromLatin1("#%1: ").arg(error); + ushort *lpMsgBuf; + + const int len = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL); + if (len) { + rc = QString::fromUtf16(lpMsgBuf, len); + LocalFree(lpMsgBuf); + } else { + rc += QString::fromLatin1("<unknown error>"); + } + return rc.trimmed(); +} + +bool VirtualSerialDevice::open(OpenMode mode) +{ + Q_ASSERT(QThread::currentThread() == thread()); + if (isOpen()) return true; + + d->portHandle = CreateFileA(windowsPortName(portName).toAscii(), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + if (d->portHandle == INVALID_HANDLE_VALUE) { + setErrorString(tr("The port %1 could not be opened: %2"). + arg(portName, winErrorMessage(GetLastError()))); + return false; + } + + DCB commState; + memset(&commState, 0, sizeof(DCB)); + commState.DCBlength = sizeof(DCB); + bool ok = GetCommState(d->portHandle, &commState); + if (ok) { + commState.BaudRate = CBR_115200; + commState.fBinary = TRUE; + commState.fParity = FALSE; + commState.fOutxCtsFlow = FALSE; + commState.fOutxDsrFlow = FALSE; + commState.fInX = FALSE; + commState.fOutX = FALSE; + commState.fNull = FALSE; + commState.fAbortOnError = FALSE; + commState.fDsrSensitivity = FALSE; + commState.fDtrControl = DTR_CONTROL_DISABLE; + commState.ByteSize = 8; + commState.Parity = NOPARITY; + commState.StopBits = ONESTOPBIT; + ok = SetCommState(d->portHandle, &commState); + } + if (!ok) { + qWarning("%s setting comm state", qPrintable(winErrorMessage(GetLastError()))); + } + + // http://msdn.microsoft.com/en-us/library/aa363190(v=vs.85).aspx says this means + // "the read operation is to return immediately with the bytes that have already been received, even if no bytes have been received" + COMMTIMEOUTS timeouts; + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.ReadTotalTimeoutConstant = 0; + timeouts.WriteTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; + SetCommTimeouts(d->portHandle, &timeouts); + + d->writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + d->writeCompleteNotifier = new QWinEventNotifier(d->writeOverlapped.hEvent, this); + connect(d->writeCompleteNotifier, SIGNAL(activated(HANDLE)), this, SLOT(writeCompleted())); + + // This is how we implement readyRead notifications + d->commEventOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + d->commEventNotifier = new QWinEventNotifier(d->commEventOverlapped.hEvent, this); + connect(d->commEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(commEventOccurred())); + + if (!SetCommMask(d->portHandle, EV_RXCHAR)) { + // What to do? + qWarning("%s: Could not set comm mask, err=%d", Q_FUNC_INFO, (int)GetLastError()); + } + bool result = WaitCommEvent(d->portHandle, &d->commEventMask, &d->commEventOverlapped); + Q_ASSERT(result == false); // Can't see how it would make sense to be anything else... + (void)result; // For release build + if (GetLastError() != ERROR_IO_PENDING) { + setErrorString(tr("An error occurred while waiting for read notifications from %1: %2"). + arg(portName, winErrorMessage(GetLastError()))); + close(); + return false; + } + + ok = QIODevice::open(mode); + if (!ok) close(); + return ok; +} + +void VirtualSerialDevice::platClose() +{ + delete d->writeCompleteNotifier; + d->writeCompleteNotifier = NULL; + CloseHandle(d->writeOverlapped.hEvent); + d->writeOverlapped.hEvent = INVALID_HANDLE_VALUE; + + delete d->commEventNotifier; + d->commEventNotifier = NULL; + d->commEventOverlapped.hEvent = INVALID_HANDLE_VALUE; + + CloseHandle(d->portHandle); + d->portHandle = INVALID_HANDLE_VALUE; +} + +VirtualSerialDevice::~VirtualSerialDevice() +{ + close(); + delete d; +} + +qint64 VirtualSerialDevice::bytesAvailable() const +{ + QMutexLocker locker(&lock); + if (!isOpen()) return 0; + + qint64 avail = 0; + COMSTAT Status; + if (ClearCommError(d->portHandle, NULL, &Status)) { + avail = Status.cbInQue; + } + return avail + QIODevice::bytesAvailable(); +} + +void VirtualSerialDevice::commEventOccurred() +{ + DWORD event = d->commEventMask; + if (event & EV_RXCHAR) { + emit readyRead(); + } + ResetEvent(d->commEventOverlapped.hEvent); + WaitCommEvent(d->portHandle, &d->commEventMask, &d->commEventOverlapped); +} + +qint64 VirtualSerialDevice::readData(char *data, qint64 maxSize) +{ + QMutexLocker locker(&lock); + // We do our reads synchronously + OVERLAPPED readOverlapped; + memset(&readOverlapped, 0, sizeof(OVERLAPPED)); + DWORD bytesRead; + BOOL done = ReadFile(d->portHandle, data, maxSize, &bytesRead, &readOverlapped); + if (done) return (qint64)bytesRead; + + if (GetLastError() == ERROR_IO_PENDING) { + // Note the TRUE to wait for the read to complete + done = GetOverlappedResult(d->portHandle, &readOverlapped, &bytesRead, TRUE); + if (done) return (qint64)bytesRead; + } + + // If we reach here an error has occurred + setErrorString(tr("An error occurred while reading from %1: %2"). + arg(portName, winErrorMessage(GetLastError()))); + return -1; +} + + +qint64 VirtualSerialDevice::writeData(const char *data, qint64 maxSize) +{ + QMutexLocker locker(&lock); + + pendingWrites.append(QByteArray(data, maxSize)); // Can't see a way of doing async io safely without having to copy here... + if (pendingWrites.count() == 1) { + return writeNextBuffer(locker); + } else { + return maxSize; + } +} + +qint64 VirtualSerialDevice::writeNextBuffer(QMutexLocker& locker) +{ + Q_UNUSED(locker) + // Must be locked on entry + qint64 bufLen = pendingWrites[0].length(); + BOOL ok = WriteFile(d->portHandle, pendingWrites[0].constData(), bufLen, NULL, &d->writeOverlapped); + if (ok || GetLastError() == ERROR_IO_PENDING) { + // Apparently it can return true for a small asynchronous write... + // Hopefully it still gets signalled in the same way! + + // Wait for signal via writeCompleted + return bufLen; + } + else { + setErrorString(tr("An error occurred while writing to %1: %2"). + arg(portName, winErrorMessage(GetLastError()))); + pendingWrites.removeFirst(); + return -1; + } +} + +void VirtualSerialDevice::writeCompleted() +{ + QMutexLocker locker(&lock); + if (pendingWrites.count() == 0) { + qWarning("%s: writeCompleted called when there are no pending writes on %s!", + Q_FUNC_INFO, qPrintable(portName)); + return; + } + + doWriteCompleted(locker); +} + +void VirtualSerialDevice::doWriteCompleted(QMutexLocker &locker) +{ + // Must be locked on entry + ResetEvent(d->writeOverlapped.hEvent); + + qint64 len = pendingWrites.first().length(); + pendingWrites.removeFirst(); + + if (pendingWrites.count() > 0) { + // Get the next write started before notifying in case client calls waitForBytesWritten in their slot + writeNextBuffer(locker); + } + + emitBytesWrittenIfNeeded(locker, len); +} + +bool VirtualSerialDevice::waitForBytesWritten(int msecs) +{ + QMutexLocker locker(&lock); + if (pendingWrites.count() == 0) return false; + + if (QThread::currentThread() != thread()) { + // Wait for signal from main thread + unsigned long timeout = msecs; + if (msecs == -1) timeout = ULONG_MAX; + if (waiterForBytesWritten == NULL) + waiterForBytesWritten = new QWaitCondition; + return waiterForBytesWritten->wait(&lock, timeout); + } + + DWORD waitTime = msecs; + if (msecs == -1) waitTime = INFINITE; // Ok these are probably bitwise the same, but just to prove I've thought about it... + DWORD result = WaitForSingleObject(d->writeOverlapped.hEvent, waitTime); // Do I need WaitForSingleObjectEx and worry about alertable states? + if (result == WAIT_TIMEOUT) { + return false; + } + else if (result == WAIT_OBJECT_0) { + DWORD bytesWritten; + BOOL ok = GetOverlappedResult(d->portHandle, &d->writeOverlapped, &bytesWritten, TRUE); + if (!ok) { + setErrorString(tr("An error occurred while syncing on waitForBytesWritten for %1: %2"). + arg(portName, winErrorMessage(GetLastError()))); + return false; + } + Q_ASSERT(bytesWritten == (DWORD)pendingWrites.first().length()); + + doWriteCompleted(locker); + return true; + } + else { + setErrorString(QString("An error occurred in waitForBytesWritten() for %1: %2"). + arg(portName, winErrorMessage(GetLastError()))); + return false; + } +} + +void VirtualSerialDevice::flush() +{ + while (waitForBytesWritten(-1)) { /* loop */ } +} + +bool VirtualSerialDevice::waitForReadyRead(int msecs) +{ + return QIODevice::waitForReadyRead(msecs); //TODO +} + +} // namespace SymbianUtils diff --git a/tools/runonphone/trksignalhandler.cpp b/tools/runonphone/trksignalhandler.cpp index 062501a..59ff22c 100644 --- a/tools/runonphone/trksignalhandler.cpp +++ b/tools/runonphone/trksignalhandler.cpp @@ -77,10 +77,10 @@ private: bool terminateNeeded; }; -void TrkSignalHandler::copyingStarted() +void TrkSignalHandler::copyingStarted(const QString &fileName) { if (d->loglevel > 0) - d->out << "Copying..." << endl; + d->out << "Copying " << fileName << "..." << endl; } void TrkSignalHandler::canNotConnect(const QString &errorMessage) @@ -103,10 +103,10 @@ void TrkSignalHandler::canNotCloseFile(const QString &filename, const QString &e d->err << "Cannot close file (" << filename << ") - " << errorMessage << endl; } -void TrkSignalHandler::installingStarted() +void TrkSignalHandler::installingStarted(const QString &packageName) { if (d->loglevel > 0) - d->out << "Installing..." << endl; + d->out << "Installing" << packageName << "..." << endl; } void TrkSignalHandler::canNotInstall(const QString &packageFilename, const QString &errorMessage) diff --git a/tools/runonphone/trksignalhandler.h b/tools/runonphone/trksignalhandler.h index 5c76b19..e551c34 100644 --- a/tools/runonphone/trksignalhandler.h +++ b/tools/runonphone/trksignalhandler.h @@ -50,12 +50,12 @@ class TrkSignalHandler : public QObject { Q_OBJECT public slots: - void copyingStarted(); + void copyingStarted(const QString &fileName); void canNotConnect(const QString &errorMessage); void canNotCreateFile(const QString &filename, const QString &errorMessage); void canNotWriteFile(const QString &filename, const QString &errorMessage); void canNotCloseFile(const QString &filename, const QString &errorMessage); - void installingStarted(); + void installingStarted(const QString &packageName); void canNotInstall(const QString &packageFilename, const QString &errorMessage); void installingFinished(); void startingApplication(); |