2 /* $Id: main.cc 420 2007-06-22 15:29:58Z murrayc $ */
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>
36 class SourceConnectionNode
39 explicit inline SourceConnectionNode(const sigc::slot_base& slot);
41 static void* notify(void* data);
42 static void destroy_notify_callback(void* data);
44 inline void install(GSource* source);
45 inline sigc::slot_base* get_slot();
48 sigc::slot_base slot_;
53 SourceConnectionNode::SourceConnectionNode(const sigc::slot_base& slot)
58 slot_.set_parent(this, &SourceConnectionNode::notify);
61 void* SourceConnectionNode::notify(void* data)
63 SourceConnectionNode *const self = static_cast<SourceConnectionNode*>(data);
65 // if there is no object, this call was triggered from destroy_notify_handler(),
66 // because we set self->source_ to 0 there:
69 GSource* s = self->source_;
73 // Destroying the object triggers execution of destroy_notify_handler(),
74 // eiter immediately or later, so we leave that to do the deletion.
81 void SourceConnectionNode::destroy_notify_callback(void* data)
83 SourceConnectionNode *const self = static_cast<SourceConnectionNode*>(data);
87 // The GLib side is disconnected now, thus the GSource* is no longer valid.
95 void SourceConnectionNode::install(GSource* source)
101 sigc::slot_base* SourceConnectionNode::get_slot()
107 /* We use the callback data member of GSource to store both a pointer to our
108 * wrapper and a pointer to the connection node that is currently being used.
109 * The one and only SourceCallbackData object of a Glib::Source is constructed
110 * in the ctor of Glib::Source and destroyed after the GSource object when the
111 * reference counter of the GSource object reaches zero!
113 struct SourceCallbackData
115 explicit inline SourceCallbackData(Glib::Source* wrapper_);
117 void set_node(SourceConnectionNode* node_);
119 static void destroy_notify_callback(void* data);
121 Glib::Source* wrapper;
122 SourceConnectionNode* node;
126 SourceCallbackData::SourceCallbackData(Glib::Source* wrapper_)
132 void SourceCallbackData::set_node(SourceConnectionNode* node_)
135 SourceConnectionNode::destroy_notify_callback(node);
141 void SourceCallbackData::destroy_notify_callback(void* data)
143 SourceCallbackData *const self = static_cast<SourceCallbackData*>(data);
146 SourceConnectionNode::destroy_notify_callback(self->node);
149 Glib::Source::destroy_notify_callback(self->wrapper);
155 /* Retrieve the callback data from a wrapped GSource object.
157 static SourceCallbackData* glibmm_source_get_callback_data(GSource* source)
159 g_return_val_if_fail(source->callback_funcs->get != 0, 0);
164 // Retrieve the callback function and data.
165 (*source->callback_funcs->get)(source->callback_data, source, &func, &user_data);
167 return static_cast<SourceCallbackData*>(user_data);
170 /* Glib::Source doesn't use the callback function installed with
171 * g_source_set_callback(). Instead, it invokes the sigc++ slot
172 * directly from dispatch_vfunc(), which is both simpler and more
174 * For correctness, provide a pointer to this dummy callback rather
175 * than some random pointer. That also allows for sanity checks
176 * here as well as in Source::dispatch_vfunc().
178 static gboolean glibmm_dummy_source_callback(void*)
180 g_assert_not_reached();
184 /* Only used by SignalTimeout::connect() and SignalIdle::connect().
185 * These don't use Glib::Source, to avoid the unnecessary overhead
186 * of a completely unused wrapper object.
188 static gboolean glibmm_source_callback(void* data)
190 SourceConnectionNode *const conn_data = static_cast<SourceConnectionNode*>(data);
192 #ifdef GLIBMM_EXCEPTIONS_ENABLED
195 #endif //GLIBMM_EXCEPTIONS_ENABLED
196 // Recreate the specific slot from the generic slot node.
197 return (*static_cast<sigc::slot<bool>*>(conn_data->get_slot()))();
198 #ifdef GLIBMM_EXCEPTIONS_ENABLED
202 Glib::exception_handlers_invoke();
204 #endif //GLIBMM_EXCEPTIONS_ENABLED
208 static gboolean glibmm_iosource_callback(GIOChannel*, GIOCondition condition, void* data)
210 SourceCallbackData *const callback_data = static_cast<SourceCallbackData*>(data);
211 g_return_val_if_fail(callback_data->node != 0, 0);
213 #ifdef GLIBMM_EXCEPTIONS_ENABLED
216 #endif //GLIBMM_EXCEPTIONS_ENABLED
217 // Recreate the specific slot from the generic slot node.
218 return (*static_cast<sigc::slot<bool, Glib::IOCondition>*>(callback_data->node->get_slot()))
219 ((Glib::IOCondition) condition);
220 #ifdef GLIBMM_EXCEPTIONS_ENABLED
224 Glib::exception_handlers_invoke();
226 #endif //GLIBMM_EXCEPTIONS_ENABLED
230 /* Only used by SignalChildWatch::connect().
231 * These don't use Glib::Source, to avoid the unnecessary overhead
232 * of a completely unused wrapper object.
234 static gboolean glibmm_child_watch_callback(GPid pid, gint child_status, void* data)
236 SourceConnectionNode *const conn_data = static_cast<SourceConnectionNode*>(data);
238 #ifdef GLIBMM_EXCEPTIONS_ENABLED
240 #endif //GLIBMM_EXCEPTIONS_ENABLED
241 //Recreate the specific slot from the generic slot node.
242 (*static_cast<sigc::slot<void, GPid, int>*>(conn_data->get_slot()))(pid, child_status);
243 #ifdef GLIBMM_EXCEPTIONS_ENABLED
247 Glib::exception_handlers_invoke();
249 #endif //GLIBMM_EXCEPTIONS_ENABLED
253 } // anonymous namespace
259 /**** Glib::PollFD *********************************************************/
265 gobject_.revents = 0;
268 PollFD::PollFD(int fd)
272 gobject_.revents = 0;
275 PollFD::PollFD(int fd, IOCondition events)
278 gobject_.events = events;
279 gobject_.revents = 0;
283 /**** Glib::SignalTimeout **************************************************/
286 SignalTimeout::SignalTimeout(GMainContext* context)
291 /* Note that this is our equivalent of g_timeout_add(). */
292 sigc::connection SignalTimeout::connect(const sigc::slot<bool>& slot,
293 unsigned int interval, int priority)
295 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
296 const sigc::connection connection (*conn_node->get_slot());
298 GSource *const source = g_timeout_source_new(interval);
300 if(priority != G_PRIORITY_DEFAULT)
301 g_source_set_priority(source, priority);
303 g_source_set_callback(
304 source, &glibmm_source_callback, conn_node,
305 &SourceConnectionNode::destroy_notify_callback);
307 g_source_attach(source, context_);
308 g_source_unref(source); // GMainContext holds a reference
310 conn_node->install(source);
314 /* Note that this is our equivalent of g_timeout_add_seconds(). */
315 sigc::connection SignalTimeout::connect_seconds(const sigc::slot<bool>& slot,
316 unsigned int interval, int priority)
318 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
319 const sigc::connection connection (*conn_node->get_slot());
321 GSource *const source = g_timeout_source_new_seconds(interval);
323 if(priority != G_PRIORITY_DEFAULT)
324 g_source_set_priority(source, priority);
326 g_source_set_callback(
327 source, &glibmm_source_callback, conn_node,
328 &SourceConnectionNode::destroy_notify_callback);
330 g_source_attach(source, context_);
331 g_source_unref(source); // GMainContext holds a reference
333 conn_node->install(source);
337 SignalTimeout signal_timeout()
339 return SignalTimeout(0); // 0 means default context
343 /**** Glib::SignalIdle *****************************************************/
346 SignalIdle::SignalIdle(GMainContext* context)
351 sigc::connection SignalIdle::connect(const sigc::slot<bool>& slot, int priority)
353 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
354 const sigc::connection connection (*conn_node->get_slot());
356 GSource *const source = g_idle_source_new();
358 if(priority != G_PRIORITY_DEFAULT)
359 g_source_set_priority(source, priority);
361 g_source_set_callback(
362 source, &glibmm_source_callback, conn_node,
363 &SourceConnectionNode::destroy_notify_callback);
365 g_source_attach(source, context_);
366 g_source_unref(source); // GMainContext holds a reference
368 conn_node->install(source);
372 SignalIdle signal_idle()
374 return SignalIdle(0); // 0 means default context
378 /**** Glib::SignalIO *******************************************************/
381 SignalIO::SignalIO(GMainContext* context)
386 sigc::connection SignalIO::connect(const sigc::slot<bool,IOCondition>& slot,
387 int fd, IOCondition condition, int priority)
389 const Glib::RefPtr<IOSource> source = IOSource::create(fd, condition);
391 if(priority != G_PRIORITY_DEFAULT)
392 source->set_priority(priority);
394 const sigc::connection connection = source->connect(slot);
396 g_source_attach(source->gobj(), context_);
401 sigc::connection SignalIO::connect(const sigc::slot<bool,IOCondition>& slot,
402 const Glib::RefPtr<IOChannel>& channel,
403 IOCondition condition, int priority)
405 const Glib::RefPtr<IOSource> source = IOSource::create(channel, condition);
407 if(priority != G_PRIORITY_DEFAULT)
408 source->set_priority(priority);
410 const sigc::connection connection = source->connect(slot);
412 g_source_attach(source->gobj(), context_);
419 return SignalIO(0); // 0 means default context
422 /**** Glib::SignalChildWatch **************************************************/
425 SignalChildWatch::SignalChildWatch(GMainContext* context)
430 sigc::connection SignalChildWatch::connect(const sigc::slot<void, GPid, int>& slot,
431 GPid pid, int priority)
433 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
434 const sigc::connection connection(*conn_node->get_slot());
436 GSource *const source = g_child_watch_source_new(pid);
438 if(priority != G_PRIORITY_DEFAULT)
439 g_source_set_priority(source, priority);
441 g_source_set_callback(
442 source, (GSourceFunc)&glibmm_child_watch_callback, conn_node,
443 &SourceConnectionNode::destroy_notify_callback);
445 g_source_attach(source, context_);
446 g_source_unref(source); // GMainContext holds a reference
448 conn_node->install(source);
452 SignalChildWatch signal_child_watch()
454 return SignalChildWatch(0); // 0 means default context
457 /**** Glib::MainContext ****************************************************/
460 Glib::RefPtr<MainContext> MainContext::create()
462 return Glib::RefPtr<MainContext>(reinterpret_cast<MainContext*>(g_main_context_new()));
466 Glib::RefPtr<MainContext> MainContext::get_default()
468 return Glib::wrap(g_main_context_default(), true);
471 bool MainContext::iteration(bool may_block)
473 return g_main_context_iteration(gobj(), may_block);
476 bool MainContext::pending()
478 return g_main_context_pending(gobj());
481 void MainContext::wakeup()
483 g_main_context_wakeup(gobj());
486 bool MainContext::acquire()
488 return g_main_context_acquire(gobj());
491 bool MainContext::wait(Glib::Cond& cond, Glib::Mutex& mutex)
493 return g_main_context_wait(gobj(), cond.gobj(), mutex.gobj());
496 void MainContext::release()
498 g_main_context_release(gobj());
501 bool MainContext::prepare(int& priority)
503 return g_main_context_prepare(gobj(), &priority);
506 bool MainContext::prepare()
508 return g_main_context_prepare(gobj(), 0);
511 void MainContext::query(int max_priority, int& timeout, std::vector<PollFD>& fds)
514 fds.resize(8); // rather bogus number, but better than 0
518 const int size_before = fds.size();
519 const int size_needed = g_main_context_query(
520 gobj(), max_priority, &timeout, reinterpret_cast<GPollFD*>(&fds.front()), size_before);
522 fds.resize(size_needed);
524 if(size_needed <= size_before)
529 bool MainContext::check(int max_priority, std::vector<PollFD>& fds)
532 return g_main_context_check(gobj(), max_priority, reinterpret_cast<GPollFD*>(&fds.front()), fds.size());
537 void MainContext::dispatch()
539 g_main_context_dispatch(gobj());
542 void MainContext::set_poll_func(GPollFunc poll_func)
544 g_main_context_set_poll_func(gobj(), poll_func);
547 GPollFunc MainContext::get_poll_func()
549 return g_main_context_get_poll_func(gobj());
552 void MainContext::add_poll(PollFD& fd, int priority)
554 g_main_context_add_poll(gobj(), fd.gobj(), priority);
557 void MainContext::remove_poll(PollFD& fd)
559 g_main_context_remove_poll(gobj(), fd.gobj());
562 SignalTimeout MainContext::signal_timeout()
564 return SignalTimeout(gobj());
567 SignalIdle MainContext::signal_idle()
569 return SignalIdle(gobj());
572 SignalIO MainContext::signal_io()
574 return SignalIO(gobj());
577 SignalChildWatch MainContext::signal_child_watch()
579 return SignalChildWatch(gobj());
582 void MainContext::reference() const
584 g_main_context_ref(reinterpret_cast<GMainContext*>(const_cast<MainContext*>(this)));
587 void MainContext::unreference() const
589 g_main_context_unref(reinterpret_cast<GMainContext*>(const_cast<MainContext*>(this)));
592 GMainContext* MainContext::gobj()
594 return reinterpret_cast<GMainContext*>(this);
597 const GMainContext* MainContext::gobj() const
599 return reinterpret_cast<const GMainContext*>(this);
602 GMainContext* MainContext::gobj_copy() const
605 return const_cast<GMainContext*>(gobj());
608 Glib::RefPtr<MainContext> wrap(GMainContext* gobject, bool take_copy)
610 if(take_copy && gobject)
611 g_main_context_ref(gobject);
613 return Glib::RefPtr<MainContext>(reinterpret_cast<MainContext*>(gobject));
617 /**** Glib::MainLoop *******************************************************/
619 Glib::RefPtr<MainLoop> MainLoop::create(bool is_running)
621 return Glib::RefPtr<MainLoop>(
622 reinterpret_cast<MainLoop*>(g_main_loop_new(0, is_running)));
625 Glib::RefPtr<MainLoop> MainLoop::create(const Glib::RefPtr<MainContext>& context, bool is_running)
627 return Glib::RefPtr<MainLoop>(
628 reinterpret_cast<MainLoop*>(g_main_loop_new(Glib::unwrap(context), is_running)));
633 g_main_loop_run(gobj());
636 void MainLoop::quit()
638 g_main_loop_quit(gobj());
641 bool MainLoop::is_running()
643 return g_main_loop_is_running(gobj());
646 Glib::RefPtr<MainContext> MainLoop::get_context()
648 return Glib::wrap(g_main_loop_get_context(gobj()), true);
652 int MainLoop::depth()
654 return g_main_depth();
657 void MainLoop::reference() const
659 g_main_loop_ref(reinterpret_cast<GMainLoop*>(const_cast<MainLoop*>(this)));
662 void MainLoop::unreference() const
664 g_main_loop_unref(reinterpret_cast<GMainLoop*>(const_cast<MainLoop*>(this)));
667 GMainLoop* MainLoop::gobj()
669 return reinterpret_cast<GMainLoop*>(this);
672 const GMainLoop* MainLoop::gobj() const
674 return reinterpret_cast<const GMainLoop*>(this);
677 GMainLoop* MainLoop::gobj_copy() const
680 return const_cast<GMainLoop*>(gobj());
683 Glib::RefPtr<MainLoop> wrap(GMainLoop* gobject, bool take_copy)
685 if(take_copy && gobject)
686 g_main_loop_ref(gobject);
688 return Glib::RefPtr<MainLoop>(reinterpret_cast<MainLoop*>(gobject));
692 /**** Glib::Source *********************************************************/
695 const GSourceFuncs Source::vfunc_table_ =
697 &Source::prepare_vfunc,
698 &Source::check_vfunc,
699 &Source::dispatch_vfunc,
700 0, // finalize_vfunc // We can't use finalize_vfunc because there is no way
701 // to store a pointer to our wrapper anywhere in GSource so
702 // that it persists until finalize_vfunc would be called from here.
703 0, // closure_callback
704 0, // closure_marshal
707 unsigned int Source::attach(const Glib::RefPtr<MainContext>& context)
709 return g_source_attach(gobject_, Glib::unwrap(context));
712 unsigned int Source::attach()
714 return g_source_attach(gobject_, 0);
717 void Source::destroy()
719 g_source_destroy(gobject_);
722 void Source::set_priority(int priority)
724 g_source_set_priority(gobject_, priority);
727 int Source::get_priority() const
729 return g_source_get_priority(gobject_);
732 void Source::set_can_recurse(bool can_recurse)
734 g_source_set_can_recurse(gobject_, can_recurse);
737 bool Source::get_can_recurse() const
739 return g_source_get_can_recurse(gobject_);
742 unsigned int Source::get_id() const
744 return g_source_get_id(gobject_);
747 Glib::RefPtr<MainContext> Source::get_context()
749 return Glib::wrap(g_source_get_context(gobject_), true);
752 GSource* Source::gobj_copy() const
754 return g_source_ref(gobject_);
757 void Source::reference() const
759 g_source_ref(gobject_);
762 void Source::unreference() const
764 g_source_unref(gobject_);
769 gobject_ (g_source_new(const_cast<GSourceFuncs*>(&vfunc_table_), sizeof(GSource)))
771 g_source_set_callback(
772 gobject_, &glibmm_dummy_source_callback,
773 new SourceCallbackData(this), // our persistant callback data object
774 &SourceCallbackData::destroy_notify_callback);
777 Source::Source(GSource* cast_item, GSourceFunc callback_func)
781 g_source_set_callback(
782 gobject_, callback_func,
783 new SourceCallbackData(this), // our persistant callback data object
784 &SourceCallbackData::destroy_notify_callback);
789 // The dtor should be invoked by destroy_notify_callback() only, which clears
790 // gobject_ before deleting. However, we might also get to this point if
791 // a derived ctor threw an exception, and then we need to unref manually.
795 SourceCallbackData *const data = glibmm_source_get_callback_data(gobject_);
798 GSource *const tmp_gobject = gobject_;
801 g_source_unref(tmp_gobject);
805 sigc::connection Source::connect_generic(const sigc::slot_base& slot)
807 SourceConnectionNode *const conn_node = new SourceConnectionNode(slot);
808 const sigc::connection connection (*conn_node->get_slot());
810 // Don't override the callback data. Reuse the existing one
811 // calling SourceCallbackData::set_node() to register conn_node.
812 SourceCallbackData *const data = glibmm_source_get_callback_data(gobject_);
813 data->set_node(conn_node);
815 conn_node->install(gobject_);
819 void Source::add_poll(Glib::PollFD& poll_fd)
821 g_source_add_poll(gobject_, poll_fd.gobj());
824 void Source::remove_poll(Glib::PollFD& poll_fd)
826 g_source_remove_poll(gobject_, poll_fd.gobj());
829 void Source::get_current_time(Glib::TimeVal& current_time)
831 g_source_get_current_time(gobject_, ¤t_time);
835 Source* Source::get_wrapper(GSource* source)
837 SourceCallbackData *const data = glibmm_source_get_callback_data(source);
838 return data->wrapper;
842 gboolean Source::prepare_vfunc(GSource* source, int* timeout)
844 #ifdef GLIBMM_EXCEPTIONS_ENABLED
847 #endif //GLIBMM_EXCEPTIONS_ENABLED
848 Source *const self = get_wrapper(source);
849 return self->prepare(*timeout);
850 #ifdef GLIBMM_EXCEPTIONS_ENABLED
854 Glib::exception_handlers_invoke();
856 #endif //GLIBMM_EXCEPTIONS_ENABLED
862 gboolean Source::check_vfunc(GSource* source)
864 #ifdef GLIBMM_EXCEPTIONS_ENABLED
867 #endif //GLIBMM_EXCEPTIONS_ENABLED
868 Source *const self = get_wrapper(source);
869 return self->check();
870 #ifdef GLIBMM_EXCEPTIONS_ENABLED
874 Glib::exception_handlers_invoke();
876 #endif //GLIBMM_EXCEPTIONS_ENABLED
882 gboolean Source::dispatch_vfunc(GSource*, GSourceFunc callback, void* user_data)
884 SourceCallbackData *const callback_data = static_cast<SourceCallbackData*>(user_data);
886 g_return_val_if_fail(callback == &glibmm_dummy_source_callback, 0);
887 g_return_val_if_fail(callback_data != 0 && callback_data->node != 0, 0);
889 #ifdef GLIBMM_EXCEPTIONS_ENABLED
892 #endif //GLIBMM_EXCEPTIONS_ENABLED
893 Source *const self = callback_data->wrapper;
894 return self->dispatch(callback_data->node->get_slot());
895 #ifdef GLIBMM_EXCEPTIONS_ENABLED
899 Glib::exception_handlers_invoke();
901 #endif //GLIBMM_EXCEPTIONS_ENABLED
906 void Source::destroy_notify_callback(void* data)
910 Source *const self = static_cast<Source*>(data);
912 // gobject_ is already invalid at this point.
915 // No exception checking: if the dtor throws, you're out of luck anyway.
921 /**** Glib::TimeoutSource **************************************************/
924 Glib::RefPtr<TimeoutSource> TimeoutSource::create(unsigned int interval)
926 return Glib::RefPtr<TimeoutSource>(new TimeoutSource(interval));
929 sigc::connection TimeoutSource::connect(const sigc::slot<bool>& slot)
931 return connect_generic(slot);
934 TimeoutSource::TimeoutSource(unsigned int interval)
938 expiration_.assign_current_time();
939 expiration_.add_milliseconds(std::min<unsigned long>(G_MAXLONG, interval_));
942 TimeoutSource::~TimeoutSource()
945 bool TimeoutSource::prepare(int& timeout)
947 Glib::TimeVal current_time;
948 get_current_time(current_time);
950 Glib::TimeVal remaining = expiration_;
951 remaining.subtract(current_time);
953 if(remaining.negative())
960 const unsigned long milliseconds =
961 static_cast<unsigned long>(remaining.tv_sec) * 1000U +
962 static_cast<unsigned long>(remaining.tv_usec) / 1000U;
964 // Set remaining milliseconds.
965 timeout = std::min<unsigned long>(G_MAXINT, milliseconds);
967 // Check if the system time has been set backwards. (remaining > interval)
968 remaining.add_milliseconds(- std::min<unsigned long>(G_MAXLONG, interval_) - 1);
969 if(!remaining.negative())
971 // Oh well. Reset the expiration time to now + interval;
972 // this at least avoids hanging for long periods of time.
973 expiration_ = current_time;
974 expiration_.add_milliseconds(interval_);
975 timeout = std::min<unsigned int>(G_MAXINT, interval_);
979 return (timeout == 0);
982 bool TimeoutSource::check()
984 Glib::TimeVal current_time;
985 get_current_time(current_time);
987 return (expiration_ <= current_time);
990 bool TimeoutSource::dispatch(sigc::slot_base* slot)
992 const bool again = (*static_cast<sigc::slot<bool>*>(slot))();
996 get_current_time(expiration_);
997 expiration_.add_milliseconds(std::min<unsigned long>(G_MAXLONG, interval_));
1004 /**** Glib::IdleSource *****************************************************/
1007 Glib::RefPtr<IdleSource> IdleSource::create()
1009 return Glib::RefPtr<IdleSource>(new IdleSource());
1012 sigc::connection IdleSource::connect(const sigc::slot<bool>& slot)
1014 return connect_generic(slot);
1017 IdleSource::IdleSource()
1019 set_priority(PRIORITY_DEFAULT_IDLE);
1022 IdleSource::~IdleSource()
1025 bool IdleSource::prepare(int& timeout)
1031 bool IdleSource::check()
1036 bool IdleSource::dispatch(sigc::slot_base* slot)
1038 return (*static_cast<sigc::slot<bool>*>(slot))();
1042 /**** Glib::IOSource *******************************************************/
1045 Glib::RefPtr<IOSource> IOSource::create(int fd, IOCondition condition)
1047 return Glib::RefPtr<IOSource>(new IOSource(fd, condition));
1050 Glib::RefPtr<IOSource> IOSource::create(const Glib::RefPtr<IOChannel>& channel, IOCondition condition)
1052 return Glib::RefPtr<IOSource>(new IOSource(channel, condition));
1055 sigc::connection IOSource::connect(const sigc::slot<bool,IOCondition>& slot)
1057 return connect_generic(slot);
1060 IOSource::IOSource(int fd, IOCondition condition)
1062 poll_fd_ (fd, condition)
1067 IOSource::IOSource(const Glib::RefPtr<IOChannel>& channel, IOCondition condition)
1069 Source(g_io_create_watch(channel->gobj(), (GIOCondition) condition),
1070 (GSourceFunc) &glibmm_iosource_callback)
1073 IOSource::~IOSource()
1076 bool IOSource::prepare(int& timeout)
1082 bool IOSource::check()
1084 return ((poll_fd_.get_revents() & poll_fd_.get_events()) != 0);
1087 bool IOSource::dispatch(sigc::slot_base* slot)
1089 return (*static_cast<sigc::slot<bool,IOCondition>*>(slot))
1090 (poll_fd_.get_revents());