xref: /haiku/src/servers/midi/MidiServerApp.h (revision d5cd5d63ff0ad395989db6cf4841a64d5b545d1d)
1 /*
2  * Copyright (c) 2002-2003 Matthijs Hollemans
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #ifndef MIDI_SERVER_APP_H
24 #define MIDI_SERVER_APP_H
25 
26 #include <Application.h>
27 #include <List.h>
28 
29 #include "DeviceWatcher.h"
30 
31 struct app_t;
32 struct endpoint_t;
33 
34 // The heart of the midi_server. This BApplication subclass
35 // keeps the roster of endpoints and applications, processes
36 // incoming messages from libmidi2.so, and notifies the apps
37 // when something interesting happens.
38 class MidiServerApp : public BApplication
39 {
40 public:
41 
42 	MidiServerApp();
43 	virtual ~MidiServerApp();
44 
45 	virtual void AboutRequested();
46 	virtual void MessageReceived(BMessage* msg);
47 
48 private:
49 
50 	typedef BApplication super;
51 
52 	void OnRegisterApp(BMessage* msg);
53 	void OnCreateEndpoint(BMessage* msg);
54 	void OnDeleteEndpoint(BMessage* msg);
55 	void OnPurgeEndpoint(BMessage* msg);
56 	void OnChangeEndpoint(BMessage* msg);
57 	void OnConnectDisconnect(BMessage* msg);
58 
59 	// Sends an app MSG_ENDPOINT_CREATED notifications for
60 	// all current endpoints. Used when the app registers.
61 	bool SendAllEndpoints(app_t* app);
62 
63 	// Sends an app MSG_ENDPOINTS_CONNECTED notifications for
64 	// all current connections. Used when the app registers.
65 	bool SendAllConnections(app_t* app);
66 
67 	// Adds the specified endpoint to the roster, and notifies
68 	// all other applications about this event.
69 	void AddEndpoint(BMessage* msg, endpoint_t* endp);
70 
71 	// Removes an endpoint from the roster, and notifies all
72 	// other apps about this event. "app" is the application
73 	// that the endpoint belongs to; if it is NULL, the app
74 	// no longer exists and we're purging the endpoint.
75 	void RemoveEndpoint(app_t* app, endpoint_t* endp);
76 
77 	// Removes a consumer from the list of connections of
78 	// all the producers it is connected to, just before
79 	// we remove it from the roster.
80 	void DisconnectDeadConsumer(endpoint_t* cons);
81 
82 	// Fills up a MSG_ENDPOINT_CREATED message.
83 	void MakeCreatedNotification(BMessage* msg, endpoint_t* endp);
84 
85 	// Fills up a MSG_ENDPOINTS_(DIS)CONNECTED message.
86 	void MakeConnectedNotification(
87 		BMessage* msg, endpoint_t* prod, endpoint_t* cons, bool mustConnect);
88 
89 	// Figures out which application a message came from.
90 	// Returns NULL if the application is not registered.
91 	app_t* WhichApp(BMessage* msg);
92 
93 	// Looks at the "midi:id" field from a message, and returns
94 	// the endpoint object that corresponds to that ID. It also
95 	// checks whether the application specified by "app" really
96 	// owns the endpoint. Returns NULL on error.
97 	endpoint_t* WhichEndpoint(BMessage* msg, app_t* app);
98 
99 	// Returns the endpoint with the specified ID, or
100 	// NULL if no such endpoint exists on the roster.
101 	endpoint_t* FindEndpoint(int32 id);
102 
103 	// Sends notification messages to all registered apps,
104 	// except to the application that triggered the event.
105 	// The "except" app is allowed to be NULL.
106 	void NotifyAll(BMessage* msg, app_t* except);
107 
108 	// Sends a notification message to an application, which is
109 	// not necessarily registered yet. Applications never reply
110 	// to such notification messages.
111 	bool SendNotification(app_t* app, BMessage* msg);
112 
113 	// Sends a reply to a request made by an application.
114 	// If "app" is NULL, the application is not registered
115 	// (and the reply should contain an error code).
116 	bool SendReply(app_t* app, BMessage* msg, BMessage* reply);
117 
118 	// Removes an app and all of its endpoints from the roster
119 	// if a reply or notification message cannot be delivered.
120 	// (Waiting for communications to fail is actually our only
121 	// way to get rid of stale endpoints.)
122 	void DeliveryError(app_t* app);
123 
124 	int32 CountApps();
125 	app_t* AppAt(int32 index);
126 
127 	int32 CountEndpoints();
128 	endpoint_t* EndpointAt(int32 index);
129 
130 	int32 CountConnections(endpoint_t* prod);
131 	endpoint_t* ConnectionAt(endpoint_t* prod, int32 index);
132 
133 	// The registered applications.
134 	BList apps;
135 
136 	// All the endpoints in the system.
137 	BList endpoints;
138 
139 	// The ID we will assign to the next new endpoint.
140 	int32 nextId;
141 
142 	// Creates endpoints for /dev/midi drivers.
143 	DeviceWatcher devWatcher;
144 
145 	#ifdef DEBUG
146 	void DumpApps();
147 	void DumpEndpoints();
148 	#endif
149 };
150 
151 #endif // MIDI_SERVER_APP_H
152