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_;