summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/kernel.pri46
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp25
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp53
-rw-r--r--src/corelib/kernel/qabstractitemmodel.h4
-rw-r--r--src/corelib/kernel/qabstractitemmodel_p.h5
-rw-r--r--src/corelib/kernel/qcore_unix.cpp236
-rw-r--r--src/corelib/kernel/qcore_unix_p.h339
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp79
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp106
-rw-r--r--src/corelib/kernel/qcorecmdlineargs_p.h9
-rw-r--r--src/corelib/kernel/qcoreevent.cpp5
-rw-r--r--src/corelib/kernel/qcoreevent.h3
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp189
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h57
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp89
-rw-r--r--src/corelib/kernel/qfunctions_p.h2
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.cpp202
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.h153
-rw-r--r--src/corelib/kernel/qfunctions_wince.cpp12
-rw-r--r--src/corelib/kernel/qfunctions_wince.h6
-rw-r--r--src/corelib/kernel/qguard_p.h157
-rw-r--r--src/corelib/kernel/qmath.h4
-rw-r--r--src/corelib/kernel/qmetaobject.cpp132
-rw-r--r--src/corelib/kernel/qmetaobject.h4
-rw-r--r--src/corelib/kernel/qmetatype.cpp27
-rw-r--r--src/corelib/kernel/qmetatype.h14
-rw-r--r--src/corelib/kernel/qmimedata.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp174
-rw-r--r--src/corelib/kernel/qobject.h11
-rw-r--r--src/corelib/kernel/qobject_p.h45
-rw-r--r--src/corelib/kernel/qobjectdefs.h5
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp8
-rw-r--r--src/corelib/kernel/qsharedmemory_win.cpp19
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp6
-rw-r--r--src/corelib/kernel/qtimer.cpp5
-rw-r--r--src/corelib/kernel/qtranslator.cpp3
-rw-r--r--src/corelib/kernel/qvariant.cpp11
-rw-r--r--src/corelib/kernel/qvariant.h7
38 files changed, 1832 insertions, 422 deletions
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index f7d4208..124b2b3 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -32,7 +32,8 @@ HEADERS += \
kernel/qsharedmemory_p.h \
kernel/qsystemsemaphore.h \
kernel/qsystemsemaphore_p.h \
- kernel/qfunctions_p.h
+ kernel/qfunctions_p.h \
+ kernel/qguard_p.h
SOURCES += \
kernel/qabstracteventdispatcher.cpp \
@@ -54,7 +55,7 @@ SOURCES += \
kernel/qcoreglobaldata.cpp \
kernel/qsharedmemory.cpp \
kernel/qsystemsemaphore.cpp \
- kernel/qpointer.cpp
+ kernel/qpointer.cpp
win32 {
SOURCES += \
@@ -86,10 +87,14 @@ mac {
kernel/qcore_mac.cpp
}
-unix {
+unix:!symbian {
SOURCES += \
- kernel/qcrashhandler.cpp
+ kernel/qcore_unix.cpp \
+ kernel/qcrashhandler.cpp \
+ kernel/qsharedmemory_unix.cpp \
+ kernel/qsystemsemaphore_unix.cpp
HEADERS += \
+ kernel/qcore_unix_p.h \
kernel/qcrashhandler_p.h
contains(QT_CONFIG, glib) {
@@ -100,25 +105,34 @@ unix {
QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
LIBS +=$$QT_LIBS_GLIB
}
-
- symbian {
SOURCES += \
+ kernel/qeventdispatcher_unix.cpp
+ HEADERS += \
+ kernel/qeventdispatcher_unix_p.h
+
+ contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri)
+}
+
+symbian {
+ SOURCES += \
+ kernel/qcore_unix.cpp \
+ kernel/qcrashhandler.cpp \
kernel/qeventdispatcher_symbian.cpp \
kernel/qcore_symbian_p.cpp \
kernel/qsharedmemory_symbian.cpp \
kernel/qsystemsemaphore_symbian.cpp
- HEADERS += \
+
+ HEADERS += \
+ kernel/qcore_unix_p.h \
+ kernel/qcrashhandler_p.h \
kernel/qeventdispatcher_symbian_p.h \
kernel/qcore_symbian_p.h
- } else {
- SOURCES += \
- kernel/qeventdispatcher_unix.cpp \
- kernel/qsharedmemory_unix.cpp \
- kernel/qsystemsemaphore_unix.cpp
- HEADERS += \
- kernel/qeventdispatcher_unix_p.h
- }
+}
- contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri)
+vxworks {
+ SOURCES += \
+ kernel/qfunctions_vxworks.cpp
+ HEADERS += \
+ kernel/qfunctions_vxworks.h
}
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index a98d005..e2682f5 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -398,20 +398,23 @@ void QAbstractEventDispatcher::closingDown()
*/
/*!
- Sets the event filter \a filter. Returns a pointer to the filter
- function previously defined.
-
- The event filter is a function that receives all messages taken
- from the system event loop before the event is dispatched to the
- respective target. This includes messages that are not sent to Qt
+ Replaces the event filter function for this
+ QAbstractEventDispatcher with \a filter and returns the replaced
+ event filter function. Only the current event filter function is
+ called. If you want to use both filter functions, save the
+ replaced EventFilter in a place where yours can call it.
+
+ The event filter function set here is called for all messages
+ taken from the system event loop before the event is dispatched to
+ the respective target, including the messages not meant for Qt
objects.
- The function can return true to stop the event to be processed by
- Qt, or false to continue with the standard event processing.
+ The event filter function should return true if the message should
+ be filtered, (i.e. stopped). It should return false to allow
+ processing the message to continue.
- Only one filter can be defined, but the filter can use the return
- value to call the previously set event filter. By default, no
- filter is set (i.e. the function returns 0).
+ By default, no event filter function is set (i.e., this function
+ returns a null EventFilter the first time it is called).
*/
QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(EventFilter filter)
{
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 914f44f..bc95c60 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -467,6 +467,27 @@ QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
return qEmptyModel();
}
+namespace {
+ struct DefaultRoleNames : public QHash<int, QByteArray>
+ {
+ DefaultRoleNames() {
+ (*this)[Qt::DisplayRole] = "display";
+ (*this)[Qt::DecorationRole] = "decoration";
+ (*this)[Qt::EditRole] = "edit";
+ (*this)[Qt::ToolTipRole] = "toolTip";
+ (*this)[Qt::StatusTipRole] = "statusTip";
+ (*this)[Qt::WhatsThisRole] = "whatsThis";
+ }
+ };
+}
+
+Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames)
+
+const QHash<int,QByteArray> &QAbstractItemModelPrivate::defaultRoleNames()
+{
+ return *qDefaultRoleNames();
+}
+
/*!
\internal
return true if \a value contains a numerical type
@@ -1407,7 +1428,7 @@ QMap<int, QVariant> QAbstractItemModel::itemData(const QModelIndex &index) const
QMap<int, QVariant> roles;
for (int i = 0; i < Qt::UserRole; ++i) {
QVariant variantData = data(index, i);
- if (variantData.type() != QVariant::Invalid)
+ if (variantData.isValid())
roles.insert(i, variantData);
}
return roles;
@@ -1863,6 +1884,33 @@ QSize QAbstractItemModel::span(const QModelIndex &) const
}
/*!
+ Sets the model's role names to \a roleNames.
+
+ This function is provided to allow mapping of role identifiers to
+ role property names in Declarative UI. This function must be called
+ before the model is used. Modifying the role names after the model
+ has been set may result in undefined behaviour.
+
+ \sa roleNames()
+*/
+void QAbstractItemModel::setRoleNames(const QHash<int,QByteArray> &roleNames)
+{
+ Q_D(QAbstractItemModel);
+ d->roleNames = roleNames;
+}
+
+/*!
+ Returns the model's role names.
+
+ \sa setRoleNames()
+*/
+const QHash<int,QByteArray> &QAbstractItemModel::roleNames() const
+{
+ Q_D(const QAbstractItemModel);
+ return d->roleNames;
+}
+
+/*!
Called to let the model know that it should submit whatever it has cached
to the permanent storage. Typically used for row editing.
@@ -2278,7 +2326,8 @@ void QAbstractItemModel::endRemoveColumns()
\note The view to which the model is attached to will be reset as well.
When a model is reset it means that any previous data reported from the
- model is now invalid and has to be queried for again.
+ model is now invalid and has to be queried for again. This also means
+ that the current item and any selected items will become invalid.
When a model radically changes its data it can sometimes be easier to just
call this function rather than emit dataChanged() to inform other
diff --git a/src/corelib/kernel/qabstractitemmodel.h b/src/corelib/kernel/qabstractitemmodel.h
index 90d04cd..2503393 100644
--- a/src/corelib/kernel/qabstractitemmodel.h
+++ b/src/corelib/kernel/qabstractitemmodel.h
@@ -220,6 +220,8 @@ public:
Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
virtual QSize span(const QModelIndex &index) const;
+ const QHash<int,QByteArray> &roleNames() const;
+
#ifdef Q_NO_USING_KEYWORD
inline QObject *parent() const { return QObject::parent(); }
#else
@@ -282,6 +284,8 @@ protected:
void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to);
QModelIndexList persistentIndexList() const;
+ void setRoleNames(const QHash<int,QByteArray> &roleNames);
+
private:
Q_DECLARE_SCOPED_PRIVATE(QAbstractItemModel)
Q_DISABLE_COPY(QAbstractItemModel)
diff --git a/src/corelib/kernel/qabstractitemmodel_p.h b/src/corelib/kernel/qabstractitemmodel_p.h
index c047f95..6a29723 100644
--- a/src/corelib/kernel/qabstractitemmodel_p.h
+++ b/src/corelib/kernel/qabstractitemmodel_p.h
@@ -78,7 +78,7 @@ class Q_CORE_EXPORT QAbstractItemModelPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QAbstractItemModel)
public:
- QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1) {}
+ QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1), roleNames(defaultRoleNames()) {}
void removePersistentIndexData(QPersistentModelIndexData *data);
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void rowsInserted(const QModelIndex &parent, int first, int last);
@@ -144,6 +144,9 @@ public:
} persistent;
Qt::DropActions supportedDragActions;
+
+ QHash<int,QByteArray> roleNames;
+ static const QHash<int,QByteArray> &defaultRoleNames();
};
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
new file mode 100644
index 0000000..b57d385
--- /dev/null
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -0,0 +1,236 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcore_unix_p.h"
+
+#ifndef Q_OS_VXWORKS
+# include <sys/select.h>
+# include <sys/time.h>
+#else
+# include <selectLib.h>
+#endif
+
+#include <stdlib.h>
+
+#ifdef Q_OS_MAC
+#include <mach/mach_time.h>
+#endif
+
+#if !defined(QT_NO_CLOCK_MONOTONIC)
+# if defined(QT_BOOTSTRAPPED)
+# define QT_NO_CLOCK_MONOTONIC
+# endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+bool qt_gettime_is_monotonic()
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 > 0) || defined(Q_OS_MAC)
+ return true;
+#else
+ static int returnValue = 0;
+
+ if (returnValue == 0) {
+# if (_POSIX_MONOTONIC_CLOCK-0 < 0)
+ returnValue = -1;
+# elif (_POSIX_MONOTONIC_CLOCK == 0)
+ // detect if the system support monotonic timers
+ long x = sysconf(_SC_MONOTONIC_CLOCK);
+ returnValue = (x >= 200112L) ? 1 : -1;
+# endif
+ }
+
+ return returnValue != -1;
+#endif
+}
+
+timeval qt_gettime()
+{
+ timeval tv;
+#if defined(Q_OS_MAC)
+ static mach_timebase_info_data_t info = {0,0};
+ if (info.denom == 0)
+ mach_timebase_info(&info);
+
+ uint64_t cpu_time = mach_absolute_time();
+ uint64_t nsecs = cpu_time * (info.numer / info.denom);
+ tv.tv_sec = nsecs / 1000000000ull;
+ tv.tv_usec = (nsecs / 1000) - (tv.tv_sec * 1000000);
+ return tv;
+#elif (_POSIX_MONOTONIC_CLOCK-0 > 0)
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000;
+ return tv;
+#else
+# if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED)
+ if (qt_gettime_is_monotonic()) {
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000;
+ return tv;
+ }
+# endif
+ // use gettimeofday
+ ::gettimeofday(&tv, 0);
+ return tv;
+#endif
+}
+
+static inline bool time_update(struct timeval *tv, const struct timeval &start,
+ const struct timeval &timeout)
+{
+ if (!qt_gettime_is_monotonic()) {
+ // we cannot recalculate the timeout without a monotonic clock as the time may have changed
+ return false;
+ }
+
+ // clock source is monotonic, so we can recalculate how much timeout is left
+ struct timeval now = qt_gettime();
+ *tv = timeout + start - now;
+ return true;
+}
+
+int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
+ const struct timeval *orig_timeout)
+{
+ if (!orig_timeout) {
+ // no timeout -> block forever
+ register int ret;
+ EINTR_LOOP(ret, select(nfds, fdread, fdwrite, fdexcept, 0));
+ return ret;
+ }
+
+ timeval start = qt_gettime();
+ timeval timeout = *orig_timeout;
+
+ // loop and recalculate the timeout as needed
+ int ret;
+ forever {
+ ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeout);
+ if (ret != -1 || errno != EINTR)
+ return ret;
+
+ // recalculate the timeout
+ if (!time_update(&timeout, start, *orig_timeout)) {
+ // clock reset, fake timeout error
+ return 0;
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+#ifdef Q_OS_LINUX
+// Don't wait for libc to supply the calls we need
+// Make syscalls directly
+
+# if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204
+// glibc 2.4 has syscall(...)
+# include <sys/syscall.h>
+# include <asm/unistd.h>
+# else
+// no syscall(...)
+static inline int syscall(...) { errno = ENOSYS; return -1;}
+# endif
+
+# ifndef __NR_dup3
+# if defined(__i386__)
+# define __NR_dup3 330
+# define __NR_pipe2 331
+# elif defined(__x86_64__)
+# define __NR_dup3 292
+# define __NR_pipe2 293
+# elif defined(__ia64__)
+# define __NR_dup3 1316
+# define __NR_pipe2 1317
+# else
+// set the syscalls to absurd numbers so that they'll cause ENOSYS errors
+# warning "Please port the pipe2/dup3 code to this platform"
+# define __NR_dup3 -1
+# define __NR_pipe2 -1
+# endif
+# endif
+
+# if !defined(__NR_socketcall) && !defined(__NR_accept4)
+# if defined(__x86_64__)
+# define __NR_accept4 288
+# elif defined(__ia64__)
+// not assigned yet to IA-64
+# define __NR_accept4 -1
+# else
+// set the syscalls to absurd numbers so that they'll cause ENOSYS errors
+# warning "Please port the accept4 code to this platform"
+# define __NR_accept4 -1
+# endif
+# endif
+
+QT_BEGIN_NAMESPACE
+namespace QtLibcSupplement {
+ int pipe2(int pipes[], int flags)
+ {
+ return syscall(__NR_pipe2, pipes, flags);
+ }
+
+ int dup3(int oldfd, int newfd, int flags)
+ {
+ return syscall(__NR_dup3, oldfd, newfd, flags);
+ }
+
+ int accept4(int s, sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags)
+ {
+# if defined(__NR_socketcall)
+ // This platform uses socketcall() instead of raw syscalls
+ // the SYS_ACCEPT4 number is cross-platform: 18
+ return syscall(__NR_socketcall, 18, &s);
+# else
+ return syscall(__NR_accept4, s, addr, addrlen, flags);
+# endif
+
+ Q_UNUSED(addr); Q_UNUSED(addrlen); Q_UNUSED(flags); // they're actually used
+ }
+}
+QT_END_NAMESPACE
+#endif // Q_OS_LINUX
+
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
new file mode 100644
index 0000000..e301c92
--- /dev/null
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -0,0 +1,339 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCORE_UNIX_P_H
+#define QCORE_UNIX_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt code on Unix. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qplatformdefs.h"
+
+#ifndef Q_OS_UNIX
+# error "qcore_unix_p.h included on a non-Unix system"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <sys/wait.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#if defined(Q_OS_VXWORKS)
+# include <ioLib.h>
+#endif
+
+struct sockaddr;
+
+#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204
+// Linux supports thread-safe FD_CLOEXEC
+# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1
+
+// add defines for the consts for Linux
+# ifndef O_CLOEXEC
+# define O_CLOEXEC 02000000
+# endif
+# ifndef FD_DUPFD_CLOEXEC
+# define F_DUPFD_CLOEXEC 1030
+# endif
+# ifndef SOCK_CLOEXEC
+# define SOCK_CLOEXEC O_CLOEXEC
+# endif
+# ifndef SOCK_NONBLOCK
+# define SOCK_NONBLOCK O_NONBLOCK
+# endif
+# ifndef MSG_CMSG_CLOEXEC
+# define MSG_CMSG_CLOEXEC 0x40000000
+# endif
+
+QT_BEGIN_NAMESPACE
+namespace QtLibcSupplement {
+ Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags);
+ Q_CORE_EXPORT int dup3(int oldfd, int newfd, int flags);
+ Q_CORE_EXPORT int pipe2(int pipes[], int flags);
+}
+QT_END_NAMESPACE
+using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement);
+
+#else
+# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0
+#endif
+
+#define EINTR_LOOP(var, cmd) \
+ do { \
+ var = cmd; \
+ } while (var == -1 && errno == EINTR)
+
+QT_BEGIN_NAMESPACE
+
+// Internal operator functions for timevals
+inline timeval &normalizedTimeval(timeval &t)
+{
+ while (t.tv_usec > 1000000l) {
+ ++t.tv_sec;
+ t.tv_usec -= 1000000l;
+ }
+ while (t.tv_usec < 0l) {
+ --t.tv_sec;
+ t.tv_usec += 1000000l;
+ }
+ return t;
+}
+inline bool operator<(const timeval &t1, const timeval &t2)
+{ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); }
+inline bool operator==(const timeval &t1, const timeval &t2)
+{ return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; }
+inline timeval &operator+=(timeval &t1, const timeval &t2)
+{
+ t1.tv_sec += t2.tv_sec;
+ t1.tv_usec += t2.tv_usec;
+ return normalizedTimeval(t1);
+}
+inline timeval operator+(const timeval &t1, const timeval &t2)
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec + t2.tv_sec;
+ tmp.tv_usec = t1.tv_usec + t2.tv_usec;
+ return normalizedTimeval(tmp);
+}
+inline timeval operator-(const timeval &t1, const timeval &t2)
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1);
+ tmp.tv_usec = t1.tv_usec - (t2.tv_usec + 1000000);
+ return normalizedTimeval(tmp);
+}
+inline timeval operator*(const timeval &t1, int mul)
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec * mul;
+ tmp.tv_usec = t1.tv_usec * mul;
+ return normalizedTimeval(tmp);
+}
+
+// don't call QT_OPEN or ::open
+// call qt_safe_open
+static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777)
+{
+#ifdef O_CLOEXEC
+ flags |= O_CLOEXEC;
+#endif
+ register int fd;
+ EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode));
+
+ // unknown flags are ignored, so we have no way of verifying if
+ // O_CLOEXEC was accepted
+ if (fd != -1)
+ ::fcntl(fd, F_SETFD, FD_CLOEXEC);
+ return fd;
+}
+#undef QT_OPEN
+#define QT_OPEN qt_safe_open
+
+#ifndef Q_OS_VXWORKS // no POSIX pipes in VxWorks
+// don't call ::pipe
+// call qt_safe_pipe
+static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
+{
+#ifdef O_CLOEXEC
+ Q_ASSERT((flags & ~(O_CLOEXEC | O_NONBLOCK)) == 0);
+#else
+ Q_ASSERT((flags & ~O_NONBLOCK) == 0);
+#endif
+
+ register int ret;
+#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC
+ // use pipe2
+ flags |= O_CLOEXEC;
+ ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR
+ if (ret == 0 || errno != ENOSYS)
+ return ret;
+#endif
+
+ ret = ::pipe(pipefd);
+ if (ret == -1)
+ return -1;
+
+ ::fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
+ ::fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
+
+ // set non-block too?
+ if (flags & O_NONBLOCK) {
+ ::fcntl(pipefd[0], F_SETFL, ::fcntl(pipefd[0], F_GETFL) | O_NONBLOCK);
+ ::fcntl(pipefd[1], F_SETFL, ::fcntl(pipefd[1], F_GETFL) | O_NONBLOCK);
+ }
+
+ return 0;
+}
+
+#endif // Q_OS_VXWORKS
+
+// don't call dup or fcntl(F_DUPFD)
+static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC)
+{
+ Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
+
+ register int ret;
+#ifdef F_DUPFD_CLOEXEC
+ // use this fcntl
+ if (flags & FD_CLOEXEC) {
+ ret = ::fcntl(oldfd, F_DUPFD_CLOEXEC, atleast);
+ if (ret != -1 || errno != EINVAL)
+ return ret;
+ }
+#endif
+
+ // use F_DUPFD
+ ret = ::fcntl(oldfd, F_DUPFD, atleast);
+
+ if (flags && ret != -1)
+ ::fcntl(ret, F_SETFD, flags);
+ return ret;
+}
+
+// don't call dup2
+// call qt_safe_dup2
+static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC)
+{
+ Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
+
+ register int ret;
+#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC
+ // use dup3
+ if (flags & FD_CLOEXEC) {
+ EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC));
+ if (ret == 0 || errno != ENOSYS)
+ return ret;
+ }
+#endif
+ EINTR_LOOP(ret, ::dup2(oldfd, newfd));
+ if (ret == -1)
+ return -1;
+
+ if (flags)
+ ::fcntl(newfd, F_SETFD, flags);
+ return 0;
+}
+
+static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
+{
+ qint64 ret = 0;
+ EINTR_LOOP(ret, QT_READ(fd, data, maxlen));
+ return ret;
+}
+#undef QT_READ
+#define QT_READ qt_safe_read
+
+static inline qint64 qt_safe_write(int fd, const void *data, qint64 len)
+{
+ qint64 ret = 0;
+ EINTR_LOOP(ret, QT_WRITE(fd, data, len));
+ return ret;
+}
+#undef QT_WRITE
+#define QT_WRITE qt_safe_write
+
+static inline int qt_safe_close(int fd)
+{
+ register int ret;
+ EINTR_LOOP(ret, QT_CLOSE(fd));
+ return ret;
+}
+#undef QT_CLOSE
+#define QT_CLOSE qt_safe_close
+
+// Open C does not (yet?) implement these on Symbian OS and VxWorks doesn't have processes
+#if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_VXWORKS)
+static inline int qt_safe_execve(const char *filename, char *const argv[],
+ char *const envp[])
+{
+ register int ret;
+ EINTR_LOOP(ret, ::execve(filename, argv, envp));
+ return ret;
+}
+
+static inline int qt_safe_execv(const char *path, char *const argv[])
+{
+ register int ret;
+ EINTR_LOOP(ret, ::execv(path, argv));
+ return ret;
+}
+
+static inline int qt_safe_execvp(const char *file, char *const argv[])
+{
+ register int ret;
+ EINTR_LOOP(ret, ::execvp(file, argv));
+ return ret;
+}
+#endif
+
+#ifndef Q_OS_VXWORKS // no processes on VxWorks
+static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
+{
+ register int ret;
+ EINTR_LOOP(ret, ::waitpid(pid, status, options));
+ return ret;
+}
+
+#endif // Q_OS_VXWORKS
+
+#if !defined(_POSIX_MONOTONIC_CLOCK)
+# define _POSIX_MONOTONIC_CLOCK -1
+#endif
+
+bool qt_gettime_is_monotonic();
+timeval qt_gettime();
+Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
+ const struct timeval *tv);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 90d8f2f..4a1da35 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -61,6 +61,7 @@
#include <private/qthread_p.h>
#include <qlibraryinfo.h>
#include <private/qfactoryloader_p.h>
+#include <private/qfunctions_p.h>
#ifdef Q_OS_SYMBIAN
# include <exception>
@@ -88,6 +89,10 @@
# include <locale.h>
#endif
+#ifdef Q_OS_VXWORKS
+# include <taskLib.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QLockedMutexUnlocker
@@ -1733,6 +1738,12 @@ QString QCoreApplication::translate(const char *context, const char *sourceText,
return result;
}
+// Declared in qglobal.h
+QString qtTrId(const char *id, int n)
+{
+ return QCoreApplication::translate(0, id, 0, QCoreApplication::UnicodeUTF8, n);
+}
+
bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
{
return QCoreApplication::self
@@ -1828,21 +1839,8 @@ QString QCoreApplication::applicationFilePath()
if (!d->cachedApplicationFilePath.isNull())
return d->cachedApplicationFilePath;
-#if defined( Q_WS_WIN )
- QFileInfo filePath;
- QT_WA({
- wchar_t module_name[MAX_PATH+1];
- GetModuleFileNameW(0, module_name, MAX_PATH);
- module_name[MAX_PATH] = 0;
- filePath = QString::fromUtf16((ushort *)module_name);
- }, {
- char module_name[MAX_PATH+1];
- GetModuleFileNameA(0, module_name, MAX_PATH);
- module_name[MAX_PATH] = 0;
- filePath = QString::fromLocal8Bit(module_name);
- });
-
- d->cachedApplicationFilePath = filePath.filePath();
+#if defined(Q_WS_WIN)
+ d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
return d->cachedApplicationFilePath;
#elif defined(Q_WS_MAC)
QString qAppFileName_str = qAppFileName();
@@ -1928,8 +1926,9 @@ qint64 QCoreApplication::applicationPid()
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
return GetCurrentProcessId();
+#elif defined(Q_OS_VXWORKS)
+ return (pid_t) taskIdCurrent;
#else
- // UNIX
return getpid();
#endif
}
@@ -2002,13 +2001,13 @@ QStringList QCoreApplication::arguments()
return list;
}
#ifdef Q_OS_WIN
- QString cmdline = QT_WA_INLINE(QString::fromUtf16((unsigned short *)GetCommandLineW()), QString::fromLocal8Bit(GetCommandLineA()));
+ QString cmdline = QString::fromWCharArray(GetCommandLine());
#if defined(Q_OS_WINCE)
wchar_t tempFilename[MAX_PATH+1];
- if (GetModuleFileNameW(0, tempFilename, MAX_PATH)) {
+ if (GetModuleFileName(0, tempFilename, MAX_PATH)) {
tempFilename[MAX_PATH] = 0;
- cmdline.prepend(QLatin1Char('\"') + QString::fromUtf16((unsigned short *)tempFilename) + QLatin1String("\" "));
+ cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" "));
}
#endif // Q_OS_WINCE
@@ -2315,21 +2314,37 @@ void QCoreApplication::removeLibraryPath(const QString &path)
/*!
\fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
- Sets the event filter \a filter. Returns a pointer to the filter
- function previously defined.
-
- The event filter is a function that is called for every message
- received in all threads. This does \e not include messages to
+ Replaces the event filter function for the QCoreApplication with
+ \a filter and returns the pointer to the replaced event filter
+ function. Only the current event filter function is called. If you
+ want to use both filter functions, save the replaced EventFilter
+ in a place where yours can call it.
+
+ The event filter function set here is called for all messages
+ received by all threads meant for all Qt objects. It is \e not
+ called for messages that are not meant for Qt objects.
+
+ The event filter function should return true if the message should
+ be filtered, (i.e. stopped). It should return false to allow
+ processing the message to continue.
+
+ By default, no event filter function is set (i.e., this function
+ returns a null EventFilter the first time it is called).
+
+ \note The filter function set here receives native messages,
+ i.e. MSG or XEvent structs, that are going to Qt objects. It is
+ called by QCoreApplication::filterEvent(). If the filter function
+ returns false to indicate the message should be processed further,
+ the native message can then be translated into a QEvent and
+ handled by the standard Qt \l{QEvent} {event} filering, e.g.
+ QObject::installEventFilter().
+
+ \note The filter function set here is different form the filter
+ function set via QAbstractEventDispatcher::setEventFilter(), which
+ gets all messages received by its thread, even messages meant for
objects that are not handled by Qt.
- The function can return true to stop the event to be processed by
- Qt, or false to continue with the standard event processing.
-
- Only one filter can be defined, but the filter can use the return
- value to call the previously set event filter. By default, no
- filter is set (i.e., the function returns 0).
-
- \sa installEventFilter()
+ \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter()
*/
QCoreApplication::EventFilter
QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 7a35340..bf5716a 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -45,14 +45,15 @@
#include "qt_windows.h"
#include "qvector.h"
#include "qmutex.h"
+#include "qfileinfo.h"
#include "qcorecmdlineargs_p.h"
#include <private/qthread_p.h>
#include <ctype.h>
QT_BEGIN_NAMESPACE
-char appFileName[MAX_PATH+1]; // application file name
-char theAppName[MAX_PATH+1]; // application name
+char appFileName[MAX_PATH]; // application file name
+char theAppName[MAX_PATH]; // application name
HINSTANCE appInst = 0; // handle to app instance
HINSTANCE appPrevInst = 0; // handle to prev app instance
int appCmdShow = 0;
@@ -73,48 +74,69 @@ Q_CORE_EXPORT int qWinAppCmdShow() // get main window sho
return appCmdShow;
}
+Q_CORE_EXPORT QString qAppFileName() // get application file name
+{
+ // We do MAX_PATH + 2 here, and request with MAX_PATH + 1, so we can handle all paths
+ // up to, and including MAX_PATH size perfectly fine with string termination, as well
+ // as easily detect if the file path is indeed larger than MAX_PATH, in which case we
+ // need to use the heap instead. This is a work-around, since contrary to what the
+ // MSDN documentation states, GetModuleFileName sometimes doesn't set the
+ // ERROR_INSUFFICIENT_BUFFER error number, and we thus cannot rely on this value if
+ // GetModuleFileName(0, buffer, MAX_PATH) == MAX_PATH.
+ // GetModuleFileName(0, buffer, MAX_PATH + 1) == MAX_PATH just means we hit the normal
+ // file path limit, and we handle it normally, if the result is MAX_PATH + 1, we use
+ // heap (even if the result _might_ be exactly MAX_PATH + 1, but that's ok).
+ wchar_t buffer[MAX_PATH + 2];
+ DWORD v = GetModuleFileName(0, buffer, MAX_PATH + 1);
+ buffer[MAX_PATH + 1] = 0;
+
+ if (v == 0)
+ return QString();
+ else if (v <= MAX_PATH)
+ return QString::fromWCharArray(buffer);
+
+ // MAX_PATH sized buffer wasn't large enough to contain the full path, use heap
+ wchar_t *b = 0;
+ int i = 1;
+ size_t size;
+ do {
+ ++i;
+ size = MAX_PATH * i;
+ b = reinterpret_cast<wchar_t *>(realloc(b, (size + 1) * sizeof(wchar_t)));
+ if (b)
+ v = GetModuleFileName(NULL, b, size);
+ } while (b && v == size);
+
+ if (b)
+ *(b + size) = 0;
+ QString res = QString::fromWCharArray(b);
+ free(b);
+
+ return res;
+}
void set_winapp_name()
{
static bool already_set = false;
if (!already_set) {
already_set = true;
-#ifndef Q_OS_WINCE
- GetModuleFileNameA(0, appFileName, sizeof(appFileName));
- appFileName[sizeof(appFileName)-1] = 0;
-#else
- QString afm;
- afm.resize(sizeof(appFileName));
- afm.resize(GetModuleFileName(0, (wchar_t *) (afm.unicode()), sizeof(appFileName)));
- memcpy(appFileName, afm.toLatin1(), sizeof(appFileName));
-#endif
- const char *p = strrchr(appFileName, '\\'); // skip path
- if (p)
- memcpy(theAppName, p+1, qstrlen(p));
- int l = qstrlen(theAppName);
- if ((l > 4) && !qstricmp(theAppName + l - 4, ".exe"))
- theAppName[l-4] = '\0'; // drop .exe extension
-
- if (appInst == 0) {
- QT_WA({
- appInst = GetModuleHandle(0);
- }, {
- appInst = GetModuleHandleA(0);
- });
- }
- }
-}
-Q_CORE_EXPORT QString qAppFileName() // get application file name
-{
- return QString::fromLatin1(appFileName);
+ QString moduleName = qAppFileName();
+
+ QByteArray filePath = moduleName.toLocal8Bit();
+ QByteArray fileName = QFileInfo(moduleName).baseName().toLocal8Bit();
+
+ memcpy(appFileName, filePath.constData(), filePath.length());
+ memcpy(theAppName, fileName.constData(), fileName.length());
+
+ if (appInst == 0)
+ appInst = GetModuleHandle(0);
+ }
}
QString QCoreApplicationPrivate::appName() const
{
- if (!theAppName[0])
- set_winapp_name();
- return QString::fromLatin1(theAppName);
+ return QFileInfo(qAppFileName()).baseName();
}
class QWinMsgHandlerCriticalSection
@@ -145,15 +167,11 @@ Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str)
str = "(null)";
staticCriticalSection.lock();
- QT_WA({
- QString s(QString::fromLocal8Bit(str));
- s += QLatin1Char('\n');
- OutputDebugStringW((TCHAR*)s.utf16());
- }, {
- QByteArray s(str);
- s += '\n';
- OutputDebugStringA(s.data());
- })
+
+ QString s(QString::fromLocal8Bit(str));
+ s += QLatin1Char('\n');
+ OutputDebugString((wchar_t*)s.utf16());
+
staticCriticalSection.unlock();
}
@@ -262,7 +280,7 @@ QT_END_INCLUDE_NAMESPACE
// The values below should never change. Note that none of the usual
// WM_...FIRST & WM_...LAST values are in the list, as they normally have other
// WM_... representations
-struct {
+struct KnownWM {
uint WM;
const char* str;
} knownWM[] =
@@ -564,7 +582,7 @@ struct {
{ 0,0 }}; // End of known messages
// Looks up the WM_ message in the table above
-const char* findWMstr(uint msg)
+static const char* findWMstr(uint msg)
{
uint i = 0;
const char* result = 0;
diff --git a/src/corelib/kernel/qcorecmdlineargs_p.h b/src/corelib/kernel/qcorecmdlineargs_p.h
index c0dd813..a012b4e 100644
--- a/src/corelib/kernel/qcorecmdlineargs_p.h
+++ b/src/corelib/kernel/qcorecmdlineargs_p.h
@@ -135,9 +135,9 @@ static inline QStringList qWinCmdArgs(QString cmdLine) // not const-ref: this mi
QStringList args;
int argc = 0;
- QVector<ushort*> argv = qWinCmdLine<ushort>((ushort*)cmdLine.utf16(), cmdLine.length(), argc);
+ QVector<wchar_t*> argv = qWinCmdLine<wchar_t>((wchar_t *)cmdLine.utf16(), cmdLine.length(), argc);
for (int a = 0; a < argc; ++a) {
- args << QString::fromUtf16(argv[a]);
+ args << QString::fromWCharArray(argv[a]);
}
return args;
@@ -147,10 +147,7 @@ static inline QStringList qCmdLineArgs(int argc, char *argv[])
{
Q_UNUSED(argc)
Q_UNUSED(argv)
- QString cmdLine = QT_WA_INLINE(
- QString::fromUtf16((unsigned short*)GetCommandLineW()),
- QString::fromLocal8Bit(GetCommandLineA())
- );
+ QString cmdLine = QString::fromWCharArray(GetCommandLine());
return qWinCmdArgs(cmdLine);
}
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 0ffd6f7..3cb8fe6 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -221,14 +221,13 @@ QT_BEGIN_NAMESPACE
\value WindowStateChange The \l{QWidget::windowState()}{window's state} (minimized, maximized or full-screen) has changed (QWindowStateChangeEvent).
\value WindowTitleChange The window title has changed.
\value WindowUnblocked The window is unblocked after a modal dialog exited.
+ \value Wrapped The event is a wrapper for, i.e., contains, another event (QWrappedEvent).
\value ZOrderChange The widget's z-order has changed. This event is never sent to top level windows.
\value KeyboardLayoutChange The keyboard layout has changed.
\value DynamicPropertyChange A dynamic property was added, changed or removed from the object.
\value TouchBegin Beginning of a sequence of touch-screen and/or track-pad events (QTouchEvent)
\value TouchUpdate Touch-screen event (QTouchEvent)
\value TouchEnd End of touch-event sequence (QTouchEvent)
- \value Gesture A gesture has occured.
- \value GraphicsSceneGesture A gesture has occured on a graphics scene.
User events should have values between \c User and \c{MaxUser}:
@@ -271,9 +270,9 @@ QT_BEGIN_NAMESPACE
\omitvalue NetworkReplyUpdated
\omitvalue FutureCallOut
\omitvalue CocoaRequestModal
- \omitvalue Wrapped
\omitvalue Signal
\omitvalue SymbianDeferredFocusChanged
+ \omitvalue WinGesture
*/
/*!
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index efa9fd3..c361fd5 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -276,8 +276,7 @@ public:
TouchUpdate = 195,
TouchEnd = 196,
- Gesture = 197,
- GraphicsSceneGesture = 198,
+ WinGesture = 197,
RequestSoftwareInputPanel = 199,
CloseSoftwareInputPanel = 200,
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 67f2cd0..78a2b0b 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -49,11 +49,22 @@
#include "qeventdispatcher_unix_p.h"
#include <private/qthread_p.h>
#include <private/qcoreapplication_p.h>
+#include <private/qcore_unix_p.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+// VxWorks doesn't correctly set the _POSIX_... options
+#if defined(Q_OS_VXWORKS)
+# if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK <= 0)
+# undef _POSIX_MONOTONIC_CLOCK
+# define _POSIX_MONOTONIC_CLOCK 1
+# endif
+# include <pipeDrv.h>
+# include <selectLib.h>
+#endif
+
#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
# include <sys/times.h>
#endif
@@ -76,6 +87,7 @@ static void signalHandler(int sig)
}
+#if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS)
static void initThreadPipeFD(int fd)
{
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -90,25 +102,52 @@ static void initThreadPipeFD(int fd)
if (ret == -1)
perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe");
}
-
+#endif
QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
{
extern Qt::HANDLE qt_application_thread_id;
mainThread = (QThread::currentThreadId() == qt_application_thread_id);
+ bool pipefail = false;
// initialize the common parts of the event loop
-#ifdef Q_OS_INTEGRITY
+#if defined(Q_OS_INTEGRITY)
// INTEGRITY doesn't like a "select" on pipes, so use socketpair instead
- if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1)
+ if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair");
+ pipefail = true;
+ } else {
+ initThreadPipeFD(thread_pipe[0]);
+ initThreadPipeFD(thread_pipe[1]);
+ }
+#elif defined(Q_OS_VXWORKS)
+ char name[20];
+ qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
+
+ // make sure there is no pipe with this name
+ pipeDevDelete(name, true);
+ // create the pipe
+ if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
+ perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe device");
+ pipefail = true;
+ } else {
+ if ((thread_pipe[0] = open(name, O_RDWR, 0)) < 0) {
+ perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
+ pipefail = true;
+ } else {
+ initThreadPipeFD(thread_pipe[0]);
+ thread_pipe[1] = thread_pipe[0];
+ }
+ }
#else
- if (pipe(thread_pipe) == -1)
+ if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
+ pipefail = true;
+ }
#endif
- initThreadPipeFD(thread_pipe[0]);
- initThreadPipeFD(thread_pipe[1]);
+ if (pipefail)
+ qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
sn_highest = -1;
@@ -117,9 +156,18 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()
{
+#if defined(Q_OS_VXWORKS)
+ close(thread_pipe[0]);
+
+ char name[20];
+ qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
+
+ pipeDevDelete(name, true);
+#else
// cleanup the common parts of the event loop
close(thread_pipe[0]);
close(thread_pipe[1]);
+#endif
// cleanup timers
qDeleteAll(timerList);
@@ -224,9 +272,15 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
// select doesn't immediately return next time
int nevents = 0;
if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) {
+#if defined(Q_OS_VXWORKS)
+ char c[16];
+ ::read(thread_pipe[0], c, sizeof(c));
+ ::ioctl(thread_pipe[0], FIOFLUSH, 0);
+#else
char c[16];
while (::read(thread_pipe[0], c, sizeof(c)) > 0)
;
+#endif
if (!wakeUps.testAndSetRelease(1, 0)) {
// hopefully, this is dead code
qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!");
@@ -257,18 +311,10 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
QTimerInfoList::QTimerInfoList()
{
-#if (_POSIX_MONOTONIC_CLOCK-0 <= 0)
- useMonotonicTimers = false;
-
-# if (_POSIX_MONOTONIC_CLOCK == 0)
- // detect if the system support monotonic timers
- long x = sysconf(_SC_MONOTONIC_CLOCK);
- useMonotonicTimers = x != -1;
-# endif
+ currentTime = qt_gettime();
- getTime(currentTime);
-
- if (!useMonotonicTimers) {
+#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)
+ if (!qt_gettime_is_monotonic()) {
// not using monotonic timers, initialize the timeChanged() machinery
previousTime = currentTime;
@@ -284,9 +330,6 @@ QTimerInfoList::QTimerInfoList()
ticksPerSecond = 0;
msPerTick = 0;
}
-#else
- // using monotonic timers unconditionally
- getTime(currentTime);
#endif
firstTimerInfo = currentTimerInfo = 0;
@@ -294,11 +337,24 @@ QTimerInfoList::QTimerInfoList()
timeval QTimerInfoList::updateCurrentTime()
{
- getTime(currentTime);
- return currentTime;
+ return (currentTime = qt_gettime());
}
-#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
+#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED)
+
+template <>
+timeval qAbs(const timeval &t)
+{
+ timeval tmp = t;
+ if (tmp.tv_sec < 0) {
+ tmp.tv_sec = -tmp.tv_sec - 1;
+ tmp.tv_usec -= 1000000;
+ }
+ if (tmp.tv_sec == 0 && tmp.tv_usec < 0) {
+ tmp.tv_usec = -tmp.tv_usec;
+ }
+ return normalizedTimeval(tmp);
+}
/*
Returns true if the real time clock has changed by more than 10%
@@ -309,60 +365,35 @@ timeval QTimerInfoList::updateCurrentTime()
*/
bool QTimerInfoList::timeChanged(timeval *delta)
{
- tms unused;
+ struct tms unused;
clock_t currentTicks = times(&unused);
- int elapsedTicks = currentTicks - previousTicks;
+ clock_t elapsedTicks = currentTicks - previousTicks;
timeval elapsedTime = currentTime - previousTime;
- int elapsedMsecTicks = (elapsedTicks * 1000) / ticksPerSecond;
- int deltaMsecs = (elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000)
- - elapsedMsecTicks;
- if (delta) {
- delta->tv_sec = deltaMsecs / 1000;
- delta->tv_usec = (deltaMsecs % 1000) * 1000;
- }
+ timeval elapsedTimeTicks;
+ elapsedTimeTicks.tv_sec = elapsedTicks / ticksPerSecond;
+ elapsedTimeTicks.tv_usec = (((elapsedTicks * 1000) / ticksPerSecond) % 1000) * 1000;
+
+ timeval dummy;
+ if (!delta)
+ delta = &dummy;
+ *delta = elapsedTime - elapsedTimeTicks;
+
previousTicks = currentTicks;
previousTime = currentTime;
// If tick drift is more than 10% off compared to realtime, we assume that the clock has
// been set. Of course, we have to allow for the tick granularity as well.
-
- return (qAbs(deltaMsecs) - msPerTick) * 10 > elapsedMsecTicks;
-}
-
-void QTimerInfoList::getTime(timeval &t)
-{
-#if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED)
- if (useMonotonicTimers) {
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t.tv_sec = ts.tv_sec;
- t.tv_usec = ts.tv_nsec / 1000;
- return;
- }
-#endif
-
- gettimeofday(&t, 0);
- // NTP-related fix
- while (t.tv_usec >= 1000000l) {
- t.tv_usec -= 1000000l;
- ++t.tv_sec;
- }
- while (t.tv_usec < 0l) {
- if (t.tv_sec > 0l) {
- t.tv_usec += 1000000l;
- --t.tv_sec;
- } else {
- t.tv_usec = 0l;
- break;
- }
- }
+ timeval tickGranularity;
+ tickGranularity.tv_sec = 0;
+ tickGranularity.tv_usec = msPerTick * 1000;
+ return elapsedTimeTicks < ((qAbs(*delta) - tickGranularity) * 10);
}
void QTimerInfoList::repairTimersIfNeeded()
{
- if (useMonotonicTimers)
+ if (qt_gettime_is_monotonic())
return;
timeval delta;
if (timeChanged(&delta))
@@ -371,14 +402,6 @@ void QTimerInfoList::repairTimersIfNeeded()
#else // !(_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(QT_BOOTSTRAPPED)
-void QTimerInfoList::getTime(timeval &t)
-{
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t.tv_sec = ts.tv_sec;
- t.tv_usec = ts.tv_nsec / 1000;
-}
-
void QTimerInfoList::repairTimersIfNeeded()
{
}
@@ -407,7 +430,7 @@ void QTimerInfoList::timerRepair(const timeval &diff)
// repair all timers
for (int i = 0; i < size(); ++i) {
register QTimerInfo *t = at(i);
- t->timeout = t->timeout - diff;
+ t->timeout = t->timeout + diff;
}
}
@@ -607,25 +630,7 @@ QEventDispatcherUNIX::~QEventDispatcherUNIX()
int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
timeval *timeout)
{
- Q_D(QEventDispatcherUNIX);
- if (timeout) {
- // handle the case where select returns with a timeout, too
- // soon.
- timeval tvStart = d->timerList.currentTime;
- timeval tvCurrent = tvStart;
- timeval originalTimeout = *timeout;
-
- int nsel;
- do {
- timeval tvRest = originalTimeout + tvStart - tvCurrent;
- nsel = ::select(nfds, readfds, writefds, exceptfds, &tvRest);
- d->timerList.getTime(tvCurrent);
- } while (nsel == 0 && (tvCurrent - tvStart) < originalTimeout);
-
- return nsel;
- }
-
- return ::select(nfds, readfds, writefds, exceptfds, timeout);
+ return ::qt_safe_select(nfds, readfds, writefds, exceptfds, timeout);
}
/*!
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index c52965a..70c287f 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -56,55 +56,20 @@
#include "QtCore/qabstracteventdispatcher.h"
#include "QtCore/qlist.h"
#include "private/qabstracteventdispatcher_p.h"
+#include "private/qcore_unix_p.h"
#include "private/qpodlist_p.h"
#include "QtCore/qvarlengtharray.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#if !defined(Q_OS_HPUX) || defined(__ia64)
-#include <sys/select.h>
+#if defined(Q_OS_VXWORKS)
+# include <sys/times.h>
+#else
+# include <sys/time.h>
+# if !defined(Q_OS_HPUX) || defined(__ia64)
+# include <sys/select.h>
+# endif
#endif
-#include <unistd.h>
QT_BEGIN_NAMESPACE
-#if !defined(_POSIX_MONOTONIC_CLOCK)
-# define _POSIX_MONOTONIC_CLOCK -1
-#endif
-
-// Internal operator functions for timevals
-inline bool operator<(const timeval &t1, const timeval &t2)
-{ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); }
-inline bool operator==(const timeval &t1, const timeval &t2)
-{ return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; }
-inline timeval &operator+=(timeval &t1, const timeval &t2)
-{
- t1.tv_sec += t2.tv_sec;
- if ((t1.tv_usec += t2.tv_usec) >= 1000000l) {
- ++t1.tv_sec;
- t1.tv_usec -= 1000000l;
- }
- return t1;
-}
-inline timeval operator+(const timeval &t1, const timeval &t2)
-{
- timeval tmp;
- tmp.tv_sec = t1.tv_sec + t2.tv_sec;
- if ((tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000l) {
- ++tmp.tv_sec;
- tmp.tv_usec -= 1000000l;
- }
- return tmp;
-}
-inline timeval operator-(const timeval &t1, const timeval &t2)
-{
- timeval tmp;
- tmp.tv_sec = t1.tv_sec - t2.tv_sec;
- if ((tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0l) {
- --tmp.tv_sec;
- tmp.tv_usec += 1000000l;
- }
- return tmp;
-}
// internal timer info
struct QTimerInfo {
@@ -117,9 +82,7 @@ struct QTimerInfo {
class QTimerInfoList : public QList<QTimerInfo*>
{
-#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
- bool useMonotonicTimers;
-
+#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED)
timeval previousTime;
clock_t previousTicks;
int ticksPerSecond;
@@ -134,8 +97,6 @@ class QTimerInfoList : public QList<QTimerInfo*>
public:
QTimerInfoList();
- void getTime(timeval &t);
-
timeval currentTime;
timeval updateCurrentTime();
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index cb1549c..33b66f5 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -355,8 +355,7 @@ QEventDispatcherWin32Private::QEventDispatcherWin32Private()
{
resolveTimerAPI();
- wakeUpNotifier.setHandle(QT_WA_INLINE(CreateEventW(0, FALSE, FALSE, 0),
- CreateEventA(0, FALSE, FALSE, 0)));
+ wakeUpNotifier.setHandle(CreateEvent(0, FALSE, FALSE, 0));
if (!wakeUpNotifier.handle())
qWarning("QEventDispatcher: Creating QEventDispatcherWin32Private wakeup event failed");
}
@@ -367,13 +366,8 @@ QEventDispatcherWin32Private::~QEventDispatcherWin32Private()
CloseHandle(wakeUpNotifier.handle());
if (internalHwnd)
DestroyWindow(internalHwnd);
- QByteArray className = "QEventDispatcherWin32_Internal_Widget" + QByteArray::number(quintptr(qt_internal_proc));
-#if !defined(Q_OS_WINCE)
- UnregisterClassA(className.constData(), qWinAppInst());
-#else
- UnregisterClassW(reinterpret_cast<const wchar_t *> (QString::fromLatin1(className.constData()).utf16())
- , qWinAppInst());
-#endif
+ QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
+ UnregisterClass((wchar_t*)className.utf16(), qWinAppInst());
}
void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen)
@@ -382,18 +376,24 @@ void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen
QCoreApplication::sendEvent(wen, &event);
}
-
+// ### Qt 5: remove
Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin,
UINT wMsgFilterMax, UINT wRemoveMsg)
{
- QT_WA({ return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); } ,
- { return PeekMessageA(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); });
+ return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
}
+// ### Qt 5: remove
Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- QT_WA({ return PostMessage(hWnd, msg, wParam, lParam); } ,
- { return PostMessageA(hWnd, msg, wParam, lParam); });
+ return PostMessage(hWnd, msg, wParam, lParam);
+}
+
+// ### Qt 5: remove
+Q_CORE_EXPORT bool winGetMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin,
+ UINT wMsgFilterMax)
+{
+ return GetMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax);
}
// This function is called by a workerthread
@@ -443,10 +443,10 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
#ifdef GWLP_USERDATA
QEventDispatcherWin32 *eventDispatcher =
- (QEventDispatcherWin32 *) GetWindowLongPtrA(hwnd, GWLP_USERDATA);
+ (QEventDispatcherWin32 *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
#else
QEventDispatcherWin32 *eventDispatcher =
- (QEventDispatcherWin32 *) GetWindowLongA(hwnd, GWL_USERDATA);
+ (QEventDispatcherWin32 *) GetWindowLong(hwnd, GWL_USERDATA);
#endif
if (eventDispatcher) {
QEventDispatcherWin32Private *d = eventDispatcher->d_func();
@@ -494,54 +494,35 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
{
- HINSTANCE hi = qWinAppInst();
-#if defined(Q_OS_WINCE)
+ // make sure that multiple Qt's can coexist in the same process
+ QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
+
WNDCLASS wc;
-#else
- WNDCLASSA wc;
-#endif
wc.style = 0;
wc.lpfnWndProc = qt_internal_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
- wc.hInstance = hi;
+ wc.hInstance = qWinAppInst();
wc.hIcon = 0;
wc.hCursor = 0;
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
+ wc.lpszClassName = reinterpret_cast<const wchar_t *> (className.utf16());
- // make sure that multiple Qt's can coexist in the same process
- QByteArray className = "QEventDispatcherWin32_Internal_Widget" + QByteArray::number(quintptr(qt_internal_proc));
-#if defined(Q_OS_WINCE)
- QString tmp = QString::fromLatin1(className.data());
- wc.lpszClassName = reinterpret_cast<const wchar_t *> (tmp.utf16());
RegisterClass(&wc);
HWND wnd = CreateWindow(wc.lpszClassName, // classname
- wc.lpszClassName, // window name
- 0, // style
- 0, 0, 0, 0, // geometry
- 0, // parent
- 0, // menu handle
- hi, // application
- 0); // windows creation data.
-#else
- wc.lpszClassName = className.constData();
- RegisterClassA(&wc);
- HWND wnd = CreateWindowA(wc.lpszClassName, // classname
- wc.lpszClassName, // window name
- 0, // style
- 0, 0, 0, 0, // geometry
- 0, // parent
- 0, // menu handle
- hi, // application
- 0); // windows creation data.
-#endif
-
+ wc.lpszClassName, // window name
+ 0, // style
+ 0, 0, 0, 0, // geometry
+ 0, // parent
+ 0, // menu handle
+ qWinAppInst(), // application
+ 0); // windows creation data.
#ifdef GWLP_USERDATA
- SetWindowLongPtrA(wnd, GWLP_USERDATA, (LONG_PTR)eventDispatcher);
+ SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)eventDispatcher);
#else
- SetWindowLongA(wnd, GWL_USERDATA, (LONG)eventDispatcher);
+ SetWindowLong(wnd, GWL_USERDATA, (LONG)eventDispatcher);
#endif
if (!wnd) {
@@ -690,7 +671,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
haveMessage = true;
msg = d->queuedSocketEvents.takeFirst();
} else {
- haveMessage = winPeekMessage(&msg, 0, 0, 0, PM_REMOVE);
+ haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
if (haveMessage && (flags & QEventLoop::ExcludeUserInputEvents)
&& ((msg.message >= WM_KEYFIRST
&& msg.message <= WM_KEYLAST)
@@ -738,11 +719,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
if (!filterEvent(&msg)) {
TranslateMessage(&msg);
- QT_WA({
- DispatchMessage(&msg);
- } , {
- DispatchMessageA(&msg);
- });
+ DispatchMessage(&msg);
}
} else if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) {
d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
@@ -781,7 +758,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
bool QEventDispatcherWin32::hasPendingEvents()
{
MSG msg;
- return qGlobalPostedEventsCount() || winPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
+ return qGlobalPostedEventsCount() || PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
}
void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h
index a7f2f9d..ad44a15 100644
--- a/src/corelib/kernel/qfunctions_p.h
+++ b/src/corelib/kernel/qfunctions_p.h
@@ -57,6 +57,8 @@
#if defined(Q_OS_WINCE)
# include "QtCore/qfunctions_wince.h"
+#elif defined(Q_OS_VXWORKS)
+# include "QtCore/qfunctions_vxworks.h"
#endif
#ifdef Q_CC_RVCT
diff --git a/src/corelib/kernel/qfunctions_vxworks.cpp b/src/corelib/kernel/qfunctions_vxworks.cpp
new file mode 100644
index 0000000..6d5e7cc
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_vxworks.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifdef Q_OS_VXWORKS
+
+#include "qplatformdefs.h"
+#include "qfunctions_vxworks.h"
+
+#include <vmLib.h>
+#include <selectLib.h>
+#include <ioLib.h>
+
+QT_USE_NAMESPACE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// no lfind() - used by the TIF image format
+void *lfind(const void* key, const void* base, size_t* elements, size_t size,
+ int (*compare)(const void*, const void*))
+{
+ const char* current = (char*) base;
+ const char* const end = (char*) (current + (*elements) * size);
+ while (current != end) {
+ if (compare(current, key) == 0)
+ return (void*)current;
+ current += size;
+ }
+ return 0;
+}
+
+
+// no rand_r(), but rand()
+// NOTE: this implementation is wrong for multi threaded applications,
+// but there is no way to get it right on VxWorks (in kernel mode)
+int rand_r(unsigned int * /*seedp*/)
+{
+ return rand();
+}
+
+// no usleep() support
+int usleep(unsigned int usec)
+{
+ div_t dt = div(usec, 1000000);
+ struct timespec ts = { dt.quot, dt.rem * 1000 };
+
+ return nanosleep(&ts, 0);
+}
+
+
+// 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)
+# pragma weak gettimeofday
+#endif
+int gettimeofday(struct timeval *tv, void /*struct timezone*/ *)
+{
+ // the compiler will optimize this and will only use one code path
+ if (sizeof(struct timeval) == sizeof(struct timespec)) {
+ int res = clock_gettime(CLOCK_REALTIME, (struct timespec *) tv);
+ if (!res)
+ tv->tv_usec /= 1000;
+ return res;
+ } else {
+ struct timespec ts;
+
+ int res = clock_gettime(CLOCK_REALTIME, &ts);
+ if (!res) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+ return res;
+ }
+}
+
+// neither getpagesize() or sysconf(_SC_PAGESIZE) are available
+int getpagesize()
+{
+ return vmPageSizeGet();
+}
+
+// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h)
+int symlink(const char *, const char *)
+{
+ errno = EIO;
+ return -1;
+}
+
+ssize_t readlink(const char *, char *, size_t)
+{
+ errno = EIO;
+ return -1;
+}
+
+// there's no truncate(), but ftruncate() support...
+int truncate(const char *path, off_t length)
+{
+ int fd = open(path, O_WRONLY, 00777);
+ if (fd >= 0) {
+ int res = ftruncate(fd, length);
+ int en = errno;
+ close(fd);
+ errno = en;
+ return res;
+ }
+ // errno is already set by open
+ return -1;
+}
+
+
+
+// VxWorks doesn't know about passwd & friends.
+// in order to avoid patching the unix fs path everywhere
+// we introduce some dummy functions that simulate a single
+// 'root' user on the system.
+
+uid_t getuid()
+{
+ return 0;
+}
+
+gid_t getgid()
+{
+ return 0;
+}
+
+uid_t geteuid()
+{
+ return 0;
+}
+
+struct passwd *getpwuid(uid_t uid)
+{
+ static struct passwd pwbuf = { "root", 0, 0, 0, 0, 0, 0 };
+
+ if (uid == 0) {
+ return &pwbuf;
+ } else {
+ errno = ENOENT;
+ return 0;
+ }
+}
+
+struct group *getgrgid(gid_t gid)
+{
+ static struct group grbuf = { "root", 0, 0, 0 };
+
+ if (gid == 0) {
+ return &grbuf;
+ } else {
+ errno = ENOENT;
+ return 0;
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // Q_OS_VXWORKS
diff --git a/src/corelib/kernel/qfunctions_vxworks.h b/src/corelib/kernel/qfunctions_vxworks.h
new file mode 100644
index 0000000..cc98948
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_vxworks.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFUNCTIONS_VXWORKS_H
+#define QFUNCTIONS_VXWORKS_H
+#ifdef Q_OS_VXWORKS
+
+#include <unistd.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/times.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#ifndef QT_NO_IPV6IFNAME
+#include <net/if.h>
+#endif
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BUILD_CORE_LIB
+QT_MODULE(Core)
+#endif
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+
+#ifndef NSIG
+#define NSIG _NSIGS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// isascii is missing (sometimes!!)
+#ifndef isascii
+inline int isascii(int c) { return (c & 0x7f); }
+#endif
+
+// no lfind() - used by the TIF image format
+void *lfind(const void* key, const void* base, size_t* elements, size_t size,
+ int (*compare)(const void*, const void*));
+
+// no rand_r(), but rand()
+// NOTE: this implementation is wrong for multi threaded applications,
+// but there is no way to get it right on VxWorks (in kernel mode)
+int rand_r(unsigned int * /*seedp*/);
+
+// no usleep() support
+int usleep(unsigned int);
+
+// 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));
+
+// neither getpagesize() or sysconf(_SC_PAGESIZE) are available
+int getpagesize();
+
+// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h)
+int symlink(const char *, const char *);
+ssize_t readlink(const char *, char *, size_t);
+
+// there's no truncate(), but ftruncate() support...
+int truncate(const char *path, off_t length);
+
+// VxWorks doesn't know about passwd & friends.
+// in order to avoid patching the unix fs path everywhere
+// we introduce some dummy functions that simulate a single
+// 'root' user on the system.
+
+uid_t getuid();
+gid_t getgid();
+uid_t geteuid();
+
+struct passwd {
+ char *pw_name; /* user name */
+ char *pw_passwd; /* user password */
+ uid_t pw_uid; /* user ID */
+ gid_t pw_gid; /* group ID */
+ char *pw_gecos; /* real name */
+ char *pw_dir; /* home directory */
+ char *pw_shell; /* shell program */
+};
+
+struct group {
+ char *gr_name; /* group name */
+ char *gr_passwd; /* group password */
+ gid_t gr_gid; /* group ID */
+ char **gr_mem; /* group members */
+};
+
+struct passwd *getpwuid(uid_t uid);
+struct group *getgrgid(gid_t gid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // Q_OS_VXWORKS
+#endif // QFUNCTIONS_VXWORKS_H
diff --git a/src/corelib/kernel/qfunctions_wince.cpp b/src/corelib/kernel/qfunctions_wince.cpp
index 2c47adb..5680ad5 100644
--- a/src/corelib/kernel/qfunctions_wince.cpp
+++ b/src/corelib/kernel/qfunctions_wince.cpp
@@ -108,7 +108,7 @@ int qt_wince__getdrive( void )
return 1;
}
-int qt_wince__waccess( const WCHAR *path, int pmode )
+int qt_wince__waccess( const wchar_t *path, int pmode )
{
DWORD res = GetFileAttributes( path );
if ( 0xFFFFFFFF == res )
@@ -118,7 +118,7 @@ int qt_wince__waccess( const WCHAR *path, int pmode )
return -1;
if ( (pmode & X_OK) && !(res & FILE_ATTRIBUTE_DIRECTORY) ) {
- QString file = QString::fromUtf16(reinterpret_cast<const ushort *> (path));
+ QString file = QString::fromWCharArray(path);
if ( !(file.endsWith(QString::fromLatin1(".exe")) ||
file.endsWith(QString::fromLatin1(".com"))) )
return -1;
@@ -130,12 +130,12 @@ int qt_wince__waccess( const WCHAR *path, int pmode )
int qt_wince_open( const char *filename, int oflag, int pmode )
{
QString fn( QString::fromLatin1(filename) );
- return _wopen( (WCHAR*)fn.utf16(), oflag, pmode );
+ return _wopen( (wchar_t*)fn.utf16(), oflag, pmode );
}
-int qt_wince__wopen( const WCHAR *filename, int oflag, int /*pmode*/ )
+int qt_wince__wopen( const wchar_t *filename, int oflag, int /*pmode*/ )
{
- WCHAR *flag;
+ wchar_t *flag;
if ( oflag & _O_APPEND ) {
if ( oflag & _O_WRONLY ) {
@@ -290,7 +290,7 @@ bool qt_wince__chmod(const char *file, int mode)
return _wchmod( reinterpret_cast<const wchar_t *> (QString::fromLatin1(file).utf16()), mode);
}
-bool qt_wince__wchmod(const WCHAR *file, int mode)
+bool qt_wince__wchmod(const wchar_t *file, int mode)
{
// ### Does not work properly, what about just adding one property?
if(mode&_S_IWRITE) {
diff --git a/src/corelib/kernel/qfunctions_wince.h b/src/corelib/kernel/qfunctions_wince.h
index 307e17b..41cb641 100644
--- a/src/corelib/kernel/qfunctions_wince.h
+++ b/src/corelib/kernel/qfunctions_wince.h
@@ -175,8 +175,8 @@ typedef int mode_t;
extern int errno;
int qt_wince__getdrive( void );
-int qt_wince__waccess( const WCHAR *path, int pmode );
-int qt_wince__wopen( const WCHAR *filename, int oflag, int pmode );
+int qt_wince__waccess( const wchar_t *path, int pmode );
+int qt_wince__wopen( const wchar_t *filename, int oflag, int pmode );
long qt_wince__lseek( int handle, long offset, int origin );
int qt_wince__read( int handle, void *buffer, unsigned int count );
int qt_wince__write( int handle, const void *buffer, unsigned int count );
@@ -204,7 +204,7 @@ int qt_wince_SetErrorMode(int);
#endif
bool qt_wince__chmod(const char *file, int mode);
-bool qt_wince__wchmod(const WCHAR *file, int mode);
+bool qt_wince__wchmod(const wchar_t *file, int mode);
#pragma warning(disable: 4273)
HANDLE qt_wince_CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
diff --git a/src/corelib/kernel/qguard_p.h b/src/corelib/kernel/qguard_p.h
new file mode 100644
index 0000000..6af01ac
--- /dev/null
+++ b/src/corelib/kernel/qguard_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGUARD_P_H
+#define QGUARD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+template<class T>
+class QGuard
+{
+ QObject *o;
+ QGuard<QObject> *next;
+ QGuard<QObject> **prev;
+ friend void q_guard_addGuard(QGuard<QObject> *);
+ friend void q_guard_removeGuard(QGuard<QObject> *);
+ friend class QObjectPrivate;
+public:
+ inline QGuard();
+ inline QGuard(T *);
+ inline QGuard(const QGuard<T> &);
+ inline virtual ~QGuard();
+
+ inline QGuard<T> &operator=(const QGuard<T> &o);
+ inline QGuard<T> &operator=(T *);
+
+ inline bool isNull() const
+ { return !o; }
+
+ inline T* operator->() const
+ { return static_cast<T*>(const_cast<QObject*>(o)); }
+ inline T& operator*() const
+ { return *static_cast<T*>(const_cast<QObject*>(o)); }
+ inline operator T*() const
+ { return static_cast<T*>(const_cast<QObject*>(o)); }
+ inline T* data() const
+ { return static_cast<T*>(const_cast<QObject*>(o)); }
+
+protected:
+ virtual void objectDestroyed(T *) {}
+};
+
+QT_END_NAMESPACE
+
+#include "private/qobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+inline void q_guard_addGuard(QGuard<QObject> *);
+inline void q_guard_removeGuard(QGuard<QObject> *);
+
+template<class T>
+QGuard<T>::QGuard()
+: o(0), next(0), prev(0)
+{
+}
+
+template<class T>
+QGuard<T>::QGuard(T *g)
+: o(g), next(0), prev(0)
+{
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+}
+
+template<class T>
+QGuard<T>::QGuard(const QGuard<T> &g)
+: o(g.o), next(0), prev(0)
+{
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+}
+
+template<class T>
+QGuard<T>::~QGuard()
+{
+ if (prev) q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ o = 0;
+}
+
+template<class T>
+QGuard<T> &QGuard<T>::operator=(const QGuard<T> &g)
+{
+ if (g.o != o) {
+ if (prev)
+ q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ o = g.o;
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ }
+ return *this;
+}
+
+template<class T>
+inline QGuard<T> &QGuard<T>::operator=(T *g)
+{
+ if (g != o) {
+ if (prev)
+ q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ o = g;
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ }
+ return *this;
+}
+
+QT_END_NAMESPACE
+
+#endif // QGUARD_P_H
diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h
index 348957f..7a77d56 100644
--- a/src/corelib/kernel/qmath.h
+++ b/src/corelib/kernel/qmath.h
@@ -132,6 +132,10 @@ inline qreal qPow(qreal x, qreal y)
return pow(x, y);
}
+#ifndef M_PI
+#define M_PI (3.14159265358979323846)
+#endif
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 0b9f841..7f8d2e8 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -148,7 +148,9 @@ enum PropertyFlags {
Resettable = 0x00000004,
EnumOrFlag = 0x00000008,
StdCppSet = 0x00000100,
-// Override = 0x00000200,
+// Override = 0x00000200,
+ Constant = 0x00000400,
+ Final = 0x00000800,
Designable = 0x00001000,
ResolveDesignable = 0x00002000,
Scriptable = 0x00004000,
@@ -179,6 +181,10 @@ enum MethodFlags {
MethodScriptable = 0x40
};
+enum MetaObjectFlags {
+ DynamicMetaObject = 0x01
+};
+
struct QMetaObjectPrivate
{
int revision;
@@ -188,6 +194,7 @@ struct QMetaObjectPrivate
int propertyCount, propertyData;
int enumeratorCount, enumeratorData;
int constructorCount, constructorData;
+ int flags;
};
static inline const QMetaObjectPrivate *priv(const uint* data)
@@ -277,6 +284,17 @@ int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
}
/*!
+ \internal
+*/
+int QMetaObject::metacall(QObject *object, Call cl, int idx, void **argv)
+{
+ if (QMetaObject *mo = object->d_ptr->metaObject)
+ return static_cast<QAbstractDynamicMetaObject*>(mo)->metaCall(cl, idx, argv);
+ else
+ return object->qt_metacall(cl, idx, argv);
+}
+
+/*!
\fn const char *QMetaObject::className() const
Returns the class name.
@@ -696,6 +714,14 @@ int QMetaObject::indexOfProperty(const char *name) const
}
m = m->d.superdata;
}
+
+ if (i == -1 && priv(this->d.data)->revision >= 3 && (priv(this->d.data)->flags & DynamicMetaObject)){
+ QAbstractDynamicMetaObject *me =
+ const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(this));
+
+ i = me->createProperty(name, 0);
+ }
+
return i;
}
@@ -1326,6 +1352,16 @@ int QMetaMethod::attributes() const
}
/*!
+ Returns this method's index.
+*/
+int QMetaMethod::methodIndex() const
+{
+ if (!mobj)
+ return -1;
+ return ((handle - priv(mobj->d.data)->methodData) / 5) + mobj->methodOffset();
+}
+
+/*!
Returns the access specification of this method (private,
protected, or public).
@@ -1525,7 +1561,7 @@ bool QMetaMethod::invoke(QObject *object,
// recompute the methodIndex by reversing the arithmetic in QMetaObject::property()
int methodIndex = ((handle - priv(mobj->d.data)->methodData) / 5) + mobj->methodOffset();
if (connectionType == Qt::DirectConnection) {
- return object->qt_metacall(QMetaObject::InvokeMetaMethod, methodIndex, param) < 0;
+ return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, methodIndex, param) < 0;
} else {
if (returnValue.data()) {
qWarning("QMetaMethod::invoke: Unable to invoke methods with return values in "
@@ -2042,6 +2078,16 @@ int QMetaProperty::userType() const
}
/*!
+ Returns this property's index.
+*/
+int QMetaProperty::propertyIndex() const
+{
+ if (!mobj)
+ return -1;
+ return idx + mobj->propertyOffset();
+}
+
+/*!
Returns true if the property's type is an enumeration value that
is used as a flag; otherwise returns false.
@@ -2138,19 +2184,25 @@ QVariant QMetaProperty::read(const QObject *object) const
return QVariant();
}
}
+
+ // the status variable is changed by qt_metacall to indicate what it did
+ // this feature is currently only used by QtDBus and should not be depended
+ // upon. Don't change it without looking into QDBusAbstractInterface first
+ // -1 (unchanged): normal qt_metacall, result stored in argv[0]
+ // changed: result stored directly in value
+ int status = -1;
QVariant value;
- void *argv[2] = { 0, &value };
+ void *argv[] = { 0, &value, &status };
if (t == QVariant::LastType) {
argv[0] = &value;
} else {
value = QVariant(t, (void*)0);
argv[0] = value.data();
}
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::ReadProperty,
- idx + mobj->propertyOffset(),
- argv);
- if (argv[1] == 0)
- // "value" was changed
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::ReadProperty,
+ idx + mobj->propertyOffset(), argv);
+
+ if (status != -1)
return value;
if (t != QVariant::LastType && argv[0] != value.data())
// pointer or reference
@@ -2208,13 +2260,19 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
return false;
}
- void *argv[2] = { 0, &v };
+ // the status variable is changed by qt_metacall to indicate what it did
+ // this feature is currently only used by QtDBus and should not be depended
+ // upon. Don't change it without looking into QDBusAbstractInterface first
+ // -1 (unchanged): normal qt_metacall, result stored in argv[0]
+ // changed: result stored directly in value, return the value of status
+ int status = -1;
+ void *argv[] = { 0, &v, &status };
if (t == QVariant::LastType)
argv[0] = &v;
else
argv[0] = v.data();
- object->qt_metacall(QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv);
- return true;
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv);
+ return status;
}
/*!
@@ -2230,7 +2288,7 @@ bool QMetaProperty::reset(QObject *object) const
if (!object || !mobj || !isResettable())
return false;
void *argv[] = { 0 };
- object->qt_metacall(QMetaObject::ResetProperty, idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(object, QMetaObject::ResetProperty, idx + mobj->propertyOffset(), argv);
return true;
}
@@ -2293,6 +2351,8 @@ QMetaMethod QMetaProperty::notifySignal() const
}
/*!
+ \since 4.6
+
Returns the index of the property change notifying signal if one was
specified, otherwise returns -1.
@@ -2342,8 +2402,8 @@ bool QMetaProperty::isDesignable(const QObject *object) const
bool b = flags & Designable;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyDesignable,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyDesignable,
+ idx + mobj->propertyOffset(), argv);
}
return b;
@@ -2368,8 +2428,8 @@ bool QMetaProperty::isScriptable(const QObject *object) const
bool b = flags & Scriptable;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyScriptable,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyScriptable,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
@@ -2392,8 +2452,8 @@ bool QMetaProperty::isStored(const QObject *object) const
bool b = flags & Stored;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyStored,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyStored,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
@@ -2419,13 +2479,41 @@ bool QMetaProperty::isUser(const QObject *object) const
bool b = flags & User;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyUser,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyUser,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
/*!
+ Returns true if the property is constant; otherwise returns false.
+
+ A property is constant if the \c{Q_PROPERTY()}'s \c CONSTANT attribute
+ is set.
+*/
+bool QMetaProperty::isConstant() const
+{
+ if (!mobj)
+ return false;
+ int flags = mobj->d.data[handle + 2];
+ return flags & Constant;
+}
+
+/*!
+ Returns true if the property is final; otherwise returns false.
+
+ A property is final if the \c{Q_PROPERTY()}'s \c FINAL attribute
+ is set.
+*/
+bool QMetaProperty::isFinal() const
+{
+ if (!mobj)
+ return false;
+ int flags = mobj->d.data[handle + 2];
+ return flags & Final;
+}
+
+/*!
\obsolete
Returns true if the property is editable for the given \a object;
@@ -2445,8 +2533,8 @@ bool QMetaProperty::isEditable(const QObject *object) const
bool b = flags & Editable;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyEditable,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyEditable,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index 000ba6e..419fe06 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -69,6 +69,7 @@ public:
MethodType methodType() const;
enum Attributes { Compatibility = 0x1, Cloned = 0x2, Scriptable = 0x4 };
int attributes() const;
+ int methodIndex() const;
inline const QMetaObject *enclosingMetaObject() const { return mobj; }
@@ -178,6 +179,7 @@ public:
const char *typeName() const;
QVariant::Type type() const;
int userType() const;
+ int propertyIndex() const;
bool isReadable() const;
bool isWritable() const;
@@ -187,6 +189,8 @@ public:
bool isStored(const QObject *obj = 0) const;
bool isEditable(const QObject *obj = 0) const;
bool isUser(const QObject *obj = 0) const;
+ bool isConstant() const;
+ bool isFinal() const;
bool isFlagType() const;
bool isEnumType() const;
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 02338fe..bd27ec2 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -171,6 +171,11 @@ QT_BEGIN_NAMESPACE
\value QBitmap QBitmap
\value QMatrix QMatrix
\value QTransform QTransform
+ \value QMatrix4x4 QMatrix4x4
+ \value QVector2D QVector2D
+ \value QVector3D QVector3D
+ \value QVector4D QVector4D
+ \value QQuaternion QQuaternion
\value User Base value for user types
@@ -272,6 +277,11 @@ static const struct { const char * typeName; int type; } types[] = {
{"QTextFormat", QMetaType::QTextFormat},
{"QMatrix", QMetaType::QMatrix},
{"QTransform", QMetaType::QTransform},
+ {"QMatrix4x4", QMetaType::QMatrix4x4},
+ {"QVector2D", QMetaType::QVector2D},
+ {"QVector3D", QMetaType::QVector3D},
+ {"QVector4D", QMetaType::QVector4D},
+ {"QQuaternion", QMetaType::QQuaternion},
/* All Metatype builtins */
{"void*", QMetaType::VoidStar},
@@ -430,16 +440,15 @@ int QMetaType::registerType(const char *typeName, Destructor destructor,
#endif
QWriteLocker locker(customTypesLock());
- static int currentIdx = User;
int idx = qMetaTypeType_unlocked(normalizedTypeName);
if (!idx) {
- ct->resize(ct->count() + 1);
- idx = currentIdx++;
- QCustomTypeInfo &inf = (*ct)[idx - User];
+ QCustomTypeInfo inf;
inf.typeName = normalizedTypeName;
inf.constr = constructor;
inf.destr = destructor;
+ idx = ct->size() + User;
+ ct->append(inf);
}
return idx;
}
@@ -671,6 +680,11 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::QTextFormat:
case QMetaType::QMatrix:
case QMetaType::QTransform:
+ case QMetaType::QMatrix4x4:
+ case QMetaType::QVector2D:
+ case QMetaType::QVector3D:
+ case QMetaType::QVector4D:
+ case QMetaType::QQuaternion:
if (!qMetaTypeGuiHelper)
return false;
qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
@@ -863,6 +877,11 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::QTextFormat:
case QMetaType::QMatrix:
case QMetaType::QTransform:
+ case QMetaType::QMatrix4x4:
+ case QMetaType::QVector2D:
+ case QMetaType::QVector3D:
+ case QMetaType::QVector4D:
+ case QMetaType::QQuaternion:
if (!qMetaTypeGuiHelper)
return false;
qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 497c014..052312c 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -79,7 +79,9 @@ public:
QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73,
QCursor = 74, QSizePolicy = 75, QKeySequence = 76, QPen = 77,
QTextLength = 78, QTextFormat = 79, QMatrix = 80, QTransform = 81,
- LastGuiType = 81 /* QTransform */,
+ QMatrix4x4 = 82, QVector2D = 83, QVector3D = 84, QVector4D = 85,
+ QQuaternion = 86,
+ LastGuiType = 86 /* QQuaternion */,
FirstCoreExtType = 128 /* VoidStar */,
VoidStar = 128, Long = 129, Short = 130, Char = 131, ULong = 132,
@@ -292,6 +294,11 @@ class QTextLength;
class QTextFormat;
class QMatrix;
class QTransform;
+class QMatrix4x4;
+class QVector2D;
+class QVector3D;
+class QVector4D;
+class QQuaternion;
QT_END_NAMESPACE
@@ -354,6 +361,11 @@ Q_DECLARE_BUILTIN_METATYPE(QTextLength, QTextLength)
Q_DECLARE_BUILTIN_METATYPE(QTextFormat, QTextFormat)
Q_DECLARE_BUILTIN_METATYPE(QMatrix, QMatrix)
Q_DECLARE_BUILTIN_METATYPE(QTransform, QTransform)
+Q_DECLARE_BUILTIN_METATYPE(QMatrix4x4, QMatrix4x4)
+Q_DECLARE_BUILTIN_METATYPE(QVector2D, QVector2D)
+Q_DECLARE_BUILTIN_METATYPE(QVector3D, QVector3D)
+Q_DECLARE_BUILTIN_METATYPE(QVector4D, QVector4D)
+Q_DECLARE_BUILTIN_METATYPE(QQuaternion, QQuaternion)
QT_END_HEADER
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index 3d2a7cb..4a1ba9f 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -105,7 +105,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
Q_Q(const QMimeData);
QVariant data = q->retrieveData(format, type);
- if (data.type() == type || data.type() == QVariant::Invalid)
+ if (data.type() == type || !data.isValid())
return data;
// provide more conversion possiblities than just what QVariant provides
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index cc2df0c..2630b63 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -124,7 +124,7 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
}
QObjectPrivate::QObjectPrivate(int version)
- : threadData(0), currentSender(0), currentChildBeingDeleted(0), connectionLists(0), senders(0)
+ : threadData(0), currentSender(0), declarativeData(0), connectionLists(0), senders(0)
{
if (version != QObjectPrivateVersion)
qFatal("Cannot mix incompatible Qt libraries");
@@ -140,15 +140,19 @@ QObjectPrivate::QObjectPrivate(int version)
receiveChildEvents = true;
postedEvents = 0;
extraData = 0;
- connectedSignals = 0;
+ for (uint i = 0; i < (sizeof connectedSignals / sizeof connectedSignals[0]); ++i)
+ connectedSignals[i] = 0;
inEventHandler = false;
inThreadChangeEvent = false;
deleteWatch = 0;
+ objectGuards = 0;
+ metaObject = 0;
hasGuards = false;
}
QObjectPrivate::~QObjectPrivate()
{
+ delete static_cast<QAbstractDynamicMetaObject*>(metaObject);
if (deleteWatch)
*deleteWatch = 1;
#ifndef QT_NO_USERDATA
@@ -428,8 +432,24 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o)
*/
void QObjectPrivate::clearGuards(QObject *object)
{
- if (!QObjectPrivate::get(object)->hasGuards)
+ QObjectPrivate *priv = QObjectPrivate::get(object);
+ QGuard<QObject> *guard = priv->objectGuards;
+ while (guard) {
+ guard->o = 0;
+ guard = guard->next;
+ }
+ while (priv->objectGuards) {
+ guard = priv->objectGuards;
+ guard->prev = 0;
+ if (guard->next) guard->next->prev = &priv->objectGuards;
+ priv->objectGuards = guard->next;
+ guard->next = 0;
+ guard->objectDestroyed(object);
+ }
+
+ if (!priv->hasGuards)
return;
+
GuardHash *hash = 0;
QMutex *mutex = 0;
QT_TRY {
@@ -480,7 +500,7 @@ QMetaCallEvent::~QMetaCallEvent()
*/
int QMetaCallEvent::placeMetaCall(QObject *object)
{
- return object->qt_metacall(QMetaObject::InvokeMetaMethod, id_, args_);
+ return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, id_, args_);
}
/*!
@@ -578,7 +598,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object)
\l uic generates code that invokes this function to enable
auto-connection to be performed between widgets on forms created
with \QD. More information about using auto-connection with \QD is
- given in the \l{Using a Designer .ui File in Your Application} section of
+ given in the \l{Using a Designer UI File in Your Application} section of
the \QD manual.
\section2 Dynamic Properties
@@ -872,6 +892,14 @@ QObject::~QObject()
d->eventFilters.clear();
+ // As declarativeData is in a union with currentChildBeingDeleted, this must
+ // be done (and declarativeData set back to 0) before deleting children.
+ if(d->declarativeData) {
+ QDeclarativeData *dd = d->declarativeData;
+ d->declarativeData = 0;
+ dd->destroyed(this);
+ }
+
if (!d->children.isEmpty())
d->deleteChildren();
@@ -898,7 +926,7 @@ QObject::~QObject()
QObjectPrivate::Connection::~Connection()
{
if (argumentTypes != &DIRECT_CONNECTION_ONLY)
- delete [] argumentTypes;
+ delete [] static_cast<int *>(argumentTypes);
}
@@ -1878,12 +1906,13 @@ void QObjectPrivate::deleteChildren()
// don't use qDeleteAll as the destructor of the child might
// delete siblings
for (int i = 0; i < children.count(); ++i) {
- currentChildBeingDeleted = children.at(i);
+ QObject *child = children.at(i);
children[i] = 0;
- delete currentChildBeingDeleted;
+ if (child)
+ child->d_func()->parent = 0;
+ delete child;
}
children.clear();
- currentChildBeingDeleted = 0;
wasDeleted = reallyWasDeleted;
}
@@ -1894,20 +1923,14 @@ void QObjectPrivate::setParent_helper(QObject *o)
return;
if (parent) {
QObjectPrivate *parentD = parent->d_func();
- if (parentD->wasDeleted && wasDeleted
- && parentD->currentChildBeingDeleted == q) {
- // don't do anything since QObjectPrivate::deleteChildren() already
- // cleared our entry in parentD->children.
+ const int index = parentD->children.indexOf(q);
+ if (parentD->wasDeleted) {
+ parentD->children[index] = 0;
} else {
- const int index = parentD->children.indexOf(q);
- if (parentD->wasDeleted) {
- parentD->children[index] = 0;
- } else {
- parentD->children.removeAt(index);
- if (sendChildEvents && parentD->receiveChildEvents) {
- QChildEvent e(QEvent::ChildRemoved, q);
- QCoreApplication::sendEvent(parent, &e);
- }
+ parentD->children.removeAt(index);
+ if (sendChildEvents && parentD->receiveChildEvents) {
+ QChildEvent e(QEvent::ChildRemoved, q);
+ QCoreApplication::sendEvent(parent, &e);
}
}
}
@@ -2132,6 +2155,34 @@ void QObject::deleteLater()
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17
+ \section1 Meta Data
+
+ Additional data can be attached to each translatable message.
+ The syntax:
+
+ \tt{//= <id>}
+
+ can be used to give the message a unique identifier to support tools
+ which need it.
+ The syntax:
+
+ \tt{//~ <field name> <field contents>}
+
+ can be used to attach meta data to the message. The field name should consist
+ of a domain prefix (possibly the conventional file extension of the file format
+ the field is inspired by), a hyphen and the actual field name in
+ underscore-delimited notation. For storage in TS files, the field name together
+ with the prefix "extra-" will form an XML element name. The field contents will
+ be XML-escaped, but otherwise appear verbatim as the element's contents.
+ Any number of unique fields can be added to each message.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp meta data
+
+ Meta data appearing right in front of a magic TRANSLATOR comment applies to the
+ whole TS file.
+
\section1 Character Encodings
You can set the encoding for \a sourceText by calling QTextCodec::setCodecForTr().
@@ -2886,10 +2937,16 @@ bool QMetaObject::connect(const QObject *sender, int signal_index,
if (c->next)
c->next->prev = &c->next;
- if (signal_index < 0)
- sender->d_func()->connectedSignals = ~0u;
- else if (signal_index < 32)
- sender->d_func()->connectedSignals |= (1 << signal_index);
+ if (signal_index < 0) {
+ for (uint i = 0; i < (sizeof sender->d_func()->connectedSignals
+ / sizeof sender->d_func()->connectedSignals[0] ); ++i)
+ sender->d_func()->connectedSignals[i] = ~0u;
+ } else if (signal_index < (int)sizeof sender->d_func()->connectedSignals * 8) {
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ sender->d_func()->connectedSignals[n] |= (1 << (signal_index - n * 8
+ * sizeof sender->d_func()->connectedSignals[0]));
+ }
+
return true;
}
@@ -3179,10 +3236,10 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal
}
#if defined(QT_NO_EXCEPTIONS)
- receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+ metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
#else
QT_TRY {
- receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+ metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
} QT_CATCH(...) {
locker.relock();
@@ -3231,11 +3288,12 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal
*/
void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
{
- if (signal_index < 32
+ if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
&& !qt_signal_spy_callback_set.signal_begin_callback
&& !qt_signal_spy_callback_set.signal_end_callback) {
- uint signal_mask = 1 << signal_index;
- if ((sender->d_func()->connectedSignals & signal_mask) == 0)
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ if ((sender->d_func()->connectedSignals[n] & m) == 0)
// nothing connected to these signals, and no spy
return;
}
@@ -3248,11 +3306,12 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
void **argv)
{
int signal_index = m->methodOffset() + local_signal_index;
- if (signal_index < 32
+ if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
&& !qt_signal_spy_callback_set.signal_begin_callback
&& !qt_signal_spy_callback_set.signal_end_callback) {
- uint signal_mask = 1 << signal_index;
- if ((sender->d_func()->connectedSignals & signal_mask) == 0)
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ if ((sender->d_func()->connectedSignals[n] & m) == 0)
// nothing connected to these signals, and no spy
return;
}
@@ -3264,21 +3323,59 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
void QMetaObject::activate(QObject *sender, const QMetaObject *m,
int from_local_signal_index, int to_local_signal_index, void **argv)
{
+ Q_ASSERT(from_local_signal_index <= to_local_signal_index);
int offset = m->methodOffset();
int from_signal_index = offset + from_local_signal_index;
int to_signal_index = offset + to_local_signal_index;
- if (to_signal_index < 32
+
+ if (to_signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
&& !qt_signal_spy_callback_set.signal_begin_callback
&& !qt_signal_spy_callback_set.signal_end_callback) {
- uint signal_mask = (1 << (to_signal_index + 1)) - 1;
- signal_mask ^= (1 << from_signal_index) - 1;
- if ((sender->d_func()->connectedSignals & signal_mask) == 0)
+
+ uint n = (from_signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (from_signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ uint nt = (to_signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint mt = 1 << (to_signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ bool connected = false;
+ quint32 *connectedSignals = sender->d_func()->connectedSignals;
+ for (uint i = 0; !connected && i < (sizeof sender->d_func()->connectedSignals
+ / sizeof sender->d_func()->connectedSignals[0]); ++i) {
+ uint mask = 0;
+ if (i > n)
+ mask = ~0u;
+ else if (i == n)
+ mask = ~(m -1);
+ if (i > nt)
+ mask = 0;
+ else if (i == nt)
+ mask &= (mt << 1) - 1;
+ connected = connectedSignals[i] & mask;
+ }
+ if (!connected)
// nothing connected to these signals, and no spy
return;
}
activate(sender, from_signal_index, to_signal_index, argv);
}
+/*! \internal
+
+ Returns true if the signal with index \a signal_index from object \a sender is connected.
+ Signals with indices above a certain range are always considered connected (see connectedSignals
+ in QObjectPrivate). If a signal spy is installed, all signals are considered connected.
+*/
+bool QMetaObject::isConnected(QObject *sender, int signal_index) {
+ if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
+ && !qt_signal_spy_callback_set.signal_begin_callback
+ && !qt_signal_spy_callback_set.signal_end_callback) {
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ if ((sender->d_func()->connectedSignals[n] & m) == 0)
+ // nothing connected to these signals, and no spy
+ return false;
+ }
+ return true;
+}
/*****************************************************************************
Properties
@@ -3885,6 +3982,7 @@ void qDeleteInEventHandler(QObject *o)
delete o;
}
+
QT_END_NAMESPACE
#include "moc_qobject.cpp"
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index e725c82..200c97d 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -110,6 +110,7 @@ public:
uint hasGuards : 1; //true iff there is one or more QPointer attached to this object
uint unused : 22;
int postedEvents;
+ QMetaObject *metaObject; // assert dynamic
};
@@ -380,6 +381,9 @@ inline QList<T> qFindChildren(const QObject *o, const QRegExp &re)
#endif // Q_MOC_RUN
+template <class T> inline const char * qobject_interface_iid()
+{ return 0; }
+
template <class T> inline T qobject_cast_helper(QObject *object, T)
{ return static_cast<T>(((T)0)->staticMetaObject.cast(object)); }
@@ -396,6 +400,8 @@ inline T qobject_cast(const QObject *object)
#ifndef Q_MOC_RUN
# define Q_DECLARE_INTERFACE(IFace, IId) \
+ template <> inline const char *qobject_interface_iid<IFace *>() \
+ { return IId; } \
template <> inline IFace *qobject_cast_helper<IFace *>(QObject *object, IFace *) \
{ return (IFace *)(object ? object->qt_metacast(IId) : 0); } \
template <> inline IFace *qobject_cast_helper<IFace *>(const QObject *object, IFace *) \
@@ -459,8 +465,13 @@ inline T qobject_cast(const QObject *object)
}
+template <class T> inline const char * qobject_interface_iid()
+{ return 0; }
+
#ifndef Q_MOC_RUN
# define Q_DECLARE_INTERFACE(IFace, IId) \
+ template <> inline const char *qobject_interface_iid<IFace *>() \
+ { return IId; } \
template <> inline IFace *qobject_cast<IFace *>(QObject *object) \
{ return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : 0)); } \
template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 07c397f..0b41c9a 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -60,6 +60,7 @@
#include "QtCore/qvector.h"
#include "QtCore/qreadwritelock.h"
#include "QtCore/qvariant.h"
+#include "private/qguard_p.h"
QT_BEGIN_NAMESPACE
@@ -85,6 +86,13 @@ inline QObjectData::~QObjectData() {}
enum { QObjectPrivateVersion = QT_VERSION };
+class QDeclarativeData
+{
+public:
+ virtual ~QDeclarativeData() {}
+ virtual void destroyed(QObject *) {}
+};
+
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
@@ -117,7 +125,7 @@ public:
// object currently activating the object
Sender *currentSender;
- QObject *currentChildBeingDeleted;
+ QDeclarativeData *declarativeData;
bool isSender(const QObject *receiver, const char *signal) const;
QObjectList receiverList(const char *signal) const;
@@ -140,7 +148,7 @@ public:
QList<QVariant> propertyValues;
};
ExtraData *extraData;
- mutable quint32 connectedSignals;
+ mutable quint32 connectedSignals[2];
QString objectName;
@@ -174,12 +182,37 @@ public:
static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch);
int *deleteWatch;
+ QGuard<QObject> *objectGuards;
static QObjectPrivate *get(QObject *o) {
return o->d_func();
}
};
+inline void q_guard_addGuard(QGuard<QObject> *g)
+{
+ QObjectPrivate *p = QObjectPrivate::get(g->o);
+ if (p->wasDeleted) {
+ qWarning("QGuard: cannot add guard to deleted object");
+ g->o = 0;
+ return;
+ }
+
+ g->next = p->objectGuards;
+ p->objectGuards = g;
+ g->prev = &p->objectGuards;
+ if (g->next)
+ g->next->prev = &g->next;
+}
+
+inline void q_guard_removeGuard(QGuard<QObject> *g)
+{
+ if (g->next) g->next->prev = g->prev;
+ *g->prev = g->next;
+ g->next = 0;
+ g->prev = 0;
+}
+
Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE);
@@ -220,6 +253,14 @@ private:
void Q_CORE_EXPORT qDeleteInEventHandler(QObject *o);
+
+struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QMetaObject
+{
+ virtual ~QAbstractDynamicMetaObject() {}
+ virtual int metaCall(QMetaObject::Call, int _id, void **) { return _id; }
+ virtual int createProperty(const char *, const char *) { return -1; }
+};
+
QT_END_NAMESPACE
#endif // QOBJECT_P_H
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 9187765..1ae46d5 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -334,6 +334,9 @@ struct Q_CORE_EXPORT QMetaObject
static void activate(QObject *sender, int from_signal_index, int to_signal_index, void **argv);
static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
static void activate(QObject *sender, const QMetaObject *, int from_local_signal_index, int to_local_signal_index, void **argv);
+
+ static bool isConnected(QObject *sender, int signal_index);
+
// internal guarded pointers
static void addGuard(QObject **ptr);
static void removeGuard(QObject **ptr);
@@ -428,6 +431,7 @@ struct Q_CORE_EXPORT QMetaObject
};
int static_metacall(Call, int, void **) const;
+ static int metacall(QObject *, Call, int, void **);
#ifdef QT3_SUPPORT
QT3_SUPPORT const char *superClassName() const;
@@ -439,6 +443,7 @@ struct Q_CORE_EXPORT QMetaObject
const uint *data;
const void *extradata;
} d;
+
};
struct QMetaObjectExtraData
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index 7e8dc23..61f7727 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -56,7 +56,7 @@
#include <fcntl.h>
#include <unistd.h>
-#ifndef QT_NO_SHAREDMEMORY
+#include "private/qcore_unix_p.h"
QT_BEGIN_NAMESPACE
@@ -82,7 +82,7 @@ void QSharedMemoryPrivate::setErrorString(const QString &function)
error = QSharedMemory::AlreadyExists;
break;
case ENOENT:
- errorString = QSharedMemory::tr("%1: doesn't exists").arg(function);
+ errorString = QSharedMemory::tr("%1: doesn't exist").arg(function);
error = QSharedMemory::NotFound;
break;
case EMFILE:
@@ -121,7 +121,7 @@ key_t QSharedMemoryPrivate::handle()
// ftok requires that an actual file exists somewhere
QString fileName = makePlatformSafeKey(key);
if (!QFile::exists(fileName)) {
- errorString = QSharedMemory::tr("%1: unix key file doesn't exists").arg(QLatin1String("QSharedMemory::handle:"));
+ errorString = QSharedMemory::tr("%1: UNIX key file doesn't exist").arg(QLatin1String("QSharedMemory::handle:"));
error = QSharedMemory::NotFound;
return 0;
}
@@ -152,7 +152,7 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
if (QFile::exists(fileName))
return 0;
- int fd = open(QFile::encodeName(fileName).constData(),
+ int fd = qt_safe_open(QFile::encodeName(fileName).constData(),
O_EXCL | O_CREAT | O_RDWR, 0640);
if (-1 == fd) {
if (errno == EEXIST)
diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp
index d963a6d..ae64806 100644
--- a/src/corelib/kernel/qsharedmemory_win.cpp
+++ b/src/corelib/kernel/qsharedmemory_win.cpp
@@ -71,7 +71,7 @@ void QSharedMemoryPrivate::setErrorString(const QString &function)
case ERROR_INVALID_PARAMETER:
#endif
error = QSharedMemory::NotFound;
- errorString = QSharedMemory::tr("%1: doesn't exists").arg(function);
+ errorString = QSharedMemory::tr("%1: doesn't exist").arg(function);
break;
case ERROR_COMMITMENT_LIMIT:
error = QSharedMemory::InvalidSize;
@@ -106,16 +106,11 @@ HANDLE QSharedMemoryPrivate::handle()
return false;
}
#ifndef Q_OS_WINCE
- QT_WA({
- hand = OpenFileMappingW(FILE_MAP_ALL_ACCESS, false, (TCHAR*)safeKey.utf16());
- }, {
- hand = OpenFileMappingA(FILE_MAP_ALL_ACCESS, false, safeKey.toLocal8Bit().constData());
- });
+ hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, (wchar_t*)safeKey.utf16());
#else
// This works for opening a mapping too, but always opens it with read/write access in
// attach as it seems.
- hand = CreateFileMappingW(INVALID_HANDLE_VALUE,
- 0, PAGE_READWRITE, 0, 0, (TCHAR*)safeKey.utf16());
+ hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 0, (wchar_t*)safeKey.utf16());
#endif
if (!hand) {
setErrorString(function);
@@ -148,13 +143,7 @@ bool QSharedMemoryPrivate::create(int size)
}
// Create the file mapping.
- QT_WA( {
- hand = CreateFileMappingW(INVALID_HANDLE_VALUE,
- 0, PAGE_READWRITE, 0, size, (TCHAR*)safeKey.utf16());
- }, {
- hand = CreateFileMappingA(INVALID_HANDLE_VALUE,
- 0, PAGE_READWRITE, 0, size, safeKey.toLocal8Bit().constData());
- } );
+ hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, (wchar_t*)safeKey.utf16());
setErrorString(function);
// hand is valid when it already exists unlike unix so explicitly check
diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp
index 4e03ddf..1102258 100644
--- a/src/corelib/kernel/qsystemsemaphore_win.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_win.cpp
@@ -87,11 +87,7 @@ HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
// Create it if it doesn't already exists.
if (semaphore == 0) {
QString safeName = makeKeyFileName();
- QT_WA({
- semaphore = CreateSemaphoreW(0, initialValue, MAXLONG, (TCHAR*)safeName.utf16());
- }, {
- semaphore = CreateSemaphoreA(0, initialValue, MAXLONG, safeName.toLocal8Bit().constData());
- });
+ semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)safeName.utf16());
if (semaphore == NULL)
setErrorString(QLatin1String("QSystemSemaphore::handle"));
}
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index d2a0b3a..2ee9d26 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -103,9 +103,8 @@ QT_BEGIN_NAMESPACE
Note that QTimer's accuracy depends on the underlying operating
system and hardware. Most platforms support an accuracy of
- 1 millisecond, but Windows 98 supports only 55. If Qt is
- unable to deliver the requested number of timer clicks, it will
- silently discard some.
+ 1 millisecond. If Qt is unable to deliver the requested number of
+ timer clicks, it will silently discard some.
An alternative to using QTimer is to call QObject::startTimer()
for your object and reimplement the QObject::timerEvent() event
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 64cf16e..dc1b530 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -58,6 +58,7 @@
#if defined(Q_OS_UNIX)
#define QT_USE_MMAP
+#include "private/qcore_unix_p.h"
#endif
// most of the headers below are already included in qplatformdefs.h
@@ -502,7 +503,7 @@ bool QTranslator::load(const QString & filename, const QString & directory,
\overload load()
\fn bool QTranslator::load(const uchar *data, int len)
- Loads the .qm file data \a data of length \a len into the
+ Loads the QM file data \a data of length \a len into the
translator.
The data is not copied. The caller must be able to guarantee that \a data
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index dd3468d..5016d3b 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1291,6 +1291,7 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler;
\value Map a QVariantMap
\value Matrix a QMatrix
\value Transform a QTransform
+ \value Matrix4x4 a QMatrix4x4
\value Palette a QPalette
\value Pen a QPen
\value Pixmap a QPixmap
@@ -1298,6 +1299,7 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler;
\value PointArray a QPointArray
\value PointF a QPointF
\value Polygon a QPolygon
+ \value Quaternion a QQuaternion
\value Rect a QRect
\value RectF a QRectF
\value RegExp a QRegExp
@@ -1313,6 +1315,9 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler;
\value UInt a \l uint
\value ULongLong a \l qulonglong
\value Url a QUrl
+ \value Vector2D a QVector2D
+ \value Vector3D a QVector3D
+ \value Vector4D a QVector4D
\value UserType Base value for user-defined types.
@@ -1704,7 +1709,7 @@ QVariant::QVariant(Qt::GlobalColor color) { create(62, &color); }
Note that return values in the ranges QVariant::Char through
QVariant::RegExp and QVariant::Font through QVariant::Transform
correspond to the values in the ranges QMetaType::QChar through
- QMetaType::QRegExp and QMetaType::QFont through QMetaType::QTransform.
+ QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
Pay particular attention when working with char and QChar
variants. Note that there is no QVariant constructor specifically
@@ -1932,7 +1937,7 @@ void QVariant::load(QDataStream &s)
create(static_cast<int>(u), 0);
d.is_null = is_null;
- if (d.type == QVariant::Invalid) {
+ if (!isValid()) {
// Since we wrote something, we should read something
QString x;
s >> x;
@@ -1976,7 +1981,7 @@ void QVariant::save(QDataStream &s) const
s << QMetaType::typeName(userType());
}
- if (d.type == QVariant::Invalid) {
+ if (!isValid()) {
s << QString();
return;
}
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index e923844..a68939d 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -154,7 +154,12 @@ class Q_CORE_EXPORT QVariant
TextFormat = 79,
Matrix = 80,
Transform = 81,
- LastGuiType = Transform,
+ Matrix4x4 = 82,
+ Vector2D = 83,
+ Vector3D = 84,
+ Vector4D = 85,
+ Quaternion = 86,
+ LastGuiType = Quaternion,
UserType = 127,
#ifdef QT3_SUPPORT