diff -r 000000000000 -r 1918ee327afb src/gui/kernel/qsound_qws.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gui/kernel/qsound_qws.cpp Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qapplication.h" + +#ifndef QT_NO_SOUND + +#include "qsound.h" +#include "qpaintdevice.h" +#include "qwsdisplay_qws.h" +#include "qsound_p.h" + +#include "qsoundqss_qws.h" + +#include "qhash.h" +#include "qfileinfo.h" + +#include "qbytearray.h" +#include "quuid.h" +#include "qdatastream.h" +#include "qcopchannel_qws.h" +#include "qbuffer.h" + + +QT_BEGIN_NAMESPACE + +#ifdef MEDIA_SERVER + +#define SERVER_CHANNEL "QPE/MediaServer" + +class QCopMessage : public QDataStream +{ +public: + QCopMessage( const QString& channel, const QString& message ) + : QDataStream( new QBuffer ), m_channel( channel ), m_message( message ) + { + device()->open( QIODevice::WriteOnly ); + } + + ~QCopMessage() + { + QCopChannel::send( m_channel, m_message, ((QBuffer*)device())->buffer() ); + delete device(); + } + +private: + QString m_channel; + QString m_message; +}; + +#endif // MEDIA_SERVER + +class QAuServerQWS; + +class QAuBucketQWS : public QObject, public QAuBucket +{ + Q_OBJECT +public: + QAuBucketQWS( QAuServerQWS*, QSound*, QObject* parent = 0 ); + + ~QAuBucketQWS(); + +#ifndef MEDIA_SERVER + int id() const { return id_; } +#endif + + QSound* sound() const { return sound_; } + +#ifdef MEDIA_SERVER + void play(); + + void stop(); +#endif + +signals: + // Only for Media Server + void done( QAuBucketQWS* ); + +private slots: + // Only for Media Server + void processMessage( const QString& msg, const QByteArray& data ); + +private: +#ifdef MEDIA_SERVER + QCopChannel *m_channel; + QUuid m_id; +#endif + +#ifndef MEDIA_SERVER + int id_; +#endif + QSound *sound_; + QAuServerQWS *server_; + + static int next; +}; + +int QAuBucketQWS::next = 0; + +class QAuServerQWS : public QAuServer +{ + Q_OBJECT +public: + QAuServerQWS( QObject* parent ); + + void init( QSound* s ) + { + QAuBucketQWS *bucket = new QAuBucketQWS( this, s ); +#ifdef MEDIA_SERVER + connect( bucket, SIGNAL(done(QAuBucketQWS*)), + this, SLOT(complete(QAuBucketQWS*)) ); +#endif + setBucket( s, bucket ); + } + +#ifndef MEDIA_SERVER + // Register bucket + void insert( QAuBucketQWS *bucket ) + { + buckets.insert( bucket->id(), bucket ); + } + + // Remove bucket from register + void remove( QAuBucketQWS *bucket ) + { + buckets.remove( bucket->id() ); + } +#endif + + void play( QSound* s ) + { + QString filepath = QFileInfo( s->fileName() ).absoluteFilePath(); +#if defined(QT_NO_QWS_SOUNDSERVER) + server->playFile( bucket( s )->id(), filepath ); +#elif defined(MEDIA_SERVER) + bucket( s )->play(); +#else + client->play( bucket( s )->id(), filepath ); +#endif + } + + void stop( QSound* s ) + { +#if defined(QT_NO_QWS_SOUNDSERVER) + server->stopFile( bucket( s )->id() ); +#elif defined(MEDIA_SERVER) + bucket( s )->stop(); +#else + client->stop( bucket( s )->id() ); +#endif + } + + bool okay() { return true; } + +private slots: + // Continue playing sound if loops remain + void complete( int id ) + { +#ifndef MEDIA_SERVER + QAuBucketQWS *bucket = find( id ); + if( bucket ) { + QSound *sound = bucket->sound(); + if( decLoop( sound ) ) { + play( sound ); + } + } +#else + Q_UNUSED(id); +#endif + } + + // Only for Media Server + void complete( QAuBucketQWS* bucket ) + { +#ifndef MEDIA_SERVER + Q_UNUSED(bucket); +#else + QSound *sound = bucket->sound(); + if( decLoop( sound ) ) { + play( sound ); + } +#endif + } + +protected: + QAuBucketQWS* bucket( QSound *s ) + { + return (QAuBucketQWS*)QAuServer::bucket( s ); + } + +private: +#ifndef MEDIA_SERVER + // Find registered bucket with given id, return null if none found + QAuBucketQWS* find( int id ) + { + QHash::Iterator it = buckets.find( id ); + if( it != buckets.end() ) { + return it.value(); + } + + return 0; + } + + QHash buckets; // ### possible problem with overlapping keys + +#ifdef QT_NO_QWS_SOUNDSERVER + QWSSoundServer *server; +#else + QWSSoundClient *client; +#endif + +#endif // MEDIA_SERVER +}; + +QAuServerQWS::QAuServerQWS(QObject* parent) : + QAuServer(parent) +{ +#ifndef MEDIA_SERVER + setObjectName(QLatin1String("qauserverqws")); + +#ifdef QT_NO_QWS_SOUNDSERVER + server = new QWSSoundServer( this ); // ### only suitable for single application + + connect( server, SIGNAL(soundCompleted(int)), + this, SLOT(complete(int)) ); +#else + client = new QWSSoundClient( this ); // ### requires successful connection + + connect( client, SIGNAL(soundCompleted(int)), + this, SLOT(complete(int)) ); +#endif + +#endif // MEDIA_SERVER +} + +QAuBucketQWS::QAuBucketQWS( QAuServerQWS *server, QSound *sound, QObject* parent ) + : QObject( parent ), sound_( sound ), server_( server ) +{ +#ifdef MEDIA_SERVER + m_id = QUuid::createUuid(); + + sound->setObjectName( m_id.toString() ); + + m_channel = new QCopChannel(QLatin1String("QPE/QSound/") + m_id, this ); + connect( m_channel, SIGNAL(received(QString,QByteArray)), + this, SLOT(processMessage(QString,QByteArray)) ); + + { + QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("subscribe(QUuid)") ); + message << m_id; + } + + { + QString filepath = QFileInfo( sound_->fileName() ).absoluteFilePath(); + QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("open(QUuid,QString)") ); + message << m_id << filepath; + } +#else + id_ = next++; + server_->insert( this ); +#endif +} + +#ifdef MEDIA_SERVER +void QAuBucketQWS::play() +{ + QString filepath = QFileInfo( sound_->fileName() ).absoluteFilePath(); + + QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("play(QUuid)") ); + message << m_id; +} + +void QAuBucketQWS::stop() +{ + QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("stop(QUuid)") ); + message << m_id; +} +#endif // MEDIA_SERVER + +void QAuBucketQWS::processMessage( const QString& msg, const QByteArray& data ) +{ + Q_UNUSED(data); +#ifndef MEDIA_SERVER + Q_UNUSED(msg); +#else + if( msg == QLatin1String("done()") ) { + emit done( this ); + } +#endif +} + +QAuBucketQWS::~QAuBucketQWS() +{ +#ifdef MEDIA_SERVER + QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("revoke(QUuid)") ); + message << m_id; +#else + server_->remove( this ); +#endif +} + + +QAuServer* qt_new_audio_server() +{ + return new QAuServerQWS(qApp); +} + +#include "qsound_qws.moc" + +#endif // QT_NO_SOUND + +QT_END_NAMESPACE