summaryrefslogtreecommitdiff
path: root/libs/pbd/base_ui.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-12-09 03:05:14 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-12-09 03:05:14 +0000
commitc38e02285fda1fd7966c9e4ad85994445247e6a6 (patch)
treea5f46d4350b8df3e0a74558169c696cbb837ce7f /libs/pbd/base_ui.cc
parent90f95df20707995e267bd624b28980cfd9200bed (diff)
major design changes: use glib event loop for MIDI thread/UI; rework design of BaseUI and AbstractUI; solo & mute are both temporarily broken; OSC control up next; may segfault during exit
git-svn-id: svn://localhost/ardour2/branches/3.0@6328 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/base_ui.cc')
-rw-r--r--libs/pbd/base_ui.cc85
1 files changed, 47 insertions, 38 deletions
diff --git a/libs/pbd/base_ui.cc b/libs/pbd/base_ui.cc
index 015951f118..259a51d954 100644
--- a/libs/pbd/base_ui.cc
+++ b/libs/pbd/base_ui.cc
@@ -33,36 +33,24 @@
using namespace std;
using namespace PBD;
+using namespace Glib;
-uint32_t BaseUI::rt_bit = 1;
+uint64_t BaseUI::rt_bit = 1;
BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type();
-BaseUI::BaseUI (string str, bool with_signal_pipe)
- : _name (str)
+BaseUI::BaseUI (const string& str)
+ : run_loop_thread (0)
+ , _name (str)
{
- /* odd pseudo-singleton semantics */
-
base_ui_instance = this;
- signal_pipe[0] = -1;
- signal_pipe[1] = -1;
+ request_channel.ios()->connect (sigc::mem_fun (*this, &BaseUI::request_handler));
- if (with_signal_pipe) {
- if (setup_signal_pipe ()) {
- throw failed_constructor ();
- }
- }
+ /* derived class must set _ok */
}
BaseUI::~BaseUI()
{
- if (signal_pipe[0] >= 0) {
- close (signal_pipe[0]);
- }
-
- if (signal_pipe[1] >= 0) {
- close (signal_pipe[1]);
- }
}
BaseUI::RequestType
@@ -78,32 +66,53 @@ BaseUI::new_request_type ()
return rt;
}
-int
-BaseUI::setup_signal_pipe ()
+void
+BaseUI::main_thread ()
+{
+ thread_init ();
+ _main_loop->run ();
+}
+
+void
+BaseUI::run ()
{
- /* setup the pipe that other threads send us notifications/requests
- through.
+ /* to be called by UI's that need/want their own distinct, self-created event loop thread.
+ Derived classes should have set up a handler for IO on request_channel.ios()
*/
- if (pipe (signal_pipe)) {
- error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, ::strerror (errno))
- << endmsg;
+ _main_loop = MainLoop::create (MainContext::create());
+ request_channel.ios()->attach (_main_loop->get_context());
+ run_loop_thread = Thread::create (mem_fun (*this, &BaseUI::main_thread), true);
+}
- return -1;
- }
+void
+BaseUI::quit ()
+{
+ _main_loop->quit ();
+ run_loop_thread->join ();
+}
+
+bool
+BaseUI::request_handler (Glib::IOCondition ioc)
+{
+ /* check the transport request pipe */
- if (fcntl (signal_pipe[0], F_SETFL, O_NONBLOCK)) {
- error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, ::strerror (errno))
- << endmsg;
- return -1;
+ if (ioc & ~IO_IN) {
+ _main_loop->quit ();
}
- if (fcntl (signal_pipe[1], F_SETFL, O_NONBLOCK)) {
- error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, ::strerror (errno))
- << endmsg;
- return -1;
+ if (ioc & IO_IN) {
+ request_channel.drain ();
+
+ /* there may been an error. we'd rather handle requests first,
+ and then get IO_HUP or IO_ERR on the next loop.
+ */
+
+ /* handle requests */
+
+ handle_ui_requests ();
}
- return 0;
+ return true;
}
-
+