2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
10 #include <proto/utility.h>
12 #include "camd_intern.h"
17 # include AROS_DEBUG_H_FILE
21 * CLSemaphore must be obtained and the clusters mutex must
22 * not be exclusive locked.
24 void RemoveCluster(struct MidiCluster
*cluster
,struct CamdBase
*CamdBase
){
26 struct ClusterNotifyNode
*cn
;
28 if(cluster
==NULL
) return;
30 Remove(&cluster
->mcl_Node
);
32 for(node
=CB(CamdBase
)->clusnotifynodes
.lh_Head
; node
->ln_Succ
; node
=node
->ln_Succ
)
34 cn
=(struct ClusterNotifyNode
*)node
;
35 Signal(cn
->cnn_Task
, 1L << cn
->cnn_SigBit
);
39 if(cluster
->mcl_Node
.ln_Name
!=NULL
){
40 FreeVec(cluster
->mcl_Node
.ln_Name
);
42 FreeMem(cluster
,sizeof(struct MyMidiCluster
));
48 * CLSemaphore must be obtained and the clusters mutex must
49 * not be exclusive locked. The link must not be freed before calling.
51 * A cluster can never have both a hardware receiver and sender.
53 void LinkHasBeenRemovedFromCluster(struct MidiCluster
*cluster
,struct CamdBase
*CamdBase
){
55 struct DriverData
*driverdata
;
57 if( ! (IsListEmpty(&cluster
->mcl_Receivers
))){
58 node
=cluster
->mcl_Receivers
.lh_Head
;
60 while(node
->ln_Succ
!=NULL
){
61 if(node
->ln_Type
==NT_USER
-MLTYPE_NTypes
){
63 /* We now know that the cluster has a hardware-receiver. */
65 if(IsListEmpty(&cluster
->mcl_Senders
)){
67 /* And we now know that the cluster has no senders. */
69 driverdata
=(struct DriverData
*)cluster
->mcl_Receivers
.lh_Head
;
71 /* We mark the hardware-receiver not to be in use. */
73 if(driverdata
->isOutOpen
==TRUE
){
74 driverdata
->isOutOpen
=FALSE
;
76 /* And we close it if the hardware-sender is not in use either. */
78 if(driverdata
->isInOpen
==FALSE
){
79 CloseDriver(driverdata
,CamdBase
);
92 if( ! (IsListEmpty(&cluster
->mcl_Senders
))){
94 node
=cluster
->mcl_Senders
.lh_Head
;
96 while(node
->ln_Succ
!=NULL
){
97 if(node
->ln_Type
==NT_USER
-MLTYPE_NTypes
){
99 /* We now now that the cluster only has a hardware-sender. */
101 if(IsListEmpty(&cluster
->mcl_Receivers
)){
103 /* And we now know that the cluster has no senders. */
105 driverdata
=(struct DriverData
*)cluster
->mcl_Senders
.lh_Head
;
106 driverdata
=(struct DriverData
*)(((char *)driverdata
-sizeof(struct Node
)));
107 /* We mark the hardware-sender not to be in use. */
109 if(driverdata
->isInOpen
==TRUE
){
110 driverdata
->isInOpen
=FALSE
;
112 /* And we close it if the hardware-receiver is not in use either. */
114 if(driverdata
->isOutOpen
==FALSE
){
115 CloseDriver(driverdata
,CamdBase
);
129 (IsListEmpty(&cluster
->mcl_Receivers
)) &&
130 (IsListEmpty(&cluster
->mcl_Senders
))
132 RemoveCluster(cluster
,CamdBase
);
138 CLSemaphore must be obtained first.
141 struct MidiCluster
*NewCluster(char *name
,struct CamdBase
*CamdBase
){
142 struct MyMidiCluster
*mymidicluster
;
143 struct MidiCluster
*midicluster
;
145 struct ClusterNotifyNode
*cn
;
148 mymidicluster
=AllocMem(sizeof(struct MyMidiCluster
),MEMF_ANY
| MEMF_CLEAR
| MEMF_PUBLIC
);
150 if(mymidicluster
==NULL
) return NULL
;
152 InitSemaphore(&mymidicluster
->semaphore
);
154 midicluster
=&mymidicluster
->cluster
;
156 midicluster
->mcl_Node
.ln_Name
=AllocVec(mystrlen(name
) + 1,MEMF_ANY
|MEMF_PUBLIC
);
158 if(midicluster
->mcl_Node
.ln_Name
==NULL
){
159 FreeMem(midicluster
,sizeof(struct MyMidiCluster
));
163 mysprintf(CamdBase
,midicluster
->mcl_Node
.ln_Name
,"%s",name
);
165 NEWLIST(&midicluster
->mcl_Receivers
);
166 NEWLIST(&midicluster
->mcl_Senders
);
168 NEWLIST(midicluster
->mcl_Receivers
);
169 NEWLIST(midicluster
->mcl_Senders
);
171 AddTail(&CB(CamdBase
)->midiclusters
,&midicluster
->mcl_Node
);
173 for(node
=CB(CamdBase
)->clusnotifynodes
.lh_Head
; node
->ln_Succ
; node
=node
->ln_Succ
)
175 cn
=(struct ClusterNotifyNode
*)node
;
176 Signal(cn
->cnn_Task
,1L<<cn
->cnn_SigBit
);
185 CLSemaphore must have been obtained before calling.
187 struct DriverData
*FindReceiverDriverInCluster(struct MidiCluster
*cluster
){
190 if( ! (IsListEmpty(&cluster
->mcl_Receivers
))){
191 node
=cluster
->mcl_Receivers
.lh_Head
;
193 while(node
->ln_Succ
!=NULL
){
194 if(node
->ln_Type
==NT_USER
-MLTYPE_NTypes
) return (struct DriverData
*)node
;
202 CLSemaphore must have been obtained before calling.
205 struct DriverData
*FindSenderDriverInCluster(struct MidiCluster
*cluster
){
208 if( ! (IsListEmpty(&cluster
->mcl_Senders
))){
209 node
=cluster
->mcl_Senders
.lh_Head
;
211 while(node
->ln_Succ
!=NULL
){
212 if(node
->ln_Type
==NT_USER
-MLTYPE_NTypes
){
213 return (struct DriverData
*)(((char *)node
-sizeof(struct Node
)));
223 CLSemaphore must have been obtained before calling.
224 The clusters exclusive mutex must not have be obtained.
227 BOOL
AddClusterReceiver(
228 struct MidiCluster
*cluster
,
231 struct CamdBase
*CamdBase
233 struct MidiLink
*midilink
;
234 struct DriverData
*driverdata
;
235 struct MyMidiCluster
*mycluster
=(struct MyMidiCluster
*)cluster
;
237 if(node
->ln_Type
!=NT_USER
-MLTYPE_NTypes
){
238 driverdata
=FindSenderDriverInCluster(cluster
);
239 if(driverdata
!=NULL
){
240 if(driverdata
->isInOpen
==FALSE
&& driverdata
->isOutOpen
==FALSE
){
241 if(OpenDriver(driverdata
,ErrorCode
,CamdBase
)==FALSE
){
245 driverdata
->isInOpen
=TRUE
;
248 midilink
=(struct MidiLink
*)node
;
249 ObtainSemaphore(&mycluster
->semaphore
);
250 midilink
->ml_Location
=cluster
;
252 /* The receiver is a hardware-receiver, not a midilink. */
253 ObtainSemaphore(&mycluster
->semaphore
);
256 Enqueue(&cluster
->mcl_Receivers
,node
);
257 ReleaseSemaphore(&mycluster
->semaphore
);
264 CLSemaphore must have been obtained before calling.
267 BOOL
AddClusterSender(
268 struct MidiCluster
*cluster
,
271 struct CamdBase
*CamdBase
273 struct MidiLink
*midilink
;
274 struct DriverData
*driverdata
;
276 if(node
->ln_Type
!=NT_USER
-MLTYPE_NTypes
){
277 driverdata
=FindReceiverDriverInCluster(cluster
);
278 if(driverdata
!=NULL
){
279 if(driverdata
->isInOpen
==FALSE
&& driverdata
->isOutOpen
==FALSE
){
280 if(OpenDriver(driverdata
,ErrorCode
,CamdBase
)==FALSE
){
283 driverdata
->isOutOpen
=TRUE
;
286 midilink
=(struct MidiLink
*)node
;
287 midilink
->ml_Location
=cluster
;
290 Enqueue(&cluster
->mcl_Senders
,node
);
297 CLSemaphore must have been obtained before calling.
300 BOOL
SetClusterForLink(
301 struct MidiLink
*midilink
,
304 struct CamdBase
*CamdBase
306 struct MidiCluster
*cluster
;
307 ULONG type
=midilink
->ml_Node
.ln_Type
;
310 UnlinkMidiLink(midilink
,FALSE
,CamdBase
);
312 midilink
->ml_Location
=NULL
;
315 cluster
=(struct MidiCluster
*)FindName(&CB(CamdBase
)->midiclusters
,name
);
319 cluster
=NewCluster(name
,CamdBase
);
323 *ErrorCode
=CME_NoMem
;
329 if(type
==NT_USER
-MLTYPE_Receiver
){
331 if(AddClusterReceiver(cluster
,&midilink
->ml_Node
,ErrorCode
,CamdBase
)==FALSE
){
336 if(AddClusterSender(cluster
,&midilink
->ml_Node
,ErrorCode
,CamdBase
)==FALSE
){