1/*
2 * Copyright 2006, Haiku.
3 *
4 * Copyright (c) 2002-2004 Matthijs Hollemans
5 * Distributed under the terms of the MIT License.
6 *
7 * Authors:
8 *		Matthijs Hollemans
9 */
10
11#ifndef MIDI_ROSTER_LOOPER_H
12#define MIDI_ROSTER_LOOPER_H
13
14#include <Looper.h>
15#include <Message.h>
16
17class BMidiProducer;
18class BMidiRoster;
19
20namespace BPrivate {
21
22// Receives messages from the midi_server on behalf of the
23// BMidiRoster. Also keeps track of the list of endpoints.
24class BMidiRosterLooper : public BLooper
25{
26public:
27
28	BMidiRosterLooper();
29	virtual ~BMidiRosterLooper();
30
31	// Starts up the looper.
32	bool Init(BMidiRoster* roster);
33
34	// Does the work for BMidiRoster::NextEndpoint().
35	BMidiEndpoint* NextEndpoint(int32* id);
36
37	// Finds an endpoint in our list of endpoints.
38	BMidiEndpoint* FindEndpoint(int32 id);
39
40	// Adds an endpoint to our list.
41	void AddEndpoint(BMidiEndpoint* endp);
42
43	// Removes an endpoint from our list. Throws away
44	// any connections that this endpoint is part of.
45	void RemoveEndpoint(BMidiEndpoint* endp);
46
47	// Invoked when the client app wants to be kept informed
48	// about changes in the roster. From now on, we will send
49 	// the messenger B_MIDI_EVENT notifications when something
50	// interesting happens. But first, we send a whole bunch
51	// of notifications about the registered remote endpoints,
52	// and the connections between them.
53	void StartWatching(const BMessenger* watcher);
54
55	// From now on, we will no longer send notifications to
56	// the client when something interesting happens.
57	void StopWatching();
58
59	virtual void MessageReceived(BMessage* msg);
60
61private:
62
63	friend class ::BMidiRoster;
64	friend class ::BMidiProducer;
65
66	typedef BLooper super;
67
68	void OnAppRegistered(BMessage* msg);
69	void OnEndpointCreated(BMessage* msg);
70	void OnEndpointDeleted(BMessage* msg);
71	void OnEndpointChanged(BMessage* msg);
72	void OnConnectedDisconnected(BMessage* msg);
73
74	void ChangeRegistered(BMessage* msg, BMidiEndpoint* endp);
75	void ChangeName(BMessage* msg, BMidiEndpoint* endp);
76	void ChangeProperties(BMessage* msg, BMidiEndpoint* endp);
77	void ChangeLatency(BMessage* msg, BMidiEndpoint* endp);
78
79	// Removes the consumer from the list of connections of
80	// all the producers it is connected to. Also sends out
81	// B_MIDI_EVENT "disconnected" notifications if the
82	// consumer is remote and the client is watching.
83	void DisconnectDeadConsumer(BMidiConsumer* cons);
84
85	// Sends out B_MIDI_EVENT "disconnected" notifications
86	// if the producer is remote and the client is watching.
87	void DisconnectDeadProducer(BMidiProducer* prod);
88
89	// Sends B_MIDI_EVENT notifications for all registered
90	// remote endpoints to the watcher. Used when the client
91	// calls StartWatching().
92	void AllEndpoints();
93
94	// Sends B_MIDI_EVENT notifications for the connections
95	// between all registered remote endpoints to the watcher.
96	// Used when the client calls StartWatching().
97	void AllConnections();
98
99	// Sends a B_MIDI_EVENT notification to the watcher
100	// when another application changes the attributes
101	// of one of its endpoints.
102	void ChangeEvent(BMessage* msg, BMidiEndpoint* endp);
103
104	// Sends a B_MIDI_EVENT notification to the watcher
105	// when another application connects or disconnects
106	// the two endpoints.
107	void ConnectionEvent(
108		BMidiProducer* prod, BMidiConsumer* cons, bool mustConnect);
109
110	int32 CountEndpoints();
111	BMidiEndpoint* EndpointAt(int32 index);
112
113	BMidiRoster* fRoster;
114
115	// Makes sure BMidiRoster::MidiRoster() does not return
116	// until confirmation from the midi_server is received.
117	sem_id fInitLock;
118
119	// The object we send B_MIDI_EVENT notifications to.
120	BMessenger* fWatcher;
121
122	// All the endpoints in the system, local and remote.
123	BList fEndpoints;
124
125	#ifdef DEBUG
126	void DumpEndpoints();
127	#endif
128};
129
130} // namespace BPrivate
131
132#endif // MIDI_ROSTER_LOOPER_H
133