2 /* $Id: main.cc 749 2008-12-10 14:23:33Z jjongsma $ */
4 /* Copyright (C) 2002 The gtkmm Development Team
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <glibmm/main.h>
22 #include <glibmm/exceptionhandler.h>
23 #include <glibmm/thread.h>
24 #include <glibmm/wrap.h>
25 #include <glibmm/iochannel.h>
35 class SourceConnectionNode
38 explicit inline SourceConnectionNode(const sigc::slot_base& slot);
40 static void* notify(void* data);
41 static void destroy_notify_callback(void* data);
43 inline void install(GSource* source);
44 inline sigc::slot_base* get_slot();
47 sigc::slot_base slot_;
52 SourceConnectionNode::SourceConnectionNode(const sigc::slot_base& slot)
57 slot_.set_parent(this, &SourceConnectionNode::notify);
60 void* SourceConnectionNode::notify(void* data)
62 SourceConnectionNode *const self = static_cast<SourceConnectionNode*>(data);
64 // if there is no object, this call was triggered from destroy_notify_handler(),
65 // because we set self->source_ to 0 there:
68 GSource* s = self->source_;
72 // Destroying the object triggers execution of destroy_notify_handler(),
73 // eiter immediately or later, so we leave that to do the deletion.
80 void SourceConnectionNode::destroy_notify_callback(void* data)
82 SourceConnectionNode *const self = static_cast<SourceConnectionNode*>(data);
86 // The GLib side is disconnected now, thus the GSource* is no longer valid.
94 void SourceConnectionNode::install(GSource* source)
100 sigc::slot_base* SourceConnectionNode::get_slot()
106 /* We use the callback data member of GSource to store both a pointer to our
107 * wrapper and a pointer to the connection node that is currently being used.
108 * The one and only SourceCallbackData object of a Glib::Source is constructed
109 * in the ctor of Glib::Source and destroyed after the GSource object when the
110 * reference counter of the GSource object reaches zero!
112 struct SourceCallbackData
114 explicit inline SourceCallbackData(Glib::Source* wrapper_);
116 void set_node(SourceConnectionNode* node_);
118 static void destroy_notify_callback(void* data);
120 Glib::Source* wrapper;
121 SourceConnectionNode* node;
125 SourceCallbackData::SourceCallbackData(Glib::Source* wrapper_)
131 void SourceCallbackData::set_node(SourceConnectionNode* node_)
134 SourceConnectionNode::destroy_notify_callback(node);
140 void SourceCallbackData::destroy_notify_callback(void* data)
142 SourceCallbackData *const self = static_cast<SourceCallbackData*>(data);
145 SourceConnectionNode::destroy_notify_callback(self->node);
148 Glib::Source::destroy_notify_callback(self->wrapper);
154 /* Retrieve the callback data from a wrapped GSource object.
156 static SourceCallbackData* glibmm_source_get_callback_data(GSource* source)
158 g_return_val_if_fail(source->callback_funcs->get != 0, 0);
163 // Retrieve the callback function and data.
164 (*source->callback_funcs->get)(source->callback_data, source, &func, &user_data);
166 return static_cast<SourceCallbackData*>(user_data);
169 /* Glib::Source doesn't use the callback function installed with
170 * g_source_set_callback(). Instead, it invokes the sigc++ slot
171 * directly from dispatch_vfunc(), which is both simpler and more
173 * For correctness, provide a pointer to this dummy callback rather
174 * than some random pointer. That also allows for sanity checks
175 * here as well as in Source::dispatch_vfunc().
177 static gboolean glibmm_dummy_source_callback(void*)
179 g_assert_not_reached();
183 /* Only used by SignalTimeout::connect() and SignalIdle::connect().
184 * These don't use Glib::Source, to avoid the unnecessary overhead
185 * of a completely unused wrapper object.
187 static gboolean glibmm_source_callback(void* data)
189 SourceConnectionNode *const conn_data = static_cast<SourceConnectionNode*>(data);
191 #ifdef GLIBMM_EXCEPTIONS_ENABLED
194 #endif //GLIBMM_EXCEPTIONS_ENABLED
195 // Recreate the specific slot from the generic slot node.
196 return (*static_cast<sigc::slot<bool>*>(conn_data->get_slot()))();
197 #ifdef GLIBMM_EXCEPTIONS_ENABLED
201 Glib::exception_handlers_invoke();
203 #endif //GLIBMM_EXCEPTIONS_ENABLED
207 static gboolean glibmm_iosource_callback(GIOChannel*, GIOCondition condition, void* data)
209 SourceCallbackData *const callback_data = static_cast<SourceCallbackData*>(data);
210 g_return_val_if_fail(callback_data->node != 0, 0);
212 #ifdef GLIBMM_EXCEPTIONS_ENABLED
215 #endif //GLIBMM_EXCEPTIONS_ENABLED
216 // Recreate the specific slot from the generic slot node.
217 return (*static_cast<sigc::slot<bool, Glib::IOCondition>*>(callback_data->node->get_slot()))
218 ((Glib::IOCondition) condition);
219 #ifdef GLIBMM_EXCEPTIONS_ENABLED
223 Glib::exception_handlers_invoke();
225 #endif //GLIBMM_EXCEPTIONS_ENABLED
229 /* Only used by SignalChildWatch::connect().
230 * These don't use Glib::Source, to avoid the unnecessary overhead
231 * of a completely unused wrapper object.
233 static gboolean glibmm_child_watch_callback(GPid pid, gint child_status, void* data)
235 SourceConnectionNode *const conn_data = static_cast<SourceConnectionNode*>(data);
237 #ifdef GLIBMM_EXCEPTIONS_ENABLED
239 #endif //GLIBMM_EXCEPTIONS_ENABLED
240 //Recreate the specific slot from the generic slot node.
241 (*static_cast<sigc::slot<void, GPid, int>*>(conn_data->get_slot()))(pid, child_status);
242 #ifdef GLIBMM_EXCEPTIONS_ENABLED
246 Glib::exception_handlers_invoke();
248 #endif //GLIBMM_EXCEPTIONS_ENABLED
252 } // anonymous namespace
258 /**** Glib::PollFD *********************************************************/
264 gobject_.revents = 0;
267 PollFD::PollFD(int fd)
271 gobject_.revents = 0;
274 PollFD::PollFD(int fd, IOCondition events)
277 gobject_.events = events;
278 gobject_.revents = 0;
282 /**** Glib::SignalTimeout **************************************************/
285 SignalTimeout::SignalTimeout(GMainContext* context)
290 /* Note that this is our equivalent of g_timeout_add(). */
291 sigc::connection SignalTimeout::connect(const sigc::slot<bool>& slot,
292 unsigned int interval, int priority)
294 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
295 const sigc::connection connection (*conn_node->get_slot());
297 GSource *const source = g_timeout_source_new(interval);
299 if(priority != G_PRIORITY_DEFAULT)
300 g_source_set_priority(source, priority);
302 g_source_set_callback(
303 source, &glibmm_source_callback, conn_node,
304 &SourceConnectionNode::destroy_notify_callback);
306 g_source_attach(source, context_);
307 g_source_unref(source); // GMainContext holds a reference
309 conn_node->install(source);
313 /* Note that this is our equivalent of g_timeout_add_seconds(). */
314 sigc::connection SignalTimeout::connect_seconds(const sigc::slot<bool>& slot,
315 unsigned int interval, int priority)
317 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
318 const sigc::connection connection (*conn_node->get_slot());
320 GSource *const source = g_timeout_source_new_seconds(interval);
322 if(priority != G_PRIORITY_DEFAULT)
323 g_source_set_priority(source, priority);
325 g_source_set_callback(
326 source, &glibmm_source_callback, conn_node,
327 &SourceConnectionNode::destroy_notify_callback);
329 g_source_attach(source, context_);
330 g_source_unref(source); // GMainContext holds a reference
332 conn_node->install(source);
336 SignalTimeout signal_timeout()
338 return SignalTimeout(0); // 0 means default context
342 /**** Glib::SignalIdle *****************************************************/
345 SignalIdle::SignalIdle(GMainContext* context)
350 sigc::connection SignalIdle::connect(const sigc::slot<bool>& slot, int priority)
352 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
353 const sigc::connection connection (*conn_node->get_slot());
355 GSource *const source = g_idle_source_new();
357 if(priority != G_PRIORITY_DEFAULT)
358 g_source_set_priority(source, priority);
360 g_source_set_callback(
361 source, &glibmm_source_callback, conn_node,
362 &SourceConnectionNode::destroy_notify_callback);
364 g_source_attach(source, context_);
365 g_source_unref(source); // GMainContext holds a reference
367 conn_node->install(source);
371 SignalIdle signal_idle()
373 return SignalIdle(0); // 0 means default context
377 /**** Glib::SignalIO *******************************************************/
380 SignalIO::SignalIO(GMainContext* context)
385 sigc::connection SignalIO::connect(const sigc::slot<bool,IOCondition>& slot,
386 int fd, IOCondition condition, int priority)
388 const Glib::RefPtr<IOSource> source = IOSource::create(fd, condition);
390 if(priority != G_PRIORITY_DEFAULT)
391 source->set_priority(priority);
393 const sigc::connection connection = source->connect(slot);
395 g_source_attach(source->gobj(), context_);
400 sigc::connection SignalIO::connect(const sigc::slot<bool,IOCondition>& slot,
401 const Glib::RefPtr<IOChannel>& channel,
402 IOCondition condition, int priority)
404 const Glib::RefPtr<IOSource> source = IOSource::create(channel, condition);
406 if(priority != G_PRIORITY_DEFAULT)
407 source->set_priority(priority);
409 const sigc::connection connection = source->connect(slot);
411 g_source_attach(source->gobj(), context_);
418 return SignalIO(0); // 0 means default context
421 /**** Glib::SignalChildWatch **************************************************/
424 SignalChildWatch::SignalChildWatch(GMainContext* context)
429 sigc::connection SignalChildWatch::connect(const sigc::slot<void, GPid, int>& slot,
430 GPid pid, int priority)
432 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
433 const sigc::connection connection(*conn_node->get_slot());
435 GSource *const source = g_child_watch_source_new(pid);
437 if(priority != G_PRIORITY_DEFAULT)
438 g_source_set_priority(source, priority);
440 g_source_set_callback(
441 source, (GSourceFunc)&glibmm_child_watch_callback, conn_node,
442 &SourceConnectionNode::destroy_notify_callback);
444 g_source_attach(source, context_);
445 g_source_unref(source); // GMainContext holds a reference
447 conn_node->install(source);
451 SignalChildWatch signal_child_watch()
453 return SignalChildWatch(0); // 0 means default context
456 /**** Glib::MainContext ****************************************************/
459 Glib::RefPtr<MainContext> MainContext::create()
461 return Glib::RefPtr<MainContext>(reinterpret_cast<MainContext*>(g_main_context_new()));
465 Glib::RefPtr<MainContext> MainContext::get_default()
467 return Glib::wrap(g_main_context_default(), true);
470 bool MainContext::iteration(bool may_block)
472 return g_main_context_iteration(gobj(), may_block);
475 bool MainContext::pending()
477 return g_main_context_pending(gobj());
480 void MainContext::wakeup()
482 g_main_context_wakeup(gobj());
485 bool MainContext::acquire()
487 return g_main_context_acquire(gobj());
490 bool MainContext::wait(Glib::Cond& cond, Glib::Mutex& mutex)
492 return g_main_context_wait(gobj(), cond.gobj(), mutex.gobj());
495 void MainContext::release()
497 g_main_context_release(gobj());
500 bool MainContext::prepare(int& priority)
502 return g_main_context_prepare(gobj(), &priority);
505 bool MainContext::prepare()
507 return g_main_context_prepare(gobj(), 0);
510 void MainContext::query(int max_priority, int& timeout, std::vector<PollFD>& fds)
513 fds.resize(8); // rather bogus number, but better than 0
517 const int size_before = fds.size();
518 const int size_needed = g_main_context_query(
519 gobj(), max_priority, &timeout, reinterpret_cast<GPollFD*>(&fds.front()), size_before);
521 fds.resize(size_needed);
523 if(size_needed <= size_before)
528 bool MainContext::check(int max_priority, std::vector<PollFD>& fds)
531 return g_main_context_check(gobj(), max_priority, reinterpret_cast<GPollFD*>(&fds.front()), fds.size());
536 void MainContext::dispatch()
538 g_main_context_dispatch(gobj());
541 void MainContext::set_poll_func(GPollFunc poll_func)
543 g_main_context_set_poll_func(gobj(), poll_func);
546 GPollFunc MainContext::get_poll_func()
548 return g_main_context_get_poll_func(gobj());
551 void MainContext::add_poll(PollFD& fd, int priority)
553 g_main_context_add_poll(gobj(), fd.gobj(), priority);
556 void MainContext::remove_poll(PollFD& fd)
558 g_main_context_remove_poll(gobj(), fd.gobj());
561 SignalTimeout MainContext::signal_timeout()
563 return SignalTimeout(gobj());
566 SignalIdle MainContext::signal_idle()
568 return SignalIdle(gobj());
571 SignalIO MainContext::signal_io()
573 return SignalIO(gobj());
576 SignalChildWatch MainContext::signal_child_watch()
578 return SignalChildWatch(gobj());
581 void MainContext::reference() const
583 g_main_context_ref(reinterpret_cast<GMainContext*>(const_cast<MainContext*>(this)));
586 void MainContext::unreference() const
588 g_main_context_unref(reinterpret_cast<GMainContext*>(const_cast<MainContext*>(this)));
591 GMainContext* MainContext::gobj()
593 return reinterpret_cast<GMainContext*>(this);
596 const GMainContext* MainContext::gobj() const
598 return reinterpret_cast<const GMainContext*>(this);
601 GMainContext* MainContext::gobj_copy() const
604 return const_cast<GMainContext*>(gobj());
607 Glib::RefPtr<MainContext> wrap(GMainContext* gobject, bool take_copy)
609 if(take_copy && gobject)
610 g_main_context_ref(gobject);
612 return Glib::RefPtr<MainContext>(reinterpret_cast<MainContext*>(gobject));
616 /**** Glib::MainLoop *******************************************************/
618 Glib::RefPtr<MainLoop> MainLoop::create(bool is_running)
620 return Glib::RefPtr<MainLoop>(
621 reinterpret_cast<MainLoop*>(g_main_loop_new(0, is_running)));
624 Glib::RefPtr<MainLoop> MainLoop::create(const Glib::RefPtr<MainContext>& context, bool is_running)
626 return Glib::RefPtr<MainLoop>(
627 reinterpret_cast<MainLoop*>(g_main_loop_new(Glib::unwrap(context), is_running)));
632 g_main_loop_run(gobj());
635 void MainLoop::quit()
637 g_main_loop_quit(gobj());
640 bool MainLoop::is_running()
642 return g_main_loop_is_running(gobj());
645 Glib::RefPtr<MainContext> MainLoop::get_context()
647 return Glib::wrap(g_main_loop_get_context(gobj()), true);
651 int MainLoop::depth()
653 return g_main_depth();
656 void MainLoop::reference() const
658 g_main_loop_ref(reinterpret_cast<GMainLoop*>(const_cast<MainLoop*>(this)));
661 void MainLoop::unreference() const
663 g_main_loop_unref(reinterpret_cast<GMainLoop*>(const_cast<MainLoop*>(this)));
666 GMainLoop* MainLoop::gobj()
668 return reinterpret_cast<GMainLoop*>(this);
671 const GMainLoop* MainLoop::gobj() const
673 return reinterpret_cast<const GMainLoop*>(this);
676 GMainLoop* MainLoop::gobj_copy() const
679 return const_cast<GMainLoop*>(gobj());
682 Glib::RefPtr<MainLoop> wrap(GMainLoop* gobject, bool take_copy)
684 if(take_copy && gobject)
685 g_main_loop_ref(gobject);
687 return Glib::RefPtr<MainLoop>(reinterpret_cast<MainLoop*>(gobject));
691 /**** Glib::Source *********************************************************/
694 const GSourceFuncs Source::vfunc_table_ =
696 &Source::prepare_vfunc,
697 &Source::check_vfunc,
698 &Source::dispatch_vfunc,
699 0, // finalize_vfunc // We can't use finalize_vfunc because there is no way
700 // to store a pointer to our wrapper anywhere in GSource so
701 // that it persists until finalize_vfunc would be called from here.
702 0, // closure_callback
703 0, // closure_marshal
706 unsigned int Source::attach(const Glib::RefPtr<MainContext>& context)
708 return g_source_attach(gobject_, Glib::unwrap(context));
711 unsigned int Source::attach()
713 return g_source_attach(gobject_, 0);
716 void Source::destroy()
718 g_source_destroy(gobject_);
721 void Source::set_priority(int priority)
723 g_source_set_priority(gobject_, priority);
726 int Source::get_priority() const
728 return g_source_get_priority(gobject_);
731 void Source::set_can_recurse(bool can_recurse)
733 g_source_set_can_recurse(gobject_, can_recurse);
736 bool Source::get_can_recurse() const
738 return g_source_get_can_recurse(gobject_);
741 unsigned int Source::get_id() const
743 return g_source_get_id(gobject_);
746 Glib::RefPtr<MainContext> Source::get_context()
748 return Glib::wrap(g_source_get_context(gobject_), true);
751 GSource* Source::gobj_copy() const
753 return g_source_ref(gobject_);
756 void Source::reference() const
758 g_source_ref(gobject_);
761 void Source::unreference() const
763 g_source_unref(gobject_);
768 gobject_ (g_source_new(const_cast<GSourceFuncs*>(&vfunc_table_), sizeof(GSource)))
770 g_source_set_callback(
771 gobject_, &glibmm_dummy_source_callback,
772 new SourceCallbackData(this), // our persistant callback data object
773 &SourceCallbackData::destroy_notify_callback);
776 Source::Source(GSource* cast_item, GSourceFunc callback_func)
780 g_source_set_callback(
781 gobject_, callback_func,
782 new SourceCallbackData(this), // our persistant callback data object
783 &SourceCallbackData::destroy_notify_callback);
788 // The dtor should be invoked by destroy_notify_callback() only, which clears
789 // gobject_ before deleting. However, we might also get to this point if
790 // a derived ctor threw an exception, and then we need to unref manually.
794 SourceCallbackData *const data = glibmm_source_get_callback_data(gobject_);
797 GSource *const tmp_gobject = gobject_;
800 g_source_unref(tmp_gobject);
804 sigc::connection Source::connect_generic(const sigc::slot_base& slot)
806 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
807 const sigc::connection connection (*conn_node->get_slot());
809 // Don't override the callback data. Reuse the existing one
810 // calling SourceCallbackData::set_node() to register conn_node.
811 SourceCallbackData *const data = glibmm_source_get_callback_data(gobject_);
812 data->set_node(conn_node);
814 conn_node->install(gobject_);
818 void Source::add_poll(Glib::PollFD& poll_fd)
820 g_source_add_poll(gobject_, poll_fd.gobj());
823 void Source::remove_poll(Glib::PollFD& poll_fd)
825 g_source_remove_poll(gobject_, poll_fd.gobj());
828 void Source::get_current_time(Glib::TimeVal& current_time)
830 g_source_get_current_time(gobject_, ¤t_time);
834 Source* Source::get_wrapper(GSource* source)
836 SourceCallbackData *const data = glibmm_source_get_callback_data(source);
837 return data->wrapper;
841 gboolean Source::prepare_vfunc(GSource* source, int* timeout)
843 #ifdef GLIBMM_EXCEPTIONS_ENABLED
846 #endif //GLIBMM_EXCEPTIONS_ENABLED
847 Source *const self = get_wrapper(source);
848 return self->prepare(*timeout);
849 #ifdef GLIBMM_EXCEPTIONS_ENABLED
853 Glib::exception_handlers_invoke();
855 #endif //GLIBMM_EXCEPTIONS_ENABLED
861 gboolean Source::check_vfunc(GSource* source)
863 #ifdef GLIBMM_EXCEPTIONS_ENABLED
866 #endif //GLIBMM_EXCEPTIONS_ENABLED
867 Source *const self = get_wrapper(source);
868 return self->check();
869 #ifdef GLIBMM_EXCEPTIONS_ENABLED
873 Glib::exception_handlers_invoke();
875 #endif //GLIBMM_EXCEPTIONS_ENABLED
881 gboolean Source::dispatch_vfunc(GSource*, GSourceFunc callback, void* user_data)
883 SourceCallbackData *const callback_data = static_cast<SourceCallbackData*>(user_data);
885 g_return_val_if_fail(callback == &glibmm_dummy_source_callback, 0);
886 g_return_val_if_fail(callback_data != 0 && callback_data->node != 0, 0);
888 #ifdef GLIBMM_EXCEPTIONS_ENABLED
891 #endif //GLIBMM_EXCEPTIONS_ENABLED
892 Source *const self = callback_data->wrapper;
893 return self->dispatch(callback_data->node->get_slot());
894 #ifdef GLIBMM_EXCEPTIONS_ENABLED
898 Glib::exception_handlers_invoke();
900 #endif //GLIBMM_EXCEPTIONS_ENABLED
905 void Source::destroy_notify_callback(void* data)
909 Source *const self = static_cast<Source*>(data);
911 // gobject_ is already invalid at this point.
914 // No exception checking: if the dtor throws, you're out of luck anyway.
920 /**** Glib::TimeoutSource **************************************************/
923 Glib::RefPtr<TimeoutSource> TimeoutSource::create(unsigned int interval)
925 return Glib::RefPtr<TimeoutSource>(new TimeoutSource(interval));
928 sigc::connection TimeoutSource::connect(const sigc::slot<bool>& slot)
930 return connect_generic(slot);
933 TimeoutSource::TimeoutSource(unsigned int interval)
937 expiration_.assign_current_time();
938 expiration_.add_milliseconds(std::min<unsigned long>(G_MAXLONG, interval_));
941 TimeoutSource::~TimeoutSource()
944 bool TimeoutSource::prepare(int& timeout)
946 Glib::TimeVal current_time;
947 get_current_time(current_time);
949 Glib::TimeVal remaining = expiration_;
950 remaining.subtract(current_time);
952 if(remaining.negative())
959 const unsigned long milliseconds =
960 static_cast<unsigned long>(remaining.tv_sec) * 1000U +
961 static_cast<unsigned long>(remaining.tv_usec) / 1000U;
963 // Set remaining milliseconds.
964 timeout = std::min<unsigned long>(G_MAXINT, milliseconds);
966 // Check if the system time has been set backwards. (remaining > interval)
967 remaining.add_milliseconds(- std::min<unsigned long>(G_MAXLONG, interval_) - 1);
968 if(!remaining.negative())
970 // Oh well. Reset the expiration time to now + interval;
971 // this at least avoids hanging for long periods of time.
972 expiration_ = current_time;
973 expiration_.add_milliseconds(interval_);
974 timeout = std::min<unsigned int>(G_MAXINT, interval_);
978 return (timeout == 0);
981 bool TimeoutSource::check()
983 Glib::TimeVal current_time;
984 get_current_time(current_time);
986 return (expiration_ <= current_time);
989 bool TimeoutSource::dispatch(sigc::slot_base* slot)
991 const bool again = (*static_cast<sigc::slot<bool>*>(slot))();
995 get_current_time(expiration_);
996 expiration_.add_milliseconds(std::min<unsigned long>(G_MAXLONG, interval_));
1003 /**** Glib::IdleSource *****************************************************/
1006 Glib::RefPtr<IdleSource> IdleSource::create()
1008 return Glib::RefPtr<IdleSource>(new IdleSource());
1011 sigc::connection IdleSource::connect(const sigc::slot<bool>& slot)
1013 return connect_generic(slot);
1016 IdleSource::IdleSource()
1018 set_priority(PRIORITY_DEFAULT_IDLE);
1021 IdleSource::~IdleSource()
1024 bool IdleSource::prepare(int& timeout)
1030 bool IdleSource::check()
1035 bool IdleSource::dispatch(sigc::slot_base* slot)
1037 return (*static_cast<sigc::slot<bool>*>(slot))();
1041 /**** Glib::IOSource *******************************************************/
1044 Glib::RefPtr<IOSource> IOSource::create(int fd, IOCondition condition)
1046 return Glib::RefPtr<IOSource>(new IOSource(fd, condition));
1049 Glib::RefPtr<IOSource> IOSource::create(const Glib::RefPtr<IOChannel>& channel, IOCondition condition)
1051 return Glib::RefPtr<IOSource>(new IOSource(channel, condition));
1054 sigc::connection IOSource::connect(const sigc::slot<bool,IOCondition>& slot)
1056 return connect_generic(slot);
1059 IOSource::IOSource(int fd, IOCondition condition)
1061 poll_fd_ (fd, condition)
1066 IOSource::IOSource(const Glib::RefPtr<IOChannel>& channel, IOCondition condition)
1068 Source(g_io_create_watch(channel->gobj(), (GIOCondition) condition),
1069 (GSourceFunc) &glibmm_iosource_callback)
1072 IOSource::~IOSource()
1075 bool IOSource::prepare(int& timeout)
1081 bool IOSource::check()
1083 return ((poll_fd_.get_revents() & poll_fd_.get_events()) != 0);
1086 bool IOSource::dispatch(sigc::slot_base* slot)
1088 return (*static_cast<sigc::slot<bool,IOCondition>*>(slot))
1089 (poll_fd_.get_revents());