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 
00046 class DomainBrowserPrivate 
00047 {
00048 public:
00049     DomainBrowserPrivate(DomainBrowser* owner) : m_browseLAN(false), m_started(false), 
00050         m_browser(0), m_owner(owner) {}
00051     ~DomainBrowserPrivate() { if (m_browser) avahi_domain_browser_free(m_browser); }
00052     QStringList m_domains;
00053     virtual void customEvent(QCustomEvent* event);
00054     bool m_browseLAN;
00055     bool m_started;
00056     AvahiDomainBrowser* m_browser;
00057     DomainBrowser* m_owner;
00058 };      
00059 
00060 void DomainBrowserPrivate::customEvent(QCustomEvent* event)
00061 {
00062     if (event->type()==QEvent::User+SD_ADDREMOVE) {
00063         AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
00064         if (aev->m_op==AddRemoveEvent::Add) m_owner->gotNewDomain(aev->m_domain);
00065             else m_owner->gotRemoveDomain(aev->m_domain);
00066     }
00067 }
00068 
00069     
00070 DomainBrowser::DomainBrowser(QObject *parent) : QObject(parent)
00071 {
00072     d = new DomainBrowserPrivate(this);
00073     d->m_domains = Configuration::domainList();
00074     if (Configuration::browseLocal()) {
00075         d->m_domains+="local.";
00076         d->m_browseLAN=true;
00077     }
00078     connect(KApplication::kApplication(),SIGNAL(kipcMessage(int,int)),this,
00079             SLOT(domainListChanged(int,int)));
00080 }
00081 
00082 DomainBrowser::DomainBrowser(const QStringList& domains, bool recursive, QObject *parent) : QObject(parent)
00083 {
00084     d = new DomainBrowserPrivate(this);
00085     d->m_browseLAN = recursive;
00086     d->m_domains=domains;
00087 }
00088 
00089 
00090 DomainBrowser::~DomainBrowser()
00091 {
00092     delete d;
00093 }
00094 
00095 
00096 void DomainBrowser::startBrowse()
00097 {
00098     if (d->m_started) return;
00099     d->m_started=true;
00100     if (ServiceBrowser::isAvailable()!=ServiceBrowser::Working) return;
00101     QStringList::const_iterator itEnd = d->m_domains.end();
00102     for (QStringList::const_iterator it=d->m_domains.begin(); it!=itEnd; ++it ) emit domainAdded(*it);
00103     if (d->m_browseLAN) 
00104 #ifdef AVAHI_API_0_6
00105         d->m_browser = avahi_domain_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00106         "local.", AVAHI_DOMAIN_BROWSER_BROWSE, (AvahiLookupFlags)0, domains_callback, this);
00107 #else
00108         d->m_browser = avahi_domain_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00109         "local.", AVAHI_DOMAIN_BROWSER_BROWSE, domains_callback, this);
00110 #endif
00111 }
00112 
00113 void DomainBrowser::gotNewDomain(const QString& domain)
00114 {
00115     if (d->m_domains.contains(domain)) return;
00116     d->m_domains.append(domain);
00117     emit domainAdded(domain);
00118 }
00119 
00120 void DomainBrowser::gotRemoveDomain(const QString& domain)
00121 {
00122     d->m_domains.remove(domain);
00123     emit domainRemoved(domain);
00124 }
00125 
00126 void DomainBrowser::domainListChanged(int message,int)
00127 {
00128     if (message!=KIPCDomainsChanged) return;
00129 
00130     bool was_started = d->m_started;
00131     if (d->m_browser) { 
00132         avahi_domain_browser_free(d->m_browser);  // LAN query
00133         d->m_browser=0;
00134     }
00135     d->m_started = false;
00136 
00137     // remove all domains and resolvers
00138     if (was_started) {
00139         QStringList::const_iterator itEnd = d->m_domains.end();
00140         for (QStringList::const_iterator it=d->m_domains.begin(); it!=itEnd; ++it )
00141             emit domainRemoved(*it);
00142     }
00143     d->m_domains.clear();
00144     // now reread configuration and add domains
00145     Configuration::self()->readConfig();
00146     d->m_browseLAN = Configuration::browseLocal();
00147     d->m_domains = Configuration::domainList();
00148     if (Configuration::browseLocal()) d->m_domains+="local";
00149     // this will emit domainAdded() for every domain if necessary
00150     if (was_started) startBrowse();
00151 }
00152 
00153 const QStringList& DomainBrowser::domains() const
00154 {
00155     return d->m_domains;
00156 }
00157 
00158 bool DomainBrowser::isRunning() const
00159 {
00160     return d->m_started;
00161 }
00162 
00163 void DomainBrowser::virtual_hook(int, void*)
00164 {}
00165 
00166 #ifdef AVAHI_API_0_6
00167 void domains_callback(AvahiDomainBrowser*,  AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00168      AvahiLookupResultFlags,void* context)
00169 #else
00170 void domains_callback(AvahiDomainBrowser*,  AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00171      void* context)
00172 #endif
00173 {
00174     QObject *obj = reinterpret_cast<QObject*>(context);
00175     AddRemoveEvent* arev=new AddRemoveEvent((event==AVAHI_BROWSER_NEW) ? AddRemoveEvent::Add :
00176             AddRemoveEvent::Remove, QString::null, QString::null, 
00177             DNSToDomain(replyDomain));
00178         QApplication::postEvent(obj, arev);
00179 }
00180 
00181 
00182 }
00183 #include "domainbrowser.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys