/* * Copyright 2006, Haiku. * * Copyright (c) 2002-2003 Matthijs Hollemans * Distributed under the terms of the MIT License. * * Authors: * Matthijs Hollemans */ #include "debug.h" #include #include #include #include "MidiRosterLooper.h" #include "protocol.h" status_t BMidiProducer::Connect(BMidiConsumer* cons) { if (cons == NULL) { WARN("Connect() does not accept a NULL consumer") return B_BAD_VALUE; } if (!IsValid() || !cons->IsValid()) { return B_ERROR; } return SendConnectRequest(cons, true); } status_t BMidiProducer::Disconnect(BMidiConsumer* cons) { if (cons == NULL) { WARN("Disconnect() does not accept a NULL consumer") return B_BAD_VALUE; } if (!IsValid() || !cons->IsValid()) { return B_ERROR; } return SendConnectRequest(cons, false); } bool BMidiProducer::IsConnected(BMidiConsumer* cons) const { bool isConnected = false; if (cons != NULL) { if (LockProducer()) { isConnected = fConnections->HasItem(cons); UnlockProducer(); } } return isConnected; } BList* BMidiProducer::Connections() const { BList* list = new BList(); if (LockProducer()) { for (int32 t = 0; t < CountConsumers(); ++t) { BMidiConsumer* cons = ConsumerAt(t); cons->Acquire(); list->AddItem(cons); } UnlockProducer(); } return list; } BMidiProducer::BMidiProducer(const char* name) : BMidiEndpoint(name), fLocker("MidiProducerLock") { fIsConsumer = false; fConnections = new BList(); } BMidiProducer::~BMidiProducer() { delete fConnections; } void BMidiProducer::_Reserved1() { } void BMidiProducer::_Reserved2() { } void BMidiProducer::_Reserved3() { } void BMidiProducer::_Reserved4() { } void BMidiProducer::_Reserved5() { } void BMidiProducer::_Reserved6() { } void BMidiProducer::_Reserved7() { } void BMidiProducer::_Reserved8() { } status_t BMidiProducer::SendConnectRequest( BMidiConsumer* cons, bool mustConnect) { ASSERT(cons != NULL) BMessage msg, reply; if (mustConnect) { msg.what = MSG_CONNECT_ENDPOINTS; } else { msg.what = MSG_DISCONNECT_ENDPOINTS; } msg.AddInt32("midi:producer", ID()); msg.AddInt32("midi:consumer", cons->ID()); status_t err = BMidiRoster::MidiRoster()->SendRequest(&msg, &reply); if (err != B_OK) return err; status_t res; if (reply.FindInt32("midi:result", &res) == B_OK) { if (res == B_OK) { if (mustConnect) { ConnectionMade(cons); } else { ConnectionBroken(cons); } #ifdef DEBUG BMidiRoster::MidiRoster()->fLooper->DumpEndpoints(); #endif } return res; } return B_ERROR; } void BMidiProducer::ConnectionMade(BMidiConsumer* consumer) { if (consumer == NULL) return; if (LockProducer()) { ASSERT(!fConnections->HasItem(consumer)) fConnections->AddItem(consumer); UnlockProducer(); } if (IsLocal()) { ((BMidiLocalProducer*) this)->Connected(consumer); } } bool BMidiProducer::ConnectionBroken(BMidiConsumer* consumer) { if (consumer == NULL) return false; bool wasConnected = false; if (LockProducer()) { wasConnected = fConnections->RemoveItem(consumer); UnlockProducer(); } if (wasConnected && IsLocal()) { ((BMidiLocalProducer*) this)->Disconnected(consumer); } return wasConnected; } int32 BMidiProducer::CountConsumers() const { return fConnections->CountItems(); } BMidiConsumer* BMidiProducer::ConsumerAt(int32 index) const { ASSERT(index >= 0 && index < CountConsumers()) return (BMidiConsumer*) fConnections->ItemAt(index); } bool BMidiProducer::LockProducer() const { return fLocker.Lock(); } void BMidiProducer::UnlockProducer() const { fLocker.Unlock(); }