diff options
58 files changed, 930 insertions, 263 deletions
@@ -5734,6 +5734,13 @@ if [ "$CFG_QML_DEBUG" = "no" ]; then fi case "$QMAKE_CONF_COMPILER" in +*clang++*) + # Clang + COMPILER_VERSION=`${QMAKE_CONF_COMPILER} -v 2>&1 | sed -n ' +/^Apple clang version /{s///; s/^\([0-9]*\)\.\([0-9]*\).*$/QT_APPLE_CLANG_MAJOR_VERSION=\1; QT_APPLE_CLANG_MINOR_VERSION=\2/;p;q;} +/^clang version /{s///; s/^\([0-9]*\)\.\([0-9]*\).*$/QT_CLANG_MAJOR_VERSION=\1; QT_CLANG_MINOR_VERSION=\2/;p;q;}'` + eval "$COMPILER_VERSION" + ;; *g++*) # GNU C++ COMPILER_VERSION=`${QMAKE_CONF_COMPILER} -dumpversion 2>/dev/null` @@ -6074,6 +6081,14 @@ if [ -n "$QT_GCC_MAJOR_VERSION" ]; then echo "QT_GCC_MINOR_VERSION = $QT_GCC_MINOR_VERSION" >> "$QTCONFIG.tmp" echo "QT_GCC_PATCH_VERSION = $QT_GCC_PATCH_VERSION" >> "$QTCONFIG.tmp" fi +if [ -n "$QT_CLANG_MAJOR_VERSION" ]; then + echo "QT_CLANG_MAJOR_VERSION = $QT_CLANG_MAJOR_VERSION" >> "$QTCONFIG.tmp" + echo "QT_CLANG_MINOR_VERSION = $QT_CLANG_MINOR_VERSION" >> "$QTCONFIG.tmp" +fi +if [ -n "$QT_APPLE_CLANG_MAJOR_VERSION" ]; then + echo "QT_APPLE_CLANG_MAJOR_VERSION = $QT_APPLE_CLANG_MAJOR_VERSION" >> "$QTCONFIG.tmp" + echo "QT_APPLE_CLANG_MINOR_VERSION = $QT_APPLE_CLANG_MINOR_VERSION" >> "$QTCONFIG.tmp" +fi if [ -n "$QMAKE_INCDIR_OPENGL_ES2" ]; then echo "#Qt opengl include path" >> "$QTCONFIG.tmp" diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h index a8664cf752..e6a7853c96 100644 --- a/src/corelib/arch/qatomic_vxworks.h +++ b/src/corelib/arch/qatomic_vxworks.h @@ -56,8 +56,13 @@ QT_BEGIN_HEADER # include <vxWorksCommon.h> # include <taskLib.h> #else +#if defined(_WRS_KERNEL) extern "C" int taskLock(); extern "C" int taskUnlock(); +#else +inline int taskLock() { return 0; } +inline int taskUnlock() { return 0; } +#endif #endif diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 01756c8419..491464621c 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -9,6 +9,7 @@ HEADERS += \ global/qendian.h \ global/qnumeric_p.h \ global/qnumeric.h \ + global/qglobalstatic.h \ global/qlibraryinfo.h \ global/qlogging.h \ global/qtypeinfo.h \ diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index a0c12b7b06..454e5d828d 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -68,7 +68,7 @@ # endif #endif -#if defined(Q_OS_VXWORKS) +#if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL) # include <envLib.h> #endif diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 7e029a139d..f3be05a8ec 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -664,125 +664,6 @@ typedef void (*QFunctionPointer)(); # define Q_UNIMPLEMENTED() qWarning("%s:%d: %s: Unimplemented code.", __FILE__, __LINE__, Q_FUNC_INFO) #endif -#if defined(QT_NO_THREAD) - -template <typename T> -class QGlobalStatic -{ -public: - T *pointer; - inline QGlobalStatic(T *p) : pointer(p) { } - inline ~QGlobalStatic() { pointer = 0; } -}; - -#define Q_GLOBAL_STATIC(TYPE, NAME) \ - static TYPE *NAME() \ - { \ - static TYPE thisVariable; \ - static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \ - return thisGlobalStatic.pointer; \ - } - -#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ - static TYPE *NAME() \ - { \ - static TYPE thisVariable ARGS; \ - static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \ - return thisGlobalStatic.pointer; \ - } - -#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \ - static TYPE *NAME() \ - { \ - static TYPE thisVariable; \ - static QGlobalStatic<TYPE > thisGlobalStatic(0); \ - if (!thisGlobalStatic.pointer) { \ - TYPE *x = thisGlobalStatic.pointer = &thisVariable; \ - INITIALIZER; \ - } \ - return thisGlobalStatic.pointer; \ - } - -#else - -// forward declaration, since qatomic.h needs qglobal.h -template <typename T> class QBasicAtomicPointer; - -// POD for Q_GLOBAL_STATIC -template <typename T> -class QGlobalStatic -{ -public: - QBasicAtomicPointer<T> pointer; - bool destroyed; -}; - -// Created as a function-local static to delete a QGlobalStatic<T> -template <typename T> -class QGlobalStaticDeleter -{ -public: - QGlobalStatic<T> &globalStatic; - QGlobalStaticDeleter(QGlobalStatic<T> &_globalStatic) - : globalStatic(_globalStatic) - { } - - inline ~QGlobalStaticDeleter() - { - delete globalStatic.pointer.load(); - globalStatic.pointer.store(0); - globalStatic.destroyed = true; - } -}; - -#define Q_GLOBAL_STATIC(TYPE, NAME) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { \ - TYPE *x = new TYPE; \ - if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \ - delete x; \ - else \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ - } \ - return thisGlobalStatic.pointer.load(); \ - } - -#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { \ - TYPE *x = new TYPE ARGS; \ - if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \ - delete x; \ - else \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ - } \ - return thisGlobalStatic.pointer.load(); \ - } - -#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { \ - QScopedPointer<TYPE > x(new TYPE); \ - INITIALIZER; \ - if (thisGlobalStatic.pointer.testAndSetOrdered(0, x.data())) { \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ - x.take(); \ - } \ - } \ - return thisGlobalStatic.pointer.load(); \ - } - -#endif - Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) { return (qAbs(p1 - p2) <= 0.000000000001 * qMin(qAbs(p1), qAbs(p2))); @@ -1089,6 +970,9 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; }; QT_END_NAMESPACE QT_END_HEADER +// Q_GLOBAL_STATIC +#include <QtCore/qglobalstatic.h> + // qDebug and friends #include <QtCore/qlogging.h> #include <QtCore/qflags.h> diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h new file mode 100644 index 0000000000..78a4acff12 --- /dev/null +++ b/src/corelib/global/qglobalstatic.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Intel Corporation +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qglobal.h> + +#ifndef QGLOBALSTATIC_H +#define QGLOBALSTATIC_H + +#include <QtCore/qatomic.h> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +/* + * QGlobalStatic internals: + * + * The pointer is initialized to 0. + * The guard is initialized to 0. + * The guard can assume the following values: + * -2: object initialized and already destroyed + * -1: object initialized and is still valid + * 0: not initialized, the value of the pointer should be null + * +1: initializing, must wait until a state change happens + * (not used in the current implementation) + */ + +namespace QtGlobalStatic { +enum GuardValues { + Destroyed = -2, + Initialized = -1, + Uninitialized = 0, + Initializing = 1 +}; +} + +#if defined(QT_NO_THREAD) || defined(Q_CC_GNU) +// some compilers support thread-safe statics +// The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4 +// support it. C++11 also requires this behavior. +// Clang and Intel CC masquerade as GCC when compiling on Linux and Mac OS X. + +#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \ + Q_DECL_HIDDEN inline Type *innerFunction() \ + { \ + struct HolderBase { \ + ~HolderBase() Q_DECL_NOTHROW \ + { guard.store(QtGlobalStatic::Destroyed); } \ + }; \ + static struct Holder : public HolderBase { \ + Type value; \ + Holder() \ + Q_DECL_NOEXCEPT_EXPR(noexcept(Type ARGS)) \ + : value ARGS \ + { guard.store(QtGlobalStatic::Initialized); } \ + } holder; \ + return &holder.value; \ + } +#else +// We don't know if this compiler supports thread-safe global statics +// so use our own locked implementation + +QT_END_NAMESPACE +#include <QtCore/qmutex.h> +QT_BEGIN_NAMESPACE + +#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \ + Q_DECL_HIDDEN inline Type *innerFunction() \ + { \ + static Type *d; \ + static QBasicMutex mutex; \ + int x = guard.loadAcquire(); \ + if (Q_UNLIKELY(x >= QtGlobalStatic::Uninitialized)) { \ + QMutexLocker locker(&mutex); \ + if (guard.load() == QtGlobalStatic::Uninitialized) { \ + d = new Type ARGS; \ + static struct Cleanup { \ + ~Cleanup() { \ + delete d; \ + guard.store(QtGlobalStatic::Destroyed); \ + } \ + } cleanup; \ + guard.store(QtGlobalStatic::Initialized); \ + } \ + } \ + return d; \ + } +#endif + +// this class must be POD, unless the compiler supports thread-safe statics +template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard> +struct QGlobalStatic +{ + typedef T Type; + + bool isDestroyed() const { return guard.load() <= QtGlobalStatic::Destroyed; } + bool exists() const { return guard.load() == QtGlobalStatic::Initialized; } + operator Type *() { if (isDestroyed()) return 0; return innerFunction(); } + Type *operator()() { if (isDestroyed()) return 0; return innerFunction(); } + Type *operator->() { return innerFunction(); } + Type &operator*() { return *innerFunction(); } +}; + +#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ + namespace { namespace Q_QGS_ ## NAME { \ + typedef TYPE Type; \ + QBasicAtomicInt guard = Q_BASIC_ATOMIC_INITIALIZER(QtGlobalStatic::Uninitialized); \ + Q_GLOBAL_STATIC_INTERNAL(ARGS) \ + } } \ + static QGlobalStatic<TYPE, \ + Q_QGS_ ## NAME::innerFunction, \ + Q_QGS_ ## NAME::guard> NAME; + +#define Q_GLOBAL_STATIC(TYPE, NAME) \ + Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ()) + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QGLOBALSTATIC_H diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 60ba19e625..20e649bab5 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -73,7 +73,7 @@ static bool isFatal(QtMsgType msgType) return true; if (msgType == QtWarningMsg) { - static bool fatalWarnings = qEnvironmentVariableIsSet("QT_FATAL_WARNINGS"); + static bool fatalWarnings = !qEnvironmentVariableIsEmpty("QT_FATAL_WARNINGS"); return fatalWarnings; } diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 2fc7557509..985e0541ae 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -286,7 +286,7 @@ QString QFileSystemEngine::resolveUserName(uint userId) struct passwd *pw = 0; #if !defined(Q_OS_INTEGRITY) -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS) struct passwd entry; getpwuid_r(userId, &entry, buf.data(), buf.size(), &pw); #else @@ -310,7 +310,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) struct group *gr = 0; #if !defined(Q_OS_INTEGRITY) -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS) size_max = sysconf(_SC_GETGR_R_SIZE_MAX); if (size_max == -1) size_max = 1024; @@ -685,8 +685,16 @@ QFileSystemEntry QFileSystemEngine::currentPath() } #else char currentName[PATH_MAX+1]; - if (::getcwd(currentName, PATH_MAX)) + if (::getcwd(currentName, PATH_MAX)) { +#if defined(Q_OS_VXWORKS) && defined(VXWORKS_VXSIM) + QByteArray dir(currentName); + if (dir.indexOf(':') < dir.indexOf('/')) + dir.remove(0, dir.indexOf(':')+1); + + qstrncpy(currentName, dir.constData(), PATH_MAX); +#endif result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath()); + } # if defined(QT_DEBUG) if (result.isEmpty()) qWarning("QFileSystemEngine::currentPath: getcwd() failed"); diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 7a0e9eb4ef..233b7eef2f 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -113,7 +113,7 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() } #elif defined(Q_OS_VXWORKS) char name[20]; - qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent)); + qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf())); // make sure there is no pipe with this name pipeDevDelete(name, true); @@ -159,7 +159,7 @@ QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() close(thread_pipe[0]); char name[20]; - qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent)); + qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf())); pipeDevDelete(name, true); #else diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 0d91fda778..f1d33f9f09 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -61,9 +61,7 @@ #include "QtCore/qvarlengtharray.h" #include "private/qtimerinfo_unix_p.h" -#if defined(Q_OS_VXWORKS) -# include <sys/times.h> -#else +#if !defined(Q_OS_VXWORKS) # include <sys/time.h> # if (!defined(Q_OS_HPUX) || defined(__ia64)) && !defined(Q_OS_NACL) # include <sys/select.h> diff --git a/src/corelib/kernel/qfunctions_vxworks.cpp b/src/corelib/kernel/qfunctions_vxworks.cpp index 2174588757..8d25ad6a8d 100644 --- a/src/corelib/kernel/qfunctions_vxworks.cpp +++ b/src/corelib/kernel/qfunctions_vxworks.cpp @@ -46,7 +46,9 @@ #include "qplatformdefs.h" #include "qfunctions_vxworks.h" +#if defined(_WRS_KERNEL) #include <vmLib.h> +#endif #include <selectLib.h> #include <ioLib.h> @@ -92,7 +94,7 @@ int usleep(unsigned int usec) // gettimeofday() is declared, but is missing from the library // It IS however defined in the Curtis-Wright X11 libraries, so // we have to make the symbol 'weak' -#if defined(Q_CC_DIAB) +#if defined(Q_CC_DIAB) && !defined(VXWORKS_DKM) && !defined(VXWORKS_RTP) # pragma weak gettimeofday #endif int gettimeofday(struct timeval *tv, void /*struct timezone*/ *) @@ -118,7 +120,11 @@ int gettimeofday(struct timeval *tv, void /*struct timezone*/ *) // neither getpagesize() or sysconf(_SC_PAGESIZE) are available int getpagesize() { +#if defined(_WRS_KERNEL) return vmPageSizeGet(); +#else + return sysconf(_SC_PAGESIZE); +#endif } // symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h) diff --git a/src/corelib/kernel/qfunctions_vxworks.h b/src/corelib/kernel/qfunctions_vxworks.h index 6339903cff..6776a6a721 100644 --- a/src/corelib/kernel/qfunctions_vxworks.h +++ b/src/corelib/kernel/qfunctions_vxworks.h @@ -52,7 +52,11 @@ #include <errno.h> #include <sys/types.h> #include <sys/ioctl.h> +#if defined(_WRS_KERNEL) #include <sys/times.h> +#else +#include <sys/time.h> +#endif #include <sys/socket.h> #include <sys/stat.h> #include <sys/wait.h> @@ -61,6 +65,44 @@ #include <net/if.h> #endif +// VxWorks has public header mbuf.h which defines following variables for DKM. +// Let's undef those to because they overlap with Qt variable names- +// File mbuf.h is included in headers <netinet/in.h> <net/if.h>, so make sure +// that those are included before undef's. +#if defined(mbuf) +# undef mbuf +#endif +#if defined(m_data) +# undef m_data +#endif +#if defined(m_type) +# undef m_type +#endif +#if defined(m_next) +# undef m_next +#endif +#if defined(m_len) +# undef m_len +#endif +#if defined(m_flags) +# undef m_flags +#endif +#if defined(m_hdr) +# undef m_hdr +#endif +#if defined(m_ext) +# undef m_ext +#endif +#if defined(m_act) +# undef m_act +#endif +#if defined(m_nextpkt) +# undef m_nextpkt +#endif +#if defined(m_pkthdr) +# undef m_pkthdr +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -100,12 +142,16 @@ int rand_r(unsigned int * /*seedp*/); // no usleep() support int usleep(unsigned int); +#if defined(VXWORKS_DKM) || defined(VXWORKS_RTP) +int gettimeofday(struct timeval *, void *); +#else // gettimeofday() is declared, but is missing from the library. // It IS however defined in the Curtis-Wright X11 libraries, so // we have to make the symbol 'weak' int gettimeofday(struct timeval *tv, void /*struct timezone*/ *) __attribute__((weak)); +#endif -// neither getpagesize() or sysconf(_SC_PAGESIZE) are available +// getpagesize() not available int getpagesize(); // symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h) diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index 7f13e3b1a2..fdd73657a9 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -151,9 +151,6 @@ key_t QSharedMemoryPrivate::handle() */ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName) { - if (QFile::exists(fileName)) - return 0; - int fd = qt_safe_open(QFile::encodeName(fileName).constData(), O_EXCL | O_CREAT | O_RDWR, 0640); if (-1 == fd) { diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index 5044d09e9b..2aed877e6b 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -56,7 +56,7 @@ #include <string.h> #endif -#if defined(Q_OS_VXWORKS) || defined (Q_OS_NACL) +#if (defined(Q_OS_VXWORKS) && !defined(VXWORKS_RTP)) || defined (Q_OS_NACL) #define QT_NO_DYNAMIC_LIBRARY #endif diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 8abf1d06ef..253f3c79e7 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -488,8 +488,20 @@ static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_pr #endif const int highestPriority = QThread::TimeCriticalPriority; - int prio_min = sched_get_priority_min(*sched_policy); - int prio_max = sched_get_priority_max(*sched_policy); + int prio_min; + int prio_max; +#if defined(Q_OS_VXWORKS) && defined(VXWORKS_DKM) + // for other scheduling policies than SCHED_RR or SCHED_FIFO + prio_min = SCHED_FIFO_LOW_PRI; + prio_max = SCHED_FIFO_HIGH_PRI; + + if ((*sched_policy == SCHED_RR) || (*sched_policy == SCHED_FIFO)) +#endif + { + prio_min = sched_get_priority_min(*sched_policy); + prio_max = sched_get_priority_max(*sched_policy); + } + if (prio_min == -1 || prio_max == -1) return false; diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp index e719358ce0..b0dbb1f047 100644 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -43,8 +43,12 @@ #define _POSIX_C_SOURCE 200809L #include "qelapsedtimer.h" +#ifdef Q_OS_VXWORKS +#include "qfunctions_vxworks.h" +#else #include <sys/time.h> #include <time.h> +#endif #include <unistd.h> #include <qatomic.h> diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h index 5d19bcea55..f7ac8da572 100644 --- a/src/corelib/tools/qscopedpointer.h +++ b/src/corelib/tools/qscopedpointer.h @@ -97,7 +97,6 @@ public: { T *oldD = this->d; Cleanup::cleanup(oldD); - this->d = 0; } inline T &operator*() const diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index a4c241941f..7e56ea9fbd 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -803,13 +803,8 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis return false; if (options & QDBusConnectionPrivate::VirtualObject) { - // technically the check for children needs to go even deeper - if (options & SubPath) { - foreach (const QDBusConnectionPrivate::ObjectTreeNode &child, node->children) { - if (child.obj) - return false; - } - } + if (options & SubPath && node->activeChildren) + return false; } else { if ((options & ExportChildObjects && !node->children.isEmpty())) return false; @@ -825,8 +820,8 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis // if a virtual object occupies this path, return false if (node->obj && (node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath)) { - qDebug("Cannot register object at %s because QDBusVirtualObject handles all sub-paths.", - qPrintable(path)); + //qDebug("Cannot register object at %s because QDBusVirtualObject handles all sub-paths.", + // qPrintable(path)); return false; } @@ -840,12 +835,13 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis // are we allowed to go deeper? if (node->flags & ExportChildObjects) { // we're not - qDebug("Cannot register object at %s because %s exports its own child objects", - qPrintable(path), qPrintable(pathComponents.at(i))); + //qDebug("Cannot register object at %s because %s exports its own child objects", + // qPrintable(path), qPrintable(pathComponents.at(i))); return false; } } else { // add entry + ++node->activeChildren; node = node->children.insert(it, pathComponents.at(i)); } @@ -883,35 +879,8 @@ void QDBusConnection::unregisterObject(const QString &path, UnregisterMode mode) if (!d || !d->connection || !QDBusUtil::isValidObjectPath(path)) return; - QStringList pathComponents = path.split(QLatin1Char('/')); QDBusWriteLocker locker(UnregisterObjectAction, d); - QDBusConnectionPrivate::ObjectTreeNode *node = &d->rootNode; - int i = 1; - - // find the object - while (node) { - if (pathComponents.count() == i || !path.compare(QLatin1String("/"))) { - // found it - node->obj = 0; - node->flags = 0; - - if (mode == UnregisterTree) { - // clear the sub-tree as well - node->children.clear(); // can't disconnect the objects because we really don't know if they can - // be found somewhere else in the path too - } - - return; - } - - QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = - std::lower_bound(node->children.begin(), node->children.end(), pathComponents.at(i)); - if (it == node->children.end() || it->name != pathComponents.at(i)) - break; // node not found - - node = it; - ++i; - } + d->unregisterObject(path, mode); } /*! diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 2c3ddefc50..bef0b88f78 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -140,14 +140,16 @@ public: { typedef QVector<ObjectTreeNode> DataList; - inline ObjectTreeNode() : obj(0), flags(0) { } + inline ObjectTreeNode() : obj(0), flags(0), activeChildren(0) { } inline ObjectTreeNode(const QString &n) // intentionally implicit - : name(n), obj(0), flags(0) { } + : name(n), obj(0), flags(0), activeChildren(0) { } inline ~ObjectTreeNode() { } inline bool operator<(const QString &other) const { return name < other; } inline bool operator<(const QStringRef &other) const { return QStringRef(&name) < other; } + inline bool isActive() const + { return obj || activeChildren; } QString name; union { @@ -155,6 +157,7 @@ public: QDBusVirtualObject *treeNode; }; int flags; + int activeChildren; DataList children; }; @@ -208,6 +211,7 @@ public: const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot); void registerObject(const ObjectTreeNode *node); + void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode); void connectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const QMetaMethod &signal); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index bc49d6816e..4326ee1fa0 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -587,17 +587,76 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) return false; } +static void garbageCollectChildren(QDBusConnectionPrivate::ObjectTreeNode &node) +{ + int size = node.children.count(); + if (node.activeChildren == 0) { + // easy case + node.children.clear(); + } else if (size > node.activeChildren * 3 || (size > 20 && size * 2 > node.activeChildren * 3)) { + // rewrite the vector, keeping only the active children + // if the vector is large (> 20 items) and has one third of inactives + // or if the vector is small and has two thirds of inactives. + QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = node.children.end(); + QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = node.children.begin(); + QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator tgt = it; + for ( ; it != end; ++it) { + if (it->isActive()) + *tgt++ = qMove(*it); + } + ++tgt; + node.children.erase(tgt, end); + } +} + static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNode &haystack) { QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin(); QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = haystack.children.end(); - for ( ; it != end; ++it) + for ( ; it != end; ++it) { + if (!it->isActive()) + continue; huntAndDestroy(needle, *it); + if (!it->isActive()) + --haystack.activeChildren; + } if (needle == haystack.obj) { haystack.obj = 0; haystack.flags = 0; } + + garbageCollectChildren(haystack); +} + +static void huntAndUnregister(const QStringList &pathComponents, int i, QDBusConnection::UnregisterMode mode, + QDBusConnectionPrivate::ObjectTreeNode *node) +{ + if (pathComponents.count() == i) { + // found it + node->obj = 0; + node->flags = 0; + + if (mode == QDBusConnection::UnregisterTree) { + // clear the sub-tree as well + node->activeChildren = 0; + node->children.clear(); // can't disconnect the objects because we really don't know if they can + // be found somewhere else in the path too + } + } else { + // keep going + QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = node->children.end(); + QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = + std::lower_bound(node->children.begin(), end, pathComponents.at(i)); + if (it == end || it->name != pathComponents.at(i) || !it->isActive()) + return; // node not found + + huntAndUnregister(pathComponents, i + 1, mode, it); + if (!it->isActive()) + --node->activeChildren; + + garbageCollectChildren(*node); + } } static void huntAndEmit(DBusConnection *connection, DBusMessage *msg, @@ -606,8 +665,10 @@ static void huntAndEmit(DBusConnection *connection, DBusMessage *msg, { QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it = haystack.children.constBegin(); QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator end = haystack.children.constEnd(); - for ( ; it != end; ++it) - huntAndEmit(connection, msg, needle, *it, isScriptable, isAdaptor, path + QLatin1Char('/') + it->name); + for ( ; it != end; ++it) { + if (it->isActive()) + huntAndEmit(connection, msg, needle, *it, isScriptable, isAdaptor, path + QLatin1Char('/') + it->name); + } if (needle == haystack.obj) { // is this a signal we should relay? @@ -2224,19 +2285,6 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) return signalHooks.erase(it); } - -static void cleanupDeletedNodes(QDBusConnectionPrivate::ObjectTreeNode &parent) -{ - QMutableVectorIterator<QDBusConnectionPrivate::ObjectTreeNode> it(parent.children); - while (it.hasNext()) { - QDBusConnectionPrivate::ObjectTreeNode& node = it.next(); - if (node.obj == 0 && node.children.isEmpty()) - it.remove(); - else - cleanupDeletedNodes(node); - } -} - void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node) { connect(node->obj, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*)), @@ -2260,10 +2308,21 @@ void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node) this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList)), Qt::DirectConnection); } +} + +void QDBusConnectionPrivate::unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode) +{ + QDBusConnectionPrivate::ObjectTreeNode *node = &rootNode; + QStringList pathComponents; + int i; + if (path == QLatin1String("/")) { + i = 0; + } else { + pathComponents = path.split(QLatin1Char('/')); + i = 1; + } - static int counter = 0; - if ((++counter % 20) == 0) - cleanupDeletedNodes(rootNode); + huntAndUnregister(pathComponents, i, mode, node); } void QDBusConnectionPrivate::connectRelay(const QString &service, diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 6836035e59..dfdc3fdc2d 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -186,31 +186,32 @@ struct _qt_BuiltInFormatStruct { _qt_BuiltInFormatType type; const char *extension; + const char *mimeType; }; static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = { #ifndef QT_NO_IMAGEFORMAT_PNG - {_qt_PngFormat, "png"}, + {_qt_PngFormat, "png", "image/png"}, #endif #ifndef QT_NO_IMAGEFORMAT_JPEG - {_qt_JpgFormat, "jpg"}, + {_qt_JpgFormat, "jpg", "image/jpeg"}, #endif #ifdef QT_BUILTIN_GIF_READER - {_qt_GifFormat, "gif"}, + {_qt_GifFormat, "gif", "image/gif"}, #endif - {_qt_BmpFormat, "bmp"}, + {_qt_BmpFormat, "bmp", "image/bmp"}, #ifndef QT_NO_IMAGEFORMAT_PPM - {_qt_PpmFormat, "ppm"}, - {_qt_PgmFormat, "pgm"}, - {_qt_PbmFormat, "pbm"}, + {_qt_PpmFormat, "ppm", "image/x-portable-pixmap"}, + {_qt_PgmFormat, "pgm", "image/x-portable-graymap"}, + {_qt_PbmFormat, "pbm", "image/x-portable-bitmap"}, #endif #ifndef QT_NO_IMAGEFORMAT_XBM - {_qt_XbmFormat, "xbm"}, + {_qt_XbmFormat, "xbm", "image/x-xbitmap"}, #endif #ifndef QT_NO_IMAGEFORMAT_XPM - {_qt_XpmFormat, "xpm"}, + {_qt_XpmFormat, "xpm", "image/x-xpixmap"}, #endif - {_qt_NoFormat, ""} + {_qt_NoFormat, "", ""} }; static QImageIOHandler *createReadHandlerHelper(QIODevice *device, @@ -1434,6 +1435,10 @@ QByteArray QImageReader::imageFormat(QIODevice *device) void supportedImageHandlerFormats(QFactoryLoader *loader, QImageIOPlugin::Capability cap, QSet<QByteArray> *result); + +void supportedImageHandlerMimeTypes(QFactoryLoader *loader, + QImageIOPlugin::Capability cap, + QSet<QByteArray> *result); #endif /*! @@ -1442,18 +1447,17 @@ void supportedImageHandlerFormats(QFactoryLoader *loader, By default, Qt can read the following formats: \table - \header \li Format \li Description - \row \li BMP \li Windows Bitmap - \row \li GIF \li Graphic Interchange Format (optional) - \row \li JPG \li Joint Photographic Experts Group - \row \li JPEG \li Joint Photographic Experts Group - \row \li PNG \li Portable Network Graphics - \row \li PBM \li Portable Bitmap - \row \li PGM \li Portable Graymap - \row \li PPM \li Portable Pixmap - \row \li XBM \li X11 Bitmap - \row \li XPM \li X11 Pixmap - \row \li SVG \li Scalable Vector Graphics + \header \li Format \li MIME type \li Description + \row \li BMP \li image/bmp \li Windows Bitmap + \row \li GIF \li image/gif \li Graphic Interchange Format (optional) + \row \li JPG \li image/jpeg \li Joint Photographic Experts Group + \row \li PNG \li image/png \li Portable Network Graphics + \row \li PBM \li image/x-portable-bitmap \li Portable Bitmap + \row \li PGM \li image/x-portable-graymap \li Portable Graymap + \row \li PPM \li image/x-portable-pixmap \li Portable Pixmap + \row \li XBM \li image/x-xbitmap \li X11 Bitmap + \row \li XPM \li image/x-xpixmap \li X11 Pixmap + \row \li SVG \li image/svg+xml \li Scalable Vector Graphics \endtable Reading and writing SVG files is supported through Qt's @@ -1484,4 +1488,31 @@ QList<QByteArray> QImageReader::supportedImageFormats() return sortedFormats; } +/*! + Returns the list of MIME types supported by QImageReader. + + Note that the QApplication instance must be created before this function is + called. + + \sa supportedImageFormats(), QImageWriter::supportedMimeTypes() +*/ + +QList<QByteArray> QImageReader::supportedMimeTypes() +{ + QSet<QByteArray> mimeTypes; + for (int i = 0; i < _qt_NumFormats; ++i) + mimeTypes << _qt_BuiltInFormats[i].mimeType; + +#ifndef QT_NO_LIBRARY + supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanRead, &mimeTypes); +#endif // QT_NO_LIBRARY + + QList<QByteArray> sortedMimeTypes; + for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it) + sortedMimeTypes << *it; + + qSort(sortedMimeTypes); + return sortedMimeTypes; +} + QT_END_NAMESPACE diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h index 11c925b142..a989ded0db 100644 --- a/src/gui/image/qimagereader.h +++ b/src/gui/image/qimagereader.h @@ -133,6 +133,7 @@ public: static QByteArray imageFormat(const QString &fileName); static QByteArray imageFormat(QIODevice *device); static QList<QByteArray> supportedImageFormats(); + static QList<QByteArray> supportedMimeTypes(); private: Q_DISABLE_COPY(QImageReader) diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index 3270a5ca01..67b21e372e 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -100,6 +100,7 @@ #include <qfile.h> #include <qfileinfo.h> #include <qimageiohandler.h> +#include <qjsonarray.h> #include <qset.h> #include <qvariant.h> @@ -677,6 +678,26 @@ void supportedImageHandlerFormats(QFactoryLoader *loader, result->insert(key); } } + +void supportedImageHandlerMimeTypes(QFactoryLoader *loader, + QImageIOPlugin::Capability cap, + QSet<QByteArray> *result) +{ + QList<QJsonObject> metaDataList = loader->metaData(); + + const int pluginCount = metaDataList.size(); + for (int i = 0; i < pluginCount; ++i) { + const QJsonObject metaData = metaDataList.at(i).value(QStringLiteral("MetaData")).toObject(); + const QJsonArray keys = metaData.value(QStringLiteral("Keys")).toArray(); + const QJsonArray mimeTypes = metaData.value(QStringLiteral("MimeTypes")).toArray(); + QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i)); + const int keyCount = keys.size(); + for (int k = 0; k < keyCount; ++k) { + if (plugin && (plugin->capabilities(0, keys.at(k).toString().toLatin1()) & cap) != 0) + result->insert(mimeTypes.at(k).toString().toLatin1()); + } + } +} #endif // QT_NO_IMAGEFORMATPLUGIN /*! @@ -685,16 +706,15 @@ void supportedImageHandlerFormats(QFactoryLoader *loader, By default, Qt can write the following formats: \table - \header \li Format \li Description - \row \li BMP \li Windows Bitmap - \row \li JPG \li Joint Photographic Experts Group - \row \li JPEG \li Joint Photographic Experts Group - \row \li PNG \li Portable Network Graphics - \row \li PBM \li Portable Bitmap - \row \li PGM \li Portable Graymap - \row \li PPM \li Portable Pixmap - \row \li XBM \li X11 Bitmap - \row \li XPM \li X11 Pixmap + \header \li Format \li MIME type \li Description + \row \li BMP \li image/bmp \li Windows Bitmap + \row \li JPG \li image/jpeg \li Joint Photographic Experts Group + \row \li PNG \li image/png \li Portable Network Graphics + \row \li PBM \li image/x-portable-bitmap \li Portable Bitmap + \row \li PGM \li image/x-portable-graymap \li Portable Graymap + \row \li PPM \li image/x-portable-pixmap \li Portable Pixmap + \row \li XBM \li image/x-xbitmap \li X11 Bitmap + \row \li XPM \li image/x-xpixmap \li X11 Pixmap \endtable Reading and writing SVG files is supported through Qt's @@ -725,9 +745,6 @@ QList<QByteArray> QImageWriter::supportedImageFormats() #ifndef QT_NO_IMAGEFORMAT_JPEG formats << "jpg" << "jpeg"; #endif -#ifdef QT_BUILTIN_GIF_READER - formats << "gif"; -#endif #ifndef QT_NO_IMAGEFORMATPLUGIN supportedImageHandlerFormats(loader(), QImageIOPlugin::CanWrite, &formats); @@ -741,4 +758,46 @@ QList<QByteArray> QImageWriter::supportedImageFormats() return sortedFormats; } +/*! + Returns the list of MIME types supported by QImageWriter. + + Note that the QApplication instance must be created before this function is + called. + + \sa supportedImageFormats(), QImageReader::supportedMimeTypes() +*/ +QList<QByteArray> QImageWriter::supportedMimeTypes() +{ + QSet<QByteArray> mimeTypes; + mimeTypes << "image/bmp"; +#ifndef QT_NO_IMAGEFORMAT_PPM + mimeTypes << "image/x-portable-bitmap"; + mimeTypes << "image/x-portable-graymap"; + mimeTypes << "image/x-portable-pixmap"; +#endif +#ifndef QT_NO_IMAGEFORMAT_XBM + mimeTypes << "image/x-xbitmap"; +#endif +#ifndef QT_NO_IMAGEFORMAT_XPM + mimeTypes << "image/x-xpixmap"; +#endif +#ifndef QT_NO_IMAGEFORMAT_PNG + mimeTypes << "image/png"; +#endif +#ifndef QT_NO_IMAGEFORMAT_JPEG + mimeTypes << "image/jpeg"; +#endif + +#ifndef QT_NO_LIBRARY + supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanWrite, &mimeTypes); +#endif // QT_NO_LIBRARY + + QList<QByteArray> sortedMimeTypes; + for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it) + sortedMimeTypes << *it; + + qSort(sortedMimeTypes); + return sortedMimeTypes; +} + QT_END_NAMESPACE diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h index 7d05cd5236..7a93f00d8e 100644 --- a/src/gui/image/qimagewriter.h +++ b/src/gui/image/qimagewriter.h @@ -102,6 +102,7 @@ public: bool supportsOption(QImageIOHandler::ImageOption option) const; static QList<QByteArray> supportedImageFormats(); + static QList<QByteArray> supportedMimeTypes(); private: Q_DISABLE_COPY(QImageWriter) diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 8be462517c..7dfb743ae2 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -1736,9 +1736,9 @@ if ( raster->worker ) raster->worker->skip_spans = params->skip_spans; - // If raster object and raster buffer are allocated, but - // raster size isn't of the minimum size, indicate out of - // memory. + /* If raster object and raster buffer are allocated, but */ + /* raster size isn't of the minimum size, indicate out of */ + /* memory. */ if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE ) return ErrRaster_OutOfMemory; @@ -1866,8 +1866,8 @@ ( sizeof ( TCell ) * 8 ) ); } else if ( pool_base) - { // Case when there is a raster pool allocated, but it - // doesn't have the minimum size (and so memory will be reallocated) + { /* Case when there is a raster pool allocated, but it */ + /* doesn't have the minimum size (and so memory will be reallocated) */ rast->buffer = pool_base; rast->worker = NULL; rast->buffer_size = pool_size; diff --git a/src/plugins/imageformats/gif/gif.json b/src/plugins/imageformats/gif/gif.json index b599b40ffe..1d6cb126c4 100644 --- a/src/plugins/imageformats/gif/gif.json +++ b/src/plugins/imageformats/gif/gif.json @@ -1,3 +1,4 @@ { - "Keys": [ "gif" ] + "Keys": [ "gif" ], + "MimeTypes": [ "image/gif" ] } diff --git a/src/plugins/imageformats/ico/ico.json b/src/plugins/imageformats/ico/ico.json index d22cb739a1..bd46e07e54 100644 --- a/src/plugins/imageformats/ico/ico.json +++ b/src/plugins/imageformats/ico/ico.json @@ -1,3 +1,4 @@ { - "Keys": [ "ico" ] + "Keys": [ "ico" ], + "MimeTypes": [ "image/vnd.microsoft.icon" ] } diff --git a/src/plugins/imageformats/jpeg/jpeg.json b/src/plugins/imageformats/jpeg/jpeg.json index 132c642c05..5e26a97206 100644 --- a/src/plugins/imageformats/jpeg/jpeg.json +++ b/src/plugins/imageformats/jpeg/jpeg.json @@ -1,3 +1,4 @@ { - "Keys": [ "jpg", "jpeg" ] + "Keys": [ "jpg", "jpeg" ], + "MimeTypes": [ "image/jpeg", "image/jpeg" ] } diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 7992461032..d8bb72dd45 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -216,7 +216,7 @@ static QString strippedText(QString s) - (void)closePanel { *mCurrentSelection = QT_PREPEND_NAMESPACE(QCFString::toQString)([[mSavePanel URL] path]); - if ([mSavePanel respondsToSelector:@selector(closePanel:)]) + if ([mSavePanel respondsToSelector:@selector(close)]) [mSavePanel close]; if ([mSavePanel isSheet]) [NSApp endSheet: mSavePanel]; @@ -230,6 +230,7 @@ static QString strippedText(QString s) bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; + [self updateProperties]; [mOpenPanel setAllowedFileTypes:nil]; [mOpenPanel setDirectoryURL:selectable ? [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath())] : [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.path())]]; @@ -273,6 +274,7 @@ static QString strippedText(QString s) bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; + [self updateProperties]; [mSavePanel setDirectoryURL:selectable ? [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath())] : [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.path())]]; NSWindow *nsparent = static_cast<NSWindow *>(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent)); @@ -403,6 +405,9 @@ static QString strippedText(QString s) [mSavePanel setCanCreateDirectories:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::ReadOnly)))]; [mOpenPanel setAllowsMultipleSelection:(fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFiles))]; [mOpenPanel setResolvesAliases:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::DontResolveSymlinks)))]; + [mOpenPanel setTitle:QCFString::toNSString(mOptions->windowTitle())]; + [mSavePanel setTitle:QCFString::toNSString(mOptions->windowTitle())]; + [mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead? QStringList ext = [self acceptableExtensionsForSave]; const QString defaultSuffix = mOptions->defaultSuffix(); @@ -575,13 +580,16 @@ extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding void QCocoaFileDialogHelper::setDirectory(const QString &directory) { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); - [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory)]]; + if (delegate) + [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory)]]; } QString QCocoaFileDialogHelper::directory() const { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); - return QCFString::toQString([delegate->mSavePanel directory]); + if (delegate) + return QCFString::toQString([delegate->mSavePanel directory]); + return QString(); } void QCocoaFileDialogHelper::selectFile(const QString &filename) @@ -598,12 +606,16 @@ void QCocoaFileDialogHelper::selectFile(const QString &filename) QStringList QCocoaFileDialogHelper::selectedFiles() const { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); - return [delegate selectedFiles]; + if (delegate) + return [delegate selectedFiles]; + return QStringList(); } void QCocoaFileDialogHelper::setFilter() { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); + if (!delegate) + return; const SharedPointerFileDialogOptions &opts = options(); [delegate->mSavePanel setTitle:QCFString::toNSString(opts->windowTitle())]; if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept)) @@ -616,9 +628,13 @@ void QCocoaFileDialogHelper::setFilter() void QCocoaFileDialogHelper::selectNameFilter(const QString &filter) { + if (!options()) + return; const int index = options()->nameFilters().indexOf(filter); if (index != -1) { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); + if (!delegate) + return; [delegate->mPopUpButton selectItemAtIndex:index]; [delegate filterChanged:nil]; } @@ -627,7 +643,11 @@ void QCocoaFileDialogHelper::selectNameFilter(const QString &filter) QString QCocoaFileDialogHelper::selectedNameFilter() const { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); + if (!delegate) + return QString(); int index = [delegate->mPopUpButton indexOfSelectedItem]; + if (index >= options()->nameFilters().count()) + return QString(); return index != -1 ? options()->nameFilters().at(index) : QString(); } @@ -673,6 +693,8 @@ bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModalit { createNSOpenSavePanelDelegate(); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); + if (!delegate) + return false; if (windowModality == Qt::NonModal) [delegate showModelessPanel]; else if (windowModality == Qt::WindowModal && parent) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 3b5be0af0f..66c4deb366 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -114,6 +114,8 @@ public: bool setMouseGrabEnabled(bool grab); QMargins frameMargins() const; + void requestActivateWindow(); + WId winId() const; void setParent(const QPlatformWindow *window); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 551e51bfa9..a3d0bc6e54 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -656,6 +656,13 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) setOpacity(opacity); } +void QCocoaWindow::requestActivateWindow() +{ + NSWindow *window = [m_contentView window]; + [ window makeFirstResponder : m_contentView ]; + [ window makeKeyWindow ]; +} + NSWindow * QCocoaWindow::createNSWindow() { QCocoaAutoReleasePool pool; diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index b4b3379a82..8bccc2cf33 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -82,6 +82,7 @@ QT_END_NAMESPACE - (BOOL)isFlipped; - (BOOL)acceptsFirstResponder; +- (BOOL)becomeFirstResponder; - (void)handleMouseEvent:(NSEvent *)theEvent; - (void)mouseDown:(NSEvent *)theEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 715b0c367f..14c24beabf 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -331,8 +331,25 @@ static QTouchDevice *touchDevice = 0; return YES; } +- (BOOL)becomeFirstResponder +{ + QWindow *focusWindow = m_window; + + // For widgets we need to do a bit of trickery as the window + // to activate is the window of the top-level widget. + if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) { + while (focusWindow->parent()) { + focusWindow = focusWindow->parent(); + } + } + QWindowSystemInterface::handleWindowActivated(focusWindow); + return YES; +} + - (BOOL)acceptsFirstResponder { + if ((m_window->flags() & Qt::ToolTip) == Qt::ToolTip) + return NO; return YES; } diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 9e5f3aa1ac..9c48ba1575 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -151,7 +151,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - return new QEglFSContext(hooks->surfaceFormatFor(context->format()), 0 /*share*/, mDisplay); + return new QEglFSContext(hooks->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay); } QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index d187af46f4..4f9698b21b 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -394,6 +394,19 @@ QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) } /*! + \brief Return cached pixmap cursor or create new one. +*/ + +QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c) +{ + const qint64 cacheKey = c.pixmap().cacheKey(); + PixmapCursorCache::iterator it = m_pixmapCursorCache.find(cacheKey); + if (it == m_pixmapCursorCache.end()) + it = m_pixmapCursorCache.insert(cacheKey, QWindowsWindowCursor(c)); + return it.value(); +} + +/*! \brief Set a cursor on a window. This is called frequently as the mouse moves over widgets in the window @@ -413,7 +426,7 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) } const QWindowsWindowCursor wcursor = cursorIn->shape() == Qt::BitmapCursor ? - QWindowsWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape()); + pixmapWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape()); if (wcursor.handle()) { QWindowsWindow::baseWindowOf(window)->setCursor(wcursor); } else { diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 14cb0ffca2..1e818bc9b8 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -83,11 +83,14 @@ public: static QPoint mousePosition(); QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor); + QWindowsWindowCursor pixmapWindowCursor(const QCursor &c); private: typedef QHash<Qt::CursorShape, QWindowsWindowCursor> StandardCursorCache; + typedef QHash<qint64, QWindowsWindowCursor> PixmapCursorCache; StandardCursorCache m_standardCursorCache; + PixmapCursorCache m_pixmapCursorCache; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index e1f4f4b143..dd16ea1c6f 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -49,6 +49,7 @@ #include <qpa/qwindowsysteminterface.h> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> +#include <QtGui/QWindow> #include <QtCore/QDebug> #include <QtCore/QScopedArrayPointer> @@ -236,6 +237,9 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, platformWindow->setFlag(QWindowsWindow::AutoMouseCapture); if (QWindowsContext::verboseEvents) qDebug() << "Automatic mouse capture " << window; + // Implement "Click to focus" for native child windows. + if (!window->isTopLevel() && QGuiApplication::focusWindow() != window) + window->requestActivate(); } else if (platformWindow->hasMouseCapture() && platformWindow->testFlag(QWindowsWindow::AutoMouseCapture) && (msg.message == WM_LBUTTONUP || msg.message == WM_MBUTTONUP diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 4023981353..4442b3f00c 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -940,7 +940,9 @@ Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded } else { QString userName = tokens.first(); userName.remove(0, 1); -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) +#if defined(Q_OS_VXWORKS) + const QString homePath = QDir::homePath(); +#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) passwd pw; passwd *tmpPw; char buf[200]; diff --git a/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro b/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro new file mode 100644 index 0000000000..21cab8f67d --- /dev/null +++ b/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro @@ -0,0 +1,12 @@ +QT += testlib core-private + +QT -= gui + +TARGET = tst_qglobalstatic +CONFIG += console +CONFIG -= app_bundle +CONFIG += exceptions + +SOURCES += tst_qglobalstatic.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp new file mode 100644 index 0000000000..b9aa70fe80 --- /dev/null +++ b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QThread> +#include <QtTest/QtTest> + +class tst_QGlobalStatic : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void beforeInitialization(); + void api(); + void constVolatile(); + void exception(); + void threadStressTest(); + void afterDestruction(); +}; + +Q_GLOBAL_STATIC_WITH_ARGS(const int, constInt, (42)) +Q_GLOBAL_STATIC_WITH_ARGS(volatile int, volatileInt, (-47)) + +void otherFunction() +{ + // never called + constInt(); + volatileInt(); +} + +// do not initialize the following Q_GLOBAL_STATIC +Q_GLOBAL_STATIC(int, checkedBeforeInitialization) +void tst_QGlobalStatic::beforeInitialization() +{ + QVERIFY(!checkedBeforeInitialization.exists()); + QVERIFY(!checkedBeforeInitialization.isDestroyed()); +} + +struct Type { + int i; +}; + +Q_GLOBAL_STATIC(Type, checkedAfterInitialization) +void tst_QGlobalStatic::api() +{ + // check the API + QVERIFY((Type *)checkedAfterInitialization); + QVERIFY(checkedAfterInitialization()); + *checkedAfterInitialization = Type(); + *checkedAfterInitialization() = Type(); + + checkedAfterInitialization()->i = 47; + checkedAfterInitialization->i = 42; + QCOMPARE(checkedAfterInitialization()->i, 42); + checkedAfterInitialization()->i = 47; + QCOMPARE(checkedAfterInitialization->i, 47); + + QVERIFY(checkedAfterInitialization.exists()); + QVERIFY(!checkedAfterInitialization.isDestroyed()); +} + +void tst_QGlobalStatic::constVolatile() +{ + QCOMPARE(*constInt(), 42); + QCOMPARE((int)*volatileInt(), -47); + QCOMPARE(*constInt(), 42); + QCOMPARE((int)*volatileInt(), -47); +} + +struct ThrowingType +{ + static QBasicAtomicInt constructedCount; + static QBasicAtomicInt destructedCount; + ThrowingType(QBasicAtomicInt &throwControl) + { + constructedCount.ref(); + if (throwControl.fetchAndAddRelaxed(-1) != 0) + throw 0; + } + ~ThrowingType() { destructedCount.ref(); } +}; +QBasicAtomicInt ThrowingType::constructedCount = Q_BASIC_ATOMIC_INITIALIZER(0); +QBasicAtomicInt ThrowingType::destructedCount = Q_BASIC_ATOMIC_INITIALIZER(0); + +QBasicAtomicInt exceptionControlVar = Q_BASIC_ATOMIC_INITIALIZER(1); +Q_GLOBAL_STATIC_WITH_ARGS(ThrowingType, exceptionGS, (exceptionControlVar)) +void tst_QGlobalStatic::exception() +{ + if (exceptionControlVar.load() != 1) + QSKIP("This test cannot be run more than once"); + ThrowingType::constructedCount.store(0); + ThrowingType::destructedCount.store(0); + + bool exceptionCaught = false; + try { + exceptionGS(); + } catch (int) { + exceptionCaught = true; + } + QCOMPARE(ThrowingType::constructedCount.load(), 1); + QVERIFY(exceptionCaught); + + exceptionGS(); + QCOMPARE(ThrowingType::constructedCount.load(), 2); +} + +QBasicAtomicInt threadStressTestControlVar = Q_BASIC_ATOMIC_INITIALIZER(5); +Q_GLOBAL_STATIC_WITH_ARGS(ThrowingType, threadStressTestGS, (threadStressTestControlVar)) + + +void tst_QGlobalStatic::threadStressTest() +{ + class ThreadStressTestThread: public QThread + { + public: + QReadWriteLock *lock; + void run() + { + QReadLocker l(lock); + //usleep(qrand() * 200 / RAND_MAX); + // thundering herd + try { + threadStressTestGS(); + } catch (int) { + } + } + }; + + ThrowingType::constructedCount.store(0); + ThrowingType::destructedCount.store(0); + int expectedConstructionCount = threadStressTestControlVar.load() + 1; + if (expectedConstructionCount <= 0) + QSKIP("This test cannot be run more than once"); + + const int numThreads = 200; + ThreadStressTestThread threads[numThreads]; + QReadWriteLock lock; + lock.lockForWrite(); + for (int i = 0; i < numThreads; ++i) { + threads[i].lock = &lock; + threads[i].start(); + } + + // wait for all threads + // release the herd + lock.unlock(); + + for (int i = 0; i < numThreads; ++i) + threads[i].wait(); + + QCOMPARE(ThrowingType::constructedCount.loadAcquire(), expectedConstructionCount); + QCOMPARE(ThrowingType::destructedCount.loadAcquire(), 0); +} + +Q_GLOBAL_STATIC(int, checkedAfterDestruction) +void tst_QGlobalStatic::afterDestruction() +{ + // this test will not produce results now + // it will simply run some code on destruction (after the global statics have been deleted) + // if that fails, this will cause a crash + + // static destruction is LIFO: so we must add our exit-time code before the + // global static is used for the first time + static struct RunAtExit { + ~RunAtExit() { + int *ptr = checkedAfterDestruction(); + if (ptr) + qFatal("Global static is not null as was expected"); + } + } runAtExit; + (void) runAtExit; + + *checkedAfterDestruction = 42; +} + +QTEST_APPLESS_MAIN(tst_QGlobalStatic); + +#include "tst_qglobalstatic.moc" diff --git a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp index 9d3519680c..45f143b9fb 100644 --- a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp @@ -43,6 +43,10 @@ #include <QObject> #include <QProcessEnvironment> +#ifdef QT_NO_PROCESS +QTEST_NOOP_MAIN +#else + class tst_QProcessEnvironment: public QObject { Q_OBJECT @@ -318,3 +322,4 @@ void tst_QProcessEnvironment::putenv() QTEST_MAIN(tst_QProcessEnvironment) #include "tst_qprocessenvironment.moc" +#endif diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp index a6e1f73904..56c07f1590 100644 --- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp @@ -194,7 +194,7 @@ private slots: void pos(); void pos2(); void pos3LargeFile(); -#ifndef Q_OS_WINCE +#if !defined(Q_OS_WINCE) && !defined(QT_NO_PROCESS) void readStdin(); void readAllFromStdin(); void readLineFromStdin(); @@ -1386,8 +1386,8 @@ void tst_QTextStream::pos3LargeFile() } // ------------------------------------------------------------------------------ -#ifndef Q_OS_WINCE // Qt/CE has no stdin/out support for processes +#if !defined(Q_OS_WINCE) && !defined(QT_NO_PROCESS) void tst_QTextStream::readStdin() { QProcess stdinProcess; @@ -1409,10 +1409,8 @@ void tst_QTextStream::readStdin() QCOMPARE(b, 2); QCOMPARE(c, 3); } -#endif // ------------------------------------------------------------------------------ -#ifndef Q_OS_WINCE // Qt/CE has no stdin/out support for processes void tst_QTextStream::readAllFromStdin() { @@ -1430,10 +1428,8 @@ void tst_QTextStream::readAllFromStdin() QChar quoteChar('"'); QCOMPARE(stream.readAll(), QString::fromLatin1("%1hello world%2 \n").arg(quoteChar).arg(quoteChar)); } -#endif // ------------------------------------------------------------------------------ -#ifndef Q_OS_WINCE // Qt/CE has no stdin/out support for processes void tst_QTextStream::readLineFromStdin() { diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 865264c43a..a6d1d9f14d 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -144,6 +144,16 @@ private slots: void disconnectDoesNotLeakFunctor(); }; +struct QObjectCreatedOnShutdown +{ + QObjectCreatedOnShutdown() {} + ~QObjectCreatedOnShutdown() + { + QObject(); + } +}; +static QObjectCreatedOnShutdown s_qobjectCreatedOnShutdown; + class SenderObject : public QObject { Q_OBJECT diff --git a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp index daf8c31772..02f99b08d3 100644 --- a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp +++ b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp @@ -82,7 +82,7 @@ private slots: void removeWhileAttached(); #endif void emptyMemory(); -#ifndef Q_OS_WIN +#if !defined(Q_OS_WIN) && !defined(QT_NO_PROCESS) void readOnly(); #endif @@ -98,8 +98,10 @@ private slots: void simpleThreadedProducerConsumer(); // with processes +#ifndef QT_NO_PROCESS void simpleProcessProducerConsumer_data(); void simpleProcessProducerConsumer(); +#endif // extreme cases void useTooMuchMemory(); @@ -447,7 +449,7 @@ void tst_QSharedMemory::emptyMemory() by writing to data and causing a segfault. */ // This test opens a crash dialog on Windows. -#ifndef Q_OS_WIN +#if !defined(Q_OS_WIN) && !defined(QT_NO_PROCESS) void tst_QSharedMemory::readOnly() { rememberKey("readonly_segfault"); @@ -728,6 +730,7 @@ void tst_QSharedMemory::simpleThreadedProducerConsumer() } } +#ifndef QT_NO_PROCESS void tst_QSharedMemory::simpleProcessProducerConsumer_data() { QTest::addColumn<int>("processes"); @@ -785,6 +788,7 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() producer.waitForBytesWritten(); QVERIFY(producer.waitForFinished(5000)); } +#endif void tst_QSharedMemory::uniqueKey_data() { diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp index b10da3ecb7..d2b6848dab 100644 --- a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp +++ b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp @@ -66,6 +66,7 @@ private slots: void basicacquire(); void complexacquire(); +#ifndef QT_NO_PROCESS void basicProcesses(); void processes_data(); @@ -75,6 +76,7 @@ private slots: void undo(); #endif void initialValue(); +#endif // QT_NO_PROCESS private: QString helperBinary(); @@ -154,6 +156,7 @@ void tst_QSystemSemaphore::complexacquire() QCOMPARE(sem.errorString(), QString()); } +#ifndef QT_NO_PROCESS void tst_QSystemSemaphore::basicProcesses() { QSystemSemaphore sem("store", 0, QSystemSemaphore::Create); @@ -261,6 +264,7 @@ void tst_QSystemSemaphore::initialValue() release.waitForFinished(HELPERWAITTIME); QVERIFY(acquire.state()== QProcess::NotRunning); } +#endif QString tst_QSystemSemaphore::helperBinary() { diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp index 224c992def..197d56359f 100644 --- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp @@ -73,7 +73,9 @@ private slots: void versions(); void threadUniqueness(); +#ifndef QT_NO_PROCESS void processUniqueness(); +#endif void hash(); @@ -319,6 +321,7 @@ void tst_QUuid::threadUniqueness() qDeleteAll(threads); } +#ifndef QT_NO_PROCESS void tst_QUuid::processUniqueness() { QProcess process; @@ -346,6 +349,7 @@ void tst_QUuid::processUniqueness() // They should be *different*! QVERIFY(processOneOutput != processTwoOutput); } +#endif void tst_QUuid::hash() { diff --git a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp index 29dbf2e31f..2072034f5f 100644 --- a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp +++ b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp @@ -71,7 +71,9 @@ private slots: void autoDelete(); void adoptedThreads(); void ensureCleanupOrder(); +#ifndef QT_NO_PROCESS void crashOnExit(); +#endif void leakInDestructor(); void resetInDestructor(); void valueBased(); @@ -305,6 +307,7 @@ void tst_QThreadStorage::ensureCleanupOrder() QVERIFY(First::order < Second::order); } +#ifndef QT_NO_PROCESS static inline bool runCrashOnExit(const QString &binary, QString *errorMessage) { const int timeout = 60000; @@ -332,6 +335,7 @@ void tst_QThreadStorage::crashOnExit() QVERIFY2(runCrashOnExit(m_crashOnExit, &errorMessage), qPrintable(errorMessage)); } +#endif // S stands for thread Safe. class SPointer diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index acdd2a9b64..fcd763f60f 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -238,7 +238,7 @@ private slots: #ifdef QT_USE_ICU void toUpperLower_icu(); #endif -#if defined(QT_UNICODE_LITERAL) && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU)) +#if !defined(QT_NO_UNICODE_LITERAL) && defined(Q_COMPILER_LAMBDA) void literals(); #endif void eightBitLiterals_data(); @@ -5437,7 +5437,7 @@ void tst_QString::toUpperLower_icu() } #endif -#if defined(QT_UNICODE_LITERAL) && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU)) +#if !defined(QT_NO_UNICODE_LITERAL) && defined(Q_COMPILER_LAMBDA) // Only tested on c++0x compliant compiler or gcc void tst_QString::literals() { diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index ea5c4e7b2b..c87b3297ee 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -1200,6 +1200,19 @@ void tst_QDBusConnection::registerVirtualObject() QVERIFY(!con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0)); } + + { + // Register object, make sure no SubPath handling object can be registered on a parent path. + // (same as above, but deeper) + QObject objectAtSubPath; + QVERIFY(con.registerObject(childChildPath, &objectAtSubPath)); + QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&objectAtSubPath)); + + VirtualObject obj; + QVERIFY(!con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0)); + } + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0)); QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0)); QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(0)); diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 50176d2430..bd11089a82 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -94,6 +94,7 @@ private slots: void multiWordNamedColorXPM(); void supportedFormats(); + void supportedMimeTypes(); void readFromDevice_data(); void readFromDevice(); @@ -570,6 +571,26 @@ void tst_QImageReader::supportedFormats() QCOMPARE(formatSet.size(), formats.size()); } +void tst_QImageReader::supportedMimeTypes() +{ + QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes(); + QList<QByteArray> sortedMimeTypes = mimeTypes; + qSort(sortedMimeTypes); + + // check that the list is sorted + QCOMPARE(mimeTypes, sortedMimeTypes); + + QSet<QByteArray> mimeTypeSet; + foreach (QByteArray mimeType, mimeTypes) + mimeTypeSet << mimeType; + + // check the list as a minimum contains image/bmp + QVERIFY(mimeTypeSet.contains("image/bmp")); + + // check that the list does not contain duplicates + QCOMPARE(mimeTypeSet.size(), mimeTypes.size()); +} + void tst_QImageReader::setBackgroundColor_data() { QTest::addColumn<QString>("fileName"); diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index 3c36482d62..f1d0e227f6 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -81,6 +81,7 @@ private slots: void writeImage2_data(); void writeImage2(); void supportedFormats(); + void supportedMimeTypes(); void writeToInvalidDevice(); @@ -352,6 +353,26 @@ void tst_QImageWriter::supportedFormats() QCOMPARE(formatSet.size(), formats.size()); } +void tst_QImageWriter::supportedMimeTypes() +{ + QList<QByteArray> mimeTypes = QImageWriter::supportedMimeTypes(); + QList<QByteArray> sortedMimeTypes = mimeTypes; + qSort(sortedMimeTypes); + + // check that the list is sorted + QCOMPARE(mimeTypes, sortedMimeTypes); + + QSet<QByteArray> mimeTypeSet; + foreach (QByteArray mimeType, mimeTypes) + mimeTypeSet << mimeType; + + // check the list as a minimum contains image/bmp + QVERIFY(mimeTypeSet.contains("image/bmp")); + + // check that the list does not contain duplicates + QCOMPARE(mimeTypeSet.size(), mimeTypes.size()); +} + void tst_QImageWriter::writeToInvalidDevice() { QLatin1String fileName("/these/directories/do/not/exist/001.png"); diff --git a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp index 8522031406..529f45f001 100644 --- a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp +++ b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp @@ -75,7 +75,9 @@ private slots: void sessionClosing_data(); void sessionClosing(); +#ifndef QT_NO_PROCESS void outOfProcessSession(); +#endif void invalidSession(); void repeatedOpenClose_data(); @@ -901,6 +903,7 @@ QDebug operator<<(QDebug debug, const QList<QNetworkConfiguration> &list) // Note: outOfProcessSession requires that at least one configuration is // at Discovered -state. +#ifndef QT_NO_PROCESS void tst_QNetworkSession::outOfProcessSession() { updateConfigurations(); @@ -998,6 +1001,7 @@ void tst_QNetworkSession::outOfProcessSession() QSKIP("Lackey failed"); } } +#endif // A convenience / helper function for testcases. Return the first matching configuration. // Ignores configurations in other than 'discovered' -state. Returns invalid (QNetworkConfiguration()) diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp index fa758d0498..2932387bdb 100644 --- a/tests/auto/other/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/other/networkselftest/tst_networkselftest.cpp @@ -975,6 +975,7 @@ void tst_NetworkSelfTest::smbServer() QCOMPARE(ret, strlen(contents)); QVERIFY(memcmp(buf, contents, strlen(contents)) == 0); #else +#ifndef QT_NO_PROCESS // try to use Samba QString progname = "smbclient"; QProcess smbclient; @@ -1012,6 +1013,9 @@ void tst_NetworkSelfTest::smbServer() output = smbclient.readAll(); QCOMPARE(output.constData(), contents); qDebug() << "Test file is correct"; +#else + QSKIP( "No QProcess support", SkipAll); +#endif #endif } diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index ea4feae9db..9e055a3d0e 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -563,6 +563,9 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge && subdir != QLatin1String("cmptest") // QImage comparison requires QGuiApplication && subdir != QLatin1String("fetchbogus") && subdir != QLatin1String("xunit") +#ifdef Q_CC_MINGW + && subdir != QLatin1String("silent") // calls qFatal() +#endif && subdir != QLatin1String("benchlibcallgrind")) QVERIFY2(err.isEmpty(), err.constData()); @@ -570,8 +573,8 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge QString logger = loggers[n]; QList<QByteArray> res = splitLines(actualOutputs[n]); QList<QByteArray> exp = expectedResult(subdir, logger); -#ifdef Q_CC_MSVC - // MSVC formats double numbers differently +#if defined (Q_CC_MSVC) || defined(Q_CC_MINGW) + // MSVC, MinGW format double numbers differently if (n == 0 && subdir == QStringLiteral("float")) { for (int i = 0; i < exp.size(); ++i) { exp[i].replace("e-07", "e-007"); diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 7e1cc77172..52cd1051ba 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -2142,6 +2142,7 @@ void tst_QApplication::qtbug_12673() QVERIFY2(!path.isEmpty(), "Cannot locate modal helper application"); path += "modal"; +#ifndef QT_NO_PROCESS QProcess testProcess; QStringList arguments; testProcess.start(path, arguments); @@ -2149,6 +2150,9 @@ void tst_QApplication::qtbug_12673() qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, testProcess.errorString()))); QVERIFY(testProcess.waitForFinished(20000)); QCOMPARE(testProcess.exitStatus(), QProcess::NormalExit); +#else + QSKIP( "No QProcess support", SkipAll); +#endif } class NoQuitOnHideWidget : public QWidget @@ -2222,7 +2226,9 @@ void tst_QApplication::abortQuitOnShow() executed *after* the destruction of QApplication. */ Q_GLOBAL_STATIC(QLocale, tst_qapp_locale); +#ifndef QT_NO_PROCESS Q_GLOBAL_STATIC(QProcess, tst_qapp_process); +#endif Q_GLOBAL_STATIC(QFileSystemWatcher, tst_qapp_fileSystemWatcher); #ifndef QT_NO_SHAREDMEMORY Q_GLOBAL_STATIC(QSharedMemory, tst_qapp_sharedMemory); @@ -2243,7 +2249,9 @@ void tst_QApplication::globalStaticObjectDestruction() int argc = 1; QApplication app(argc, &argv0); QVERIFY(tst_qapp_locale()); +#ifndef QT_NO_PROCESS QVERIFY(tst_qapp_process()); +#endif QVERIFY(tst_qapp_fileSystemWatcher()); #ifndef QT_NO_SHAREDMEMORY QVERIFY(tst_qapp_sharedMemory()); diff --git a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp index 17716ff130..c8a12a9866 100644 --- a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp @@ -201,7 +201,9 @@ private slots: void deleteStack(); void checkSignals(); void addStackAndDie(); +#ifndef QT_NO_PROCESS void commandTextFormat(); +#endif }; tst_QUndoGroup::tst_QUndoGroup() @@ -605,6 +607,7 @@ void tst_QUndoGroup::addStackAndDie() delete stack; } +#ifndef QT_NO_PROCESS void tst_QUndoGroup::commandTextFormat() { QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); @@ -644,6 +647,7 @@ void tst_QUndoGroup::commandTextFormat() qApp->removeTranslator(&translator); } +#endif #else class tst_QUndoGroup : public QObject diff --git a/tests/auto/widgets/util/qundostack/tst_qundostack.cpp b/tests/auto/widgets/util/qundostack/tst_qundostack.cpp index 4d47ed4f58..9b48dc7798 100644 --- a/tests/auto/widgets/util/qundostack/tst_qundostack.cpp +++ b/tests/auto/widgets/util/qundostack/tst_qundostack.cpp @@ -247,7 +247,9 @@ private slots: void macroBeginEnd(); void compression(); void undoLimit(); +#ifndef QT_NO_PROCESS void commandTextFormat(); +#endif void separateUndoText(); }; @@ -2964,6 +2966,7 @@ void tst_QUndoStack::undoLimit() true); // redoChanged } +#ifndef QT_NO_PROCESS void tst_QUndoStack::commandTextFormat() { QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); @@ -3001,6 +3004,7 @@ void tst_QUndoStack::commandTextFormat() qApp->removeTranslator(&translator); } +#endif void tst_QUndoStack::separateUndoText() { diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index 86e9a70d0b..740f958e21 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -758,6 +758,11 @@ void tst_QDateTimeEdit::displayFormat() void tst_QDateTimeEdit::selectAndScrollWithKeys() { +#ifdef Q_OS_MAC + QSKIP("QTBUG-23674"); + return; +#endif + qApp->setActiveWindow(testWidget); testWidget->setDate(QDate(2004, 05, 11)); testWidget->setDisplayFormat("dd/MM/yyyy"); @@ -768,9 +773,6 @@ void tst_QDateTimeEdit::selectAndScrollWithKeys() QTest::keyClick(testWidget, Qt::Key_Home); #endif QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "QTBUG-23674", Abort); -#endif QCOMPARE(testWidget->lineEdit()->selectedText(), QString("1")); QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); |