diff options
author | Sampo Savolainen <v2@iki.fi> | 2008-11-10 20:25:06 +0000 |
---|---|---|
committer | Sampo Savolainen <v2@iki.fi> | 2008-11-10 20:25:06 +0000 |
commit | 475b1e36a916d0613d927f2bcd33125f53f24795 (patch) | |
tree | 799d4913474d604a4228dfaa082171e95a8e4dbb /libs/surfaces | |
parent | 745dd9eddb11be957bf7e87e7546ffadbb1784f1 (diff) |
Das Wiimote Blinkenlights!
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4132 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/surfaces')
-rw-r--r-- | libs/surfaces/wiimote/wiimote.cc | 100 | ||||
-rw-r--r-- | libs/surfaces/wiimote/wiimote.h | 29 |
2 files changed, 110 insertions, 19 deletions
diff --git a/libs/surfaces/wiimote/wiimote.cc b/libs/surfaces/wiimote/wiimote.cc index 00de62af81..a855935bda 100644 --- a/libs/surfaces/wiimote/wiimote.cc +++ b/libs/surfaces/wiimote/wiimote.cc @@ -18,18 +18,18 @@ uint16_t WiimoteControlProtocol::button_state = 0; WiimoteControlProtocol::WiimoteControlProtocol ( Session & session) : ControlProtocol ( session, "Wiimote"), - init_thread_quit (false), + main_thread_quit (false), thread_registered_for_ardour (false), wiimote_handle (0) { - std::cerr << "WiimoteControlProtocol()" << std::endl; - init_thread = Glib::Thread::create( sigc::mem_fun(*this, &WiimoteControlProtocol::initializer_thread), true); + main_thread = Glib::Thread::create( sigc::mem_fun(*this, &WiimoteControlProtocol::wiimote_main), true); } WiimoteControlProtocol::~WiimoteControlProtocol() { - init_thread_quit = true; - init_thread->join(); + main_thread_quit = true; + slot_cond.signal(); + main_thread->join(); if (wiimote_handle) { cwiid_close(wiimote_handle); @@ -59,20 +59,46 @@ WiimoteControlProtocol::wiimote_callback(cwiid_wiimote_t *wiimote, int mesg_coun { if (mesg[i].type != CWIID_MESG_BTN) continue; + // what buttons are pressed down which weren't pressed down last time b = (mesg[i].btn_mesg.buttons ^ button_state) & mesg[i].btn_mesg.buttons; button_state = mesg[i].btn_mesg.buttons; + // if B is pressed down + if (button_state & CWIID_BTN_B) { + if (b & CWIID_BTN_A) { // B is down and A is pressed + access_action("Transport/ToggleRollForgetCapture"); + } + + if (b & CWIID_BTN_LEFT) { + access_action("Editor/playhead-to-previous-region-boundary"); + } + if (b & CWIID_BTN_RIGHT) { + access_action("Editor/playhead-to-next-region-boundary"); + } + + if (b & CWIID_BTN_HOME) { + access_action("Editor/add-location-from-playhead"); + } + + if (b & CWIID_BTN_MINUS) { + access_action("Transport/GotoStart"); + } + + if (b & CWIID_BTN_PLUS) { + access_action("Transport/GotoEnd"); + } + + continue; + } + - if (b & CWIID_BTN_A && !(button_state & CWIID_BTN_B)) { // Just "A" + if (b & CWIID_BTN_A) { access_action("Transport/ToggleRoll"); } - if (b & CWIID_BTN_A && button_state & CWIID_BTN_B) { // B is down and A is pressed - access_action("Transport/ToggleRollForgetCapture"); - } if (b & CWIID_BTN_1) { // 1 - access_action("Editor/track-record-enable-toggle"); + access_action("Editor/track-record-enable-toggle"); } if (b & CWIID_BTN_2) { // 2 rec_enable_toggle(); @@ -108,25 +134,44 @@ WiimoteControlProtocol::wiimote_callback(cwiid_wiimote_t *wiimote, int mesg_coun } void -WiimoteControlProtocol::initializer_thread() +WiimoteControlProtocol::update_led_state() +{ + ENSURE_WIIMOTE_THREAD(sigc::mem_fun(*this, &WiimoteControlProtocol::update_led_state)); + + // ensure thread needs to be done here... + uint8_t state = 0; + + if (session->transport_rolling()) { + state |= CWIID_LED3_ON; + } + + if (session->actively_recording()) { + state |= CWIID_LED4_ON; + } + + cwiid_set_led(wiimote_handle, state); +} + +void +WiimoteControlProtocol::wiimote_main() { bdaddr_t bdaddr; unsigned char rpt_mode = 0; - std::cerr << "wiimote: discovering, press 1+2" << std::endl; + std::cerr << "Wiimote: discovering, press 1+2" << std::endl; - while (!wiimote_handle && !init_thread_quit) { + while (!wiimote_handle && !main_thread_quit) { bdaddr = *BDADDR_ANY; wiimote_handle = cwiid_open(&bdaddr, 0); - if (!wiimote_handle && !init_thread_quit) { + if (!wiimote_handle && !main_thread_quit) { sleep(1); // We don't know whether the issue was a timeout or a configuration // issue } } - if (init_thread_quit) { + if (main_thread_quit) { // The corner case where the wiimote is bound at the same time as // the control protocol is destroyed if (wiimote_handle) { @@ -159,7 +204,30 @@ WiimoteControlProtocol::initializer_thread() cwiid_enable(wiimote_handle, CWIID_FLAG_MESG_IFC); cwiid_set_rpt_mode(wiimote_handle, rpt_mode); - std::cerr << "Wiimote: initialization thread stopping" << std::endl; + transport_state_conn = session->TransportStateChange.connect(sigc::mem_fun(*this, &WiimoteControlProtocol::update_led_state)); + record_state_conn = session->RecordStateChanged.connect(sigc::mem_fun(*this, &WiimoteControlProtocol::update_led_state)); + + std::cerr << "Wiimote: initialization done, waiting for callbacks / quit" << std::endl; + + while (!main_thread_quit) { + slot_mutex.lock(); + while (slot_list.empty() && !main_thread_quit) + slot_cond.wait(slot_mutex); + + if (main_thread_quit) { + slot_mutex.unlock(); + break; + } + + sigc::slot<void> call_me = *slot_list.begin(); + slot_list.pop_front(); + slot_mutex.unlock(); + + call_me(); + } + + + std::cerr << "Wiimote: main thread stopped" << std::endl; } diff --git a/libs/surfaces/wiimote/wiimote.h b/libs/surfaces/wiimote/wiimote.h index 85e7df9b9c..a5b1ea4976 100644 --- a/libs/surfaces/wiimote/wiimote.h +++ b/libs/surfaces/wiimote/wiimote.h @@ -6,6 +6,8 @@ #include <glibmm/thread.h> +#include <pbd/abstract_ui.h> + #include <cwiid.h> @@ -13,6 +15,16 @@ namespace ARDOUR { class Session; } +#define ENSURE_WIIMOTE_THREAD(slot) \ + if (Glib::Thread::self() != main_thread) {\ + slot_mutex.lock();\ + slot_list.push_back(slot);\ + slot_cond.signal();\ + slot_mutex.unlock();\ + return;\ + } + + class WiimoteControlProtocol : public ARDOUR::ControlProtocol { public: WiimoteControlProtocol (ARDOUR::Session &); @@ -29,15 +41,26 @@ class WiimoteControlProtocol : public ARDOUR::ControlProtocol { private: - void initializer_thread(); - bool init_thread_quit; + void wiimote_main(); + volatile bool main_thread_quit; + + Glib::Thread *main_thread; + + void update_led_state(); bool thread_registered_for_ardour; - Glib::Thread *init_thread; static uint16_t button_state; cwiid_wiimote_t *wiimote_handle; + + Glib::Cond slot_cond; + Glib::Mutex slot_mutex; + + std::list< sigc::slot<void> > slot_list; + + sigc::connection transport_state_conn; + sigc::connection record_state_conn; }; |