summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fmrx-qt.pro39
-rw-r--r--fmrxcontrol.cpp159
-rw-r--r--fmrxcontrol.h61
-rw-r--r--fmrxproxy.cpp148
-rw-r--r--fmrxproxy.h35
-rw-r--r--fmrxproxyadaptor.cpp118
-rw-r--r--fmrxservice.cpp154
-rw-r--r--fmrxservice.h58
-rw-r--r--fmrxserviceplugin.cpp24
-rw-r--r--fmrxserviceplugin.h15
-rw-r--r--qtc_packaging/debian_harmattan/README7
-rw-r--r--qtc_packaging/debian_harmattan/changelog5
-rw-r--r--qtc_packaging/debian_harmattan/compat1
-rw-r--r--qtc_packaging/debian_harmattan/control18
-rw-r--r--qtc_packaging/debian_harmattan/copyright22
-rw-r--r--qtc_packaging/debian_harmattan/manifest.aegis0
-rwxr-xr-xqtc_packaging/debian_harmattan/rules91
17 files changed, 955 insertions, 0 deletions
diff --git a/fmrx-qt.pro b/fmrx-qt.pro
new file mode 100644
index 0000000..e22f6bb
--- /dev/null
+++ b/fmrx-qt.pro
@@ -0,0 +1,39 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2011-12-30T19:56:22
+#
+#-------------------------------------------------
+
+QT += core
+
+TARGET = fmrx-qt
+TEMPLATE = lib
+CONFIG += plugin mobility link_pkgconfig
+MOBILITY += multimedia
+PKGCONFIG += dbus-glib-1
+
+contains(MEEGO_EDITION,harmattan) {
+ target.path = /usr/lib/qt4/plugins/mediaservice
+} else {
+ target.path = $$[QT_INSTALL_PLUGINS]/mediaservice
+}
+INSTALLS += target
+
+SOURCES += fmrxserviceplugin.cpp \
+ fmrxservice.cpp \
+ fmrxcontrol.cpp \
+ fmrxproxy.cpp
+
+HEADERS += fmrxserviceplugin.h \
+ fmrxservice.h \
+ fmrxcontrol.h \
+ fmrxproxy.h
+
+OTHER_FILES += \
+ qtc_packaging/debian_harmattan/rules \
+ qtc_packaging/debian_harmattan/README \
+ qtc_packaging/debian_harmattan/manifest.aegis \
+ qtc_packaging/debian_harmattan/copyright \
+ qtc_packaging/debian_harmattan/control \
+ qtc_packaging/debian_harmattan/compat \
+ qtc_packaging/debian_harmattan/changelog
diff --git a/fmrxcontrol.cpp b/fmrxcontrol.cpp
new file mode 100644
index 0000000..8116021
--- /dev/null
+++ b/fmrxcontrol.cpp
@@ -0,0 +1,159 @@
+#include "fmrxcontrol.h"
+#include "fmrxservice.h"
+
+FmRxControl::FmRxControl(FmRxService *parent) :
+ QRadioTunerControl(parent), m_service(parent)
+{
+ connect(m_service, SIGNAL(started()), this, SLOT(handleStarted()));
+ connect(m_service, SIGNAL(stopped()), this, SLOT(handleStopped()));
+ connect(m_service, SIGNAL(tuned(double)), this, SLOT(handleTuned(double)));
+}
+
+bool FmRxControl::isAvailable() const
+{
+ return m_service->isAvailable();
+}
+
+QtMultimediaKit::AvailabilityError FmRxControl::availabilityError() const
+{
+ return m_service->availabilityError();
+}
+
+QRadioTuner::State FmRxControl::state() const
+{
+ return m_service->isActive() ?
+ QRadioTuner::ActiveState : QRadioTuner::StoppedState;
+}
+
+QRadioTuner::Band FmRxControl::band() const
+{
+ return QRadioTuner::FM;
+}
+
+void FmRxControl::setBand(QRadioTuner::Band b)
+{
+ // Only one band!
+ Q_UNUSED(b);
+}
+
+bool FmRxControl::isBandSupported(QRadioTuner::Band b) const
+{
+ return b == QRadioTuner::FM;
+}
+
+int FmRxControl::frequency() const
+{
+ return m_service->frequency() * 1000000.0;
+}
+
+int FmRxControl::frequencyStep(QRadioTuner::Band b) const
+{
+ return 100 * 1000;
+}
+
+QPair<int, int> FmRxControl::frequencyRange(QRadioTuner::Band b) const
+{
+ if (b == QRadioTuner::FM)
+ return qMakePair<int,int>(87500000, 108000000);
+
+ return qMakePair<int,int>(0, 0);
+}
+
+void FmRxControl::setFrequency(int frequency)
+{
+ m_service->setFrequency(frequency / 1000000.0);
+}
+
+bool FmRxControl::isStereo() const
+{
+ return true; // TODO
+}
+
+QRadioTuner::StereoMode FmRxControl::stereoMode() const
+{
+ return QRadioTuner::Auto;
+}
+
+void FmRxControl::setStereoMode(QRadioTuner::StereoMode mode)
+{
+ // TODO
+}
+
+int FmRxControl::signalStrength() const
+{
+ return 0; // TODO
+}
+
+int FmRxControl::volume() const
+{
+ return 100; // Best not to have volume control in Harmattan.
+}
+void FmRxControl::setVolume(int volume)
+{
+ // Best not to have volume control in Harmattan.
+}
+
+bool FmRxControl::isMuted() const
+{
+ return false;
+}
+
+void FmRxControl::setMuted(bool muted)
+{
+ // Best not to have volume control in Harmattan.
+}
+
+bool FmRxControl::isSearching() const
+{
+ return false;
+}
+
+void FmRxControl::cancelSearch()
+{
+ // TODO
+}
+
+void FmRxControl::searchForward()
+{
+ m_service->searchForward();
+}
+
+void FmRxControl::searchBackward()
+{
+ m_service->searchBackward();
+}
+
+void FmRxControl::start()
+{
+ m_service->start();
+}
+
+void FmRxControl::stop()
+{
+ m_service->stop();
+}
+
+QRadioTuner::Error FmRxControl::error() const
+{
+ return QRadioTuner::NoError;
+}
+
+QString FmRxControl::errorString() const
+{
+ return QString();
+}
+
+void FmRxControl::handleStarted()
+{
+ emit stateChanged(QRadioTuner::ActiveState);
+}
+
+void FmRxControl::handleStopped()
+{
+ emit stateChanged(QRadioTuner::StoppedState);
+}
+
+void FmRxControl::handleTuned(double frequency)
+{
+ emit frequencyChanged(frequency * 1000000.0);
+}
diff --git a/fmrxcontrol.h b/fmrxcontrol.h
new file mode 100644
index 0000000..20247da
--- /dev/null
+++ b/fmrxcontrol.h
@@ -0,0 +1,61 @@
+#ifndef FMRXCONTROL_H
+#define FMRXCONTROL_H
+
+#include <QRadioTunerControl>
+
+class FmRxService;
+
+class FmRxControl : public QRadioTunerControl
+{
+ Q_OBJECT
+private:
+ FmRxService *m_service;
+
+public:
+ explicit FmRxControl(FmRxService *parent = 0);
+
+ bool isAvailable() const;
+ QtMultimediaKit::AvailabilityError availabilityError() const;
+
+ QRadioTuner::State state() const;
+
+ QRadioTuner::Band band() const;
+ void setBand(QRadioTuner::Band b);
+ bool isBandSupported(QRadioTuner::Band b) const;
+
+ int frequency() const;
+ int frequencyStep(QRadioTuner::Band b) const;
+ QPair<int, int> frequencyRange(QRadioTuner::Band b) const;
+ void setFrequency(int frequency);
+
+ bool isStereo() const;
+ QRadioTuner::StereoMode stereoMode() const;
+ void setStereoMode(QRadioTuner::StereoMode mode);
+
+ int signalStrength() const;
+
+ int volume() const;
+ void setVolume(int volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+ bool isSearching() const;
+ void cancelSearch();
+
+ void searchForward();
+ void searchBackward();
+
+ void start();
+ void stop();
+
+ QRadioTuner::Error error() const;
+ QString errorString() const;
+
+private slots:
+ void handleStarted();
+ void handleStopped();
+ void handleTuned(double frequency);
+};
+
+#endif // FMRXCONTROL_H
diff --git a/fmrxproxy.cpp b/fmrxproxy.cpp
new file mode 100644
index 0000000..77fcfb1
--- /dev/null
+++ b/fmrxproxy.cpp
@@ -0,0 +1,148 @@
+#include "fmrxproxy.h"
+
+#include <QtDebug>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+// Cannot really use QtDbus because lack of support for FD passing, pity.
+
+#define BUS_NAME "com.javispedro.fmrxd"
+#define BUS_PATH "/com/javispedro/fmrxd"
+#define BUS_INTERFACE BUS_NAME
+
+#define BUS_MATCH_RULE "type='signal',sender='" BUS_NAME "',interface='" BUS_INTERFACE "'"
+
+FmRxProxy::FmRxProxy(QObject *parent) :
+ QObject(parent)
+{
+ GError *gerr = NULL;
+ DBusGConnection *gconn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &gerr);
+ if (!gconn) {
+ qWarning("Failed to connect to D-Bus: %s", gerr->message);
+ g_error_free(gerr);
+ }
+
+ // From dbus-glib all we want is main loop integration,
+ // the rest we use plain D-Bus.
+
+ m_conn = dbus_g_connection_get_connection(gconn);
+ dbus_bus_add_match(m_conn, BUS_MATCH_RULE, NULL);
+ dbus_connection_add_filter(m_conn, bus_message_filter, this, NULL);
+}
+
+FmRxProxy::~FmRxProxy()
+{
+ dbus_bus_remove_match(m_conn, BUS_MATCH_RULE, NULL);
+ dbus_connection_remove_filter(m_conn, bus_message_filter, this);
+}
+
+int FmRxProxy::Connect()
+{
+ DBusError err;
+ dbus_bool_t ret;
+ int fd;
+ DBusMessage *reply;
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "Connect");
+ Q_ASSERT(msg != NULL);
+
+ dbus_error_init(&err);
+
+ reply = dbus_connection_send_with_reply_and_block(m_conn, msg, -1, &err);
+ dbus_message_unref(msg);
+
+ if (!reply) {
+ qWarning("Failed to Connect(): %s", err.message);
+ dbus_error_free(&err);
+ return -1;
+ }
+
+ ret = dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
+ dbus_message_unref(reply);
+
+ if (!ret) {
+ qWarning("Failed to parse Connect() reply: %s", err.message);
+ dbus_error_free(&err);
+ return -1;
+ }
+
+
+ return fd;
+}
+
+void FmRxProxy::Tune(double f)
+{
+ DBusError err;
+ DBusMessage *reply;
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "Tune");
+ Q_ASSERT(msg != NULL);
+
+ dbus_error_init(&err);
+
+ dbus_message_append_args(msg, DBUS_TYPE_DOUBLE, &f, DBUS_TYPE_INVALID);
+
+ reply = dbus_connection_send_with_reply_and_block(m_conn, msg, -1, &err);
+ dbus_message_unref(msg);
+
+ if (!reply) {
+ qWarning("Failed to Tune(): %s", err.message);
+ dbus_error_free(&err);
+ return;
+ }
+
+ dbus_message_unref(reply);
+}
+
+void FmRxProxy::SearchForward()
+{
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "SearchForward");
+ Q_ASSERT(msg != NULL);
+
+ dbus_connection_send(m_conn, msg, NULL);
+ dbus_message_unref(msg);
+}
+
+void FmRxProxy::SearchBackward()
+{
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "SearchBackward");
+ Q_ASSERT(msg != NULL);
+
+ dbus_connection_send(m_conn, msg, NULL);
+ dbus_message_unref(msg);
+}
+
+DBusHandlerResult FmRxProxy::bus_message_filter(DBusConnection *,
+ DBusMessage *m, void *user_data)
+{
+ FmRxProxy *self = reinterpret_cast<FmRxProxy*>(user_data);
+ if (dbus_message_has_interface(m, BUS_INTERFACE)) {
+ if (dbus_message_is_signal(m, BUS_INTERFACE, "Tuned")) {
+ double freq;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_DOUBLE, &freq, DBUS_TYPE_INVALID)) {
+ emit self->Tuned(freq);
+ }
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "Stopped")) {
+ emit self->Stopped();
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "PiReceived")) {
+ quint16 pi;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_UINT16, &pi, DBUS_TYPE_INVALID)) {
+ emit self->PiReceived(pi);
+ }
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "PsReceived")) {
+ char * s;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
+ emit self->PsReceived(QString::fromUtf8(s));
+ }
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "RtReceived")) {
+ char * s;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
+ emit self->RtReceived(QString::fromUtf8(s));
+ }
+ }
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
diff --git a/fmrxproxy.h b/fmrxproxy.h
new file mode 100644
index 0000000..ccd544a
--- /dev/null
+++ b/fmrxproxy.h
@@ -0,0 +1,35 @@
+#ifndef FMRXPROXY_H
+#define FMRXPROXY_H
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <dbus/dbus.h>
+
+class FmRxProxy : public QObject
+{
+ Q_OBJECT
+public:
+ explicit FmRxProxy(QObject *parent = 0);
+ ~FmRxProxy();
+
+ int Connect();
+ void Tune(double frequency);
+ void SearchBackward();
+ void SearchForward();
+
+signals:
+ void Tuned(double frequency);
+ void Stopped();
+ void PiReceived(ushort pi);
+ void PsReceived(const QString &ps);
+ void RtReceived(const QString &rt);
+
+private:
+ DBusConnection *m_conn;
+
+ static DBusHandlerResult bus_message_filter(DBusConnection *conn,
+ DBusMessage *m, void *user_data);
+
+};
+
+#endif // FMRXPROXY_H
diff --git a/fmrxproxyadaptor.cpp b/fmrxproxyadaptor.cpp
new file mode 100644
index 0000000..eb18eb2
--- /dev/null
+++ b/fmrxproxyadaptor.cpp
@@ -0,0 +1,118 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -c FmRxProxy -p fmrxproxy.cpp -a fmrxproxyadaptor.cpp /home/javier/maemo/fm/h/fmrxd-0.1/fmrxd.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#ifndef FMRXPROXYADAPTOR_CPP_1325275015
+#define FMRXPROXYADAPTOR_CPP_1325275015
+
+#include <QtCore/QObject>
+#include <QtCore/QMetaObject>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+
+/*
+ * Adaptor class for interface com.javispedro.fmrxd
+ */
+class FmRxProxy: public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "com.javispedro.fmrxd")
+ Q_CLASSINFO("D-Bus Introspection", ""
+" <interface name=\"com.javispedro.fmrxd\">\n"
+" <method name=\"Connect\">\n"
+" <arg direction=\"out\" type=\"i\" name=\"pipe\"/>\n"
+" </method>\n"
+" <method name=\"Tune\">\n"
+" <arg direction=\"in\" type=\"d\" name=\"frequency\"/>\n"
+" </method>\n"
+" <method name=\"SearchForward\"/>\n"
+" <method name=\"SearchBackward\"/>\n"
+" <signal name=\"Tuned\">\n"
+" <arg type=\"d\" name=\"frequency\"/>\n"
+" </signal>\n"
+" <signal name=\"Stopped\"/>\n"
+" <signal name=\"PiReceived\">\n"
+" <arg type=\"q\" name=\"pi\"/>\n"
+" </signal>\n"
+" <signal name=\"PsReceived\">\n"
+" <arg type=\"s\" name=\"ps\"/>\n"
+" </signal>\n"
+" <signal name=\"RtReceived\">\n"
+" <arg type=\"s\" name=\"rt\"/>\n"
+" </signal>\n"
+" </interface>\n"
+ "")
+public:
+ FmRxProxy(QObject *parent);
+ virtual ~FmRxProxy();
+
+public: // PROPERTIES
+public Q_SLOTS: // METHODS
+ int Connect();
+ void SearchBackward();
+ void SearchForward();
+ void Tune(double frequency);
+Q_SIGNALS: // SIGNALS
+ void PiReceived(ushort pi);
+ void PsReceived(const QString &ps);
+ void RtReceived(const QString &rt);
+ void Stopped();
+ void Tuned(double frequency);
+};
+
+#endif
+/*
+ * Implementation of adaptor class FmRxProxy
+ */
+
+FmRxProxy::FmRxProxy(QObject *parent)
+ : QDBusAbstractAdaptor(parent)
+{
+ // constructor
+ setAutoRelaySignals(true);
+}
+
+FmRxProxy::~FmRxProxy()
+{
+ // destructor
+}
+
+int FmRxProxy::Connect()
+{
+ // handle method call com.javispedro.fmrxd.Connect
+ int pipe;
+ QMetaObject::invokeMethod(parent(), "Connect", Q_RETURN_ARG(int, pipe));
+ return pipe;
+}
+
+void FmRxProxy::SearchBackward()
+{
+ // handle method call com.javispedro.fmrxd.SearchBackward
+ QMetaObject::invokeMethod(parent(), "SearchBackward");
+}
+
+void FmRxProxy::SearchForward()
+{
+ // handle method call com.javispedro.fmrxd.SearchForward
+ QMetaObject::invokeMethod(parent(), "SearchForward");
+}
+
+void FmRxProxy::Tune(double frequency)
+{
+ // handle method call com.javispedro.fmrxd.Tune
+ QMetaObject::invokeMethod(parent(), "Tune", Q_ARG(double, frequency));
+}
+
diff --git a/fmrxservice.cpp b/fmrxservice.cpp
new file mode 100644
index 0000000..3a990bd
--- /dev/null
+++ b/fmrxservice.cpp
@@ -0,0 +1,154 @@
+#include <QtMultimedia/QAudioDeviceInfo>
+#include <QtMultimedia/QAudioOutput>
+#include <QtCore/QFile>
+#include <QtDebug>
+
+#include "fmrxservice.h"
+#include "fmrxcontrol.h"
+#include "fmrxproxy.h"
+
+// Again, this would be incredibly shorter if QAudioOuput could be used.
+// Unfortunately, it is completely useless in the Harmattan version.
+
+struct FmRxPriv
+{
+ QAudioOutput *out;
+ QFile *in;
+ int fd;
+ bool active;
+ double frequency;
+};
+
+FmRxService::FmRxService(QObject *parent) :
+ QMediaService(parent)
+{
+ m_proxy = new FmRxProxy(this);
+ m_control = new FmRxControl(this);
+ m_priv = new FmRxPriv;
+
+ QAudioFormat format;
+ format.setFrequency(48000);
+ format.setChannels(2);
+ format.setSampleType(QAudioFormat::SignedInt);
+ format.setSampleSize(16);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setCodec("audio/pcm");
+
+ QAudioDeviceInfo info = QAudioDeviceInfo::defaultOutputDevice();
+ if (!info.isFormatSupported(format)) {
+ qWarning("FM radio format not supported by audio output");
+ }
+ qDebug("Starting output to %s", qPrintable(info.deviceName()));
+
+ m_priv->out = new QAudioOutput(info, format, this);
+ m_priv->in = new QFile(this);
+ m_priv->active = false;
+
+ connect(m_proxy, SIGNAL(Tuned(double)), this, SLOT(handleTuned(double)));
+ connect(m_proxy, SIGNAL(Stopped()), this, SLOT(handleStopped()));
+ connect(m_proxy, SIGNAL(PiReceived(ushort)), this, SIGNAL(piReceived(ushort)));
+ connect(m_proxy, SIGNAL(PsReceived(QString)), this, SIGNAL(psReceived(QString)));
+ connect(m_proxy, SIGNAL(RtReceived(QString)), this, SIGNAL(rtReceived(QString)));
+
+ connect(m_priv->out, SIGNAL(stateChanged(QAudio::State)),
+ this, SLOT(handleOutState(QAudio::State)));
+}
+
+FmRxService::~FmRxService()
+{
+ delete m_priv;
+}
+
+QMediaControl *FmRxService::requestControl(const char *name)
+{
+ if (qstrcmp(name, QRadioTunerControl_iid) == 0)
+ return m_control;
+
+ return 0;
+}
+
+void FmRxService::releaseControl(QMediaControl *control)
+{
+ // Do nothing
+}
+
+void FmRxService::start()
+{
+ m_priv->fd = m_proxy->Connect();
+ m_priv->in->open(m_priv->fd, QIODevice::ReadOnly);
+ m_priv->out->start(m_priv->in);
+ qDebug("Starting fmrx service");
+}
+
+void FmRxService::stop()
+{
+ m_priv->out->stop();
+ m_priv->in->close();
+ close(m_priv->fd);
+}
+
+bool FmRxService::isAvailable() const
+{
+ // TODO Check avaibility of fmrxd service
+ return true;
+}
+
+QtMultimediaKit::AvailabilityError FmRxService::availabilityError() const
+{
+ return QtMultimediaKit::NoError;
+}
+
+bool FmRxService::isActive() const
+{
+ return m_priv->active;
+}
+
+void FmRxService::handleTuned(double frequency)
+{
+ if (!qFuzzyCompare(m_priv->frequency, frequency)) {
+ m_priv->frequency = frequency;
+ emit tuned(frequency);
+ }
+ if (!m_priv->active) {
+ m_priv->active = true;
+ emit started();
+ }
+}
+
+void FmRxService::handleStopped()
+{
+ if (m_priv->active) {
+ m_priv->active = false;
+ emit stopped();
+ }
+}
+
+void FmRxService::handleOutState(QAudio::State state)
+{
+ qDebug() << "New out state = " << state;
+ if (state == QAudio::IdleState &&
+ m_priv->out->error() == QAudio::UnderrunError) {
+ qDebug() << "Restarting";
+ m_priv->out->start(m_priv->in);
+ }
+}
+
+double FmRxService::frequency()
+{
+ return m_priv->frequency;
+}
+
+void FmRxService::setFrequency(double frequency)
+{
+ m_proxy->Tune(frequency);
+}
+
+void FmRxService::searchForward()
+{
+ m_proxy->SearchForward();
+}
+
+void FmRxService::searchBackward()
+{
+ m_proxy->SearchBackward();
+}
diff --git a/fmrxservice.h b/fmrxservice.h
new file mode 100644
index 0000000..1f9e278
--- /dev/null
+++ b/fmrxservice.h
@@ -0,0 +1,58 @@
+#ifndef FMRXSERVICE_H
+#define FMRXSERVICE_H
+
+#include <QAudio>
+#include <QMediaService>
+#include <QRadioTuner>
+
+struct FmRxPriv;
+class FmRxProxy;
+class FmRxControl;
+class FmRxRds;
+
+class FmRxService : public QMediaService
+{
+ Q_OBJECT
+
+public:
+ explicit FmRxService(QObject *parent = 0);
+ ~FmRxService();
+
+ QMediaControl *requestControl(const char *name);
+ void releaseControl(QMediaControl *control);
+
+ void start();
+ void stop();
+
+ bool isAvailable() const;
+ QtMultimediaKit::AvailabilityError availabilityError() const;
+
+ bool isActive() const;
+
+ double frequency();
+ void setFrequency(double frequency);
+
+ void searchForward();
+ void searchBackward();
+
+signals:
+ void tuned(double frequency);
+ void started();
+ void stopped();
+ void piReceived(ushort pi);
+ void psReceived(const QString &ps);
+ void rtReceived(const QString &rt);
+
+private slots:
+ void handleTuned(double frequency);
+ void handleStopped();
+ void handleOutState(QAudio::State state);
+
+private:
+ FmRxPriv *m_priv;
+ FmRxProxy *m_proxy;
+ FmRxControl *m_control;
+ FmRxRds *m_rds;
+};
+
+#endif // FMRXSERVICE_H
diff --git a/fmrxserviceplugin.cpp b/fmrxserviceplugin.cpp
new file mode 100644
index 0000000..38c4ce8
--- /dev/null
+++ b/fmrxserviceplugin.cpp
@@ -0,0 +1,24 @@
+#include <QMediaServiceProvider>
+
+#include "fmrxserviceplugin.h"
+#include "fmrxservice.h"
+
+QStringList FmRxServicePlugin::keys() const
+{
+ return QStringList() << QLatin1String(Q_MEDIASERVICE_RADIO);
+}
+
+QMediaService* FmRxServicePlugin::create(const QString &key)
+{
+ if (key == QLatin1String(Q_MEDIASERVICE_RADIO))
+ return new FmRxService;
+
+ return 0;
+}
+
+void FmRxServicePlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+Q_EXPORT_PLUGIN2(fmrx-qt, FmRxServicePlugin)
diff --git a/fmrxserviceplugin.h b/fmrxserviceplugin.h
new file mode 100644
index 0000000..b28bfad
--- /dev/null
+++ b/fmrxserviceplugin.h
@@ -0,0 +1,15 @@
+#ifndef FMRXSERVICEPLUGIN_H
+#define FMRXSERVICEPLUGIN_H
+
+#include <QMediaServiceProviderPlugin>
+
+class FmRxServicePlugin : public QMediaServiceProviderPlugin {
+ Q_OBJECT
+
+public:
+ QStringList keys() const;
+ QMediaService* create(QString const& key);
+ void release(QMediaService *service);
+};
+
+#endif // FMRXSERVICEPLUGIN_H
diff --git a/qtc_packaging/debian_harmattan/README b/qtc_packaging/debian_harmattan/README
new file mode 100644
index 0000000..f36a498
--- /dev/null
+++ b/qtc_packaging/debian_harmattan/README
@@ -0,0 +1,7 @@
+The Harmattan Package fmrx-qt
+----------------------------
+
+This package is a Qt Multimedia Kit plugin. Please consult QRadioTuner QT
+documentation for examples of use.
+
+ -- Javier <maemo@javispedro.com> Fri, 30 Dec 2011 19:56:24 +0100
diff --git a/qtc_packaging/debian_harmattan/changelog b/qtc_packaging/debian_harmattan/changelog
new file mode 100644
index 0000000..f0e26be
--- /dev/null
+++ b/qtc_packaging/debian_harmattan/changelog
@@ -0,0 +1,5 @@
+fmrx-qt (0.0.1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Javier <javier@unknown> Fri, 30 Dec 2011 19:56:24 +0100
diff --git a/qtc_packaging/debian_harmattan/compat b/qtc_packaging/debian_harmattan/compat
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/qtc_packaging/debian_harmattan/compat
@@ -0,0 +1 @@
+7
diff --git a/qtc_packaging/debian_harmattan/control b/qtc_packaging/debian_harmattan/control
new file mode 100644
index 0000000..e28bdf5
--- /dev/null
+++ b/qtc_packaging/debian_harmattan/control
@@ -0,0 +1,18 @@
+Source: fmrx-qt
+Section: sound
+Priority: optional
+Maintainer: Javier S. Pedro <maemo@javispedro.com>
+Build-Depends: debhelper (>= 5), libqt4-dev, libqtm-multimedia-dev,
+ libglib2.0-dev, libdbus-glib-1-dev, libdbus-1-dev
+Standards-Version: 3.7.3
+Homepage: https://gitorious.org/n950-fmrx/fmrx-qt
+
+Package: fmrx-qt
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, fmrxd
+Description: FmRx Qt MediaService plugin
+ This is a Qt Multimedia MediaService plugin that provides access
+ to the N950/N9 via the FmRx daemon.
+ .
+ If this plugin is installed, QRadioTuner can be used in
+ Harmattan apps.
diff --git a/qtc_packaging/debian_harmattan/copyright b/qtc_packaging/debian_harmattan/copyright
new file mode 100644
index 0000000..ed51293
--- /dev/null
+++ b/qtc_packaging/debian_harmattan/copyright
@@ -0,0 +1,22 @@
+This work was created and packaged for Debian by:
+
+ Javier S. Pedro <maemo@javispedro.com> on Sat, 03 Sep 2011 19:47:50 +0200
+
+Copyright:
+
+ Javier S. Pedro <maemo@javispedro.com>
+
+License:
+
+ 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 package 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, see <http://www.gnu.org/licenses/>.
diff --git a/qtc_packaging/debian_harmattan/manifest.aegis b/qtc_packaging/debian_harmattan/manifest.aegis
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/qtc_packaging/debian_harmattan/manifest.aegis
diff --git a/qtc_packaging/debian_harmattan/rules b/qtc_packaging/debian_harmattan/rules
new file mode 100755
index 0000000..30783dc
--- /dev/null
+++ b/qtc_packaging/debian_harmattan/rules
@@ -0,0 +1,91 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # qmake PREFIX=/usr# Uncomment this line for use without Qt Creator
+
+ touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+
+ # Add here commands to compile the package.
+ # $(MAKE) # Uncomment this line for use without Qt Creator
+ #docbook-to-man debian/fmrx-qt.sgml > fmrx-qt.1
+
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ $(MAKE) clean
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/fmrx-qt.
+ $(MAKE) INSTALL_ROOT="$(CURDIR)"/debian/fmrx-qt install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+# dh_install
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_python
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_perl
+# dh_makeshlibs
+ dh_installdeb
+ # dh_shlibdeps # Uncomment this line for use without Qt Creator
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure