xref: /haiku/docs/user/midi2/MidiEndpoint.dox (revision e6ecb3fc07443f15c9901127f2ca2bd8b1149953)
1*820dca4dSJohn Scipione/*!
2*820dca4dSJohn Scipione	\file MidiEndpoint.h
3*820dca4dSJohn Scipione	\ingroup midi2
4*820dca4dSJohn Scipione	\brief Defines the Baseclass of all MIDI consumers and producers.
5*820dca4dSJohn Scipione*/
6*820dca4dSJohn Scipione
7*820dca4dSJohn Scipione
8*820dca4dSJohn Scipione/*!
9*820dca4dSJohn Scipione	\class BMidiEndpoint
10*820dca4dSJohn Scipione	\ingroup midi2
11*820dca4dSJohn Scipione	\brief Base class for all MIDI endpoints.
12*820dca4dSJohn Scipione
13*820dca4dSJohn Scipione	BMidiEndpoint is the abstract base class that represents either a
14*820dca4dSJohn Scipione	producer or consumer endpoint. It may be used to obtain the state, name,
15*820dca4dSJohn Scipione	properties, or system-wide ID of the object. BMidiEndpoint also provides
16*820dca4dSJohn Scipione	the ability to change the name and properties of endpoints that were
17*820dca4dSJohn Scipione	created locally.
18*820dca4dSJohn Scipione
19*820dca4dSJohn Scipione	Remember, you cannot call the destructor of BMidiEndpoint and its
20*820dca4dSJohn Scipione	subclasses directly. Endpoint objects are destructed automatically when
21*820dca4dSJohn Scipione	their reference count drops to zero. If necessary, the destructor of a
22*820dca4dSJohn Scipione	local endpoint first breaks off any connections and Unregister()'s the
23*820dca4dSJohn Scipione	endpoint before it is deleted. However, for good style and bonus points
24*820dca4dSJohn Scipione	you should really \link BMidiProducer::Disconnect() Disconnect() \endlink
25*820dca4dSJohn Scipione	and Unregister() the object yourself and not rely on the destructor to
26*820dca4dSJohn Scipione	do this.
27*820dca4dSJohn Scipione*/
28*820dca4dSJohn Scipione
29*820dca4dSJohn Scipione/*!
30*820dca4dSJohn Scipione	\fn const char* BMidiEndpoint::Name() const
31*820dca4dSJohn Scipione	\brief Returns the name of the endpoint.
32*820dca4dSJohn Scipione
33*820dca4dSJohn Scipione	The function never returns NULL. If you created a local endpoint by
34*820dca4dSJohn Scipione	passing a \c NULL name into its constructor (or passing no name,
35*820dca4dSJohn Scipione	which is the same thing), then Name() will return an empty string,
36*820dca4dSJohn Scipione	not \c NULL.
37*820dca4dSJohn Scipione
38*820dca4dSJohn Scipione	\sa SetName()
39*820dca4dSJohn Scipione*/
40*820dca4dSJohn Scipione
41*820dca4dSJohn Scipione/*!
42*820dca4dSJohn Scipione	\fn void BMidiEndpoint::SetName(const char* name)
43*820dca4dSJohn Scipione	\brief Changes the name of the endpoint.
44*820dca4dSJohn Scipione
45*820dca4dSJohn Scipione	Names don't have to be unique, but it is recommended that you give any
46*820dca4dSJohn Scipione	endpoints you publish meaningful and unique names, so users can easily
47*820dca4dSJohn Scipione	recognize what each endpoint does. There is no limit to the size of
48*820dca4dSJohn Scipione	endpoint names.
49*820dca4dSJohn Scipione
50*820dca4dSJohn Scipione	Even though you can call this function on both remote and local objects,
51*820dca4dSJohn Scipione	you are only allowed to change the names of local endpoints; SetName()
52*820dca4dSJohn Scipione	calls on remote endpoints are ignored.
53*820dca4dSJohn Scipione
54*820dca4dSJohn Scipione	\param name The new name. If you pass \c NULL the name won't be changed.
55*820dca4dSJohn Scipione
56*820dca4dSJohn Scipione	\sa Name()
57*820dca4dSJohn Scipione*/
58*820dca4dSJohn Scipione
59*820dca4dSJohn Scipione/*!
60*820dca4dSJohn Scipione	\fn int32 BMidiEndpoint::ID() const
61*820dca4dSJohn Scipione	\brief Returns the ID of the endpoint
62*820dca4dSJohn Scipione
63*820dca4dSJohn Scipione	An ID uniquely identifies an endpoint in the system. The ID is a signed
64*820dca4dSJohn Scipione	32-bit number that is assigned by the Midi Server when the endpoint is
65*820dca4dSJohn Scipione	created. (So even if a local endpoint is not published, it still has a
66*820dca4dSJohn Scipione	unique ID.) Valid IDs range from 1 to 0x7FFFFFFF, the largest value an
67*820dca4dSJohn Scipione	int32 can have. 0 and negative values are <b>not</b> valid IDs.
68*820dca4dSJohn Scipione*/
69*820dca4dSJohn Scipione
70*820dca4dSJohn Scipione
71*820dca4dSJohn Scipione/*!
72*820dca4dSJohn Scipione	\fn bool BMidiEndpoint::IsProducer() const
73*820dca4dSJohn Scipione	\brief Determines whether this endpoint is a BMidiProducer
74*820dca4dSJohn Scipione
75*820dca4dSJohn Scipione	If it is, you can use a dynamic_cast to convert this object into a
76*820dca4dSJohn Scipione	producer:
77*820dca4dSJohn Scipione
78*820dca4dSJohn Scipione\code
79*820dca4dSJohn Scipioneif (endp->IsProducer())
80*820dca4dSJohn Scipione{
81*820dca4dSJohn Scipione    BMidiProducer* prod = dynamic_cast<BMidiProducer*>(endp);
82*820dca4dSJohn Scipione
83*820dca4dSJohn Scipione    ....
84*820dca4dSJohn Scipione
85*820dca4dSJohn Scipione}
86*820dca4dSJohn Scipione\endcode
87*820dca4dSJohn Scipione
88*820dca4dSJohn Scipione*/
89*820dca4dSJohn Scipione
90*820dca4dSJohn Scipione
91*820dca4dSJohn Scipione/*!
92*820dca4dSJohn Scipione	\fn bool BMidiEndpoint::IsConsumer() const
93*820dca4dSJohn Scipione	\brief Determines whether this endpoint is a BMidiConsumer
94*820dca4dSJohn Scipione
95*820dca4dSJohn Scipione	If it is, you can use a dynamic_cast to convert this object into a consumer:
96*820dca4dSJohn Scipione
97*820dca4dSJohn Scipione\code
98*820dca4dSJohn Scipioneif (endp->IsConsumer())
99*820dca4dSJohn Scipione{
100*820dca4dSJohn Scipione    BMidiConsumer* cons = dynamic_cast<BMidiConsumer*>(endp);
101*820dca4dSJohn Scipione
102*820dca4dSJohn Scipione    ....
103*820dca4dSJohn Scipione
104*820dca4dSJohn Scipione}
105*820dca4dSJohn Scipione\endcode
106*820dca4dSJohn Scipione
107*820dca4dSJohn Scipione*/
108*820dca4dSJohn Scipione
109*820dca4dSJohn Scipione
110*820dca4dSJohn Scipione/*!
111*820dca4dSJohn Scipione	\fn bool BMidiEndpoint::IsRemote() const
112*820dca4dSJohn Scipione	\brief Determines whether this endpoint is a proxy for a remote object.
113*820dca4dSJohn Scipione
114*820dca4dSJohn Scipione	An endpoint is "remote" when it is created by another application.
115*820dca4dSJohn Scipione	Obviously, the remote object is Register()'ed as well, otherwise you would
116*820dca4dSJohn Scipione	not be able to see it.
117*820dca4dSJohn Scipione*/
118*820dca4dSJohn Scipione
119*820dca4dSJohn Scipione
120*820dca4dSJohn Scipione/*!
121*820dca4dSJohn Scipione	\fn bool BMidiEndpoint::IsLocal() const
122*820dca4dSJohn Scipione	\brief Determines whether this endpoint represents a local object
123*820dca4dSJohn Scipione
124*820dca4dSJohn Scipione	An endpoint is "local" when it is created by this application; in other
125*820dca4dSJohn Scipione	words, a BMidiLocalConsumer or BMidiLocalProducer.
126*820dca4dSJohn Scipione*/
127*820dca4dSJohn Scipione
128*820dca4dSJohn Scipione
129*820dca4dSJohn Scipione/*!
130*820dca4dSJohn Scipione	\fn bool BMidiEndpoint::IsPersistent() const
131*820dca4dSJohn Scipione	\brief Not used.
132*820dca4dSJohn Scipione
133*820dca4dSJohn Scipione	The purpose of this function is unclear, and as a result it doesn't do
134*820dca4dSJohn Scipione	anything in the Haiku Midi Kit implementation.
135*820dca4dSJohn Scipione
136*820dca4dSJohn Scipione	\return \c false always.
137*820dca4dSJohn Scipione*/
138*820dca4dSJohn Scipione
139*820dca4dSJohn Scipione
140*820dca4dSJohn Scipione/*!
141*820dca4dSJohn Scipione	\fn bool BMidiEndpoint::IsValid() const
142*820dca4dSJohn Scipione	\brief Determines whether the endpoint still exists.
143*820dca4dSJohn Scipione
144*820dca4dSJohn Scipione	Suppose you obtained a proxy object for a remote endpoint by querying the
145*820dca4dSJohn Scipione	BMidiRoster. What if the application that published this endpoint quits,
146*820dca4dSJohn Scipione	or less drastically, Unregister()'s that endpoint? Even though you still
147*820dca4dSJohn Scipione	have a BMidiEndpoint proxy object, the real endpoint no longer exists.
148*820dca4dSJohn Scipione	You can use IsValid() to check for this.
149*820dca4dSJohn Scipione
150*820dca4dSJohn Scipione	Don't worry, operations on invalid objects, such as GetProperties(), will
151*820dca4dSJohn Scipione	return an error code (typically B_ERROR), but not cause a crash. Local
152*820dca4dSJohn Scipione	objects are always are considered to be valid, even if you did not
153*820dca4dSJohn Scipione	Register() them. (The only time a local endpoint is not valid is when there
154*820dca4dSJohn Scipione	was a problem constructing it.)
155*820dca4dSJohn Scipione
156*820dca4dSJohn Scipione	If the application that created the remote endpoint crashes, then there is
157*820dca4dSJohn Scipione	no guarantee that the Midi Server immediately recognizes this. In that
158*820dca4dSJohn Scipione	case, IsValid() may still return true. Eventually, the stale endpoint will
159*820dca4dSJohn Scipione	be removed from the roster, though. From then on, IsValid() correctly
160*820dca4dSJohn Scipione	returns \c false.
161*820dca4dSJohn Scipione*/
162*820dca4dSJohn Scipione
163*820dca4dSJohn Scipione
164*820dca4dSJohn Scipione/*!
165*820dca4dSJohn Scipione	\fn status_t BMidiEndpoint::Acquire()
166*820dca4dSJohn Scipione	\brief Increments the endpoint's reference count
167*820dca4dSJohn Scipione
168*820dca4dSJohn Scipione	Each BMidiEndpoint has a reference count associated with it, so that
169*820dca4dSJohn Scipione	BMidiRoster can do proper bookkeeping. Acquire() increments this reference
170*820dca4dSJohn Scipione	count, and Release() decrements it. Once the count reaches zero, the
171*820dca4dSJohn Scipione	endpoint is deleted.
172*820dca4dSJohn Scipione
173*820dca4dSJohn Scipione	When you are done with the endpoint, whether local or remote, you should
174*820dca4dSJohn Scipione	always Release() it!
175*820dca4dSJohn Scipione
176*820dca4dSJohn Scipione	Upon construction, local endpoints start with a reference count of 1. Any
177*820dca4dSJohn Scipione	objects you obtain from BMidiRoster using the NextXXX() or FindXXX()
178*820dca4dSJohn Scipione	functions have their reference counts incremented in the process. If you
179*820dca4dSJohn Scipione	forget to call  Release(), the objects won't be properly cleaned up and
180*820dca4dSJohn Scipione	you'll make a fool out of yourself.
181*820dca4dSJohn Scipione
182*820dca4dSJohn Scipione	After you Release() an object, you are advised not to use it any further.
183*820dca4dSJohn Scipione	If you do, your app will probably crash. That also happens if you Release()
184*820dca4dSJohn Scipione	an object too many times.
185*820dca4dSJohn Scipione
186*820dca4dSJohn Scipione	Typically, you don't need to call Acquire(), unless you have two disparate
187*820dca4dSJohn Scipione	parts of your application working with the same endpoint, and you don't
188*820dca4dSJohn Scipione	want to have to keep track of who needs to Release() the endpoint. Now you
189*820dca4dSJohn Scipione	simply have both of them release it.
190*820dca4dSJohn Scipione
191*820dca4dSJohn Scipione	\return Always returns B_OK
192*820dca4dSJohn Scipione
193*820dca4dSJohn Scipione	\sa Release()
194*820dca4dSJohn Scipione*/
195*820dca4dSJohn Scipione
196*820dca4dSJohn Scipione/*!
197*820dca4dSJohn Scipione	\fn status_t BMidiEndpoint::Release()
198*820dca4dSJohn Scipione	\brief Decrements the endpoint's reference count.
199*820dca4dSJohn Scipione
200*820dca4dSJohn Scipione	\return Always returns B_OK
201*820dca4dSJohn Scipione
202*820dca4dSJohn Scipione	\sa Acquire()
203*820dca4dSJohn Scipione*/
204*820dca4dSJohn Scipione
205*820dca4dSJohn Scipione/*!
206*820dca4dSJohn Scipione	\fn status_t BMidiEndpoint::Register()
207*820dca4dSJohn Scipione	\brief Publishes the endpoint on the roster
208*820dca4dSJohn Scipione
209*820dca4dSJohn Scipione	MIDI objects created by an application are invisible to other applications
210*820dca4dSJohn Scipione	until they are published. To publish an object use the Register() method.
211*820dca4dSJohn Scipione	The corresponding Unregister() method will cause an object to once again
212*820dca4dSJohn Scipione	become invisible to remote applications.
213*820dca4dSJohn Scipione
214*820dca4dSJohn Scipione	BMidiRoster also has Register() and Unregister() methods. You may also use
215*820dca4dSJohn Scipione	those methods  to publish or hide your endpoints; both do the same thing.
216*820dca4dSJohn Scipione
217*820dca4dSJohn Scipione	Although it is considered bad style, calling Register() on local endpoints
218*820dca4dSJohn Scipione	that are already registered won't mess things up. The Midi Server will
219*820dca4dSJohn Scipione	simply ignore your request. Likewise for Unregister()'ing more than once.
220*820dca4dSJohn Scipione	Attempts to Register() or Unregister() remote endpoints will fail, of
221*820dca4dSJohn Scipione	course.
222*820dca4dSJohn Scipione
223*820dca4dSJohn Scipione	If you are \link BMidiRoster::StartWatching() watching \endlink, you will
224*820dca4dSJohn Scipione	<b>not</b> receive notifications for any local endpoints you register or
225*820dca4dSJohn Scipione	unregister. Of course, other applications <I>will</I> be notified about
226*820dca4dSJohn Scipione	your endpoints.
227*820dca4dSJohn Scipione
228*820dca4dSJohn Scipione	Existing connections will not be broken when an object is unregistered,
229*820dca4dSJohn Scipione	but future remote connections will be denied. When objects are destroyed,
230*820dca4dSJohn Scipione	they automatically become unregistered.
231*820dca4dSJohn Scipione
232*820dca4dSJohn Scipione	\returns B_OK on success, or an error code (typically \c B_ERROR) if
233*820dca4dSJohn Scipione			 something went wrong.
234*820dca4dSJohn Scipione
235*820dca4dSJohn Scipione	\sa Unregister()
236*820dca4dSJohn Scipione*/
237*820dca4dSJohn Scipione
238*820dca4dSJohn Scipione/*!
239*820dca4dSJohn Scipione	\fn status_t BMidiEndpoint::Unregister()
240*820dca4dSJohn Scipione	\brief Hides the endpoint from the roster/
241*820dca4dSJohn Scipione
242*820dca4dSJohn Scipione	\sa Register()
243*820dca4dSJohn Scipione*/
244*820dca4dSJohn Scipione
245*820dca4dSJohn Scipione/*!
246*820dca4dSJohn Scipione	\fn status_t BMidiEndpoint::SetProperties(const BMessage* props)
247*820dca4dSJohn Scipione	\brief Changes the properties of the endpoint
248*820dca4dSJohn Scipione
249*820dca4dSJohn Scipione	Endpoints can have properties, which is any kind of information that
250*820dca4dSJohn Scipione	might be useful to associate with a MIDI object. The properties are
251*820dca4dSJohn Scipione	stored in a BMessage.
252*820dca4dSJohn Scipione
253*820dca4dSJohn Scipione	Usage example:
254*820dca4dSJohn Scipione
255*820dca4dSJohn Scipione\code
256*820dca4dSJohn ScipioneBMessage props;
257*820dca4dSJohn Scipioneif (endpoint->GetProperties(&props) == B_OK)
258*820dca4dSJohn Scipione{
259*820dca4dSJohn Scipione    ...add data to the message...
260*820dca4dSJohn Scipione    endpoint->SetProperties(&props);
261*820dca4dSJohn Scipione}
262*820dca4dSJohn Scipione\endcode
263*820dca4dSJohn Scipione
264*820dca4dSJohn Scipione	You are only allowed to call SetProperties() on a local object.
265*820dca4dSJohn Scipione
266*820dca4dSJohn Scipione	Properties should follow a protocol, so different applications will know
267*820dca4dSJohn Scipione	how to read each other's properties. The current protocol is very limited
268*820dca4dSJohn Scipione	-- it only allows you to associate icons with your endpoints. Be planned
269*820dca4dSJohn Scipione	to publish a more complete protocol that included additional information,
270*820dca4dSJohn Scipione	such as vendor/model names, copyright/version info, category, etc., but
271*820dca4dSJohn Scipione	they never got around to it.
272*820dca4dSJohn Scipione
273*820dca4dSJohn Scipione	<TABLE BORDER="1">
274*820dca4dSJohn Scipione	<TR><TD>property</TD><TD>Vector icon (raw data)</TD></TR>
275*820dca4dSJohn Scipione	<TR><TD>field name</TD><TD>"icon"</TD></TR>
276*820dca4dSJohn Scipione	<TR><TD>field type</TD><TD>'VICN'</TD></TR>
277*820dca4dSJohn Scipione	</TABLE>
278*820dca4dSJohn Scipione
279*820dca4dSJohn Scipione	This vector icon is available under Haiku only, and comes as raw data,
280*820dca4dSJohn Scipione	not a BBitmap. Before being able to display it, you first must render
281*820dca4dSJohn Scipione	the vector icon in the size of your choice.
282*820dca4dSJohn Scipione
283*820dca4dSJohn Scipione	<TABLE BORDER="1">
284*820dca4dSJohn Scipione	<TR><TD>property</TD><TD>Large (32x32) icon</TD></TR>
285*820dca4dSJohn Scipione	<TR><TD>field name</TD><TD>"be:large_icon"</TD></TR>
286*820dca4dSJohn Scipione	<TR><TD>field type</TD><TD>'ICON'</TD></TR>
287*820dca4dSJohn Scipione	</TABLE>
288*820dca4dSJohn Scipione
289*820dca4dSJohn Scipione	<TABLE BORDER="1">
290*820dca4dSJohn Scipione	<TR><TD>property</TD><TD>Small (16x16) icon</TD></TR>
291*820dca4dSJohn Scipione	<TR><TD>field name</TD><TD>"be:mini_icon"</TD></TR>
292*820dca4dSJohn Scipione	<TR><TD>field type</TD><TD>'MICN'</TD></TR>
293*820dca4dSJohn Scipione	</TABLE>
294*820dca4dSJohn Scipione
295*820dca4dSJohn Scipione	The MidiUtil package (downloadable from the OpenBeOS website) contains a
296*820dca4dSJohn Scipione	number of convenient functions to associate icons with endpoints, so you
297*820dca4dSJohn Scipione	don't have to write that code all over again.
298*820dca4dSJohn Scipione
299*820dca4dSJohn Scipione	\sa GetProperties()
300*820dca4dSJohn Scipione*/
301*820dca4dSJohn Scipione
302*820dca4dSJohn Scipione/*!
303*820dca4dSJohn Scipione	\fn status_t BMidiEndpoint::GetProperties(BMessage* props) const
304*820dca4dSJohn Scipione	\brief Reads the properties of the endpoint
305*820dca4dSJohn Scipione
306*820dca4dSJohn Scipione	Usage example:
307*820dca4dSJohn Scipione
308*820dca4dSJohn Scipione\code
309*820dca4dSJohn ScipioneBMessage props;
310*820dca4dSJohn Scipioneif (endpoint->GetProperties(&props) == B_OK)
311*820dca4dSJohn Scipione{
312*820dca4dSJohn Scipione    ...examine the contents of the message...
313*820dca4dSJohn Scipione}
314*820dca4dSJohn Scipione\endcode
315*820dca4dSJohn Scipione
316*820dca4dSJohn Scipione	Note that GetProperties() overwrites the contents of your BMessage.
317*820dca4dSJohn Scipione
318*820dca4dSJohn Scipione	\sa SetProperties()
319*820dca4dSJohn Scipione*/
320