1/* 2 * Copyright 2006, Haiku. 3 * 4 * Copyright (c) 2002-2003 Matthijs Hollemans 5 * Distributed under the terms of the MIT License. 6 * 7 * Authors: 8 * Matthijs Hollemans 9 */ 10 11#include "debug.h" 12#include <MidiConsumer.h> 13#include <MidiProducer.h> 14#include <MidiRoster.h> 15#include "MidiRosterLooper.h" 16#include "protocol.h" 17 18 19status_t 20BMidiProducer::Connect(BMidiConsumer* cons) 21{ 22 if (cons == NULL) { 23 WARN("Connect() does not accept a NULL consumer") 24 return B_BAD_VALUE; 25 } 26 if (!IsValid() || !cons->IsValid()) { 27 return B_ERROR; 28 } 29 return SendConnectRequest(cons, true); 30} 31 32 33status_t 34BMidiProducer::Disconnect(BMidiConsumer* cons) 35{ 36 if (cons == NULL) { 37 WARN("Disconnect() does not accept a NULL consumer") 38 return B_BAD_VALUE; 39 } 40 if (!IsValid() || !cons->IsValid()) { 41 return B_ERROR; 42 } 43 return SendConnectRequest(cons, false); 44} 45 46 47bool 48BMidiProducer::IsConnected(BMidiConsumer* cons) const 49{ 50 bool isConnected = false; 51 52 if (cons != NULL) { 53 if (LockProducer()) { 54 isConnected = fConnections->HasItem(cons); 55 UnlockProducer(); 56 } 57 } 58 59 return isConnected; 60} 61 62 63BList* 64BMidiProducer::Connections() const 65{ 66 BList* list = new BList(); 67 68 if (LockProducer()) { 69 for (int32 t = 0; t < CountConsumers(); ++t) { 70 BMidiConsumer* cons = ConsumerAt(t); 71 cons->Acquire(); 72 list->AddItem(cons); 73 } 74 75 UnlockProducer(); 76 } 77 78 return list; 79} 80 81 82BMidiProducer::BMidiProducer(const char* name) 83 : BMidiEndpoint(name), 84 fLocker("MidiProducerLock") 85{ 86 fIsConsumer = false; 87 fConnections = new BList(); 88} 89 90 91BMidiProducer::~BMidiProducer() 92{ 93 delete fConnections; 94} 95 96 97void BMidiProducer::_Reserved1() { } 98void BMidiProducer::_Reserved2() { } 99void BMidiProducer::_Reserved3() { } 100void BMidiProducer::_Reserved4() { } 101void BMidiProducer::_Reserved5() { } 102void BMidiProducer::_Reserved6() { } 103void BMidiProducer::_Reserved7() { } 104void BMidiProducer::_Reserved8() { } 105 106 107status_t 108BMidiProducer::SendConnectRequest( 109 BMidiConsumer* cons, bool mustConnect) 110{ 111 ASSERT(cons != NULL) 112 113 BMessage msg, reply; 114 115 if (mustConnect) { 116 msg.what = MSG_CONNECT_ENDPOINTS; 117 } else { 118 msg.what = MSG_DISCONNECT_ENDPOINTS; 119 } 120 121 msg.AddInt32("midi:producer", ID()); 122 msg.AddInt32("midi:consumer", cons->ID()); 123 124 status_t err = BMidiRoster::MidiRoster()->SendRequest(&msg, &reply); 125 if (err != B_OK) 126 return err; 127 128 status_t res; 129 if (reply.FindInt32("midi:result", &res) == B_OK) { 130 if (res == B_OK) { 131 if (mustConnect) { 132 ConnectionMade(cons); 133 } else { 134 ConnectionBroken(cons); 135 } 136 137 #ifdef DEBUG 138 BMidiRoster::MidiRoster()->fLooper->DumpEndpoints(); 139 #endif 140 } 141 142 return res; 143 } 144 145 return B_ERROR; 146} 147 148 149void 150BMidiProducer::ConnectionMade(BMidiConsumer* consumer) 151{ 152 if (consumer == NULL) 153 return; 154 155 if (LockProducer()) { 156 ASSERT(!fConnections->HasItem(consumer)) 157 158 fConnections->AddItem(consumer); 159 UnlockProducer(); 160 } 161 162 if (IsLocal()) { 163 ((BMidiLocalProducer*) this)->Connected(consumer); 164 } 165} 166 167 168bool 169BMidiProducer::ConnectionBroken(BMidiConsumer* consumer) 170{ 171 if (consumer == NULL) 172 return false; 173 174 bool wasConnected = false; 175 176 if (LockProducer()) { 177 wasConnected = fConnections->RemoveItem(consumer); 178 UnlockProducer(); 179 } 180 181 if (wasConnected && IsLocal()) { 182 ((BMidiLocalProducer*) this)->Disconnected(consumer); 183 } 184 185 return wasConnected; 186} 187 188 189int32 190BMidiProducer::CountConsumers() const 191{ 192 return fConnections->CountItems(); 193} 194 195 196BMidiConsumer* 197BMidiProducer::ConsumerAt(int32 index) const 198{ 199 ASSERT(index >= 0 && index < CountConsumers()) 200 201 return (BMidiConsumer*) fConnections->ItemAt(index); 202} 203 204 205bool 206BMidiProducer::LockProducer() const 207{ 208 return fLocker.Lock(); 209} 210 211 212void 213BMidiProducer::UnlockProducer() const 214{ 215 fLocker.Unlock(); 216} 217 218