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