diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-25 17:39:52 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-25 17:39:52 (GMT) |
commit | 5a7223450d0ebd4eaa47f263005c6d1c2e142a76 (patch) | |
tree | 9970c8b78e0d5178fbf44bab0317212b2a8c7bdd /src | |
parent | 77e5ced3e6b4c1c5ef05684de736bf4939dbe115 (diff) | |
parent | d7d0aaf8bea4e6a5c4c0500a46417d7c788f489a (diff) | |
download | Qt-5a7223450d0ebd4eaa47f263005c6d1c2e142a76.zip Qt-5a7223450d0ebd4eaa47f263005c6d1c2e142a76.tar.gz Qt-5a7223450d0ebd4eaa47f263005c6d1c2e142a76.tar.bz2 |
Merge branch 'qt-4.7-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration into 4.7-integration
* 'qt-4.7-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration: (22 commits)
Fix compilation of qegl.cpp after the last merge
Fix a race condition with QtDBus blocking for replies.
QtDBus: Debug message update
Removed DEPLOYMENT from demos/spectrum/spectrum.pro
Install source for spectrum demo
Fixed path for copying launcher script for spectrum demo
My 4.6.3 changes.
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( ecee9d7244ce4f7e7acf723bcef535532780db5f )
Fixed an assert in QMenu
Backport multitouch bug fixes to 4.6
tst_bic: Add the Qt 4.5 and 4.6 baselines for x86-64
Call eglTerminate() when the last QEglContext is destroyed to free mem.
Removed double EINTR loop from nativeWrite and nativeRead.
Fixed qsslkey test deployment for Symbian and fixed compiler warnings.
Fixing the race condition in event dispatcher implementation on
changes-4.6.3 updated
Fixing the compile issue.
Fixing the compile issue.
Typo.
Removed nearest test from qaudiodeviceinfo unit test.
...
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian.cpp | 46 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian_p.h | 20 | ||||
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 46 | ||||
-rw-r--r-- | src/dbus/qdbuspendingcall.cpp | 35 | ||||
-rw-r--r-- | src/dbus/qdbuspendingcall_p.h | 35 | ||||
-rw-r--r-- | src/dbus/qdbuspendingreply.cpp | 3 | ||||
-rw-r--r-- | src/gui/egl/qegl.cpp | 37 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 3 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 23 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiodeviceinfo.cpp | 62 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput.cpp | 11 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel_p.h | 2 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_unix.cpp | 10 |
13 files changed, 266 insertions, 67 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 33775d2..1cb8455 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -100,25 +100,40 @@ static inline int qt_socket_select(int nfds, fd_set *readfds, fd_set *writefds, class QSelectMutexGrabber { public: - QSelectMutexGrabber(int fd, QMutex *mutex) - : m_mutex(mutex) + QSelectMutexGrabber(int fd, QMutex *threadMutex, QMutex *selectCallMutex) + : m_threadMutex(threadMutex), m_selectCallMutex(selectCallMutex), bHasThreadLock(false) { - if (m_mutex->tryLock()) + // see if selectThread is waiting m_waitCond + // if yes ... dont write to pipe + if (m_threadMutex->tryLock()) { + bHasThreadLock = true; return; + } + + // still check that SelectThread + // is in select call + if (m_selectCallMutex->tryLock()) { + m_selectCallMutex->unlock(); + return; + } char dummy = 0; qt_pipe_write(fd, &dummy, 1); - m_mutex->lock(); + m_threadMutex->lock(); + bHasThreadLock = true; } ~QSelectMutexGrabber() { - m_mutex->unlock(); + if(bHasThreadLock) + m_threadMutex->unlock(); } private: - QMutex *m_mutex; + QMutex *m_threadMutex; + QMutex *m_selectCallMutex; + bool bHasThreadLock; }; /* @@ -400,7 +415,12 @@ void QSelectThread::run() int ret; int savedSelectErrno; - ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0); + { + // helps fighting the race condition between + // selctthread and new socket requests (cancel, restart ...) + QMutexLocker locker(&m_selectCallMutex); + ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0); + } savedSelectErrno = errno; char buffer; @@ -495,7 +515,9 @@ void QSelectThread::requestSocketEvents ( QSocketNotifier *notifier, TRequestSta start(); } - QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex); + QMutexLocker locker(&m_grabberMutex); + + QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex, &m_selectCallMutex); Q_ASSERT(!m_AOStatuses.contains(notifier)); @@ -506,7 +528,9 @@ void QSelectThread::requestSocketEvents ( QSocketNotifier *notifier, TRequestSta void QSelectThread::cancelSocketEvents ( QSocketNotifier *notifier ) { - QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex); + QMutexLocker locker(&m_grabberMutex); + + QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex, &m_selectCallMutex); m_AOStatuses.remove(notifier); @@ -515,7 +539,9 @@ void QSelectThread::cancelSocketEvents ( QSocketNotifier *notifier ) void QSelectThread::restart() { - QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex); + QMutexLocker locker(&m_grabberMutex); + + QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex, &m_selectCallMutex); m_waitCond.wakeAll(); } diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index bc42753..211ded4 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -211,6 +211,26 @@ private: QMutex m_mutex; QWaitCondition m_waitCond; bool m_quit; + + // to protect when several + // requests like: + // requestSocketEvents + // cancelSocketEvents + // kick in the same time + // all will fight for m_mutex + // + // TODO: fix more elegantely + // + QMutex m_grabberMutex; + + // this one will tell + // if selectthread is + // really in select call + // and will prevent + // writing to pipe that + // causes later in locking + // of the thread in waitcond + QMutex m_selectCallMutex; }; class Q_CORE_EXPORT CQtActiveScheduler : public CActiveScheduler diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index b4598ae..efa6744 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -525,7 +525,7 @@ qDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message); - qDBusDebug() << d << "got message:" << amsg; + qDBusDebug() << d << "got message (signal):" << amsg; return d->handleMessage(amsg) ? DBUS_HANDLER_RESULT_HANDLED : @@ -1692,15 +1692,31 @@ static void qDBusResultReceived(DBusPendingCall *pending, void *user_data) void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall) { Q_ASSERT(pcall->pending); - QDBusDispatchLocker locker(PendingCallBlockAction, this); - q_dbus_pending_call_block(pcall->pending); - // QDBusConnectionPrivate::processFinishedCall() is called automatically + Q_ASSERT(!pcall->autoDelete); + //Q_ASSERT(pcall->mutex.isLocked()); // there's no such function + + if (pcall->waitingForFinished) { + // another thread is already waiting + pcall->waitForFinishedCondition.wait(&pcall->mutex); + } else { + pcall->waitingForFinished = true; + pcall->mutex.unlock(); + + { + QDBusDispatchLocker locker(PendingCallBlockAction, this); + q_dbus_pending_call_block(pcall->pending); + // QDBusConnectionPrivate::processFinishedCall() is called automatically + } + pcall->mutex.lock(); + } } void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) { QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection); + QMutexLocker locker(&call->mutex); + QDBusMessage &msg = call->replyMessage; if (call->pending) { // decode the message @@ -1730,6 +1746,12 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) qDBusDebug() << "Deliver failed!"; } + if (call->pending) + q_dbus_pending_call_unref(call->pending); + call->pending = 0; + + locker.unlock(); + // Are there any watchers? if (call->watcherHelper) call->watcherHelper->emitSignals(msg, call->sentMessage); @@ -1737,12 +1759,10 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) if (msg.type() == QDBusMessage::ErrorMessage) emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage); - if (call->pending) - q_dbus_pending_call_unref(call->pending); - call->pending = 0; - - if (call->autoDelete) + if (call->autoDelete) { + Q_ASSERT(!call->waitingForFinished); // can't wait on a call with autoDelete! delete call; + } } int QDBusConnectionPrivate::send(const QDBusMessage& message) @@ -1884,17 +1904,14 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM { if (isServiceRegisteredByThread(message.service())) { // special case for local calls - QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; - pcall->sentMessage = message; + QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this); pcall->replyMessage = sendWithReplyLocal(message); - pcall->connection = this; return pcall; } checkThread(); - QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; - pcall->sentMessage = message; + QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this); pcall->ref = 0; QDBusError error; @@ -1918,7 +1935,6 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM q_dbus_message_unref(msg); pcall->pending = pending; - pcall->connection = this; q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0); return pcall; diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index dac7a92..c2e94b3 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -210,6 +210,8 @@ void QDBusPendingCallPrivate::setMetaTypes(int count, const int *types) void QDBusPendingCallPrivate::checkReceivedSignature() { + // MUST BE CALLED WITH A LOCKED MUTEX! + if (replyMessage.type() == QDBusMessage::InvalidMessage) return; // not yet finished - no message to // validate against @@ -232,6 +234,8 @@ void QDBusPendingCallPrivate::checkReceivedSignature() void QDBusPendingCallPrivate::waitForFinished() { + QMutexLocker locker(&mutex); + if (replyMessage.type() != QDBusMessage::InvalidMessage) return; // already finished @@ -312,7 +316,11 @@ QDBusPendingCall &QDBusPendingCall::operator=(const QDBusPendingCall &other) bool QDBusPendingCall::isFinished() const { - return !d || (d->replyMessage.type() != QDBusMessage::InvalidMessage); + if (!d) + return true; // considered finished + + QMutexLocker locker(&d->mutex); + return d->replyMessage.type() != QDBusMessage::InvalidMessage; } void QDBusPendingCall::waitForFinished() @@ -331,7 +339,10 @@ void QDBusPendingCall::waitForFinished() */ bool QDBusPendingCall::isValid() const { - return d ? d->replyMessage.type() == QDBusMessage::ReplyMessage : false; + if (!d) + return false; + QMutexLocker locker(&d->mutex); + return d->replyMessage.type() == QDBusMessage::ReplyMessage; } /*! @@ -345,7 +356,10 @@ bool QDBusPendingCall::isValid() const */ bool QDBusPendingCall::isError() const { - return d ? d->replyMessage.type() == QDBusMessage::ErrorMessage : true; + if (!d) + return true; // considered finished and an error + QMutexLocker locker(&d->mutex); + return d->replyMessage.type() == QDBusMessage::ErrorMessage; } /*! @@ -358,8 +372,10 @@ bool QDBusPendingCall::isError() const */ QDBusError QDBusPendingCall::error() const { - if (d) + if (d) { + QMutexLocker locker(&d->mutex); return d->replyMessage; + } // not connected, return an error QDBusError err = QDBusError(QDBusError::Disconnected, @@ -380,7 +396,10 @@ QDBusError QDBusPendingCall::error() const */ QDBusMessage QDBusPendingCall::reply() const { - return d ? d->replyMessage : QDBusMessage::createError(error()); + if (!d) + return QDBusMessage::createError(error()); + QMutexLocker locker(&d->mutex); + return d->replyMessage; } #if 0 @@ -441,9 +460,8 @@ QDBusPendingCall QDBusPendingCall::fromCompletedCall(const QDBusMessage &msg) QDBusPendingCallPrivate *d = 0; if (msg.type() == QDBusMessage::ErrorMessage || msg.type() == QDBusMessage::ReplyMessage) { - d = new QDBusPendingCallPrivate; + d = new QDBusPendingCallPrivate(QDBusMessage(), 0); d->replyMessage = msg; - d->connection = 0; } return QDBusPendingCall(d); @@ -473,9 +491,10 @@ QDBusPendingCallWatcher::QDBusPendingCallWatcher(const QDBusPendingCall &call, Q : QObject(*new QDBusPendingCallWatcherPrivate, parent), QDBusPendingCall(call) { if (d) { // QDBusPendingCall::d + QMutexLocker locker(&d->mutex); if (!d->watcherHelper) { d->watcherHelper = new QDBusPendingCallWatcherHelper; - if (isFinished()) { + if (d->replyMessage.type() != QDBusMessage::InvalidMessage) { // cause a signal emission anyways QMetaObject::invokeMethod(d->watcherHelper, "finished", Qt::QueuedConnection); } diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h index f1f6dc2..8683552 100644 --- a/src/dbus/qdbuspendingcall_p.h +++ b/src/dbus/qdbuspendingcall_p.h @@ -57,6 +57,8 @@ #include <qshareddata.h> #include <qpointer.h> #include <qlist.h> +#include <qmutex.h> +#include <qwaitcondition.h> #include "qdbusmessage.h" #include "qdbus_symbols_p.h" @@ -73,24 +75,35 @@ class QDBusConnectionPrivate; class QDBusPendingCallPrivate: public QSharedData { public: - QDBusMessage sentMessage; - QDBusMessage replyMessage; -// QDBusMessage pendingReplyMessage; // used in the local loop - QDBusPendingCallWatcherHelper *watcherHelper; - DBusPendingCall *pending; - QDBusConnectionPrivate *connection; + // { + // set only during construction: + const QDBusMessage sentMessage; + QDBusConnectionPrivate * const connection; - QString expectedReplySignature; - int expectedReplyCount; - - // for the callback + // for the callback mechanism (see setReplyCallback and QDBusConnectionPrivate::sendWithReplyAsync) QPointer<QObject> receiver; QList<int> metaTypes; int methodIdx; bool autoDelete; + // } + + mutable QMutex mutex; + QWaitCondition waitForFinishedCondition; + + // { + // protected by the mutex above: + QDBusPendingCallWatcherHelper *watcherHelper; + QDBusMessage replyMessage; + DBusPendingCall *pending; + volatile bool waitingForFinished; + + QString expectedReplySignature; + int expectedReplyCount; + // } - QDBusPendingCallPrivate() : watcherHelper(0), pending(0), autoDelete(false) + QDBusPendingCallPrivate(const QDBusMessage &sent, QDBusConnectionPrivate *connection) + : sentMessage(sent), connection(connection), autoDelete(false), watcherHelper(0), pending(0), waitingForFinished(false) { } ~QDBusPendingCallPrivate(); bool setReplyCallback(QObject *target, const char *member); diff --git a/src/dbus/qdbuspendingreply.cpp b/src/dbus/qdbuspendingreply.cpp index 40cf6e3..891b348 100644 --- a/src/dbus/qdbuspendingreply.cpp +++ b/src/dbus/qdbuspendingreply.cpp @@ -254,7 +254,7 @@ void QDBusPendingReplyData::assign(const QDBusPendingCall &other) void QDBusPendingReplyData::assign(const QDBusMessage &message) { - d = new QDBusPendingCallPrivate; // drops the reference to the old one + d = new QDBusPendingCallPrivate(QDBusMessage(), 0); // drops the reference to the old one d->replyMessage = message; } @@ -273,6 +273,7 @@ QVariant QDBusPendingReplyData::argumentAt(int index) const void QDBusPendingReplyData::setMetaTypes(int count, const int *types) { Q_ASSERT(d); + QMutexLocker locker(&d->mutex); d->setMetaTypes(count, types); d->checkReceivedSignature(); } diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index bf9f530..671a568 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -42,6 +42,7 @@ #include <QtGui/qpaintdevice.h> #include <QtGui/qpixmap.h> #include <QtGui/qwidget.h> +#include <QtCore/qatomic.h> #include <QtCore/qdebug.h> #include "qegl_p.h" @@ -50,6 +51,34 @@ QT_BEGIN_NAMESPACE + +/* + QEglContextTracker is used to track the EGL contexts that we + create internally in Qt, so that we can call eglTerminate() to + free additional EGL resources when the last context is destroyed. +*/ + +class QEglContextTracker +{ +public: + static void ref() { contexts.ref(); } + static void deref() { + if (!contexts.deref()) { + eglTerminate(QEgl::display()); + displayOpen = 0; + } + } + static void setDisplayOpened() { displayOpen = 1; } + static bool displayOpened() { return displayOpen; } + +private: + static QAtomicInt contexts; + static QAtomicInt displayOpen; +}; + +QAtomicInt QEglContextTracker::contexts = 0; +QAtomicInt QEglContextTracker::displayOpen = 0; + // Current GL and VG contexts. These are used to determine if // we can avoid an eglMakeCurrent() after a call to lazyDoneCurrent(). // If a background thread modifies the value, the worst that will @@ -66,6 +95,7 @@ QEglContext::QEglContext() , ownsContext(true) , sharing(false) { + QEglContextTracker::ref(); } QEglContext::~QEglContext() @@ -76,6 +106,7 @@ QEglContext::~QEglContext() currentGLContext = 0; if (currentVGContext == this) currentVGContext = 0; + QEglContextTracker::deref(); } bool QEglContext::isValid() const @@ -505,11 +536,9 @@ static _eglDestroyImageKHR qt_eglDestroyImageKHR = 0; EGLDisplay QEgl::display() { static EGLDisplay dpy = EGL_NO_DISPLAY; - static bool openedDisplay = false; - - if (!openedDisplay) { + if (!QEglContextTracker::displayOpened()) { dpy = eglGetDisplay(nativeDisplay()); - openedDisplay = true; + QEglContextTracker::setDisplayOpened(); if (dpy == EGL_NO_DISPLAY) { qWarning("QEgl::display(): Falling back to EGL_DEFAULT_DISPLAY"); dpy = eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY)); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 01abe54..e30b6be 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -581,7 +581,8 @@ public: void _q_readRX71MultiTouchEvents(); #endif -#if defined(Q_WS_S60) +#if defined(Q_OS_SYMBIAN) + int pressureSupported; int maxTouchPressure; QList<QTouchEvent::TouchPoint> appAllTouchPoints; #endif diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index fa07b1a..dc8d8f7 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -408,15 +408,22 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event) { QApplicationPrivate *d = QApplicationPrivate::instance(); + qreal pressure; + if(d->pressureSupported + && event->Pressure() > 0) //workaround for misconfigured HAL + pressure = event->Pressure() / qreal(d->maxTouchPressure); + else + pressure = qreal(1.0); QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget); - while (d->appAllTouchPoints.count() <= event->PointerNumber()) - d->appAllTouchPoints.append(QTouchEvent::TouchPoint(d->appAllTouchPoints.count())); + QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints; + while (points.count() <= event->PointerNumber()) + points.append(QTouchEvent::TouchPoint(points.count())); Qt::TouchPointStates allStates = 0; - for (int i = 0; i < d->appAllTouchPoints.count(); ++i) { - QTouchEvent::TouchPoint &touchPoint = d->appAllTouchPoints[i]; + for (int i = 0; i < points.count(); ++i) { + QTouchEvent::TouchPoint &touchPoint = points[i]; if (touchPoint.id() == event->PointerNumber()) { Qt::TouchPointStates state; @@ -446,7 +453,7 @@ void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), screenPos.y() / screenGeometry.height())); - touchPoint.setPressure(event->Pressure() / qreal(d->maxTouchPressure)); + touchPoint.setPressure(pressure); } else if (touchPoint.state() != Qt::TouchPointReleased) { // all other active touch points should be marked as stationary touchPoint.setState(Qt::TouchPointStationary); @@ -458,11 +465,13 @@ void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) { // all touch points released d->appAllTouchPoints.clear(); + } else { + d->appAllTouchPoints = points; } QApplicationPrivate::translateRawTouchEvent(qwidget, QTouchEvent::TouchScreen, - d->appAllTouchPoints); + points); } #endif @@ -1983,6 +1992,8 @@ TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) void QApplicationPrivate::initializeMultitouch_sys() { #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER + if (HAL::Get(HALData::EPointer3DPressureSupported, pressureSupported) != KErrNone) + pressureSupported = 0; if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone) maxTouchPressure = KMaxTInt; #endif diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp index ff04b4e..201a03d 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo.cpp @@ -43,6 +43,7 @@ #include <QtMultimedia/qaudioengine.h> #include <QtMultimedia/qaudiodeviceinfo.h> +#include <QtCore/qmap.h> QT_BEGIN_NAMESPACE @@ -238,7 +239,66 @@ QAudioFormat QAudioDeviceInfo::preferredFormat() const QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const { - return isNull() ? QAudioFormat() : d->info->nearestFormat(settings); + if (isFormatSupported(settings)) + return settings; + + QAudioFormat nearest = settings; + + nearest.setCodec(QLatin1String("audio/pcm")); + + if (nearest.sampleType() == QAudioFormat::Unknown) { + QAudioFormat preferred = preferredFormat(); + nearest.setSampleType(preferred.sampleType()); + } + + QMap<int,int> testFrequencies; + QList<int> frequenciesAvailable = supportedFrequencies(); + QMap<int,int> testSampleSizes; + QList<int> sampleSizesAvailable = supportedSampleSizes(); + + // Get sorted sampleSizes (equal to and ascending values only) + if (sampleSizesAvailable.contains(settings.sampleSize())) + testSampleSizes.insert(0,settings.sampleSize()); + sampleSizesAvailable.removeAll(settings.sampleSize()); + foreach (int size, sampleSizesAvailable) { + int larger = (size > settings.sampleSize()) ? size : settings.sampleSize(); + int smaller = (size > settings.sampleSize()) ? settings.sampleSize() : size; + if (size >= settings.sampleSize()) { + int diff = larger - smaller; + testSampleSizes.insert(diff, size); + } + } + + // Get sorted frequencies (equal to and ascending values only) + if (frequenciesAvailable.contains(settings.frequency())) + testFrequencies.insert(0,settings.frequency()); + frequenciesAvailable.removeAll(settings.frequency()); + foreach (int frequency, frequenciesAvailable) { + int larger = (frequency > settings.frequency()) ? frequency : settings.frequency(); + int smaller = (frequency > settings.frequency()) ? settings.frequency() : frequency; + if (frequency >= settings.frequency()) { + int diff = larger - smaller; + testFrequencies.insert(diff, frequency); + } + } + + // Try to find nearest + // Check ascending frequencies, ascending sampleSizes + QMapIterator<int, int> sz(testSampleSizes); + while (sz.hasNext()) { + sz.next(); + nearest.setSampleSize(sz.value()); + QMapIterator<int, int> i(testFrequencies); + while (i.hasNext()) { + i.next(); + nearest.setFrequency(i.value()); + if (isFormatSupported(nearest)) + return nearest; + } + } + + //Fallback + return preferredFormat(); } /*! diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index 371773c..cf3b79c 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -369,8 +369,17 @@ int QAudioOutput::notifyInterval() const } /*! - Returns the amount of audio data processed since start() + Returns the amount of audio data processed by the class since start() was called in microseconds. + + Note: The amount of audio data played can be determined by subtracting + the microseconds of audio data still in the systems audio buffer. + + \code + qint64 bytesInBuffer = bufferSize() - bytesFree(); + qint64 usInBuffer = (qint64)(1000000) * bytesInBuffer / ( channels() * sampleSize() / 8 ) / frequency(); + qint64 usPlayed = processedUSecs() - usInBuffer; + \endcode */ qint64 QAudioOutput::processedUSecs() const diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 51cb5e8..41a896d 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -65,7 +65,7 @@ #include <private/qhttpnetworkrequest_p.h> #include <private/qhttpnetworkreply_p.h> -#include "qhttpnetworkconnection_p.h" +#include <private/qhttpnetworkconnection_p.h> #ifndef QT_NO_HTTP diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 70bb0da..f91ce5f 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -851,11 +851,7 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) // Symbian does not support signals natively and Open C returns EINTR when moving to offline writtenBytes = ::write(socketDescriptor, data, len); #else - // loop while ::write() returns -1 and errno == EINTR, in case - // of an interrupting signal. - do { - writtenBytes = qt_safe_write(socketDescriptor, data, len); - } while (writtenBytes < 0 && errno == EINTR); + writtenBytes = qt_safe_write(socketDescriptor, data, len); #endif if (writtenBytes < 0) { @@ -899,9 +895,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize) #ifdef Q_OS_SYMBIAN r = ::read(socketDescriptor, data, maxSize); #else - do { - r = qt_safe_read(socketDescriptor, data, maxSize); - } while (r == -1 && errno == EINTR); + r = qt_safe_read(socketDescriptor, data, maxSize); #endif if (r < 0) { |