2 Copyright (C) 1999 Paul Barton-Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <pbd/error.h>
25 #include <pbd/pathscanner.h>
27 #include <midi++/types.h>
28 #include <midi++/fd_midiport.h>
34 string *FD_MidiPort::midi_dirpath = 0;
35 string *FD_MidiPort::midi_filename_pattern = 0;
37 FD_MidiPort::FD_MidiPort (PortRequest &req,
38 const string &dirpath,
39 const string &pattern)
47 error << "MIDI: port device in use" << endmsg;
48 req.status = PortRequest::Busy;
51 error << "MIDI: no such port device" << endmsg;
52 req.status = PortRequest::NoSuchFile;
55 error << "MIDI: access to port denied" << endmsg;
56 req.status = PortRequest::NotAllowed;
59 req.status = PortRequest::Unknown;
63 req.status = PortRequest::OK;
65 if (midi_dirpath == 0) {
66 midi_dirpath = new string (dirpath);
67 midi_filename_pattern = new string (pattern);
70 if (req.mode & O_NONBLOCK == 0) {
71 /* we unconditionally set O_NONBLOCK during
72 open, but the request didn't ask for it,
76 int flags = fcntl (_fd, F_GETFL, 0);
77 fcntl (_fd, F_SETFL, flags & ~(O_NONBLOCK));
83 FD_MidiPort::open (PortRequest &req)
86 int mode = req.mode | O_NONBLOCK;
87 _fd = ::open (req.devname, mode);
91 FD_MidiPort::list_devices ()
96 return scanner (*midi_dirpath, *midi_filename_pattern, false, true);
100 FD_MidiPort::selectable () const
105 /* turn on non-blocking mode, since we plan to use select/poll
106 to tell us when there is data to read.
109 flags = fcntl (_fd, F_GETFL);
112 if (fcntl (_fd, F_SETFL, flags)) {
113 error << "FD_MidiPort: could not turn on non-blocking mode"
114 << " (" << strerror (errno)
126 FD_MidiPort::do_slow_write (byte *msg, unsigned int msglen)
132 for (n = 0; n < msglen; n++) {
134 if (::write (_fd, &msg[n], 1) != 1) {
139 for (i = 0; i < slowdown * 10000; i++);
143 if (n && output_parser) {
144 output_parser->raw_preparse (*output_parser, msg, n);
145 for (unsigned int i = 0; i < n; i++) {
146 output_parser->scanner (msg[i]);
148 output_parser->raw_postparse (*output_parser, msg, n);
155 FD_MidiPort::read (byte* buf, size_t max, timestamp_t timestamp)
159 if ((_mode & O_ACCMODE) == O_WRONLY) {
163 // cerr << "MIDI: read up to " << max << " from " << _fd << " (" << name() << ')' << endl;
165 if ((nread = ::read (_fd, buf, max)) > 0) {
168 // cerr << " read " << nread << endl;
171 input_parser->raw_preparse
172 (*input_parser, buf, nread);
173 for (int i = 0; i < nread; i++) {
174 input_parser->scanner (buf[i]);
176 input_parser->raw_postparse
177 (*input_parser, buf, nread);