Home | History | Annotate | Download | only in avahi-qt
      1 /***
      2   This file is part of avahi.
      3 
      4   avahi is free software; you can redistribute it and/or modify it
      5   under the terms of the GNU Lesser General Public License as
      6   published by the Free Software Foundation; either version 2.1 of the
      7   License, or (at your option) any later version.
      8 
      9   avahi is distributed in the hope that it will be useful, but WITHOUT
     10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     11   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
     12   Public License for more details.
     13 
     14   You should have received a copy of the GNU Lesser General Public
     15   License along with avahi; if not, write to the Free Software
     16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
     17   USA.
     18 ***/
     19 
     20 #include <sys/time.h>
     21 #ifdef QT4
     22 #include <Qt/qsocketnotifier.h>
     23 #include <Qt/qobject.h>
     24 #include <Qt/qtimer.h>
     25 #else
     26 #include <qsocketnotifier.h>
     27 #include <qobject.h>
     28 #include <qtimer.h>
     29 #endif
     30 #include <avahi-common/timeval.h>
     31 #include "qt-watch.h"
     32 
     33 class AvahiWatch : public QObject
     34 {
     35     Q_OBJECT
     36 public:
     37     AvahiWatch(int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void* userdata);
     38     ~AvahiWatch() {}
     39     AvahiWatchEvent getEvents() const { return m_incallback ? m_lastEvent : (AvahiWatchEvent)0; }
     40     void setWatchedEvents(AvahiWatchEvent event);
     41 
     42 private slots:
     43     void gotIn();
     44     void gotOut();
     45 
     46 private:
     47     QSocketNotifier* m_in;
     48     QSocketNotifier* m_out;
     49     //FIXME: ERR and HUP?
     50     AvahiWatchCallback m_callback;
     51     AvahiWatchEvent m_lastEvent;
     52     int m_fd;
     53     void* m_userdata;
     54     bool m_incallback;
     55 };
     56 
     57 class AvahiTimeout : public QObject
     58 {
     59     Q_OBJECT
     60 
     61 public:
     62     AvahiTimeout(const struct timeval* tv, AvahiTimeoutCallback callback, void* userdata);
     63     ~AvahiTimeout() {}
     64     void update(const struct timeval* tv);
     65 
     66 private slots:
     67     void timeout();
     68 
     69 private:
     70     QTimer m_timer;
     71     AvahiTimeoutCallback m_callback;
     72     void* m_userdata;
     73 };
     74 
     75 
     76 
     77 AvahiWatch::AvahiWatch(int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void* userdata) :
     78     m_in(0), m_out(0),  m_callback(callback), m_fd(fd), m_userdata(userdata), m_incallback(false)
     79 {
     80     setWatchedEvents(event);
     81 }
     82 
     83 void AvahiWatch::gotIn()
     84 {
     85     m_lastEvent = AVAHI_WATCH_IN;
     86     m_incallback=true;
     87     m_callback(this,m_fd,m_lastEvent,m_userdata);
     88     m_incallback=false;
     89 }
     90 
     91 void AvahiWatch::gotOut()
     92 {
     93     m_lastEvent = AVAHI_WATCH_IN;
     94     m_incallback=true;
     95     m_callback(this,m_fd,m_lastEvent,m_userdata);
     96     m_incallback=false;
     97 }
     98 
     99 void AvahiWatch::setWatchedEvents(AvahiWatchEvent event)
    100 {
    101     if (!(event & AVAHI_WATCH_IN)) { delete m_in; m_in=0; }
    102     if (!(event & AVAHI_WATCH_OUT)) { delete m_out; m_out=0; }
    103     if (event & AVAHI_WATCH_IN) {
    104 	m_in = new QSocketNotifier(m_fd,QSocketNotifier::Read, this);
    105 	connect(m_in,SIGNAL(activated(int)),SLOT(gotIn()));
    106     }
    107     if (event & AVAHI_WATCH_OUT) {
    108 	m_out = new QSocketNotifier(m_fd,QSocketNotifier::Write, this);
    109 	connect(m_out,SIGNAL(activated(int)),SLOT(gotOut()));
    110     }
    111 }
    112 
    113 AvahiTimeout::AvahiTimeout(const struct timeval* tv, AvahiTimeoutCallback callback, void *userdata) :
    114     m_callback(callback), m_userdata(userdata)
    115 {
    116     connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeout()));
    117 #ifdef QT4
    118     m_timer.setSingleShot(true);
    119 #endif
    120     update(tv);
    121 }
    122 
    123 void AvahiTimeout::update(const struct timeval *tv)
    124 {
    125     m_timer.stop();
    126     if (tv) {
    127     AvahiUsec u = avahi_age(tv)/1000;
    128 #ifdef QT4
    129     m_timer.start( (u>0) ? 0 : -u);
    130 #else
    131     m_timer.start( (u>0) ? 0 : -u,true);
    132 #endif
    133     }
    134 }
    135 
    136 void AvahiTimeout::timeout()
    137 {
    138     m_callback(this,m_userdata);
    139 }
    140 
    141 static AvahiWatch* q_watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback,
    142     void *userdata)
    143 {
    144     return new AvahiWatch(fd, event, callback, userdata);
    145 }
    146 
    147 static void q_watch_update(AvahiWatch *w, AvahiWatchEvent events)
    148 {
    149     w->setWatchedEvents(events);
    150 }
    151 
    152 static AvahiWatchEvent q_watch_get_events(AvahiWatch *w)
    153 {
    154     return w->getEvents();
    155 }
    156 
    157 static void q_watch_free(AvahiWatch *w)
    158 {
    159     delete w;
    160 }
    161 
    162 static AvahiTimeout* q_timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback,
    163     void *userdata)
    164 {
    165     return new AvahiTimeout(tv, callback, userdata);
    166 }
    167 
    168 static void q_timeout_update(AvahiTimeout *t, const struct timeval *tv)
    169 {
    170     t->update(tv);
    171 }
    172 
    173 static void q_timeout_free(AvahiTimeout *t)
    174 {
    175     delete t;
    176 }
    177 
    178 const AvahiPoll* avahi_qt_poll_get(void)
    179 {
    180     static const AvahiPoll qt_poll = {
    181         NULL,
    182         q_watch_new,
    183         q_watch_update,
    184         q_watch_get_events,
    185         q_watch_free,
    186         q_timeout_new,
    187         q_timeout_update,
    188         q_timeout_free
    189     };
    190 
    191     return &qt_poll;
    192 }
    193 
    194 #ifdef QT4
    195 #include "qt-watch.moc4"
    196 #else
    197 #include "qt-watch.moc3"
    198 #endif
    199