+// wrapper for one day when strerror_r is working properly
+string fetch_errmsg (int error_number)
+{
+ char * msg = strerror (error_number);
+ return msg;
+}
+
+int
+SurfacePort::write (const MidiByteArray & mba)
+{
+ if (mba.empty()) {
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("port %1 asked to write an empty MBA\n", output_port().name()));
+ return 0;
+ }
+
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("port %1 write %2\n", output_port().name(), mba));
+
+ if (mba[0] != 0xf0 && mba.size() > 3) {
+ std::cerr << "TOO LONG WRITE: " << mba << std::endl;
+ }
+
+ /* this call relies on std::vector<T> using contiguous storage. not
+ * actually guaranteed by the standard, but way, way beyond likely.
+ */
+
+ int count = output_port().write (&mba[0], mba.size(), 0);
+
+ if (count != (int) mba.size()) {
+
+ if (errno == 0) {
+
+ cout << "port overflow on " << output_port().name() << ". Did not write all of " << mba << endl;
+
+ } else if (errno != EAGAIN) {
+ ostringstream os;
+ os << "Surface: couldn't write to port " << output_port().name();
+ os << ", error: " << fetch_errmsg (errno) << "(" << errno << ")";
+ cout << os.str() << endl;
+ }
+
+ return -1;
+ }
+
+ return 0;
+}
+
+ostream &
+Mackie::operator << (ostream & os, const SurfacePort & port)