summaryrefslogtreecommitdiffstats
path: root/kdemm
diff options
context:
space:
mode:
Diffstat (limited to 'kdemm')
-rw-r--r--kdemm/0.pngbin0 -> 21253 bytes
-rw-r--r--kdemm/DESIGN31
-rw-r--r--kdemm/Makefile.am43
-rw-r--r--kdemm/TODO27
-rw-r--r--kdemm/backend.cpp78
-rw-r--r--kdemm/backend.h86
-rw-r--r--kdemm/channel.cpp69
-rw-r--r--kdemm/channel.h96
-rw-r--r--kdemm/factory.cpp296
-rw-r--r--kdemm/factory.h222
-rw-r--r--kdemm/mixeriface.h41
-rw-r--r--kdemm/mmbackendinfo.desktop30
-rw-r--r--kdemm/player.cpp53
-rw-r--r--kdemm/player.h259
-rw-r--r--kdemm/reqspec.html533
-rw-r--r--kdemm/simpleplayer.cpp198
-rw-r--r--kdemm/simpleplayer.h72
-rw-r--r--kdemm/test/Makefile.am30
-rw-r--r--kdemm/test/main.cpp38
-rw-r--r--kdemm/test/statetest.cpp299
-rw-r--r--kdemm/test/statetest.h57
-rw-r--r--kdemm/test/testwidget.cpp194
-rw-r--r--kdemm/test/testwidget.h64
-rw-r--r--kdemm/videoplayer.cpp34
-rw-r--r--kdemm/videoplayer.h54
-rw-r--r--kdemm/volumecontrold/Makefile.am31
-rw-r--r--kdemm/volumecontrold/volumecontrold.cpp47
-rw-r--r--kdemm/volumecontrold/volumecontrold.desktop13
-rw-r--r--kdemm/volumecontrold/volumecontrold.h53
29 files changed, 3048 insertions, 0 deletions
diff --git a/kdemm/0.png b/kdemm/0.png
new file mode 100644
index 000000000..0c65b5cc8
--- /dev/null
+++ b/kdemm/0.png
Binary files differ
diff --git a/kdemm/DESIGN b/kdemm/DESIGN
new file mode 100644
index 000000000..524f64faa
--- /dev/null
+++ b/kdemm/DESIGN
@@ -0,0 +1,31 @@
+There should be at least two libs:
+1. kdemm(core)
+==============
+
+Provides the wrapper for the media framework and all needed media functionality.
+Whether this lib needs to depend on kdeui? Depends on how we could handle video
+without UI... but if possible we should put the video-widget in kdemmwidgets.
+
+The Requirements & Specification document can be found in reqspec.html
+
+
+2. kdemmwidgets
+===============
+
+Provides convenience widgets for the common widgets that are needed:
+- Position slider (display position and move it to seek)
+- Volume fader
+- Effects dialog (including EQ)
+- Video widget
+- Player controls as toolbar
+
+
+Also there could be a KPart:
+3. kdemmpart
+============
+
+A KPart implementing the KMediaPlayer interface.
+
+
+
+// vim: tw=80
diff --git a/kdemm/Makefile.am b/kdemm/Makefile.am
new file mode 100644
index 000000000..9bab914ef
--- /dev/null
+++ b/kdemm/Makefile.am
@@ -0,0 +1,43 @@
+# This file is part of the KDE libraries
+# Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License version 2 as published by the Free Software Foundation.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+INCLUDES = -I$(top_srcdir)/kdecore -I$(top_srcdir)/kio $(all_includes)
+
+SUBDIRS = . test
+
+lib_LTLIBRARIES = libkdemm.la
+
+kdemmincludedir = $(includedir)/kdemm
+kdemminclude_HEADERS = backend.h factory.h player.h channel.h videoplayer.h mixeriface.h simpleplayer.h
+
+libkdemm_la_SOURCES = backend.cpp factory.cpp player.cpp channel.cpp videoplayer.cpp mixeriface.skel simpleplayer.cpp factory.skel
+
+libkdemm_la_LDFLAGS = $(QT_LDFLAGS) $(KDE_RPATH) $(KDE_MT_LDFLAGS) $(USER_LDFLAGS) -version-info 0:0:0 -no-undefined
+libkdemm_la_LIBADD = ../kdecore/libkdecore.la ../kio/libkio.la
+
+factory_DCOPIDLNG = true
+
+METASOURCES = AUTO
+
+kde_servicetypes_DATA = mmbackendinfo.desktop
+
+SRCDOC_DEST=$(kde_htmldir)/en/kdelibs/kdemm
+
+DOXYGEN_REFERENCES = dcop kdecore kio
+
+include ../admin/Doxyfile.am
+
diff --git a/kdemm/TODO b/kdemm/TODO
new file mode 100644
index 000000000..457bc6f0a
--- /dev/null
+++ b/kdemm/TODO
@@ -0,0 +1,27 @@
+Factory
+- get a list of available backends
+- be able to choose the one you want to use, overriding the KTrader information
+- test on the fly switching
+
+Audio
+- function to retrieve the PCM data that currently is played (could be done in
+ the Channel as well as in the Player)
+
+Video
+- either a new interface or somehow integrate into the player
+ If it's a new interface we have to copy most of the Player class, which I
+ wouldn't like to see.
+
+two wrapper APIs:
+- for notifications
+ play file and don't care
+ automatically use the notification channel if present
+- for simple players
+ open file and provide seek and volume
+
+Mixer abstraction
+- provide access to the hardware mixer and/or the mixer of the backend
+- provide access to software volume controls (like the Channels)
+
+Record Interface
+- simple PCM recording API
diff --git a/kdemm/backend.cpp b/kdemm/backend.cpp
new file mode 100644
index 000000000..715fc52de
--- /dev/null
+++ b/kdemm/backend.cpp
@@ -0,0 +1,78 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "backend.h"
+#include "player.h"
+
+#include <tqstringlist.h>
+
+#include <kglobal.h>
+#include <kinstance.h>
+#include <kaboutdata.h>
+
+namespace KDE
+{
+namespace Multimedia
+{
+
+class Backend::Private
+{
+ public:
+ Channel * channel;
+};
+
+Backend::Backend( TQObject * parent, const char * name )
+ : TQObject( parent, name )
+ , d( 0 )
+{
+}
+
+Backend::~Backend()
+{
+ delete d;
+}
+
+bool Backend::playSoundEvent( const KURL & url )
+{
+ if( ! d )
+ {
+ d = new Private;
+
+ TQString ctype = "notifications";
+ if( availableChannels( Channel::Output ).contains( ctype ) < 1 )
+ ctype = "default";
+ d->channel = createChannel( KGlobal::instance()->aboutData()->programName(), ctype, Channel::Output );
+ }
+
+ Player * player = createPlayer();
+ player->setOutputChannel( d->channel );
+ connect( player, TQT_SIGNAL( finished() ), player, TQT_SLOT( deleteLater() ) );
+
+ if( player->load( url ) )
+ if( player->play() )
+ return true;
+ delete player;
+ return false;
+}
+
+}} // namespaces
+
+#include "backend.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/backend.h b/kdemm/backend.h
new file mode 100644
index 000000000..2f626c4f4
--- /dev/null
+++ b/kdemm/backend.h
@@ -0,0 +1,86 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef BACKEND_H
+#define BACKEND_H
+
+#include <tqobject.h>
+#include <kdemacros.h>
+#include <kdemm/channel.h>
+#include <kurl.h>
+
+namespace KDE
+{
+namespace Multimedia
+{
+ class Player;
+ class VideoPlayer;
+ /**
+ * \brief Base class for all KDE Multimedia Backends
+ *
+ * This class provides the interface for Multimedia Backends. Use it to get
+ * a pointer to a new Player or VideoWidget. There are some reserved
+ * functions for later extension of the class.
+ *
+ * \author Matthias Kretz <kretz@kde.org>
+ * \since 4.0
+ */
+ class Backend : public QObject
+ {
+ Q_OBJECT
+ public:
+ /**
+ * default TQObject constructor
+ */
+ Backend( TQObject * parent = 0, const char * name = 0 );
+ virtual ~Backend();
+
+ /**
+ * @return A new instance to a Player from the Backend.
+ */
+ virtual Player * createPlayer() = 0;
+
+ /**
+ * Create a new VideoPlayer object. The Backend does not have to
+ * implement this function.
+ *
+ * @return A new instance to a VideoPlayer from the Backend. Or 0 if
+ * the Backend does not support the VideoPlayer interface.
+ */
+ virtual VideoPlayer * createVideoPlayer() { return 0; }
+
+ virtual bool playSoundEvent(const KURL & url);
+
+ virtual Channel * createChannel( const TQString & title, const TQString & channeltype,
+ Channel::Direction direction ) = 0;
+
+ virtual TQStringList availableChannels( Channel::Direction direction ) const = 0;
+
+ virtual TQStringList playableMimeTypes() const = 0;
+
+ private:
+ RESERVE_VIRTUAL_10
+
+ class Private;
+ Private * d;
+ };
+}} // namespaces
+
+// vim: sw=4 ts=4 noet tw=80
+#endif // BACKEND_H
diff --git a/kdemm/channel.cpp b/kdemm/channel.cpp
new file mode 100644
index 000000000..fa1d662f9
--- /dev/null
+++ b/kdemm/channel.cpp
@@ -0,0 +1,69 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Scott Wheeler <wheeler@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "channel.h"
+
+#include <tqstring.h>
+
+namespace KDE
+{
+namespace Multimedia
+{
+
+class Channel::Private
+{
+ public:
+ TQString channelName;
+ TQString channelType;
+ Direction direction;
+};
+
+Channel::Channel( const TQString & channelName, const TQString & type, Direction direction,
+ TQObject * parent, const char * name )
+ : TQObject( parent, name )
+{
+ d = new Private;
+ d->channelName = channelName;
+ d->channelType = type;
+ d->direction = direction;
+}
+
+Channel::~Channel()
+{
+ delete d;
+}
+
+TQString Channel::channelName() const
+{
+ return d->channelName;
+}
+
+TQString Channel::channelType() const
+{
+ return d->channelType;
+}
+
+Channel::Direction Channel::direction() const
+{
+ return d->direction;
+}
+
+}}
+#include "channel.moc"
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/channel.h b/kdemm/channel.h
new file mode 100644
index 000000000..6e47febac
--- /dev/null
+++ b/kdemm/channel.h
@@ -0,0 +1,96 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef KDEMM_CHANNEL_H
+#define KDEMM_CHANNEL_H
+
+#include <kdemm/mixeriface.h>
+
+class TQString;
+
+namespace KDE
+{
+namespace Multimedia
+{
+ /**
+ * \short Abstraction of different inputs or outputs
+ *
+ * \author Matthias Kretz <kretz@kde.org>
+ * \since 4.0
+ */
+ class KDE_EXPORT Channel : public TQObject, virtual public MixerIface
+ {
+ Q_OBJECT
+ public:
+ virtual ~Channel();
+
+ enum Direction
+ {
+ Input,
+ Output
+ };
+
+ /**
+ * The user visible name of the channel
+ */
+ virtual TQString channelName() const;
+
+ /**
+ * The (internal) channel type.
+ */
+ virtual TQString channelType() const;
+
+ /**
+ * Whether it is an Input or Output channel
+ */
+ virtual Direction direction() const;
+
+ /**
+ * If the channel has a volume control this function returns \p true
+ */
+ virtual bool hasVolumeControl() const = 0;
+
+ /**
+ * The current volume of the channel
+ */
+ virtual float volume() const = 0;
+
+ /**
+ * Set the volume for the channel
+ *
+ * \returns Returns \p true if the volume has been successfully set
+ */
+ virtual bool setVolume( float volume ) = 0;
+
+ protected:
+ /**
+ * You can not instantiate channels yourself, use the Factory to
+ * create them.
+ */
+ Channel( const TQString & channelName, const TQString & type, Direction direction,
+ TQObject * parent = 0, const char * name = 0 );
+
+ private:
+ class Private;
+ Private * d;
+ };
+}} // namespaces
+// vim: sw=4 ts=4 noet tw=80
+
+#endif // KDEMM_CHANNEL_H
diff --git a/kdemm/factory.cpp b/kdemm/factory.cpp
new file mode 100644
index 000000000..1994b8e5e
--- /dev/null
+++ b/kdemm/factory.cpp
@@ -0,0 +1,296 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "factory.h"
+#include "backend.h"
+#include "player.h"
+#include "videoplayer.h"
+#include "channel.h"
+
+#include <ktrader.h>
+#include <kservice.h>
+#include <klibloader.h>
+#include <kmessagebox.h>
+#include <tqfile.h>
+#include <klocale.h>
+#include <kmimetype.h>
+#include <kdebug.h>
+
+namespace KDE
+{
+namespace Multimedia
+{
+class Factory::Private
+{
+ public:
+ Private()
+ : backend( 0 )
+ {
+ createBackend();
+ }
+
+ void createBackend()
+ {
+ KTrader::OfferList offers = KTrader::self()->query( "KDEMultimediaBackend", "Type == 'Service'" );
+ KTrader::OfferListIterator it = offers.begin();
+ KTrader::OfferListIterator end = offers.end();
+ TQStringList errormsg;
+ for( ; it != end; ++it )
+ {
+ KService::Ptr ptr = *it;
+ KLibFactory * factory = KLibLoader::self()->factory( TQFile::encodeName( ptr->library() ) );
+ if( factory )
+ {
+ backend = ( Backend* )factory->create( 0, "Multimedia Backend", "KDE::Multimedia::Backend" );
+ if( 0 == backend )
+ {
+ TQString e = i18n( "create method returned 0" );
+ errormsg.append( e );
+ kdDebug( 600 ) << "Error getting backend from factory for " <<
+ ptr->name() << ":\n" << e << endl;
+ }
+ else
+ {
+ service = ptr;
+ kdDebug( 600 ) << "using backend: " << ptr->name() << endl;
+ break;
+ }
+ }
+ else
+ {
+ TQString e = KLibLoader::self()->lastErrorMessage();
+ errormsg.append( e );
+ kdDebug( 600 ) << "Error getting factory for " << ptr->name() <<
+ ":\n" << e << endl;
+ }
+ }
+#if 0
+ if( 0 == backend )
+ {
+ if( offers.size() == 0 )
+ KMessageBox::error( 0, i18n( "Unable to find a Multimedia Backend" ) );
+ else
+ {
+ TQString details = "<qt><table>";
+ TQStringList::Iterator eit = errormsg.begin();
+ TQStringList::Iterator eend = errormsg.end();
+ KTrader::OfferListIterator oit = offers.begin();
+ KTrader::OfferListIterator oend = offers.end();
+ for( ; eit != eend || oit != oend; ++eit, ++oit )
+ details += TQString( "<tr><td><b>%1</b></td><td>%2</td></tr>" )
+ .arg( ( *oit )->name() ).arg( *eit );
+ details += "</table></qt>";
+
+ KMessageBox::detailedError( 0,
+ i18n( "Unable to use any of the available Multimedia Backends" ), details );
+ }
+ }
+#endif
+ }
+
+ Backend * backend;
+ KService::Ptr service;
+
+ TQValueList<void*> objects;
+};
+
+Factory * Factory::m_self = 0;
+
+Factory * Factory::self()
+{
+ if( ! m_self )
+ m_self = new Factory();
+ return m_self;
+}
+
+Factory::Factory()
+ : DCOPObject( "KDEMMFactory" )
+ , d( new Private )
+{
+ connectDCOPSignal( 0, 0, "kdemmBackendChanged()", "kdemmBackendChanged()", false);
+}
+
+Factory::~Factory()
+{
+ delete d;
+}
+
+void Factory::kdemmBackendChanged()
+{
+ if( d->backend )
+ {
+ // wouw, if we want to switch on the fly we have to exchange the
+ // (Video)Player and Channel classes without the API user noticing. That
+ // would mean to implement a kind of smartwrapper:
+ // Player: Interface that accesses Player_skel which is abstract and is
+ // implemented by the Backend. The API user would only get access to the
+ // Player class and if you want to switch the backend you can delete the
+ // Player_skel object and put another implementation in its place.
+ //
+ // Now we tell the kdemm using app to help us. With the first signal we
+ // tell 'em to delete all the (Video)Players and Channels and with the
+ // second to recreate them all again.
+ emit deleteYourObjects();
+ if( d->objects.size() > 0 )
+ {
+ kdWarning( 600 ) << "we were asked to change the backend but the application did\n"
+ "not free all references to objects created by the factory. Therefor we can not\n"
+ "change the backend without crashing. Now we have to wait for a restart to make\n"
+ "backendswitching possible." << endl;
+ // in case there were objects deleted give 'em a chance to recreate
+ // them now
+ emit recreateObjects();
+ return;
+ }
+ delete d->backend;
+ d->backend = 0;
+ }
+ d->createBackend();
+ emit recreateObjects();
+}
+
+void Factory::objectDestroyed( TQObject * obj )
+{
+ kdDebug( 600 ) << k_funcinfo << obj << endl;
+ void * p = ( void* )obj;
+ d->objects.remove( p );
+}
+
+Player * Factory::createPlayer()
+{
+ if( d->backend )
+ {
+ Player * p = d->backend->createPlayer();
+ connect( p, TQT_SIGNAL( destroyed( TQObject* ) ), TQT_SLOT( objectDestroyed( TQObject* ) ) );
+ d->objects.append( p );
+ return p;
+ }
+ else
+ return 0;
+}
+
+VideoPlayer * Factory::createVideoPlayer()
+{
+ if( d->backend )
+ {
+ VideoPlayer * vp = d->backend->createVideoPlayer();
+ connect( vp, TQT_SIGNAL( destroyed( TQObject* ) ), TQT_SLOT( objectDestroyed( TQObject* ) ) );
+ d->objects.append( vp );
+ return vp;
+ }
+ else
+ return 0;
+}
+
+bool Factory::playSoundEvent(const KURL & url)
+{
+ if( d->backend )
+ return d->backend->playSoundEvent(url);
+ else
+ return false;
+}
+
+Channel * Factory::createChannel( const TQString & title, const TQString & channeltype,
+ Channel::Direction direction )
+{
+ if( d->backend )
+ {
+ Channel * c = d->backend->createChannel( title, channeltype, direction );
+ connect( c, TQT_SIGNAL( destroyed( TQObject* ) ), TQT_SLOT( objectDestroyed( TQObject* ) ) );
+ d->objects.append( c );
+ return c;
+ }
+ else
+ return 0;
+}
+
+TQStringList Factory::availableChannels( Channel::Direction direction ) const
+{
+ if( d->backend )
+ return d->backend->availableChannels( direction );
+ else
+ return TQStringList();
+}
+
+TQStringList Factory::playableMimeTypes() const
+{
+ if( d->backend )
+ return d->backend->playableMimeTypes();
+ else
+ return TQStringList();
+}
+
+bool Factory::isMimeTypePlayable( const TQString & type ) const
+{
+ if( d->backend )
+ {
+ KMimeType::Ptr mimetype = KMimeType::mimeType( type );
+ TQStringList mimetypes = playableMimeTypes();
+ for( TQStringList::ConstIterator i=mimetypes.begin(); i!=mimetypes.end(); i++ )
+ if( mimetype->is( *i ) )
+ return true;
+ }
+ return false;
+}
+
+TQString Factory::backendName() const
+{
+ if( d->service )
+ return d->service->name();
+ else
+ return TQString::null;
+}
+
+TQString Factory::backendComment() const
+{
+ if( d->service )
+ return d->service->comment();
+ else
+ return TQString::null;
+}
+
+TQString Factory::backendVersion() const
+{
+ if( d->service )
+ return d->service->property( "X-KDE-MMBackendInfo-Version" ).toString();
+ else
+ return TQString::null;
+}
+
+TQString Factory::backendIcon() const
+{
+ if( d->service )
+ return d->service->icon();
+ else
+ return TQString::null;
+}
+
+TQString Factory::backendWebsite() const
+{
+ if( d->service )
+ return d->service->property( "X-KDE-MMBackendInfo-Website" ).toString();
+ else
+ return TQString::null;
+}
+
+}} //namespaces
+
+#include "factory.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/factory.h b/kdemm/factory.h
new file mode 100644
index 000000000..c9ed2e3da
--- /dev/null
+++ b/kdemm/factory.h
@@ -0,0 +1,222 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef KDEMM_FACTORY_H
+#define KDEMM_FACTORY_H
+
+#include <kurl.h>
+#include <kdemm/channel.h>
+#include <tqstring.h>
+#include <tqstringlist.h>
+#include <dcopobject.h>
+
+namespace KDE
+{
+/**
+ * \brief The KDE Multimedia classes
+ *
+ * In this Namespace you find a few classes to access Multimedia functions like
+ * playing audio files and simple video playing. Those classes are not dependent
+ * on any specific framework (like they were in pre KDE4 times) but rather use
+ * exchangeable backends to do the "dirty" work.
+ *
+ * If you want to write a new backend you also find the necessary classes in
+ * this namespace.
+ *
+ * \since 4.0
+ */
+namespace Multimedia
+{
+class Backend;
+class Player;
+class VideoPlayer;
+
+/**
+ * \brief Factory to access the preferred Backend.
+ *
+ * This class is your entry point to KDE Multimedia usage. It provides the
+ * necessary objects for playing audio and video.
+ *
+ * For simple access to just playing an audio file see SimplePlayer.
+ *
+ * \remarks
+ * Extensions to the existing functionality can either be added by using the
+ * reserved virtual functions in Backend or by adding a new interface e.g.
+ * BackendV2 and creating a BackendV2 instance when the Backend instance is
+ * created.
+ *
+ * \author Matthias Kretz <kretz@kde.org>
+ * \since 4.0
+ */
+class KDE_EXPORT Factory : public TQObject, public DCOPObject
+{
+ Q_OBJECT
+ public:
+ /**
+ * Returns a pointer to the factory.
+ * Use this function to get an instance of KLibLoader.
+ *
+ * @return a pointer to the loader. If no loader exists until now then
+ * one is created
+ */
+ static Factory * self();
+
+ /**
+ * Create a new Player.
+ *
+ * You need to call it like this:
+ * \code
+ * Factory::self()->createPlayer();
+ * \endcode
+ *
+ * @return a pointer to the Player the backend provides
+ */
+ Player * createPlayer();
+
+ /**
+ * Create a new VideoPlayer object. The Backend does not have to
+ * implement this functionality so you have to check that it didn't
+ * return 0.
+ *
+ * @return A new instance to a VideoPlayer from the Backend. Or 0 if
+ * the Backend does not support the VideoPlayer interface.
+ */
+ VideoPlayer * createVideoPlayer();
+
+ /**
+ * Play the specified sound-file with no further control. Returns
+ * immediatly.
+ *
+ * @return if the file was be succesfully issued, but is not a
+ * garantie for succes of playing the entire file.
+ */
+ bool playSoundEvent(const KURL & url);
+
+ /**
+ * Creates a new Channel object that you can use for a Player object to
+ * play to.
+ *
+ * \param title A user visible title for the Channel. Most of the time
+ * you will use the application's name.
+ *
+ * \param channeltype \ref availableChannels() returns a list of strings
+ * where you can choose one to be used. Most of the time you will use
+ * the "default" channel. But the Backend could also provide special
+ * purpose channels like one for notifications, one for previews and one
+ * for media playback.
+ *
+ * \param direction Whether it's a Channel::Input or Channel::Output
+ * that you're requesting.
+ *
+ * \returns Returns a Channel object or 0 if your request couldn't be
+ * fullfilled.
+ */
+ Channel * createChannel( const TQString & title,
+ const TQString & channeltype = TQString::fromLatin1( "default" ),
+ Channel::Direction direction = Channel::Output );
+
+ /**
+ * Returns the names of the channels that can be used to play or record,
+ * depending on the value of \p direction.
+ *
+ * \param direction If set to Channel::Output you will get the names of
+ * all output channels, if set to Channel::Input you get the same for
+ * the input channels.
+ */
+ TQStringList availableChannels( Channel::Direction direction = Channel::Output ) const;
+
+ /**
+ * Returns the mimetypes that can be played.
+ */
+ TQStringList playableMimeTypes() const;
+
+ /**
+ * Checks whether a certain mimetype is playable.
+ */
+ bool isMimeTypePlayable( const TQString & mimetype ) const;
+
+ /**
+ * Get the name of the Backend. It's the name from the .desktop file.
+ */
+ TQString backendName() const;
+
+ /**
+ * Get the comment of the Backend. It's the comment from the .desktop file.
+ */
+ TQString backendComment() const;
+
+ /**
+ * Get the version of the Backend. It's the version from the .desktop file.
+ *
+ * The version is especially interesting if there are several versions
+ * available for binary incompatible versions of the backend's media
+ * framework.
+ */
+ TQString backendVersion() const;
+
+ /**
+ * Get the icon (name) of the Backend. It's the icon from the .desktop file.
+ */
+ TQString backendIcon() const;
+
+ /**
+ * Get the website of the Backend. It's the website from the .desktop file.
+ */
+ TQString backendWebsite() const;
+
+ signals:
+ /**
+ * This signal is emitted when the user changes the backend. You then
+ * have to free all your references to Player or Channel objects.
+ */
+ void deleteYourObjects();
+
+ /**
+ * After you got a deleteYourObjects() signal the backend is changed
+ * internally. Then you will receive this signal, and only then should
+ * you reconstruct all your objects again. This time they will
+ * internally use the new backend.
+ */
+ void recreateObjects();
+
+ protected:
+ Factory();
+ ~Factory();
+
+ private slots:
+ void objectDestroyed( TQObject * );
+
+ private:
+ static Factory * m_self;
+ class Private;
+ Private * d;
+
+ K_DCOP
+ k_dcop:
+ /**
+ * \internal
+ * This is called via DCOP when the user changes the KDEMM Backend.
+ */
+ void kdemmBackendChanged();
+
+};
+}} // namespaces
+
+#endif // BACKENDFACTORY_H
+// vim: sw=4 ts=4 tw=80 noet
diff --git a/kdemm/mixeriface.h b/kdemm/mixeriface.h
new file mode 100644
index 000000000..8ee9fc96b
--- /dev/null
+++ b/kdemm/mixeriface.h
@@ -0,0 +1,41 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef MIXERIFACE_H
+#define MIXERIFACE_H
+
+#include <dcopobject.h>
+#include <kdelibs_export.h>
+
+class KDE_EXPORT MixerIface : public DCOPObject
+{
+ K_DCOP
+ k_dcop:
+ virtual TQString channelName() const = 0;
+ virtual TQString channelType() const = 0;
+ virtual bool hasVolumeControl() const = 0;
+ virtual float volume() const = 0;
+ virtual bool setVolume( float volume ) = 0;
+
+ protected:
+ MixerIface() : DCOPObject( "MixerIface" ) {}
+};
+
+#endif // MIXERIFACE_H
+// vim: sw=4 ts=4 noet tw=80
diff --git a/kdemm/mmbackendinfo.desktop b/kdemm/mmbackendinfo.desktop
new file mode 100644
index 000000000..001a48c58
--- /dev/null
+++ b/kdemm/mmbackendinfo.desktop
@@ -0,0 +1,30 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=ServiceType
+X-KDE-ServiceType=KDEMultimediaBackend
+Name=KDE Multimedia Backend
+
+[PropertyDef::X-KDE-MMBackendInfo-Version]
+Type=QString
+
+[PropertyDef::X-KDE-MMBackendInfo-Website]
+Type=QString
+
+#[PropertyDef::X-KDE-MMBackendInfo-Supports]
+#Type=QStringList
+#
+#[PropertyDef::X-KDE-MMBackendInfo-Depends]
+#Type=QStringList
+#
+#[PropertyDef::X-KDE-MMBackendInfo-License]
+#Type=QString
+#
+#[PropertyDef::X-KDE-MMBackendInfo-Author]
+#Type=QString
+#
+#[PropertyDef::X-KDE-MMBackendInfo-Email]
+#Type=QString
+#
+#[PropertyDef::X-KDE-MMBackendInfo-Name]
+#Type=QString
+#
diff --git a/kdemm/player.cpp b/kdemm/player.cpp
new file mode 100644
index 000000000..b16c942fc
--- /dev/null
+++ b/kdemm/player.cpp
@@ -0,0 +1,53 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "player.h"
+
+namespace KDE {
+namespace Multimedia {
+Player::Player( TQObject * parent, const char * name )
+ : TQObject( parent, name )
+ , m_state( Player::NoMedia )
+{
+}
+
+Player::~Player()
+{
+}
+
+Player::State Player::state() const
+{
+ return m_state;
+}
+
+void Player::setState( Player::State newstate )
+{
+ if( m_state != newstate )
+ {
+ Player::State oldstate = m_state;
+ m_state = newstate;
+ emit stateChanged( newstate, oldstate );
+ }
+}
+
+}} // namespaces
+
+#include "player.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/player.h b/kdemm/player.h
new file mode 100644
index 000000000..b753073a7
--- /dev/null
+++ b/kdemm/player.h
@@ -0,0 +1,259 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef PLAYOBJECT_H
+#define PLAYOBJECT_H
+
+#include <kdelibs_export.h>
+#include <tqobject.h>
+
+class KURL;
+
+namespace KDE
+{
+namespace Multimedia
+{
+ class Channel;
+ /**
+ * \short Interface for accessing media playback functions
+ *
+ * \author Matthias Kretz <kretz@kde.org>
+ * \since 4.0
+ */
+ class Player : public QObject
+ {
+ Q_OBJECT
+ public:
+ /**
+ * The state the playobject is in at the moment
+ */
+ enum State
+ {
+ /**
+ * The load method wasn't called or didn't succeed. If the
+ * object is in this state the next thing you have to do is to
+ * call load.
+ */
+ NoMedia,
+ /**
+ * After calling load it might take a while before the Player is
+ * ready to play(). Normally this doesn't happen for local
+ * files, but can happen for remote files where the asynchronous
+ * mimetype detection can take a while.
+ */
+ Loading,
+ /**
+ * The Player has a valid media file loaded and is ready for
+ * playing.
+ */
+ Stopped,
+ /**
+ * The Player is playing a media file.
+ */
+ Playing,
+ /**
+ * The Player is waiting for data to be able to continue
+ * playing.
+ */
+ Buffering,
+ /**
+ * The Player is paused currently.
+ */
+ Paused
+ };
+
+ virtual ~Player();
+
+ /**
+ * Set the output device the Player should use.
+ *
+ * @return Returns \p true on success. If it returns \p false the
+ * output device wasn't changed. This could happen if you pass a
+ * Channel with Channel::direction() == Channel::Input.
+ */
+ virtual bool setOutputChannel( Channel * device ) = 0;
+
+ /**
+ * Get the current state.
+ */
+ virtual State state() const;
+
+ /**
+ * Check whether the Player supports to control the volume.
+ *
+ * @returns Return \p true if the Player can change its volume.
+ */
+ virtual bool hasVolumeControl() const = 0;
+
+ /**
+ * Get the current volume.
+ *
+ * @returns the current volume
+ */
+ virtual float volume() const = 0;
+
+ /**
+ * Get the total time (in milliseconds) of the file currently being played.
+ */
+ virtual long totalTime() const = 0;
+
+ /**
+ * Get the remaining time (in milliseconds) of the file currently being played.
+ */
+ virtual long remainingTime() const = 0;
+
+ /**
+ * Get the current time (in milliseconds) of the file currently being played.
+ */
+ virtual long currentTime() const = 0;
+
+ /**
+ * If the current media may be seeked returns true.
+ *
+ * @returns whether the current media may be seeked.
+ */
+ virtual bool seekable() const = 0;
+
+ /**
+ * Return the time interval in milliseconds between two ticks.
+ */
+ virtual long tickInterval() const = 0;
+
+ public slots:
+ /**
+ * Load a media file. If another media is currently loaded it is
+ * stopped and unloaded.
+ *
+ * @param url The location of the media file
+ *
+ * @returns If the call was successfull (the media file was found
+ * and can be read and decoded) returns \p true
+ */
+ virtual bool load( const KURL & url ) = 0;
+
+ /**
+ * Play the media file.
+ */
+ virtual bool play() = 0;
+
+ /**
+ * Pause a playing media. If it was paused before nothing changes.
+ */
+ virtual bool pause() = 0;
+
+ /**
+ * Stop a playback.
+ */
+ virtual bool stop() = 0;
+
+ /**
+ * Set the volume of the playback
+ *
+ * @param volume 0.0 is complete silence and 1.0 is full volume.
+ * Higher values than 1.0 are possible but might
+ * result in distortion of the sound.
+ *
+ * @returns returns \p true if the call was successfull, returns \p
+ * false if the volume change didn't work and therefor didn't
+ * change.
+ */
+ virtual bool setVolume( float volume ) = 0;
+
+ /**
+ * Seek to the time indicated.
+ *
+ * @param time The time in milliseconds where to continue playing.
+ *
+ * @returns whether the seek was successfull.
+ */
+ virtual bool seek( long time ) = 0;
+
+ /**
+ * Change the interval the tick signal is emitted. If you set \p ms
+ * to 0 the signal gets disabled.
+ *
+ * \param ms tick interval in milliseconds
+ *
+ * @returns Returns \p true if the tick intervall was changed.
+ */
+ virtual bool setTickInterval( long ms ) = 0;
+
+ signals:
+ /**
+ * Emitted when the file has finished playing on its own.
+ * I.e. it is not emitted if you call stop(), pause() or
+ * load(), but only on end-of-file or a critical error.
+ */
+ void finished();
+
+ //XXX do we want a aboutToFinish() signal?
+
+ /**
+ * Emitted when the state of the Player has changed.
+ * In case you're not interested in the old state you can also
+ * connect to a slot that only has one State argument.
+ *
+ * @param newstate The state the Player is in now
+ * @param oldstate The state the Player was in before
+ */
+ void stateChanged( KDE::Multimedia::Player::State newstate, KDE::Multimedia::Player::State oldstate );
+
+ /**
+ * This signal gets emitted every tickInterval milliseconds.
+ *
+ * \param time The position of the media file in milliseconds.
+ *
+ * \see setTickInterval, tickInterval
+ */
+ void tick( long time );
+
+ /**
+ * This signal is emitted as soon as the length of the media file is
+ * known or has changed.
+ *
+ * @param length The length of the media file in milliseconds.
+ */
+ void length( long length );
+
+ protected:
+ /**
+ * You can not instantiate players yourself, use the Factory to
+ * create them.
+ */
+ Player( TQObject * parent, const char * name );
+
+ /**
+ * Call this in your reimplementation for state changes.
+ * It emits the stateChanged signal if the state has really changed.
+ *
+ * @param newstate The new state of the Player. If \p newstate is
+ * equal to the old state() the call will be ignored.
+ */
+ void setState( State newstate );
+
+ private:
+ class Private;
+ Private * d;
+
+ State m_state;
+ };
+}} //namespaces
+
+// vim: sw=4 ts=4 tw=80 noet
+#endif // PLAYOBJECT_H
diff --git a/kdemm/reqspec.html b/kdemm/reqspec.html
new file mode 100644
index 000000000..a07860c79
--- /dev/null
+++ b/kdemm/reqspec.html
@@ -0,0 +1,533 @@
+<HTML><HEAD><TITLE>Requirements & Specification</TITLE></HEAD><BODY BGColor="#FFFFFF" LINK="#0000FF" VLINK="#0000FF">
+<H2><CENTER>Requirements & Specification</CENTER></H2>
+
+<A NAME="Problem Statement" />
+<H3>1. Problem Statement</H3>
+
+<P>KDE needs to integrate better into existing Multimedia solutions for Linux.</P>
+
+<P>Currently many KDE apps use aRts as media framework and soundserver, while other apps use mplayer, xine and/or gstreamer to do what they need. Sometimes this results in mutually exclusive usage of the soundcard and generally it's an unneeded overhead.</P>
+
+<P>KDE Developers should be able to "natively" use multimedia functions in the KDE API. The KDE Mulitmedia API (short kdemm) should provide an easy to use and Qt/KDE API like aproach to multimedia functionality.</P>
+
+<P>Nowadays when a KDE developer wants to add multimedia functionality to his program he can either choose one framework to do it, write all the media code himself (nobody does this, and probably nobody should) or use an abstraction to be able to use more than one framework. Most of the time the development models (object model, programming language) are not the same as a KDE developer is used to. And very often the API of the framework used is more complicated than the task he wants to accomplish. The kdemm API should be useable without any knowledge about media frameworks and how these things work internally.</P>
+
+<P>The API does not aim to be a general Linux solution to multimedia. It aims to be the solution for all KDE developers.</P>
+
+<P>KDE should ease the use of pro audio tools on Linux and provide the necessary configuration and integration so that for pro audio tools the DE of choice is KDE.</P>
+
+<A NAME="Requirements" />
+<H3>2. Requirements</H3>
+
+<A NAME="Actors" />
+<H4>2.1. Actors</H4>
+
+<A NAME="Actor: Admin" />
+<H4>Actor: Admin</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">Administrates a KDE installation. Most users are their own admins...</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated User Tasks</I></TD><TD COLSPAN="1" VALIGN="top">configure Multimedia sytems</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">Configure kdemm</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Actor: KDE Developer" />
+<H4>Actor: KDE Developer</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">The average KDE Developer who might need some multimedia functionality, like playing a media object, for his program.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated User Tasks</I></TD><TD COLSPAN="1" VALIGN="top">add media playback to his program</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">add media playback functionality to a program, initialize kdemm</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Actor: KDE Multimedia Developer" />
+<H4>Actor: KDE Multimedia Developer</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">KDE Developer writing a media application like a jukebox or full-featured media player.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated User Tasks</I></TD><TD COLSPAN="1" VALIGN="top">Develop Media Player</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">media playback, manage video window, modify audio path, play media object, load media object, create reusable audio path, crossfading</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Actor: KDE User" />
+<H4>Actor: KDE User</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">User of the K Desktop Environment.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated User Tasks</I></TD><TD COLSPAN="1" VALIGN="top">change audio output volume</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiated Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">change audio volume</TD></TR>
+
+</TABLE></P>
+
+<A NAME="User Tasks" />
+<H4>2.2. User Tasks</H4>
+
+<P>Actor Admin initilizes the following user tasks</P>
+
+<A NAME="User Task: configure Multimedia sytems" />
+<H4>User Task: configure Multimedia sytems</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">His aim is to make all multimedia applications work happily side by side.<BR><BR>He has several options to select, like the audio driver backend to use OSS or ALSA, whether he wants to have a soundserver running and what application uses what audio output. He can set the video output method, like e.g. xv or SDL or plain X.<BR><BR>This has to be done so that applications don't block each other and sometimes to make them interact with one another (like you can do with soundservers).<BR><BR>It is important to have it correctly configured else the user will have problems whenever he uses multimedia programs.<BR><BR>This configuration has to be done once until a new program is installed that is incompatible with the setup. Ideally this task has to be done once and never again.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Realized in Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">Configure kdemm</TD></TR>
+
+</TABLE></P>
+<BR>
+<BR>
+
+<P>Actor KDE Developer initilizes the following user tasks</P>
+
+<A NAME="User Task: add media playback to his program" />
+<H4>User Task: add media playback to his program</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">The average KDE Developer might want to add media playback functionality to his program, meaning that his program will be able to play a sound file or even video file.<BR><BR>He can select from a lot of choices how to achieve his goal.<BR>- write the relevant audio/video code himself<BR>- select and use a media framework like gstreamer or aRts<BR>- use existing code from kdelibs (might not be enough for what he's trying to do)<BR><BR>A lot of programs nowadays need to have multimedia functionality.<BR><BR>It's important that KDE developers can add multimedia functionality to their programs.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Realized in Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">add media playback functionality to a program</TD></TR>
+
+</TABLE></P>
+<BR>
+<BR>
+
+<P>Actor KDE Multimedia Developer initilizes the following user tasks</P>
+
+<A NAME="User Task: Develop Media Player" />
+<H4>User Task: Develop Media Player</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">Aim: The developers aim is to write a full featured media player like mplayer, xine, all the frontends for the former, windoze media player :-P, realplayer, you name it.<BR><BR>Options: He can choose from a variety of available code, like NMM, gstreamer, aRts to a certain extend, mplayer or (lib)xine to provide for his multimedia needs. He can choose how to output the audio and video as far as the former choice gives him options. There are constraints on what media formats he can play or what he can do with the data depending on his choice of media backend/framework.<BR><BR>Reason: A modern desktop environment needs to have a modern media player with all the latest bells and whistles.<BR><BR>Priority: It is important that KDE has "native" media players.<BR><BR>Info-In:<BR>- knowledge about what other media players can do<BR>- features asked for by users (e.g. EQ is a must have for some users)</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Realized in Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">media playback, manage video window, modify audio path, play media object, load media object, create reusable audio path, crossfading</TD></TR>
+
+</TABLE></P>
+<BR>
+<BR>
+
+<P>Actor KDE User initilizes the following user tasks</P>
+
+<A NAME="User Task: change audio output volume" />
+<H4>User Task: change audio output volume</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">The user wants to change the volume of some program because it is too loud compared to the sound of another program.<BR><BR>This is a tricky task for the user if the program itself doesn't allow to attenuate its sound. If it does he can use the volume control of the program. If it doesn't he has to use a soundserver that allows him to use a volume control for this one specific program only.<BR><BR>It is rather important to have this functionality as it can become pretty anoying if you e.g. want to get notifications when people are chatting with you while you're listening to classical music. The notifications really need attenuation.<BR><BR>It might happen a few times a day that a user needs this functionality.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Realized in Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">change audio volume</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Domain Data" />
+<H4>2.3. Domain Data</H4>
+
+<P>When I say "sent" in the diagram below I'm actually talking about the data flow in the underlying media framework. kdemm only creates connections so that the data flow is done by the framework.</P>
+<IMG SRC="0.png" />
+
+
+<A NAME="Domain Constraints" />
+<H4>2.4. Domain Constraints</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%"><B>Network transparency</B></TD><TD >It must be possible to run the desktop over the network, not only the GUI, but also audio output. If it is possible, the system should try to play the audio on the computer where the GUI is shown by default.</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Quality Constraints" />
+<H4>2.5. Quality Constraints</H4>
+
+<A NAME="Interaction Data" />
+<H4>2.6. Interaction Data</H4>
+
+<A NAME="Specification" />
+<H3>3. Specification</H3>
+
+<P>When reading the use cases keep in mind that the user often is the Application Developer. So the actor steps are steps the application written by the developer does.</P>
+
+<A NAME="Use Cases" />
+<H4>3.1. Use Cases</H4>
+
+<A NAME="Use Case: add media playback functionality to a program" />
+<H4>Use Case: add media playback functionality to a program</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >the kdemm API has been initialized without errors (see use case "initialize kdemm")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Tell kdemm what media object you want to play back.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Check whether the media object is one of the known types that the backend can decode. If it cannot be decoded error out.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Prepare for being asked to play back the media object, to seek in it or other operations.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >a) Ask for meta information of the current media object. (e.g. length, bitrate, etc.) --> go on with step 5<BR><BR>or<BR><BR>b) asking kdemm to play the media object --> go on with step 7</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">read out meta information, either using the media backend if it supports this function, or using other external libs</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >display meta information on the GUI while asking kdemm to play the media object</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Tell media backend to start playing.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Wait for notification that the media object has finished playing. Remove display of meta info and clean up all used datastructures.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: change audio volume" />
+<H4>Use Case: change audio volume</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE User</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >a kdemm using program (let's call it A) is running with its volume being x</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >open KDE Mixer Window</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">look for all available volume controls and show them (with informative description what control does what) to the user</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >locate the control for A and move the fader down</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">decrease the output volume of A</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Postconditions</I></TD><TD >A is running with output volume y < x</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: Configure kdemm" />
+<H4>Use Case: Configure kdemm</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >Admin</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >KDE is installed and the backends the Admin wants to use are installed.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >open kdemm admin tool</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">kdemm looks for available options (media frameworks and their output options) and presents these options in a view (see glossary). One framework is already selected as KDE default and kdemm does a good guess (based on audio driver) on what should be the default audio output option.<BR>For the selected media framework there might be more options that need to be shown.<BR>Also if the audio output choice has configuration options they get shown. (e.g. jackd has a lot of options that are more or less important to the admin)</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >select another media framework</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Change audio output options according to what the framework supports.<BR><BR>Provide access to the configuration options of the just selected media framework.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >take a look at media framework config options</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">show media framework config options (e.g. NMM might show some network related options here)</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >tweak a few settings</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">write config out so that programs using kdemm behave like configured</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >change default audio output</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Set the media framework to use the specified audio output.<BR><BR>Provide access to the configuration options of the newly selected audio output.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >save settings and close admin tool</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">write out all configuration and tell all kdemm programs to use the new configuration</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: create reusable audio path" />
+<H4>Use Case: create reusable audio path</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Multimedia Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >the kdemm API has been initialized without errors (see use case "initialize kdemm")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask kdemm for an "audio path"</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Create a representation for the flow graph audio normally takes from the media object to the output and return an interface to it.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask for a list of effects that can be inserted into the audio path.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Look what effects the media framework supports and return a list that describes those effects (1. information for the end-user, 2. info that a computer program can recognize and identify, 3. unique identifier for the effect)</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Create list of effects and let the user decide what effects he wants. Tell kdemm to insert effects into the audio path.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Prepare an audio path with the selected effects for later use.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >optional steps:<BR>The user decides to configure the parameters of one effect.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Return a Widget showing the parameters the effect has so that the user can configure the effects.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask kdemm to save the state of the current audio path to a configuration object.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Look at current audio path, the contained effects and the parameters of the effects. Write those values in the configuration object.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >load media</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Tell kdemm to use the above audio path for the media object.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Change flow graph of media framework to use the selected audio path.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >play</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: crossfading" />
+<H4>Use Case: crossfading</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Multimedia Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >the kdemm API has been initialized without errors (see use case "initialize kdemm")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask kdemm to send a notification 3 seconds before a media object finishes playing.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">tell "notification system" from the media framework if it has one, else start a timer that checks for the end of playback to send the notification</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >take from playlist</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Insert a "Fader" effect into the audio path of the media object</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Change flow graph of the media framework to include the "Fader" effect.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >play</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >take from playlist</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Insert a "Fader" effect into the audio path of the media object</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Change flow graph of the media framework to include the "Fader" effect.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >When notification arrives tell the Fader of media object 1 to fade out in 3 seconds. Tell the Fader of media object 2 to fade in in 3 seconds and start playing media object 2.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: initialize kdemm" />
+<H4>Use Case: initialize kdemm</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >KDE and all its libraries are installed correctly.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >ask kdemm to initialize</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Look at config set by the admin tool and accordingly load the media framework code and initialize an audio output that is at this point already available for the kdemm mixer API.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Postconditions</I></TD><TD >kdemm is initialized and ready for action</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: load media object" />
+<H4>Use Case: load media object</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Multimedia Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >the kdemm API has been initialized without errors (see use case "initialize kdemm")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Tell kdemm to load a media object.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Prepare media framework for working with the media object (play, seek, etc.).</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Postconditions</I></TD><TD >Media object is ready for use.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: manage video window" />
+<H4>Use Case: manage video window</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Multimedia Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >the kdemm API has been initialized without errors (see use case "initialize kdemm")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask kdemm for a dedicated video widget.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Create widget and keep reference to it for so that all video output at some later point can be displayed in this widget.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >optional step - can be inserted at any point from here on:</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Resize video widget (might also be fullscreen display).</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Adjust for new video output size: video needs to be scaled to fit into the widget.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask for available video ratio options.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Ask media framework for available video ratio options. If the media framework doesn't provide any options <BR> Mark the currently used option.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Select one of the ratio options.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Change video ratio.</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: media playback" />
+<H4>Use Case: media playback</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Multimedia Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >the kdemm API has been initialized without errors (see use case "initialize kdemm")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Tell kdemm to send a notification whenever a media object is about to finish playing.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">tell "notification system" from the media framework if it has one, else start a timer that checks for the end of playback to send the notification</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Take first media object from the playlist</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >play</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >When notified that the playback is about to end</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >When notified that the playback has finished</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: modify audio path" />
+<H4>Use Case: modify audio path</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Multimedia Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >the kdemm API has been initialized without errors (see use case "initialize kdemm")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >load</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask for "audio path" of the media object.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Prepare for changing the flow graph of the audio going from the media object to the default output. Return a reference to an object that can be used to modify the path the audio takes.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask for a list of effects that can be inserted into the audio path.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Look what effects the media framework supports and return a list that describes those effects (1. information for the end-user, 2. info that a computer program can recognize and identify, 3. unique identifier for the effect)</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Select an effect and tell kdemm to insert it into the audio path (the position can also be specified)</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Change audio flow graph of the media framework to include the selected effect at the specified position.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >play with effect</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+</TABLE></P>
+
+<A NAME="Use Case: play media object" />
+<H4>Use Case: play media object</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Initiating Actor</I></TD><TD >KDE Multimedia Developer</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Preconditions</I></TD><TD >a media object has been loaded (include use case "load media object")</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>FlowSteps</I></TD><TD >Actor</TD><TD COLSPAN="1" VALIGN="top">System</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD >Ask kdemm to play the media.</TD><TD COLSPAN="1" VALIGN="top"></TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I></I></TD><TD ></TD><TD COLSPAN="1" VALIGN="top">Instruct the media framework to play.</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Features" />
+<H4>3.2. Features</H4>
+
+<A NAME="Feature: create media object" />
+<H4>Feature: create media object</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">Check whether the media data can be accessed and decoded. If not return an error indicating the problem.<BR>Use the underlying media framework to create a flow graph for reading and decoding the media data. (If the media framework does not support reading data from a remote location an extension has to be created that can use KIO to read the data.)<BR>Create an object to represent the media data.</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Inputs</I></TD><TD COLSPAN="1" VALIGN="top">URL to the media data</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Outputs</I></TD><TD COLSPAN="1" VALIGN="top">media object</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Used in Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">load media object</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Feature: init notifications" />
+<H4>Feature: init notifications</H4>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Description</I></TD><TD COLSPAN="1" VALIGN="top">two cases: <BR>if( The media framework can produce the notification in question ) { <BR>Initialize notifications from media framework and prepare to forward them. <BR>} else { <BR>Use timer to send ticks and check for end of media playback. <BR>}</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Inputs</I></TD><TD COLSPAN="1" VALIGN="top">- time before media playback ends <BR>- time between ticks <BR>- what notifications to enable/disable (choices are: ticks, aboutToEnd, end)</TD></TR>
+
+<TR ><TD WIDTH="20%" VALIGN="top"><I>Used in Use Cases</I></TD><TD COLSPAN="1" VALIGN="top">media playback, crossfading</TD></TR>
+
+</TABLE></P>
+
+<A NAME="Global Functional Constraints" />
+<H4>3.3. Global Functional Constraints</H4>
+
+<A NAME="Quality Constraints on Use Cases" />
+<H4>3.4. Quality Constraints on Use Cases</H4>
+
+<A NAME="Quality Constraints on Features" />
+<H4>3.5. Quality Constraints on Features</H4>
+
+<A NAME="Architectural Constraints" />
+<H4>3.6. Architectural Constraints</H4>
+
+<A NAME="User Interface Constraints" />
+<H4>3.7. User Interface Constraints</H4>
+
+<A NAME="Examples" />
+<H3>4. Examples</H3>
+
+<A NAME="Actor Instances" />
+<H4>4.1. Actor Instances</H4>
+
+<A NAME="Scenarios" />
+<H4>4.2. Scenarios</H4>
+
+<A NAME="Glossary" />
+<H3>5. Glossary</H3>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="2">
+<TR ><TD>&nbsp;</TD><TD ><DT>admin options view</DT><DD>The kdemm admin tool shows a selection for the media framework and the audio output. Both define an order in which the kdemm applications try to use the framework/audio output.
+Further options can be reached in another view for the media framework and the audio output.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>ALSA</DT><DD>Advanced Linux Sound Architecture: new audio interface for Linux</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>API</DT><DD>Application Programmer Interface: The interface that the Application Programmer uses to interact with the kdemm framework.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>aRts</DT><DD>analog Realtime Synthesizer: the current soundserver and "media framework" of KDE</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>BC</DT><DD>binary compatibility: If the ABI (application binary interface) is changed in an incompatible way (http://developer.kde.org/documentation/other/binarycompatibility.html) the programs using the library will crash.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>DE</DT><DD>Desktop Environment</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>desktop</DT><DD>The GUIs of today all work with the metaphor of a "desktop" on your screen. The elements on screen are the objects that you can handle and work with.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>EQ</DT><DD>equalizer: audio filter to boost and attenuate selected frequencies of the signal</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>flow graph</DT><DD>In media frameworks the flow of media data is modeled as a flow graph. There are nodes representing data sources, data processors and data sinks.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>gstreamer</DT><DD>GStreamer is a library that allows the construction of graphs of media-handling components, ranging from simple Ogg/Vorbis playback to complex audio (mixing) and video (non-linear editing) processing.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>GUI</DT><DD>Graphical User Interface</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>kdemm</DT><DD>short for KDE Multimedia - it's the name of the library/framework the API discussed in here is going to have.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>media object</DT><DD>A media object is a representation for the media data. This could be an audio or video file or stream.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>mplayer</DT><DD>media player that is often used as backend for other media player GUIs</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>NMM</DT><DD>NETWORK-INTEGRATED MULTIMEDIA MIDDLEWARE: a network-integrated multimedia infrastructure for Linux (as well as other operating systems)</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>OSS</DT><DD>Open Sound System: audio interface for UNIX systems</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>SDL</DT><DD>Simple DirectMedia Layer: multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>tick</DT><DD>While playing a media file a common task is to show the current position in the file. A tick is a signal every second or so to notify about the progress.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>URL</DT><DD>Uniform Resource Locator (http://en.wikipedia.org/wiki/Uniform_Resource_Locator)</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>user</DT><DD>As long as I talk about API usage the user equals the AP in API.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>X</DT><DD>X Window system: The client server architecture used for most UNIX GUI programs.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>xine</DT><DD>xine is a free multimedia player. It plays back CDs, DVDs, and VCDs. It also decodes multimedia files like AVI, MOV, WMV, and MP3 from local disk drives, and displays multimedia streamed over the Internet. It interprets many of the most common multimedia formats available - and some of the most uncommon formats, too.</DD></TD></TR>
+
+<TR ><TD>&nbsp;</TD><TD ><DT>xv</DT><DD>X Video: extension to X for hardware accelerated video display</DD></TD></TR>
+
+</TABLE></P>
+</BODY></HTML>
diff --git a/kdemm/simpleplayer.cpp b/kdemm/simpleplayer.cpp
new file mode 100644
index 000000000..71e0edb18
--- /dev/null
+++ b/kdemm/simpleplayer.cpp
@@ -0,0 +1,198 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "simpleplayer.h"
+#include <kurl.h>
+#include <kglobal.h>
+#include <kinstance.h>
+#include <kaboutdata.h>
+
+namespace KDE
+{
+namespace Multimedia
+{
+
+class SimplePlayer::Private
+{
+ public:
+ Channel * channel;
+ Player * player;
+
+ KURL url;
+ Player::State state;
+ float channelvolume;
+ long time;
+ TQString title;
+ TQString type;
+};
+
+SimplePlayer::SimplePlayer( TQObject * parent, const char * name )
+ : TQObject( parent, name )
+ , d( new Private )
+{
+ connect( Factory::self(), TQT_SIGNAL( deleteYourObjects() ), TQT_SLOT( deleteYourObjects() ) );
+ connect( Factory::self(), TQT_SIGNAL( recreateObjects() ), TQT_SLOT( recreateObjects() ) );
+ d->channel = Factory::self()->createChannel( KGlobal::instance()->aboutData()->programName() );
+ d->player = Factory::self()->createPlayer();
+ if ( d->player ) {
+ d->player->setOutputChannel( d->channel );
+ connect( d->player, TQT_SIGNAL( stateChanged( KDE::Multimedia::Player::State, KDE::Multimedia::Player::State ) ),
+ TQT_SLOT( stateChanged( KDE::Multimedia::Player::State, KDE::Multimedia::Player::State ) ) );
+ connect( d->player, TQT_SIGNAL( finished() ), TQT_SIGNAL( finished() ) );
+ };
+}
+
+SimplePlayer::~SimplePlayer()
+{
+ delete d->player;
+ delete d->channel;
+}
+
+void SimplePlayer::play( const KURL & url )
+{
+ if( ! d->player )
+ return;
+ if( isPaused() && url == d->url )
+ {
+ d->player->play();
+ return;
+ }
+ if( ! d->player->load( url ) )
+ return;
+ d->url = url;
+ if( d->player->state() == Player::Stopped )
+ d->player->play();
+}
+
+void SimplePlayer::pause()
+{
+ if( ! d->player )
+ return;
+ d->player->pause();
+}
+
+void SimplePlayer::stop()
+{
+ if( ! d->player )
+ return;
+ d->player->stop();
+}
+
+long SimplePlayer::totalTime() const
+{
+ if( ! d->player )
+ return 0;
+ return d->player->totalTime();
+}
+
+long SimplePlayer::currentTime() const
+{
+ if( ! d->player )
+ return 0;
+ return d->player->currentTime();
+}
+
+void SimplePlayer::seek( long ms )
+{
+ if( ! d->player )
+ return;
+ d->player->seek( ms );
+}
+
+float SimplePlayer::volume() const
+{
+ if( ! d->player )
+ return 0;
+ return d->channel->volume();
+}
+
+void SimplePlayer::setVolume( float v )
+{
+ if( ! d->player )
+ return;
+ d->channel->setVolume( v );
+}
+
+bool SimplePlayer::isPlaying() const
+{
+ if( ! d->player )
+ return false;
+ return ( d->player->state() == Player::Playing );
+}
+
+bool SimplePlayer::isPaused() const
+{
+ if( ! d->player )
+ return false;
+ return ( d->player->state() == Player::Paused );
+}
+
+void SimplePlayer::stateChanged( Player::State ns, Player::State os )
+{
+ if( ! d->player )
+ return;
+ if( os == Player::Loading && ns == Player::Stopped )
+ d->player->play();
+}
+
+void SimplePlayer::deleteYourObjects()
+{
+ d->state = d->player->state();
+ d->channelvolume = d->channel->volume();
+ d->time = d->player->currentTime();
+ d->title = d->channel->channelName();
+ d->type = d->channel->channelType();
+
+ if( d->player )
+ d->player->stop();
+
+ delete d->player;
+ delete d->channel;
+ d->player = 0;
+ d->channel = 0;
+}
+
+void SimplePlayer::recreateObjects()
+{
+ d->channel = Factory::self()->createChannel( d->title, d->type );
+ d->channel->setVolume( d->channelvolume );
+
+ d->player = Factory::self()->createPlayer();
+ if( ! d->player )
+ return;
+
+ d->player->setOutputChannel( d->channel );
+
+ if( d->state != Player::NoMedia )
+ if( ! d->player->load( d->url ) )
+ return;
+ if( d->state == Player::Playing || d->state == Player::Paused || d->state == Player::Buffering )
+ {
+ d->player->play();
+ d->player->seek( d->time );
+ if( d->state == Player::Paused )
+ d->player->pause();
+ }
+}
+
+}} // namespaces
+
+#include "simpleplayer.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/simpleplayer.h b/kdemm/simpleplayer.h
new file mode 100644
index 000000000..f9575d21f
--- /dev/null
+++ b/kdemm/simpleplayer.h
@@ -0,0 +1,72 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef SIMPLEPLAYER_H
+#define SIMPLEPLAYER_H
+
+#include <kdemm/factory.h>
+#include <kdemm/channel.h>
+#include <kdemm/player.h>
+#include <tqobject.h>
+
+class KURL;
+
+namespace KDE
+{
+namespace Multimedia
+{
+
+class KDE_EXPORT SimplePlayer : public TQObject
+{
+ Q_OBJECT
+ public:
+ SimplePlayer( TQObject * parent = 0, const char * name = 0 );
+ ~SimplePlayer();
+
+ void play( const KURL & url );
+ void pause();
+ void stop();
+
+ long totalTime() const;
+ long currentTime() const;
+ void seek( long ms );
+
+ float volume() const;
+ void setVolume( float volume );
+
+ bool isPlaying() const;
+ bool isPaused() const;
+
+ signals:
+ void finished();
+
+ private slots:
+ void stateChanged( KDE::Multimedia::Player::State, KDE::Multimedia::Player::State );
+ void deleteYourObjects();
+ void recreateObjects();
+
+ private:
+ class Private;
+ Private * d;
+};
+
+}} // namespaces
+
+#endif // SIMPLEPLAYER_H
+// vim: sw=4 ts=4 noet tw=80
diff --git a/kdemm/test/Makefile.am b/kdemm/test/Makefile.am
new file mode 100644
index 000000000..d488da365
--- /dev/null
+++ b/kdemm/test/Makefile.am
@@ -0,0 +1,30 @@
+# This file is part of the KDE libraries
+# Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License version 2 as published by the Free Software Foundation.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+INCLUDES = -I$(top_srcdir)/kdemm $(all_includes)
+
+METASOURCES = AUTO
+
+check_PROGRAMS = guitest statetest
+
+guitest_SOURCES = main.cpp testwidget.cpp
+guitest_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+guitest_LDADD = $(LIB_KPARTS) $(top_builddir)/kdemm/libkdemm.la
+
+statetest_SOURCES = statetest.cpp
+statetest_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+statetest_LDADD = $(top_builddir)/kdemm/libkdemm.la
diff --git a/kdemm/test/main.cpp b/kdemm/test/main.cpp
new file mode 100644
index 000000000..eb42dc1ec
--- /dev/null
+++ b/kdemm/test/main.cpp
@@ -0,0 +1,38 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+#include "testwidget.h"
+
+int main( int argc, char ** argv )
+{
+ KAboutData about( "kdemmtest", "KDE Multimedia Test",
+ "0.1", "Testprogram",
+ KAboutData::License_LGPL, 0 );
+ about.addAuthor( "Matthias Kretz", 0, "kretz@kde.org" );
+ KCmdLineArgs::init( argc, argv, &about );
+ KApplication app;
+ TestWidget foo;
+ app.setMainWidget( &foo );
+ return app.exec();
+}
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/test/statetest.cpp b/kdemm/test/statetest.cpp
new file mode 100644
index 000000000..48ae444ee
--- /dev/null
+++ b/kdemm/test/statetest.cpp
@@ -0,0 +1,299 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "statetest.h"
+
+#include <kdemm/factory.h>
+#include <kdemm/channel.h>
+#include <kdemm/player.h>
+
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kurl.h>
+#include <cstdlib>
+
+using namespace KDE::Multimedia;
+
+kdbgstream& operator<<( kdbgstream & stream, const Player::State state )
+{
+ switch( state )
+ {
+ case Player::NoMedia:
+ stream << "NoMedia";
+ break;
+ case Player::Loading:
+ stream << "Loading";
+ break;
+ case Player::Stopped:
+ stream << "Stopped";
+ break;
+ case Player::Playing:
+ stream << "Playing";
+ break;
+ case Player::Buffering:
+ stream << "Buffering";
+ break;
+ case Player::Paused:
+ stream << "Paused";
+ break;
+ }
+
+ return stream;
+}
+
+void StateTester::run( const KURL & url )
+{
+ /*
+ check for correct states:
+
+ - after construction:
+ NoMedia
+
+ - load()
+ NoMedia -> NoMedia, (only? for remote files: Loading -> NoMedia, Stopped ), Stopped
+
+ - play()
+ Stopped, Paused -> Playing (except: Stopped -> Stopped)
+
+ - when playing:
+ Playing -> Buffering -> Playing
+
+ - pause()
+ Playing -> Paused
+
+ - stop()
+ Playing, Paused -> Stopped
+ */
+
+ f = Factory::self();
+ kdDebug() << "using backend: " << f->backendName() <<
+ "\n Comment: " << f->backendComment() <<
+ "\n Version: " << f->backendVersion() << endl;
+
+ c = f->createChannel( "teststates" );
+ p = f->createPlayer();
+ p->setOutputChannel( c );
+ connect( p, TQT_SIGNAL( stateChanged( KDE::Multimedia::Player::State, KDE::Multimedia::Player::State ) ),
+ TQT_SLOT( stateChanged( KDE::Multimedia::Player::State, KDE::Multimedia::Player::State ) ) );
+ connect( p, TQT_SIGNAL( finished() ), kapp, TQT_SLOT( quit() ) );
+
+ if( p->state() != Player::NoMedia )
+ kdDebug() << p->state() << " should be NoMedia" << endl;
+
+ kdDebug() << "loading " << url << endl;
+
+ if( ! p->load( url ) )
+ kdDebug() << "load failed" << endl;
+ if( p->state() == Player::Loading )
+ kdDebug() << "wait until Player finished Loading" << endl;
+ else if( p->state() == Player::Stopped )
+ testplaying();
+ else if( p->state() == Player::NoMedia )
+ {
+ kdDebug() << "could not load media. exiting." << endl;
+ exit( 0 );
+ }
+}
+
+void StateTester::stateChanged( Player::State newstate, Player::State oldstate )
+{
+ kdDebug() << "stateChanged( new = " << newstate << ", old = " << oldstate << " )" << endl;
+ switch( oldstate )
+ {
+ case Player::NoMedia:
+ switch( newstate )
+ {
+ case Player::NoMedia:
+ case Player::Loading:
+ case Player::Stopped:
+ return;
+ default:
+ break;
+ }
+ case Player::Loading:
+ switch( newstate )
+ {
+ case Player::NoMedia:
+ return;
+ case Player::Stopped:
+ testplaying();
+ return;
+ default:
+ break;
+ }
+ case Player::Stopped:
+ switch( newstate )
+ {
+ case Player::Playing:
+ case Player::Stopped:
+ return;
+ default:
+ break;
+ }
+ case Player::Playing:
+ switch( newstate )
+ {
+ case Player::Buffering:
+ //testbuffering();
+ case Player::Paused:
+ case Player::Stopped:
+ return;
+ default:
+ break;
+ }
+ case Player::Buffering:
+ switch( newstate )
+ {
+ case Player::Playing:
+ case Player::Stopped:
+ case Player::Paused:
+ return;
+ default:
+ break;
+ }
+ case Player::Paused:
+ switch( newstate )
+ {
+ case Player::Playing:
+ case Player::Stopped:
+ case Player::Buffering:
+ return;
+ default:
+ break;
+ }
+ }
+
+ wrongStateChange();
+}
+
+void StateTester::testplaying()
+{
+ if( ! p->play() )
+ kdDebug() << "play failed" << endl;
+ if( p->state() == Player::Stopped )
+ {
+ kdDebug() << "could not play media. exiting." << endl;
+ exit( 0 );
+ }
+ else if( p->state() == Player::Playing )
+ {
+ if( ! p->pause() )
+ {
+ kdDebug() << "pause failed" << endl;
+ if( p->state() != Player::Playing )
+ wrongStateChange();
+ }
+ else
+ {
+ if( p->state() != Player::Paused )
+ wrongStateChange();
+ if( ! p->play() )
+ {
+ kdDebug() << "play failed" << endl;
+ if( p->state() != Player::Paused )
+ wrongStateChange();
+ kdError() << "what now? play shouldn't fail here" << endl;
+ exit( 1 );
+ }
+ if( p->state() != Player::Playing )
+ wrongStateChange();
+ }
+ // it's playing now
+ if( ! p->stop() )
+ {
+ kdDebug() << "stop failed" << endl;
+ if( p->state() != Player::Playing )
+ wrongStateChange();
+ }
+ else
+ {
+ if( p->state() != Player::Stopped )
+ wrongStateChange();
+ if( ! p->play() )
+ {
+ kdDebug() << "play failed" << endl;
+ if( p->state() != Player::Stopped )
+ wrongStateChange();
+ kdError() << "play shouldn't fail after it worked before. exiting." << endl;
+ exit( 1 );
+ }
+ }
+ // it's playing again
+ if( ! p->pause() )
+ {
+ kdDebug() << "pause failed. exiting." << endl;
+ exit( 1 );
+ }
+ if( p->state() != Player::Paused )
+ wrongStateChange();
+ if( ! p->stop() )
+ {
+ kdDebug() << "stop failed" << endl;
+ if( p->state() != Player::Paused )
+ wrongStateChange();
+ exit( 1 );
+ }
+ if( p->state() != Player::Stopped )
+ wrongStateChange();
+ // do further checking, calling load again
+ kdDebug() << "success! playing the last 1/5 of the file now and quit on the finished signal" << endl;
+ p->play();
+ p->seek( p->totalTime() * 4 / 5 );
+ }
+}
+
+void StateTester::wrongStateChange()
+{
+ kdError() << "wrong state change in backend!" << endl;
+ exit( 1 );
+}
+
+static const KCmdLineOptions options[] =
+{
+ { "+url", I18N_NOOP( "media file to play" ), 0 },
+ KCmdLineLastOption // End of options.
+};
+
+int main( int argc, char ** argv )
+{
+ KAboutData about( "kdemmtest", "KDE Multimedia Test",
+ "0.1", "Testprogram",
+ KAboutData::License_LGPL, 0 );
+ about.addAuthor( "Matthias Kretz", 0, "kretz@kde.org" );
+ KCmdLineArgs::init( argc, argv, &about );
+ KCmdLineArgs::addCmdLineOptions( options );
+ KApplication app; // we need it for KTrader
+
+ StateTester tester;
+ if( KCmdLineArgs::parsedArgs()->count() > 0 )
+ tester.run( KCmdLineArgs::parsedArgs()->url( 0 ) );
+ else
+ {
+ KCmdLineArgs::usage();
+ exit( 2 );
+ }
+
+ return app.exec();
+}
+
+#include "statetest.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/test/statetest.h b/kdemm/test/statetest.h
new file mode 100644
index 000000000..cf912ac56
--- /dev/null
+++ b/kdemm/test/statetest.h
@@ -0,0 +1,57 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef STATETEST_H
+#define STATETEST_H
+
+#include <tqobject.h>
+
+#include <kdemm/player.h>
+
+class KURL;
+
+namespace KDE
+{
+ namespace Multimedia
+ {
+ class Factory;
+ class Channel;
+ }
+}
+
+class StateTester : public QObject
+{
+ Q_OBJECT
+ public:
+ void run( const KURL & );
+
+ private slots:
+ void stateChanged( KDE::Multimedia::Player::State, KDE::Multimedia::Player::State );
+
+ private:
+ void testplaying();
+ void wrongStateChange();
+
+ KDE::Multimedia::Factory * f;
+ KDE::Multimedia::Channel * c;
+ KDE::Multimedia::Player * p;
+};
+
+#endif // STATETEST_H
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/test/testwidget.cpp b/kdemm/test/testwidget.cpp
new file mode 100644
index 000000000..a9a579cd1
--- /dev/null
+++ b/kdemm/test/testwidget.cpp
@@ -0,0 +1,194 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "testwidget.h"
+
+#include <kdemm/factory.h>
+#include <kdemm/player.h>
+#include <kdemm/channel.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kurl.h>
+#include <tqslider.h>
+#include <tqlayout.h>
+#include <tqapplication.h>
+#include <tqpushbutton.h>
+#include <tqlabel.h>
+#include <klineedit.h>
+#include <kurlcompletion.h>
+
+using namespace KDE::Multimedia;
+
+TestWidget::TestWidget()
+ : TQWidget( 0, 0 )
+ , m_ticking( false )
+{
+ c = Factory::self()->createChannel( i18n( "KDE Multimedia testprogram" ) );
+ if( ! c )
+ kdFatal() << "couldn't create outputdevice" << endl;
+ po = Factory::self()->createPlayer();
+ if( ! po )
+ kdFatal() << "couldn't create Player" << endl;
+
+ if( ! po->setOutputChannel( c ) )
+ kdFatal() << "PlayObject::setOutputChannel failed" << endl;
+
+ if( ! po->state() == Player::NoMedia )
+ kdFatal() << "PlayObject in wrong state 1" << endl;
+
+ ( new TQHBoxLayout( this ) )->setAutoAdd( true );
+
+ m_v1slider = new TQSlider( this );
+ m_v1slider->setRange( 0, 150 );
+ m_v1slider->setValue( ( int )( 100 * po->volume() ) );
+ connect( m_v1slider, TQT_SIGNAL( valueChanged( int ) ), TQT_SLOT( v1changed( int ) ) );
+
+ m_v2slider = new TQSlider( this );
+ m_v2slider->setRange( 0, 150 );
+ m_v2slider->setValue( ( int )( 100 * c->volume() ) );
+ connect( m_v2slider, TQT_SIGNAL( valueChanged( int ) ), TQT_SLOT( v2changed( int ) ) );
+
+ TQFrame * frame = new TQFrame( this );
+ ( new TQVBoxLayout( frame ) )->setAutoAdd( true );
+
+ m_seekslider = new TQSlider( frame );
+ m_seekslider->setOrientation( Qt::Horizontal );
+ connect( m_seekslider, TQT_SIGNAL( valueChanged( int ) ), TQT_SLOT( seek( int ) ) );
+ po->setTickInterval( 100 );
+ connect( po, TQT_SIGNAL( tick( long ) ), TQT_SLOT( tick( long ) ) );
+ connect( po, TQT_SIGNAL( length( long ) ), TQT_SLOT( length( long ) ) );
+
+ m_statelabel = new TQLabel( frame );
+ connect( po, TQT_SIGNAL( stateChanged( KDE::Multimedia::Player::State, KDE::Multimedia::Player::State ) ),
+ TQT_SLOT( stateChanged( KDE::Multimedia::Player::State ) ) );
+ stateChanged( po->state() );
+
+ TQPushButton * pause = new TQPushButton( frame );
+ pause->setText( "pause" );
+ connect( pause, TQT_SIGNAL( clicked() ), po, TQT_SLOT( pause() ) );
+
+ TQPushButton * play = new TQPushButton( frame );
+ play->setText( "play" );
+ connect( play, TQT_SIGNAL( clicked() ), po, TQT_SLOT( play() ) );
+
+ TQPushButton * stop = new TQPushButton( frame );
+ stop->setText( "stop" );
+ connect( stop, TQT_SIGNAL( clicked() ), po, TQT_SLOT( stop() ) );
+
+ KLineEdit * file = new KLineEdit( frame );
+ file->setCompletionObject( new KURLCompletion( KURLCompletion::FileCompletion ) );
+ connect( file, TQT_SIGNAL( returnPressed( const TQString & ) ), TQT_SLOT( loadFile( const TQString & ) ) );
+
+ TQFrame * frame2 = new TQFrame( this );
+ ( new TQVBoxLayout( frame2 ) )->setAutoAdd( true );
+
+ m_volumelabel1 = new TQLabel( frame2 );
+ m_volumelabel1->setText( TQString::number( po->volume() ) );
+
+ m_volumelabel2 = new TQLabel( frame2 );
+ m_volumelabel2->setText( TQString::number( c->volume() ) );
+
+ m_totaltime = new TQLabel( frame2 );
+ m_totaltime->setText( TQString::number( po->totalTime() ) );
+
+ m_currenttime = new TQLabel( frame2 );
+ m_currenttime->setText( TQString::number( po->currentTime() ) );
+
+ m_remainingtime = new TQLabel( frame2 );
+ m_remainingtime->setText( TQString::number( po->remainingTime() ) );
+
+ show();
+
+ if( ! po->load( KURL( "/home/mkretz/Musik/qt23.mp3" ) ) )
+ kdFatal() << "PlayObject::load failed" << endl;
+
+ connect( po, TQT_SIGNAL( finished() ), qApp, TQT_SLOT( quit() ) );
+
+}
+
+void TestWidget::v1changed( int v )
+{
+ if( ! po->setVolume( ( ( float )v ) / 100 ) )
+ kdDebug() << "setVolume1 failed" << endl;
+ m_volumelabel1->setText( TQString::number( po->volume() ) );
+}
+
+void TestWidget::v2changed( int v )
+{
+ if( ! c->setVolume( ( ( float )v ) / 100 ) )
+ kdDebug() << "setVolume2 failed" << endl;
+ m_volumelabel2->setText( TQString::number( c->volume() ) );
+}
+
+void TestWidget::tick( long t )
+{
+ m_ticking = true;
+ m_seekslider->setValue( t );
+ m_currenttime->setText( TQString::number( po->currentTime() ) );
+ m_remainingtime->setText( TQString::number( po->remainingTime() ) );
+ m_ticking = false;
+}
+
+void TestWidget::stateChanged( Player::State newstate )
+{
+ switch( newstate )
+ {
+ case Player::NoMedia:
+ m_statelabel->setText( "NoMedia" );
+ break;
+ case Player::Loading:
+ m_statelabel->setText( "Loading" );
+ break;
+ case Player::Stopped:
+ m_statelabel->setText( "Stopped" );
+ break;
+ case Player::Paused:
+ m_statelabel->setText( "Paused" );
+ break;
+ case Player::Buffering:
+ m_statelabel->setText( "Buffering" );
+ break;
+ case Player::Playing:
+ m_statelabel->setText( "Playing" );
+ break;
+ }
+}
+
+void TestWidget::seek( int ms )
+{
+ if( ! m_ticking )
+ po->seek( ms );
+}
+
+void TestWidget::length( long ms )
+{
+ m_seekslider->setRange( 0, ms );
+ m_totaltime->setText( TQString::number( po->totalTime() ) );
+ m_currenttime->setText( TQString::number( po->currentTime() ) );
+ m_remainingtime->setText( TQString::number( po->remainingTime() ) );
+}
+
+void TestWidget::loadFile( const TQString & file )
+{
+ po->load( KURL( file ) );
+}
+
+#include "testwidget.moc"
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/test/testwidget.h b/kdemm/test/testwidget.h
new file mode 100644
index 000000000..7a9d0df72
--- /dev/null
+++ b/kdemm/test/testwidget.h
@@ -0,0 +1,64 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef TESTWIDGET_H
+#define TESTWIDGET_H
+
+#include <tqwidget.h>
+
+#include <kdemm/player.h>
+
+class TQSlider;
+class TQLabel;
+class TQString;
+
+namespace KDE
+{
+ namespace Multimedia
+ {
+ class Channel;
+ }
+}
+
+using namespace KDE::Multimedia;
+
+class TestWidget : public QWidget
+{
+ Q_OBJECT
+ public:
+ TestWidget();
+ private slots:
+ void v1changed( int );
+ void v2changed( int );
+ void tick( long );
+ void stateChanged( KDE::Multimedia::Player::State );
+ void seek( int );
+ void length( long );
+ void loadFile( const TQString & );
+
+ private:
+ TQSlider *m_v1slider, *m_v2slider, *m_seekslider;
+ TQLabel *m_statelabel, *m_volumelabel1, *m_volumelabel2, *m_totaltime, *m_currenttime, *m_remainingtime;
+ Channel * c;
+ Player * po;
+ bool m_ticking;
+};
+
+#endif // TESTWIDGET_H
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/videoplayer.cpp b/kdemm/videoplayer.cpp
new file mode 100644
index 000000000..e11705204
--- /dev/null
+++ b/kdemm/videoplayer.cpp
@@ -0,0 +1,34 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "videoplayer.h"
+
+namespace KDE
+{
+namespace Multimedia
+{
+VideoPlayer::VideoPlayer( TQObject * parent, const char * name )
+ : Player( parent, name )
+{
+}
+}} // namespaces
+
+#include "videoplayer.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/videoplayer.h b/kdemm/videoplayer.h
new file mode 100644
index 000000000..3bf26eba0
--- /dev/null
+++ b/kdemm/videoplayer.h
@@ -0,0 +1,54 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef VIDEOPLAYER_H
+#define VIDEOPLAYER_H
+
+#include "player.h"
+
+namespace KDE
+{
+namespace Multimedia
+{
+
+class VideoPlayer : public Player
+{
+ Q_OBJECT
+ public:
+ /**
+ * Create a widget that will show the video.
+ *
+ * \param parent The parent to use for the video widget
+ * \param name The TQObject name for the widget
+ *
+ * \returns Returns the video widget.
+ */
+ virtual TQWidget * createVideoWidget( TQWidget * parent, const char * name ) = 0;
+
+ protected:
+ /**
+ * You can not instantiate players yourself, use the Factory to
+ * create them.
+ */
+ VideoPlayer( TQObject * parent, const char * name );
+};
+
+}} //namespaces
+#endif // VIDEOPLAYER_H
+// vim: sw=4 ts=4 tw=80 noet
diff --git a/kdemm/volumecontrold/Makefile.am b/kdemm/volumecontrold/Makefile.am
new file mode 100644
index 000000000..b7c7ca729
--- /dev/null
+++ b/kdemm/volumecontrold/Makefile.am
@@ -0,0 +1,31 @@
+# This file is part of the KDE project
+# Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License version 2 as published by the Free Software Foundation.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+INCLUDES = -I$(top_srcdir) $(all_includes)
+
+kde_module_LTLIBRARIES = kded_volumecontrold.la
+
+kded_volumecontrold_la_LDFLAGS = $(all_libraries) -module -avoid-version
+kded_volumecontrold_la_LIBADD = ../libkdemm.la
+kded_volumecontrold_la_SOURCES = volumecontrold.cpp volumecontrold.skel
+
+METASOURCES = AUTO
+
+noinst_HEADERS = volumecontrold.h
+
+services_DATA = volumecontrold.desktop
+servicesdir = $(kde_servicesdir)/kded
diff --git a/kdemm/volumecontrold/volumecontrold.cpp b/kdemm/volumecontrold/volumecontrold.cpp
new file mode 100644
index 000000000..41fbc40fd
--- /dev/null
+++ b/kdemm/volumecontrold/volumecontrold.cpp
@@ -0,0 +1,47 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "volumecontrold.h"
+
+#include <kapplication.h>
+#include <dcopclient.h>
+
+extern "C"
+{
+ KDEDModule * create_volumecontrold( const TQCString &name )
+ {
+ return new VolumeControlD( name );
+ }
+}
+
+class VolumeControlD::Private
+{
+ public:
+};
+
+VolumeControlD::VolumeControlD( const TQCString & name )
+ : KDEDModule( name )
+{
+ connect( KApplication::dcopClient(), TQT_SIGNAL( applicationRemoved( const TQCString & ) ),
+ TQT_SLOT( applicationRemoved( const TQCString& ) ) );
+}
+
+#include "volumecontrold.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/kdemm/volumecontrold/volumecontrold.desktop b/kdemm/volumecontrold/volumecontrold.desktop
new file mode 100644
index 000000000..8c0bde15f
--- /dev/null
+++ b/kdemm/volumecontrold/volumecontrold.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+ServiceTypes=KDEDModule
+
+X-KDE-ModuleType=Library
+X-KDE-Library=volumecontrold
+X-KDE-FactoryName=volumecontrold
+X-KDE-Kded-autoload=false
+X-KDE-Kded-load-on-demand=true
+
+Name=Volume Control
+Comment=volume control daemon module for KDED
diff --git a/kdemm/volumecontrold/volumecontrold.h b/kdemm/volumecontrold/volumecontrold.h
new file mode 100644
index 000000000..709323c47
--- /dev/null
+++ b/kdemm/volumecontrold/volumecontrold.h
@@ -0,0 +1,53 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef VOLUMECONTROLD_H
+#define VOLUMECONTROLD_H
+
+#include <kded/kdedmodule.h>
+#include <tqstringlist.h>
+
+class VolumeControlD : public KDEDModule
+{
+ Q_OBJECT
+ K_DCOP
+ public:
+ VolumeControlD(const TQCString &name);
+ virtual ~VolumeControlD();
+
+ k_dcop:
+ // think of some better API here...
+ TQStringList availableChannels() const;
+ TQStringList openConnectionsToChannel( const TQString & channel ) const;
+ float volume( const TQString & connection, const TQString & channel ) const;
+ void setVolume( const TQString & connection, const TQString & channel, float volume );
+
+ private slots:
+ /**
+ * When an app with a registered Channel goes down we want to notice...
+ */
+ void applicationRemoved( const TQCString & );
+
+ private:
+ class Private;
+ Private * d;
+};
+
+// vim: sw=4 ts=4 tw=80 noet
+#endif // VOLUMECONTROLD_H