domainbrowser.cpp
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include <qstringlist.h>
00022 #include "domainbrowser.h"
00023 #include "settings.h"
00024 #include "sdevent.h"
00025 #include "responder.h"
00026 #include "remoteservice.h"
00027 #include "query.h"
00028 #include "servicebrowser.h"
00029 #include <kapplication.h>
00030 #ifdef AVAHI_API_0_6
00031 #include <avahi-client/lookup.h>
00032 #endif
00033 
00034 namespace DNSSD
00035 {
00036 
00037 #ifdef AVAHI_API_0_6
00038 void domains_callback(AvahiDomainBrowser*,  AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00039      AvahiLookupResultFlags, void* context);
00040 #else
00041 void domains_callback(AvahiDomainBrowser*,  AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00042      void* context);
00043 #endif
00044 
00045 class DomainBrowserPrivate
00046 {
00047 public:
00048     DomainBrowserPrivate(DomainBrowser* owner) : m_browseLAN(false), m_started(false), 
00049         m_browser(0), m_owner(owner) {}
00050     ~DomainBrowserPrivate() { if (m_browser) avahi_domain_browser_free(m_browser); }
00051     QStringList m_domains;
00052     virtual void customEvent(QCustomEvent* event);
00053     bool m_browseLAN;
00054     bool m_started;
00055     AvahiDomainBrowser* m_browser;
00056     DomainBrowser* m_owner;
00057 };      
00058 
00059 void DomainBrowserPrivate::customEvent(QCustomEvent* event)
00060 {
00061     if (event->type()==QEvent::User+SD_ADDREMOVE) {
00062         AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
00063         if (aev->m_op==AddRemoveEvent::Add) m_owner->gotNewDomain(aev->m_domain);
00064             else m_owner->gotRemoveDomain(aev->m_domain);
00065     }
00066 }
00067     
00068 DomainBrowser::DomainBrowser(QObject *parent) : QObject(parent)
00069 {
00070     d = new DomainBrowserPrivate(this);
00071     d->m_domains = Configuration::domainList();
00072     if (Configuration::browseLocal()) {
00073         d->m_domains+="local.";
00074         d->m_browseLAN=true;
00075     }
00076     connect(KApplication::kApplication(),SIGNAL(kipcMessage(int,int)),this,
00077         SLOT(domainListChanged(int,int)));
00078 }
00079 
00080 DomainBrowser::DomainBrowser(const QStringList& domains, bool recursive, QObject *parent) : QObject(parent)
00081 {
00082     d = new DomainBrowserPrivate(this);
00083     d->m_browseLAN = recursive;
00084     d->m_domains=domains;
00085 }
00086 
00087 
00088 DomainBrowser::~DomainBrowser()
00089 {
00090     delete d;
00091 }
00092 
00093 
00094 void DomainBrowser::startBrowse()
00095 {
00096     if (d->m_started) return;
00097     d->m_started=true;
00098     if (ServiceBrowser::isAvailable()!=ServiceBrowser::Working) return;
00099     QStringList::const_iterator itEnd = d->m_domains.end();
00100     for (QStringList::const_iterator it=d->m_domains.begin(); it!=itEnd; ++it ) emit domainAdded(*it);
00101     if (d->m_browseLAN) 
00102 #ifdef AVAHI_API_0_6
00103         d->m_browser = avahi_domain_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00104         "local.", AVAHI_DOMAIN_BROWSER_BROWSE, (AvahiLookupFlags)0, domains_callback, this);
00105 #else
00106         d->m_browser = avahi_domain_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00107         "local.", AVAHI_DOMAIN_BROWSER_BROWSE, domains_callback, this);
00108 #endif
00109 }
00110 
00111 void DomainBrowser::gotNewDomain(const QString& domain)
00112 {
00113     if (d->m_domains.contains(domain)) return;
00114     d->m_domains.append(domain);
00115     emit domainAdded(domain);
00116 }
00117 
00118 void DomainBrowser::gotRemoveDomain(const QString& domain)
00119 {
00120     d->m_domains.remove(domain);
00121     emit domainRemoved(domain);
00122 }
00123 
00124 void DomainBrowser::domainListChanged(int message,int)
00125 {
00126     if (message!=KIPCDomainsChanged) return;
00127 
00128     bool was_started = d->m_started;
00129     if (d->m_browser) { 
00130         avahi_domain_browser_free(d->m_browser);  // LAN query
00131         d->m_browser=0;
00132     }
00133     d->m_started = false;
00134 
00135     // remove all domains and resolvers
00136     if (was_started) {
00137         QStringList::const_iterator itEnd = d->m_domains.end();
00138         for (QStringList::const_iterator it=d->m_domains.begin(); it!=itEnd; ++it )
00139             emit domainRemoved(*it);
00140     }
00141     d->m_domains.clear();
00142     // now reread configuration and add domains
00143     Configuration::self()->readConfig();
00144     d->m_browseLAN = Configuration::browseLocal();
00145     d->m_domains = Configuration::domainList();
00146     if (Configuration::browseLocal()) d->m_domains+="local";
00147     // this will emit domainAdded() for every domain if necessary
00148     if (was_started) startBrowse();
00149 }
00150 
00151 const QStringList& DomainBrowser::domains() const
00152 {
00153     return d->m_domains;
00154 }
00155 
00156 bool DomainBrowser::isRunning() const
00157 {
00158     return d->m_started;
00159 }
00160 
00161 void DomainBrowser::virtual_hook(int, void*)
00162 {}
00163 
00164 #ifdef AVAHI_API_0_6
00165 void domains_callback(AvahiDomainBrowser*,  AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00166      AvahiLookupResultFlags,void* context)
00167 #else
00168 void domains_callback(AvahiDomainBrowser*,  AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00169      void* context)
00170 #endif
00171 {
00172     QObject *obj = reinterpret_cast<QObject*>(context);
00173     AddRemoveEvent* arev=new AddRemoveEvent((event==AVAHI_BROWSER_NEW) ? AddRemoveEvent::Add :
00174             AddRemoveEvent::Remove, QString::null, QString::null, 
00175             DNSToDomain(replyDomain));
00176         QApplication::postEvent(obj, arev);
00177 }
00178 
00179 
00180 }
00181 #include "domainbrowser.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys