headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / midi2 / MidiProducer.cpp
blob0c491240811cc04aff2c9bdb219f3a9ccc8e573f
1 /*
2 * Copyright 2006, Haiku.
3 *
4 * Copyright (c) 2002-2003 Matthijs Hollemans
5 * Distributed under the terms of the MIT License.
7 * Authors:
8 * Matthijs Hollemans
9 */
11 #include "debug.h"
12 #include <MidiConsumer.h>
13 #include <MidiProducer.h>
14 #include <MidiRoster.h>
15 #include "MidiRosterLooper.h"
16 #include "protocol.h"
19 status_t
20 BMidiProducer::Connect(BMidiConsumer* cons)
22 if (cons == NULL) {
23 WARN("Connect() does not accept a NULL consumer")
24 return B_BAD_VALUE;
26 if (!IsValid() || !cons->IsValid()) {
27 return B_ERROR;
29 return SendConnectRequest(cons, true);
33 status_t
34 BMidiProducer::Disconnect(BMidiConsumer* cons)
36 if (cons == NULL) {
37 WARN("Disconnect() does not accept a NULL consumer")
38 return B_BAD_VALUE;
40 if (!IsValid() || !cons->IsValid()) {
41 return B_ERROR;
43 return SendConnectRequest(cons, false);
47 bool
48 BMidiProducer::IsConnected(BMidiConsumer* cons) const
50 bool isConnected = false;
52 if (cons != NULL) {
53 if (LockProducer()) {
54 isConnected = fConnections->HasItem(cons);
55 UnlockProducer();
59 return isConnected;
63 BList*
64 BMidiProducer::Connections() const
66 BList* list = new BList();
68 if (LockProducer()) {
69 for (int32 t = 0; t < CountConsumers(); ++t) {
70 BMidiConsumer* cons = ConsumerAt(t);
71 cons->Acquire();
72 list->AddItem(cons);
75 UnlockProducer();
78 return list;
82 BMidiProducer::BMidiProducer(const char* name)
83 : BMidiEndpoint(name),
84 fLocker("MidiProducerLock")
86 fIsConsumer = false;
87 fConnections = new BList();
91 BMidiProducer::~BMidiProducer()
93 delete fConnections;
97 void BMidiProducer::_Reserved1() { }
98 void BMidiProducer::_Reserved2() { }
99 void BMidiProducer::_Reserved3() { }
100 void BMidiProducer::_Reserved4() { }
101 void BMidiProducer::_Reserved5() { }
102 void BMidiProducer::_Reserved6() { }
103 void BMidiProducer::_Reserved7() { }
104 void BMidiProducer::_Reserved8() { }
107 status_t
108 BMidiProducer::SendConnectRequest(
109 BMidiConsumer* cons, bool mustConnect)
111 ASSERT(cons != NULL)
113 BMessage msg, reply;
115 if (mustConnect) {
116 msg.what = MSG_CONNECT_ENDPOINTS;
117 } else {
118 msg.what = MSG_DISCONNECT_ENDPOINTS;
121 msg.AddInt32("midi:producer", ID());
122 msg.AddInt32("midi:consumer", cons->ID());
124 status_t err = BMidiRoster::MidiRoster()->SendRequest(&msg, &reply);
125 if (err != B_OK)
126 return err;
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);
137 #ifdef DEBUG
138 BMidiRoster::MidiRoster()->fLooper->DumpEndpoints();
139 #endif
142 return res;
145 return B_ERROR;
149 void
150 BMidiProducer::ConnectionMade(BMidiConsumer* consumer)
152 if (consumer == NULL)
153 return;
155 if (LockProducer()) {
156 ASSERT(!fConnections->HasItem(consumer))
158 fConnections->AddItem(consumer);
159 UnlockProducer();
162 if (IsLocal()) {
163 ((BMidiLocalProducer*) this)->Connected(consumer);
168 bool
169 BMidiProducer::ConnectionBroken(BMidiConsumer* consumer)
171 if (consumer == NULL)
172 return false;
174 bool wasConnected = false;
176 if (LockProducer()) {
177 wasConnected = fConnections->RemoveItem(consumer);
178 UnlockProducer();
181 if (wasConnected && IsLocal()) {
182 ((BMidiLocalProducer*) this)->Disconnected(consumer);
185 return wasConnected;
189 int32
190 BMidiProducer::CountConsumers() const
192 return fConnections->CountItems();
196 BMidiConsumer*
197 BMidiProducer::ConsumerAt(int32 index) const
199 ASSERT(index >= 0 && index < CountConsumers())
201 return (BMidiConsumer*) fConnections->ItemAt(index);
205 bool
206 BMidiProducer::LockProducer() const
208 return fLocker.Lock();
212 void
213 BMidiProducer::UnlockProducer() const
215 fLocker.Unlock();