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 33class AvahiWatch : public QObject 34{ 35 Q_OBJECT 36public: 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 42private slots: 43 void gotIn(); 44 void gotOut(); 45 46private: 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 57class AvahiTimeout : public QObject 58{ 59 Q_OBJECT 60 61public: 62 AvahiTimeout(const struct timeval* tv, AvahiTimeoutCallback callback, void* userdata); 63 ~AvahiTimeout() {} 64 void update(const struct timeval* tv); 65 66private slots: 67 void timeout(); 68 69private: 70 QTimer m_timer; 71 AvahiTimeoutCallback m_callback; 72 void* m_userdata; 73}; 74 75 76 77AvahiWatch::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 83void 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 91void 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 99void 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 113AvahiTimeout::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 123void 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 136void AvahiTimeout::timeout() 137{ 138 m_callback(this,m_userdata); 139} 140 141static 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 147static void q_watch_update(AvahiWatch *w, AvahiWatchEvent events) 148{ 149 w->setWatchedEvents(events); 150} 151 152static AvahiWatchEvent q_watch_get_events(AvahiWatch *w) 153{ 154 return w->getEvents(); 155} 156 157static void q_watch_free(AvahiWatch *w) 158{ 159 delete w; 160} 161 162static 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 168static void q_timeout_update(AvahiTimeout *t, const struct timeval *tv) 169{ 170 t->update(tv); 171} 172 173static void q_timeout_free(AvahiTimeout *t) 174{ 175 delete t; 176} 177 178const 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