diff options
author | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-09-13 08:54:45 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-09-13 08:54:45 +0200 |
commit | b62bd0584a7872b6917917009b707785b3abd077 (patch) | |
tree | 9981f274712c098cabbff0c4667672a3934e5393 /src/widgets/platforms/x11/qsound_x11.cpp | |
parent | 5e10745dca1d10025404a9f268f03ae697fb10cc (diff) | |
parent | 97baad65f65783d2b5ff938f6217aec9434f2e5f (diff) |
Merge branch 'refactor'
Conflicts:
mkspecs/qws/linux-lsb-g++/qmake.conf
src/gui/image/qpixmap_mac.cpp
src/gui/painting/qpaintengine_x11.cpp
src/gui/painting/qtessellator.cpp
src/gui/text/qfontengine_qws.cpp
src/gui/text/qfontengine_x11.cpp
src/gui/widgets/qlinecontrol.cpp
src/opengl/qgl.h
src/opengl/qgl_x11egl.cpp
src/plugins/plugins.pro
Change-Id: If52dcd55cd55f2983a756c2f843967702b60a310
Diffstat (limited to 'src/widgets/platforms/x11/qsound_x11.cpp')
-rw-r--r-- | src/widgets/platforms/x11/qsound_x11.cpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/src/widgets/platforms/x11/qsound_x11.cpp b/src/widgets/platforms/x11/qsound_x11.cpp new file mode 100644 index 0000000000..c83c26a027 --- /dev/null +++ b/src/widgets/platforms/x11/qsound_x11.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $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 |