# DBus-C++

## Desktop Communication Bus System

libdbus-c-- Documentation 0.9.0

- Files
- Data Structures
- Globals
- Main Page

glib-integration.cpp
Go to the documentation of this file.
1/*
2 *
3 * D-Bus++ - C++ bindings for D-Bus
4 *
5 * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
6 *
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27#include <dbus-c++/glib-integration.h>
28
29#include <dbus/dbus.h> // for DBUS_WATCH_*
30
31 using namespace DBus;
32
33 Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority)
34 : Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL)
35{
36 if (Timeout::enabled())
37 _enable();
38}
39
40 Glib::BusTimeout::~BusTimeout()
41{
42 _disable();
43}
44
45 void Glib::BusTimeout::toggle()
46{
47 debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
48
49 if (Timeout::enabled()) _enable();
50 else _disable();
51}
52
53gboolean Glib::BusTimeout::timeout_handler(gpointer data)
54{
55 Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *>(data);
56
57 t->handle();
58
59 return TRUE;
60}
61
62 void Glib::BusTimeout::_enable()
63{
64 if (_source)
65 _disable(); // be sane
66
67 _source = g_timeout_source_new(Timeout::interval());
68 g_source_set_priority(_source, _priority);
69 g_source_set_callback(_source, timeout_handler, this, NULL);
70 g_source_attach(_source, _ctx);
71}
72
73 void Glib::BusTimeout::_disable()
74{
75 if (_source)
76 {
77 g_source_destroy(_source);
78 _source = NULL;
79 }
80}
81
82 struct BusSource
83{
84 GSource source;
85 GPollFD poll;
86};
87
88 static gboolean watch_prepare(GSource *source, gint *timeout)
89{
90 debug_log("glib: watch_prepare");
91
92 *timeout = -1;
93 return FALSE;
94}
95
96 static gboolean watch_check(GSource *source)
97{
98 debug_log("glib: watch_check");
99
100 BusSource *io = (BusSource *)source;
101 return io->poll.revents ? TRUE : FALSE;
102}
103
104 static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer data)
105{
106 debug_log("glib: watch_dispatch");
107
108 gboolean cb = callback(data);
109 return cb;
110}
111
112 static GSourceFuncs watch_funcs =
113{
114 watch_prepare,
115 watch_check,
116 watch_dispatch,
117 NULL
118};
119
120 Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority)
121 : Watch(wi), _ctx(ctx), _priority(priority), _source(NULL)
122{
123 if (Watch::enabled())
124 _enable();
125}
126
127 Glib::BusWatch::~BusWatch()
128{
129 _disable();
130}
131
132 void Glib::BusWatch::toggle()
133{
134 debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
135
136 if (Watch::enabled()) _enable();
137 else _disable();
138}
139
140gboolean Glib::BusWatch::watch_handler(gpointer data)
141{
142 Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *>(data);
143
144 BusSource *io = (BusSource *)(w->_source);
145
146 int flags = 0;
147 if (io->poll.revents & G_IO_IN)
148 flags |= DBUS_WATCH_READABLE;
149 if (io->poll.revents & G_IO_OUT)
150 flags |= DBUS_WATCH_WRITABLE;
151 if (io->poll.revents & G_IO_ERR)
152 flags |= DBUS_WATCH_ERROR;
153 if (io->poll.revents & G_IO_HUP)
154 flags |= DBUS_WATCH_HANGUP;
155
156 w->handle(flags);
157
158 return TRUE;
159}
160
161 void Glib::BusWatch::_enable()
162{
163 if (_source)
164 _disable(); // be sane
165 _source = g_source_new(&watch_funcs, sizeof(BusSource));
166 g_source_set_priority(_source, _priority);
167 g_source_set_callback(_source, watch_handler, this, NULL);
168
169 int flags = Watch::flags();
170 int condition = 0;
171
172 if (flags & DBUS_WATCH_READABLE)
173 condition |= G_IO_IN;
174 if (flags & DBUS_WATCH_WRITABLE)
175 condition |= G_IO_OUT;
176 if (flags & DBUS_WATCH_ERROR)
177 condition |= G_IO_ERR;
178 if (flags & DBUS_WATCH_HANGUP)
179 condition |= G_IO_HUP;
180
181 GPollFD *poll = &(((BusSource *)_source)->poll);
182 poll->fd = Watch::descriptor();
183 poll->events = condition;
184 poll->revents = 0;
185
186 g_source_add_poll(_source, poll);
187 g_source_attach(_source, _ctx);
188}
189
190 void Glib::BusWatch::_disable()
191{
192 if (!_source)
193 return;
194 GPollFD *poll = &(((BusSource *)_source)->poll);
195 g_source_remove_poll(_source, poll);
196 g_source_destroy(_source);
197 _source = NULL;
198}
199
200/*
201 * We need this on top of the IO handlers, because sometimes
202 * there are messages to dispatch queued up but no IO pending.
203 * (fixes also a previous problem of code not working in case of multiple dispatchers)
204*/
205 struct DispatcherSource
206{
207 GSource source;
208 Dispatcher *dispatcher;
209};
210
211
212 static gboolean dispatcher_prepare(GSource *source, gint *timeout)
213{
214 Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
215
216 *timeout = -1;
217
218 return dispatcher->has_something_to_dispatch() ? TRUE : FALSE;
219}
220
221 static gboolean dispatcher_check(GSource *source)
222{
223 return FALSE;
224}
225
226 static gboolean
227 dispatcher_dispatch(GSource *source,
228 GSourceFunc callback,
229 gpointer user_data)
230{
231 Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
232
233 dispatcher->dispatch_pending();
234 return TRUE;
235}
236
237 static const GSourceFuncs dispatcher_funcs =
238{
239 dispatcher_prepare,
240 dispatcher_check,
241 dispatcher_dispatch,
242 NULL
243};
244
245 Glib::BusDispatcher::BusDispatcher()
246 : _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL)
247{
248}
249
250 Glib::BusDispatcher::~BusDispatcher()
251{
252 if (_source)
253 {
254 GSource *temp = _source;
255 _source = NULL;
256
257 g_source_destroy(temp);
258 g_source_unref(temp);
259 }
260
261 if (_ctx)
262 g_main_context_unref(_ctx);
263}
264
265 void Glib::BusDispatcher::attach(GMainContext *ctx)
266{
267 g_assert(_ctx == NULL); // just to be sane
268
269 _ctx = ctx ? ctx : g_main_context_default();
270 g_main_context_ref(_ctx);
271
272 // create the source for dispatching messages
273 _source = g_source_new((GSourceFuncs *) &dispatcher_funcs,
274 sizeof(DispatcherSource));
275
276 ((DispatcherSource *)_source)->dispatcher = this;
277 g_source_attach(_source, _ctx);
278}
279
280 Timeout *Glib::BusDispatcher::add_timeout(Timeout::Internal *wi)
281{
282 Timeout *t = new Glib::BusTimeout(wi, _ctx, _priority);
283
284 debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on" : "off");
285
286 return t;
287}
288
289 void Glib::BusDispatcher::rem_timeout(Timeout *t)
290{
291 debug_log("glib: removed timeout %p", t);
292
293 delete t;
294}
295
296 Watch *Glib::BusDispatcher::add_watch(Watch::Internal *wi)
297{
298 Watch *w = new Glib::BusWatch(wi, _ctx, _priority);
299
300 debug_log("glib: added watch %p (%s) fd=%d flags=%d",
301 w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
302 );
303 return w;
304}
305
306 void Glib::BusDispatcher::rem_watch(Watch *w)
307{
308 debug_log("glib: removed watch %p", w);
309
310 delete w;
311}
312
313 void Glib::BusDispatcher::set_priority(int priority)
314{
315 _priority = priority;
316}
DBus::Dispatcher
Definition dispatcher.h:152
DBus::Dispatcher::dispatch_pending
void dispatch_pending()
Definition dispatcher.cpp:182
DBus::Dispatcher::has_something_to_dispatch
bool has_something_to_dispatch()
Definition dispatcher.cpp:166
DBus::Glib::BusDispatcher::_source
GSource * _source
Definition glib-integration.h:118
DBus::Glib::BusDispatcher::set_priority
void set_priority(int priority)
Definition glib-integration.cpp:313
DBus::Glib::BusDispatcher::rem_timeout
void rem_timeout(Timeout *)
Definition glib-integration.cpp:289
DBus::Glib::BusDispatcher::add_watch
Watch * add_watch(Watch::Internal *)
Definition glib-integration.cpp:296
DBus::Glib::BusDispatcher::attach
void attach(GMainContext *)
Definition glib-integration.cpp:265
DBus::Glib::BusDispatcher::_priority
int _priority
Definition glib-integration.h:117
DBus::Glib::BusDispatcher::_ctx
GMainContext * _ctx
Definition glib-integration.h:116
DBus::Glib::BusDispatcher::rem_watch
void rem_watch(Watch *)
Definition glib-integration.cpp:306
DBus::Glib::BusDispatcher::~BusDispatcher
~BusDispatcher()
Definition glib-integration.cpp:250
DBus::Glib::BusDispatcher::add_timeout
Timeout * add_timeout(Timeout::Internal *)
Definition glib-integration.cpp:280
DBus::Glib::BusDispatcher::BusDispatcher
BusDispatcher()
Definition glib-integration.cpp:245
DBus::Glib::BusTimeout
Definition glib-integration.h:42
DBus::Glib::BusTimeout::_disable
void _disable()
Definition glib-integration.cpp:73
DBus::Glib::BusTimeout::_source
GSource * _source
Definition glib-integration.h:61
DBus::Glib::BusTimeout::_enable
void _enable()
Definition glib-integration.cpp:62
DBus::Glib::BusTimeout::timeout_handler
static gboolean timeout_handler(gpointer)
Definition glib-integration.cpp:53
DBus::Glib::BusTimeout::toggle
void toggle()
Definition glib-integration.cpp:45
DBus::Glib::BusTimeout::_ctx
GMainContext * _ctx
Definition glib-integration.h:59
DBus::Glib::BusTimeout::BusTimeout
BusTimeout(Timeout::Internal *, GMainContext *, int)
Definition glib-integration.cpp:33
DBus::Glib::BusTimeout::~BusTimeout
~BusTimeout()
Definition glib-integration.cpp:40
DBus::Glib::BusTimeout::_priority
int _priority
Definition glib-integration.h:60
DBus::Glib::BusWatch
Definition glib-integration.h:67
DBus::Glib::BusWatch::_priority
int _priority
Definition glib-integration.h:85
DBus::Glib::BusWatch::_source
GSource * _source
Definition glib-integration.h:86
DBus::Glib::BusWatch::_disable
void _disable()
Definition glib-integration.cpp:190
DBus::Glib::BusWatch::_ctx
GMainContext * _ctx
Definition glib-integration.h:84
DBus::Glib::BusWatch::BusWatch
BusWatch(Watch::Internal *, GMainContext *, int)
Definition glib-integration.cpp:120
DBus::Glib::BusWatch::toggle
void toggle()
Definition glib-integration.cpp:132
DBus::Glib::BusWatch::_enable
void _enable()
Definition glib-integration.cpp:161
DBus::Glib::BusWatch::~BusWatch
~BusWatch()
Definition glib-integration.cpp:127
DBus::Glib::BusWatch::watch_handler
static gboolean watch_handler(gpointer)
Definition glib-integration.cpp:140
DBus::Timeout
Definition dispatcher.h:36
DBus::Timeout::enabled
bool enabled() const
Definition dispatcher.cpp:51
DBus::Timeout::interval
int interval() const
Gets the timeout interval.
Definition dispatcher.cpp:46
DBus::Timeout::handle
bool handle()
Calls the timeout handler for this timeout.
Definition dispatcher.cpp:56
DBus::Timeout::Timeout
Timeout(Internal *i)
DBus::Watch
Definition dispatcher.h:87
DBus::Watch::enabled
bool enabled() const
Definition dispatcher.cpp:91
DBus::Watch::flags
int flags() const
Gets flags from DBusWatchFlags indicating what conditions should be monitored on the file descriptor.
Definition dispatcher.cpp:86
DBus::Watch::Watch
Watch(Internal *i)
DBus::Watch::handle
bool handle(int flags)
Called to notify the D-Bus library when a previously-added watch is ready for reading or writing,...
Definition dispatcher.cpp:96
DBus::Watch::descriptor
int descriptor() const
A main loop could poll this descriptor to integrate dbus-c++.
Definition dispatcher.cpp:70
dispatcher_dispatch
static gboolean dispatcher_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
Definition glib-integration.cpp:227
watch_funcs
static GSourceFuncs watch_funcs
Definition glib-integration.cpp:112
watch_check
static gboolean watch_check(GSource *source)
Definition glib-integration.cpp:96
dispatcher_funcs
static const GSourceFuncs dispatcher_funcs
Definition glib-integration.cpp:237
dispatcher_check
static gboolean dispatcher_check(GSource *source)
Definition glib-integration.cpp:221
watch_prepare
static gboolean watch_prepare(GSource *source, gint *timeout)
Definition glib-integration.cpp:88
watch_dispatch
static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer data)
Definition glib-integration.cpp:104
dispatcher_prepare
static gboolean dispatcher_prepare(GSource *source, gint *timeout)
Definition glib-integration.cpp:212
glib-integration.h
DBus
Definition connection_p.h:42
DBus::debug_log
DXXAPI LogFunction debug_log
Definition debug.cpp:55
BusSource
Definition glib-integration.cpp:83
BusSource::source
GSource source
Definition glib-integration.cpp:84
BusSource::poll
GPollFD poll
Definition glib-integration.cpp:85
DispatcherSource
Definition glib-integration.cpp:206
DispatcherSource::dispatcher
Dispatcher * dispatcher
Definition glib-integration.cpp:208
DispatcherSource::source
GSource source
Definition glib-integration.cpp:207