From 056e50ea51e4563f9467f42759f1a62a7b9ca134 Mon Sep 17 00:00:00 2001 From: Tobias Rundstrom Date: Thu, 9 Mar 2006 00:42:12 -0300 Subject: [PATCH] Added AVAHI support to promoe. Check the promoe.pro file to enable / disable it. --- MainWindow.cpp | 10 ++- ServerBrowser.cpp | 190 ++++++++++++++++++++++++++++++++++++++++++++++ ServerBrowser.h | 57 ++++++++++++++ XMMSHandler.cpp | 15 +++- XMMSHandler.h | 3 + avahi.prf | 4 + promoe.pro | 6 +- 7 files changed, 280 insertions(+), 5 deletions(-) create mode 100644 ServerBrowser.cpp create mode 100644 ServerBrowser.h create mode 100644 avahi.prf diff --git a/MainWindow.cpp b/MainWindow.cpp index 4dbf8f7..ce77e76 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -1,6 +1,10 @@ #include #include "MainWindow.h" +#ifdef HAVE_SERVERBROWSER +#include "ServerBrowser.h" +#endif + #include #include #include @@ -155,7 +159,6 @@ main (int argc, char **argv) playlistwin->move (settings.value("playlist/pos").toPoint ()); playlistwin->move (settings.value("playlist/pos").toPoint ()); - if (!settings.contains ("playlist/hidden")) settings.setValue ("playlist/hidden", true); @@ -164,5 +167,10 @@ main (int argc, char **argv) else playlistwin->show (); +#ifdef HAVE_SERVERBROWSER + ServerBrowserWindow *browser = new ServerBrowserWindow (mw); + browser->show (); +#endif + return app.exec(); } diff --git a/ServerBrowser.cpp b/ServerBrowser.cpp new file mode 100644 index 0000000..e2deddd --- /dev/null +++ b/ServerBrowser.cpp @@ -0,0 +1,190 @@ +#include "ServerBrowser.h" + +#include + +ServerBrowserWindow::ServerBrowserWindow (QWidget *parent) : QMainWindow (parent) +{ +#ifndef _WIN32 + setWindowIcon (QIcon (":icon.png")); +#endif + setWindowFlags (Qt::Dialog); + setWindowModality (Qt::ApplicationModal); + setAttribute (Qt::WA_DeleteOnClose); + + QWidget *c = new QWidget (this); + setCentralWidget (c); + + QVBoxLayout *vbox = new QVBoxLayout (c); + QLabel *label = new QLabel ("Available XMMS2 servers...", c); + label->setFont (QFont ("Helvetica", 16)); + vbox->addWidget (label); + + m_list = new ServerBrowserList (c); + vbox->addWidget (m_list); + + c = new QWidget (c); + QHBoxLayout *hbox = new QHBoxLayout (c); + vbox->addWidget (c); + + QPushButton *connect = new QPushButton ("Connect", c); + hbox->addWidget (new QWidget (), 1); + hbox->addWidget (connect); + + resize (300, 400); +} + +ServerBrowserList::ServerBrowserList (QWidget *parent) : QListWidget (parent) +{ + setIconSize (QSize (32, 32)); + setupAvahi (); + + + connect (this, SIGNAL (itemDoubleClicked (QListWidgetItem *)), + SLOT (connectServer (QListWidgetItem *))); +} + +void +ServerBrowserList::connectServer (QListWidgetItem *it) +{ + ServerBrowserWindow *sw = dynamic_cast (window ()); + + XMMSHandler *xmmsh = XMMSHandler::getInstance (); + ServerItem *item = dynamic_cast (it); + if (xmmsh->connect (item->path ().toAscii())) { + sw->close (); + } +} + +void +ServerBrowserList::addServer (const QString &name, const QString &path) +{ + new ServerItem (QIcon (":icon.png"), name, path, this); + update (); +} + +static void +resolve_callback (AvahiServiceResolver *r, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiResolverEvent event, + const char *name, + const char *type, + const char *domain, + const char *host_name, + const AvahiAddress *address, + uint16_t port, + AvahiStringList *txt, + AvahiLookupResultFlags flags, + void* userdata) +{ + ServerBrowserList *sl = static_cast (userdata); + + switch (event) { + case AVAHI_RESOLVER_FAILURE: + qWarning ("something broke..."); + break; + case AVAHI_RESOLVER_FOUND: + char a[AVAHI_ADDRESS_STR_MAX]; + avahi_address_snprint (a, sizeof (a), address); + QString path; + path.sprintf ("tcp://%s:%u", a, port); + + sl->addServer (QString::fromLatin1 (name), path); + break; + } +} + +static void +browse_callback (AvahiServiceBrowser *b, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char *name, + const char *type, + const char *domain, + AvahiLookupResultFlags flags, + void* userdata) +{ + ServerBrowserList *sl = static_cast (userdata); + + switch (event) { + case AVAHI_BROWSER_FAILURE: + + qWarning("(Browser) %s\n", avahi_strerror (avahi_client_errno(avahi_service_browser_get_client(b)))); + sl->close (); + return; + + case AVAHI_BROWSER_NEW: + if (!(avahi_service_resolver_new (sl->client (), interface, + protocol, name, + type, domain, + AVAHI_PROTO_UNSPEC, + (AvahiLookupFlags) 0, + resolve_callback, userdata))) + { + qWarning ("couldn't resolv service!"); + sl->close (); + } + break; + + case AVAHI_BROWSER_REMOVE: + break; + case AVAHI_BROWSER_ALL_FOR_NOW: + qDebug ("done!"); + break; + case AVAHI_BROWSER_CACHE_EXHAUSTED: + break; + } +} + +static void +client_callback (AvahiClient *c, + AvahiClientState state, + void *userdata) +{ + ServerBrowserList *sl = static_cast (userdata); + + if (state == AVAHI_CLIENT_FAILURE) { + qWarning ("Avahi failure!!"); + sl->close (); + } +} + +bool +ServerBrowserList::setupAvahi (void) +{ + int ret = 1; + int error; + + m_poll = avahi_qt_poll_get (); + m_client = avahi_client_new (m_poll, (AvahiClientFlags)0, client_callback, this, &error); + + if (!m_client) { + qWarning ("couldn't create avahi browser!"); + return false; + } + + if (!(m_sb = avahi_service_browser_new (m_client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_xmms2._tcp", NULL, (AvahiLookupFlags)0, + browse_callback, this))) { + qWarning ("couldn't create avahi browser!"); + return false; + } + +} + +ServerBrowserList::~ServerBrowserList () +{ + /* + if (m_poll) { + delete m_poll; + } + if (m_client) { + avahi_client_free (m_client); + } + if (m_sb) { + avahi_service_browser_free (m_sb); + } + */ +} diff --git a/ServerBrowser.h b/ServerBrowser.h new file mode 100644 index 0000000..1dd4e6f --- /dev/null +++ b/ServerBrowser.h @@ -0,0 +1,57 @@ +#ifndef __SERVER_BROWSER_H__ +#define __SERVER_BROWSER_H__ + +#include "XMMSHandler.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +class ServerItem : public QListWidgetItem { + public: + ServerItem (QIcon i, const QString &name, const QString &path, QListWidget *parent) : + QListWidgetItem (i, name, parent) { + m_path = path; + setToolTip (m_path); + } + QString path (void) const { return m_path; } + private: + QString m_path; +}; + +class ServerBrowserList : public QListWidget { + Q_OBJECT + public: + ServerBrowserList (QWidget *parent); + ~ServerBrowserList (); + void addServer (const QString &, const QString &); + bool setupAvahi (void); + AvahiClient *client (void) const { return m_client; } + + public slots: + void connectServer (QListWidgetItem *); + + private: + const AvahiPoll *m_poll; + AvahiClient *m_client; + AvahiServiceBrowser *m_sb; +}; + +class ServerBrowserWindow : public QMainWindow { + Q_OBJECT + public: + ServerBrowserWindow (QWidget *parent); + ~ServerBrowserWindow () {} + private: + ServerBrowserList *m_list; +}; + +#endif diff --git a/XMMSHandler.cpp b/XMMSHandler.cpp index 882598c..5c6d1c9 100644 --- a/XMMSHandler.cpp +++ b/XMMSHandler.cpp @@ -15,20 +15,27 @@ XMMSHandler *XMMSHandler::getInstance (void) { if (!singleton) { singleton = new XMMSHandler (); +#ifndef HAVE_SERVERBROWSER + singleton->connect (getenv ("XMMS_PATH")); +#endif } return singleton; } -XMMSHandler::XMMSHandler (void) : sigc::trackable () +XMMSHandler::XMMSHandler () : sigc::trackable () { m_xmmsc = new XMMSClient ("promoe"); +} - if (!m_xmmsc->connect (getenv ("XMMS_PATH"))) { +bool +XMMSHandler::connect (const char *path) +{ + if (!m_xmmsc->connect (path)) { QErrorMessage *err = new QErrorMessage (); err->showMessage ("Couldn't connect to XMMS2, please try again."); err->exec (); - exit (-1); + return false; } m_qt4 = new XmmsQT4 (m_xmmsc->getConn (), qApp); @@ -55,6 +62,8 @@ XMMSHandler::XMMSHandler (void) : sigc::trackable () r = m_xmmsc->broadcast_medialib_entry_changed (); r->connect (sigc::mem_fun (this, &XMMSHandler::medialib_entry_changed)); + + return true; } void diff --git a/XMMSHandler.h b/XMMSHandler.h index 6c7c5ae..25a4447 100644 --- a/XMMSHandler.h +++ b/XMMSHandler.h @@ -14,6 +14,9 @@ class XMMSHandler : public QObject, public sigc::trackable { static XMMSHandler *getInstance (void); XMMSHandler (void); ~XMMSHandler (); + + bool connect (const char *path); + void playback_playtime (XMMSResultValue *res); void playback_current_id (XMMSResultValue *res); void medialib_info (XMMSResultDict *res); diff --git a/avahi.prf b/avahi.prf new file mode 100644 index 0000000..62d06c2 --- /dev/null +++ b/avahi.prf @@ -0,0 +1,4 @@ +SOURCES += ServerBrowser.cpp +HEADERS += ServerBrowser.h +PKGCONFIG += avahi-client avahi-qt4 +DEFINES += HAVE_SERVERBROWSER diff --git a/promoe.pro b/promoe.pro index b979b7e..3297b0c 100644 --- a/promoe.pro +++ b/promoe.pro @@ -53,6 +53,7 @@ HEADERS += XmmsQT4.h \ MediaSongList.h + RESOURCES = promoe.qrc macx:RC_FILE = promoe.icns @@ -61,8 +62,11 @@ macx:QTPLUGIN += qjpeg QMAKE_LFLAGS += -L$$[QT_INSTALL_PLUGINS]/imageformats CONFIG += link_pkgconfig + QMAKE_CXXFLAGS += -g ;CONFIG += debug warn_on QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter -PKGCONFIG += xmms2-client xmms2-client-cpp sigc++-2.0 +PKGCONFIG += xmms2-client xmms2-client-cpp sigc++-2.0 + +CONFIG += avahi