summaryrefslogtreecommitdiffstats
path: root/arts
diff options
context:
space:
mode:
Diffstat (limited to 'arts')
-rw-r--r--arts/Makefile.am9
-rw-r--r--arts/configure.in.in75
-rw-r--r--arts/kde/Makefile.am40
-rw-r--r--arts/kde/README51
-rw-r--r--arts/kde/artskde.idl41
-rw-r--r--arts/kde/kartsdispatcher.cc60
-rw-r--r--arts/kde/kartsdispatcher.h87
-rw-r--r--arts/kde/kartsfloatwatch.cpp64
-rw-r--r--arts/kde/kartsfloatwatch.h82
-rw-r--r--arts/kde/kartsserver.cpp111
-rw-r--r--arts/kde/kartsserver.h75
-rw-r--r--arts/kde/kaudioconverter.cc198
-rw-r--r--arts/kde/kaudioconverter.h65
-rw-r--r--arts/kde/kaudiomanagerplay.cpp90
-rw-r--r--arts/kde/kaudiomanagerplay.h84
-rw-r--r--arts/kde/kaudioplaystream.cpp210
-rw-r--r--arts/kde/kaudioplaystream.h127
-rw-r--r--arts/kde/kaudioplaystream_p.h84
-rw-r--r--arts/kde/kaudiorecordstream.cpp269
-rw-r--r--arts/kde/kaudiorecordstream.h165
-rw-r--r--arts/kde/kaudiorecordstream_p.h62
-rw-r--r--arts/kde/kconverttest.cc96
-rw-r--r--arts/kde/kconverttest.h46
-rw-r--r--arts/kde/kdatarequest_impl.cpp80
-rw-r--r--arts/kde/kdatarequest_impl.h59
-rw-r--r--arts/kde/kioinputstream_impl.cpp236
-rw-r--r--arts/kde/kioinputstream_impl.h89
-rw-r--r--arts/kde/kiotest.cc54
-rw-r--r--arts/kde/kiotestslow.cc131
-rw-r--r--arts/kde/kplayobject.cc303
-rw-r--r--arts/kde/kplayobject.h306
-rw-r--r--arts/kde/kplayobjectcreator.cc104
-rw-r--r--arts/kde/kplayobjectcreator.h56
-rw-r--r--arts/kde/kplayobjectfactory.cc258
-rw-r--r--arts/kde/kplayobjectfactory.h156
-rw-r--r--arts/kde/kplayobjectfactory_p.h46
-rw-r--r--arts/kde/kvideowidget.cpp446
-rw-r--r--arts/kde/kvideowidget.h82
-rw-r--r--arts/kde/mcop-dcop/Makefile.am20
-rw-r--r--arts/kde/mcop-dcop/kmcop.cpp171
-rw-r--r--arts/kde/mcop-dcop/kmcop.desktop90
-rw-r--r--arts/kde/mcop-dcop/kmcop.h50
-rw-r--r--arts/kde/mcop-dcop/mcopdcopobject.cpp152
-rw-r--r--arts/kde/mcop-dcop/mcopdcopobject.h89
-rw-r--r--arts/kde/mcop-dcop/mcopdcoptools.h47
-rw-r--r--arts/knotify/Makefile.am27
-rw-r--r--arts/knotify/README33
-rw-r--r--arts/knotify/knotify.cpp800
-rw-r--r--arts/knotify/knotify.desktop119
-rw-r--r--arts/knotify/knotify.h111
-rw-r--r--arts/knotify/knotifytest.cpp19
-rw-r--r--arts/message/Makefile.am8
-rw-r--r--arts/message/artsmessage.cc93
53 files changed, 6426 insertions, 0 deletions
diff --git a/arts/Makefile.am b/arts/Makefile.am
new file mode 100644
index 000000000..31bd7bbbd
--- /dev/null
+++ b/arts/Makefile.am
@@ -0,0 +1,9 @@
+if include_ARTS
+SUBDIRS = kde knotify message
+else
+SUBDIRS = knotify
+endif
+
+DOXYGEN_REFERENCES = kio kdecore kdeui
+include ../admin/Doxyfile.am
+
diff --git a/arts/configure.in.in b/arts/configure.in.in
new file mode 100644
index 000000000..6571c8b68
--- /dev/null
+++ b/arts/configure.in.in
@@ -0,0 +1,75 @@
+
+dnl aRts specific configure tests
+dnl
+
+dnl
+dnl ensure that the user has aRts-1.1.0 or newer installed
+dnl
+
+dnl Check for artsc-config
+dnl no need to, AC_BASE_PATH_KDE does it for us already (see also
+dnl comment below for mcopidl)
+dnl AC_PATH_PROG(ARTSCCONFIG, artsc-config, no)
+
+ARTS_WANT_VERSION_MAJOR=1
+ARTS_WANT_VERSION_MINOR=1
+ARTS_HAVE_VERSION=none
+ARTS_HAVE_PREFIX=none
+
+dnl Check for Glib-2.0
+AC_MSG_CHECKING(for aRts-$ARTS_WANT_VERSION_MAJOR.$ARTS_WANT_VERSION_MINOR)
+
+ARTS_OK=no
+
+if test "$build_arts" != "yes"; then
+ AC_MSG_RESULT(disabled)
+else
+
+ if test "x$ARTSCCONFIG" != "xno"; then
+ ARTS_HAVE_VERSION=`$ARTSCCONFIG --arts-version`
+ ARTS_HAVE_PREFIX=`$ARTSCCONFIG --arts-prefix`
+ fi
+
+ # And delete superfluous '/' to make compares easier
+ ARTS_HAVE_PREFIX=`echo "$ARTS_HAVE_PREFIX" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+
+ ARTS_MAJOR=`echo $ARTS_HAVE_VERSION | sed 's/\.[[0-9]]*\.[[0-9]]*$//'`
+ ARTS_MINOR=`echo $ARTS_HAVE_VERSION | sed 's/\.[[0-9]]*$//' | sed 's/^[[0-9]]*\.//'`
+ dnl don't look at the micro version
+ if test "x$ARTS_MAJOR" != "x" && test "x$ARTS_MINOR" != "x" && test $ARTS_MAJOR -ge $ARTS_WANT_VERSION_MAJOR && test $ARTS_MINOR -ge $ARTS_WANT_VERSION_MINOR; then
+ realartsprefix=`(cd $ARTS_HAVE_PREFIX; /bin/pwd)`
+ realprefix=`(cd $prefix; /bin/pwd)`
+ if test "x$realartsprefix" = "x$realprefix"; then
+ ARTS_OK=yes
+ else
+ AC_MSG_ERROR([aRts $ARTS_WANT_VERSION_MAJOR.$ARTS_WANT_VERSION_MINOR not installed in the same prefix as KDE!
+Please reinstall aRts in the same prefix as KDE, different prefixes are not
+supported right now.
+
+(kdelibs prefix is $prefix, aRts prefix is $ARTS_HAVE_PREFIX)
+ ])
+ fi
+ fi
+
+ AC_MSG_RESULT($ARTS_OK)
+
+ if test "x$ARTS_OK" = "xno"; then
+ AC_MSG_ERROR([aRts $ARTS_WANT_VERSION_MAJOR.$ARTS_WANT_VERSION_MINOR not found.
+
+You'll need to install a suitable version of aRts in the same prefix as KDE
+before you build kdelibs.
+
+(found
+ * artsc-config: $ARTSCCONFIG
+ * kdelibs prefix: $prefix
+ * aRts prefix: $ARTS_HAVE_PREFIX
+ * aRts version: $ARTS_HAVE_VERSION (required: $ARTS_WANT_VERSION_MAJOR.$ARTS_WANT_VERSION_MINOR)
+)
+])
+ fi
+fi
+
+dnl AC_BASE_PATH_KDE already checks for mcopidl, and it does it the
+dnl right way using KDE_FIND_PATH
+dnl AC_PATH_PROG(MCOPIDL, mcopidl, no)
+dnl AC_SUBST(MCOPIDL)
diff --git a/arts/kde/Makefile.am b/arts/kde/Makefile.am
new file mode 100644
index 000000000..5a933ba68
--- /dev/null
+++ b/arts/kde/Makefile.am
@@ -0,0 +1,40 @@
+INCLUDES = -I$(top_builddir)/arts/kde \
+ -I$(top_srcdir) -I$(includedir)/arts $(all_includes)
+
+lib_LTLIBRARIES = libartskde.la
+libartskde_la_SOURCES = artskde.cc kioinputstream_impl.cpp kplayobject.cc \
+ kplayobjectfactory.cc kartsfloatwatch.cpp kartsdispatcher.cc \
+ kaudiorecordstream.cpp kaudioplaystream.cpp \
+ kartsserver.cpp kdatarequest_impl.cpp kaudioconverter.cc \
+ kvideowidget.cpp kplayobjectcreator.cc \
+ kaudiomanagerplay.cpp
+libartskde_la_LIBADD = $(LIB_KIO) -lqtmcop -lsoundserver_idl
+libartskde_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 3:0:2
+libartskde_la_METASOURCES = AUTO
+libartskde_la_COMPILE_FIRST = artskde.h
+
+artskdeincludedir = $(includedir)/arts
+artskdeinclude_HEADERS = kplayobject.h kplayobjectfactory.h kartsfloatwatch.h \
+ artskde.h kartsdispatcher.h \
+ kaudiorecordstream.h kaudioplaystream.h \
+ kartsserver.h kvideowidget.h kaudiomanagerplay.h
+noinst_HEADERS = kplayobjectcreator.h kplayobjectfactory_p.h
+
+artskde.mcoptype: artskde.h
+artskde.mcopclass: artskde.h
+MCOPINC = -I$(srcdir)
+artskde.cc artskde.h: $(top_srcdir)/arts/kde/artskde.idl $(MCOPIDL)
+ $(MCOPIDL) -I$(includedir)/arts -t $(MCOPINC) $(top_srcdir)/arts/kde/artskde.idl
+
+DISTCLEANFILES = artskde.cc artskde.h artskde.mcoptype artskde.mcopclass
+
+check_PROGRAMS = kiotest kiotestslow kconverttest
+kiotest_SOURCES = kiotest.cc
+kiotestslow_SOURCES = kiotestslow.cc
+kconverttest_SOURCES = kconverttest.cc
+
+kiotest_LDADD = libartskde.la -lqtmcop -lkmedia2 -lsoundserver_idl
+kiotestslow_LDADD = $(kiotest_LDADD)
+kconverttest_LDADD = $(kiotest_LDADD)
+
+# vim: ts=8 noet
diff --git a/arts/kde/README b/arts/kde/README
new file mode 100644
index 000000000..2d34f08fd
--- /dev/null
+++ b/arts/kde/README
@@ -0,0 +1,51 @@
+libartskde Introduction
+-----------------------
+
+1. What is libartskde?
+libartskde is a simple KDE->aRts wrapper
+that allows the developer to use KDE
+technology to access aRts.
+ie. no need to deal with std::string's anymore
+etc.. you can just use QString's or KURL's
+to play sound
+
+2. How to use it to play sounds?
+<snip>
+1 KArtsDispatcher dispatcher;
+2 KArtsServer server;
+
+3 KURL file = "file:/home/nikoz/test.mp3";
+
+4 KPlayObjectFactory factory(server.server());
+5 KPlayObject *playobj = factory.createPlayObject(file, true);
+
+6 playobj->play();
+<snap>
+
+Line:
+1 Sets up the a KArtsDispatcher
+2 Starts a new SoundServerV2 in the running artsd process
+
+3 Simple test URL to demonstrate the use with KURL
+
+4 Creates a KPlayObjectFactory, parameter: our SoundServerV2
+5 Gets a KPlayObject from the factory, containing an Arts::PlayObject
+ created in our running artsd process
+ Parameters:
+ KURL url
+ (specifies the url to be played)
+ bool createBUS
+ (specifies wheter to create a Synth_BUS_UPLINK or not, "false" is only interesting if you want to use EffectsStacks etc..., see Noatun)
+6 Play the file
+
+That's it, with 6 LOC a "full" media player :)
+
+To make the example above compile you will also have to add these #includes:
+#include <arts/kartsserver.h>
+#include <arts/kartsdispatcher.h>
+#include <arts/kplayobject.h>
+#include <arts/kplayobjectfactory.h>
+
+Enjoy...
+Nikolas Zimmermann
+<wildfox@kde.org>
diff --git a/arts/kde/artskde.idl b/arts/kde/artskde.idl
new file mode 100644
index 000000000..f31b49ed4
--- /dev/null
+++ b/arts/kde/artskde.idl
@@ -0,0 +1,41 @@
+#include <kmedia2.idl>
+
+module Arts {
+
+/*
+ * notification proxy for floats, used internally!
+ */
+interface KFloatWatchProxy {
+ attribute float value;
+};
+
+/*
+ * used for deliviering MCOP data to the playobjects
+ */
+interface KIOInputStream : InputStream {
+ boolean openURL(string url);
+
+ attribute long bufferPackets;
+
+ long packetSize();
+};
+
+/*
+ * used for piping raw data to KAudioConverter from the POs
+ */
+interface KDataRequest : SynthModule {
+ void goOn();
+
+ default in audio stream left, right;
+};
+
+/*
+ * TESTING ONLY
+ */
+
+interface KIOTestSlow : SynthModule {
+ async in byte stream data;
+
+ attribute InputStream inputStream;
+};
+};
diff --git a/arts/kde/kartsdispatcher.cc b/arts/kde/kartsdispatcher.cc
new file mode 100644
index 000000000..e6136ce12
--- /dev/null
+++ b/arts/kde/kartsdispatcher.cc
@@ -0,0 +1,60 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include <qiomanager.h>
+#include <dispatcher.h>
+
+#include <kdebug.h>
+
+#include "kartsdispatcher.moc"
+
+int KArtsDispatcher::m_refCount = 0;
+Arts::Dispatcher *KArtsDispatcher::artsDispatcher = 0;
+Arts::QIOManager *KArtsDispatcher::artsQIOManager = 0;
+
+KArtsDispatcher::KArtsDispatcher(QObject *parent, const char *name)
+ : QObject(parent, name)
+{
+ m_refCount++;
+ if(artsDispatcher == 0)
+ {
+ if (!Arts::Dispatcher::the()) // only if no Arts::Dispatcher is created yet
+ {
+ artsQIOManager = new Arts::QIOManager();
+ artsDispatcher = new Arts::Dispatcher(artsQIOManager);
+ }
+ else
+ kdWarning(400) << "An Arts::Dispatcher() instance exists already while trying to instantiate KArtsDispatcher!" << endl;
+ }
+}
+
+KArtsDispatcher::~KArtsDispatcher()
+{
+ m_refCount--;
+ if(m_refCount == 0)
+ {
+ delete KArtsDispatcher::artsDispatcher;
+ artsDispatcher = 0;
+
+ delete KArtsDispatcher::artsQIOManager;
+ artsQIOManager = 0;
+ }
+}
diff --git a/arts/kde/kartsdispatcher.h b/arts/kde/kartsdispatcher.h
new file mode 100644
index 000000000..db2792a97
--- /dev/null
+++ b/arts/kde/kartsdispatcher.h
@@ -0,0 +1,87 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KARTSDISPATCHER_H
+#define KARTSDISPATCHER_H
+
+#include <qobject.h>
+
+#include <kdelibs_export.h>
+
+namespace Arts
+{
+ class QIOManager;
+ class Dispatcher;
+}
+
+/**
+ * KArtsDispatcher ensures that an instance of Arts::Dispatcher using an
+ * Arts::QIOManager exists. When the last KArtsDispatcher is deleted, the
+ * Arts::Dispatcher is released as well.
+ *
+ * Using KArtsDispatcher is especially useful in setups where another plugin
+ * might also already use an Arts::Dispatcher, for instance in konqueror.
+ *
+ * \code
+ * {
+ * // old code
+ * Arts::QIOManager qiomanager;
+ * Arts::Dispatcher dispatcher(&qiomanager);
+ *
+ * Arts::SoundServer server = Arts::Reference("global:Arts_SoundServer");
+ * server.play("/usr/share/sounds/pop.wav");
+ * }
+ * \endcode
+ *
+ * \code
+ * {
+ * // new code
+ * KArtsDispatcher dispatcher;
+ *
+ * Arts::SoundServer server = Arts::Reference("global:Arts_SoundServer");
+ * server.play("/usr/share/sounds/pop.wav");
+ * }
+ * \endcode
+ */
+class KDE_EXPORT KArtsDispatcher : public QObject
+{
+Q_OBJECT
+public:
+ /**
+ * Constructor.
+ *
+ * @param parent the parent Qt object
+ * @param name the Qt object name of this object
+ */
+ KArtsDispatcher(QObject *parent = 0, const char *name = 0);
+
+ /**
+ * Destructor
+ */
+ ~KArtsDispatcher();
+
+private:
+ static int m_refCount;
+ static Arts::Dispatcher *artsDispatcher;
+ static Arts::QIOManager *artsQIOManager;
+};
+
+#endif
diff --git a/arts/kde/kartsfloatwatch.cpp b/arts/kde/kartsfloatwatch.cpp
new file mode 100644
index 000000000..d26d76718
--- /dev/null
+++ b/arts/kde/kartsfloatwatch.cpp
@@ -0,0 +1,64 @@
+ /*
+
+ Copyright (C) 2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include "artskde.h"
+#include "kartsfloatwatch.moc"
+#include "connect.h"
+
+using namespace Arts;
+
+class KArtsFloatWatchPrivate {
+public:
+ KFloatWatchProxy proxy;
+};
+
+namespace Arts {
+
+class KFloatWatchProxy_impl : public KFloatWatchProxy_skel {
+protected:
+ KArtsFloatWatch *watch;
+public:
+ KFloatWatchProxy_impl(KArtsFloatWatch *watch) : watch(watch) { };
+
+ float value() { return 0.0; /* dummy */ }
+ void value(float newValue) { watch->change(newValue); }
+};
+
+}
+
+KArtsFloatWatch::KArtsFloatWatch(Arts::Object object, const char *stream,
+ QObject *parent, const char *name) : QObject(parent, name)
+{
+ d = new KArtsFloatWatchPrivate();
+ d->proxy = KFloatWatchProxy::_from_base(new KFloatWatchProxy_impl(this));
+ Arts::connect(object, stream, d->proxy, "value");
+}
+
+KArtsFloatWatch::~KArtsFloatWatch()
+{
+ delete d;
+}
+
+void KArtsFloatWatch::change(float newValue)
+{
+ emit valueChanged(newValue);
+}
diff --git a/arts/kde/kartsfloatwatch.h b/arts/kde/kartsfloatwatch.h
new file mode 100644
index 000000000..6c23327ea
--- /dev/null
+++ b/arts/kde/kartsfloatwatch.h
@@ -0,0 +1,82 @@
+ /*
+
+ Copyright (C) 2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include "common.h"
+#include <qobject.h>
+
+class KArtsFloatWatchPrivate;
+namespace Arts { class KFloatWatchProxy_impl; }
+
+/**
+ * KArtsFloatWatch offers an easy way to watch aRts streams via Qt signals.
+ * For instance, if you have an object of the following type:
+ *
+ * \code
+ * interface StereoVolumeControl : StereoEffect {
+ * attribute float scaleFactor;
+ * readonly attribute float currentVolumeLeft;
+ * readonly attribute float currentVolumeRight;
+ * };
+ * \endcode
+ *
+ * and you want to get notified when scaleFactor changes, you could do it
+ * like this:
+ *
+ * \code
+ * StereoVolumeControl stereoVolumeControl = ...;
+ * KArtsFloatWatch *w = new KArtsFloatWatch(stereoVolumeControl, "scaleFactor_changed", this);
+ * connect(w, SIGNAL(valueChanged(float)), this, SLOT(setValue(float)));
+ * \endcode
+ */
+class KArtsFloatWatch : public QObject {
+ Q_OBJECT
+private:
+ KArtsFloatWatchPrivate *d;
+ friend class Arts::KFloatWatchProxy_impl;
+
+ /**
+ * called by the proxy (internal)
+ */
+ void change(float newValue);
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param object the aRts object that should be watched
+ * @param stream the aRts stream that should be watched
+ * @param parent the parent Qt object
+ * @param name the Qt object name of this object
+ */
+ KArtsFloatWatch(Arts::Object object, const char *stream, QObject *parent = 0, const char *name = 0);
+
+ /**
+ * Destructor
+ */
+ ~KArtsFloatWatch();
+
+signals:
+ /**
+ * this signal will be emitted with values of the aRts stream
+ */
+ void valueChanged(float newValue);
+};
diff --git a/arts/kde/kartsserver.cpp b/arts/kde/kartsserver.cpp
new file mode 100644
index 000000000..9b4739928
--- /dev/null
+++ b/arts/kde/kartsserver.cpp
@@ -0,0 +1,111 @@
+// Copyright (c) 2000-2001 Charles Samuels <charles@kde.org>
+// Neil Stevens <neil@qualityassistant.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIAB\ILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include <flowsystem.h>
+#include <ksimpleconfig.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <qdir.h>
+#include <qfile.h>
+#include "kartsserver.h"
+
+struct KArtsServer::Data
+{
+ Arts::SoundServerV2 server;
+};
+
+KArtsServer::KArtsServer(QObject *parent, const char *name)
+ : QObject(parent, name)
+ , d(new Data)
+{
+ d->server = Arts::SoundServerV2::null();
+}
+
+KArtsServer::~KArtsServer(void)
+{
+ d->server = Arts::SoundServerV2::null();
+ delete d;
+}
+
+Arts::SoundServerV2 KArtsServer::server(void)
+{
+ bool error = d->server.error();
+ if( d->server.isNull() || error )
+ {
+ d->server = Arts::Reference("global:Arts_SoundServerV2");
+ if( error && !d->server.isNull() && !d->server.error() )
+ emit restartedServer();
+ }
+
+ if(!d->server.isNull() && !d->server.error())
+ return d->server;
+
+ // aRts seems not to be running, let's try to run it
+ // First, let's read the configuration as in kcmarts
+ KConfig config("kcmartsrc", false /*bReadOnly*/, false /*bUseKDEGlobals*/);
+ KProcess proc;
+
+ config.setGroup("Arts");
+
+ bool rt = config.readBoolEntry("StartRealtime", false);
+ bool x11Comm = config.readBoolEntry("X11GlobalComm", false);
+
+ // put the value of x11Comm into .mcoprc
+ KSimpleConfig X11CommConfig(QDir::homeDirPath()+"/.mcoprc");
+
+ if(x11Comm)
+ X11CommConfig.writeEntry("GlobalComm", "Arts::X11GlobalComm");
+ else
+ X11CommConfig.writeEntry("GlobalComm", "Arts::TmpGlobalComm");
+
+ X11CommConfig.sync();
+
+ proc << QFile::encodeName(KStandardDirs::findExe(QString::fromLatin1("kdeinit_wrapper")));
+
+ if(rt)
+ proc << QFile::encodeName(KStandardDirs::findExe(QString::fromLatin1("artswrapper")));
+ else
+ proc << QFile::encodeName(KStandardDirs::findExe(QString::fromLatin1("artsd")));
+
+ proc << QStringList::split( " ", config.readEntry( "Arguments", "-F 10 -S 4096 -s 60 -m artsmessage -l 3 -f" ) );
+
+ if(proc.start(KProcess::Block) && proc.normalExit())
+ {
+ // We could have a race-condition here.
+ // The correct way to do it is to make artsd fork-and-exit
+ // after starting to listen to connections (and running artsd
+ // directly instead of using kdeinit), but this is better
+ // than nothing.
+ int time = 0;
+ do
+ {
+ sleep(1);
+ d->server = Arts::Reference("global:Arts_SoundServerV2");
+ } while(++time < 5 && (d->server.isNull()));
+
+ emit restartedServer();
+ }
+ // TODO else what?
+
+ return d->server;
+}
+
+// vim: sw=4 ts=4 noet
+#include "kartsserver.moc"
diff --git a/arts/kde/kartsserver.h b/arts/kde/kartsserver.h
new file mode 100644
index 000000000..8456e25ea
--- /dev/null
+++ b/arts/kde/kartsserver.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2000-2001 Charles Samuels <charles@kde.org>
+// Neil Stevens <neil@qualityassistant.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIAB\ILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef KARTSSERVER_H
+#define KARTSSERVER_H
+
+#include "kmedia2.h"
+#include <qobject.h>
+#include "soundserver.h"
+#include <kdelibs_export.h>
+
+/**
+ * KArtsServer is a wrapper to conveniently get a reference to a SoundServer,
+ * and restart artsd when necessary, using the kcontrol settings.
+ *
+ * Of course we'd rather that artsd never crashed, and that all users start
+ * artsd on KDE startup, but at the very least there will always be third
+ * party PlayObjects that will crash. So, this is necessary.
+ */
+class KDE_ARTS_EXPORT KArtsServer : public QObject
+{
+Q_OBJECT
+
+public:
+ /**
+ * Create a new KArtsServer. Don't forget to create a KArtsDispatcher
+ * before using KArtsServer.
+ */
+ KArtsServer(QObject *parent = 0, const char *name = 0);
+ virtual ~KArtsServer(void);
+
+ /**
+ * Get a verified reference to the SoundServerV2, (re)starting artsd
+ * using the kcontrol-specified settings if necessary.
+ *
+ * If the soundserver has changed since you called this method the last
+ * time (meaning artsd was restarted) restartedServer() will be emitted.
+ */
+ Arts::SoundServerV2 server(void);
+
+signals:
+ /**
+ * This is emitted when the soundserver has been restarted (by this
+ * KArtsServer instance or outside). It is not
+ * emitted automatically when the soundserver comes up but only after
+ * your code calls server().
+ */
+ void restartedServer(void);
+
+private:
+ KArtsServer(const KArtsServer &rhs);
+ KArtsServer &operator=(const KArtsServer &rhs);
+
+ struct Data;
+ Data *d;
+};
+
+#endif
diff --git a/arts/kde/kaudioconverter.cc b/arts/kde/kaudioconverter.cc
new file mode 100644
index 000000000..a5f1e8e43
--- /dev/null
+++ b/arts/kde/kaudioconverter.cc
@@ -0,0 +1,198 @@
+ /*
+
+ Copyright (C) 2002 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include "config.h"
+#include "artskde.h"
+#include "connect.h"
+#include "flowsystem.h"
+#include "audiosubsys.h"
+#include "dynamicrequest.h"
+#include "kdatarequest_impl.h"
+#include "kioinputstream_impl.h"
+#include "kaudioconverter.moc"
+
+#include <iostream>
+
+#include <qfile.h>
+#include <qtimer.h>
+
+#include <kurl.h>
+#include <kdebug.h>
+#include <kmimetype.h>
+#include <kapplication.h>
+
+using namespace std;
+
+KAudioConverter::KAudioConverter()
+{
+ m_incoming = 0;
+ m_started = false;
+}
+
+KAudioConverter::~KAudioConverter()
+{
+ delete m_incoming;
+}
+
+bool KAudioConverter::setup(int samplingRate)
+{
+ string backupAudioIO = Arts::AudioSubSystem::the()->audioIO();
+ int backupSamplingRate = Arts::AudioSubSystem::the()->samplingRate();
+
+ Arts::AudioSubSystem::the()->audioIO("null");
+ Arts::AudioSubSystem::the()->samplingRate(samplingRate);
+
+ if(!Arts::AudioSubSystem::the()->open())
+ {
+ Arts::AudioSubSystem::the()->audioIO(backupAudioIO);
+ Arts::AudioSubSystem::the()->samplingRate(backupSamplingRate);
+
+ return false;
+ }
+
+ return true;
+}
+
+void KAudioConverter::slotMimeType(const QString &mimeType)
+{
+ m_mimeType = mimeType;
+ kapp->exit_loop();
+}
+
+void KAudioConverter::requestPlayObject(const KURL &url)
+{
+ string queryInterface = "Arts::PlayObject";
+
+ Arts::KIOInputStream inputStream;
+
+ if(!url.isLocalFile())
+ {
+ Arts::KIOInputStream_impl *inputStreamImpl = new Arts::KIOInputStream_impl();
+ inputStream = Arts::KIOInputStream::_from_base(inputStreamImpl);
+
+ QObject::connect(inputStreamImpl, SIGNAL(mimeTypeFound(const QString &)), SLOT(slotMimeType(const QString &)));
+
+ inputStream.openURL(url.url().latin1());
+ inputStream.streamStart();
+
+ // ugly hacks.. :/
+ kapp->enter_loop();
+
+ queryInterface = "Arts::StreamPlayObject";
+ }
+ else
+ {
+ KMimeType::Ptr mimetype = KMimeType::findByURL(url);
+ m_mimeType = mimetype->name();
+ }
+
+ Arts::TraderQuery query;
+ query.supports("Interface", queryInterface);
+ query.supports("MimeType", string(m_mimeType.latin1()));
+
+ string objectType;
+
+ vector<Arts::TraderOffer> *offers = query.query();
+ if(!offers->empty())
+ objectType = offers->front().interfaceName(); // first offer
+
+ delete offers;
+
+ if(objectType.empty())
+ {
+ m_incoming = 0;
+ return;
+ }
+
+ if(!url.isLocalFile())
+ {
+ Arts::StreamPlayObject result = Arts::SubClass(objectType);
+ result.streamMedia(inputStream);
+ result._node()->start();
+
+ m_incoming = new KPlayObject(result, true);
+ }
+ else
+ {
+ Arts::PlayObject result = Arts::SubClass(objectType);
+
+ if(result.loadMedia(string(QFile::encodeName(url.path()))))
+ {
+ result._node()->start();
+ m_incoming = new KPlayObject(result, false);
+ }
+ else
+ m_incoming = 0;
+ }
+}
+
+void KAudioConverter::start()
+{
+ if(m_started || !m_incoming)
+ return;
+
+ m_started = true;
+
+ emit rawStreamStart();
+
+ m_incoming->play();
+
+ Arts::KDataRequest_impl *requestImpl = new Arts::KDataRequest_impl();
+ m_request = Arts::KDataRequest::_from_base(requestImpl);
+
+ Arts::connect(m_incoming->object(), "left", m_request, "left");
+ Arts::connect(m_incoming->object(), "right", m_request, "right");
+
+ QObject::connect(requestImpl, SIGNAL(newBlockSize(long)), SIGNAL(newBlockSize(long)));
+ QObject::connect(requestImpl, SIGNAL(newBlockPointer(long)), SIGNAL(newBlockPointer(long)));
+ QObject::connect(requestImpl, SIGNAL(newData()), SIGNAL(newData()));
+
+ // Special mpeglib case
+ // TODO: needed at all??
+ usleep(100000);
+ if(m_incoming->object()._base()->_isCompatibleWith("DecoderBaseObject"))
+ if(!Arts::DynamicRequest(m_incoming->object()).method("_set_blocking").param(true).invoke())
+ cerr << "mpeglib, and blocking attribute can't be changed?" << endl;
+
+ m_request.start();
+
+ // TODO: Maybe do this async, using QTimer::singleShot
+ // But jowenn i think jowenn is right -> this would
+ // lead to problems in slotNewData() when accessing the data
+ // (could already be overwritten...)
+ while(m_incoming->state() != Arts::posIdle)
+ m_request.goOn();
+
+ stop();
+}
+
+void KAudioConverter::stop()
+{
+ if(!m_started || !m_incoming)
+ return;
+
+ m_incoming->halt();
+ m_request.streamEnd();
+
+ m_started = false;
+
+ emit rawStreamFinished();
+}
diff --git a/arts/kde/kaudioconverter.h b/arts/kde/kaudioconverter.h
new file mode 100644
index 000000000..6235739d8
--- /dev/null
+++ b/arts/kde/kaudioconverter.h
@@ -0,0 +1,65 @@
+ /*
+
+ Copyright (C) 2002 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KAUDIOCONVERTER_H
+#define KAUDIOCONVERTER_H
+
+#include <qobject.h>
+#include "artskde.h"
+#include "kplayobject.h"
+
+class KURL;
+class QString;
+
+class KAudioConverter : public QObject
+{
+Q_OBJECT
+public:
+ KAudioConverter();
+ ~KAudioConverter();
+
+ bool setup(int samplingRate);
+ void requestPlayObject(const KURL &url);
+
+ void start();
+ void stop();
+
+signals:
+ void rawStreamStart();
+
+ void newBlockSize(long blockSize);
+ void newBlockPointer(long blockPointer);
+ void newData();
+
+ void rawStreamFinished();
+
+private slots:
+ void slotMimeType(const QString &mimeType);
+
+private:
+ Arts::KDataRequest m_request;
+ KPlayObject *m_incoming;
+ QString m_mimeType;
+
+ bool m_started;
+};
+
+#endif
diff --git a/arts/kde/kaudiomanagerplay.cpp b/arts/kde/kaudiomanagerplay.cpp
new file mode 100644
index 000000000..12b817a87
--- /dev/null
+++ b/arts/kde/kaudiomanagerplay.cpp
@@ -0,0 +1,90 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "kaudiomanagerplay.h"
+#include "kartsserver.h"
+
+#include <soundserver.h>
+#include <string>
+
+KAudioManagerPlay::KAudioManagerPlay( KArtsServer * server, const QString & title )
+{
+ d = new PrivateData;
+ d->amanPlay = Arts::DynamicCast( server->server().createObject( "Arts::Synth_AMAN_PLAY" ) );
+ d->started = false;
+ setTitle( title );
+}
+
+KAudioManagerPlay::~KAudioManagerPlay()
+{
+ stop();
+ delete d;
+}
+
+Arts::Synth_AMAN_PLAY KAudioManagerPlay::amanPlay()
+{
+ return d->amanPlay;
+}
+
+bool KAudioManagerPlay::isNull() const
+{
+ if( !this )
+ return true;
+ return d->amanPlay.isNull();
+}
+
+void KAudioManagerPlay::setTitle( const QString & title )
+{
+ d->amanPlay.title( std::string( title.local8Bit() ) );
+}
+
+QString KAudioManagerPlay::title()
+{
+ return QString::fromLocal8Bit( d->amanPlay.title().c_str() );
+}
+
+void KAudioManagerPlay::setAutoRestoreID( const QString & autoRestoreID )
+{
+ d->amanPlay.autoRestoreID( std::string( autoRestoreID.local8Bit() ) );
+}
+
+QString KAudioManagerPlay::autoRestoreID()
+{
+ return QString::fromLocal8Bit( d->amanPlay.autoRestoreID().c_str() );
+}
+
+void KAudioManagerPlay::start()
+{
+ if( d->started )
+ return;
+
+ d->started = true;
+ d->amanPlay.start();
+}
+
+void KAudioManagerPlay::stop()
+{
+ if( !d->started )
+ return;
+
+ d->started = false;
+ d->amanPlay.stop();
+}
+
+// vim: sw=4 ts=4
diff --git a/arts/kde/kaudiomanagerplay.h b/arts/kde/kaudiomanagerplay.h
new file mode 100644
index 000000000..6bf332130
--- /dev/null
+++ b/arts/kde/kaudiomanagerplay.h
@@ -0,0 +1,84 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KAUDIOMANAGERPLAY_H
+#define KAUDIOMANAGERPLAY_H
+
+#include <artsflow.h>
+#include <qstring.h>
+#include <kdelibs_export.h>
+
+class KArtsServer;
+class QString;
+
+/**
+ * KDE Wrapper for Arts::Synth_AMAN_PLAY. Use this class to create an entry in
+ * the AudioManager - that's the list you see when opening the AudioManager view
+ * in artscontrol.
+ *
+ * @author Matthias Kretz <kretz@kde.org>
+ * @since 3.2
+ */
+class KDE_ARTS_EXPORT KAudioManagerPlay
+{
+ public:
+ KAudioManagerPlay( KArtsServer * server, const QString & title = QString::null );
+ ~KAudioManagerPlay();
+
+ /**
+ * Returns the internal Arts::Synth_AMAN_PLAY
+ */
+ Arts::Synth_AMAN_PLAY amanPlay();
+
+ /**
+ * return true if this == 0 or amanPlay().isNull()
+ *
+ * in essence, ((KDE::PlayObject*)0)->isNull() will not
+ * crash
+ **/
+ bool isNull() const;
+
+ /**
+ * Set the name of the output in the AudioManager
+ */
+ void setTitle( const QString & title );
+
+ /**
+ * returns the name of the output as it appears in the AudioManager
+ */
+ QString title();
+
+ void setAutoRestoreID( const QString & autoRestoreID );
+ QString autoRestoreID();
+
+ void start();
+ void stop();
+
+ private:
+ struct PrivateData {
+ Arts::Synth_AMAN_PLAY amanPlay;
+ bool started;
+ };
+ PrivateData* d;
+};
+
+
+#endif // KAUDIOMANAGERPLAY_H
+
+// vim: sw=4 ts=4
diff --git a/arts/kde/kaudioplaystream.cpp b/arts/kde/kaudioplaystream.cpp
new file mode 100644
index 000000000..200128ffc
--- /dev/null
+++ b/arts/kde/kaudioplaystream.cpp
@@ -0,0 +1,210 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Arnold Krille <arnold@arnoldarts.de>
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "kaudioplaystream.h"
+#include "kaudioplaystream_p.h"
+
+#include <kartsserver.h>
+#include <kaudiomanagerplay.h>
+
+#include <artsflow.h>
+#include <soundserver.h>
+
+#include <kglobal.h>
+#include <kdebug.h>
+
+#include <qstring.h>
+//#include <qptrqueue.h>
+//#include <qcstring.h> //QByteArray
+
+#include <string.h> // for strncpy
+
+//#include <assert.h>
+
+KAudioPlayStreamPrivate::KAudioPlayStreamPrivate( KArtsServer* server, const QString title, QObject* p, const char* n )
+ : QObject( p,n )
+ , _server( server )
+ , _play( new KAudioManagerPlay( _server, title ) )
+ , _effectrack( Arts::StereoEffectStack::null() )
+ , _polling( true ), _attached( false ), _effects( true )
+{
+kdDebug( 400 ) << k_funcinfo << endl;
+ initaRts();
+}
+
+KAudioPlayStreamPrivate::~KAudioPlayStreamPrivate()
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+ _play->stop();
+ if ( _effects ) _effectrack.stop();
+ _bs2a.stop();
+}
+
+void KAudioPlayStreamPrivate::initaRts() {
+ kdDebug( 400 ) << k_funcinfo << endl;
+
+ _effectrack = Arts::DynamicCast( _server->server().createObject( "Arts::StereoEffectStack" ) );
+ if ( _effectrack.isNull() )
+ {
+ kdWarning( 400 ) << "Couldn't create EffectStack!" << endl;
+ _effects = false;
+ }
+
+ _bs2a = Arts::DynamicCast( _server->server().createObject( "Arts::ByteStreamToAudio" ) );
+ if ( _bs2a.isNull() )
+ kdFatal( 400 ) << "Couldn't create ByteStreamToAudio" << endl;
+
+ if ( _effects )
+ {
+ Arts::connect( _effectrack, _play->amanPlay() );
+ Arts::connect( _bs2a, _effectrack );
+ } else {
+ Arts::connect( _bs2a, _play->amanPlay() );
+ }
+
+ _play->start();
+ if ( _effects ) _effectrack.start();
+}
+
+KAudioPlayStream::KAudioPlayStream( KArtsServer* server, const QString title, QObject* p, const char* n )
+ : QObject( p,n )
+ , d( new KAudioPlayStreamPrivate( server, title, this ) )
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+}
+KAudioPlayStream::~KAudioPlayStream()
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+}
+
+void KAudioPlayStream::setPolling( bool n ) { d->_polling = n; }
+bool KAudioPlayStream::polling() const { return d->_polling; }
+
+bool KAudioPlayStream::running() const { return d->_attached; }
+
+Arts::StereoEffectStack KAudioPlayStream::effectStack() const {
+ return d->_effectrack;
+}
+
+void KAudioPlayStream::start( int samplingRate, int bits, int channels )
+{
+ kdDebug( 400 ) << k_funcinfo << "samplingRate: " << samplingRate << " bits: " << bits << " channels: " << channels << endl;
+ if ( !d->_attached )
+ {
+ d->_bs2a.samplingRate( samplingRate );
+ d->_bs2a.channels( channels );
+ d->_bs2a.bits( bits );
+
+ d->_sender = new KByteSoundProducer( this, d->_server->server().minStreamBufferTime(), samplingRate, bits, channels, "PS" );
+ d->_artssender = Arts::ByteSoundProducerV2::_from_base( d->_sender );
+ Arts::connect( d->_artssender, "outdata", d->_bs2a, "indata" );
+
+ d->_bs2a.start();
+ d->_artssender.start();
+
+// // Needed?
+ Arts::Dispatcher::the()->ioManager()->processOneEvent( false );
+
+ d->_attached = true;
+ emit running( d->_attached );
+ }
+}
+void KAudioPlayStream::stop()
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+ if ( d->_attached )
+ {
+ d->_attached = false;
+
+ d->_bs2a.stop();
+ d->_artssender.stop();
+
+ // Shortly stop the play so we dont get clicks and artefacts
+ d->_play->stop();
+ d->_play->start();
+
+ Arts::disconnect( d->_artssender, d->_bs2a );
+ d->_artssender = Arts::ByteSoundProducerV2::null();
+ d->_sender = 0;
+
+ emit running( d->_attached );
+ }
+}
+
+void KAudioPlayStream::write( QByteArray& )
+{
+}
+
+void KAudioPlayStream::fillData( Arts::DataPacket<Arts::mcopbyte> *packet )
+{
+ //kdDebug( 400 ) << k_funcinfo << "packet->size=" << packet->size << endl;
+ if ( d->_polling )
+ {
+ QByteArray bytearray( packet->size );
+ bytearray.setRawData( ( char* )packet->contents, packet->size );
+ bytearray.fill( 0 );
+ emit requestData( bytearray );
+ bytearray.resetRawData( ( char* )packet->contents, packet->size );
+
+ //for ( int i=0; i<10; i++ )
+ // kdDebug() << packet->contents[ i ] << " : " << bytearray.data()[ i ] << endl;
+ } else {
+ /// TODO: Implement a queue and fetching from it...
+ }
+}
+
+// * * * KByteSoundProducer * * *
+
+KByteSoundProducer::KByteSoundProducer( KAudioPlayStream* impl, float minBufferTime, int rate, int bits, int channels, const char * title )
+ : _samplingRate( rate )
+ , _channels( channels )
+ , _bits( bits )
+ , _packets( 7 )
+ , _title( title )
+ , _impl( impl )
+{
+ // Calculate packet count (packetsize is fixed to packetCapacity = 4096
+ float streamBufferTime;
+ do {
+ _packets++;
+ streamBufferTime = ( float )( _packets * packetCapacity * 1000 )
+ / ( float )( _samplingRate * _channels * 2 );
+ } while ( streamBufferTime < minBufferTime );
+ //kdDebug( 400 ) << k_funcinfo << "_packets:" << _packets << " packetCapacity:" << packetCapacity << endl;
+}
+
+KByteSoundProducer::~KByteSoundProducer()
+{
+}
+
+void KByteSoundProducer::streamStart() { outdata.setPull( _packets, packetCapacity ); }
+void KByteSoundProducer::streamEnd() { outdata.endPull(); }
+
+void KByteSoundProducer::request_outdata( Arts::DataPacket<Arts::mcopbyte> *packet )
+{
+ if ( _impl->running() ) {
+ _impl->fillData( packet );
+ packet->send();
+ }
+}
+
+// vim: sw=4 ts=4 tw=80
+
+#include "kaudioplaystream.moc"
+#include "kaudioplaystream_p.moc"
diff --git a/arts/kde/kaudioplaystream.h b/arts/kde/kaudioplaystream.h
new file mode 100644
index 000000000..8f34cc8c9
--- /dev/null
+++ b/arts/kde/kaudioplaystream.h
@@ -0,0 +1,127 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Arnold Krille <arnold@arnoldarts.de>
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KAUDIOPLAYSTREAM_H
+#define KAUDIOPLAYSTREAM_H
+
+#include <qobject.h>
+
+#include <qcstring.h>
+#include <stdsynthmodule.h>
+
+#include <kdelibs_export.h>
+
+class KArtsServer;
+namespace Arts { class StereoEffectStack; }
+
+class KAudioPlayStreamPrivate;
+
+/**
+ * @brief A wrapper around ByteSoundProducer/ByteStreamToAudio/Synth_AMAN_PLAY.
+ *
+ * @author Arnold Krille <arnold@arnoldarts.de>
+ * @since 3.2
+*/
+
+class KDE_ARTS_EXPORT KAudioPlayStream : public QObject {
+ Q_OBJECT
+public:
+ /**
+ * Creates a KAudioPlayStream on server with a title. You should pass the KArtsServer also
+ * as parent to be sure this object is deleted before the server is.
+ *
+ * @param server The server where it should play to.
+ * @param title The title that is shown in the AudioManager.
+ * @param parent You will propably want to pass the server as parent to so this stream gets deleted before the server disappears.
+ * @param name The name of the stream.
+ */
+ KAudioPlayStream( KArtsServer* server, const QString title, QObject* parent=0, const char* name=0 );
+ /**
+ * Destructs the KAudioPlayStream.
+ */
+ ~KAudioPlayStream();
+
+ /**
+ * Controls wether this Stream should poll the data from you via the signal requestData()
+ * or you use write() to fill the inputbuffer.
+ *
+ * Default is true
+ */
+ void setPolling( bool );
+ /**
+ * Returns the polling state.
+ * @see setPolling
+ */
+ bool polling() const;
+
+ /**
+ * @return wether this stream is running ("on air") or not.
+ */
+ bool running() const;
+
+ /**
+ * @return The Arts::StereoEffectStack right before the Synth_AMAN_PLAY.
+ */
+ Arts::StereoEffectStack effectStack() const;
+public slots:
+ /**
+ * Start the stream.
+ * @param samplingRate how many samples per second ( typically 11000/22050/44100/48000 )
+ * @param bits how many bits per sample ( 8 / 16 )
+ * @param channels how many channels ( 1 or 2 )
+ */
+ void start( int samplingRate, int bits, int channels );
+ /**
+ * Stops the stream.
+ */
+ void stop();
+
+ /**
+ * Write data into the inputbuffer.
+ * If you ignore the signal noData() it will play 0 ( silence ).
+ */
+ void write( QByteArray& data );
+signals:
+ /**
+ * This signal is emitted when audio should be played.
+ * You have to fill the array with data.
+ */
+ void requestData( QByteArray& );
+
+ /**
+ * Is emitted when the state changes.
+ */
+ void running( bool );
+
+ /**
+ * Is emitted if the inputbuffer runs dry and polling os off.
+ */
+ void noData();
+public:
+ /**
+ * @internal
+ */
+ void fillData( Arts::DataPacket<Arts::mcopbyte> *packet );
+private:
+ KAudioPlayStreamPrivate* d;
+};
+
+#endif // KAUDIOPLAYSTREAM_H
+
+// vim: sw=4 ts=4 tw=80
diff --git a/arts/kde/kaudioplaystream_p.h b/arts/kde/kaudioplaystream_p.h
new file mode 100644
index 000000000..a7e5cc4e7
--- /dev/null
+++ b/arts/kde/kaudioplaystream_p.h
@@ -0,0 +1,84 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Arnold Krille <arnold@arnoldarts.de>
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KAUDIOPLAYSTREAM_P_H
+#define KAUDIOPLAYSTREAM_P_H
+
+#include <soundserver.h>
+#include <stdsynthmodule.h>
+
+#include <qobject.h>
+
+class KArtsServer;
+class KAudioManagerPlay;
+namespace Arts {
+ class Synth_AMAN_PLAY;
+ class StereoEffectStack;
+ class ByteStreamToAudio;
+}
+
+class KAudioPlayStream;
+class KByteSoundProducer;
+
+class KAudioPlayStreamPrivate : public QObject {
+ Q_OBJECT
+public:
+ KAudioPlayStreamPrivate( KArtsServer*, const QString title, QObject*, const char* =0 );
+ ~KAudioPlayStreamPrivate();
+
+ KArtsServer* _server;
+ KAudioManagerPlay* _play;
+ Arts::StereoEffectStack _effectrack;
+ Arts::ByteStreamToAudio _bs2a;
+ KByteSoundProducer* _sender;
+ Arts::ByteSoundProducerV2 _artssender;
+ bool _polling, _attached, _effects;
+
+public slots:
+ void initaRts();
+};
+
+class KByteSoundProducer : virtual public Arts::ByteSoundProducerV2_skel
+ , virtual public Arts::StdSynthModule
+{
+public:
+ KByteSoundProducer( KAudioPlayStream*, float minBufferTime, int rate, int bits, int channels, const char * title );
+ ~KByteSoundProducer();
+
+ long samplingRate() { return _samplingRate; }
+ long channels() { return _channels; }
+ long bits() { return _bits; }
+ std::string title() { return _title; }
+
+ void streamStart();
+ void streamEnd();
+
+protected:
+ void request_outdata( Arts::DataPacket<Arts::mcopbyte> *packet );
+
+private:
+ long _samplingRate, _channels, _bits, _packets;
+ std::string _title;
+ enum { packetCapacity = 4096 };
+ KAudioPlayStream* _impl;
+};
+
+#endif // KAUDIOPLAYSTREAM_P_H
+
+// vim: sw=4 ts=4
diff --git a/arts/kde/kaudiorecordstream.cpp b/arts/kde/kaudiorecordstream.cpp
new file mode 100644
index 000000000..53788e296
--- /dev/null
+++ b/arts/kde/kaudiorecordstream.cpp
@@ -0,0 +1,269 @@
+ /*
+
+ Copyright (C) 2001, 2002 Matthias Kretz
+ kretz@kde.org
+ 2003 Arnold Krille
+ arnold@arnoldarts.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include "kaudiorecordstream.h"
+#include "kaudiorecordstream_p.h"
+#include "kartsserver.h"
+
+#include <artsflow.h>
+#include <soundserver.h>
+
+#include <kglobal.h>
+#include <kdebug.h>
+
+#include <qstring.h>
+#include <qptrqueue.h>
+#include <qcstring.h> //QByteArray
+
+#include <assert.h>
+
+struct KAudioRecordStream::Data
+{
+ Arts::Synth_AMAN_RECORD in;
+ Arts::AudioToByteStream convert;
+ Arts::StereoEffectStack effectStack;
+ Arts::ByteSoundReceiver receiver;
+ KByteSoundReceiver * receiver_base;
+ KArtsServer * kserver;
+ bool attached;
+ bool blocking;
+ bool polling;
+ unsigned int pos;
+ QPtrQueue<QByteArray> inqueue;
+ QString title;
+};
+
+KAudioRecordStream::KAudioRecordStream( KArtsServer * kserver, const QString & title, QObject * parent, const char * name )
+ : QObject( parent, name )
+ , d( new Data )
+{
+ d->kserver = kserver;
+ d->attached = false;
+ d->blocking = true;
+ d->polling = false;
+ d->pos = 0;
+ d->inqueue.setAutoDelete( true );
+ d->title = title;
+
+ connect( d->kserver, SIGNAL( restartedServer() ), SLOT( slotRestartedServer() ) );
+
+ d->in = Arts::DynamicCast( d->kserver->server().createObject( "Arts::Synth_AMAN_RECORD" ) );
+ d->effectStack = Arts::DynamicCast( d->kserver->server().createObject( "Arts::StereoEffectStack" ) );
+ d->convert = Arts::DynamicCast( d->kserver->server().createObject( "Arts::AudioToByteStream" ) );
+ if( d->in.isNull() )
+ kdFatal( 400 ) << "couldn't create a Synth_AMAN_RECORD on the aRts server\n";
+ if( d->effectStack.isNull() )
+ kdFatal( 400 ) << "couldn't create a StereoEffectStack on the aRts server\n";
+ if( d->convert.isNull() )
+ kdFatal( 400 ) << "couldn't create a AudioToByteStream on the aRts server\n";
+
+ d->in.title( ( const char * ) d->title.local8Bit() );
+ Arts::connect( d->in, d->effectStack );
+ d->in.start();
+ d->effectStack.start();
+}
+
+KAudioRecordStream::~KAudioRecordStream()
+{
+ d->receiver = Arts::ByteSoundReceiver::null();
+ // don't delete receiver_base because aRts takes care of that (in the line
+ // above)
+ d->receiver_base = 0;
+ delete d;
+}
+
+int KAudioRecordStream::read( char * buffer, int size )
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+ unsigned int remaining = size;
+ while( remaining )
+ {
+ if( d->blocking )
+ while( d->inqueue.isEmpty() )
+ Arts::Dispatcher::the()->ioManager()->processOneEvent( true );
+ else
+ {
+ if( d->inqueue.isEmpty() )
+ Arts::Dispatcher::the()->ioManager()->processOneEvent( false );
+ if( d->inqueue.isEmpty() )
+ return size - remaining;
+ }
+ QByteArray * data = d->inqueue.head();
+ unsigned int tocopy = kMin( remaining, data->size() - d->pos );
+ memcpy( buffer, data->data() + d->pos, tocopy );
+ d->pos += tocopy;
+ buffer += tocopy;
+ remaining -= tocopy;
+ if( d->pos == data->size() )
+ {
+ d->inqueue.remove();
+ d->pos = 0;
+ }
+ }
+ return size;
+}
+
+void KAudioRecordStream::setBlockingIO( bool blocking )
+{
+ d->blocking = blocking;
+}
+
+bool KAudioRecordStream::blockingIO() const
+{
+ return d->blocking;
+}
+
+void KAudioRecordStream::usePolling( bool polling )
+{
+ d->polling = polling;
+ if( ! polling )
+ flush();
+}
+
+bool KAudioRecordStream::polling() const
+{
+ return d->polling;
+}
+
+Arts::StereoEffectStack KAudioRecordStream::effectStack() const
+{
+ return d->effectStack;
+}
+
+bool KAudioRecordStream::running() const
+{
+ return d->attached;
+}
+
+void KAudioRecordStream::stop()
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+ if( d->attached )
+ {
+ d->receiver.stop();
+ d->convert.stop();
+
+ Arts::disconnect( d->convert, d->receiver );
+ d->receiver = Arts::ByteSoundReceiver::null();
+ d->receiver_base = 0;
+
+ Arts::disconnect( d->effectStack, d->convert );
+
+ d->attached = false;
+ emit running( false );
+ }
+}
+
+void KAudioRecordStream::start( int samplingRate, int bits, int channels )
+{
+ kdDebug( 400 ) << k_funcinfo << "samplingRate: " << samplingRate << " bits: " << bits << " channels: " << channels << endl;
+ if( ! d->attached )
+ {
+ assert( d->kserver );
+
+ if( ( samplingRate < 500 || samplingRate > 2000000 )
+ || ( channels != 1 && channels != 2 ) || ( bits != 8 && bits != 16 ) )
+ {
+ kdWarning( 400 ) << "invalid stream parameters: rate=" << samplingRate << ", " << bits << " bit, " << channels << " channels\n";
+ }
+ else
+ {
+ d->convert.samplingRate( samplingRate );
+ d->convert.channels( channels );
+ d->convert.bits( bits );
+ Arts::connect( d->effectStack, d->convert );
+
+ d->receiver_base = new KByteSoundReceiver( samplingRate, bits, channels, d->title.local8Bit() );
+ d->receiver = Arts::ByteSoundReceiver::_from_base( d->receiver_base );
+ connect( d->receiver_base, SIGNAL( data( const char *, unsigned int ) ),
+ SLOT( slotData( const char *, unsigned int ) ) );
+ Arts::connect( d->convert, "outdata", d->receiver, "indata" );
+
+ d->convert.start();
+ d->receiver.start();
+
+ //### needed?
+ Arts::Dispatcher::the()->ioManager()->processOneEvent( false );
+ d->attached = true;
+ emit running( true );
+ }
+ }
+}
+
+void KAudioRecordStream::flush()
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+ d->inqueue.clear();
+}
+
+void KAudioRecordStream::slotRestartedServer() { }
+
+void KAudioRecordStream::slotData( const char * contents, unsigned int size )
+{
+ //kdDebug( 400 ) << k_funcinfo << endl;
+ QByteArray * bytearray = new QByteArray( size );
+ // copy the contents to the bytearray
+ // this has to be deleted later
+ bytearray->duplicate( contents, size );
+ if( d->polling )
+ {
+ kdDebug( 400 ) << "enqueue the data\n";
+ d->inqueue.enqueue( bytearray );
+ }
+ else
+ {
+ //kdDebug( 400 ) << "emit the data\n";
+ emit data( *bytearray );
+ //kdDebug( 400 ) << "delete the data\n";
+ delete bytearray;
+ }
+}
+
+////////////////////////////////////////
+// ---*--- KByteSoundReceiver ---*--- //
+////////////////////////////////////////
+
+KByteSoundReceiver::KByteSoundReceiver( int rate, int bits, int channels, const char * title )
+ : _samplingRate( rate )
+ , _bits( bits )
+ , _channels( channels )
+ , _title( title )
+{
+}
+
+KByteSoundReceiver::~KByteSoundReceiver()
+{
+}
+
+void KByteSoundReceiver::process_indata( Arts::DataPacket<Arts::mcopbyte> * inpacket )
+{
+ //kdDebug( 400 ) << k_funcinfo << " size of the packet: " << inpacket->size << endl;
+ emit data( (char *)inpacket->contents, inpacket->size );
+ inpacket->processed();
+}
+
+// vim:sw=4:ts=4
+
+#include "kaudiorecordstream.moc"
+#include "kaudiorecordstream_p.moc"
diff --git a/arts/kde/kaudiorecordstream.h b/arts/kde/kaudiorecordstream.h
new file mode 100644
index 000000000..9f8097676
--- /dev/null
+++ b/arts/kde/kaudiorecordstream.h
@@ -0,0 +1,165 @@
+ /*
+
+ Copyright (C) 2001,2002 Matthias Kretz
+ kretz@kde.org
+ 2003 Arnold Krille
+ arnold@arnoldarts.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef _KAUDIORECORDSTREAM__H
+#define _KAUDIORECORDSTREAM__H
+
+#include <qobject.h>
+
+#include <kdelibs_export.h>
+
+class KArtsServer;
+namespace Arts { class StereoEffectStack; }
+
+/**
+ * @brief A KDE wrapper around Synth_AMAN_RECORD/AudioToByteStream/ByteSoundReceiver
+ *
+ * @author Matthias Kretz <kretz@kde.org>
+ * @since 3.2
+*/
+class KDE_ARTS_EXPORT KAudioRecordStream : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Construct a KAudioRecordStream
+ *
+ * @param server The server where it should record from.
+ * @param title The title that is shown in the AudioManager.
+ * @param parent You will propably want to pass the server as parent to so this stream gets deleted before the server disappears.
+ * @param name The name of the stream.
+ */
+ KAudioRecordStream( KArtsServer * server, const QString & title, QObject * parent = 0, const char * name = 0 );
+
+ ~KAudioRecordStream();
+
+ /**
+ * You can read @p size number of bytes. If blockingIO() is set the method
+ * will return as soon as it has all your data and could possibly block your
+ * program. The method returns the number of bytes that are actually in the
+ * buffer.
+ *
+ * @see usePolling()
+ */
+ int read( char *, int size );
+
+ /**
+ * If you set blockingIO to true the read method will wait
+ * until it has enough data to return exactly what you asked for. If
+ * blockingIO is false you can count on having control back to your
+ * program soon enough
+ */
+ void setBlockingIO( bool );
+
+ /**
+ * read blocking I/O setting
+ *
+ * @see setBlockingIO()
+ */
+ bool blockingIO() const;
+
+ /**
+ * If you want to poll for data using read() set this to true. If
+ * you'd rather not poll use the data() signal for asynchronous
+ * I/O. If you set polling to true and don't call read() or
+ * flush() the inputbuffer will grow endlessly.
+ *
+ * The default is false (if you want to use read() set this to true).
+ */
+ void usePolling( bool );
+
+ /**
+ * read whether polling is enabled
+ *
+ * @see usePolling()
+ */
+ bool polling() const;
+
+ /**
+ * @return The Effect Stack right after the Synth_AMAN_RECORD.
+ */
+ Arts::StereoEffectStack effectStack() const;
+
+ /**
+ * @return Wether it is running (recording) or not.
+ * @since 3.2
+ */
+ bool running() const;
+
+ public slots:
+ /**
+ * Detaches the stream from the soundserver but doesn't remove the Synth_AMAN_RECORD
+ * so that the entry in the Audiomanager remains.
+ */
+ void stop();
+
+ /**
+ * Attach to the soundserver and start getting data to read. This method
+ * must be called as soon as you want to receive data. In any case you have
+ * to call start() before read()
+ *
+ * @param samplingRate The sampling rate the stream should be resampled to. Use
+ * a number between 500 and 2000000.
+ * @param bits The number of bits the stream should have. Only 8 and
+ * 16 Bits are supported.
+ * @param channels The number of channels (mono/stereo). Only 1 and 2 are
+ * supported.
+ */
+ void start( int samplingRate, int bits, int channels );
+
+ /**
+ * flush input buffer
+ */
+ void flush();
+
+ signals:
+ /**
+ * Data from the aRts server has arrived. You should copy the data
+ * because the passed QByteArray will be deleted right after
+ * returning from your slot(s).
+ *
+ * @param data the data from the server
+ */
+ void data( QByteArray & data );
+
+ /**
+ * Wether this RecordStream is recording or not.
+ * @since 3.2
+ */
+ void running( bool );
+
+ private slots:
+ void slotRestartedServer();
+ void slotData( const char *, unsigned int );
+
+ private:
+ KAudioRecordStream( const KAudioRecordStream & );
+ KAudioRecordStream & operator=( const KAudioRecordStream & );
+
+ struct Data;
+ Data * d;
+};
+
+#endif //_KAUDIORECORDSTREAM__H
diff --git a/arts/kde/kaudiorecordstream_p.h b/arts/kde/kaudiorecordstream_p.h
new file mode 100644
index 000000000..f2899519a
--- /dev/null
+++ b/arts/kde/kaudiorecordstream_p.h
@@ -0,0 +1,62 @@
+ /*
+
+ Copyright (C) 2002 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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef _KAUDIORECORDSTREAM_P__H
+#define _KAUDIORECORDSTREAM_P__H
+
+#include <soundserver.h>
+#include <stdsynthmodule.h>
+
+#include <qobject.h>
+
+class KByteSoundReceiver : public QObject,
+ public Arts::ByteSoundReceiver_skel,
+ public Arts::StdSynthModule
+{
+ Q_OBJECT
+
+ public:
+ KByteSoundReceiver( int rate, int bits, int channels, const char * title );
+ ~KByteSoundReceiver();
+
+ long samplingRate() { return _samplingRate; }
+ long channels() { return _channels; }
+ long bits() { return _bits; }
+ std::string title() { return _title; }
+
+ signals:
+ /**
+ * new data arrived, the data pointer will be deleted
+ * after this signal was emitted. So if you want to keep it
+ * you have to copy it.
+ */
+ void data( const char * data, unsigned int size );
+
+ protected:
+ void process_indata(Arts::DataPacket<Arts::mcopbyte> *);
+
+ private:
+ int _samplingRate, _bits, _channels;
+ std::string _title;
+};
+
+#endif // _KAUDIORECORDSTREAM_P__H
diff --git a/arts/kde/kconverttest.cc b/arts/kde/kconverttest.cc
new file mode 100644
index 000000000..25cb02e4c
--- /dev/null
+++ b/arts/kde/kconverttest.cc
@@ -0,0 +1,96 @@
+#include <stdio.h>
+
+#include <qfile.h>
+#include <qobject.h>
+
+#include <klocale.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+
+#include <flowsystem.h>
+#include <kplayobject.h>
+#include <kartsdispatcher.h>
+#include <kplayobjectfactory.h>
+#include <kaudioconverter.h>
+#include "kconverttest.moc"
+
+using namespace std;
+using namespace Arts;
+
+static KCmdLineOptions options[] =
+{
+ { "+[URL]", I18N_NOOP("URL to open"), 0 },
+ KCmdLineLastOption
+};
+
+KConvertTest::KConvertTest()
+{
+}
+
+void KConvertTest::slotRawStreamStart()
+{
+// cout << "[START]\n\n" << endl;
+}
+
+void KConvertTest::slotNewBlockSize(long blockSize)
+{
+ m_blockSize = blockSize;
+}
+
+void KConvertTest::slotNewBlockPointer(long blockPointer)
+{
+ m_blockPointer = blockPointer;
+}
+
+void KConvertTest::slotNewData()
+{
+ fwrite((void *) m_blockPointer, 1, m_blockSize, stdout);
+}
+
+void KConvertTest::slotRawStreamFinished()
+{
+// cout << "\n\n[END]" << endl;
+}
+
+int main(int argc, char **argv)
+{
+ KAboutData aboutData("kconverttest", I18N_NOOP("KConvertTest"), I18N_NOOP("0.1"), "", KAboutData::License_GPL, "");
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KApplication app;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ KURL url;
+
+ if(args->count())
+ url = args->arg(0);
+ else
+ exit(1);
+
+ args->clear();
+
+ KConvertTest *get = new KConvertTest();
+
+ KArtsDispatcher dispatcher;
+ KAudioConverter converter;
+
+ // FIXME: crashes
+ // converter.setup(44100);
+ converter.requestPlayObject(url);
+
+ QObject::connect(&converter, SIGNAL(rawStreamStart()), get, SLOT(slotRawStreamStart()));
+
+ QObject::connect(&converter, SIGNAL(newBlockSize(long)), get, SLOT(slotNewBlockSize(long)));
+ QObject::connect(&converter, SIGNAL(newBlockPointer(long)), get, SLOT(slotNewBlockPointer(long)));
+ QObject::connect(&converter, SIGNAL(newData()), get, SLOT(slotNewData()));
+
+ QObject::connect(&converter, SIGNAL(rawStreamFinished()), get, SLOT(slotRawStreamFinished()));
+
+ converter.start();
+
+ app.exec();
+}
+
diff --git a/arts/kde/kconverttest.h b/arts/kde/kconverttest.h
new file mode 100644
index 000000000..60847b0aa
--- /dev/null
+++ b/arts/kde/kconverttest.h
@@ -0,0 +1,46 @@
+ /*
+
+ Copyright (C) 2002 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KCONVERTTEST_H
+#define KCONVERTTEST_H
+
+#include <qobject.h>
+
+class KConvertTest : public QObject
+{
+Q_OBJECT
+public:
+ KConvertTest();
+
+public slots:
+ void slotRawStreamStart();
+
+ void slotNewBlockSize(long blockSize);
+ void slotNewBlockPointer(long blockPointer);
+ void slotNewData();
+
+ void slotRawStreamFinished();
+
+private:
+ long m_blockSize, m_blockPointer;
+};
+
+#endif
diff --git a/arts/kde/kdatarequest_impl.cpp b/arts/kde/kdatarequest_impl.cpp
new file mode 100644
index 000000000..ce8f30f9b
--- /dev/null
+++ b/arts/kde/kdatarequest_impl.cpp
@@ -0,0 +1,80 @@
+ /*
+
+ Copyright (C) 2002 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include <kdebug.h>
+#include "flowsystem.h"
+#include "convert.h"
+#include "kdatarequest_impl.moc"
+
+using namespace Arts;
+
+KDataRequest_impl::KDataRequest_impl()
+{
+ m_lastBlockSize = 0;
+ m_outBlock = 0;
+}
+
+KDataRequest_impl::~KDataRequest_impl()
+{
+ delete []m_outBlock;
+}
+
+void KDataRequest_impl::streamInit()
+{
+}
+
+void KDataRequest_impl::streamEnd()
+{
+}
+
+void KDataRequest_impl::calculateBlock(unsigned long samples)
+{
+ long blockSize = samples * 4;
+
+ if(m_lastBlockSize != blockSize)
+ {
+ delete []m_outBlock;
+ emit newBlockSize(blockSize);
+
+ m_outBlock = new unsigned char[blockSize]; // 2 channels, 16 bit
+
+ emit newBlockPointer((long) m_outBlock);
+
+ m_lastBlockSize = blockSize;
+ }
+
+ convert_stereo_2float_i16le(samples, left, right, m_outBlock);
+ emit newData();
+}
+
+/*
+ * this is the most tricky part here - since we will run in a context
+ * where no audio hardware will play the "give me more data role",
+ * we'll have to request things ourselves (requireFlow() tells the
+ * flowsystem that more signal flow should happen, so that
+ * calculateBlock will get called
+ */
+void KDataRequest_impl::goOn()
+{
+ _node()->requireFlow();
+}
+
+REGISTER_IMPLEMENTATION(KDataRequest_impl);
diff --git a/arts/kde/kdatarequest_impl.h b/arts/kde/kdatarequest_impl.h
new file mode 100644
index 000000000..07522f0f1
--- /dev/null
+++ b/arts/kde/kdatarequest_impl.h
@@ -0,0 +1,59 @@
+ /*
+
+ Copyright (C) 2002 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KDATAREQUEST_IMPL
+#define KDATAREQUEST_IMPL
+
+#include <qobject.h>
+#include "artskde.h"
+#include "stdsynthmodule.h"
+
+namespace Arts
+{
+
+class KDataRequest_impl : public QObject, virtual public KDataRequest_skel,
+ virtual public StdSynthModule
+{
+Q_OBJECT
+public:
+ KDataRequest_impl();
+ ~KDataRequest_impl();
+
+ void streamInit();
+ void streamEnd();
+
+ void calculateBlock(unsigned long samples);
+
+ void goOn();
+
+signals:
+ void newData();
+ void newBlockSize(long blockSize);
+ void newBlockPointer(long blockPointer);
+
+private:
+ long m_lastBlockSize;
+ unsigned char *m_outBlock;
+};
+
+}
+
+#endif
diff --git a/arts/kde/kioinputstream_impl.cpp b/arts/kde/kioinputstream_impl.cpp
new file mode 100644
index 000000000..b82764931
--- /dev/null
+++ b/arts/kde/kioinputstream_impl.cpp
@@ -0,0 +1,236 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+/*
+ * How does it work?
+ * -----------------
+ *
+ * First the buffer has to be filled. When it reaches a defined size the outdata
+ * stream has to start pulling packets. If the buffer reaches a size of zero the
+ * stream has to stop. If the buffer gets to big the job has to be suspended
+ * until the buffer is small enough again.
+ */
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kio/job.h>
+#include <kio/kmimetype.h>
+#include <kio/jobclasses.h>
+#include <qtimer.h>
+#include <qdatastream.h>
+#include "artsversion.h"
+#include "kioinputstream_impl.moc"
+
+using namespace Arts;
+
+const unsigned int KIOInputStream_impl::PACKET_COUNT = 10;
+
+KIOInputStream_impl::KIOInputStream_impl() : m_packetSize(2048)
+{
+ m_job = 0;
+ m_finished = false;
+ m_firstBuffer = false;
+ m_packetBuffer = 16;
+ m_streamStarted = false;
+ m_streamSuspended = false;
+ m_streamPulled = false;
+ m_size = 0;
+}
+
+KIOInputStream_impl::~KIOInputStream_impl()
+{
+ if(m_job != 0)
+ m_job->kill();
+}
+
+void KIOInputStream_impl::streamStart()
+{
+ // prevent kill/reconnect
+ if (m_streamStarted) {
+ kdDebug( 400 ) << "not restarting stream!\n";
+ if (m_job->isSuspended())
+ m_job->resume();
+ return;
+ }
+
+ kdDebug( 400 ) << "(re)starting stream\n";
+
+ if(m_job != 0)
+ m_job->kill();
+ m_job = KIO::get(m_url, false, false);
+
+ m_job->addMetaData("accept", "audio/x-mp3, video/mpeg, application/ogg");
+ m_job->addMetaData("UserAgent", QString::fromLatin1("aRts/") + QString::fromLatin1(ARTS_VERSION));
+
+ QObject::connect(m_job, SIGNAL(data(KIO::Job *, const QByteArray &)),
+ this, SLOT(slotData(KIO::Job *, const QByteArray &)));
+ QObject::connect(m_job, SIGNAL(result(KIO::Job *)),
+ this, SLOT(slotResult(KIO::Job *)));
+ QObject::connect(m_job, SIGNAL(mimetype(KIO::Job *, const QString &)),
+ this, SLOT(slotScanMimeType(KIO::Job *, const QString &)));
+ QObject::connect(m_job, SIGNAL(totalSize( KIO::Job *, KIO::filesize_t)),
+ this, SLOT(slotTotalSize(KIO::Job *, KIO::filesize_t)));
+
+ m_streamStarted = true;
+}
+
+void KIOInputStream_impl::streamEnd()
+{
+ kdDebug( 400 ) << "streamEnd()\n";
+
+ if(m_job != 0)
+ {
+ QObject::disconnect(m_job, SIGNAL(data(KIO::Job *, const QByteArray &)),
+ this, SLOT(slotData(KIO::Job *, const QByteArray &)));
+ QObject::disconnect(m_job, SIGNAL(result(KIO::Job *)),
+ this, SLOT(slotResult(KIO::Job *)));
+ QObject::disconnect(m_job, SIGNAL(mimetype(KIO::Job *, const QString &)),
+ this, SLOT(slotScanMimeType(KIO::Job *, const QString &)));
+ QObject::disconnect(m_job, SIGNAL(totalSize( KIO::Job *, KIO::filesize_t)),
+ this, SLOT(slotTotalSize(KIO::Job *, KIO::filesize_t)));
+
+ if ( m_streamPulled )
+ outdata.endPull();
+
+ m_job->kill();
+ m_job = 0;
+ }
+
+ m_streamStarted = false;
+}
+
+bool KIOInputStream_impl::openURL(const std::string& url)
+{
+ m_url = KURL(url.c_str());
+ m_size = 0;
+ return true;
+}
+
+void KIOInputStream_impl::slotData(KIO::Job *, const QByteArray &data)
+{
+ if(m_finished)
+ m_finished = false;
+
+ QDataStream dataStream(m_data, IO_WriteOnly | IO_Append);
+ dataStream.writeRawBytes(data.data(), data.size());
+ //kdDebug( 400 ) << "STREAMING: buffersize = " << m_data.size() << " bytes" << endl;
+
+ processQueue();
+}
+
+void KIOInputStream_impl::slotResult(KIO::Job *job)
+{
+ // jobs delete themselves after emitting their result
+ m_finished = true;
+ m_streamStarted = false;
+ m_job = 0;
+
+ if(job->error()) {
+ // break out of the event loop in case of
+ // connection error
+ emit mimeTypeFound("application/x-zerosize");
+ job->showErrorDialog();
+ }
+}
+
+void KIOInputStream_impl::slotScanMimeType(KIO::Job *, const QString &mimetype)
+{
+ kdDebug( 400 ) << "got mimetype: " << mimetype << endl;
+ emit mimeTypeFound(mimetype);
+}
+
+void KIOInputStream_impl::slotTotalSize(KIO::Job *, KIO::filesize_t size)
+{
+ m_size = size;
+}
+
+bool KIOInputStream_impl::eof()
+{
+ return (m_finished && m_data.size() == 0);
+}
+
+bool KIOInputStream_impl::seekOk()
+{
+ return false;
+}
+
+long KIOInputStream_impl::size()
+{
+ return m_size ? m_size : m_data.size();
+}
+
+long KIOInputStream_impl::seek(long)
+{
+ return -1;
+}
+
+void KIOInputStream_impl::processQueue()
+{
+ if(m_job != 0)
+ {
+ if(m_data.size() > (m_packetBuffer * m_packetSize * 2) && !m_job->isSuspended())
+ {
+ kdDebug( 400 ) << "STREAMING: suspend job" << endl;
+ m_job->suspend();
+ }
+ else if(m_data.size() < (m_packetBuffer * m_packetSize) && m_job->isSuspended())
+ {
+ kdDebug( 400 ) << "STREAMING: resume job" << endl;
+ m_job->resume();
+ }
+ }
+
+ if (!m_firstBuffer) {
+ if(m_data.size() < (m_packetBuffer * m_packetSize * 2) ) {
+ kdDebug( 400 ) << "STREAMING: Buffering in progress... (Needed bytes before it starts to play: " << ((m_packetBuffer * m_packetSize * 2) - m_data.size()) << ")" << endl;
+ return;
+ } else {
+ m_firstBuffer = true;
+ m_streamPulled = true;
+ outdata.setPull(PACKET_COUNT, m_packetSize);
+ }
+ }
+}
+
+void KIOInputStream_impl::request_outdata(DataPacket<mcopbyte> *packet)
+{
+ processQueue();
+ packet->size = std::min(m_packetSize, m_data.size());
+ kdDebug( 400 ) << "STREAMING: Filling one DataPacket with " << packet->size << " bytes of the stream!" << endl;
+
+ if (!m_finished) {
+ if( (unsigned)packet->size < m_packetSize || ! m_firstBuffer) {
+ m_firstBuffer = false;
+ packet->size = 0;
+ outdata.endPull();
+ }
+ }
+
+ if (packet->size > 0)
+ {
+ memcpy(packet->contents, m_data.data(), packet->size);
+ memmove(m_data.data(), m_data.data() + packet->size, m_data.size() - packet->size);
+ m_data.resize(m_data.size() - packet->size);
+ }
+ packet->send();
+}
+
+REGISTER_IMPLEMENTATION(KIOInputStream_impl);
diff --git a/arts/kde/kioinputstream_impl.h b/arts/kde/kioinputstream_impl.h
new file mode 100644
index 000000000..95daac169
--- /dev/null
+++ b/arts/kde/kioinputstream_impl.h
@@ -0,0 +1,89 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KIOINPUTSTREAM_IMPL
+#define KIOINPUTSTREAM_IMPL
+
+#include <qobject.h>
+#include <qcstring.h>
+#include <kio/jobclasses.h>
+#include <kurl.h>
+#include "artskde.h"
+#include "stdsynthmodule.h"
+
+namespace Arts {
+
+class KIOInputStream_impl : public QObject, virtual public KIOInputStream_skel,
+ virtual public InputStream_skel,
+ virtual public StdSynthModule
+{
+Q_OBJECT
+public:
+ KIOInputStream_impl();
+ ~KIOInputStream_impl();
+
+ void streamStart();
+ void streamEnd();
+
+ bool eof();
+ bool seekOk();
+ long size();
+ long seek(long);
+
+ bool openURL(const std::string& url);
+
+ void processQueue();
+ void request_outdata(DataPacket<mcopbyte> *packet);
+
+ long bufferPackets() { return m_packetBuffer; }
+ void bufferPackets(long i) { m_packetBuffer = i; }
+
+ long packetSize() { return m_packetSize; }
+
+signals:
+ void mimeTypeFound(const QString & mimetype);
+
+private slots:
+ void slotData(KIO::Job *, const QByteArray &);
+ void slotResult(KIO::Job *);
+ void slotScanMimeType(KIO::Job *, const QString &mimetype);
+ void slotTotalSize(KIO::Job *, KIO::filesize_t size);
+
+private:
+ KURL m_url;
+ KIO::TransferJob *m_job;
+ QByteArray m_data;
+ bool m_finished;
+ bool m_firstBuffer;
+ bool m_streamStarted;
+ bool m_streamSuspended;
+ bool m_streamPulled;
+
+ unsigned int m_packetBuffer;
+ const unsigned int m_packetSize;
+ KIO::filesize_t m_size;
+
+ static const unsigned int PACKET_COUNT;
+};
+
+}
+
+#endif
diff --git a/arts/kde/kiotest.cc b/arts/kde/kiotest.cc
new file mode 100644
index 000000000..b5403ce0d
--- /dev/null
+++ b/arts/kde/kiotest.cc
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <kmedia2.h>
+#include <kcmdlineargs.h>
+#include <connect.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include "qiomanager.h"
+#include "artskde.h"
+
+using namespace std;
+using namespace Arts;
+
+
+static KCmdLineOptions options[] =
+{
+ { "+[URL]", I18N_NOOP("URL to open"), 0 },
+ KCmdLineLastOption
+};
+
+int main(int argc, char **argv)
+{
+ KAboutData aboutData( "kiotest", I18N_NOOP("KIOTest"), I18N_NOOP("0.1"), "", KAboutData::License_GPL, "");
+
+ KCmdLineArgs::init(argc,argv,&aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KApplication app;
+ QIOManager qiomanager;
+ Dispatcher dispatcher(&qiomanager);
+ KIOInputStream stream;
+ StdoutWriter writer;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if(args->count())
+ {
+ if(!stream.openURL(args->arg(0)))
+ {
+ printf("can't open url");
+ exit(1);
+ }
+ }
+ else
+ exit(1);
+
+ args->clear();
+
+ connect(stream, writer);
+
+ writer.start();
+ stream.start();
+
+ app.exec();
+}
diff --git a/arts/kde/kiotestslow.cc b/arts/kde/kiotestslow.cc
new file mode 100644
index 000000000..fd5f1e129
--- /dev/null
+++ b/arts/kde/kiotestslow.cc
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <kmedia2.h>
+#include <kcmdlineargs.h>
+#include <connect.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <stdsynthmodule.h>
+#include "qiomanager.h"
+#include "artskde.h"
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+/* simulate slow receiver */
+class KIOTestSlow_impl : public KIOTestSlow_skel,
+ public TimeNotify,
+ public StdSynthModule
+{
+ int pos;
+ list< DataPacket<mcopbyte>* > q;
+ InputStream _inputStream;
+
+public:
+ InputStream inputStream() { return _inputStream; }
+ void inputStream(InputStream i) { _inputStream = i; }
+
+ KIOTestSlow_impl()
+ {
+ Dispatcher::the()->ioManager()->addTimer(10, this);
+ pos = 0;
+ }
+ void notifyTime()
+ {
+ if(!_inputStream.isNull() && _inputStream.eof())
+ {
+ printf("\n[*EOF*] remaining = %d packets\n");
+ _inputStream = InputStream::null();
+ return;
+ }
+
+ int TODO = 100;
+ do {
+ if(q.empty())
+ return;
+
+ DataPacket<mcopbyte> *p = q.front();
+ char ch = p->contents[pos++];
+ if(p->size == pos)
+ {
+ p->processed();
+ q.pop_front();
+ pos = 0;
+ }
+
+ if(ch == '\n')
+ {
+ long size = 0;
+ list<DataPacket<mcopbyte>*>::iterator i;
+ for(i = q.begin(); i != q.end(); i++)
+ size += (*i)->size;
+ printf("\n[queued %8ld] ",size-pos);
+ }
+ else
+ putchar(ch);
+
+ } while(TODO-- > 0);
+ }
+ void process_data(DataPacket<mcopbyte> *p)
+ {
+ if(p->size == 0)
+ p->processed();
+ else
+ q.push_back(p);
+ }
+};
+REGISTER_IMPLEMENTATION(KIOTestSlow_impl);
+};
+
+static KCmdLineOptions options[] =
+{
+ { "+[URL]", I18N_NOOP("URL to open"), 0 },
+ KCmdLineLastOption
+};
+
+#undef USE_FILEINPUTSTREAM
+
+int main(int argc, char **argv)
+{
+ KAboutData aboutData( "kiotestslow", I18N_NOOP("KIOTest"), I18N_NOOP("0.1"), "", KAboutData::License_GPL, "");
+
+ KCmdLineArgs::init(argc,argv,&aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KApplication app;
+ QIOManager qiomanager;
+ Dispatcher dispatcher(&qiomanager);
+#ifndef USE_FILEINPUTSTREAM
+ KIOInputStream stream;
+#else
+ FileInputStream stream;
+#endif
+ KIOTestSlow writer;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if(args->count())
+ {
+#ifdef USE_FILEINPUTSTREAM
+ if(!stream.open(args->arg(0)))
+#else
+ if(!stream.openURL(args->arg(0)))
+#endif
+ {
+ printf("can't open url");
+ exit(1);
+ }
+ }
+ else
+ exit(1);
+
+ args->clear();
+
+ writer.inputStream(stream);
+ connect(stream, writer);
+
+ writer.start();
+ stream.start();
+
+ app.exec();
+}
diff --git a/arts/kde/kplayobject.cc b/arts/kde/kplayobject.cc
new file mode 100644
index 000000000..af37735cb
--- /dev/null
+++ b/arts/kde/kplayobject.cc
@@ -0,0 +1,303 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include "kplayobject.h"
+#include "kplayobject.moc"
+#include "kplayobjectcreator.h"
+#include <kdebug.h>
+
+KPlayObject::KPlayObject() : QObject()
+{
+ m_playObject = Arts::PlayObject::null();
+ m_isStream = false;
+}
+
+KPlayObject::KPlayObject(Arts::PlayObject playobject, bool isStream) : QObject()
+{
+ m_playObject = playobject;
+ m_isStream = isStream;
+}
+
+KPlayObject::~KPlayObject()
+{
+}
+
+void KPlayObject::play()
+{
+ object().play();
+}
+
+void KPlayObject::seek(Arts::poTime newTime)
+{
+ if(!m_isStream)
+ object().seek(newTime);
+ else
+ kdDebug( 400 ) << "Seeking in a Stream? huh?" << endl;
+}
+
+void KPlayObject::pause()
+{
+ object().pause();
+}
+
+void KPlayObject::halt()
+{
+ object().halt();
+}
+
+QString KPlayObject::description()
+{
+ return QString::fromLatin1(object().description().c_str());
+}
+
+Arts::poTime KPlayObject::currentTime()
+{
+ return object().currentTime();
+}
+
+Arts::poTime KPlayObject::overallTime()
+{
+ return object().overallTime();
+}
+
+Arts::poCapabilities KPlayObject::capabilities()
+{
+ return object().capabilities();
+}
+
+QString KPlayObject::mediaName()
+{
+ return QString::fromLatin1(object().mediaName().c_str());
+}
+
+Arts::poState KPlayObject::state()
+{
+ return object().state();
+}
+
+Arts::PlayObject KPlayObject::object()
+{
+ return m_playObject;
+}
+
+bool KPlayObject::isNull()
+{
+ if( !this )
+ return true;
+ return object().isNull();
+}
+
+void KPlayObject::setObject(Arts::PlayObject playObject)
+{
+ m_playObject = playObject;
+}
+
+bool KPlayObject::stream()
+{
+ return m_isStream;
+}
+
+struct KDE::PlayObject::PrivateData
+{
+ PrivateData() : creator( 0 ),
+ isProxy( false ),
+ internalState( Arts::posIdle ) {}
+ ~PrivateData() {
+ delete creator;
+ }
+ Arts::SoundServerV2 server;
+ KDE::PlayObjectCreator* creator;
+ bool createBUS;
+ bool isProxy;
+ Arts::poState internalState;
+ KURL url;
+};
+
+KDE::PlayObject::PlayObject() : QObject()
+{
+ m_playObject = Arts::PlayObject::null();
+ m_isStream = false;
+ d = new PrivateData;
+}
+
+KDE::PlayObject::PlayObject(Arts::PlayObject playobject, bool isStream) : QObject()
+{
+ m_playObject = playobject;
+ m_isStream = isStream;
+ d = new PrivateData;
+
+ //very funny! you can't connect to signals before creating
+ //the object - so nobody will ever receive this signal (mkretz)
+ //
+ //emit playObjectCreated();
+}
+
+KDE::PlayObject::PlayObject( Arts::SoundServerV2 server, const KURL& url, bool isStream, bool createBUS ) : QObject()
+{
+ kdDebug( 400 ) << "KDE::PlayObject: created as proxy for URL " << url.url()<< endl;
+
+ m_playObject = Arts::PlayObject::null();
+ m_isStream = isStream;
+ d = new PrivateData;
+ d->server = server;
+ d->url = url;
+ d->createBUS = createBUS;
+ d->isProxy = true;
+}
+
+KDE::PlayObject::~PlayObject()
+{
+ kdDebug( 400 ) << "KDE::PlayObject: destroyed" << endl;
+
+ delete d;
+}
+
+void KDE::PlayObject::play()
+{
+ kdDebug( 400 ) << "KDE::PlayObject::play()" << endl;
+
+ if ( object().isNull() ) {
+ if ( m_isStream ) {
+ if ( d->creator )
+ delete d->creator;
+ d->creator = new KDE::PlayObjectCreator( d->server );
+ d->creator->create( d->url, d->createBUS, this, SLOT( attachPlayObject( Arts::PlayObject ) ) );
+ kdDebug( 400 ) << "KDE::PlayObject::play(): creator called" << endl;
+ d->internalState = Arts::posPlaying;
+ }
+ return;
+ }
+ object().play();
+}
+
+void KDE::PlayObject::attachPlayObject( Arts::PlayObject playObject )
+{
+ kdDebug( 400 ) << "KDE::PlayObject::attachPlayObject()" << endl;
+
+ m_playObject = playObject;
+ emit playObjectCreated();
+ if ( object().isNull() )
+ return;
+ switch ( d->internalState ) {
+ case Arts::posIdle:
+ object().halt();
+ break;
+ case Arts::posPaused:
+ object().pause();
+ break;
+ case Arts::posPlaying:
+ object().play ();
+ break;
+ }
+}
+
+void KDE::PlayObject::seek(Arts::poTime newTime)
+{
+ if ( object().isNull() )
+ return;
+ if(!m_isStream)
+ object().seek(newTime);
+ else
+ kdDebug( 400 ) << "Seeking in a Stream? huh?" << endl;
+}
+
+void KDE::PlayObject::pause()
+{
+ if ( !object().isNull() )
+ object().pause();
+ d->internalState = Arts::posPaused;
+}
+
+void KDE::PlayObject::halt()
+{
+ kdDebug( 400 ) << "KDE::PlayObject::halt()" << endl;
+ if ( !object().isNull() )
+ object().halt();
+ else if ( d->creator ) {
+ delete d->creator;
+ d->creator = 0;
+ kdDebug( 400 ) << "KDE::PlayObject::halt(): creator destroyed" << endl;
+ }
+ d->internalState = Arts::posIdle;
+}
+
+QString KDE::PlayObject::description()
+{
+ if ( object().isNull() )
+ return QString();
+ return QString::fromLatin1(object().description().c_str());
+}
+
+Arts::poTime KDE::PlayObject::currentTime()
+{
+ if ( object().isNull() )
+ return Arts::poTime( 0, 0, -1, "" );
+ return object().currentTime();
+}
+
+Arts::poTime KDE::PlayObject::overallTime()
+{
+ if ( object().isNull() )
+ return Arts::poTime( 0, 0, -1, "" );
+ return object().overallTime();
+}
+
+Arts::poCapabilities KDE::PlayObject::capabilities()
+{
+ if ( object().isNull() )
+ return static_cast<Arts::poCapabilities>( 0 );
+ return object().capabilities();
+}
+
+QString KDE::PlayObject::mediaName()
+{
+ if ( object().isNull() )
+ return QString();
+ return QString::fromLatin1(object().mediaName().c_str());
+}
+
+Arts::poState KDE::PlayObject::state()
+{
+ if ( object().isNull() )
+ return d->internalState;
+ return object().state();
+}
+
+Arts::PlayObject KDE::PlayObject::object()
+{
+ return m_playObject;
+}
+
+bool KDE::PlayObject::isNull()
+{
+ if ( !this )
+ return true;
+ if ( d->isProxy )
+ return false;
+ return object().isNull();
+}
+
+bool KDE::PlayObject::stream()
+{
+ return m_isStream;
+}
+
+// vim: sw=4 ts=4 noet
diff --git a/arts/kde/kplayobject.h b/arts/kde/kplayobject.h
new file mode 100644
index 000000000..959e46810
--- /dev/null
+++ b/arts/kde/kplayobject.h
@@ -0,0 +1,306 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KPLAYOBJECT_H
+#define KPLAYOBJECT_H
+
+#include "kmedia2.h"
+#include "soundserver.h"
+#include <kurl.h>
+#include <qobject.h>
+
+class KDE_EXPORT KPlayObject : public QObject
+{
+Q_OBJECT
+public:
+ KPlayObject();
+ KPlayObject(Arts::PlayObject playobject, bool isStream);
+ ~KPlayObject();
+
+ /**
+ * Sets the internal Arts::PlayObject
+ * to @a playObject
+ */
+ void setObject(Arts::PlayObject playObject);
+
+ /**
+ * Returns the internal Arts::PlayObject
+ */
+ Arts::PlayObject object();
+
+ /**
+ * return true if both this != 0, and object.isNull()
+ *
+ * in essence, ((KPlayObject*)0)->isNull() will not
+ * crash
+ **/
+ bool isNull();
+
+ /**
+ * returns true if the internally playobject
+ * is used to play a stream
+ */
+ bool stream();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ void play();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ void seek(Arts::poTime newTime);
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ void pause();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+
+ void halt();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ QString description();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ Arts::poTime currentTime();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ Arts::poTime overallTime();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ Arts::poCapabilities capabilities();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ QString mediaName();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ Arts::poState state();
+
+private:
+ Arts::PlayObject m_playObject;
+ bool m_isStream;
+};
+
+
+
+namespace KDE {
+
+class PlayObjectFactory;
+
+/**
+ * This class acts as a general interface to the KDE multimedia framework.
+ * You basically point the Playobject to an URL and say "play", and it will
+ * automatically decode and play and / or display the file or stream.
+ * For non-local media, it will make extensive use of KIOInputStream to
+ * directly play the content from the remote location without having to
+ * download it to a temporary local file first.
+ *
+ * A KDE::PlayObject is never created directly with new, but only through
+ * a KDE::PlayObjectFactory.
+ *
+ * Basically, it is used like this:
+ * \code
+ * KArtsDispatcher dispatcher;
+ * KArtsServer server;
+ * KDE::PlayObjectFactory factory( server.server() );
+ * KDE::PlayObject* playobj = factory.createPlayObject( someURL, true );
+ * playobj->play();
+ * \endcode
+ *
+ * Internally, the KDE::PlayObject acts as a wrapper for an Arts::PlayObject.
+ *
+ * Special care needs to be taken for non-local media. In general, you
+ * cannot safely figure out the mimetype of the remote media content, by
+ * looking at the URL alone. You need to download some data to analyze
+ * the content. Since KDE::PlayObject is only a wrapper for an
+ * Arts::PlayObject, and an Arts::PlayObject needs to know the mimetype
+ * of the data it plays in order to pick the correct decoder, one cannot
+ * directly create an Arts::PlayObject and attach it to a stream. Therefore,
+ * the following approach is used.
+ *
+ * Whenever a the factory creates a KDE::PlayObject for a non-local content,
+ * it first generates a so called "Proxy" Playobject. This is a
+ * KDE::PlayObject that does not contain a real Arts::PlayObject yet.
+ * As soon as you invoke the play() method, a connection to the media
+ * source is made, and as soon as the mimetype is known, the appropriate
+ * Arts::PlayObject is created.
+ *
+ * This has some side effects that developers need to be aware of:
+ * Until the real Arts::PlayObject got created,
+ * - the capabilities() method returns "zero" capabilities,
+ * - description() and mediaName() will return a null QString,
+ * - currentTime() and overallTime() will return "zero",
+ * - despite the fact that isNull() returns "false", object().isNull()
+ * will return "true". If you need to directly access methods of the
+ * internal Arts::PlayObject, be sure to use object().isNull() to guard
+ * your access.
+ *
+ * A KDE::PlayObject will emit the signal playObjectCreated()
+ * as soon as the real internal Arts::PlayObject got created. This is also
+ * true for local media files. So you can generally connect to this signal
+ * and act on it if your application needs to know about the real capabilities
+ * of the Arts::PlayObject.
+ *
+ * However, KDE::PlayObject will try to act reasonable on calls to play(),
+ * halt(), pause() and state(). If you call play() and then pause()
+ * before the connection to the media source was established, it will
+ * not start playing once the connection got established. Calling halt()
+ * will cancel the connection process. KDE::PlayObject will maintain
+ * an internal state variable, and calling state() will return this
+ * internal state until the real Arts::PlayObject got created, afterwards
+ * the state of the Arts::PlayObject will be returned.
+ */
+class KDE_EXPORT PlayObject : public QObject
+{
+Q_OBJECT
+public:
+ ~PlayObject();
+
+ /**
+ * Returns the internal Arts::PlayObject
+ */
+ Arts::PlayObject object();
+
+ /**
+ * return true if this != 0.
+ *
+ * in essence, ((KDE::PlayObject*)0)->isNull() will not
+ * crash
+ **/
+ bool isNull();
+
+ /**
+ * returns "true" if the content to play is delivered as a stream.
+ */
+ bool stream();
+
+ /**
+ * causes the PlayObject to start the play back.
+ */
+ void play();
+
+ /**
+ * causes the PlayObject to skip to the time @p newTime.
+ * You don't need to stop or restart the play back after calling seek.
+ */
+ void seek(Arts::poTime newTime);
+
+ /**
+ * causes the PlayObject to pause play back immediately. It will not
+ * restart until you call play(). This also works on streams, the
+ * connection to the media source will be maintained while the
+ * PlayObject is paused.
+ */
+ void pause();
+
+ /**
+ * immediately stops the play back and resets the media to the
+ * start of the content. If playing from a stream, halt() causes
+ * the connection to be canceled.
+ */
+
+ void halt();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ QString description();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ Arts::poTime currentTime();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ Arts::poTime overallTime();
+
+ /**
+ * returns the capabilities of the PlayObject. The return value is
+ * a binary OR of Arts::capSeek and Arts::capPause, or 0.
+ */
+ Arts::poCapabilities capabilities();
+
+ /**
+ * Reimplemented (Arts::PlayObject Wrapper)
+ */
+ QString mediaName();
+
+ /**
+ * returns the internal state of the PlayObject. The state can be
+ * either Arts::posIdle, Arts::posPaused or Arts::posPlaying. A
+ * PlayObject in state Arts::posIdle is stopped. Once you call
+ * play(), the state changes to Arts::posPlaying. pause() causes
+ * the PlayObject to change to Arts::posPaused.
+ */
+ Arts::poState state();
+
+signals:
+ /**
+ * this signal is emitted as soon as the internal Arts::PlayObject
+ * is created and ready to play. It is granted that the Arts::PlayObject
+ * has not started playing, but KDE::PlayObject will call
+ * object().play() immediately after emitting this signal, so you
+ * need not do it yourself.
+ */
+ void playObjectCreated();
+
+private slots:
+ void attachPlayObject( Arts::PlayObject );
+
+private:
+ Arts::PlayObject m_playObject;
+ bool m_isStream;
+
+ struct PrivateData;
+ PrivateData* d;
+
+ /* private constructors, to prevent instantiation and copying */
+ PlayObject();
+ PlayObject( const PlayObject& ) : QObject() {};
+ PlayObject(Arts::PlayObject playobject, bool isStream);
+ PlayObject( Arts::SoundServerV2 server, const KURL& url, bool isStream, bool createBUS );
+
+ friend class KDE::PlayObjectFactory;
+
+};
+
+}
+
+#endif
diff --git a/arts/kde/kplayobjectcreator.cc b/arts/kde/kplayobjectcreator.cc
new file mode 100644
index 000000000..26b4308ab
--- /dev/null
+++ b/arts/kde/kplayobjectcreator.cc
@@ -0,0 +1,104 @@
+ /*
+
+ Copyright (C) 2002 Matthias Welwarsky <mwelwarsky@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include <kio/kmimetype.h>
+#include "artskde.h"
+#include "kplayobjectcreator.h"
+#include "kplayobjectcreator.moc"
+#include "kioinputstream_impl.h"
+
+#include <qfile.h>
+
+#include <kdebug.h>
+
+KDE::PlayObjectCreator::PlayObjectCreator(Arts::SoundServerV2 server)
+{
+ m_server = server;
+}
+
+KDE::PlayObjectCreator::~PlayObjectCreator()
+{
+}
+
+bool KDE::PlayObjectCreator::create(const KURL& url, bool createBUS, const QObject* receiver, const char* slot)
+{
+ // no need to go any further, and I hate deep indentation
+ if (m_server.isNull() || url.isEmpty() )
+ return false;
+
+ connect( this, SIGNAL( playObjectCreated( Arts::PlayObject ) ),
+ receiver, slot );
+
+ // check if the URL is a local file
+ if (!url.isLocalFile())
+ {
+ m_createBUS = createBUS;
+
+ // This is the RightWay(tm) according to stw
+ Arts::KIOInputStream_impl* instream_impl = new Arts::KIOInputStream_impl();
+ m_instream = Arts::KIOInputStream::_from_base(instream_impl);
+
+ // signal will be called once the ioslave knows the mime-type of the stream
+ connect(instream_impl, SIGNAL(mimeTypeFound(const QString &)),
+ this, SLOT(slotMimeType(const QString &)));
+
+ // GO!
+ m_instream.openURL(url.url().latin1());
+ m_instream.streamStart();
+
+ return true;
+ }
+ kdDebug( 400 ) << "stream is local file: " << url.url() << endl;
+
+ // usual stuff if we have a local file
+ KMimeType::Ptr mimetype = KMimeType::findByURL(url);
+ emit playObjectCreated (
+ m_server.createPlayObjectForURL(std::string(QFile::encodeName(url.path())),
+ std::string(mimetype->name().latin1()),
+ createBUS)
+ );
+ return true;
+}
+
+void KDE::PlayObjectCreator::slotMimeType(const QString& mimetype)
+{
+
+ kdDebug( 400 ) << "slotMimeType called: " << mimetype << endl;
+
+ QString mimetype_copy = mimetype;
+
+ if ( mimetype_copy == "application/octet-stream" )
+ mimetype_copy = QString("audio/x-mp3");
+
+ if (mimetype_copy == "application/x-zerosize")
+ emit playObjectCreated(Arts::PlayObject::null());
+
+ playObject = m_server.createPlayObjectForStream(
+ m_instream,
+ std::string( mimetype_copy.latin1() ),
+ m_createBUS );
+ if ( playObject.isNull() ) {
+ m_instream.streamEnd();
+ emit playObjectCreated( Arts::PlayObject::null() );
+ return;
+ }
+ emit playObjectCreated( playObject );
+}
diff --git a/arts/kde/kplayobjectcreator.h b/arts/kde/kplayobjectcreator.h
new file mode 100644
index 000000000..31b0a0b48
--- /dev/null
+++ b/arts/kde/kplayobjectcreator.h
@@ -0,0 +1,56 @@
+ /*
+
+ Copyright (C) 2002 Matthias Welwarsky <mwelwarsky@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KPLAYOBJECTCREATOR_H
+#define KPLAYOBJECTCREATOR_H
+
+#include <kurl.h>
+#include <qobject.h>
+#include "soundserver.h"
+#include "kioinputstream_impl.h"
+
+namespace KDE {
+
+class PlayObjectCreator : public QObject
+{
+Q_OBJECT
+public:
+ PlayObjectCreator(Arts::SoundServerV2 server);
+ ~PlayObjectCreator();
+
+ bool create(const KURL& url, bool createBUS, const QObject* receiver, const char* slot);
+
+signals:
+ void playObjectCreated(Arts::PlayObject playObject);
+
+private slots:
+ void slotMimeType(const QString &mimetype);
+
+private:
+ Arts::SoundServerV2 m_server;
+ Arts::KIOInputStream m_instream;
+ Arts::PlayObject playObject;
+ bool m_createBUS;
+};
+
+}
+#endif
+
diff --git a/arts/kde/kplayobjectfactory.cc b/arts/kde/kplayobjectfactory.cc
new file mode 100644
index 000000000..ea0218746
--- /dev/null
+++ b/arts/kde/kplayobjectfactory.cc
@@ -0,0 +1,258 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include <kio/kmimetype.h>
+#include "kplayobject.h"
+#include "artskde.h"
+#include "kplayobjectfactory.h"
+#include "kplayobjectfactory_p.h"
+#include "kplayobjectcreator.h"
+#include "kioinputstream_impl.h"
+#include "kartsdispatcher.h"
+#include "kartsserver.h"
+
+#include <qfile.h>
+#include <kdebug.h>
+#include "kaudiomanagerplay.h"
+#include <flowsystem.h>
+#include <kio/netaccess.h>
+
+using namespace std;
+
+KPlayObjectFactory::KPlayObjectFactory(Arts::SoundServerV2 server)
+{
+ m_server = server;
+ m_allowStreaming = true;
+ m_stream = false;
+}
+
+KPlayObjectFactory::KPlayObjectFactory(KArtsServer* server)
+{
+ m_server = server->server();
+ m_allowStreaming = true;
+ m_stream = false;
+}
+
+KPlayObjectFactory::~KPlayObjectFactory()
+{
+}
+
+KPlayObject *KPlayObjectFactory::createPlayObject(const KURL& url, bool createBUS)
+{
+ KMimeType::Ptr mimetype = KMimeType::findByURL(url);
+ return createPlayObject(url, mimetype->name(), createBUS);
+}
+
+
+KPlayObject *KPlayObjectFactory::createPlayObject(const KURL& _url, const QString &mimetype, bool createBUS)
+{
+ // WHY DOES BROKEN KIO_MEDIA GIVE WRONG URLS?
+ // I hate it
+ // I hate it
+ // It sucks
+ // kio_media please die
+ KURL url = KIO::NetAccess::mostLocalURL(_url, 0);
+
+ if(!m_server.isNull())
+ {
+ if(mimetype == "application/octet-stream" && m_allowStreaming)
+ {
+ Arts::KIOInputStream instream;
+ instream.openURL(url.url().latin1());
+
+ m_stream = true;
+
+ // TODO: what else than hardcoding audio/x-mp3 ?
+ return new KPlayObject(m_server.createPlayObjectForStream(instream, string("audio/x-mp3"), createBUS), true);
+ }
+ else
+ return new KPlayObject(m_server.createPlayObjectForURL(string(QFile::encodeName(url.path())), string(mimetype.latin1()), createBUS), false);
+ }
+ else
+ return new KPlayObject();
+}
+
+
+
+//
+
+KDE::PlayObjectFactory::PlayObjectFactory(Arts::SoundServerV2 server)
+{
+ d = new PrivateData;
+ d->server = server;
+ d->amanPlay = 0;
+ d->helper = 0;
+ d->allowStreaming = true;
+ d->isStream = false;
+}
+
+KDE::PlayObjectFactory::PlayObjectFactory(KArtsServer* server)
+{
+ d = new PrivateData;
+ d->server = server->server();
+ d->amanPlay = 0;
+ d->helper = 0;
+ d->allowStreaming = true;
+ d->isStream = false;
+}
+
+KDE::PlayObjectFactory::~PlayObjectFactory()
+{
+ delete d->helper;
+ delete d;
+}
+
+void KDE::PlayObjectFactory::setAudioManagerPlay( KAudioManagerPlay * amanPlay )
+{
+ d->amanPlay = amanPlay;
+ if( ! d->helper )
+ d->helper = new POFHelper;
+}
+
+KDE::PlayObject *KDE::PlayObjectFactory::createPlayObject(const KURL& url, bool createBUS)
+{
+ KMimeType::Ptr mimetype = KMimeType::findByURL(url);
+ return createPlayObject(url, mimetype->name(), createBUS);
+}
+
+KDE::PlayObject *KDE::PlayObjectFactory::createPlayObject(const KURL& _url, const QString &mimetype, bool createBUS)
+{
+ // WHY DOES BROKEN KIO_MEDIA GIVE WRONG URLS?
+ // I hate it
+ // I hate it
+ // It sucks
+ // kio_media please die
+ KURL url = KIO::NetAccess::mostLocalURL(_url, 0);
+
+ // return a NULL playobject if the server is NULL
+ if ( d->server.isNull() || url.isEmpty() )
+ return new KDE::PlayObject();
+
+ // if the program wants to use it's own Synth_AMAN_PLAY we don't need a
+ // bus
+ if( d->amanPlay && createBUS )
+ {
+ kdWarning( 400 ) << "KDE::PlayObjectFactory was instructed to use a Synth_AMAN_PLAY for output but the program also asked for a Synth_BUS_UPLINK" << endl;
+ createBUS = false;
+ }
+
+ // decide if it's a local file. mpeglib provides cdda reading and decoding, so we prefer that over kio_audiocd
+ if ( url.isLocalFile() || !d->allowStreaming || (url.protocol() == "audiocd" && mimetype == "application/x-cda" && mimeTypes().contains( "application/x-cda" ) ) )
+ {
+ // we rely on the delivered mimetype if it's a local file
+ d->playObj = new KDE::PlayObject( d->server.createPlayObjectForURL( string( QFile::encodeName( url.path() ) ), string( mimetype.latin1() ), createBUS ), false );
+ }
+ else
+ {
+ // if non-local, let the KPlayObject figure out the mimetype itself
+ // this invokes asynchronous creation automatically
+ d->playObj = new KDE::PlayObject( d->server, url, true, createBUS );
+ }
+
+ if( d->playObj->isNull() )
+ {
+ delete d->playObj;
+ d->playObj = 0;
+ return new KDE::PlayObject(); // return a NULL playobject
+ }
+
+ if( d->amanPlay )
+ {
+ d->helper->po = d->playObj;
+ d->helper->ap = d->amanPlay;
+ if( d->playObj->object().isNull() && d->amanPlay )
+ QObject::connect( d->playObj, SIGNAL( playObjectCreated() ), d->helper, SLOT( connectAmanPlay() ) );
+ else
+ d->helper->connectAmanPlay();
+ }
+
+ return d->playObj;
+}
+
+QStringList KDE::PlayObjectFactory::mimeTypes(void)
+{
+ KArtsDispatcher dispatcher; // we need such a thing, otherwise we crash
+ Arts::TraderQuery query;
+ vector<Arts::TraderOffer> *offers = query.query();
+
+ QStringList results;
+ for(vector<Arts::TraderOffer>::iterator offer = offers->begin();
+ offer != offers->end(); ++offer)
+ {
+ vector<string> *mimetypes = (*offer).getProperty("MimeType");
+
+ for(vector<string>::iterator mimetype = mimetypes->begin();
+ mimetype != mimetypes->end(); ++mimetype)
+ {
+ QString name = QString::fromLocal8Bit((*mimetype).c_str()).stripWhiteSpace();
+ if(KMimeType::mimeType(name))
+ results.append(name);
+ }
+
+ delete mimetypes;
+ }
+ delete offers;
+
+ // clean out duplicates
+ results.sort();
+ for(QStringList::iterator result = results.begin(); result != results.end(); )
+ {
+ QStringList::iterator previous = result;
+ ++result;
+ if(result != results.end() && *result == *previous)
+ {
+ results.remove(result);
+ result = previous;
+ }
+ }
+
+ return results;
+}
+
+/* ### KDE4
+void KDE::PlayObjectFactory::connectAmanPlay()
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+ if( d->playObj->object().isNull() )
+ return;
+
+ d->amanPlay->start();
+ d->playObj->object()._node()->start();
+ Arts::connect( d->playObj->object(), "left" , d->amanPlay->amanPlay(), "left" );
+ Arts::connect( d->playObj->object(), "right", d->amanPlay->amanPlay(), "right" );
+}
+*/
+
+void KDE::POFHelper::connectAmanPlay()
+{
+ kdDebug( 400 ) << k_funcinfo << endl;
+ if( po->object().isNull() )
+ return;
+
+ ap->start();
+ po->object()._node()->start();
+ Arts::connect( po->object(), "left" , ap->amanPlay(), "left" );
+ Arts::connect( po->object(), "right", ap->amanPlay(), "right" );
+}
+
+#include "kplayobjectfactory_p.moc"
+
+// vim: sw=4 ts=4 noet
diff --git a/arts/kde/kplayobjectfactory.h b/arts/kde/kplayobjectfactory.h
new file mode 100644
index 000000000..2f9c096fc
--- /dev/null
+++ b/arts/kde/kplayobjectfactory.h
@@ -0,0 +1,156 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#ifndef KPLAYOBJECTFACTORY_H
+#define KPLAYOBJECTFACTORY_H
+
+#include <kurl.h>
+#include <kdelibs_export.h>
+
+#include "soundserver.h"
+#include "kplayobject.h"
+
+class KArtsServer;
+
+class KDE_EXPORT KPlayObjectFactory
+{
+public:
+ /**
+ * Constructs a new Factory for creating aRts playobjects on the
+ * soundserver.
+ */
+ KPlayObjectFactory(Arts::SoundServerV2 server);
+
+ /**
+ * Convenience constructor to pass a KArtsServer instead of an
+ * Arts::SoundServerV2. This equivalent to calling
+ * KPlayObjectFactory( server.server() ).
+ *
+ * @since 3.2
+ */
+ KPlayObjectFactory(KArtsServer* server);
+
+ ~KPlayObjectFactory();
+
+ KPlayObject *createPlayObject(const KURL& url, bool createBUS);
+ KPlayObject *createPlayObject(const KURL& url, const QString &mimetype, bool createBUS);
+
+ void setAllowStreaming(bool s) { m_allowStreaming = s; }
+ bool allowStreaming() { return m_allowStreaming; }
+
+ bool isAStream() { return m_stream; }
+
+private:
+ Arts::SoundServerV2 m_server;
+ bool m_allowStreaming;
+ bool m_stream;
+};
+
+class KAudioManagerPlay;
+
+namespace KDE {
+
+class POFHelper;
+
+ /**
+ * This class implements a factory to create KDE::PlayObjects for
+ * a given URL and mimetype. A detailed description about how to
+ * use the KDE multimedia framework can be found in the documentation
+ * for KDE::PlayObject.
+ */
+class KDE_EXPORT PlayObjectFactory// : public QObject ### for KDE4 make it a QObject to be able to receive signals
+{
+public:
+ /**
+ * Creates a KDE::PlayObjectFactory. @p server is an
+ * Arts::SoundServerV2
+ */
+ PlayObjectFactory(Arts::SoundServerV2 server);
+ /**
+ * Convenience constructor to pass a KArtsServer instead of an
+ * Arts::SoundServerV2. This equivalent to calling
+ * KDE::PlayObjectFactory( server.server() ).
+ *
+ * @since 3.2
+ */
+ PlayObjectFactory( KArtsServer* server );
+ ~PlayObjectFactory();
+
+ /**
+ * If this is set the PlayObject doesn't create a Synth_BUS_UPLINK at all
+ * but always uses the Synth_AMAN_PLAY that you passed.
+ */
+ void setAudioManagerPlay( KAudioManagerPlay * amanplay );
+
+ /**
+ * Creates a KDE::PlayObject to play back the file or stream
+ * @p url points to. Set @p createBUS to "true", if you want the
+ * PlayObject to be connected to a SYNTH_BUS_UPLINK on creation.
+ * This is usually the case. You only need to set this to "false"
+ * if you want to attach your own sound effects to the PlayObject.
+ *
+ * You don't need to know the mimetype of the file or stream, it
+ * will be detected automatically.
+ */
+ KDE::PlayObject *createPlayObject(const KURL& url, bool createBUS);
+
+ /**
+ * This method also creates a KDE::PlayObject, but does no automatic
+ * mimetype detection. Use this method with care.
+ */
+ KDE::PlayObject *createPlayObject(const KURL& url, const QString &mimetype, bool createBUS);
+
+ /**
+ * setAllowStreaming( true ) allows the factory to create a
+ * streaming PlayObject for a non-local URL. This is also the default.
+ * Usually, you should not need to set this to false.
+ */
+ void setAllowStreaming(bool s) { d->allowStreaming = s; }
+
+ /**
+ * returns "true" if the factory is allowed to create streaming
+ * PlayObjects.
+ */
+ bool allowStreaming() { return d->allowStreaming; }
+
+ /**
+ * Return the mimetypes that are playable
+ */
+ static QStringList mimeTypes(void);
+
+/*private slots: ### KDE4 and remove Helper class
+ void connectAmanPlay();*/
+
+private:
+ struct PrivateData {
+ Arts::SoundServerV2 server;
+ KDE::PlayObject* playObj;
+ KAudioManagerPlay* amanPlay;
+ POFHelper* helper;
+ bool allowStreaming;
+ bool isStream;
+ };
+ PrivateData* d;
+};
+
+}
+#endif
+// vim: sw=4 ts=4 noet
diff --git a/arts/kde/kplayobjectfactory_p.h b/arts/kde/kplayobjectfactory_p.h
new file mode 100644
index 000000000..21ea4c4e9
--- /dev/null
+++ b/arts/kde/kplayobjectfactory_p.h
@@ -0,0 +1,46 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KPLAYOBJECTFACTORY_P_H
+#define KPLAYOBJECTFACTORY_P_H
+
+#include <qobject.h>
+#include "kplayobjectfactory.h"
+
+namespace KDE
+{
+
+/**
+ * @internal
+ */
+class POFHelper : public QObject
+{
+ friend class PlayObjectFactory;
+ Q_OBJECT
+private slots:
+ void connectAmanPlay();
+private:
+ KDE::PlayObject *po;
+ KAudioManagerPlay *ap;
+};
+
+}
+
+#endif // KPLAYOBJECTFACTORY_P_H
+// vim: sw=4 ts=4 noet
diff --git a/arts/kde/kvideowidget.cpp b/arts/kde/kvideowidget.cpp
new file mode 100644
index 000000000..2b0fbd66b
--- /dev/null
+++ b/arts/kde/kvideowidget.cpp
@@ -0,0 +1,446 @@
+/*
+ This file is part of KDE/aRts (Noatun) - xine integration
+ Copyright (C) 2002 Ewald Snel <ewald@rambo.its.tudelft.nl>
+ Copyright (C) 2002 Neil Stevens <neil@qualityassistant.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2 as published by the Free Software Foundation.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <time.h>
+#ifdef HAVE_USLEEP
+#include <unistd.h>
+#endif
+#include <qaccel.h>
+#include <qcursor.h>
+
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#else
+#define XEvent void
+#endif
+
+#include <kaction.h>
+#include <klocale.h>
+#include "kvideowidget.h"
+
+
+class KFullscreenVideoWidget : public KVideoWidget
+{
+public:
+ KFullscreenVideoWidget( KVideoWidget *parent = 0, const char *name = 0 );
+
+protected:
+ virtual void windowActivationChange( bool );
+ virtual bool x11Event( XEvent *event );
+
+private:
+ KVideoWidget *videoWidget;
+};
+
+KFullscreenVideoWidget::KFullscreenVideoWidget( KVideoWidget *parent, const char *name )
+ : KVideoWidget( 0, name )
+{
+ this->videoWidget = parent;
+ setEraseColor( black );
+ setCursor(QCursor(Qt::BlankCursor));
+}
+
+void KFullscreenVideoWidget::windowActivationChange( bool )
+{
+ if (!isActiveWindow())
+ {
+ videoWidget->setWindowed();
+ }
+}
+
+bool KFullscreenVideoWidget::x11Event( XEvent *event )
+{
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ if (event->type == ClientMessage &&
+ event->xclient.message_type ==
+ XInternAtom( qt_xdisplay(), "VPO_RESIZE_NOTIFY", False ))
+ {
+ videoWidget->resizeNotify( event->xclient.data.l[0], event->xclient.data.l[1] );
+ }
+#endif
+ return false;
+}
+
+KVideoWidget::KVideoWidget( KXMLGUIClient *clientParent, QWidget *parent, const char *name, WFlags f )
+ : KXMLGUIClient( clientParent ),
+ QWidget( parent, name, f )
+{
+ init();
+ // ???
+ QString toolbarName = i18n("Video Toolbar");
+ setXML(QString("<!DOCTYPE kpartgui>\n<kpartgui name=\"kvideowidget\" version=\"1\"><MenuBar><Menu name=\"edit\"><Separator/><Action name=\"double_size\"/><Action name=\"normal_size\"/><Action name=\"half_size\"/><Separator/><Action name=\"fullscreen_mode\"/></Menu></MenuBar><Toolbar name=\"VideoToolbar\"><text>Video Toolbar</text><Action name=\"fullscreen_mode\"/></Toolbar></kpartgui>"), true);
+}
+
+KVideoWidget::KVideoWidget( QWidget *parent, const char *name, WFlags f )
+ : QWidget( parent, name, f )
+{
+ init();
+}
+
+void KVideoWidget::init(void)
+{
+ setMinimumSize(0, 0);
+ setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+ setFocusPolicy( ClickFocus );
+
+ fullscreenWidget = 0;
+ poVideo = Arts::VideoPlayObject::null();
+ videoWidth = 0;
+ videoHeight = 0;
+
+ // Setup actions
+ new KToggleAction( i18n("Fullscreen &Mode"), "window_fullscreen",
+ CTRL+SHIFT+Key_F, this, SLOT(fullscreenActivated()),
+ actionCollection(), "fullscreen_mode" );
+ new KRadioAction( i18n("&Half Size"), ALT+Key_0,
+ this, SLOT(halfSizeActivated()),
+ actionCollection(), "half_size" );
+ new KRadioAction( i18n("&Normal Size"), ALT+Key_1,
+ this, SLOT(normalSizeActivated()),
+ actionCollection(), "normal_size" );
+ new KRadioAction( i18n("&Double Size"), ALT+Key_2,
+ this, SLOT(doubleSizeActivated()),
+ actionCollection(), "double_size" );
+
+ ((KToggleAction *)action( "half_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
+ ((KToggleAction *)action( "normal_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
+ ((KToggleAction *)action( "double_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
+
+ action("double_size")->setEnabled(false);
+ action("half_size")->setEnabled(false);
+ action("normal_size")->setEnabled(false);
+ action("fullscreen_mode")->setEnabled(false);
+}
+
+KVideoWidget::~KVideoWidget()
+{
+ if (isEmbedded())
+ {
+ poVideo.x11WindowId( -1 );
+ poVideo = Arts::VideoPlayObject::null();
+ }
+
+ delete fullscreenWidget;
+}
+
+void KVideoWidget::embed( Arts::VideoPlayObject vpo )
+{
+ bool enable;
+ if (vpo.isNull())
+ {
+ if (isEmbedded())
+ {
+ poVideo.x11WindowId( -1 );
+ poVideo = Arts::VideoPlayObject::null();
+ }
+
+ setBackgroundMode( PaletteBackground );
+ repaint();
+
+ // Resize GUI
+ videoWidth = 0;
+ videoHeight = 0;
+
+ if (isHalfSize() || isNormalSize() || isDoubleSize())
+ emit adaptSize( 0, 0 );
+
+ enable = false;
+ updateGeometry();
+ }
+ else
+ {
+ if (isEmbedded())
+ {
+ poVideo.x11WindowId( -1 );
+ }
+
+ poVideo = vpo;
+
+ // Don't reset fullscreen mode for video playlists
+ if (fullscreenWidget)
+ {
+ poVideo.x11WindowId( fullscreenWidget->winId() );
+ fullscreenWidget->setBackgroundMode( NoBackground );
+
+ setEraseColor( black );
+ }
+ else
+ {
+ poVideo.x11WindowId( winId() );
+ setBackgroundMode( NoBackground );
+ }
+ enable = true;
+ }
+ action("double_size")->setEnabled(enable);
+ action("half_size")->setEnabled(enable);
+ action("normal_size")->setEnabled(enable);
+ action("fullscreen_mode")->setEnabled(enable);
+}
+
+QImage KVideoWidget::snapshot( Arts::VideoPlayObject vpo )
+{
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ Window root;
+ Pixmap pixmap;
+ XImage *xImage;
+ unsigned int width, height, border, depth;
+ int x, y;
+
+ if (vpo.isNull() || (long)(pixmap = vpo.x11Snapshot()) == -1)
+ return QImage();
+
+ // Get 32bit RGBA image data (stored in 1bpp pixmap)
+ XGetGeometry( qt_xdisplay(), pixmap, &root, &x, &y, &width, &height, &border, &depth );
+
+ xImage = XGetImage( qt_xdisplay(), pixmap, 0, 0, width, height, 1, XYPixmap );
+
+ if (xImage == 0)
+ {
+ XFreePixmap( qt_xdisplay(), pixmap );
+ return QImage();
+ }
+
+ // Convert 32bit RGBA image data into Qt image
+ QImage qImage = QImage( (uchar *)xImage->data, width/32, height, 32, (QRgb *)0, 0, QImage::IgnoreEndian ).copy();
+
+ // Free X11 resources and return Qt image
+ XDestroyImage( xImage );
+ XFreePixmap( qt_xdisplay(), pixmap );
+
+ return qImage;
+#else
+ return 0;
+#endif
+}
+
+bool KVideoWidget::isEmbedded()
+{
+ return !poVideo.isNull();
+}
+
+bool KVideoWidget::isFullscreen()
+{
+ return ((KToggleAction *)action( "fullscreen_mode" ))->isChecked();
+}
+
+bool KVideoWidget::isHalfSize()
+{
+ return ((KToggleAction *)action( "half_size" ))->isChecked();
+}
+
+bool KVideoWidget::isNormalSize()
+{
+ return ((KToggleAction *)action( "normal_size" ))->isChecked();
+}
+
+bool KVideoWidget::isDoubleSize()
+{
+ return ((KToggleAction *)action( "double_size" ))->isChecked();
+}
+
+void KVideoWidget::setFullscreen()
+{
+ if (!isFullscreen())
+ {
+ ((KToggleAction *)action( "fullscreen_mode" ))->setChecked( true );
+ fullscreenActivated();
+ }
+}
+
+void KVideoWidget::setWindowed()
+{
+ if (isFullscreen())
+ {
+ ((KToggleAction *)action( "fullscreen_mode" ))->setChecked( false );
+ fullscreenActivated();
+ }
+}
+
+void KVideoWidget::setHalfSize()
+{
+ ((KToggleAction *)action( "half_size" ))->setChecked( true );
+ halfSizeActivated();
+}
+
+void KVideoWidget::setNormalSize()
+{
+ ((KToggleAction *)action( "normal_size" ))->setChecked( true );
+ normalSizeActivated();
+}
+
+void KVideoWidget::setDoubleSize()
+{
+ ((KToggleAction *)action( "double_size" ))->setChecked( true );
+ doubleSizeActivated();
+}
+
+QSize KVideoWidget::sizeHint() const
+{
+ return QSize( videoWidth, videoHeight );
+}
+
+int KVideoWidget::heightForWidth( int w ) const
+{
+ if(videoWidth == 0)
+ return 0;
+ else
+ return int( double(w)*double(videoHeight)/double(videoWidth) );
+}
+
+void KVideoWidget::mousePressEvent( QMouseEvent *event )
+{
+ QPoint pos = mapToGlobal( event->pos() );
+
+ emit mouseButtonPressed( event->button(), pos, event->state() );
+
+ // ### Remove in KDE4
+ if ( event->button() == RightButton )
+ emit rightButtonPressed( pos );
+}
+
+void KVideoWidget::mouseDoubleClickEvent( QMouseEvent *event )
+{
+ emit mouseButtonDoubleClick( mapToGlobal( event->pos() ), event->state() );
+}
+
+void KVideoWidget::resizeEvent( QResizeEvent *event )
+{
+ QWidget::resizeEvent( event );
+
+ if (width() > minimumWidth() || height() > minimumHeight())
+ {
+ if (width() == QMAX( (videoWidth / 2), minimumWidth() ) &&
+ height() == QMAX( (videoHeight / 2), minimumHeight() ))
+ ((KToggleAction *)action( "half_size" ))->setChecked( true );
+ else if (width() == QMAX( videoWidth, minimumWidth() ) &&
+ height() == QMAX( videoHeight, minimumHeight() ))
+ ((KToggleAction *)action( "normal_size" ))->setChecked( true );
+ else if (width() == QMAX( (2 * videoWidth), minimumWidth() ) &&
+ height() == QMAX( (2 * videoHeight), minimumHeight() ))
+ ((KToggleAction *)action( "double_size" ))->setChecked( true );
+ else
+ {
+ ((KToggleAction *)action( "half_size" ))->setChecked( false );
+ ((KToggleAction *)action( "normal_size" ))->setChecked( false );
+ ((KToggleAction *)action( "double_size" ))->setChecked( false );
+ }
+ }
+}
+
+void KVideoWidget::resizeNotify( int width, int height )
+{
+ if(!isEmbedded()) return;
+
+ videoWidth = width;
+ videoHeight = height;
+
+ if (isHalfSize())
+ emit adaptSize( (videoWidth / 2), (videoHeight / 2) );
+ else if (isNormalSize())
+ emit adaptSize( videoWidth, videoHeight );
+ else if (isDoubleSize())
+ emit adaptSize( (2 * videoWidth), (2 * videoHeight) );
+
+ updateGeometry();
+}
+
+bool KVideoWidget::x11Event( XEvent *event )
+{
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ if (event->type == ClientMessage &&
+ event->xclient.message_type ==
+ XInternAtom( qt_xdisplay(), "VPO_RESIZE_NOTIFY", False ))
+ {
+ resizeNotify( event->xclient.data.l[0], event->xclient.data.l[1] );
+ }
+#endif
+ return false;
+}
+
+void KVideoWidget::fullscreenActivated()
+{
+ if (isFullscreen() == (fullscreenWidget != 0))
+ return;
+
+ if (isFullscreen())
+ {
+ fullscreenWidget = new KFullscreenVideoWidget( this );
+
+ // Interconnect mouse button signals
+ connect( fullscreenWidget, SIGNAL(mouseButtonPressed( int, const QPoint &, int )),
+ this, SIGNAL(mouseButtonPressed( int, const QPoint &, int)) );
+
+ connect( fullscreenWidget, SIGNAL(mouseButtonDoubleClick( const QPoint &, int )),
+ this, SIGNAL(mouseButtonDoubleClick( const QPoint &, int )) );
+
+ // ### Remove in KDE4
+ connect( fullscreenWidget, SIGNAL(rightButtonPressed(const QPoint &)),
+ this, SIGNAL(rightButtonPressed(const QPoint &)) );
+
+ // Leave fullscreen mode with <Escape> key
+ QAccel *a = new QAccel( fullscreenWidget );
+ a->connectItem( a->insertItem( Key_Escape ),
+ this, SLOT(setWindowed()) );
+
+ fullscreenWidget->setFocus();
+ fullscreenWidget->showFullScreen();
+
+ if (isEmbedded())
+ {
+ poVideo.x11WindowId( fullscreenWidget->winId() );
+ fullscreenWidget->setBackgroundMode( NoBackground );
+ }
+ }
+ else
+ {
+ if (isEmbedded())
+ {
+ poVideo.x11WindowId( winId() );
+ setBackgroundMode( NoBackground );
+ }
+
+ delete fullscreenWidget;
+ fullscreenWidget = 0;
+ }
+}
+
+void KVideoWidget::halfSizeActivated()
+{
+ if (isHalfSize())
+ {
+ if(isEmbedded()) emit adaptSize( (videoWidth / 2), (videoHeight / 2) );
+ setWindowed();
+ }
+}
+
+void KVideoWidget::normalSizeActivated()
+{
+ if (isNormalSize())
+ {
+ if(isEmbedded()) emit adaptSize( videoWidth, videoHeight );
+ setWindowed();
+ }
+}
+
+void KVideoWidget::doubleSizeActivated()
+{
+ if (isDoubleSize())
+ {
+ if(isEmbedded()) emit adaptSize( (2 * videoWidth), (2 * videoHeight) );
+ setWindowed();
+ }
+}
+
+#include "kvideowidget.moc"
diff --git a/arts/kde/kvideowidget.h b/arts/kde/kvideowidget.h
new file mode 100644
index 000000000..f314267ca
--- /dev/null
+++ b/arts/kde/kvideowidget.h
@@ -0,0 +1,82 @@
+/*
+ This file is part of KDE/aRts (Noatun) - xine integration
+ Copyright (C) 2002 Ewald Snel <ewald@rambo.its.tudelft.nl>
+ Copyright (C) 2002 Neil Stevens <neil@qualityassistant.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2 as published by the Free Software Foundation.
+*/
+
+#ifndef ARTSKDE_KVIDEOWIDGET_H
+#define ARTSKDE_KVIDEOWIDGET_H
+
+#include <qevent.h>
+#include <qimage.h>
+#include <qwidget.h>
+#include <kmedia2.h>
+#include <kxmlguiclient.h>
+
+
+class KDE_ARTS_EXPORT KVideoWidget : public QWidget, virtual public KXMLGUIClient
+{
+Q_OBJECT
+
+public:
+ KVideoWidget( KXMLGUIClient *clientParent, QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ KVideoWidget( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ virtual ~KVideoWidget();
+
+ void embed( Arts::VideoPlayObject vpo );
+ static QImage snapshot( Arts::VideoPlayObject vpo );
+
+ bool isEmbedded();
+ bool isFullscreen();
+ bool isHalfSize();
+ bool isNormalSize();
+ bool isDoubleSize();
+
+ QSize sizeHint() const;
+
+ virtual int heightForWidth ( int w ) const;
+
+protected:
+ virtual void mousePressEvent( QMouseEvent *event );
+ virtual void mouseDoubleClickEvent( QMouseEvent *event);
+ virtual void resizeEvent( QResizeEvent *event );
+ virtual bool x11Event( XEvent *event );
+
+public slots:
+ void setFullscreen();
+ void setWindowed();
+ void setHalfSize();
+ void setNormalSize();
+ void setDoubleSize();
+
+ void resizeNotify( int width, int height );
+
+protected slots:
+ void fullscreenActivated();
+ void halfSizeActivated();
+ void normalSizeActivated();
+ void doubleSizeActivated();
+
+signals:
+ void adaptSize( int width, int height );
+ void mouseButtonPressed( int type, const QPoint &, int state );
+ void mouseButtonDoubleClick( const QPoint &, int state );
+ /**
+ * @deprecated
+ * use mouseButtonPressed( int type, const QPoint & ) instead.
+ */
+ void rightButtonPressed( const QPoint & );
+
+private:
+ void init(void);
+ QWidget *fullscreenWidget;
+ int videoWidth;
+ int videoHeight;
+ Arts::VideoPlayObject poVideo;
+};
+
+#endif
diff --git a/arts/kde/mcop-dcop/Makefile.am b/arts/kde/mcop-dcop/Makefile.am
new file mode 100644
index 000000000..6e2b90eac
--- /dev/null
+++ b/arts/kde/mcop-dcop/Makefile.am
@@ -0,0 +1,20 @@
+
+INCLUDES= -I$(includedir)/arts -I$(top_srcdir)/arts/kde $(all_includes)
+
+bin_PROGRAMS=
+lib_LTLIBRARIES =
+kdeinit_LTLIBRARIES = kmcop.la
+
+kmcop_la_SOURCES = mcopdcopobject.cpp kmcop.cpp kmcop.skel
+kmcop_la_LIBADD = ../libartskde.la
+kmcop_la_LDFLAGS = $(all_libraries) -module -avoid-version
+kmcop_la_METASOURCES = AUTO
+
+noinst_HEADERS = kmcop.h
+
+kdelnkdir = $(kde_servicesdir)
+kdelnk_DATA = kmcop.desktop
+
+messages:
+ $(XGETTEXT) kmcop.cpp -o $(podir)/kmcop.pot
+
diff --git a/arts/kde/mcop-dcop/kmcop.cpp b/arts/kde/mcop-dcop/kmcop.cpp
new file mode 100644
index 000000000..22e19dc9d
--- /dev/null
+++ b/arts/kde/mcop-dcop/kmcop.cpp
@@ -0,0 +1,171 @@
+/*
+ Copyright (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <kdebug.h>
+#include <kuniqueapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <dcopclient.h>
+
+#include <qvaluelist.h>
+#include <qcstring.h>
+
+#include <kartsdispatcher.h>
+#include <soundserver.h>
+#include <dispatcher.h>
+#include <object.h>
+#include <core.h>
+
+#include "mcopdcopobject.h"
+
+#include "kmcop.moc"
+
+using namespace Arts;
+using namespace std;
+
+class KMCOPPrivate
+{
+public:
+ MCOPInfo mcopInfo;
+ QPtrList<MCOPDCOPObject> list;
+};
+
+int main(int argc, char **argv)
+{
+ KAboutData aboutdata("kmcop", I18N_NOOP("KMCOP"),
+ "0.1", I18N_NOOP("KDE MCOP-DCOP Bridge"),
+ KAboutData::License_GPL, "(C) 2001, Nikolas Zimmermann");
+ aboutdata.addAuthor("Nikolas Zimmermann", I18N_NOOP("Author"), "wildfox@kde.org");
+
+ KCmdLineArgs::init(argc, argv, &aboutdata);
+ KUniqueApplication::addCmdLineOptions();
+
+ if(!KUniqueApplication::start())
+ {
+ kdDebug() << "Running kmcop found" << endl;
+ return 0;
+ }
+
+ KUniqueApplication app;
+ app.disableSessionManagement();
+
+ KArtsDispatcher dispatcher;
+
+ KMCOP notify;
+ app.dcopClient()->setDefaultObject("arts");
+ app.dcopClient()->setDaemonMode(true);
+
+ return app.exec();
+}
+
+KMCOP::KMCOP() : QObject(), DCOPObject("arts")
+{
+ d = new KMCOPPrivate();
+ d->mcopInfo = Reference("global:Arts_MCOPInfo");
+ d->list.setAutoDelete(true);
+}
+
+KMCOP::~KMCOP()
+{
+ delete d;
+}
+
+int KMCOP::objectCount()
+{
+ return d->mcopInfo.objectCount();
+}
+
+QCString KMCOP::correctType(const QCString &str)
+{
+ if(str == "string")
+ return "QCString";
+ return str;
+}
+
+void KMCOP::addInterfacesHackHackHack()
+{
+ for(int i = 0; i <= objectCount(); i++)
+ {
+ Arts::Object obj = d->mcopInfo.objectForNumber(i);
+
+ if(!obj.isNull())
+ {
+ QCString interfaceName = obj._interfaceName().c_str();
+
+ if(interfaceName != "Arts::TraderOffer")
+ {
+ Arts::InterfaceRepo ifaceRepo = Dispatcher::the()->interfaceRepo();
+
+ MCOPDCOPObject *interface = new MCOPDCOPObject(interfaceName);
+ d->list.append(interface);
+
+ InterfaceDef ifaceDef = ifaceRepo.queryInterface(string(interfaceName));
+ vector<MethodDef> ifaceMethods = ifaceDef.methods;
+
+ vector<MethodDef>::iterator ifaceMethodsIterator;
+ for(ifaceMethodsIterator = ifaceMethods.begin(); ifaceMethodsIterator != ifaceMethods.end(); ifaceMethodsIterator++)
+ {
+ QCString function, signature;
+
+ MCOPEntryInfo *entry = new MCOPEntryInfo();
+
+ MethodDef currentMethod = *ifaceMethodsIterator;
+ vector<ParamDef> currentParameters = currentMethod.signature;
+
+ QCString newType = correctType(QCString(currentMethod.type.c_str()));
+
+ entry->setFunctionType(newType);
+ entry->setFunctionName(QCString(currentMethod.name.c_str()));
+
+ function = entry->functionType() + QCString(" ") + entry->functionName() + QCString("(");
+
+ signature = QCString("(");
+
+ QCStringList signatureList;
+
+ vector<ParamDef>::iterator methodParametersIterator;
+ for(methodParametersIterator = currentParameters.begin(); methodParametersIterator != currentParameters.end(); methodParametersIterator++)
+ {
+ ParamDef parameter = *methodParametersIterator;
+ if(methodParametersIterator != currentParameters.begin())
+ {
+ function += QCString(", ");
+ signature += QCString(",");
+ }
+
+ QCString correctParameter = correctType(QCString(parameter.type.c_str()));
+
+ function += correctParameter;
+ signature += correctParameter;
+
+ signatureList.append(QCString(parameter.type.c_str()));
+ }
+
+ function += QCString(")");
+ signature += QCString(")");
+
+ entry->setSignature(signature);
+ entry->setSignatureList(signatureList);
+
+ interface->addDynamicFunction(function, entry);
+ }
+ }
+ }
+ }
+}
diff --git a/arts/kde/mcop-dcop/kmcop.desktop b/arts/kde/mcop-dcop/kmcop.desktop
new file mode 100644
index 000000000..4e6400ef1
--- /dev/null
+++ b/arts/kde/mcop-dcop/kmcop.desktop
@@ -0,0 +1,90 @@
+[Desktop Entry]
+Type=Service
+Name=KMCOP
+Name[hi]=के-एमकॉप
+Name[te]=కెఎంకాప్
+Exec=kmcop
+Comment=KDE MCOP-DCOP Bridge
+Comment[af]=KDE MCOP-DCOP Brug
+Comment[ar]=جسر KDE MCOP-DCOP
+Comment[az]=KDE MCOP-DCOP Körpüsü
+Comment[be]=Сувязь MCOP/DCOP
+Comment[bn]=কে.ডি.ই MCOP-DCOP ব্রিজ
+Comment[br]=Pont KDE MCOP-DCOP
+Comment[bs]=KDE MCOP-DCOP prelaz
+Comment[ca]=Connector MCOP-DCOP per al KDE
+Comment[cs]=KDE MCOP-DCOP můstek
+Comment[csb]=Mostk KDE MCOP-DCOP
+Comment[cy]=Pont MCOP-DCOP KDE
+Comment[da]=KDE MCOP-DCOP-bro
+Comment[de]=Verbindung zwischen MCOP und DCOP
+Comment[el]=Γέφυρα MCOP-DCOP του KDE
+Comment[eo]=KDE-ponto inter MCOP-DCOP
+Comment[es]=Puente KDE MCOP-DCOP
+Comment[et]=KDE MCOP-DCOP sild
+Comment[eu]=KDEren MCOP-DCOP zubia
+Comment[fa]=پل KDE MCOP-DCOP
+Comment[fi]=MCOP-DCOP -silta
+Comment[fo]=KDE MCOP-DCOP-brúgv
+Comment[fr]=Passerelle MCOP-DCOP pour KDE
+Comment[ga]=Droichead KDE idir MCOP agus DCOP
+Comment[gl]=Ponte MCOP-DCOP de KDE
+Comment[he]=גשר MCOP-DCOP ל־KDE
+Comment[hi]=केडीई MCOP-डीकॉप ब्रिज
+Comment[hr]=KDE most MCOP-DCOP
+Comment[hsb]=KDE MCOP-DCOP-móst
+Comment[hu]=KDE MCOP-DCOP összekötőprogram
+Comment[id]=Jembatan KDE MCOP-DCOP
+Comment[is]=KDE MCOP-DCOP brú
+Comment[it]=Ponte MCOP-DCOP per KDE
+Comment[ja]=KDE MCOP-DCOP ブリッジ
+Comment[ka]=KDE MCOP-DCOP ხიდი
+Comment[kk]=KDE MCOP-DCOP көпірі
+Comment[ko]=KDE MCOP-DCOP 브릿지
+Comment[lb]=KDE-MCOP-DCOP-Bréck
+Comment[lt]=KDE MCOP-DCOP tiltas
+Comment[lv]=KDE MCOP-DCOP Tilts
+Comment[mk]=KDE MCOP-DCOP Мост
+Comment[mn]=KDE-н MCOP ба DCOP хоорондын гүүр
+Comment[ms]=Jambatan KDE MCOP-DCOP
+Comment[mt]=Pont bejn MCOP u DCOP
+Comment[nb]=KDE MCOP-DCOP Bro
+Comment[nds]=KDE-Brüch twischen MCOP un DCOP
+Comment[ne]=KDE MCOP-DCOP ब्रिज
+Comment[nn]=MCOP-DCOP-bru for KDE
+Comment[nso]=Leporogo la KDE MCOP-DCOP
+Comment[pa]=KDE MCOP-DCOP ਪੁੱਲ
+Comment[pl]=Mostek MCOP-DCOP
+Comment[pt]=Ponte MCOP-DCOP para o KDE
+Comment[pt_BR]=Ligação KDE MCOP-DCOP
+Comment[ro]=Punte MCOP-DCOP KDE
+Comment[ru]=Мост MCOP-DCOP
+Comment[rw]=Iteme MCOP-DCOP KDE
+Comment[se]=KDE MCOP-DCOP šaldi
+Comment[sk]=Most KDE MCOP-DCOP
+Comment[sl]=Premostitelj MCOP-DCOP za KDE
+Comment[sq]=Ura e KDE MCOP-DCOP-it
+Comment[sr]=KDED MCOP-DCOP мост
+Comment[sr@Latn]=KDED MCOP-DCOP most
+Comment[ss]=Libhuloho le MCOP-DCOP ku KDE
+Comment[sv]=KDE MCOP-DCOP-brygga
+Comment[ta]=கேடிஇ MCOP-DCOP பாலம்
+Comment[te]=కెడిఈ ఎంసిఓపి-డిసిఓపి వారధి
+Comment[tg]=Пайвасти KDE MCOP-DCOP
+Comment[th]=ตัวเชื่อม KDE MCOP-DCOP
+Comment[tr]=KDE MCOP-DCOP Köprüsü
+Comment[tt]=KDE MCOP-DCOP Küpere
+Comment[uk]=Міст KDE MCOP-DCOP
+Comment[uz]=KDE MCOP-DCOP koʻprigi
+Comment[uz@cyrillic]=KDE MCOP-DCOP кўприги
+Comment[ven]=KDE MCOP-DCOP Buroho
+Comment[vi]=Cầu MCOP-DCOP của KDE
+Comment[xh]=KDE MCOP-DCOP Ibhulorho
+Comment[zh_CN]=KDE MCOP-DCOP 桥
+Comment[zh_HK]=KDE MCOP-DCOP 橋樑
+Comment[zh_TW]=KDE MCOP-DCOP 橋樑
+Comment[zu]=Ibhulogo le-KDE MCOP-DCOP
+Icon=kmcop
+ServiceTypes=KMCOP
+X-DCOP-ServiceType=Unique
+X-KDE-StartupNotify=false
diff --git a/arts/kde/mcop-dcop/kmcop.h b/arts/kde/mcop-dcop/kmcop.h
new file mode 100644
index 000000000..c81e385ff
--- /dev/null
+++ b/arts/kde/mcop-dcop/kmcop.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KMCOP_H
+#define KMCOP_H
+
+#include <qobject.h>
+
+#include <dcopobject.h>
+
+class KMCOPPrivate;
+
+class KMCOP : public QObject,
+ public DCOPObject
+{
+Q_OBJECT
+K_DCOP
+
+public:
+ KMCOP();
+ ~KMCOP();
+
+k_dcop:
+ int objectCount();
+ void addInterfacesHackHackHack();
+
+private:
+ QCString correctType(const QCString &str);
+ KMCOPPrivate *d;
+};
+
+
+#endif
+
diff --git a/arts/kde/mcop-dcop/mcopdcopobject.cpp b/arts/kde/mcop-dcop/mcopdcopobject.cpp
new file mode 100644
index 000000000..f1d1acad5
--- /dev/null
+++ b/arts/kde/mcop-dcop/mcopdcopobject.cpp
@@ -0,0 +1,152 @@
+/*
+ Copyright (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <kdebug.h>
+
+#include <core.h>
+//#include <object.h>
+//#include <reference.h>
+#include <dynamicrequest.h>
+
+#include <qmap.h>
+#include <qdatastream.h>
+
+using namespace std;
+
+#include "mcopdcoptools.h"
+#include "mcopdcopobject.h"
+
+class MCOPDCOPObjectPrivate
+{
+public:
+ QMap<QCString, MCOPEntryInfo *> dynamicFunctions;
+};
+
+MCOPDCOPObject::MCOPDCOPObject(QCString name) : DCOPObject(name)
+{
+ d = new MCOPDCOPObjectPrivate();
+}
+
+MCOPDCOPObject::~MCOPDCOPObject()
+{
+ delete d;
+}
+
+QCStringList MCOPDCOPObject::functionsDynamic()
+{
+ QCStringList returnList;
+
+ QMap<QCString, MCOPEntryInfo *>::iterator it;
+ for(it = d->dynamicFunctions.begin(); it != d->dynamicFunctions.end(); ++it)
+ returnList.append(it.key());
+
+ return returnList;
+}
+
+Arts::Buffer *MCOPDCOPObject::callFunction(MCOPEntryInfo *entry, QCString ifaceName, const QByteArray &data)
+{
+ Arts::Object workingObject = Arts::SubClass(string(ifaceName));
+ Arts::DynamicRequest request(workingObject);
+ request.method(string(entry->functionName()));
+
+ if(entry->signatureList().size() > 0)
+ {
+ QCStringList list = entry->signatureList();
+
+ QCStringList::iterator it;
+ for(it = list.begin(); it != list.end(); ++it)
+ {
+ QCString param = *it;
+
+ kdDebug() << "PARAM: " << param << endl;
+
+ QDataStream argStream(data, IO_ReadOnly);
+
+ if(param == "long")
+ request.param(MCOPDCOPTools::getLong(argStream));
+ else if(param == "string")
+ request.param(MCOPDCOPTools::getString(argStream));
+ }
+ }
+
+ Arts::AnyRef result;
+ if(!request.invoke(result))
+ return 0;
+
+ Arts::Buffer *newBuffer = new Arts::Buffer();
+ result.write(newBuffer);
+
+ return newBuffer;
+}
+
+bool MCOPDCOPObject::processDynamic(const QCString &fun, const QByteArray &data, QCString &replyType, QByteArray &replyData)
+{
+ QMap<QCString, MCOPEntryInfo *>::iterator it;
+ for(it = d->dynamicFunctions.begin(); it != d->dynamicFunctions.end(); ++it)
+ {
+ MCOPEntryInfo *entry = it.data();
+
+ if((entry->functionName() + entry->signature()) == fun)
+ {
+ QCString type = entry->functionType();
+
+ if(type == "void")
+ {
+ replyType = type;
+
+ Arts::Buffer *result = callFunction(entry, objId(), data);
+
+ if(result != 0)
+ delete result;
+ }
+ else if(type == "string")
+ {
+ replyType = "QCString";
+
+ QDataStream reply(replyData, IO_WriteOnly);
+ reply << "fooo!";
+ }
+ else if(type == "long")
+ {
+ replyType = type;
+
+ long returnCode = -1;
+
+ Arts::Buffer *result = callFunction(entry, objId(), data);
+
+ if(result != 0)
+ {
+ returnCode = result->readLong();
+ delete result;
+ }
+
+ QDataStream reply(replyData, IO_WriteOnly);
+ reply << returnCode;
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void MCOPDCOPObject::addDynamicFunction(QCString value, MCOPEntryInfo *entry)
+{
+ d->dynamicFunctions.insert(value, entry);
+}
diff --git a/arts/kde/mcop-dcop/mcopdcopobject.h b/arts/kde/mcop-dcop/mcopdcopobject.h
new file mode 100644
index 000000000..4c7e70cf5
--- /dev/null
+++ b/arts/kde/mcop-dcop/mcopdcopobject.h
@@ -0,0 +1,89 @@
+/*
+ Copyright (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef MCOPDCOPOBJECT_H
+#define MCOPDCOPOBJECT_H
+
+#include <dcopobject.h>
+
+#include <qvaluelist.h>
+#include <qcstring.h>
+
+typedef QValueList<QCString> QCStringList;
+
+class MCOPDCOPObjectPrivate;
+
+class MCOPEntryInfo
+{
+public:
+ MCOPEntryInfo()
+ { }
+
+ ~MCOPEntryInfo()
+ { }
+
+ QCString functionType()
+ { return m_functionType; }
+
+ QCString functionName()
+ { return m_functionName; }
+
+ QCString signature()
+ { return m_signature; }
+
+ QCStringList signatureList()
+ { return m_signatureList; }
+
+ void setFunctionType(QCString s)
+ { m_functionType = s; }
+
+ void setFunctionName(QCString s)
+ { m_functionName = s; }
+
+ void setSignature(QCString s)
+ { m_signature = s; }
+
+ void setSignatureList(QCStringList s)
+ { m_signatureList = s; }
+
+private:
+ QCString m_functionType, m_functionName, m_signature;
+ QCStringList m_signatureList;
+};
+
+class MCOPDCOPObject : public DCOPObject
+{
+public:
+ MCOPDCOPObject(QCString name);
+ ~MCOPDCOPObject();
+
+ virtual bool processDynamic(const QCString &fun, const QByteArray &data, QCString &replyType, QByteArray &replyData);
+ virtual QCStringList functionsDynamic();
+
+ void addDynamicFunction(QCString value, MCOPEntryInfo *entry);
+
+ Arts::Buffer *callFunction(MCOPEntryInfo *entry, QCString ifaceName, const QByteArray &data);
+
+private:
+ MCOPDCOPObjectPrivate *d;
+};
+
+
+#endif
+
diff --git a/arts/kde/mcop-dcop/mcopdcoptools.h b/arts/kde/mcop-dcop/mcopdcoptools.h
new file mode 100644
index 000000000..f1279111c
--- /dev/null
+++ b/arts/kde/mcop-dcop/mcopdcoptools.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef MCOPDCOPTOOLS_H
+#define MCOPDCOPTOOLS_H
+
+#include <string>
+
+#include <qdatastream.h>
+
+class MCOPDCOPTools
+{
+public:
+ static long getLong(QDataStream &stream)
+ {
+ long l;
+ stream << l;
+
+ return l;
+ }
+
+ static std::string getString(QDataStream &stream)
+ {
+ QCString s;
+ stream << s;
+
+ return std::string(s);
+ }
+};
+
+#endif
diff --git a/arts/knotify/Makefile.am b/arts/knotify/Makefile.am
new file mode 100644
index 000000000..bf743ce45
--- /dev/null
+++ b/arts/knotify/Makefile.am
@@ -0,0 +1,27 @@
+
+INCLUDES= -I$(top_srcdir)/arts/kde -I$(includedir)/arts $(all_includes)
+
+####### Files
+
+kde_module_LTLIBRARIES = knotify.la
+
+knotify_la_SOURCES = knotify.cpp knotify.skel
+if include_ARTS
+knotify_la_LIBADD = -lsoundserver_idl -lqtmcop $(LIB_KDEUI) $(top_builddir)/arts/kde/libartskde.la
+endif
+knotify_la_LDFLAGS = $(all_libraries) -module -avoid-version
+knotify_la_METASOURCES = AUTO
+
+check_PROGRAMS = knotifytest
+knotifytest_SOURCES = knotifytest.cpp
+knotifytest_LDADD = $(LIB_KDECORE)
+knotifytest_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+noinst_HEADERS = knotify.h
+
+kdelnkdir = $(kde_servicesdir)
+kdelnk_DATA = knotify.desktop
+
+messages:
+ $(XGETTEXT) knotify.cpp -o $(podir)/knotify.pot
+
diff --git a/arts/knotify/README b/arts/knotify/README
new file mode 100644
index 000000000..3257cdc33
--- /dev/null
+++ b/arts/knotify/README
@@ -0,0 +1,33 @@
+About KNotify
+
+Historic overview. From KDE-1 to KDE-2:
+---------------------------------------
+KDE-1 ships with a notification system for window manager events - a sound
+could be played for example on startup or when a window closes. This was a
+very limited notification system.
+
+KNotify in contrast is a very flexible notification system. It can easily be
+accessed by any application, and notifications can have several
+presentations: Sound is still supported, but you can as well display a
+message box, write a text to a log file or log window.
+
+The notification presentation will be user configurable. Some people don't
+like message boxes popping up at unexpected times, so they prefer sounds
+instead. Deaf people on the otehr hand will not be happy about desktop
+sounds.
+
+
+
+Usage:
+------
+1. Compile
+2. Start knotify
+3. Test it with knotifyclient.
+
+Ideas:
+------
+It might be useful to modify message presentation from time to time. For
+example, while the screen is locked, it is very likely that the user is not
+present. Thus, he will not be able to hear a "You have mail" sound (or to
+see a talk request). Re-routing this to a log window sounds like a very good
+idea.
diff --git a/arts/knotify/knotify.cpp b/arts/knotify/knotify.cpp
new file mode 100644
index 000000000..794ef3dcd
--- /dev/null
+++ b/arts/knotify/knotify.cpp
@@ -0,0 +1,800 @@
+/*
+ Copyright (c) 1997 Christian Esken (esken@kde.org)
+ 2000 Charles Samuels (charles@kde.org)
+ 2000 Stefan Schimanski (1Stein@gmx.de)
+ 2000 Matthias Ettrich (ettrich@kde.org)
+ 2000 Waldo Bastian <bastian@kde.org>
+ 2000-2003 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+// C headers
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <config.h>
+#ifndef WITHOUT_ARTS
+// aRts headers
+#include <connect.h>
+#include <dispatcher.h>
+#include <flowsystem.h>
+#include <qiomanager.h>
+#include <soundserver.h>
+#endif
+
+// QT headers
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+#include <qtextstream.h>
+
+// KDE headers
+#include <dcopclient.h>
+#include <kaboutdata.h>
+#ifndef WITHOUT_ARTS
+#include <kartsdispatcher.h>
+#include <kartsserver.h>
+#endif
+#include <kcmdlineargs.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpassivepopup.h>
+#include <kiconloader.h>
+#include <kmacroexpander.h>
+#ifndef WITHOUT_ARTS
+#include <kplayobjectfactory.h>
+#include <kaudiomanagerplay.h>
+#endif
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <kuniqueapplication.h>
+#include <kwin.h>
+
+#include "knotify.h"
+#include "knotify.moc"
+
+class KNotifyPrivate
+{
+public:
+ KConfig* globalEvents;
+ KConfig* globalConfig;
+ QMap<QString, KConfig*> events;
+ QMap<QString, KConfig*> configs;
+ QString externalPlayer;
+ KProcess *externalPlayerProc;
+
+#ifndef WITHOUT_ARTS
+ QPtrList<KDE::PlayObject> playObjects;
+ QMap<KDE::PlayObject*,int> playObjectEventMap;
+ KAudioManagerPlay *audioManager;
+#endif
+ int externalPlayerEventId;
+
+ bool useExternal;
+ bool useArts;
+ int volume;
+ QTimer *playTimer;
+ bool inStartup;
+ QString startupEvents;
+};
+
+// Yes, it's ugly to put this here, but this facilitates the cautious startup
+// procedure.
+#ifndef WITHOUT_ARTS
+KArtsServer *soundServer = 0;
+#endif
+
+extern "C"{
+
+KDE_EXPORT int kdemain(int argc, char **argv)
+{
+ KAboutData aboutdata("knotify", I18N_NOOP("KNotify"),
+ "3.0", I18N_NOOP("KDE Notification Server"),
+ KAboutData::License_GPL, "(C) 1997-2003, KDE Developers");
+ aboutdata.addAuthor("Carsten Pfeiffer",I18N_NOOP("Current Maintainer"),"pfeiffer@kde.org");
+ aboutdata.addAuthor("Christian Esken",0,"esken@kde.org");
+ aboutdata.addAuthor("Stefan Westerfeld",I18N_NOOP("Sound support"),"stefan@space.twc.de");
+ aboutdata.addAuthor("Charles Samuels",I18N_NOOP("Previous Maintainer"),"charles@kde.org");
+
+ KCmdLineArgs::init( argc, argv, &aboutdata );
+ KUniqueApplication::addCmdLineOptions();
+
+
+ // initialize application
+ if ( !KUniqueApplication::start() ) {
+ kdDebug() << "Running knotify found" << endl;
+ return 0;
+ }
+
+ KUniqueApplication app;
+ app.disableSessionManagement();
+
+ // KNotify is started on KDE startup and on demand (using
+ // KNotifClient::startDaemon()) whenever a KNotify event occurs. Especially
+ // KWin may fire many events (e.g. when a window pops up). When we have
+ // problems with aRts or the installation, we might get an infinite loop
+ // of knotify crashing, popping up the crashhandler window and kwin firing
+ // another event, starting knotify again...
+ // We try to prevent this by tracking our startup and offer options to
+ // abort this.
+
+#ifndef WITHOUT_ARTS
+ KConfigGroup config( KGlobal::config(), "StartProgress" );
+ KConfig artsKCMConfig( "kcmartsrc" );
+ artsKCMConfig.setGroup( "Arts" );
+ bool useArts = artsKCMConfig.readBoolEntry( "StartServer", true );
+ if (useArts)
+ useArts = config.readBoolEntry( "Use Arts", useArts );
+ bool ok = config.readBoolEntry( "Arts Init", true );
+
+ if ( useArts && !ok )
+ {
+ if ( KMessageBox::questionYesNo(
+ 0L,
+ i18n("During the previous startup, KNotify crashed while creating "
+ "Arts::Dispatcher. Do you want to try again or disable "
+ "aRts sound output?\n\n"
+ "If you choose to disable aRts output now, you can re-enable "
+ "it later or select an alternate sound player "
+ "in the System Notifications control panel."),
+ i18n("KNotify Problem"),
+ i18n("&Try Again"),
+ i18n("D&isable aRts Output"),
+ "KNotifyStartProgress",
+ 0 /* don't call KNotify :) */
+ )
+ == KMessageBox::No )
+ {
+ useArts = false;
+ }
+ }
+
+ // when ArtsDispatcher crashes, we know it the next start.
+ config.writeEntry( "Arts Init", false );
+ config.writeEntry( "Use Arts", useArts );
+ config.sync();
+
+ KArtsDispatcher *dispatcher = 0;
+ if ( useArts )
+ {
+ dispatcher = new KArtsDispatcher;
+ soundServer = new KArtsServer;
+ }
+
+ // ok, seemed to work.
+ config.writeEntry("Arts Init", useArts );
+ config.sync();
+
+ ok = config.readBoolEntry( "KNotify Init", true );
+ if ( useArts && !ok )
+ {
+ if ( KMessageBox::questionYesNo(
+ 0L,
+ i18n("During the previous startup, KNotify crashed while instantiating "
+ "KNotify. Do you want to try again or disable "
+ "aRts sound output?\n\n"
+ "If you choose to disable aRts output now, you can re-enable "
+ "it later or select an alternate sound player "
+ "in the System Notifications control panel."),
+ i18n("KNotify Problem"),
+ i18n("&Try Again"),
+ i18n("D&isable aRts Output"),
+ "KNotifyStartProgress",
+ 0 /* don't call KNotify :) */
+ )
+ == KMessageBox::No )
+ {
+ useArts = false;
+ delete soundServer;
+ soundServer = 0L;
+ delete dispatcher;
+ dispatcher = 0L;
+ }
+ }
+
+ // when KNotify instantiation crashes, we know it the next start.
+ config.writeEntry( "KNotify Init", false );
+ config.writeEntry( "Use Arts", useArts );
+ config.sync();
+
+ // start notify service
+ KNotify *notify = new KNotify( useArts );
+
+ config.writeEntry( "KNotify Init", true );
+ config.sync();
+
+#else
+
+ // start notify service, without aRts
+ KNotify *notify = new KNotify( false );
+
+#endif
+
+ app.dcopClient()->setDefaultObject( "Notify" );
+ app.dcopClient()->setDaemonMode( true );
+ // kdDebug() << "knotify starting" << endl;
+
+ int ret = app.exec();
+ delete notify;
+#ifndef WITHOUT_ARTS
+ delete soundServer;
+ delete dispatcher;
+#endif
+ return ret;
+}
+}// end extern "C"
+
+KNotify::KNotify( bool useArts )
+ : QObject(), DCOPObject("Notify")
+{
+ d = new KNotifyPrivate;
+ d->globalEvents = new KConfig("knotify/eventsrc", true, false, "data");
+ d->globalConfig = new KConfig("knotify.eventsrc", true, false);
+ d->externalPlayerProc = 0;
+ d->useArts = useArts;
+ d->inStartup = true;
+#ifndef WITHOUT_ARTS
+ d->playObjects.setAutoDelete(true);
+ d->audioManager = 0;
+ if( useArts )
+ {
+ connect( soundServer, SIGNAL( restartedServer() ), this, SLOT( restartedArtsd() ) );
+ restartedArtsd(); //started allready need to initialize d->audioManager
+ }
+#endif
+
+ d->volume = 100;
+
+ d->playTimer = 0;
+
+ loadConfig();
+}
+
+KNotify::~KNotify()
+{
+ reconfigure();
+
+#ifndef WITHOUT_ARTS
+ d->playObjects.clear();
+
+ delete d->globalEvents;
+ delete d->globalConfig;
+ delete d->externalPlayerProc;
+ delete d->audioManager;
+#endif
+ delete d;
+}
+
+
+void KNotify::loadConfig() {
+ // load external player settings
+ KConfig *kc = KGlobal::config();
+ kc->setGroup("Misc");
+ d->useExternal = kc->readBoolEntry( "Use external player", false );
+ d->externalPlayer = kc->readPathEntry("External player");
+
+ // try to locate a suitable player if none is configured
+ if ( d->externalPlayer.isEmpty() ) {
+ QStringList players;
+ players << "wavplay" << "aplay" << "auplay";
+ QStringList::Iterator it = players.begin();
+ while ( d->externalPlayer.isEmpty() && it != players.end() ) {
+ d->externalPlayer = KStandardDirs::findExe( *it );
+ ++it;
+ }
+ }
+
+ // load default volume
+ d->volume = kc->readNumEntry( "Volume", 100 );
+}
+
+
+void KNotify::reconfigure()
+{
+ kapp->config()->reparseConfiguration();
+ loadConfig();
+
+ // clear loaded config files
+ d->globalConfig->reparseConfiguration();
+ for ( QMapIterator<QString,KConfig*> it = d->configs.begin(); it != d->configs.end(); ++it )
+ delete it.data();
+ d->configs.clear();
+}
+
+
+void KNotify::notify(const QString &event, const QString &fromApp,
+ const QString &text, QString sound, QString file,
+ int present, int level)
+{
+ notify( event, fromApp, text, sound, file, present, level, 0, 1 );
+}
+
+void KNotify::notify(const QString &event, const QString &fromApp,
+ const QString &text, QString sound, QString file,
+ int present, int level, int winId)
+{
+ notify( event, fromApp, text, sound, file, present, level, winId, 1 );
+}
+
+void KNotify::notify(const QString &event, const QString &fromApp,
+ const QString &text, QString sound, QString file,
+ int present, int level, int winId, int eventId )
+{
+ // kdDebug() << "event=" << event << " fromApp=" << fromApp << " text=" << text << " sound=" << sound <<
+ // " file=" << file << " present=" << present << " level=" << level << " winId=" << winId << " eventId=" << eventId << endl;
+ if( d->inStartup ) {
+ d->startupEvents += "(" + event + ":" + fromApp + ")";
+ }
+
+ QString commandline;
+ KConfig *eventsFile = NULL;
+ KConfig *configFile = NULL;
+
+ // check for valid events
+ if ( !event.isEmpty() ) {
+
+ // get config file
+ if ( d->events.contains( fromApp ) ) {
+ eventsFile = d->events[fromApp];
+ } else {
+ eventsFile=new KConfig(locate("data", fromApp+"/eventsrc"),true,false);
+ d->events.insert( fromApp, eventsFile );
+ }
+ if ( d->configs.contains( fromApp) ) {
+ configFile = d->configs[fromApp];
+ } else {
+ configFile=new KConfig(fromApp+".eventsrc",true,false);
+ d->configs.insert( fromApp, configFile );
+ }
+
+ if ( !eventsFile->hasGroup( event ) && isGlobal(event) )
+ {
+ eventsFile = d->globalEvents;
+ configFile = d->globalConfig;
+ }
+
+ eventsFile->setGroup( event );
+ configFile->setGroup( event );
+
+ // get event presentation
+ if ( present==-1 )
+ present = configFile->readNumEntry( "presentation", -1 );
+ if ( present==-1 )
+ present = eventsFile->readNumEntry( "default_presentation", 0 );
+
+ // get sound file name
+ if( present & KNotifyClient::Sound ) {
+ QString theSound = configFile->readPathEntry( "soundfile" );
+ if ( theSound.isEmpty() )
+ theSound = eventsFile->readPathEntry( "default_sound" );
+ if ( !theSound.isEmpty() )
+ sound = theSound;
+ }
+
+ // get log file name
+ if( present & KNotifyClient::Logfile ) {
+ QString theFile = configFile->readPathEntry( "logfile" );
+ if ( theFile.isEmpty() )
+ theFile = eventsFile->readPathEntry( "default_logfile" );
+ if ( !theFile.isEmpty() )
+ file = theFile;
+ }
+
+ // get default event level
+ if( present & KNotifyClient::Messagebox )
+ level = eventsFile->readNumEntry( "level", 0 );
+
+ // get command line
+ if (present & KNotifyClient::Execute ) {
+ commandline = configFile->readPathEntry( "commandline" );
+ if ( commandline.isEmpty() )
+ commandline = eventsFile->readPathEntry( "default_commandline" );
+ }
+ }
+
+ // emit event
+ if ( present & KNotifyClient::Sound ) // && QFile(sound).isReadable()
+ notifyBySound( sound, fromApp, eventId );
+
+ if ( present & KNotifyClient::Execute )
+ notifyByExecute( commandline, event, fromApp, text, winId, eventId );
+
+ if ( present & KNotifyClient::Logfile ) // && QFile(file).isWritable()
+ notifyByLogfile( text, file );
+
+ if ( present & KNotifyClient::Stderr )
+ notifyByStderr( text );
+
+ if ( present & KNotifyClient::Taskbar )
+ notifyByTaskbar( checkWinId( fromApp, winId ));
+
+ if ( present & KNotifyClient::PassivePopup )
+ notifyByPassivePopup( text, fromApp, eventsFile, checkWinId( fromApp, winId ));
+ else if ( present & KNotifyClient::Messagebox )
+ notifyByMessagebox( text, level, checkWinId( fromApp, winId ));
+
+ QByteArray qbd;
+ QDataStream ds(qbd, IO_WriteOnly);
+ ds << event << fromApp << text << sound << file << present << level
+ << winId << eventId;
+ emitDCOPSignal("notifySignal(QString,QString,QString,QString,QString,int,int,int,int)", qbd);
+
+}
+
+
+bool KNotify::notifyBySound( const QString &sound, const QString &appname, int eventId )
+{
+ if (sound.isEmpty()) {
+ soundFinished( eventId, NoSoundFile );
+ return false;
+ }
+
+ bool external = d->useExternal && !d->externalPlayer.isEmpty();
+ // get file name
+ QString soundFile(sound);
+ if ( QFileInfo(sound).isRelative() )
+ {
+ QString search = QString("%1/sounds/%2").arg(appname).arg(sound);
+ soundFile = KGlobal::instance()->dirs()->findResource("data", search);
+ if ( soundFile.isEmpty() )
+ soundFile = locate( "sound", sound );
+ }
+ if ( soundFile.isEmpty() || isPlaying( soundFile ) )
+ {
+ soundFinished( eventId, soundFile.isEmpty() ? NoSoundFile : FileAlreadyPlaying );
+ return false;
+ }
+
+
+ // kdDebug() << "KNotify::notifyBySound - trying to play file " << soundFile << endl;
+
+ if (!external) {
+ //If we disabled using aRts, just return,
+ //(If we don't, we'll blow up accessing the null soundServer)
+ if (!d->useArts)
+ {
+ soundFinished( eventId, NoSoundSupport );
+ return false;
+ }
+
+#ifndef WITHOUT_ARTS
+ // play sound finally
+ while( d->playObjects.count()>5 )
+ abortFirstPlayObject();
+
+ KDE::PlayObjectFactory factory(soundServer->server());
+ if( d->audioManager )
+ factory.setAudioManagerPlay( d->audioManager );
+ KURL soundURL;
+ soundURL.setPath(soundFile);
+ KDE::PlayObject *playObject = factory.createPlayObject(soundURL, false);
+
+ if (playObject->isNull())
+ {
+ soundFinished( eventId, NoSoundSupport );
+ delete playObject;
+ return false;
+ }
+
+ if ( d->volume != 100 )
+ {
+ // It works to access the playObject immediately because we don't allow
+ // non-file URLs for sounds.
+ Arts::StereoVolumeControl volumeControl = Arts::DynamicCast(soundServer->server().createObject("Arts::StereoVolumeControl"));
+ Arts::PlayObject player = playObject->object();
+ Arts::Synth_AMAN_PLAY ap = d->audioManager->amanPlay();
+ if( ! volumeControl.isNull() && ! player.isNull() && ! ap.isNull() )
+ {
+ volumeControl.scaleFactor( d->volume/100.0 );
+
+ ap.stop();
+ Arts::disconnect( player, "left", ap, "left" );
+ Arts::disconnect( player, "right", ap, "right" );
+
+ ap.start();
+ volumeControl.start();
+
+ Arts::connect(player,"left",volumeControl,"inleft");
+ Arts::connect(player,"right",volumeControl,"inright");
+
+ Arts::connect(volumeControl,"outleft",ap,"left");
+ Arts::connect(volumeControl,"outright",ap,"right");
+
+ player._addChild( volumeControl, "volume" );
+ }
+ }
+
+ playObject->play();
+ d->playObjects.append( playObject );
+ d->playObjectEventMap.insert( playObject, eventId );
+
+ if ( !d->playTimer )
+ {
+ d->playTimer = new QTimer( this );
+ connect( d->playTimer, SIGNAL( timeout() ), SLOT( playTimeout() ) );
+ }
+ if ( !d->playTimer->isActive() )
+ d->playTimer->start( 1000 );
+#endif
+ return true;
+
+ } else if(!d->externalPlayer.isEmpty()) {
+ // use an external player to play the sound
+ KProcess *proc = d->externalPlayerProc;
+ if (!proc)
+ {
+ proc = d->externalPlayerProc = new KProcess;
+ connect( proc, SIGNAL( processExited( KProcess * )),
+ SLOT( slotPlayerProcessExited( KProcess * )));
+ }
+ if (proc->isRunning())
+ {
+ soundFinished( eventId, PlayerBusy );
+ return false; // Skip
+ }
+ proc->clearArguments();
+ (*proc) << d->externalPlayer << QFile::encodeName( soundFile );
+ d->externalPlayerEventId = eventId;
+ proc->start(KProcess::NotifyOnExit);
+ return true;
+ }
+
+ soundFinished( eventId, Unknown );
+ return false;
+}
+
+bool KNotify::notifyByMessagebox(const QString &text, int level, WId winId)
+{
+ // ignore empty messages
+ if ( text.isEmpty() )
+ return false;
+
+ // display message box for specified event level
+ switch( level ) {
+ default:
+ case KNotifyClient::Notification:
+ KMessageBox::informationWId( winId, text, i18n("Notification"), 0, false );
+ break;
+ case KNotifyClient::Warning:
+ KMessageBox::sorryWId( winId, text, i18n("Warning"), false );
+ break;
+ case KNotifyClient::Error:
+ KMessageBox::errorWId( winId, text, i18n("Error"), false );
+ break;
+ case KNotifyClient::Catastrophe:
+ KMessageBox::errorWId( winId, text, i18n("Catastrophe!"), false );
+ break;
+ }
+
+ return true;
+}
+
+bool KNotify::notifyByPassivePopup( const QString &text,
+ const QString &appName,
+ KConfig* eventsFile,
+ WId senderWinId )
+{
+ KIconLoader iconLoader( appName );
+ if ( eventsFile != NULL ) {
+ KConfigGroup config( eventsFile, "!Global!" );
+ QString iconName = config.readEntry( "IconName", appName );
+ QPixmap icon = iconLoader.loadIcon( iconName, KIcon::Small );
+ QString title = config.readEntry( "Comment", appName );
+ KPassivePopup::message(title, text, icon, senderWinId);
+ } else
+ kdError() << "No events for app " << appName << "defined!" <<endl;
+
+ return true;
+}
+
+bool KNotify::notifyByExecute(const QString &command, const QString& event,
+ const QString& fromApp, const QString& text,
+ int winId, int eventId) {
+ if (!command.isEmpty()) {
+ // kdDebug() << "executing command '" << command << "'" << endl;
+ QMap<QChar,QString> subst;
+ subst.insert( 'e', event );
+ subst.insert( 'a', fromApp );
+ subst.insert( 's', text );
+ subst.insert( 'w', QString::number( winId ));
+ subst.insert( 'i', QString::number( eventId ));
+ QString execLine = KMacroExpander::expandMacrosShellQuote( command, subst );
+ if ( execLine.isEmpty() )
+ execLine = command; // fallback
+
+ KProcess p;
+ p.setUseShell(true);
+ p << execLine;
+ p.start(KProcess::DontCare);
+ return true;
+ }
+ return false;
+}
+
+
+bool KNotify::notifyByLogfile(const QString &text, const QString &file)
+{
+ // ignore empty messages
+ if ( text.isEmpty() )
+ return true;
+
+ // open file in append mode
+ QFile logFile(file);
+ if ( !logFile.open(IO_WriteOnly | IO_Append) )
+ return false;
+
+ // append msg
+ QTextStream strm( &logFile );
+ strm << "- KNotify " << QDateTime::currentDateTime().toString() << ": ";
+ strm << text << endl;
+
+ // close file
+ logFile.close();
+ return true;
+}
+
+bool KNotify::notifyByStderr(const QString &text)
+{
+ // ignore empty messages
+ if ( text.isEmpty() )
+ return true;
+
+ // open stderr for output
+ QTextStream strm( stderr, IO_WriteOnly );
+
+ // output msg
+ strm << "KNotify " << QDateTime::currentDateTime().toString() << ": ";
+ strm << text << endl;
+
+ return true;
+}
+
+bool KNotify::notifyByTaskbar( WId win )
+{
+ if( win == 0 )
+ return false;
+ KWin::demandAttention( win );
+ return true;
+}
+
+bool KNotify::isGlobal(const QString &eventname)
+{
+ return d->globalEvents->hasGroup( eventname );
+}
+
+void KNotify::setVolume( int volume )
+{
+ if ( volume<0 ) volume=0;
+ if ( volume>=100 ) volume=100;
+ d->volume = volume;
+}
+
+void KNotify::playTimeout()
+{
+#ifndef WITHOUT_ARTS
+ for ( QPtrListIterator< KDE::PlayObject > it(d->playObjects); *it;)
+ {
+ QPtrListIterator< KDE::PlayObject > current = it;
+ ++it;
+ if ( (*current)->state() != Arts::posPlaying )
+ {
+ QMap<KDE::PlayObject*,int>::Iterator eit = d->playObjectEventMap.find( *current );
+ if ( eit != d->playObjectEventMap.end() )
+ {
+ soundFinished( *eit, PlayedOK );
+ d->playObjectEventMap.remove( eit );
+ }
+ d->playObjects.remove( current );
+ }
+ }
+ if ( !d->playObjects.count() )
+ d->playTimer->stop();
+#endif
+}
+
+bool KNotify::isPlaying( const QString& soundFile ) const
+{
+#ifndef WITHOUT_ARTS
+ for ( QPtrListIterator< KDE::PlayObject > it(d->playObjects); *it; ++it)
+ {
+ if ( (*it)->mediaName() == soundFile )
+ return true;
+ }
+#endif
+ return false;
+}
+
+void KNotify::slotPlayerProcessExited( KProcess *proc )
+{
+ soundFinished( d->externalPlayerEventId,
+ (proc->normalExit() && proc->exitStatus() == 0) ? PlayedOK : Unknown );
+}
+
+void KNotify::abortFirstPlayObject()
+{
+#ifndef WITHOUT_ARTS
+ QMap<KDE::PlayObject*,int>::Iterator it = d->playObjectEventMap.find( d->playObjects.getFirst() );
+ if ( it != d->playObjectEventMap.end() )
+ {
+ soundFinished( it.data(), Aborted );
+ d->playObjectEventMap.remove( it );
+ }
+ d->playObjects.removeFirst();
+#endif
+}
+
+void KNotify::soundFinished( int eventId, PlayingFinishedStatus reason )
+{
+ QByteArray data;
+ QDataStream stream( data, IO_WriteOnly );
+ stream << eventId << (int) reason;
+
+ DCOPClient::mainClient()->emitDCOPSignal( "KNotify", "playingFinished(int,int)", data );
+}
+
+WId KNotify::checkWinId( const QString &appName, WId senderWinId )
+{
+ if ( senderWinId == 0 )
+ {
+ QCString senderId = kapp->dcopClient()->senderId();
+ QCString compare = (appName + "-mainwindow").latin1();
+ int len = compare.length();
+ // kdDebug() << "notifyByPassivePopup: appName=" << appName << " sender=" << senderId << endl;
+
+ QCStringList objs = kapp->dcopClient()->remoteObjects( senderId );
+ for (QCStringList::ConstIterator it = objs.begin(); it != objs.end(); ++it ) {
+ QCString obj( *it );
+ if ( obj.left(len) == compare) {
+ // kdDebug( ) << "found " << obj << endl;
+ QCString replyType;
+ QByteArray data, replyData;
+
+ if ( kapp->dcopClient()->call(senderId, obj, "getWinID()", data, replyType, replyData) ) {
+ QDataStream answer(replyData, IO_ReadOnly);
+ if (replyType == "int") {
+ answer >> senderWinId;
+ // kdDebug() << "SUCCESS, found getWinID(): type='" << QString(replyType)
+ // << "' senderWinId=" << senderWinId << endl;
+ }
+ }
+ }
+ }
+ }
+ return senderWinId;
+}
+
+void KNotify::restartedArtsd()
+{
+#ifndef WITHOUT_ARTS
+ delete d->audioManager;
+ d->audioManager = new KAudioManagerPlay( soundServer );
+ d->audioManager->setTitle( i18n( "KDE System Notifications" ) );
+ d->audioManager->setAutoRestoreID( "KNotify Aman Play" );
+#endif
+}
+
+void KNotify::sessionReady()
+{
+ if( d->inStartup && !d->startupEvents.isEmpty())
+ kdDebug() << "There were knotify events while startup:" << d->startupEvents << endl;
+ d->inStartup = false;
+}
+
+// vim: sw=4 sts=4 ts=8 et
diff --git a/arts/knotify/knotify.desktop b/arts/knotify/knotify.desktop
new file mode 100644
index 000000000..da950fa8a
--- /dev/null
+++ b/arts/knotify/knotify.desktop
@@ -0,0 +1,119 @@
+[Desktop Entry]
+Type=Service
+Name=KNotify
+Name[af]=Knotify
+Name[ar]=برنامج الإبلاغ
+Name[bn]=কে-নোটিফাই
+Name[csb]=Òdkôzanié
+Name[cy]=KHysbyu
+Name[eo]=Katentigilo
+Name[fo]=KÁminning
+Name[hi]=के-नोटिफाई
+Name[ka]=სისტემური შეტყობინება
+Name[ko]=K알림이
+Name[mn]=Сонордуулга
+Name[ne]=केनोटिफाइ
+Name[nso]=KLemosa
+Name[pa]=ਕੇਟਿੱਪਣੀ
+Name[pl]=Powiadamianie
+Name[pt_BR]=Notificações
+Name[ru]=Системные сообщения
+Name[ss]=KNotify
+Name[sv]=Knotify
+Name[ta]=கேகுறிப்பெடு
+Name[te]=కెనోటిఫై
+Name[tg]=Хабарҳои системавӣ
+Name[th]=ระบบแจ้งเตือน - K
+Name[ven]=U divhadza ha K
+Name[zu]=I-KNotify
+Exec=knotify
+Comment=KDE Notification Daemon
+Comment[af]=Kde Inkennisstelling Bediener
+Comment[ar]=مراقب تنبيهات كيدي
+Comment[az]=KDE Bildiriş Demonu
+Comment[be]=Сервіс нагадванняў KDE
+Comment[bg]=Сървър за съобщения
+Comment[bn]=কে.ডি.ই নোটিশ সরবরাহকারী ডিমন
+Comment[br]=Diaoul Kemennadenn KDE
+Comment[bs]=KDE Sistemska obavještenja
+Comment[ca]=Dimoni de notificacions per al KDE
+Comment[cs]=Démon pro systémová hlášení prostředí KDE
+Comment[csb]=Demon òdkôzëwaniô KDE
+Comment[cy]=Daemon Hysbysu KDE
+Comment[da]=KDE Bekendtgørelsesdæmon
+Comment[de]=KDE-Benachrichtigungsprogramm
+Comment[el]=Δαίμονας ειδοποίησης του KDE
+Comment[eo]=KDE-Sistematentigo-demono
+Comment[es]=Demonio de notificación de KDE
+Comment[et]=KDE süsteemsete märguannete deemon
+Comment[eu]=KDEko jakinarazpenaren daemona
+Comment[fa]=شبح اخطار KDE
+Comment[fi]=KDE:n huomautuspalvelin
+Comment[fo]=Áminningarandi KDE's
+Comment[fr]=Démon de notifications de KDE
+Comment[fy]=KDE's systeemberjochtenprogramma
+Comment[ga]=Deamhan Fógartha KDE
+Comment[gl]=Demo de notificacións de KDE
+Comment[he]=תהליך הרקע הודעות של KDE
+Comment[hi]=केडीई सूचना ङेमन
+Comment[hr]=KDE demon obavještavanja
+Comment[hsb]=KDE-demon za zdźělenki
+Comment[hu]=KDE figyelmeztető szolgáltatás
+Comment[id]=Daemon pemberitahuan KDE
+Comment[is]=KDE tilkynningapúkinn
+Comment[it]=Demone avvisi di KDE
+Comment[ja]=KDE 通知デーモン
+Comment[ka]=KDE შეტყობინებების შიკრიკი
+Comment[kk]=KDE құлақтандыру қызметі
+Comment[ko]=KDE용 알림 서버
+Comment[lb]=KDE-Norichtendämon
+Comment[lt]=KDE pranešimų tarnyba
+Comment[lv]=KDE Apziņošanas Dēmons
+Comment[mi]=Kaikorero KDE
+Comment[mk]=KDE даемон за известувања
+Comment[mn]=KDE-Сонордуулга программ
+Comment[ms]=Daemon Pemberitahuan KDE
+Comment[mt]=Daemon tan-notifika KDE
+Comment[nb]=KDE Varslings-nisse
+Comment[nds]=KDE-Dämoon för Bescheden
+Comment[ne]=KDE सूचना डेइमन
+Comment[nl]=KDE's systeemnotificatieprogramma
+Comment[nn]=KDE-varselnisse
+Comment[nso]=Daemon ya Tsebiso ya KDE
+Comment[oc]=Dimoni de notificacion KDE
+Comment[pa]=KDE ਟਿੱਪਣੀ ਪੇਸ਼ਕਾਰ
+Comment[pl]=Demon powiadamiania KDE
+Comment[pt]=Servidor de mensagens do KDE
+Comment[pt_BR]=Serviço de notificação do KDE
+Comment[ro]=Demon de notificare KDE
+Comment[ru]=Системные сообщения KDE
+Comment[rw]=Dayimoni y'Imenyesha KDE
+Comment[se]=KDE dieđihanbálvá
+Comment[sk]=KDE Oznamovací démon
+Comment[sl]=Sistemska obvestila KDE
+Comment[sq]=KDE Demoni i Njoftimit
+Comment[sr]=KDE Демон за обавештавање
+Comment[sr@Latn]=KDE Demon za obaveštavanje
+Comment[ss]=I-daemon yekwatisa ku KDE
+Comment[sv]=KDE:s underrättelsedemon
+Comment[ta]=கேடிஇ அறிவிப்பு டேமன்
+Comment[te]=కెడిఈ ప్రకటనల సూత్రధారి
+Comment[tg]=Хабарҳои системавии KDE
+Comment[th]=เดมอนการแจ้งเตือนของ KDE
+Comment[tr]=KDE Bilgilendirme Programı
+Comment[tt]=KDE'nıñ Kisätü Xezmäte
+Comment[uk]=Демон сповіщення про нову пошту
+Comment[uz]=KDE xabarnomalar xizmati
+Comment[uz@cyrillic]=KDE хабарномалар хизмати
+Comment[ven]=Daemon yau divhadza ya KDE
+Comment[vi]=Trình nền thông báo của KDE
+Comment[wa]=Démon di notifiaedje di KDE
+Comment[xh]=Daemon Ulwaziso lwe KDE
+Comment[zh_CN]=KDE 通告守护进程
+Comment[zh_HK]=KDE 通知伺服程式
+Comment[zh_TW]=KDE 通知服務程式
+Comment[zu]=Isaziso se-Daemon ye-KDE
+Icon=knotify
+ServiceTypes=KNotify
+X-DCOP-ServiceType=Unique
+X-KDE-StartupNotify=false
diff --git a/arts/knotify/knotify.h b/arts/knotify/knotify.h
new file mode 100644
index 000000000..c98be2e97
--- /dev/null
+++ b/arts/knotify/knotify.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (c) 1997 Christian Esken (esken@kde.org)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KNOTIFY_H
+#define KNOTIFY_H
+
+#include <qobject.h>
+#include <knotifyclient.h>
+#include <dcopobject.h>
+
+class KNotifyPrivate;
+class KProcess;
+class KConfig;
+
+class KNotify : public QObject, public DCOPObject
+{
+Q_OBJECT
+K_DCOP
+
+public:
+ KNotify( bool useArts );
+ ~KNotify();
+
+ enum PlayingFinishedStatus
+ {
+ PlayedOK = 0, // success, all following mean failure
+ NoSoundFile,
+ FileAlreadyPlaying,
+ NoSoundSupport,
+ PlayerBusy,
+ Aborted,
+ Unknown = 5000
+ };
+
+protected:
+k_dcop:
+ // deprecated
+ void notify(const QString &event, const QString &fromApp,
+ const QString &text, QString sound, QString file,
+ int present, int level);
+
+ // deprecated
+ void notify(const QString &event, const QString &fromApp,
+ const QString &text, QString sound, QString file,
+ int present, int level, int winId);
+
+ void notify(const QString &event, const QString &fromApp,
+ const QString &text, QString sound, QString file,
+ int present, int level, int winId, int eventId);
+
+
+ void reconfigure();
+ void setVolume( int volume );
+ void sessionReady(); // from ksmserver
+
+private:
+ bool notifyBySound(const QString &sound, const QString &appname, int eventId);
+ bool notifyByMessagebox(const QString &text, int level, WId winId);
+ bool notifyByLogfile(const QString &text, const QString &file);
+ bool notifyByStderr(const QString &text);
+ bool notifyByPassivePopup(const QString &text, const QString &appName,
+ KConfig* eventsFile, WId winId );
+ bool notifyByExecute(const QString &command,
+ const QString& event,
+ const QString& fromApp,
+ const QString& text,
+ int winId,
+ int eventId );
+ bool notifyByTaskbar( WId winId );
+
+ bool isPlaying( const QString& soundFile ) const;
+
+ void soundFinished( int eventId, PlayingFinishedStatus reason );
+ void abortFirstPlayObject();
+
+ WId checkWinId( const QString& appName, WId senderWinId );
+
+ /**
+ * checks if eventname is a global event (exists in config/eventsrc)
+ **/
+ bool isGlobal(const QString &eventname);
+
+private slots:
+ void playTimeout();
+ void slotPlayerProcessExited( KProcess *proc );
+ void restartedArtsd();
+
+private:
+ KNotifyPrivate* d;
+ void loadConfig();
+};
+
+
+#endif
+
diff --git a/arts/knotify/knotifytest.cpp b/arts/knotify/knotifytest.cpp
new file mode 100644
index 000000000..9ca10cb9d
--- /dev/null
+++ b/arts/knotify/knotifytest.cpp
@@ -0,0 +1,19 @@
+#include <string>
+#include <stdio.h>
+#include <kapplication.h>
+#include <knotifyclient.h>
+
+int main(int argc, char **argv)
+{
+ KApplication app(argc, argv, "knotifytest");
+
+//
+ while (1) {
+ char inp = getc(stdin);
+
+ if ( inp=='q' || inp==27 ) break;
+ if ( inp=='1' ) KNotifyClient::userEvent( "Foo", KNotifyClient::Sound, KNotifyClient::Default, "KDE_Window_DeIconify.ogg" );
+ if ( inp=='2' ) KNotifyClient::userEvent( "MessageBox Event", KNotifyClient::Messagebox );
+ if ( inp=='3' ) KNotifyClient::userEvent( "Stderr Event", KNotifyClient::Stderr );
+ }
+}
diff --git a/arts/message/Makefile.am b/arts/message/Makefile.am
new file mode 100644
index 000000000..be67e4bd8
--- /dev/null
+++ b/arts/message/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = $(all_includes)
+
+bin_PROGRAMS = artsmessage
+
+artsmessage_SOURCES = artsmessage.cc
+
+artsmessage_LDADD = ../../kdeui/libkdeui.la
+artsmessage_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(KDE_MT_LDFLAGS)
diff --git a/arts/message/artsmessage.cc b/arts/message/artsmessage.cc
new file mode 100644
index 000000000..7a127d4a4
--- /dev/null
+++ b/arts/message/artsmessage.cc
@@ -0,0 +1,93 @@
+/*
+ Copyright (C) 2001 Jeff Tranter
+ tranter@kde.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+------------------------------------------------------------------------
+
+This application displays an error, warning, or informational message
+in a dialog. It is normally used by artsd in conjunction with the -m
+option. By abstracting this out of artsd, we keep it independent of
+any particular graphics toolkit.
+
+This version uses KDE. Equivalent versions could be written using Qt,
+Gnome, etc. and used instead.
+
+*/
+
+#include <qregexp.h>
+
+#include <klocale.h>
+#include <kglobal.h>
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kmessagebox.h>
+#include <kcmdlineargs.h>
+
+// command line options
+static KCmdLineOptions options[] =
+ {
+ { "e", 0,0 },
+ { "error", I18N_NOOP("Display error message (default)"), 0 },
+ { "w", 0, 0},
+ { "warning", I18N_NOOP("Display warning message"), 0 },
+ { "i", 0, 0 },
+ { "info", I18N_NOOP("Display informational message"), 0 },
+ { "+message", I18N_NOOP("Message string to be displayed"), 0 },
+ KCmdLineLastOption // End of options.
+ };
+
+KAboutData aboutData("artsmessage", I18N_NOOP("artsmessage"), "0.1",
+ I18N_NOOP("Utility to display aRts error messages"),
+ KAboutData::License_GPL, "(c) 2001, Jeff Tranter", 0, 0, "tranter@kde.org");
+
+int main(int argc, char **argv) {
+ aboutData.addAuthor("Jeff Tranter", 0, "tranter@kde.org");
+ KGlobal::locale()->setMainCatalogue("kdelibs");
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KApplication app;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ QString msg;
+
+ // must be at least one argument
+ if (args->count() == 0) {
+ args->usage();
+ }
+
+ // build up message string from remaining arguments
+ for (int i = 0; i < args->count(); i++) {
+ if (i == 0)
+ msg = args->arg(i);
+ else
+ msg += QString(" ") + args->arg(i);
+ }
+
+ const int notifyOptions = 0; // never activate KNotify
+ if (args->isSet("w")) {
+ KMessageBox::sorry(0, msg, i18n("Warning"), notifyOptions);
+ } else if (args->isSet("i")) {
+ QString id = msg;
+ id.replace(QRegExp("[\\[\\]\\s=]"), "_");
+ KMessageBox::information(0, msg, i18n("Informational"), id, notifyOptions);
+ } else {
+ KMessageBox::error(0, msg, i18n("Error"), notifyOptions);
+ }
+
+ return 0;
+}