1 /*
2 * Copyright (C) 2013 Simon Richter
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include "messagepump_avahi.h"
23 #include "messagepump.h"
24
25 #include <sys/time.h>
26
27 extern "C" {
28 static AvahiWatch *avahi_watch_new(AvahiPoll const *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata);
29 static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event);
30 static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w);
31 static void avahi_watch_free(AvahiWatch *w);
32 static AvahiTimeout* avahi_timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata);
33 static void avahi_timeout_update(AvahiTimeout *, const struct timeval *tv);
34 static void avahi_timeout_free(AvahiTimeout *t);
35 }
36
37 using namespace librevisa;
38
39 struct AvahiWatch :
40 public messagepump::watch
41 {
42 AvahiWatchCallback callback;
43 void *userdata;
44
45 virtual void notify_fd_event(int fd, messagepump::fd_event event);
cleanupAvahiWatch46 virtual void cleanup() { delete this; }
47
48 // Avoid warning
~AvahiWatchAvahiWatch49 virtual ~AvahiWatch() throw() { }
50 };
51
52 struct AvahiTimeout :
53 public librevisa::messagepump::timeout
54 {
55 AvahiTimeoutCallback callback;
56 void *userdata;
57
58 virtual void notify_timeout();
cleanupAvahiTimeout59 virtual void cleanup() { delete this; }
60
61 // Avoid watning
~AvahiTimeoutAvahiTimeout62 virtual ~AvahiTimeout() throw() { }
63 };
64
operator |=(AvahiWatchEvent & lhs,AvahiWatchEvent rhs)65 inline AvahiWatchEvent &operator|=(AvahiWatchEvent &lhs, AvahiWatchEvent rhs)
66 {
67 return (lhs = AvahiWatchEvent(unsigned(lhs) | unsigned(rhs)));
68 }
69
to_avahi(messagepump::fd_event event)70 inline AvahiWatchEvent to_avahi(messagepump::fd_event event)
71 {
72 AvahiWatchEvent ret = AvahiWatchEvent(0);
73 if(event & main.read)
74 ret |= AVAHI_WATCH_IN;
75 if(event & main.write)
76 ret |= AVAHI_WATCH_OUT;
77 return ret;
78 }
79
to_librevisa(AvahiWatchEvent event)80 inline messagepump::fd_event to_librevisa(AvahiWatchEvent event)
81 {
82 messagepump::fd_event ret = messagepump::fd_event(0);
83 if(event & AVAHI_WATCH_IN)
84 ret |= main.read;
85 if(event & AVAHI_WATCH_OUT)
86 ret |= main.write;
87 return ret;
88 }
89
notify_fd_event(int fd,messagepump::fd_event event)90 void AvahiWatch::notify_fd_event(int fd, messagepump::fd_event event)
91 {
92 callback(this, fd, to_avahi(event), userdata);
93 }
94
notify_timeout()95 void AvahiTimeout::notify_timeout()
96 {
97 callback(this, userdata);
98 }
99
avahi_watch_new(AvahiPoll const *,int fd,AvahiWatchEvent event,AvahiWatchCallback callback,void * userdata)100 static AvahiWatch *avahi_watch_new(
101 AvahiPoll const *,
102 int fd,
103 AvahiWatchEvent event,
104 AvahiWatchCallback callback,
105 void *userdata)
106 {
107 AvahiWatch *n = new AvahiWatch;
108 n->fd = fd;
109 n->event = to_librevisa(event);
110 n->callback = callback;
111 n->userdata = userdata;
112
113 main.register_watch(*n);
114 return n;
115 }
116
avahi_watch_update(AvahiWatch * w,AvahiWatchEvent event)117 static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event)
118 {
119 main.update_watch(*w, to_librevisa(event));
120 }
121
avahi_watch_get_events(AvahiWatch * w)122 static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w)
123 {
124 return to_avahi(main.get_events(*w));
125 }
126
avahi_watch_free(AvahiWatch * w)127 static void avahi_watch_free(AvahiWatch *w)
128 {
129 main.unregister_watch(*w);
130 }
131
avahi_timeout_new(AvahiPoll const *,struct timeval const * tv,AvahiTimeoutCallback callback,void * userdata)132 static AvahiTimeout* avahi_timeout_new(
133 AvahiPoll const *,
134 struct timeval const *tv,
135 AvahiTimeoutCallback callback,
136 void *userdata)
137 {
138 AvahiTimeout *n = new AvahiTimeout;
139 if(tv)
140 n->tv = *tv;
141 n->callback = callback;
142 n->userdata = userdata;
143 main.register_timeout(*n);
144 return n;
145 }
146
avahi_timeout_update(AvahiTimeout * t,const struct timeval * tv)147 static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv)
148 {
149 main.update_timeout(*t, tv);
150 }
151
avahi_timeout_free(AvahiTimeout * t)152 static void avahi_timeout_free(AvahiTimeout *t)
153 {
154 main.unregister_timeout(*t);
155 }
156
157 struct AvahiPoll const avahi_main =
158 {
159 0,
160 &avahi_watch_new,
161 &avahi_watch_update,
162 &avahi_watch_get_events,
163 &avahi_watch_free,
164 &avahi_timeout_new,
165 &avahi_timeout_update,
166 &avahi_timeout_free
167 };
168