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