+ // the ports take time to release and we may be rebuilding right away
+ // in the case of changing devices.
+ g_usleep (10000);
+ DEBUG_TRACE (DEBUG::MackieControl, "Surface::~Surface done\n");
+}
+
+bool
+Surface::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
+{
+ if (!_port) {
+ return false;
+ }
+
+ string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (_port->input_name());
+ string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (_port->output_name());
+
+ if (ni == name1 || ni == name2) {
+ if (yn) {
+ connection_state |= InputConnected;
+ } else {
+ connection_state &= ~InputConnected;
+ }
+ } else if (no == name1 || no == name2) {
+ if (yn) {
+ connection_state |= OutputConnected;
+ } else {
+ connection_state &= ~OutputConnected;
+ }
+ } else {
+ /* not our ports */
+ return false;
+ }
+
+ if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
+
+ /* this will send a device query message, which should
+ result in a response that will kick off device type
+ discovery and activation of the surface(s).
+
+ The intended order of events is:
+
+ - each surface sends a device query message
+ - devices respond with either MCP or LCP response (sysex in both
+ cases)
+ - sysex message causes Surface::turn_it_on() which tells the
+ MCP object that the surface is ready, and sets up strip
+ displays and binds faders and buttons for that surface
+
+ In the case of LCP, where this is a handshake process that could
+ fail, the response process to the initial sysex after a device query
+ will mark the surface inactive, which won't shut anything down
+ but will stop any writes to the device.
+
+ Note: there are no known cases of the handshake process failing.
+
+ We actually can't initiate this in this callback, so we have
+ to queue it with the MCP event loop.
+ */
+
+ /* XXX this is a horrible hack. Without a short sleep here,
+ something prevents the device wakeup messages from being
+ sent and/or the responses from being received.
+ */
+
+ g_usleep (100000);
+ connected ();
+
+ } else {
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 disconnected (input or output or both)\n", _name));
+ _active = false;
+ }
+
+ return true; /* connection status changed */
+}
+
+XMLNode&
+Surface::get_state()
+{
+ XMLNode* node = new XMLNode (X_("Surface"));
+ node->add_property (X_("name"), _name);
+ node->add_child_nocopy (_port->get_state());
+ return *node;
+}
+
+int
+Surface::set_state (const XMLNode& node, int version)
+{
+ /* Look for a node named after the device we're part of */
+
+ XMLNodeList const& children = node.children();
+ XMLNode* mynode = 0;
+
+ for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
+ XMLProperty const* prop = (*c)->property (X_("name"));
+ if (prop) {
+ if (prop->value() == _name) {
+ mynode = *c;
+ break;
+ }
+ }
+ }
+
+ if (!mynode) {
+ return 0;
+ }
+
+ XMLNode* portnode = mynode->child (X_("Port"));
+ if (portnode) {
+ if (_port->set_state (*portnode, version)) {
+ return -1;
+ }
+ }
+
+ return 0;