mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 08:36:32 +01:00
allow for mandatory control protocols, plus some ongoing work on automation control point selection (unfinished)
git-svn-id: svn://localhost/trunk/ardour2@516 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
50ee09e80f
commit
9c6984dbbb
16 changed files with 212 additions and 101 deletions
|
|
@ -61,7 +61,7 @@ AddRouteDialog::AddRouteDialog ()
|
||||||
: Dialog (_("ardour: add track/bus")),
|
: Dialog (_("ardour: add track/bus")),
|
||||||
track_button (_("Tracks")),
|
track_button (_("Tracks")),
|
||||||
bus_button (_("Busses")),
|
bus_button (_("Busses")),
|
||||||
routes_adjustment (1, 1, 32, 1, 4),
|
routes_adjustment (1, 1, 128, 1, 4),
|
||||||
routes_spinner (routes_adjustment)
|
routes_spinner (routes_adjustment)
|
||||||
{
|
{
|
||||||
if (channel_combo_strings.empty()) {
|
if (channel_combo_strings.empty()) {
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include <ardour/session.h>
|
#include <ardour/session.h>
|
||||||
#include <ardour/control_protocol_manager.h>
|
#include <ardour/control_protocol_manager.h>
|
||||||
|
#include <ardour/control_protocol.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -472,24 +473,27 @@ ARDOUR_UI::build_control_surface_menu ()
|
||||||
|
|
||||||
for (i = ControlProtocolManager::instance().control_protocol_info.begin(); i != ControlProtocolManager::instance().control_protocol_info.end(); ++i) {
|
for (i = ControlProtocolManager::instance().control_protocol_info.begin(); i != ControlProtocolManager::instance().control_protocol_info.end(); ++i) {
|
||||||
|
|
||||||
string action_name = "Toggle";
|
if (!(*i)->mandatory) {
|
||||||
action_name += legalize_for_path ((*i)->name);
|
|
||||||
action_name += "Surface";
|
|
||||||
|
|
||||||
string action_label = (*i)->name;
|
|
||||||
|
|
||||||
Glib::RefPtr<Action> act = ActionManager::register_toggle_action (editor->editor_actions, action_name.c_str(), action_label.c_str(),
|
|
||||||
(bind (mem_fun (*this, &ARDOUR_UI::toggle_control_protocol), *i)));
|
|
||||||
|
|
||||||
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
string action_name = "Toggle";
|
||||||
|
action_name += legalize_for_path ((*i)->name);
|
||||||
if ((*i)->protocol || (*i)->requested) {
|
action_name += "Surface";
|
||||||
tact->set_active ();
|
|
||||||
|
string action_label = (*i)->name;
|
||||||
|
|
||||||
|
Glib::RefPtr<Action> act = ActionManager::register_toggle_action (editor->editor_actions, action_name.c_str(), action_label.c_str(),
|
||||||
|
(bind (mem_fun (*this, &ARDOUR_UI::toggle_control_protocol), *i)));
|
||||||
|
|
||||||
|
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||||
|
|
||||||
|
if ((*i)->protocol || (*i)->requested) {
|
||||||
|
tact->set_active ();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui += "<menuitem action='";
|
||||||
|
ui += action_name;
|
||||||
|
ui += "'/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ui += "<menuitem action='";
|
|
||||||
ui += action_name;
|
|
||||||
ui += "'/>\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui += "</menu>\n</menu>\n</menubar>\n";
|
ui += "</menu>\n</menu>\n</menubar>\n";
|
||||||
|
|
|
||||||
|
|
@ -536,6 +536,31 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationTimeAxisView::reset_objects (PointSelection& selection)
|
||||||
|
{
|
||||||
|
for (vector<AutomationLine*>::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||||
|
reset_objects_one ((**i), selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection& selection)
|
||||||
|
{
|
||||||
|
AutomationList& alist (line.the_list());
|
||||||
|
|
||||||
|
_session.add_undo (alist.get_memento());
|
||||||
|
|
||||||
|
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
|
||||||
|
|
||||||
|
if (&(*i).track != this) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
alist.reset_range ((*i).start, (*i).end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AutomationTimeAxisView::cut_copy_clear_objects (PointSelection& selection, CutCopyOp op)
|
AutomationTimeAxisView::cut_copy_clear_objects (PointSelection& selection, CutCopyOp op)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
bool cut_copy_clear (Selection&, Editing::CutCopyOp);
|
bool cut_copy_clear (Selection&, Editing::CutCopyOp);
|
||||||
bool cut_copy_clear_objects (PointSelection&, Editing::CutCopyOp);
|
bool cut_copy_clear_objects (PointSelection&, Editing::CutCopyOp);
|
||||||
bool paste (jack_nframes_t, float times, Selection&, size_t nth);
|
bool paste (jack_nframes_t, float times, Selection&, size_t nth);
|
||||||
|
void reset_objects (PointSelection&);
|
||||||
|
|
||||||
void add_ghost (GhostRegion*);
|
void add_ghost (GhostRegion*);
|
||||||
void remove_ghost (GhostRegion*);
|
void remove_ghost (GhostRegion*);
|
||||||
|
|
@ -105,6 +106,7 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
bool cut_copy_clear_one (AutomationLine&, Selection&, Editing::CutCopyOp);
|
bool cut_copy_clear_one (AutomationLine&, Selection&, Editing::CutCopyOp);
|
||||||
bool cut_copy_clear_objects_one (AutomationLine&, PointSelection&, Editing::CutCopyOp);
|
bool cut_copy_clear_objects_one (AutomationLine&, PointSelection&, Editing::CutCopyOp);
|
||||||
bool paste_one (AutomationLine&, jack_nframes_t, float times, Selection&, size_t nth);
|
bool paste_one (AutomationLine&, jack_nframes_t, float times, Selection&, size_t nth);
|
||||||
|
void reset_objects_one (AutomationLine&, PointSelection&);
|
||||||
|
|
||||||
virtual void set_automation_state (ARDOUR::AutoState) = 0;
|
virtual void set_automation_state (ARDOUR::AutoState) = 0;
|
||||||
bool ignore_state_request;
|
bool ignore_state_request;
|
||||||
|
|
|
||||||
|
|
@ -3143,19 +3143,25 @@ Editor::set_selected_control_point_from_click (Selection::Operation op, bool wit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (with_undo) {
|
/* select this point and any others that it represents */
|
||||||
begin_reversible_command (_("set selected control point"));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (op) {
|
bool commit;
|
||||||
case Selection::Set:
|
|
||||||
break;
|
|
||||||
case Selection::Toggle:
|
|
||||||
break;
|
|
||||||
case Selection::Extend:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (with_undo) {
|
if (with_undo) {
|
||||||
|
begin_reversible_command (_("select control points"));
|
||||||
|
}
|
||||||
|
|
||||||
|
double y1, y2;
|
||||||
|
jack_nframes_t x1, x2;
|
||||||
|
|
||||||
|
x1 = pixel_to_frame (clicked_control_point->get_x() - 10);
|
||||||
|
x2 = pixel_to_frame (clicked_control_point->get_x() + 10);
|
||||||
|
y1 = clicked_control_point->get_x() - 10;
|
||||||
|
y2 = clicked_control_point->get_y() + 10;
|
||||||
|
|
||||||
|
commit = select_all_within (x1, x2, y1, y2, op);
|
||||||
|
|
||||||
|
if (with_undo && commit) {
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -841,6 +841,7 @@ class Editor : public PublicEditor
|
||||||
|
|
||||||
/* EDITING OPERATIONS */
|
/* EDITING OPERATIONS */
|
||||||
|
|
||||||
|
void reset_point_selection ();
|
||||||
void toggle_region_mute ();
|
void toggle_region_mute ();
|
||||||
void toggle_region_opaque ();
|
void toggle_region_opaque ();
|
||||||
void raise_region ();
|
void raise_region ();
|
||||||
|
|
|
||||||
|
|
@ -52,77 +52,78 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
|
||||||
|
|
||||||
switch (ev->direction) {
|
switch (ev->direction) {
|
||||||
case GDK_SCROLL_UP:
|
case GDK_SCROLL_UP:
|
||||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
|
if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
|
||||||
//if (ev->state == GDK_CONTROL_MASK) {
|
//if (ev->state == GDK_CONTROL_MASK) {
|
||||||
/* XXX
|
/* XXX
|
||||||
the ev->x will be out of step with the canvas
|
the ev->x will be out of step with the canvas
|
||||||
if we're in mid zoom, so we have to get the damn mouse
|
if we're in mid zoom, so we have to get the damn mouse
|
||||||
pointer again
|
pointer again
|
||||||
*/
|
*/
|
||||||
track_canvas.get_pointer (x, y);
|
track_canvas.get_pointer (x, y);
|
||||||
track_canvas.window_to_world (x, y, wx, wy);
|
track_canvas.window_to_world (x, y, wx, wy);
|
||||||
wx += horizontal_adjustment.get_value();
|
wx += horizontal_adjustment.get_value();
|
||||||
wy += vertical_adjustment.get_value();
|
wy += vertical_adjustment.get_value();
|
||||||
|
|
||||||
GdkEvent event;
|
GdkEvent event;
|
||||||
event.type = GDK_BUTTON_RELEASE;
|
event.type = GDK_BUTTON_RELEASE;
|
||||||
event.button.x = wx;
|
event.button.x = wx;
|
||||||
event.button.y = wy;
|
event.button.y = wy;
|
||||||
|
|
||||||
jack_nframes_t where = event_frame (&event, 0, 0);
|
jack_nframes_t where = event_frame (&event, 0, 0);
|
||||||
temporal_zoom_to_frame (true, where);
|
temporal_zoom_to_frame (true, where);
|
||||||
return true;
|
return true;
|
||||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
|
||||||
if (!current_stepping_trackview) {
|
if (!current_stepping_trackview) {
|
||||||
step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
|
step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
|
||||||
if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
|
if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
gettimeofday (&last_track_height_step_timestamp, 0);
|
||||||
|
current_stepping_trackview->step_height (true);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
scroll_tracks_up_line ();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
gettimeofday (&last_track_height_step_timestamp, 0);
|
break;
|
||||||
current_stepping_trackview->step_height (true);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
scroll_tracks_up_line ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GDK_SCROLL_DOWN:
|
case GDK_SCROLL_DOWN:
|
||||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
|
if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
|
||||||
//if (ev->state == GDK_CONTROL_MASK) {
|
//if (ev->state == GDK_CONTROL_MASK) {
|
||||||
track_canvas.get_pointer (x, y);
|
track_canvas.get_pointer (x, y);
|
||||||
track_canvas.window_to_world (x, y, wx, wy);
|
track_canvas.window_to_world (x, y, wx, wy);
|
||||||
wx += horizontal_adjustment.get_value();
|
wx += horizontal_adjustment.get_value();
|
||||||
wy += vertical_adjustment.get_value();
|
wy += vertical_adjustment.get_value();
|
||||||
|
|
||||||
GdkEvent event;
|
GdkEvent event;
|
||||||
event.type = GDK_BUTTON_RELEASE;
|
event.type = GDK_BUTTON_RELEASE;
|
||||||
event.button.x = wx;
|
event.button.x = wx;
|
||||||
event.button.y = wy;
|
event.button.y = wy;
|
||||||
|
|
||||||
jack_nframes_t where = event_frame (&event, 0, 0);
|
jack_nframes_t where = event_frame (&event, 0, 0);
|
||||||
temporal_zoom_to_frame (false, where);
|
temporal_zoom_to_frame (false, where);
|
||||||
return true;
|
return true;
|
||||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
|
||||||
if (!current_stepping_trackview) {
|
if (!current_stepping_trackview) {
|
||||||
step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
|
step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
|
||||||
if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
|
if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
gettimeofday (&last_track_height_step_timestamp, 0);
|
||||||
|
current_stepping_trackview->step_height (false);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
scroll_tracks_down_line ();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
gettimeofday (&last_track_height_step_timestamp, 0);
|
break;
|
||||||
current_stepping_trackview->step_height (false);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
scroll_tracks_down_line ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* no left/right handling yet */
|
/* no left/right handling yet */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -547,6 +548,12 @@ Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, C
|
||||||
clicked_regionview = 0;
|
clicked_regionview = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GDK_SCROLL_UP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_SCROLL_DOWN:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
||||||
case PanAutomationControlPointItem:
|
case PanAutomationControlPointItem:
|
||||||
case RedirectAutomationControlPointItem:
|
case RedirectAutomationControlPointItem:
|
||||||
if ((cp = static_cast<ControlPoint *> (item->get_data ("control_point"))) != 0) {
|
if ((cp = static_cast<ControlPoint *> (item->get_data ("control_point"))) != 0) {
|
||||||
set_selected_control_point_from_click (Keyboard::selection_type (event->button.state), true);
|
set_selected_control_point_from_click (Keyboard::selection_type (event->button.state), false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2495,13 +2495,26 @@ Editor::control_point_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent*
|
||||||
cp->line.point_drag (*cp, cx_frames , fraction, push);
|
cp->line.point_drag (*cp, cx_frames , fraction, push);
|
||||||
|
|
||||||
set_verbose_canvas_cursor_text (cp->line.get_verbose_cursor_string (fraction));
|
set_verbose_canvas_cursor_text (cp->line.get_verbose_cursor_string (fraction));
|
||||||
|
|
||||||
|
drag_info.first_move = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::control_point_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
Editor::control_point_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||||
{
|
{
|
||||||
ControlPoint* cp = reinterpret_cast<ControlPoint *> (drag_info.data);
|
ControlPoint* cp = reinterpret_cast<ControlPoint *> (drag_info.data);
|
||||||
control_point_drag_motion_callback (item, event);
|
|
||||||
|
if (drag_info.first_move) {
|
||||||
|
|
||||||
|
/* just a click */
|
||||||
|
|
||||||
|
if ((event->type == GDK_BUTTON_RELEASE) && (event->button.button == 1) && Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) {
|
||||||
|
reset_point_selection ();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
control_point_drag_motion_callback (item, event);
|
||||||
|
}
|
||||||
cp->line.end_drag (cp);
|
cp->line.end_drag (cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1351,18 +1351,27 @@ Editor::select_all_within (jack_nframes_t start, jack_nframes_t end, double top,
|
||||||
}
|
}
|
||||||
(*iter)->get_selectables (start, end, top, bot, touched);
|
(*iter)->get_selectables (start, end, top, bot, touched);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cerr << "select all within found " << touched.size() << endl;
|
||||||
|
|
||||||
begin_reversible_command (_("select all within"));
|
begin_reversible_command (_("select all within"));
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Selection::Toggle:
|
case Selection::Toggle:
|
||||||
|
cerr << "toggle\n";
|
||||||
selection->add (touched);
|
selection->add (touched);
|
||||||
break;
|
break;
|
||||||
case Selection::Set:
|
case Selection::Set:
|
||||||
|
cerr << "set\n";
|
||||||
selection->set (touched);
|
selection->set (touched);
|
||||||
break;
|
break;
|
||||||
case Selection::Extend:
|
case Selection::Extend:
|
||||||
|
cerr << "extend\n";
|
||||||
/* not defined yet */
|
/* not defined yet */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cerr << "selection now has " << selection->points.size() << endl;
|
||||||
|
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
return !touched.empty();
|
return !touched.empty();
|
||||||
}
|
}
|
||||||
|
|
@ -3148,6 +3157,23 @@ Editor::duplicate_selection (float times)
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::reset_point_selection ()
|
||||||
|
{
|
||||||
|
/* reset all selected points to the relevant default value */
|
||||||
|
|
||||||
|
cerr << "point selection has " << selection->points.size() << " entries\n";
|
||||||
|
|
||||||
|
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
|
||||||
|
|
||||||
|
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(&(*i).track);
|
||||||
|
|
||||||
|
if (atv) {
|
||||||
|
atv->reset_objects (selection->points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::center_playhead ()
|
Editor::center_playhead ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -633,6 +633,8 @@ Selection::add (list<Selectable*>& selectables)
|
||||||
if (!autos.empty()) {
|
if (!autos.empty()) {
|
||||||
add (autos);
|
add (autos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cerr << "Selection @ " << this << " has " << points.size() << " points\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -651,6 +653,6 @@ Selection::add (vector<AutomationSelectable*>& autos)
|
||||||
points.push_back (**i);
|
points.push_back (**i);
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
PointsChanged ();
|
PointsChanged ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,10 +83,11 @@ class ControlProtocol : public sigc::trackable, public BasicUI {
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
struct ControlProtocolDescriptor {
|
struct ControlProtocolDescriptor {
|
||||||
const char* name; /* descriptive */
|
const char* name; /* descriptive */
|
||||||
const char* id; /* unique and version-specific */
|
const char* id; /* unique and version-specific */
|
||||||
void* ptr; /* protocol can store a value here */
|
void* ptr; /* protocol can store a value here */
|
||||||
void* module; /* not for public access */
|
void* module; /* not for public access */
|
||||||
|
int mandatory; /* if non-zero, always load and do not make optional */
|
||||||
ControlProtocol* (*initialize)(ControlProtocolDescriptor*,Session*);
|
ControlProtocol* (*initialize)(ControlProtocolDescriptor*,Session*);
|
||||||
void (*destroy)(ControlProtocolDescriptor*,ControlProtocol*);
|
void (*destroy)(ControlProtocolDescriptor*,ControlProtocol*);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ struct ControlProtocolInfo {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string path;
|
std::string path;
|
||||||
bool requested;
|
bool requested;
|
||||||
|
bool mandatory;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ControlProtocolManager : public sigc::trackable, public Stateful
|
class ControlProtocolManager : public sigc::trackable, public Stateful
|
||||||
|
|
@ -35,6 +36,7 @@ struct ControlProtocolInfo {
|
||||||
void set_session (Session&);
|
void set_session (Session&);
|
||||||
void discover_control_protocols (std::string search_path);
|
void discover_control_protocols (std::string search_path);
|
||||||
void foreach_known_protocol (sigc::slot<void,const ControlProtocolInfo*>);
|
void foreach_known_protocol (sigc::slot<void,const ControlProtocolInfo*>);
|
||||||
|
void load_mandatory_protocols ();
|
||||||
|
|
||||||
ControlProtocol* instantiate (ControlProtocolInfo&);
|
ControlProtocol* instantiate (ControlProtocolInfo&);
|
||||||
int teardown (ControlProtocolInfo&);
|
int teardown (ControlProtocolInfo&);
|
||||||
|
|
|
||||||
|
|
@ -163,8 +163,10 @@ ControlProtocol::route_get_rec_enable (uint32_t table_index)
|
||||||
AudioTrack* at = dynamic_cast<AudioTrack*>(r);
|
AudioTrack* at = dynamic_cast<AudioTrack*>(r);
|
||||||
|
|
||||||
if (at) {
|
if (at) {
|
||||||
at->record_enabled ();
|
return at->record_enabled ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ ControlProtocolManager::set_session (Session& s)
|
||||||
_session->going_away.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
|
_session->going_away.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
|
||||||
|
|
||||||
for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
|
for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
|
||||||
if ((*i)->requested) {
|
if ((*i)->requested || (*i)->mandatory) {
|
||||||
instantiate (**i);
|
instantiate (**i);
|
||||||
(*i)->requested = false;
|
(*i)->requested = false;
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +102,10 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cpi.mandatory) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
|
cpi.descriptor->destroy (cpi.descriptor, cpi.protocol);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -124,6 +128,21 @@ static bool protocol_filter (const string& str, void *arg)
|
||||||
return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
|
return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ControlProtocolManager::load_mandatory_protocols ()
|
||||||
|
{
|
||||||
|
if (_session == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
|
||||||
|
if ((*i)->mandatory && ((*i)->protocol == 0)) {
|
||||||
|
info << string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name) << endmsg;
|
||||||
|
instantiate (**i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ControlProtocolManager::discover_control_protocols (string path)
|
ControlProtocolManager::discover_control_protocols (string path)
|
||||||
{
|
{
|
||||||
|
|
@ -156,13 +175,13 @@ ControlProtocolManager::control_protocol_discover (string path)
|
||||||
info->path = path;
|
info->path = path;
|
||||||
info->protocol = 0;
|
info->protocol = 0;
|
||||||
info->requested = false;
|
info->requested = false;
|
||||||
|
info->mandatory = descriptor->mandatory;
|
||||||
|
|
||||||
control_protocol_info.push_back (info);
|
control_protocol_info.push_back (info);
|
||||||
|
|
||||||
cerr << "discovered control surface protocol \"" << info->name << '"' << endl;
|
cerr << "discovered control surface protocol \"" << info->name << '"' << endl;
|
||||||
|
|
||||||
dlclose (descriptor->module);
|
dlclose (descriptor->module);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ static ControlProtocolDescriptor generic_midi_descriptor = {
|
||||||
id : "uri://ardour.org/surfaces/generic_midi:0",
|
id : "uri://ardour.org/surfaces/generic_midi:0",
|
||||||
ptr : 0,
|
ptr : 0,
|
||||||
module : 0,
|
module : 0,
|
||||||
|
mandatory : 0,
|
||||||
initialize : new_generic_midi_protocol,
|
initialize : new_generic_midi_protocol,
|
||||||
destroy : delete_generic_midi_protocol
|
destroy : delete_generic_midi_protocol
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@ static ControlProtocolDescriptor tranzport_descriptor = {
|
||||||
id : "uri://ardour.org/surfaces/tranzport:0",
|
id : "uri://ardour.org/surfaces/tranzport:0",
|
||||||
ptr : 0,
|
ptr : 0,
|
||||||
module : 0,
|
module : 0,
|
||||||
|
mandatory : 1,
|
||||||
initialize : new_tranzport_protocol,
|
initialize : new_tranzport_protocol,
|
||||||
destroy : delete_tranzport_protocol
|
destroy : delete_tranzport_protocol
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue