| @@ -36,6 +36,7 @@ public: | |||
| JACK_Module ( ); | |||
| virtual ~JACK_Module ( ); | |||
| bool allows_external_control ( void ) const { return false; } | |||
| const char *name ( void ) const { return "JACK"; } | |||
| bool initialize ( void ); | |||
| @@ -44,6 +44,7 @@ public: | |||
| Meter_Indicator_Module ( bool is_default = false ); | |||
| virtual ~Meter_Indicator_Module ( ); | |||
| bool allows_external_control ( void ) const { return false; } | |||
| const char *name ( void ) const { return "Meter Indicator"; } | |||
| int can_support_inputs ( int ) { return 0; } | |||
| @@ -213,6 +213,12 @@ Module::handle_control_changed ( Port *p ) | |||
| _editor->handle_control_changed ( p ); | |||
| } | |||
| bool | |||
| Module::Port::connected_osc ( void ) const | |||
| { | |||
| return _scaled_signal->connected(); | |||
| } | |||
| char * | |||
| Module::Port::generate_osc_path () | |||
| { | |||
| @@ -222,6 +228,12 @@ Module::Port::generate_osc_path () | |||
| // /mixer/STRIPNAME/MODULENAME/CONTROLNAME | |||
| if ( ! module()->allows_external_control() ) | |||
| { | |||
| /* Don't create signals for the default modules other than Gain */ | |||
| return NULL; | |||
| } | |||
| int n = module()->chain()->get_module_instance_number( module() ); | |||
| if ( n > 0 ) | |||
| @@ -290,6 +302,7 @@ Module::Port::change_osc_path ( char *path ) | |||
| 0.0f, | |||
| 1.0f, | |||
| scaled_default ); | |||
| } | |||
| } | |||
| @@ -500,7 +513,12 @@ Module::draw_box ( void ) | |||
| { | |||
| /* maybe draw control indicators */ | |||
| if ( control_input.size() ) | |||
| { | |||
| fl_draw_box( FL_ROUNDED_BOX, tx + 4, ty + 4, 5, 5, is_being_controlled() ? FL_YELLOW : fl_inactive( FL_YELLOW ) ); | |||
| fl_draw_box( FL_ROUNDED_BOX, tx + 4, ty + 8, 5, 5, is_being_controlled_osc() ? FL_GREEN : fl_inactive( FL_GREEN ) ); | |||
| } | |||
| if ( control_output.size() ) | |||
| fl_draw_box( FL_ROUNDED_BOX, tx + tw - 8, ty + 4, 5, 5, is_controlling() ? FL_YELLOW : fl_inactive( FL_YELLOW ) ); | |||
| } | |||
| @@ -71,6 +71,8 @@ public: | |||
| bool is_default ( void ) const { return _is_default; } | |||
| void is_default ( bool v ) { _is_default = v; } | |||
| virtual bool allows_external_control ( void ) const { return true; } | |||
| class Port | |||
| { | |||
| /* char *type_names[] = { "Audio", "Control" }; */ | |||
| @@ -160,7 +162,10 @@ public: | |||
| const char *osc_path ( ) | |||
| { | |||
| return _scaled_signal->path(); | |||
| if ( _scaled_signal ) | |||
| return _scaled_signal->path(); | |||
| else | |||
| return NULL; | |||
| } | |||
| void update_osc_port ( ) | |||
| @@ -205,6 +210,7 @@ public: | |||
| } | |||
| bool connected ( void ) const { return _connected; } | |||
| bool connected_osc ( void ) const; | |||
| Port *connected_port ( void ) const | |||
| { | |||
| @@ -293,6 +299,15 @@ public: | |||
| return false; | |||
| } | |||
| bool | |||
| is_being_controlled_osc ( void ) const | |||
| { | |||
| for ( nframes_t i = control_input.size(); i--; ) | |||
| if ( control_input[i].connected_osc() ) | |||
| return true; | |||
| return false; | |||
| } | |||
| virtual const char *name ( void ) const = 0; | |||
| std::vector<Port> audio_input; | |||
| @@ -80,6 +80,8 @@ NSM_Client::command_open ( const char *name, const char *display_name, const cha | |||
| instance_name = strdup( client_id ); | |||
| mixer->osc_endpoint->name( client_id ); | |||
| int r = ERR_OK; | |||
| if ( Project::validate( name ) ) | |||
| @@ -84,6 +84,21 @@ namespace OSC | |||
| free( _path ); | |||
| _path = strdup( path ); | |||
| } | |||
| bool | |||
| Signal::is_connected_to ( const OSC::Signal *s ) const | |||
| { | |||
| for ( std::list<Target*>::const_iterator i = _outgoing.begin(); | |||
| i != _outgoing.end(); | |||
| ++i ) | |||
| { | |||
| if ( (*i)->peer == s->_peer && | |||
| (*i)->signal_id == s->id() ) | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| void | |||
| Signal::value ( float f ) | |||
| @@ -92,8 +107,6 @@ namespace OSC | |||
| i != _outgoing.end(); | |||
| ++i ) | |||
| { | |||
| // DMESSAGE( "Sending signal value %i %f", (*i)->signal_id, f ); | |||
| if ( (*i)->value != f ) | |||
| { | |||
| (*i)->value = f; | |||
| @@ -140,10 +153,14 @@ namespace OSC | |||
| return -1; | |||
| } | |||
| add_method( "/signal/hello", "s", &Endpoint::osc_sig_hello, this, "" ); | |||
| add_method( "/signal/connect", "ii", &Endpoint::osc_sig_connect, this, "" ); | |||
| add_method( "/signal/disconnect", "ii", &Endpoint::osc_sig_disconnect, this, "" ); | |||
| add_method( "/signal/renamed", "is", &Endpoint::osc_sig_renamed, this, "" ); | |||
| add_method( "/signal/change", "if", &Endpoint::osc_sig_handler, this, "" ); | |||
| add_method( NULL, "", &Endpoint::osc_generic, this, "" ); | |||
| add_method( NULL, NULL, &Endpoint::osc_signal_lister, this, "" ); | |||
| add_method( "/signal/list", NULL, &Endpoint::osc_signal_lister, this, "" ); | |||
| add_method( "/reply", NULL, &Endpoint::osc_reply, this, "" ); | |||
| return 0; | |||
| @@ -215,6 +232,135 @@ namespace OSC | |||
| return NULL; | |||
| } | |||
| void | |||
| Endpoint::hello ( const char *url ) | |||
| { | |||
| lo_address addr = lo_address_new_from_url ( url ); | |||
| send( addr, "/signal/hello", name() ); | |||
| lo_address_free( addr ); | |||
| } | |||
| int | |||
| Endpoint::osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) | |||
| { | |||
| Endpoint *ep = (Endpoint*)user_data; | |||
| const char *peer_name = &argv[0]->s; | |||
| DMESSAGE( "Got hello from %s", peer_name ); | |||
| if ( ! ep->find_peer_by_name( peer_name ) ) | |||
| { | |||
| char *url = lo_address_get_url( lo_message_get_source( msg )); | |||
| ep->scan_peer( peer_name, url ); | |||
| ep->send( lo_message_get_source( msg ), "/signal/hello", ep->name() ); | |||
| free(url); | |||
| } | |||
| return 0; | |||
| } | |||
| int | |||
| Endpoint::osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) | |||
| { | |||
| int their_id = argv[0]->i; | |||
| int our_id = argv[1]->i; | |||
| Endpoint *ep = (Endpoint*)user_data; | |||
| Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) ); | |||
| if ( ! p ) | |||
| return 0; | |||
| Signal *ps = ep->find_peer_signal_by_id( p, their_id ); | |||
| if ( ! ps ) | |||
| return 0; | |||
| Signal *s = ep->find_signal_by_id( our_id ); | |||
| if ( ! s ) | |||
| return 0; | |||
| if ( s->_direction == Signal::Input ) | |||
| { | |||
| for ( std::list<Target*>::iterator i = s->_incoming.begin(); | |||
| i != s->_incoming.end(); | |||
| ++i ) | |||
| { | |||
| if ( (*i)->peer == p && | |||
| (*i)->signal_id == ps->id() ) | |||
| { | |||
| DMESSAGE( "Peer %s has disconnected from signal %s", p->name, ps->path() ); | |||
| delete *i; | |||
| i = s->_incoming.erase( i ); | |||
| return 0; | |||
| } | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| int | |||
| Endpoint::osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) | |||
| { | |||
| int their_id = argv[0]->i; | |||
| int our_id = argv[1]->i; | |||
| Endpoint *ep = (Endpoint*)user_data; | |||
| Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) ); | |||
| if ( ! p ) | |||
| { | |||
| WARNING( "Got connection signal from unknown peer" ); | |||
| return 0; | |||
| } | |||
| Signal *ps = ep->find_peer_signal_by_id( p, their_id ); | |||
| if ( ! ps ) | |||
| { | |||
| WARNING( "Unknown source signal" ); | |||
| return 0; | |||
| } | |||
| Signal *s = ep->find_signal_by_id( our_id ); | |||
| if ( ! s ) | |||
| { | |||
| WARNING( "Unknown destination signal" ); | |||
| return 0; | |||
| } | |||
| DMESSAGE( "Peer %s has connected to signal %s", p->name, s->path() ); | |||
| if ( s->_direction == Signal::Input ) | |||
| { | |||
| Target *t = new Target; | |||
| t->peer = p; | |||
| t->signal_id = ps->id(); | |||
| s->_incoming.push_back( t ); | |||
| return 0; | |||
| } | |||
| return 0; | |||
| } | |||
| int | |||
| Endpoint::osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) | |||
| @@ -346,19 +492,6 @@ namespace OSC | |||
| { | |||
| // OSC_DMSG(); | |||
| Signal::Direction dir; | |||
| if ( ! strcmp( path, "/signal/list_inputs" ) ) | |||
| { | |||
| dir = Signal::Input; | |||
| } | |||
| else if ( ! strcmp( path, "/signal/list_outputs" ) ) | |||
| { | |||
| dir = Signal::Output; | |||
| } | |||
| else | |||
| return -1; | |||
| const char *prefix = NULL; | |||
| if ( argc ) | |||
| @@ -370,24 +503,21 @@ namespace OSC | |||
| { | |||
| Signal *o = *i; | |||
| if ( dir == Signal::Bidirectional || | |||
| dir == o->_direction ) | |||
| if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) ) | |||
| { | |||
| if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) ) | |||
| { | |||
| ep->send( lo_message_get_source( msg ), | |||
| "/reply", | |||
| path, | |||
| o->path(), | |||
| o->id(), | |||
| o->parameter_limits().min, | |||
| o->parameter_limits().max, | |||
| o->parameter_limits().default_value | |||
| ); | |||
| } | |||
| ep->send( lo_message_get_source( msg ), | |||
| "/reply", | |||
| path, | |||
| o->path(), | |||
| o->_direction == Signal::Input ? "in" : "out", | |||
| o->id(), | |||
| o->parameter_limits().min, | |||
| o->parameter_limits().max, | |||
| o->parameter_limits().default_value | |||
| ); | |||
| } | |||
| } | |||
| ep->send( lo_message_get_source( msg ), "/reply", path ); | |||
| return 0; | |||
| @@ -469,7 +599,7 @@ namespace OSC | |||
| } | |||
| bool | |||
| Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path ) | |||
| Endpoint::disconnect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path ) | |||
| { | |||
| if ( s->_direction == Signal::Output ) | |||
| { | |||
| @@ -483,23 +613,67 @@ namespace OSC | |||
| if ( ! ps ) | |||
| return false; | |||
| MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, s->_id ); | |||
| MESSAGE( "Disconnecting signal output \"%s\" to %s:%i", s->path(), peer_name, ps->_id ); | |||
| if ( p ) | |||
| for ( std::list<Target*>::iterator i = s->_outgoing.begin(); | |||
| i != s->_outgoing.end(); | |||
| ++i ) | |||
| { | |||
| Target *t = new Target(); | |||
| if ( (*i)->peer == p && | |||
| (*i)->signal_id == ps->id() ) | |||
| { | |||
| send( p->addr, "/signal/disconnect", | |||
| s->_id, /* our signal id */ | |||
| (*i)->signal_id /* their signal id */ ); | |||
| t->peer = p; | |||
| t->signal_id = ps->_id; | |||
| delete *i; | |||
| i = s->_outgoing.erase( i ); | |||
| DMESSAGE( "Number of outgoing connections: %i", s->_outgoing.size() ); | |||
| return true; | |||
| } | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| bool | |||
| Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path ) | |||
| { | |||
| if ( s->_direction == Signal::Output ) | |||
| { | |||
| Peer *p = find_peer_by_name( peer_name ); | |||
| if ( ! p ) | |||
| return false; | |||
| Signal *ps = find_peer_signal_by_path( p, signal_path ); | |||
| if ( ! ps ) | |||
| return false; | |||
| if ( s->is_connected_to( ps ) ) | |||
| { | |||
| return false; | |||
| } | |||
| MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, ps->_id ); | |||
| Target *t = new Target(); | |||
| t->peer = p; | |||
| t->signal_id = ps->_id; | |||
| s->_outgoing.push_back( t ); | |||
| s->_outgoing.push_back( t ); | |||
| send( p->addr, "/signal/connect", | |||
| s->_id, /* our signal id */ | |||
| t->signal_id /* their signal id */ ); | |||
| send( p->addr, "/signal/connect", | |||
| s->_id, /* our signal id */ | |||
| t->signal_id /* their signal id */ ); | |||
| return true; | |||
| } | |||
| return true; | |||
| } | |||
| return false; | |||
| @@ -557,7 +731,7 @@ namespace OSC | |||
| { | |||
| Endpoint *ep = (Endpoint*)user_data; | |||
| if ( argc && !strcmp( &argv[0]->s, "/signal/list_inputs" ) ) | |||
| if ( argc && !strcmp( &argv[0]->s, "/signal/list" ) ) | |||
| { | |||
| Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) ); | |||
| @@ -576,12 +750,20 @@ namespace OSC | |||
| { | |||
| DMESSAGE( "Peer %s has signal %s", p->name, &argv[1]->s ); | |||
| Signal *s = new Signal( &argv[1]->s, Signal::Input ); | |||
| int dir = 0; | |||
| if ( !strcmp( &argv[2]->s, "in" ) ) | |||
| dir = Signal::Input; | |||
| else if ( !strcmp( &argv[2]->s, "out" ) ) | |||
| dir = Signal::Output; | |||
| Signal *s = new Signal( &argv[1]->s, (Signal::Direction)dir ); | |||
| s->_id = argv[2]->i; | |||
| s->parameter_limits().min = argv[3]->f; | |||
| s->parameter_limits().max = argv[4]->f; | |||
| s->parameter_limits().default_value = argv[4]->f; | |||
| s->_peer = p; | |||
| s->_id = argv[3]->i; | |||
| s->parameter_limits().min = argv[4]->f; | |||
| s->parameter_limits().max = argv[5]->f; | |||
| s->parameter_limits().default_value = argv[6]->f; | |||
| p->_signals.push_back( s ); | |||
| } | |||
| @@ -690,13 +872,15 @@ namespace OSC | |||
| { | |||
| Peer *p = new Peer; | |||
| DMESSAGE( "Scanning peer %s @ %s...", name, url ); | |||
| p->name = strdup( name ); | |||
| p->addr = lo_address_new_from_url( url ); | |||
| p->_scanning = true; | |||
| _peers.push_back( p ); | |||
| send( p->addr, "/signal/list_inputs" ); | |||
| send( p->addr, "/signal/list" ); | |||
| } | |||
| void * | |||
| @@ -940,6 +1124,12 @@ namespace OSC | |||
| return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssifff", v1, v2, v3, v4, v5, v6 ); | |||
| } | |||
| int | |||
| Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 ) | |||
| { | |||
| return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssifff", v1, v2, v3, v4, v5, v6, 7 ); | |||
| } | |||
| int | |||
| Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3 ) | |||
| { | |||
| @@ -150,6 +150,8 @@ namespace OSC | |||
| Endpoint *_endpoint; | |||
| Peer *_peer; | |||
| int _id; | |||
| char *_path; | |||
| @@ -182,6 +184,7 @@ namespace OSC | |||
| _id = ++next_id; | |||
| _value = 0.0f; | |||
| _endpoint = NULL; | |||
| _peer = NULL; | |||
| } | |||
| ~Signal ( ); | |||
| @@ -213,6 +216,8 @@ namespace OSC | |||
| /* get current value */ | |||
| float value ( void ) const { return _value; } | |||
| bool is_connected_to ( const Signal *s ) const; | |||
| friend class Endpoint; | |||
| }; | |||
| @@ -246,6 +251,11 @@ namespace OSC | |||
| static int osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
| static int osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
| static int osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
| static int osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
| static int osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
| static int osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
| void scan_peer ( const char *name, const char *url ); | |||
| Thread _thread; | |||
| @@ -269,6 +279,8 @@ namespace OSC | |||
| static Target *find_target_by_peer_address ( std::list<Target*> *l, lo_address addr ); | |||
| char *_name; | |||
| public: | |||
| void list_peers ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v ); | |||
| @@ -279,6 +291,7 @@ namespace OSC | |||
| ~Endpoint ( ); | |||
| bool disconnect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path ); | |||
| bool connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path ); | |||
| bool connect_signal( OSC::Signal *s, const char *peer_name, int signal_id ); | |||
| @@ -293,12 +306,15 @@ namespace OSC | |||
| int port ( void ) const; | |||
| char * url ( void ) const; | |||
| void scan_peer ( const char *name, const char *url ); | |||
| void check ( void ) const; | |||
| void wait ( int timeout ) const; | |||
| void run ( void ) const; | |||
| void name ( const char *name ) { _name = strdup( name ); } | |||
| const char *name ( void ) { return _name; } | |||
| void hello ( const char *url ); | |||
| int send ( lo_address to, const char *path, std::list< OSC_Value > values ); | |||
| /* overloads for common message formats */ | |||
| @@ -331,6 +347,8 @@ namespace OSC | |||
| int send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 ); | |||
| int send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 ); | |||
| // can be used to point back to owning object. | |||
| void *owner; | |||
| }; | |||
| @@ -779,7 +779,7 @@ private: | |||
| int err = argv[1]->i; | |||
| if ( err != 0 ) | |||
| fl_alert( "ERROR: %s failed with: %s", &argv[0]->s, &argv[2]->s ); | |||
| fl_alert( "Command %s failed with:\n\n%s", &argv[0]->s, &argv[2]->s ); | |||
| } | |||
| else if (!strcmp( path, "/reply" )) | |||
| { | |||
| @@ -143,12 +143,13 @@ Control_Sequence::get_unjournaled ( Log_Entry &e ) const | |||
| { | |||
| char *path; | |||
| char *peer; | |||
| _osc_output->get_connected_peer_name_and_path( &peer, &path ); | |||
| e.add( ":osc-peer", peer ); | |||
| e.add( ":osc_peer", peer ); | |||
| e.add( ":osc_path", path ); | |||
| e.add( ":osc-path", path ); | |||
| free( path ); | |||
| free( peer ); | |||
| } | |||
| @@ -182,16 +183,20 @@ Control_Sequence::set ( Log_Entry &e ) | |||
| t->add( this ); | |||
| } | |||
| else if ( ! strcmp( ":name", s ) ) | |||
| { | |||
| name( v ); | |||
| } | |||
| else if ( ! strcmp( ":interpolation", s ) ) | |||
| { | |||
| interpolation( (curve_type_e)atoi( v ) ); | |||
| } | |||
| /* else if ( ! strcmp( ":frequency", s ) ) */ | |||
| /* frequency( atoi( v ) ); */ | |||
| else if ( ! strcmp( ":osc_peer", s ) ) | |||
| else if ( ! strcmp( ":osc-peer", s ) ) | |||
| { | |||
| _osc_connected_peer = strdup( v ); | |||
| } | |||
| else if ( !strcmp( ":osc_path", s ) ) | |||
| else if ( !strcmp( ":osc-path", s ) ) | |||
| { | |||
| _osc_connected_path = strdup( v ); | |||
| } | |||
| @@ -369,23 +374,28 @@ Control_Sequence::menu_cb ( const Fl_Menu_ *m ) | |||
| if ( ! strncmp( picked, "Connect To/", strlen( "Connect To/" ) ) ) | |||
| { | |||
| if ( ! _osc_output ) | |||
| { | |||
| char *path; | |||
| asprintf( &path, "/non/daw/%s/control/%i", track()->name(), track()->ncontrols() ); | |||
| _osc_output = timeline->osc->add_signal( path, OSC::Signal::Output, NULL, NULL ); | |||
| free( path ); | |||
| } | |||
| int id = ((OSC::Signal*)m->mvalue()->user_data())->id(); | |||
| char *peer_name = index( picked, '/' ) + 1; | |||
| *index( peer_name, '/' ) = 0; | |||
| timeline->osc->connect_signal( _osc_output, peer_name, id ); | |||
| _osc_connected_peer = strdup( peer_name ); | |||
| _osc_connected_path = strdup( ((OSC::Signal*)m->mvalue()->user_data())->path() ); | |||
| if ( ! _osc_output->is_connected_to( ((OSC::Signal*)m->mvalue()->user_data()) ) ) | |||
| { | |||
| connect_osc(); | |||
| } | |||
| else | |||
| { | |||
| timeline->osc->disconnect_signal( _osc_output, _osc_connected_peer, _osc_connected_path ); | |||
| free( _osc_connected_path ); | |||
| free( _osc_connected_peer ); | |||
| _osc_connected_peer = _osc_connected_path = NULL; | |||
| } | |||
| } | |||
| else if ( ! strcmp( picked, "Interpolation/Linear" ) ) | |||
| interpolation( Linear ); | |||
| @@ -437,7 +447,15 @@ Control_Sequence::connect_osc ( void ) | |||
| { | |||
| if ( ! timeline->osc->connect_signal( _osc_output, _osc_connected_peer, _osc_connected_path ) ) | |||
| { | |||
| /* failed to connect */ | |||
| // MESSAGE( "Failed to connect output %s to %s:%s", _osc_output->path(), _osc_connected_peer, _osc_connected_path ); | |||
| } | |||
| else | |||
| { | |||
| tooltip( _osc_connected_path ); | |||
| // _osc_connected_peer = _osc_connected_path = | |||
| MESSAGE( "Connected output %s to %s:%s", _osc_output->path(), _osc_connected_peer, _osc_connected_path ); | |||
| } | |||
| } | |||
| } | |||
| @@ -460,6 +478,40 @@ Control_Sequence::process_osc ( void ) | |||
| } | |||
| } | |||
| void | |||
| Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig, void *v ) | |||
| { | |||
| ((Control_Sequence*)v)->peer_callback( name, sig ); | |||
| } | |||
| static Fl_Menu_Button *peer_menu; | |||
| static const char *peer_prefix; | |||
| void | |||
| Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig ) | |||
| { | |||
| char *s; | |||
| asprintf( &s, "%s/%s%s", peer_prefix, name, sig->path() ); | |||
| peer_menu->add( s, 0, NULL, (void*)( sig ), | |||
| FL_MENU_TOGGLE | | |||
| ( _osc_output->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) ); | |||
| free( s ); | |||
| connect_osc(); | |||
| } | |||
| void | |||
| Control_Sequence::add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix ) | |||
| { | |||
| peer_menu = m; | |||
| peer_prefix = prefix; | |||
| timeline->osc->list_peers( &Control_Sequence::peer_callback, this ); | |||
| } | |||
| int | |||
| Control_Sequence::handle ( int m ) | |||
| { | |||
| @@ -509,7 +561,7 @@ Control_Sequence::handle ( int m ) | |||
| menu.clear(); | |||
| timeline->add_osc_peers_to_menu( &menu, "Connect To" ); | |||
| add_osc_peers_to_menu( &menu, "Connect To" ); | |||
| /* menu.add( "Connect To", 0, 0, 0); */ | |||
| /* menu.add( "Connect To", 0, 0, const_cast< Fl_Menu_Item *>( con->menu() ), FL_SUBMENU_POINTER ); */ | |||
| @@ -49,6 +49,10 @@ private: | |||
| /* osc output port */ | |||
| OSC::Signal *_osc_output; | |||
| static void peer_callback( const char *name, const OSC::Signal *sig, void *v ); | |||
| void peer_callback( const char *name, const OSC::Signal *sig ); | |||
| void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix ); | |||
| bool _highlighted; | |||
| curve_type_e _interpolation; | |||
| @@ -58,6 +58,8 @@ NSM_Client::command_open ( const char *name, const char *display_name, const cha | |||
| instance_name = strdup( client_id ); | |||
| timeline->osc->name( client_id ); | |||
| if ( Project::validate( name ) ) | |||
| { | |||
| if ( timeline->command_load( name, display_name ) ) | |||
| @@ -1528,7 +1528,7 @@ Timeline::command_load ( const char *name, const char *display_name ) | |||
| Project::set_name ( display_name ? display_name : name ); | |||
| discover_peers(); | |||
| // discover_peers(); | |||
| return true; | |||
| } | |||
| @@ -1553,7 +1553,7 @@ Timeline::command_new ( const char *name, const char *display_name ) | |||
| /* tle->main_window->redraw(); */ | |||
| discover_peers(); | |||
| // discover_peers(); | |||
| return b; | |||
| } | |||
| @@ -1623,7 +1623,9 @@ Timeline::osc_non_hello ( const char *path, const char *types, lo_arg **argv, in | |||
| MESSAGE( "Scanning..." ); | |||
| timeline->osc->scan_peer( id, url ); | |||
| // timeline->osc->scan_peer( id, url ); | |||
| timeline->osc->hello( url ); | |||
| return 0; | |||
| } | |||
| @@ -1684,44 +1686,13 @@ Timeline::discover_peers ( void ) | |||
| MESSAGE( "Waiting for OSC peers..." ); | |||
| // osc->wait( 1000 ); | |||
| osc->wait( 1000 ); | |||
| MESSAGE( "Reconnecting signals." ); | |||
| connect_osc(); | |||
| } | |||
| void | |||
| Timeline::peer_callback( const char *name, const OSC::Signal *sig, void *v ) | |||
| { | |||
| ((Timeline*)v)->peer_callback( name, sig ); | |||
| } | |||
| static Fl_Menu_Button *peer_menu; | |||
| static const char *peer_prefix; | |||
| void | |||
| Timeline::peer_callback( const char *name, const OSC::Signal *sig ) | |||
| { | |||
| char *s; | |||
| asprintf( &s, "%s/%s%s", peer_prefix, name, sig->path() ); | |||
| peer_menu->add( s, 0, NULL, (void*)( sig ) ); | |||
| free( s ); | |||
| connect_osc(); | |||
| } | |||
| void | |||
| Timeline::add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix ) | |||
| { | |||
| peer_menu = m; | |||
| peer_prefix = prefix; | |||
| osc->list_peers( &Timeline::peer_callback, this ); | |||
| } | |||
| /* runs in the OSC thread... */ | |||
| void | |||
| @@ -236,12 +236,9 @@ public: | |||
| /* OSC */ | |||
| static void peer_callback( const char *name, const OSC::Signal *sig, void *v ); | |||
| void peer_callback( const char *name, const OSC::Signal *sig ); | |||
| void connect_osc ( void ); | |||
| void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix ); | |||
| void discover_peers ( void ); | |||