diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 10:18:55 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 10:18:55 +0100 |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/gui/kernel/qsound_x11.cpp | |
download | qt4-tools-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz |
Long live Qt 4.5!
Diffstat (limited to 'src/gui/kernel/qsound_x11.cpp')
-rw-r--r-- | src/gui/kernel/qsound_x11.cpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/src/gui/kernel/qsound_x11.cpp b/src/gui/kernel/qsound_x11.cpp new file mode 100644 index 0000000000..f2aeea8291 --- /dev/null +++ b/src/gui/kernel/qsound_x11.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 "qsound.h" + +#ifndef QT_NO_SOUND + +#include "qhash.h" +#include "qsocketnotifier.h" +#include "qapplication.h" +#include "qsound_p.h" + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_NAS + +QT_BEGIN_INCLUDE_NAMESPACE +#include <audio/audiolib.h> +#include <audio/soundlib.h> +QT_END_INCLUDE_NAMESPACE + +static AuServer *nas=0; + +static AuBool eventPred(AuServer *, AuEvent *e, AuPointer p) +{ + if (e && (e->type == AuEventTypeElementNotify)) { + if (e->auelementnotify.flow == *((AuFlowID *)p)) + return true; + } + return false; +} + +class QAuBucketNAS : public QAuBucket { +public: + QAuBucketNAS(AuBucketID b, AuFlowID f = 0) : id(b), flow(f), stopped(true), numplaying(0) { } + ~QAuBucketNAS() + { + if (nas) { + AuSync(nas, false); + AuDestroyBucket(nas, id, NULL); + + AuEvent ev; + while (AuScanEvents(nas, AuEventsQueuedAfterFlush, true, eventPred, &flow, &ev)) + ; + } + } + + AuBucketID id; + AuFlowID flow; + bool stopped; + int numplaying; +}; + +class QAuServerNAS : public QAuServer { + Q_OBJECT + + QSocketNotifier* sn; + +public: + QAuServerNAS(QObject* parent); + ~QAuServerNAS(); + + void init(QSound*); + void play(const QString& filename); + void play(QSound*); + void stop(QSound*); + bool okay(); + void setDone(QSound*); + +public slots: + void dataReceived(); + void soundDestroyed(QObject *o); + +private: + QAuBucketNAS* bucket(QSound* s) + { + return (QAuBucketNAS*)QAuServer::bucket(s); + } +}; + +QAuServerNAS::QAuServerNAS(QObject* parent) : + QAuServer(parent) +{ + setObjectName(QLatin1String("Network Audio System")); + nas = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL); + if (nas) { + AuSetCloseDownMode(nas, AuCloseDownDestroy, NULL); + // Ask Qt for async messages... + sn=new QSocketNotifier(AuServerConnectionNumber(nas), + QSocketNotifier::Read); + QObject::connect(sn, SIGNAL(activated(int)), + this, SLOT(dataReceived())); + } else { + sn = 0; + } +} + +QAuServerNAS::~QAuServerNAS() +{ + if (nas) + AuCloseServer(nas); + delete sn; + nas = 0; +} + +typedef QHash<void*,QAuServerNAS*> AuServerHash; +static AuServerHash *inprogress=0; + +void QAuServerNAS::soundDestroyed(QObject *o) +{ + if (inprogress) { + QSound *so = static_cast<QSound *>(o); + while (inprogress->remove(so)) + ; // Loop while remove returns true + } +} + +void QAuServerNAS::play(const QString& filename) +{ + if (nas) { + int iv=100; + AuFixedPoint volume=AuFixedPointFromFraction(iv,100); + AuSoundPlayFromFile(nas, filename.toLocal8Bit().constData(), AuNone, volume, + NULL, NULL, NULL, NULL, NULL, NULL); + AuFlush(nas); + dataReceived(); + AuFlush(nas); + qApp->flush(); + } +} + +static void callback(AuServer*, AuEventHandlerRec*, AuEvent* e, AuPointer p) +{ + if (inprogress->contains(p) && e) { + if (e->type==AuEventTypeElementNotify && + e->auelementnotify.kind==AuElementNotifyKindState) { + if (e->auelementnotify.cur_state == AuStateStop) { + AuServerHash::Iterator it = inprogress->find(p); + if (it != inprogress->end()) + (*it)->setDone((QSound*)p); + } + } + } +} + +void QAuServerNAS::setDone(QSound* s) +{ + if (nas) { + decLoop(s); + if (s->loopsRemaining() && !bucket(s)->stopped) { + bucket(s)->stopped = true; + play(s); + } else { + if (--(bucket(s)->numplaying) == 0) + bucket(s)->stopped = true; + inprogress->remove(s); + } + } +} + +void QAuServerNAS::play(QSound* s) +{ + if (nas) { + ++(bucket(s)->numplaying); + if (!bucket(s)->stopped) { + stop(s); + } + + bucket(s)->stopped = false; + if (!inprogress) + inprogress = new AuServerHash; + inprogress->insert(s,this); + int iv=100; + AuFixedPoint volume=AuFixedPointFromFraction(iv,100); + QAuBucketNAS *b = bucket(s); + AuSoundPlayFromBucket(nas, b->id, AuNone, volume, + callback, s, 0, &b->flow, NULL, NULL, NULL); + AuFlush(nas); + dataReceived(); + AuFlush(nas); + qApp->flush(); + } +} + +void QAuServerNAS::stop(QSound* s) +{ + if (nas && !bucket(s)->stopped) { + bucket(s)->stopped = true; + AuStopFlow(nas, bucket(s)->flow, NULL); + AuFlush(nas); + dataReceived(); + AuFlush(nas); + qApp->flush(); + } +} + +void QAuServerNAS::init(QSound* s) +{ + connect(s, SIGNAL(destroyed(QObject*)), + this, SLOT(soundDestroyed(QObject*))); + + if (nas) { + AuBucketID b_id = + AuSoundCreateBucketFromFile(nas, s->fileName().toLocal8Bit().constData(), + 0 /*AuAccessAllMasks*/, NULL, NULL); + setBucket(s, new QAuBucketNAS(b_id)); + } +} + +bool QAuServerNAS::okay() +{ + return !!nas; +} + +void QAuServerNAS::dataReceived() +{ + AuHandleEvents(nas); +} + +QT_BEGIN_INCLUDE_NAMESPACE +#include "qsound_x11.moc" +QT_END_INCLUDE_NAMESPACE + +#endif + + +class QAuServerNull : public QAuServer +{ +public: + QAuServerNull(QObject* parent); + + void play(const QString&) { } + void play(QSound*s) { while(decLoop(s) > 0) /* nothing */ ; } + void stop(QSound*) { } + bool okay() { return false; } +}; + +QAuServerNull::QAuServerNull(QObject* parent) + : QAuServer(parent) +{ +} + + +QAuServer* qt_new_audio_server() +{ +#ifndef QT_NO_NAS + QAuServer* s = new QAuServerNAS(qApp); + if (s->okay()) + return s; + else + delete s; +#endif + return new QAuServerNull(qApp); +} + +QT_END_NAMESPACE + +#endif // QT_NO_SOUND |