diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-24 14:28:46 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-24 14:28:46 (GMT) |
commit | bbf096c7ba589d05df8b8bce724e9393deb8f3b4 (patch) | |
tree | 0689bfba547d519486eec6529fb3e88202615519 | |
parent | 6d0002fe9bc91b9901e56050d247fbded09c9c76 (diff) | |
parent | 8c10e0b73c312a6c1aacce11cc8d6f57dc94a09d (diff) | |
download | Qt-bbf096c7ba589d05df8b8bce724e9393deb8f3b4.zip Qt-bbf096c7ba589d05df8b8bce724e9393deb8f3b4.tar.gz Qt-bbf096c7ba589d05df8b8bce724e9393deb8f3b4.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
33 files changed, 584 insertions, 163 deletions
@@ -725,6 +725,7 @@ CFG_DBUS=auto CFG_GLIB=auto CFG_GSTREAMER=auto CFG_QGTKSTYLE=auto +CFG_QS60STYLE=auto CFG_LARGEFILE=yes CFG_OPENSSL=auto CFG_PTMALLOC=no @@ -1798,6 +1799,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + style-s60) + if [ "$VAL" = "qt" ] || [ "$VAL" = "no" ]; then + CFG_QS60STYLE="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; qdbus|dbus) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ] || [ "$VAL" = "linked" ]; then CFG_DBUS="$VAL" @@ -3353,7 +3361,6 @@ Usage: $relconf [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir [-no-openssl] [-openssl] [-openssl-linked] [-no-gtkstyle] [-gtkstyle] [-no-svg] [-svg] [-no-webkit] [-webkit] [-no-javascript-jit] [-javascript-jit] [-no-script] [-script] [-no-scripttools] [-scripttools] [-no-declarative] [-declarative] - [-no-s60] [-s60] [-no-usedeffiles] [-usedeffiles] [additional platform specific options (see below)] @@ -3537,11 +3544,6 @@ EOF fi cat << EOF - -no-s60 ............ Do not compile in S60 support. - + -s60 ............... Compile with support for the S60 UI Framework. - -no-usedeffiles .... Disable the usage of DEF files. - * -usedeffiles ....... Enable the usage of DEF files. - -no-mmx ............ Do not compile with use of MMX instructions. -no-3dnow .......... Do not compile with use of 3DNOW instructions. -no-sse ............ Do not compile with use of SSE instructions. @@ -3992,6 +3994,20 @@ if [ "$PLATFORM_QWS" = "yes" -o "$PLATFORM_X11" = "yes" ]; then EOF fi +if echo "$XPLATFORM" | grep symbian > /dev/null ; then + cat << EOF + +Qt for Symbian only: + -no-s60 ............ Do not compile in S60 support. + + -s60 ............... Compile with support for the S60 UI Framework. + -no-style-s60....... Disable s60 style + + -qt-style-s60....... Enable s60 style in the Qt Library + + -no-usedeffiles .... Disable the usage of DEF files. + * -usedeffiles ....... Enable the usage of DEF files. +EOF +fi + [ "x$ERROR" = "xyes" ] && exit 1 exit 0 fi # Help @@ -4005,6 +4021,8 @@ if [ "$PLATFORM_QWS" = "yes" ]; then Platform="Qt for Embedded Linux" elif [ "$PLATFORM_MAC" = "yes" ]; then Platform="Qt for Mac OS X" +elif echo "$XPLATFORM" | grep "symbian" > /dev/null ; then + Platform="Qt for Symbian" elif [ '!' -z "`getQMakeConf \"$XQMAKESPEC\" | grep QMAKE_LIBS_X11 | awk '{print $3;}'`" ]; then PLATFORM_X11=yes Platform="Qt for Linux/X11" @@ -4630,15 +4648,23 @@ if [ "$CFG_ZLIB" = "auto" ]; then fi if [ "$CFG_S60" = "auto" ]; then - if echo "$XQMAKESPEC" | grep symbian > /dev/null; then + if echo "$XPLATFORM" | grep symbian > /dev/null; then CFG_S60=yes else CFG_S60=no fi fi +if [ "$CFG_QS60STYLE" = "auto" ]; then + if echo "$XPLATFORM" | grep symbian > /dev/null; then + CFG_QS60STYLE=qt + else + CFG_QS60STYLE=no + fi +fi + if [ "$CFG_SYMBIAN_DEFFILES" = "auto" ]; then - if echo "$XQMAKESPEC" | grep symbian > /dev/null && [ "$CFG_DEV" = "no" ]; then + if echo "$XPLATFORM" | grep symbian > /dev/null && [ "$CFG_DEV" = "no" ]; then CFG_SYMBIAN_DEFFILES=yes else CFG_SYMBIAN_DEFFILES=no @@ -5671,6 +5697,8 @@ fi if [ "$CFG_ENDIAN" = "auto" ]; then if [ "$PLATFORM_MAC" = "yes" ]; then true #leave as auto + elif [ "$XPLATFORM" = "symbian-sbsv2" ]; then + CFG_ENDIAN="Q_LITTLE_ENDIAN" else "$unixtests/endian.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" F="$?" @@ -5756,7 +5784,7 @@ if [ "$CFG_DOUBLEFORMAT" = "auto" ]; then fi HAVE_STL=no -if echo "$XQMAKESPEC" | grep symbian > /dev/null || "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then +if echo "$XPLATFORM" | grep symbian > /dev/null || "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then HAVE_STL=yes fi @@ -5910,7 +5938,7 @@ if [ "$CFG_OPENSSL" != "no" ]; then fi # detect OpenVG support -if [ "$CFG_OPENVG" != "no" ]; then +if [ "$CFG_OPENVG" != "no" ] && [ "$XPLATFORM" != "symbian-sbsv2" ]; then if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" "config.tests/unix/openvg" "OpenVG" $L_FLAGS $I_FLAGS $l_FLAGS $CONFIG_ARG; then if [ "$CFG_OPENVG" = "auto" ]; then CFG_OPENVG=yes @@ -5994,7 +6022,7 @@ elif [ "$CFG_JAVASCRIPTCORE_JIT" = "no" ]; then fi if [ "$CFG_AUDIO_BACKEND" = "auto" ]; then - if echo "$XQMAKESPEC" | grep symbian > /dev/null 2>&1; then + if echo "$XPLATFORM" | grep symbian > /dev/null 2>&1; then "$symbiantests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/symbian/audio "audio" $L_FLAGS $I_FLAGS $l_FLAGS else CFG_AUDIO_BACKEND=yes @@ -6172,6 +6200,12 @@ else fi fi +if [ "$CFG_QS60STYLE" = "no" ]; then + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_STYLE_S60" +else + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_STYLE_S60" +fi + # Disable OpenGL on Symbian. case "$XPLATFORM" in symbian*) diff --git a/mkspecs/features/symbian/application_icon.prf b/mkspecs/features/symbian/application_icon.prf index 1109060..9979f40 100644 --- a/mkspecs/features/symbian/application_icon.prf +++ b/mkspecs/features/symbian/application_icon.prf @@ -31,9 +31,9 @@ contains( CONFIG, no_icon ) { # Note: symbian-sbsv2 builds can't utilize extra compiler for mifconv, so ICON handling is done in code !symbian-sbsv2 { + !contains(ICON, "^(/|\\\\|.:).*"):ICON = $$_PRO_FILE_PWD_/$$ICON #absolute path #Makefile: requires paths with backslash ICON_backslashed = $$ICON - contains(QMAKE_HOST.os, "Windows"):ICON_backslashed = $$replace( ICON_backslashed, /, \\) symbian-abld { mifIconZDir = ${ZDIR}$$APP_RESOURCE_DIR @@ -47,9 +47,14 @@ contains( CONFIG, no_icon ) { # Extra compiler rules for mifconv mifconv.target = $$mifIconZDir/$${baseTarget}.mif + contains(QMAKE_HOST.os, "Windows") { + ICON_backslashed = $$replace(ICON_backslashed, /, \\) + mifconv.target = $$replace(mifconv.target, /, \\) + } # Based on: http://www.forum.nokia.com/document/Cpp_Developers_Library # svg-t icons should always use /c32 depth mifconv.commands = mifconv $$mifconv.target /c32 $$ICON_backslashed + mifconv.depends = $$ICON PRE_TARGETDEPS += $$mifconv.target QMAKE_EXTRA_TARGETS += mifconv diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index 2dc614f..0d2e6eb 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -43,5 +43,5 @@ isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x020000 0x800000 # Workaround for the fact that Gnupoc and Symbian chose different approaches to # the letter casing of headers. contains(CONFIG, is_using_gnupoc) { - INCLUDEPATH += $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian/header-wrappers + INCLUDEPATH += $$QMAKESPEC/../../common/symbian/header-wrappers } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h index 5fb7fe3..5b655e8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h @@ -75,7 +75,7 @@ #include <libkern/OSAtomic.h> #elif OS(ANDROID) #include <cutils/atomic.h> -#elif COMPILER(GCC) && !PLATFORM(SYMBIAN) +#elif COMPILER(GCC) && !defined(__SYMBIAN32__) #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) #include <ext/atomicity.h> #else @@ -239,7 +239,7 @@ inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Bar inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); } inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); } -#elif COMPILER(GCC) && !PLATFORM(SPARC64) && !PLATFORM(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc +#elif COMPILER(GCC) && !PLATFORM(SPARC64) && !defined(__SYMBIAN32__) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h index 52a24f6..3e25c95 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Threading.h @@ -73,7 +73,7 @@ #include <windows.h> #elif PLATFORM(DARWIN) #include <libkern/OSAtomic.h> -#elif COMPILER(GCC) && !PLATFORM(SYMBIAN) +#elif COMPILER(GCC) && !defined(__SYMBIAN32__) #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) #include <ext/atomicity.h> #else @@ -232,7 +232,7 @@ inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(r inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); } inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); } -#elif COMPILER(GCC) && !PLATFORM(SPARC64) && !PLATFORM(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc +#elif COMPILER(GCC) && !PLATFORM(SPARC64) && !defined(__SYMBIAN32__) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; } diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 394323f..eb42c20 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -100,7 +100,7 @@ qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) void QWindowsPipeWriter::run() { - OVERLAPPED overl = {0, 0, 0, 0, NULL}; + OVERLAPPED overl = {0, 0, {{ 0 }}, 0}; overl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); forever { lock.lock(); diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 566626d..c1925e7 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -1022,12 +1022,12 @@ QString decodeMSG(const MSG& msg) if (!winPos) break; QString hwndAfter = valueCheck(quint64(winPos->hwndInsertAfter), - FLAG_STRING((quintptr)HWND_BOTTOM, "HWND_BOTTOM"), - FLAG_STRING((quintptr)HWND_NOTOPMOST, "HWND_NOTOPMOST"), - FLAG_STRING((quintptr)HWND_TOP, "HWND_TOP"), - FLAG_STRING((quintptr)HWND_TOPMOST, "HWND_TOPMOST"), + FLAG_STRING((qptrdiff)HWND_BOTTOM, "HWND_BOTTOM"), + FLAG_STRING((qptrdiff)HWND_NOTOPMOST, "HWND_NOTOPMOST"), + FLAG_STRING((qptrdiff)HWND_TOP, "HWND_TOP"), + FLAG_STRING((qptrdiff)HWND_TOPMOST, "HWND_TOPMOST"), FLAG_STRING()); - if (hwndAfter.size() == 0) + if (hwndAfter.isEmpty()) hwndAfter = QString::number((quintptr)winPos->hwndInsertAfter, 16); QString flags = flagCheck(winPos->flags, FLGSTR(SWP_DRAWFRAME), diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h index 84a5df9..8776c08 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings_p.h +++ b/src/declarative/qml/qdeclarativecompiledbindings_p.h @@ -60,7 +60,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QDeclarativeBindingCompilerPrivate; +struct QDeclarativeBindingCompilerPrivate; class QDeclarativeBindingCompiler { public: diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 42d2950..2ea7bff 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -2094,7 +2094,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert buildDynamicMeta(baseObj, ForceCreation); v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor; } else { - COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(v->object->typeName.constData()).arg(prop->name.constData())); + COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(QString::fromLatin1(v->object->typeName)).arg(QString::fromLatin1(prop->name.constData()))); } return true; diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index 1a36f10..d41323d 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -136,7 +136,7 @@ public: int index() const; private: friend class QDeclarativeTypePrivate; - friend class QDeclarativeMetaTypeData; + friend struct QDeclarativeMetaTypeData; friend int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterInterface &); friend int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &); QDeclarativeType(int, const QDeclarativePrivate::RegisterInterface &); diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index ddf00ea..f455870 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -62,8 +62,7 @@ HEADERS += \ $$PWD/qdeclarativebehavior_p.h \ $$PWD/qdeclarativefontloader_p.h \ $$PWD/qdeclarativestyledtext_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p_p.h + $$PWD/qdeclarativelistmodelworkeragent_p.h contains(QT_CONFIG, xmlpatterns) { QT+=xmlpatterns diff --git a/src/gui/dialogs/qwizard_win_p.h b/src/gui/dialogs/qwizard_win_p.h index fe01587..5f3b6c2 100644 --- a/src/gui/dialogs/qwizard_win_p.h +++ b/src/gui/dialogs/qwizard_win_p.h @@ -82,7 +82,6 @@ class QWizard; class QVistaHelper : public QObject { - Q_OBJECT public: QVistaHelper(QWizard *wizard); ~QVistaHelper(); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index ae9b34c..715b4c4 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -2278,7 +2278,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa case WM_GETOBJECT: { // Ignoring all requests while starting up - if (QApplication::startingUp() || QApplication::closingDown() || (DWORD)lParam != OBJID_CLIENT) { + if (QApplication::startingUp() || QApplication::closingDown() || (LONG)lParam != OBJID_CLIENT) { result = false; break; } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 71e2e3b..1f75ec7 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3884,8 +3884,8 @@ inline void interpolate_pixel_unaligned_2(DST *dest, const SRC *src, template <class DST, class SRC> inline void interpolate_pixel_2(DST *dest, const SRC *src, quint16 alpha) { - Q_ASSERT((long(dest) & 0x3) == 0); - Q_ASSERT((long(src) & 0x3) == 0); + Q_ASSERT((quintptr(dest) & 0x3) == 0); + Q_ASSERT((quintptr(src) & 0x3) == 0); const quint16 a = eff_alpha_2(alpha, dest); const quint16 ia = eff_ialpha_2(alpha, dest); @@ -3958,8 +3958,8 @@ template <class DST, class SRC> inline void interpolate_pixel_2(DST *dest, quint8 a, const SRC *src, quint8 b) { - Q_ASSERT((long(dest) & 0x3) == 0); - Q_ASSERT((long(src) & 0x3) == 0); + Q_ASSERT((quintptr(dest) & 0x3) == 0); + Q_ASSERT((quintptr(src) & 0x3) == 0); Q_ASSERT(!SRC::hasAlpha()); @@ -4007,8 +4007,8 @@ inline void interpolate_pixel_2(qrgb444 *dest, quint8 a, template <class DST, class SRC> inline void interpolate_pixel_4(DST *dest, const SRC *src, quint32 alpha) { - Q_ASSERT((long(dest) & 0x3) == 0); - Q_ASSERT((long(src) & 0x3) == 0); + Q_ASSERT((quintptr(dest) & 0x3) == 0); + Q_ASSERT((quintptr(src) & 0x3) == 0); const quint32 a = eff_alpha_4(alpha, dest); const quint32 ia = eff_ialpha_4(alpha, dest); @@ -4411,7 +4411,7 @@ void QT_FASTCALL blendUntransformed_dest16(DST *dest, const SRC *src, { Q_ASSERT(sizeof(DST) == 2); Q_ASSERT(sizeof(SRC) == 2); - Q_ASSERT((long(dest) & 0x3) == (long(src) & 0x3)); + Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); Q_ASSERT(coverage > 0); const int align = quintptr(dest) & 0x3; @@ -4479,8 +4479,8 @@ void QT_FASTCALL blendUntransformed_dest16(DST *dest, const SRC *src, } while (length >= 2) { - Q_ASSERT((long(dest) & 3) == 0); - Q_ASSERT((long(src) & 3) == 0); + Q_ASSERT((quintptr(dest) & 3) == 0); + Q_ASSERT((quintptr(src) & 3) == 0); const quint16 a = alpha_2(src); if (a == 0xffff) { @@ -4511,7 +4511,7 @@ template <class DST, class SRC> void QT_FASTCALL blendUntransformed_dest24(DST *dest, const SRC *src, quint8 coverage, int length) { - Q_ASSERT((long(dest) & 0x3) == (long(src) & 0x3)); + Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); Q_ASSERT(sizeof(DST) == 3); Q_ASSERT(coverage > 0); diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index e2de43a..bd87ca4 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -769,6 +769,8 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, GtkArrowType type = GTK_ARROW_UP; QRect r = header->rect; QImage arrow; + // This sorting indicator inversion is intentional, and follows the GNOME HIG. + // See http://library.gnome.org/devel/hig-book/stable/controls-lists.html.en#controls-lists-sortable if (header->sortIndicator & QStyleOptionHeader::SortUp) type = GTK_ARROW_UP; else if (header->sortIndicator & QStyleOptionHeader::SortDown) diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 6138e85..4a279a7 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -63,7 +63,7 @@ #include <AknUtils.h> #include <aknnavi.h> #include <gulicon.h> -#include <AknBitmapAnimation.h> +#include <aknbitmapanimation.h> #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index b826588..8dded4e 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1124,14 +1124,13 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const bool kerningEnabled = this->font(si).d->kerning; HB_ShaperItem entire_shaper_item; - entire_shaper_item.kerning_applied = false; + qMemSet(&entire_shaper_item, 0, sizeof(entire_shaper_item)); entire_shaper_item.string = reinterpret_cast<const HB_UChar16 *>(layoutData->string.constData()); entire_shaper_item.stringLength = layoutData->string.length(); entire_shaper_item.item.script = (HB_Script)si.analysis.script; entire_shaper_item.item.pos = si.position; entire_shaper_item.item.length = length(item); entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel; - entire_shaper_item.glyphIndicesPresent = false; HB_UChar16 upperCased[256]; // XXX what about making this 4096, so we don't have to extend it ever. if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase @@ -2467,7 +2466,7 @@ void QTextEngine::splitItem(int item, int pos) const if (pos <= 0) return; - layoutData->items.insert(item + 1, QScriptItem(layoutData->items[item])); + layoutData->items.insert(item + 1, layoutData->items[item]); QScriptItem &oldItem = layoutData->items[item]; QScriptItem &newItem = layoutData->items[item+1]; newItem.position += pos; diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp index 465a1e7..e9d30d0 100644 --- a/src/multimedia/video/qabstractvideobuffer.cpp +++ b/src/multimedia/video/qabstractvideobuffer.cpp @@ -71,6 +71,8 @@ QT_BEGIN_NAMESPACE \value NoHandle The buffer has no handle, its data can only be accessed by mapping the buffer. \value GLTextureHandle The handle of the buffer is an OpenGL texture ID. + \value XvShmImageHandle The handle contains pointer to shared memory XVideo image. + \value CoreImageHandle The handle contains pointer to Mac OS X CIImage. \value UserHandle Start value for user defined handle types. \sa handleType() diff --git a/src/multimedia/video/qabstractvideobuffer.h b/src/multimedia/video/qabstractvideobuffer.h index 4ffa46f..a8389db 100644 --- a/src/multimedia/video/qabstractvideobuffer.h +++ b/src/multimedia/video/qabstractvideobuffer.h @@ -61,6 +61,8 @@ public: { NoHandle, GLTextureHandle, + XvShmImageHandle, + CoreImageHandle, UserHandle = 1000 }; diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.h b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h index 31a0314..49049ad 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewoutput.h +++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h @@ -100,6 +100,7 @@ private: void *m_movie; void *m_movieView; + bool m_layouted; WId m_winId; QRect m_displayRect; diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm index d8dbf9b..8e4dd9b 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm +++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm @@ -154,6 +154,7 @@ QT7MovieViewOutput::QT7MovieViewOutput(QObject *parent) :QT7VideoWindowControl(parent), m_movie(0), m_movieView(0), + m_layouted(false), m_winId(0), m_fullscreen(false), m_aspectRatioMode(Qt::KeepAspectRatio), @@ -166,6 +167,8 @@ QT7MovieViewOutput::QT7MovieViewOutput(QObject *parent) QT7MovieViewOutput::~QT7MovieViewOutput() { + [(QTMovieView*)m_movieView release]; + [(QTMovie*)m_movie release]; } void QT7MovieViewOutput::setupVideoOutput() @@ -186,6 +189,7 @@ void QT7MovieViewOutput::setupVideoOutput() [(QTMovieView*)m_movieView setMovie:(QTMovie*)m_movie]; [(NSView *)m_winId addSubview:(QTMovieView*)m_movieView]; + m_layouted = true; setDisplayRect(m_displayRect); } @@ -196,8 +200,21 @@ void QT7MovieViewOutput::setEnabled(bool) void QT7MovieViewOutput::setMovie(void *movie) { - m_movie = movie; - setupVideoOutput(); + if (m_movie != movie) { + if (m_movie) { + if (m_movieView) + [(QTMovieView*)m_movieView setMovie:nil]; + + [(QTMovie*)m_movie release]; + } + + m_movie = movie; + + if (m_movie) + [(QTMovie*)m_movie retain]; + + setupVideoOutput(); + } } void QT7MovieViewOutput::updateNaturalSize(const QSize &newSize) @@ -215,8 +232,15 @@ WId QT7MovieViewOutput::winId() const void QT7MovieViewOutput::setWinId(WId id) { - m_winId = id; - setupVideoOutput(); + if (m_winId != id) { + if (m_movieView && m_layouted) { + [(QTMovieView*)m_movieView removeFromSuperview]; + m_layouted = false; + } + + m_winId = id; + setupVideoOutput(); + } } QRect QT7MovieViewOutput::displayRect() const diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index bdc0a0c..da99368 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -237,6 +237,7 @@ private slots: void task245654_changeModelAndExpandAll(); void doubleClickedWithSpans(); void taskQTBUG_6450_selectAllWith1stColumnHidden(); + void taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint(); }; class QtTestModel: public QAbstractItemModel @@ -3714,5 +3715,34 @@ void tst_QTreeView::taskQTBUG_6450_selectAllWith1stColumnHidden() QVERIFY(tree.selectionModel()->isRowSelected(i, QModelIndex())); } +class TreeViewQTBUG_9216 : public QTreeView +{ + Q_OBJECT +public: + void paintEvent(QPaintEvent *event) + { + QCOMPARE(event->rect(), viewport()->rect()); + QTreeView::paintEvent(event); + } +}; + +void tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint() +{ + QStandardItemModel model(10, 10, this); + for (int row = 0; row < 10; row++) + for (int col = 0; col < 10; col++) + model.setItem(row, col, new QStandardItem(QString("row %0, col %1").arg(row).arg(col))); + TreeViewQTBUG_9216 view; + view.setUniformRowHeights(true); + view.setModel(&model); + view.resize(800, 800); + view.show(); + QTest::qWaitForWindowShown(&view); + + QTest::qWait(100); // This one is needed to make the test fail before the patch. + model.setData(model.index(0, 5), QVariant(QSize(100,100)), Qt::SizeHintRole); + QTest::qWait(100); +} + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 0aca545..0b14cba 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1886,7 +1886,7 @@ bool Configure::findFile( const QString &fileName ) const QString file = fileName.toLower(); const QString pathEnvVar = QString::fromLocal8Bit(getenv("PATH")); const QString mingwPath = dictionary["QMAKESPEC"].endsWith("-g++") ? - findFileInPaths("mingw32-g++.exe", pathEnvVar) : QString(); + findFileInPaths("g++.exe", pathEnvVar) : QString(); QString paths; if (file.endsWith(".h")) { @@ -1978,7 +1978,7 @@ bool Configure::checkAvailability(const QString &part) { bool available = false; if (part == "STYLE_WINDOWSXP") - available = (findFile("uxtheme.h")); + available = findFile("uxtheme.h"); else if (part == "ZLIB") available = findFile("zlib.h"); @@ -3508,14 +3508,15 @@ void Configure::buildQmake() args += makefile; cout << "Creating qmake..." << endl; - int exitCode = 0; - if( exitCode = Environment::execute(args, QStringList(), QStringList()) ) { + int exitCode = Environment::execute(args, QStringList(), QStringList()); + if( exitCode ) { args.clear(); args += dictionary[ "MAKE" ]; args += "-f"; args += makefile; args += "clean"; - if( exitCode = Environment::execute(args, QStringList(), QStringList())) { + exitCode = Environment::execute(args, QStringList(), QStringList()); + if(exitCode) { cout << "Cleaning qmake failed, return code " << exitCode << endl << endl; dictionary[ "DONE" ] = "error"; } else { @@ -3523,7 +3524,8 @@ void Configure::buildQmake() args += dictionary[ "MAKE" ]; args += "-f"; args += makefile; - if (exitCode = Environment::execute(args, QStringList(), QStringList())) { + exitCode = Environment::execute(args, QStringList(), QStringList()); + if (exitCode) { cout << "Building qmake failed, return code " << exitCode << endl << endl; dictionary[ "DONE" ] = "error"; } @@ -3567,8 +3569,8 @@ void Configure::buildHostTools() QDir().mkpath(toolBuildPath); QDir::setCurrent(toolSourcePath); - int exitCode = 0; - if (exitCode = Environment::execute(args, QStringList(), QStringList())) { + int exitCode = Environment::execute(args, QStringList(), QStringList()); + if (exitCode) { cout << "qmake failed, return code " << exitCode << endl << endl; dictionary["DONE"] = "error"; break; @@ -3578,18 +3580,21 @@ void Configure::buildHostTools() args.clear(); args += dictionary["MAKE"]; QDir::setCurrent(toolBuildPath); - if (exitCode = Environment::execute(args, QStringList(), QStringList())) { + exitCode = Environment::execute(args, QStringList(), QStringList()); + if (exitCode) { args.clear(); args += dictionary["MAKE"]; args += "clean"; - if(exitCode = Environment::execute(args, QStringList(), QStringList())) { + exitCode = Environment::execute(args, QStringList(), QStringList()); + if(exitCode) { cout << "Cleaning " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl; dictionary["DONE"] = "error"; break; } else { args.clear(); args += dictionary["MAKE"]; - if (exitCode = Environment::execute(args, QStringList(), QStringList())) { + exitCode = Environment::execute(args, QStringList(), QStringList()); + if (exitCode) { cout << "Building " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl; dictionary["DONE"] = "error"; break; diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index e93f9a0..74bebb2 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -357,7 +357,7 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv QString args = qt_create_commandline(program, arguments); QByteArray envlist = qt_create_environment(fullEnv); - DWORD exitCode = -1; + DWORD exitCode = DWORD(-1); PROCESS_INFORMATION procInfo; memset(&procInfo, 0, sizeof(procInfo)); @@ -378,7 +378,7 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv } - if (exitCode == -1) { + if (exitCode == DWORD(-1)) { switch(GetLastError()) { case E2BIG: cerr << "execute: Argument list exceeds 1024 bytes" << endl; diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index af08777..80e5e34 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -44,6 +44,7 @@ #include <QStringList> #include <QScopedPointer> #include <QTimer> +#include <QFileInfo> #include "symbianutils/trkutils.h" #include "symbianutils/trkdevice.h" #include "symbianutils/launcher.h" @@ -51,9 +52,9 @@ #include "trksignalhandler.h" #include "serenum.h" -void printUsage(QTextStream& outstream) +void printUsage(QTextStream& outstream, QString exeName) { - outstream << "runtest [options] <program> [program arguments]" << endl + outstream << exeName << " [options] [program] [program arguments]" << endl << "-s, --sis <file> specify sis file to install" << endl << "-p, --portname <COMx> specify COM port to use by device name" << endl << "-f, --portfriendlyname <substring> specify COM port to use by friendly name" << endl @@ -61,7 +62,9 @@ void printUsage(QTextStream& outstream) << "-v, --verbose show debugging output" << endl << "-q, --quiet hide progress messages" << endl << endl - << "USB COM ports can usually be autodetected" << endl; + << "USB COM ports can usually be autodetected, use -p or -f to force a specific port." << 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; } int main(int argc, char *argv[]) @@ -86,22 +89,22 @@ int main(int argc, char *argv[]) return 1; } QString param = args.at(i+1); - if(arg.compare("--portname", Qt::CaseSensitive) == 0 + if (arg.compare("--portname", Qt::CaseSensitive) == 0 || arg.compare("-p", Qt::CaseSensitive) == 0) { serialPortName = param; i++; } - else if(arg.compare("--portfriendlyname", Qt::CaseSensitive) == 0 + else if (arg.compare("--portfriendlyname", Qt::CaseSensitive) == 0 || arg.compare("-f", Qt::CaseSensitive) == 0) { serialPortFriendlyName = param; i++; } - else if(arg.compare("--sis", Qt::CaseSensitive) == 0 + else if (arg.compare("--sis", Qt::CaseSensitive) == 0 || arg.compare("-s", Qt::CaseSensitive) == 0) { sisFile = param; i++; } - else if(arg.compare("--timeout", Qt::CaseSensitive) == 0 + else if (arg.compare("--timeout", Qt::CaseSensitive) == 0 || arg.compare("-t", Qt::CaseSensitive) == 0) { bool ok; timeout = param.toInt(&ok); @@ -111,10 +114,10 @@ int main(int argc, char *argv[]) } i++; } - else if(arg.compare("--verbose", Qt::CaseSensitive) == 0 + else if (arg.compare("--verbose", Qt::CaseSensitive) == 0 || arg.compare("-v", Qt::CaseSensitive) == 0) loglevel=2; - else if(arg.compare("--quiet", Qt::CaseSensitive) == 0 + else if (arg.compare("--quiet", Qt::CaseSensitive) == 0 || arg.compare("-q", Qt::CaseSensitive) == 0) loglevel=0; else @@ -128,8 +131,8 @@ int main(int argc, char *argv[]) } } - if(exeFile.isEmpty()) { - printUsage(outstream); + if (exeFile.isEmpty() && sisFile.isEmpty()) { + printUsage(outstream, args[0]); return 1; } @@ -161,24 +164,26 @@ int main(int argc, char *argv[]) } QScopedPointer<trk::Launcher> launcher; - - if (sisFile.isEmpty()) { - launcher.reset(new trk::Launcher(trk::Launcher::ActionCopyRun)); - launcher->setCopyFileName(exeFile, QString("c:\\sys\\bin\\") + exeFile); - errstream << "System TRK required to copy EXE, use --sis if using Application TRK" << endl; - } else { - launcher.reset(new trk::Launcher(trk::Launcher::ActionCopyInstallRun)); - launcher->addStartupActions(trk::Launcher::ActionInstall); + launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly)); + QFileInfo info(exeFile); + if (!sisFile.isEmpty()) { + launcher->addStartupActions(trk::Launcher::ActionCopyInstall); launcher->setCopyFileName(sisFile, "c:\\data\\testtemp.sis"); launcher->setInstallFileName("c:\\data\\testtemp.sis"); } + else if (info.exists()) { + launcher->addStartupActions(trk::Launcher::ActionCopy); + launcher->setCopyFileName(exeFile, QString("c:\\sys\\bin\\") + info.fileName()); + } + if (!exeFile.isEmpty()) { + launcher->addStartupActions(trk::Launcher::ActionRun); + launcher->setFileName(QString("c:\\sys\\bin\\") + info.fileName()); + launcher->setCommandLineArgs(cmdLine); + } if (loglevel > 0) outstream << "Connecting to target via " << serialPortName << endl; launcher->setTrkServerName(serialPortName); - launcher->setFileName(QString("c:\\sys\\bin\\") + exeFile); - launcher->setCommandLineArgs(cmdLine); - if (loglevel > 1) launcher->setVerbose(1); diff --git a/tools/runonphone/symbianutils/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp index 408829b..92b494a 100644 --- a/tools/runonphone/symbianutils/launcher.cpp +++ b/tools/runonphone/symbianutils/launcher.cpp @@ -44,6 +44,7 @@ #include "trkutils_p.h" #include "trkdevice.h" #include "bluetoothlistener.h" +#include "symbiandevicemanager.h" #include <QtCore/QTimer> #include <QtCore/QDateTime> @@ -100,12 +101,15 @@ Launcher::Launcher(Actions startupActions, d(new LauncherPrivate(dev)) { d->m_startupActions = startupActions; - connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult))); - connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); + connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult))); } Launcher::~Launcher() { + // Destroyed before protocol was through: Close + if (d->m_closeDevice && d->m_device->isOpen()) + d->m_device->close(); + emit destroyed(d->m_device->port()); logMessage("Shutting down.\n"); delete d; } @@ -214,11 +218,6 @@ bool Launcher::startServer(QString *errorMessage) } if (!d->m_device->isOpen() && !d->m_device->open(errorMessage)) return false; - if (d->m_closeDevice) { - connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); - } else { - disconnect(this, SIGNAL(finished()), d->m_device.data(), 0); - } setState(Connecting); // Set up the temporary 'waiting' state if we do not get immediate connection QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk())); @@ -266,6 +265,13 @@ void Launcher::logMessage(const QString &msg) qDebug() << "LAUNCHER: " << qPrintable(msg); } +void Launcher::handleFinished() +{ + if (d->m_closeDevice) + d->m_device->close(); + emit finished(); +} + void Launcher::terminate() { switch (state()) { @@ -287,7 +293,7 @@ void Launcher::terminate() case Connecting: case WaitingForTrk: setState(Disconnected); - emit finished(); + handleFinished(); break; } } @@ -446,7 +452,7 @@ void Launcher::handleTrkVersion(const TrkResult &result) if (result.errorCode() || result.data.size() < 5) { if (d->m_startupActions == ActionPingOnly) { setState(Disconnected); - emit finished(); + handleFinished(); } return; } @@ -455,11 +461,13 @@ void Launcher::handleTrkVersion(const TrkResult &result) d->m_session.trkAppVersion.protocolMajor = result.data.at(3); d->m_session.trkAppVersion.protocolMinor = result.data.at(4); setState(DeviceDescriptionReceived); + const QString msg = deviceDescription(); + emit deviceDescriptionReceived(trkServerName(), msg); // Ping mode: Log & Terminate if (d->m_startupActions == ActionPingOnly) { - qWarning("%s", qPrintable(deviceDescription())); + qWarning("%s", qPrintable(msg)); setState(Disconnected); - emit finished(); + handleFinished(); } } @@ -586,7 +594,7 @@ void Launcher::handleWaitForFinished(const TrkResult &result) { logMessage(" FINISHED: " + stringFromArray(result.data)); setState(Disconnected); - emit finished(); + handleFinished(); } void Launcher::handleSupportMask(const TrkResult &result) @@ -704,18 +712,14 @@ QByteArray Launcher::startProcessMessage(const QString &executable, { // It's not started yet QByteArray ba; - appendShort(&ba, 0, TargetByteOrder); // create new process + appendShort(&ba, 0, TargetByteOrder); // create new process (kDSOSProcessItem) ba.append(char(0)); // options - currently unused - if(arguments.isEmpty()) { - appendString(&ba, executable.toLocal8Bit(), TargetByteOrder); - return ba; - } - // Append full command line as one string (leading length information). - QByteArray commandLineBa; - commandLineBa.append(executable.toLocal8Bit()); - commandLineBa.append('\0'); - commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit()); - appendString(&ba, commandLineBa, TargetByteOrder); + // One string consisting of binary terminated by '\0' and arguments terminated by '\0' + QByteArray commandLineBa = executable.toLocal8Bit(); + commandLineBa.append(char(0)); + if (!arguments.isEmpty()) + commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit()); + appendString(&ba, commandLineBa, TargetByteOrder, true); return ba; } @@ -737,4 +741,37 @@ void Launcher::resumeProcess(uint pid, uint tid) appendInt(&ba, tid, BigEndian); d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); } + +// Acquire a device from SymbianDeviceManager, return 0 if not available. +Launcher *Launcher::acquireFromDeviceManager(const QString &serverName, + QObject *parent, + QString *errorMessage) +{ + 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); + return 0; + } + // Wire release signal. + Launcher *rc = new Launcher(trk::Launcher::ActionPingOnly, device, parent); + connect(rc, SIGNAL(deviceDescriptionReceived(QString,QString)), + sdm, SLOT(setAdditionalInformation(QString,QString))); + connect(rc, SIGNAL(destroyed(QString)), sdm, SLOT(releaseDevice(QString))); + return rc; +} + +// Preliminary release of device, disconnecting the signal. +void Launcher::releaseToDeviceManager(Launcher *launcher) +{ + SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); + // Disentangle launcher and its device, remove connection from destroyed + launcher->setCloseDevice(false); + TrkDevice *device = launcher->trkDevice().data(); + launcher->disconnect(device); + device->disconnect(launcher); + launcher->disconnect(sdm); + sdm->releaseDevice(launcher->trkServerName()); +} + } // namespace trk diff --git a/tools/runonphone/symbianutils/launcher.h b/tools/runonphone/symbianutils/launcher.h index 2b23fd8..c47285c 100644 --- a/tools/runonphone/symbianutils/launcher.h +++ b/tools/runonphone/symbianutils/launcher.h @@ -97,7 +97,7 @@ public: void setInstallFileName(const QString &name); void setCommandLineArgs(const QStringList &args); bool startServer(QString *errorMessage); - void setVerbose(int v); + void setVerbose(int v); void setSerialFrame(bool b); bool serialFrame() const; // Close device or leave it open @@ -109,6 +109,15 @@ public: // becomes valid after successful execution of ActionPingOnly QString deviceDescription(unsigned verbose = 0u) const; + // Acquire a device from SymbianDeviceManager, return 0 if not available. + // The device will be released on destruction. + static Launcher *acquireFromDeviceManager(const QString &serverName, + QObject *parent, + QString *errorMessage); + // Preliminary release of device, disconnecting the signal. + static void releaseToDeviceManager(Launcher *l); + + // Create Trk message to start a process. static QByteArray startProcessMessage(const QString &executable, const QStringList &arguments); // Parse a TrkNotifyStopped message @@ -119,6 +128,7 @@ public: static QString msgStopped(uint pid, uint tid, uint address, const QString &why); signals: + void deviceDescriptionReceived(const QString &port, const QString &description); void copyingStarted(); void canNotConnect(const QString &errorMessage); void canNotCreateFile(const QString &filename, const QString &errorMessage); @@ -135,6 +145,8 @@ signals: void copyProgress(int percent); void stateChanged(int); void processStopped(uint pc, uint pid, uint tid, const QString& reason); + // Emitted by the destructor, for releasing devices of SymbianDeviceManager by name + void destroyed(const QString &serverName); public slots: void terminate(); @@ -167,6 +179,7 @@ private: void copyFileToRemote(); void installRemotePackageSilently(); void startInferiorIfNeeded(); + void handleFinished(); void logMessage(const QString &msg); void setState(State s); diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.cpp b/tools/runonphone/symbianutils/symbiandevicemanager.cpp index f663816..8877ea1 100644 --- a/tools/runonphone/symbianutils/symbiandevicemanager.cpp +++ b/tools/runonphone/symbianutils/symbiandevicemanager.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "symbiandevicemanager.h" +#include "trkdevice.h" #include <QtCore/QSettings> #include <QtCore/QStringList> @@ -48,6 +49,7 @@ #include <QtCore/QTextStream> #include <QtCore/QSharedData> #include <QtCore/QScopedPointer> +#include <QtCore/QSignalMapper> namespace SymbianUtils { @@ -61,19 +63,51 @@ const char *SymbianDeviceManager::linuxBlueToothDeviceRootC = "/dev/rfcomm"; // ------------- SymbianDevice class SymbianDeviceData : public QSharedData { public: - SymbianDeviceData() : type(SerialPortCommunication) {} + SymbianDeviceData(); + ~SymbianDeviceData(); + + inline bool isOpen() const { return !device.isNull() && device->isOpen(); } + void forcedClose(); QString portName; QString friendlyName; QString deviceDesc; QString manufacturer; + QString additionalInformation; + DeviceCommunicationType type; + QSharedPointer<trk::TrkDevice> device; + bool deviceAcquired; }; +SymbianDeviceData::SymbianDeviceData() : + type(SerialPortCommunication), + deviceAcquired(false) +{ +} + +SymbianDeviceData::~SymbianDeviceData() +{ + forcedClose(); +} + +void SymbianDeviceData::forcedClose() +{ + // Close the device when unplugging. Should devices be in 'acquired' state, + // their owners should hit on write failures. + // Apart from the <shared item> destructor, also called by the devicemanager + // to ensure it also happens if other shared instances are still around. + if (isOpen()) { + if (deviceAcquired) + qWarning("Device on '%s' unplugged while an operation is in progress.", + qPrintable(portName)); + device->close(); + } +} + SymbianDevice::SymbianDevice(SymbianDeviceData *data) : m_data(data) { - } SymbianDevice::SymbianDevice() : @@ -96,6 +130,11 @@ SymbianDevice::~SymbianDevice() { } +void SymbianDevice::forcedClose() +{ + m_data->forcedClose(); +} + QString SymbianDevice::portName() const { return m_data->portName; @@ -106,6 +145,51 @@ QString SymbianDevice::friendlyName() const return m_data->friendlyName; } +QString SymbianDevice::additionalInformation() const +{ + return m_data->additionalInformation; +} + +void SymbianDevice::setAdditionalInformation(const QString &a) +{ + m_data->additionalInformation = a; +} + +SymbianDevice::TrkDevicePtr SymbianDevice::acquireDevice() +{ + if (debug) + qDebug() << "SymbianDevice::acquireDevice" << m_data->portName + << "acquired: " << m_data->deviceAcquired << " open: " << isOpen(); + if (isNull() || m_data->deviceAcquired) + return TrkDevicePtr(); + if (m_data->device.isNull()) { + m_data->device = TrkDevicePtr(new trk::TrkDevice); + m_data->device->setPort(m_data->portName); + m_data->device->setSerialFrame(m_data->type == SerialPortCommunication); + } + m_data->deviceAcquired = true; + return m_data->device; +} + +void SymbianDevice::releaseDevice(TrkDevicePtr *ptr /* = 0 */) +{ + if (debug) + qDebug() << "SymbianDevice::releaseDevice" << m_data->portName + << " open: " << isOpen(); + if (m_data->deviceAcquired) { + if (m_data->device->isOpen()) + m_data->device->clearWriteQueue(); + // Release if a valid pointer was passed in. + if (ptr && !ptr->isNull()) { + ptr->data()->disconnect(); + *ptr = TrkDevicePtr(); + } + m_data->deviceAcquired = false; + } else { + qWarning("Internal error: Attempt to release device that is not acquired."); + } +} + QString SymbianDevice::deviceDesc() const { return m_data->deviceDesc; @@ -123,7 +207,12 @@ DeviceCommunicationType SymbianDevice::type() const bool SymbianDevice::isNull() const { - return !m_data->portName.isEmpty(); + return m_data->portName.isEmpty(); +} + +bool SymbianDevice::isOpen() const +{ + return m_data->isOpen(); } QString SymbianDevice::toString() const @@ -158,7 +247,7 @@ int SymbianDevice::compare(const SymbianDevice &rhs) const return 0; } -QDebug operator<<(QDebug d, const SymbianDevice &cd) +SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &cd) { d.nospace() << cd.toString(); return d; @@ -166,10 +255,11 @@ QDebug operator<<(QDebug d, const SymbianDevice &cd) // ------------- SymbianDeviceManagerPrivate struct SymbianDeviceManagerPrivate { - SymbianDeviceManagerPrivate() : m_initialized(false) {} + SymbianDeviceManagerPrivate() : m_initialized(false), m_destroyReleaseMapper(0) {} bool m_initialized; SymbianDeviceManager::SymbianDeviceList m_devices; + QSignalMapper *m_destroyReleaseMapper; }; SymbianDeviceManager::SymbianDeviceManager(QObject *parent) : @@ -185,8 +275,7 @@ SymbianDeviceManager::~SymbianDeviceManager() SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const { - if (!d->m_initialized) - const_cast<SymbianDeviceManager*>(this)->update(false); + ensureInitialized(); return d->m_devices; } @@ -194,6 +283,7 @@ QString SymbianDeviceManager::toString() const { QString rc; QTextStream str(&rc); + str << d->m_devices.size() << " devices:\n"; const int count = d->m_devices.size(); for (int i = 0; i < count; i++) { str << '#' << i << ' '; @@ -203,13 +293,37 @@ QString SymbianDeviceManager::toString() const return rc; } +int SymbianDeviceManager::findByPortName(const QString &p) const +{ + ensureInitialized(); + const int count = d->m_devices.size(); + for (int i = 0; i < count; i++) + if (d->m_devices.at(i).portName() == p) + return i; + return -1; +} + QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const { - foreach (const SymbianDevice &device, d->m_devices) { - if (device.portName() == port) - return device.friendlyName(); - } - return QString(); + const int idx = findByPortName(port); + return idx == -1 ? QString() : d->m_devices.at(idx).friendlyName(); +} + +SymbianDeviceManager::TrkDevicePtr + SymbianDeviceManager::acquireDevice(const QString &port) +{ + ensureInitialized(); + 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 TrkDevicePtr(); + } + const TrkDevicePtr rc = d->m_devices[idx].acquireDevice(); + if (debug) + qDebug() << "SymbianDeviceManager::acquireDevice" << port << " returns " << !rc.isNull(); + return rc; } void SymbianDeviceManager::update() @@ -217,12 +331,38 @@ void SymbianDeviceManager::update() update(true); } +void SymbianDeviceManager::releaseDevice(const QString &port) +{ + const int idx = findByPortName(port); + if (debug) + qDebug() << "SymbianDeviceManager::releaseDevice" << port << idx << sender(); + if (idx != -1) { + d->m_devices[idx].releaseDevice(); + } else { + qWarning("Attempt to release non-existing device %s.", qPrintable(port)); + } +} + +void SymbianDeviceManager::setAdditionalInformation(const QString &port, const QString &ai) +{ + const int idx = findByPortName(port); + if (idx != -1) + d->m_devices[idx].setAdditionalInformation(ai); +} + +void SymbianDeviceManager::ensureInitialized() const +{ + if (!d->m_initialized) // Flag is set in update() + const_cast<SymbianDeviceManager*>(this)->update(false); +} + void SymbianDeviceManager::update(bool emitSignals) { + static int n = 0; typedef SymbianDeviceList::iterator SymbianDeviceListIterator; if (debug) - qDebug(">SerialDeviceLister::update(%d)\n%s", int(emitSignals), + qDebug(">SerialDeviceLister::update(#%d, signals=%d)\n%s", n++, int(emitSignals), qPrintable(toString())); d->m_initialized = true; @@ -230,8 +370,11 @@ void SymbianDeviceManager::update(bool emitSignals) SymbianDeviceList newDevices = serialPorts() + blueToothDevices(); if (newDevices.size() > 1) qStableSort(newDevices.begin(), newDevices.end()); - if (d->m_devices == newDevices) // Happy, nothing changed. + if (d->m_devices == newDevices) { // Happy, nothing changed. + if (debug) + qDebug("<SerialDeviceLister::update: unchanged\n"); return; + } // 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 if (!d->m_devices.isEmpty()) { @@ -240,7 +383,8 @@ void SymbianDeviceManager::update(bool emitSignals) if (newDevices.contains(*oldIt)) { ++oldIt; } else { - const SymbianDevice toBeDeleted = *oldIt; + SymbianDevice toBeDeleted = *oldIt; + toBeDeleted.forcedClose(); oldIt = d->m_devices.erase(oldIt); if (emitSignals) emit deviceRemoved(toBeDeleted); @@ -301,16 +445,30 @@ SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() // Bluetooth devices are created on connection. List the existing ones // or at least the first one. const QString prefix = QLatin1String(linuxBlueToothDeviceRootC); - const QString friendlyFormat = QLatin1String("Bluetooth device (%1)"); + const QString blueToothfriendlyFormat = QLatin1String("Bluetooth device (%1)"); for (int d = 0; d < 4; d++) { QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData); device->type = BlueToothCommunication; device->portName = prefix + QString::number(d); if (d == 0 || QFileInfo(device->portName).exists()) { - device->friendlyName = friendlyFormat.arg(device->portName); + device->friendlyName = blueToothfriendlyFormat.arg(device->portName); rc.push_back(SymbianDevice(device.take())); } } + // New kernel versions support /dev/ttyUSB0, /dev/ttyUSB1. Trk responds + // on the latter (usually), try first. + static const char *usbTtyDevices[] = { "/dev/ttyUSB1", "/dev/ttyUSB0" }; + const int usbTtyCount = sizeof(usbTtyDevices)/sizeof(const char *); + for (int d = 0; d < usbTtyCount; d++) { + const QString ttyUSBDevice = QLatin1String(usbTtyDevices[d]); + if (QFileInfo(ttyUSBDevice).exists()) { + SymbianDeviceData *device = new SymbianDeviceData; + device->type = SerialPortCommunication; + device->portName = ttyUSBDevice; + device->friendlyName = QString::fromLatin1("USB/Serial device (%1)").arg(device->portName); + rc.push_back(SymbianDevice(device)); + } + } #endif return rc; } @@ -322,7 +480,7 @@ SymbianDeviceManager *SymbianDeviceManager::instance() return symbianDeviceManager(); } -QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm) +SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm) { d.nospace() << sdm.toString(); return d; diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.h b/tools/runonphone/symbianutils/symbiandevicemanager.h index dcf131a..180173d 100644 --- a/tools/runonphone/symbianutils/symbiandevicemanager.h +++ b/tools/runonphone/symbianutils/symbiandevicemanager.h @@ -46,12 +46,17 @@ #include <QtCore/QObject> #include <QtCore/QExplicitlySharedDataPointer> +#include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE class QDebug; class QTextStream; QT_END_NAMESPACE +namespace trk { + class TrkDevice; +} + namespace SymbianUtils { struct SymbianDeviceManagerPrivate; @@ -62,11 +67,16 @@ enum DeviceCommunicationType { BlueToothCommunication = 1 }; -// SymbianDevice, explicitly shared. +// 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 +// device being closed. class SYMBIANUTILS_EXPORT SymbianDevice { explicit SymbianDevice(SymbianDeviceData *data); friend class SymbianDeviceManager; public: + typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr; + SymbianDevice(); SymbianDevice(const SymbianDevice &rhs); SymbianDevice &operator=(const SymbianDevice &rhs); @@ -77,6 +87,17 @@ public: bool isNull() const; QString portName() const; QString friendlyName() const; + 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. QString deviceDesc() const; @@ -86,10 +107,12 @@ public: QString toString() const; private: + void forcedClose(); + QExplicitlySharedDataPointer<SymbianDeviceData> m_data; }; -QDebug operator<<(QDebug d, const SymbianDevice &); +SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &); inline bool operator==(const SymbianDevice &d1, const SymbianDevice &d2) { return d1.compare(d2) == 0; } @@ -100,13 +123,15 @@ inline bool operator<(const SymbianDevice &d1, const SymbianDevice &d2) /* SymbianDeviceManager: Singleton that maintains a list of Symbian devices. * and emits change signals. - * On Windows, the update slot must be connected to a signal - * emitted from an event handler listening for WM_DEVICECHANGE. */ + * On Windows, the update slot must be connected to a [delayed] signal + * emitted from an event handler listening for WM_DEVICECHANGE. + * Device removal will result in the device being closed. */ class SYMBIANUTILS_EXPORT SymbianDeviceManager : public QObject { Q_OBJECT public: typedef QList<SymbianDevice> SymbianDeviceList; + typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr; static const char *linuxBlueToothDeviceRootC; @@ -120,17 +145,25 @@ public: SymbianDeviceList devices() const; QString toString() const; + // Acquire a device for use. See releaseDevice(). + TrkDevicePtr acquireDevice(const QString &port); + + int findByPortName(const QString &p) const; QString friendlyNameForPort(const QString &port) const; public slots: void update(); + // Relase a device, make it available for further use. + void releaseDevice(const QString &port); + void setAdditionalInformation(const QString &port, const QString &ai); signals: - void deviceRemoved(const SymbianDevice &d); - void deviceAdded(const SymbianDevice &d); + void deviceRemoved(const SymbianUtils::SymbianDevice &d); + void deviceAdded(const SymbianUtils::SymbianDevice &d); void updated(); private: + void ensureInitialized() const; void update(bool emitSignals); SymbianDeviceList serialPorts() const; SymbianDeviceList blueToothDevices() const; @@ -138,7 +171,7 @@ private: SymbianDeviceManagerPrivate *d; }; -QDebug operator<<(QDebug d, const SymbianDeviceManager &); +SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &); } // namespace SymbianUtils diff --git a/tools/runonphone/symbianutils/trkdevice.cpp b/tools/runonphone/symbianutils/trkdevice.cpp index b327ab3..bd24300 100644 --- a/tools/runonphone/symbianutils/trkdevice.cpp +++ b/tools/runonphone/symbianutils/trkdevice.cpp @@ -52,6 +52,7 @@ #include <QtCore/QMutex> #include <QtCore/QWaitCondition> #include <QtCore/QSharedPointer> +#include <QtCore/QScopedPointer> #include <QtCore/QMetaType> #ifdef Q_OS_WIN @@ -102,6 +103,11 @@ QString winErrorMessage(unsigned long error) enum { verboseTrk = 0 }; +static inline QString msgAccessingClosedDevice(const QString &msg) +{ + return QString::fromLatin1("Error: Attempt to access device '%1', which is closed.").arg(msg); +} + namespace trk { /////////////////////////////////////////////////////////////////////// @@ -155,10 +161,11 @@ namespace trk { /////////////////////////////////////////////////////////////////////// class TrkWriteQueue -{ +{ Q_DISABLE_COPY(TrkWriteQueue) public: explicit TrkWriteQueue(); + void clear(); // Enqueue messages. void queueTrkMessage(byte code, TrkCallback callback, @@ -208,13 +215,24 @@ TrkWriteQueue::TrkWriteQueue() : { } +void TrkWriteQueue::clear() +{ + m_trkWriteToken = 0; + m_trkWriteBusy = false; + m_trkWriteQueue.clear(); + const int discarded = m_writtenTrkMessages.size(); + m_writtenTrkMessages.clear(); + if (verboseTrk) + qDebug() << "TrkWriteQueue::clear: discarded " << discarded; +} + byte TrkWriteQueue::nextTrkWriteToken() { ++m_trkWriteToken; if (m_trkWriteToken == 0) ++m_trkWriteToken; if (verboseTrk) - qDebug() << "Write token: " << m_trkWriteToken; + qDebug() << "nextTrkWriteToken:" << m_trkWriteToken; return m_trkWriteToken; } @@ -349,7 +367,7 @@ class WriterThread : public QThread { Q_OBJECT Q_DISABLE_COPY(WriterThread) -public: +public: explicit WriterThread(const QSharedPointer<DeviceContext> &context); // Enqueue messages. @@ -357,6 +375,8 @@ public: const QByteArray &data, const QVariant &cookie); void queueTrkInitialPing(); + void clearWriteQueue(); + // Call this from the device read notification with the results. void slotHandleResult(const TrkResult &result); @@ -374,7 +394,7 @@ public slots: private slots: void invokeNoopMessage(const trk::TrkMessage &); -private: +private: bool write(const QByteArray &data, QString *errorMessage); inline int writePendingMessage(); @@ -462,6 +482,7 @@ void WriterThread::terminate() m_waitCondition.wakeAll(); wait(); m_terminate = false; + m_queue.clear(); } #ifdef Q_OS_WIN @@ -561,6 +582,13 @@ void WriterThread::queueTrkMessage(byte code, TrkCallback callback, tryWrite(); } +void WriterThread::clearWriteQueue() +{ + m_dataMutex.lock(); + m_queue.clear(); + m_dataMutex.unlock(); +} + void WriterThread::queueTrkInitialPing() { m_dataMutex.lock(); @@ -592,6 +620,8 @@ class ReaderThreadBase : public QThread Q_DISABLE_COPY(ReaderThreadBase) public: + int bytesPending() const { return m_trkReadBuffer.size(); } + signals: void messageReceived(const trk::TrkResult &result, const QByteArray &rawData); @@ -692,7 +722,7 @@ int WinReaderThread::tryRead() if (!ClearCommError(m_context->device, NULL, &comStat)){ emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError()))); return -7; - } + } const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize))); // Trigger read DWORD bytesRead = 0; @@ -708,7 +738,7 @@ int WinReaderThread::tryRead() if (readError != ERROR_IO_PENDING) { emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError))); return -1; - } + } // Wait for either termination or data const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE); if (wr == WAIT_FAILED) { @@ -783,7 +813,7 @@ private: int m_terminatePipeFileDescriptors[2]; }; -UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) : +UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) : ReaderThreadBase(context) { m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1; @@ -877,8 +907,8 @@ struct TrkDevicePrivate TrkDevicePrivate(); QSharedPointer<DeviceContext> deviceContext; - QSharedPointer<WriterThread> writerThread; - QSharedPointer<ReaderThread> readerThread; + QScopedPointer<WriterThread> writerThread; + QScopedPointer<ReaderThread> readerThread; QByteArray trkReadBuffer; int verbose; @@ -917,14 +947,14 @@ TrkDevice::~TrkDevice() bool TrkDevice::open(QString *errorMessage) { - if (d->verbose) + if (d->verbose || verboseTrk) qDebug() << "Opening" << port() << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + if (isOpen()) + return true; if (d->port.isEmpty()) { *errorMessage = QLatin1String("Internal error: No port set on TrkDevice"); return false; } - - close(); #ifdef Q_OS_WIN const QString fullPort = QLatin1String("\\\\.\\") + d->port; d->deviceContext->device = CreateFile(reinterpret_cast<const WCHAR*>(fullPort.utf16()), @@ -975,7 +1005,7 @@ bool TrkDevice::open(QString *errorMessage) return false; } #endif - d->readerThread = QSharedPointer<ReaderThread>(new ReaderThread(d->deviceContext)); + d->readerThread.reset(new ReaderThread(d->deviceContext)); connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), Qt::QueuedConnection); connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)), @@ -983,18 +1013,22 @@ bool TrkDevice::open(QString *errorMessage) Qt::QueuedConnection); d->readerThread->start(); - d->writerThread = QSharedPointer<WriterThread>(new WriterThread(d->deviceContext)); + d->writerThread.reset(new WriterThread(d->deviceContext)); connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), - Qt::QueuedConnection); - d->writerThread->start(); + Qt::QueuedConnection); + d->writerThread->start(); - if (d->verbose) - qDebug() << "Opened" << d->port; + if (d->verbose || verboseTrk) + qDebug() << "Opened" << d->port << d->readerThread.data() << d->writerThread.data(); return true; } void TrkDevice::close() { + if (verboseTrk) + qDebug() << "close" << d->port << " is open: " << isOpen() + << " read pending " << (d->readerThread.isNull() ? 0 : d->readerThread->bytesPending()) + << sender(); if (!isOpen()) return; if (d->readerThread) @@ -1010,6 +1044,7 @@ void TrkDevice::close() #else d->deviceContext->file.close(); #endif + if (d->verbose) emitLogMessage("Close"); } @@ -1030,6 +1065,8 @@ QString TrkDevice::port() const void TrkDevice::setPort(const QString &p) { + if (verboseTrk) + qDebug() << "setPort" << p; d->port = p; } @@ -1045,6 +1082,8 @@ bool TrkDevice::serialFrame() const void TrkDevice::setSerialFrame(bool f) { + if (verboseTrk) + qDebug() << "setSerialFrame" << f; d->deviceContext->serialFrame = f; } @@ -1060,12 +1099,14 @@ void TrkDevice::setVerbose(int b) void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) { - d->writerThread->slotHandleResult(result); - if (d->verbose > 1) - qDebug() << "Received: " << result.toString(); - emit messageReceived(result); - if (!rawData.isEmpty()) - emit rawDataReceived(rawData); + if (isOpen()) { // Might receive bytes after closing due to queued connections. + d->writerThread->slotHandleResult(result); + if (d->verbose > 1) + qDebug() << "Received: " << result.toString(); + emit messageReceived(result); + if (!rawData.isEmpty()) + emit rawDataReceived(rawData); + } } void TrkDevice::emitError(const QString &s) @@ -1075,15 +1116,27 @@ void TrkDevice::emitError(const QString &s) emit error(s); } +void TrkDevice::clearWriteQueue() +{ + if (isOpen()) + d->writerThread->clearWriteQueue(); +} + void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, const QByteArray &data, const QVariant &cookie) { + if (!isOpen()) { + emitError(msgAccessingClosedDevice(d->port)); + return; + } if (!d->writerThread.isNull()) { if (d->verbose > 1) { - QByteArray msg = "Sending: "; + QByteArray msg = "Sending: 0x"; msg += QByteArray::number(code, 16); msg += ": "; msg += stringFromArray(data).toLatin1(); + if (cookie.isValid()) + msg += " Cookie: " + cookie.toString().toLatin1(); qDebug("%s", msg.data()); } d->writerThread->queueTrkMessage(code, callback, data, cookie); @@ -1092,12 +1145,20 @@ void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, void TrkDevice::sendTrkInitialPing() { + if (!isOpen()) { + emitError(msgAccessingClosedDevice(d->port)); + return; + } if (!d->writerThread.isNull()) d->writerThread->queueTrkInitialPing(); } bool TrkDevice::sendTrkAck(byte token) { + if (!isOpen()) { + emitError(msgAccessingClosedDevice(d->port)); + return false; + } if (d->writerThread.isNull()) return false; // The acknowledgement must not be queued! diff --git a/tools/runonphone/symbianutils/trkdevice.h b/tools/runonphone/symbianutils/trkdevice.h index 78012fd..1021a7d 100644 --- a/tools/runonphone/symbianutils/trkdevice.h +++ b/tools/runonphone/symbianutils/trkdevice.h @@ -64,12 +64,14 @@ struct TrkDevicePrivate; * Trk communications. Provides synchronous write and asynchronous * read operation. * The serialFrames property specifies whether packets are encapsulated in - * "0x90 <length>" frames, which is currently the case for serial ports. + * "0x90 <length>" frames, which is currently the case for serial ports. * Contains a write message queue allowing * for queueing messages with a notification callback. If the message receives * an ACK, the callback is invoked. - * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronisation. - * The respective message will not be sent, the callback is just invoked. */ + * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronization. + * The respective message will not be sent, the callback is just invoked. + * Note that calling open/close in quick succession can cause crashes + * due to the use of queused signals. */ enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; @@ -111,6 +113,9 @@ public: // Send an Ack synchronously, bypassing the queue bool sendTrkAck(unsigned char token); +public slots: + void clearWriteQueue(); + signals: void messageReceived(const trk::TrkResult &result); // Emitted with the contents of messages enclosed in 07e, not for log output diff --git a/tools/runonphone/trksignalhandler.cpp b/tools/runonphone/trksignalhandler.cpp index 18a2c0c..2abf91f 100644 --- a/tools/runonphone/trksignalhandler.cpp +++ b/tools/runonphone/trksignalhandler.cpp @@ -54,6 +54,7 @@ private: QTextStream out; QTextStream err; int loglevel; + int lastpercent; }; void TrkSignalHandler::copyingStarted() @@ -131,7 +132,12 @@ void TrkSignalHandler::applicationOutputReceived(const QString &output) void TrkSignalHandler::copyProgress(int percent) { if (d->loglevel > 0) { - d->out << percent << "% "; + if (d->lastpercent == 0) + d->out << "[ ]\r[" << flush; + while (percent > d->lastpercent) { + d->out << QLatin1Char('#'); + d->lastpercent+=2; //because typical console is 80 chars wide + } d->out.flush(); if (percent==100) d->out << endl; @@ -167,7 +173,8 @@ void TrkSignalHandler::timeout() TrkSignalHandlerPrivate::TrkSignalHandlerPrivate() : out(stdout), err(stderr), - loglevel(0) + loglevel(0), + lastpercent(0) { } diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp index d342d78..67d9b56 100644 --- a/tools/shared/windows/registry.cpp +++ b/tools/shared/windows/registry.cpp @@ -148,7 +148,7 @@ QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) } default: - qWarning("QSettings: unknown data %d type in windows registry", dataType); + qWarning("QSettings: unknown data %u type in windows registry", quint32(dataType)); break; } |