diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 553de4235..3da967033 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -630,6 +630,36 @@ if(HAVE_DBUS)
# Gnome Screensaver DBus interface
list(APPEND SOURCES ui/dbusscreensaver.cpp)
+
+ if(HAVE_REMOTE)
+ # TODO: Use CMake macro when it supports -i
+ find_program(QDBUSXML2CPP qdbusxml2cpp)
+ add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.h
+ COMMAND ${QDBUSXML2CPP}
+ dbus/org.freedesktop.Avahi.EntryGroup.xml
+ -p ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup
+ -i dbus/metatypes.h
+ DEPENDS dbus/org.freedesktop.Avahi.EntryGroup.xml
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ list(APPEND HEADERS ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.h)
+ list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.cpp)
+
+ add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.h
+ COMMAND ${QDBUSXML2CPP}
+ dbus/org.freedesktop.Avahi.Server.xml
+ -p ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver
+ -i dbus/metatypes.h
+ DEPENDS dbus/org.freedesktop.Avahi.Server.xml
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ list(APPEND HEADERS ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.h)
+ list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.cpp)
+ endif(HAVE_REMOTE)
endif(HAVE_DBUS)
# Libgpod device backend
@@ -727,6 +757,10 @@ if(HAVE_REMOTE)
if(APPLE)
list(APPEND SOURCES remote/bonjour.mm)
endif(APPLE)
+
+ if(HAVE_DBUS)
+ list(APPEND SOURCES remote/avahi.cpp)
+ endif(HAVE_DBUS)
endif(HAVE_REMOTE)
# OS-specific sources that should be searched for translatable strings even
diff --git a/src/dbus/org.freedesktop.Avahi.EntryGroup.xml b/src/dbus/org.freedesktop.Avahi.EntryGroup.xml
new file mode 100644
index 000000000..2930d7eeb
--- /dev/null
+++ b/src/dbus/org.freedesktop.Avahi.EntryGroup.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/dbus/org.freedesktop.Avahi.Server.xml b/src/dbus/org.freedesktop.Avahi.Server.xml
new file mode 100644
index 000000000..f336f207c
--- /dev/null
+++ b/src/dbus/org.freedesktop.Avahi.Server.xml
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main.cpp b/src/main.cpp
index 4d1bdb034..0482f3148 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -80,6 +80,7 @@ using boost::scoped_ptr;
#include "core/mpris_common.h"
#include "core/mpris.h"
#include "core/mpris2.h"
+ #include "dbus/metatypes.h"
#include
#include
#include
@@ -310,8 +311,9 @@ int main(int argc, char *argv[]) {
qDBusRegisterMetaType();
qDBusRegisterMetaType();
qDBusRegisterMetaType();
+ qDBusRegisterMetaType >();
- // Create the session bus here so it's sure to live in the main thread
+ // Create the session bus here so it's sure to live in the main thread.
QDBusConnection::sessionBus();
mpris::ArtLoader art_loader;
@@ -323,6 +325,10 @@ int main(int argc, char *argv[]) {
#endif
#ifdef HAVE_REMOTE
+ #ifdef HAVE_DBUS
+ // Create the system bus here so it's sure to live in the main thread.
+ QDBusConnection::systemBus();
+ #endif
Zeroconf* zeroconf = Zeroconf::GetZeroconf();
if (zeroconf) {
HttpServer* server = new HttpServer(&player);
diff --git a/src/remote/avahi.cpp b/src/remote/avahi.cpp
new file mode 100644
index 000000000..fd47e2cfe
--- /dev/null
+++ b/src/remote/avahi.cpp
@@ -0,0 +1,48 @@
+#include "avahi.h"
+
+#include
+#include
+#include
+
+#include
+
+#include "dbus/avahientrygroup.h"
+#include "dbus/avahiserver.h"
+
+void Avahi::Publish(
+ const QString& domain, const QString& type, const QString& name, quint16 port) {
+ QtConcurrent::run(Avahi::SyncPublish, domain, type, name, port);
+}
+
+void Avahi::SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port) {
+ OrgFreedesktopAvahiServerInterface server_interface(
+ "org.freedesktop.Avahi",
+ "/",
+ QDBusConnection::systemBus());
+
+ QDBusPendingReply reply = server_interface.EntryGroupNew();
+ reply.waitForFinished();
+
+ OrgFreedesktopAvahiEntryGroupInterface entry_group_interface(
+ "org.freedesktop.Avahi",
+ reply.value().path(),
+ QDBusConnection::systemBus());
+
+ QDBusPendingReply<> add_reply = entry_group_interface.AddService(
+ -1, // Interface (Unspecified, ie. all interfaces)
+ -1, // Protocol (Unspecified, ie. IPv4 & IPv6)
+ 0, // Flags
+ name, // Service name
+ type, // Service type
+ domain, // Domain, ie. local
+ QString::null, // Hostname (Avahi fills it if it's null)
+ port, // Port
+ QList()); // TXT record
+ add_reply.waitForFinished();
+
+ QDBusPendingReply<> commit_reply = entry_group_interface.Commit();
+ commit_reply.waitForFinished();
+ if (commit_reply.isValid()) {
+ qDebug() << "Remote interface published on Avahi";
+ }
+}
diff --git a/src/remote/avahi.h b/src/remote/avahi.h
new file mode 100644
index 000000000..ac31e2814
--- /dev/null
+++ b/src/remote/avahi.h
@@ -0,0 +1,15 @@
+#ifndef AVAHI_H
+#define AVAHI_H
+
+#include "zeroconf.h"
+
+class Avahi : public Zeroconf {
+ public:
+ virtual void Publish(
+ const QString& domain, const QString& type, const QString& name, quint16 port);
+
+ private:
+ static void SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port);
+};
+
+#endif
diff --git a/src/remote/zeroconf.cpp b/src/remote/zeroconf.cpp
index 2a95c895a..cab2c00d9 100644
--- a/src/remote/zeroconf.cpp
+++ b/src/remote/zeroconf.cpp
@@ -1,9 +1,15 @@
#include "zeroconf.h"
+#include "config.h"
+
#ifdef Q_OS_DARWIN
#include "bonjour.h"
#endif
+#ifdef HAVE_DBUS
+#include "avahi.h"
+#endif
+
Zeroconf* Zeroconf::instance_ = NULL;
Zeroconf* Zeroconf::GetZeroconf() {
@@ -11,6 +17,10 @@ Zeroconf* Zeroconf::GetZeroconf() {
#ifdef Q_OS_DARWIN
return new Bonjour();
#endif
+
+ #ifdef HAVE_DBUS
+ return new Avahi();
+ #endif
}
return instance_;