diff options
author | Shane Kearns <shane.kearns@sosco.com> | 2009-11-24 18:54:02 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@sosco.com> | 2009-11-25 09:03:15 (GMT) |
commit | 339a11182a3e64c9cfbd8082622b5920c90c99c5 (patch) | |
tree | 374c7c709db9a2cafde257b8fe434502d6f958e8 /src/gui/kernel | |
parent | 6bf1037df75d8d6f697f9f49d8d7fbe9b2cabc98 (diff) | |
download | Qt-339a11182a3e64c9cfbd8082622b5920c90c99c5.zip Qt-339a11182a3e64c9cfbd8082622b5920c90c99c5.tar.gz Qt-339a11182a3e64c9cfbd8082622b5920c90c99c5.tar.bz2 |
Fix crash in QApplication::beep() on S60
Using an asynchronous API synchronously caused a crash, because the
data structure was deleted while an async request is still pending.
Depending on the multimedia implementation on the phone, the crash will
happen or you just get no sound (or it can even work if the underlying
implementation is blocking).
Solution is to use the API asynchronously, and delete the handling object
in qt_cleanup.
Also raised the tone by one octave to be more similar to the system beep.
Task-number: QTBUG-6170
Reviewed-by: Janne Anttila
Reviewed-by: Miikka Heikkinen
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index fb2bc72..89d961c 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -133,36 +133,46 @@ private: TTimeIntervalMicroSeconds iDuration; }; +static QS60Beep* qt_S60Beep = 0; + QS60Beep::~QS60Beep() { + if (iToneUtil) { + switch (iState) { + case EBeepPlaying: + iToneUtil->CancelPlay(); + break; + case EBeepNotPrepared: + iToneUtil->CancelPrepare(); + break; + } + } delete iToneUtil; } QS60Beep* QS60Beep::NewL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - QS60Beep* self=new (ELeave) QS60Beep(); + QS60Beep* self = new (ELeave) QS60Beep(); CleanupStack::PushL(self); self->ConstructL(aFrequency, aDuration); CleanupStack::Pop(); return self; -}; +} void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - iToneUtil=CMdaAudioToneUtility::NewL(*this); - iState=EBeepNotPrepared; - iFrequency=aFrequency; - iDuration=aDuration; - iToneUtil->PrepareToPlayTone(iFrequency,iDuration); + iToneUtil = CMdaAudioToneUtility::NewL(*this); + iState = EBeepNotPrepared; + iFrequency = aFrequency; + iDuration = aDuration; + iToneUtil->PrepareToPlayTone(iFrequency, iDuration); } void QS60Beep::Play() { - if (iState != EBeepNotPrepared) { - if (iState == EBeepPlaying) { - iToneUtil->CancelPlay(); - iState = EBeepPrepared; - } + if (iState == EBeepPlaying) { + iToneUtil->CancelPlay(); + iState = EBeepPrepared; } iToneUtil->Play(); @@ -173,13 +183,14 @@ void QS60Beep::MatoPrepareComplete(TInt aError) { if (aError == KErrNone) { iState = EBeepPrepared; + Play(); } } void QS60Beep::MatoPlayComplete(TInt aError) { Q_UNUSED(aError); - iState=EBeepPrepared; + iState = EBeepPrepared; } @@ -1226,6 +1237,10 @@ void qt_init(QApplicationPrivate * /* priv */, int) *****************************************************************************/ void qt_cleanup() { + if(qt_S60Beep) { + delete qt_S60Beep; + qt_S60Beep = 0; + } QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles // S60 structure and window server session are freed in eventdispatcher destructor as they are needed there @@ -1467,14 +1482,13 @@ void QApplication::setCursorFlashTime(int msecs) void QApplication::beep() { - TInt frequency=440; - TTimeIntervalMicroSeconds duration(500000); - QS60Beep* beep=NULL; - TRAPD(err, beep=QS60Beep::NewL(frequency, duration)); - if (!err) - beep->Play(); - delete beep; - beep=NULL; + if (!qt_S60Beep) { + TInt frequency = 880; + TTimeIntervalMicroSeconds duration(500000); + TRAP_IGNORE(qt_S60Beep=QS60Beep::NewL(frequency, duration)); + } + if (qt_S60Beep) + qt_S60Beep->Play(); } /*! |