midi_server: cleanup.
* Style cleanup. * Moved documentation to source file. * Improved variable/member naming, added '_' prefix for private methods.
This commit is contained in:
+331
-270
@@ -20,24 +20,29 @@
|
|||||||
* DEALINGS IN THE SOFTWARE.
|
* DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "MidiServerApp.h"
|
|
||||||
#include "PortDrivers.h"
|
|
||||||
#include "ServerDefs.h"
|
|
||||||
#include "protocol.h"
|
|
||||||
|
|
||||||
#include <Alert.h>
|
#include "MidiServerApp.h"
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
#include <Alert.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
#include "PortDrivers.h"
|
||||||
|
#include "ServerDefs.h"
|
||||||
|
|
||||||
|
|
||||||
using std::nothrow;
|
using std::nothrow;
|
||||||
|
|
||||||
|
|
||||||
MidiServerApp::MidiServerApp()
|
MidiServerApp::MidiServerApp()
|
||||||
: BApplication(MIDI_SERVER_SIGNATURE)
|
:
|
||||||
|
BApplication(MIDI_SERVER_SIGNATURE)
|
||||||
{
|
{
|
||||||
TRACE(("Running Haiku MIDI server"))
|
TRACE(("Running Haiku MIDI server"))
|
||||||
|
|
||||||
nextId = 1;
|
fNextID = 1;
|
||||||
fDeviceWatcher = new(std::nothrow) DeviceWatcher();
|
fDeviceWatcher = new(std::nothrow) DeviceWatcher();
|
||||||
if (fDeviceWatcher != NULL)
|
if (fDeviceWatcher != NULL)
|
||||||
fDeviceWatcher->Run();
|
fDeviceWatcher->Run();
|
||||||
@@ -49,12 +54,12 @@ MidiServerApp::~MidiServerApp()
|
|||||||
if (fDeviceWatcher && fDeviceWatcher->Lock())
|
if (fDeviceWatcher && fDeviceWatcher->Lock())
|
||||||
fDeviceWatcher->Quit();
|
fDeviceWatcher->Quit();
|
||||||
|
|
||||||
for (int32 t = 0; t < CountApps(); ++t) {
|
for (int32 t = 0; t < _CountApps(); ++t) {
|
||||||
delete AppAt(t);
|
delete _AppAt(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 t = 0; t < CountEndpoints(); ++t) {
|
for (int32 t = 0; t < _CountEndpoints(); ++t) {
|
||||||
delete EndpointAt(t);
|
delete _EndpointAt(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,28 +82,44 @@ MidiServerApp::AboutRequested()
|
|||||||
void
|
void
|
||||||
MidiServerApp::MessageReceived(BMessage* msg)
|
MidiServerApp::MessageReceived(BMessage* msg)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("IN "); msg->PrintToStream();
|
printf("IN "); msg->PrintToStream();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (msg->what) {
|
switch (msg->what) {
|
||||||
case MSG_REGISTER_APP: OnRegisterApp(msg); break;
|
case MSG_REGISTER_APP:
|
||||||
case MSG_CREATE_ENDPOINT: OnCreateEndpoint(msg); break;
|
_OnRegisterApp(msg);
|
||||||
case MSG_DELETE_ENDPOINT: OnDeleteEndpoint(msg); break;
|
break;
|
||||||
case MSG_PURGE_ENDPOINT: OnPurgeEndpoint(msg); break;
|
case MSG_CREATE_ENDPOINT:
|
||||||
case MSG_CHANGE_ENDPOINT: OnChangeEndpoint(msg); break;
|
_OnCreateEndpoint(msg);
|
||||||
case MSG_CONNECT_ENDPOINTS: OnConnectDisconnect(msg); break;
|
break;
|
||||||
case MSG_DISCONNECT_ENDPOINTS: OnConnectDisconnect(msg); break;
|
case MSG_DELETE_ENDPOINT:
|
||||||
|
_OnDeleteEndpoint(msg);
|
||||||
|
break;
|
||||||
|
case MSG_PURGE_ENDPOINT:
|
||||||
|
_OnPurgeEndpoint(msg);
|
||||||
|
break;
|
||||||
|
case MSG_CHANGE_ENDPOINT:
|
||||||
|
_OnChangeEndpoint(msg);
|
||||||
|
break;
|
||||||
|
case MSG_CONNECT_ENDPOINTS:
|
||||||
|
_OnConnectDisconnect(msg);
|
||||||
|
break;
|
||||||
|
case MSG_DISCONNECT_ENDPOINTS:
|
||||||
|
_OnConnectDisconnect(msg);
|
||||||
|
break;
|
||||||
|
|
||||||
default: super::MessageReceived(msg); break;
|
default:
|
||||||
|
super::MessageReceived(msg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiServerApp::OnRegisterApp(BMessage* msg)
|
MidiServerApp::_OnRegisterApp(BMessage* msg)
|
||||||
{
|
{
|
||||||
TRACE(("MidiServerApp::OnRegisterApp"))
|
TRACE(("MidiServerApp::_OnRegisterApp"))
|
||||||
|
|
||||||
// We only send the "app registered" message upon success,
|
// We only send the "app registered" message upon success,
|
||||||
// so if anything goes wrong here, we do not let the app
|
// so if anything goes wrong here, we do not let the app
|
||||||
@@ -108,22 +129,18 @@ MidiServerApp::OnRegisterApp(BMessage* msg)
|
|||||||
|
|
||||||
app_t* app = new app_t;
|
app_t* app = new app_t;
|
||||||
|
|
||||||
if (msg->FindMessenger("midi:messenger", &app->messenger) == B_OK) {
|
if (msg->FindMessenger("midi:messenger", &app->messenger) == B_OK
|
||||||
if (SendAllEndpoints(app)) {
|
&& _SendAllEndpoints(app)
|
||||||
if (SendAllConnections(app)) {
|
&& _SendAllConnections(app)) {
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
reply.what = MSG_APP_REGISTERED;
|
reply.what = MSG_APP_REGISTERED;
|
||||||
|
|
||||||
if (SendNotification(app, &reply)) {
|
if (_SendNotification(app, &reply)) {
|
||||||
apps.AddItem(app);
|
fApps.AddItem(app);
|
||||||
|
#ifdef DEBUG
|
||||||
#ifdef DEBUG
|
_DumpApps();
|
||||||
DumpApps();
|
#endif
|
||||||
#endif
|
return;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,71 +149,73 @@ MidiServerApp::OnRegisterApp(BMessage* msg)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiServerApp::OnCreateEndpoint(BMessage* msg)
|
MidiServerApp::_OnCreateEndpoint(BMessage* msg)
|
||||||
{
|
{
|
||||||
TRACE(("MidiServerApp::OnCreateEndpoint"))
|
TRACE(("MidiServerApp::_OnCreateEndpoint"))
|
||||||
|
|
||||||
status_t err;
|
status_t status;
|
||||||
endpoint_t* endp = new endpoint_t;
|
endpoint_t* endpoint = new endpoint_t;
|
||||||
|
|
||||||
endp->app = WhichApp(msg);
|
endpoint->app = _WhichApp(msg);
|
||||||
if (endp->app == NULL) {
|
if (endpoint->app == NULL) {
|
||||||
err = B_ERROR;
|
status = B_ERROR;
|
||||||
} else {
|
} else {
|
||||||
err = B_BAD_VALUE;
|
status = B_BAD_VALUE;
|
||||||
|
|
||||||
if (msg->FindBool("midi:consumer", &endp->consumer) == B_OK
|
if (msg->FindBool("midi:consumer", &endpoint->consumer) == B_OK
|
||||||
&& msg->FindBool("midi:registered", &endp->registered) == B_OK
|
&& msg->FindBool("midi:registered", &endpoint->registered) == B_OK
|
||||||
&& msg->FindString("midi:name", &endp->name) == B_OK
|
&& msg->FindString("midi:name", &endpoint->name) == B_OK
|
||||||
&& msg->FindMessage("midi:properties", &endp->properties) == B_OK) {
|
&& msg->FindMessage("midi:properties", &endpoint->properties)
|
||||||
if (endp->consumer) {
|
== B_OK) {
|
||||||
if (msg->FindInt32("midi:port", &endp->port) == B_OK
|
if (endpoint->consumer) {
|
||||||
&& msg->FindInt64("midi:latency", &endp->latency) == B_OK)
|
if (msg->FindInt32("midi:port", &endpoint->port) == B_OK
|
||||||
err = B_OK;
|
&& msg->FindInt64("midi:latency", &endpoint->latency)
|
||||||
|
== B_OK)
|
||||||
|
status = B_OK;
|
||||||
} else
|
} else
|
||||||
err = B_OK;
|
status = B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
|
|
||||||
if (err == B_OK) {
|
if (status == B_OK) {
|
||||||
endp->id = nextId++;
|
endpoint->id = fNextID++;
|
||||||
reply.AddInt32("midi:id", endp->id);
|
reply.AddInt32("midi:id", endpoint->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.AddInt32("midi:result", err);
|
reply.AddInt32("midi:result", status);
|
||||||
|
|
||||||
if (SendReply(endp->app, msg, &reply) && err == B_OK)
|
if (_SendReply(endpoint->app, msg, &reply) && status == B_OK)
|
||||||
AddEndpoint(msg, endp);
|
_AddEndpoint(msg, endpoint);
|
||||||
else
|
else
|
||||||
delete endp;
|
delete endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiServerApp::OnDeleteEndpoint(BMessage* msg)
|
MidiServerApp::_OnDeleteEndpoint(BMessage* msg)
|
||||||
{
|
{
|
||||||
TRACE(("MidiServerApp::OnDeleteEndpoint"))
|
TRACE(("MidiServerApp::_OnDeleteEndpoint"))
|
||||||
|
|
||||||
// Clients send the "delete endpoint" message from
|
// Clients send the "delete endpoint" message from
|
||||||
// the BMidiEndpoint destructor, so there is no point
|
// the BMidiEndpoint destructor, so there is no point
|
||||||
// sending a reply, because the endpoint object will
|
// sending a reply, because the endpoint object will
|
||||||
// be destroyed no matter what.
|
// be destroyed no matter what.
|
||||||
|
|
||||||
app_t* app = WhichApp(msg);
|
app_t* app = _WhichApp(msg);
|
||||||
if (app != NULL) {
|
if (app != NULL) {
|
||||||
endpoint_t* endp = WhichEndpoint(msg, app);
|
endpoint_t* endpoint = _WhichEndpoint(msg, app);
|
||||||
if (endp != NULL)
|
if (endpoint != NULL)
|
||||||
RemoveEndpoint(app, endp);
|
_RemoveEndpoint(app, endpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiServerApp::OnPurgeEndpoint(BMessage* msg)
|
MidiServerApp::_OnPurgeEndpoint(BMessage* msg)
|
||||||
{
|
{
|
||||||
TRACE(("MidiServerApp::OnPurgeEndpoint"))
|
TRACE(("MidiServerApp::_OnPurgeEndpoint"))
|
||||||
|
|
||||||
// This performs the same task as OnDeleteEndpoint(),
|
// This performs the same task as OnDeleteEndpoint(),
|
||||||
// except that this message was send by the midi_server
|
// except that this message was send by the midi_server
|
||||||
@@ -207,154 +226,158 @@ MidiServerApp::OnPurgeEndpoint(BMessage* msg)
|
|||||||
if (!msg->IsSourceRemote()) {
|
if (!msg->IsSourceRemote()) {
|
||||||
int32 id;
|
int32 id;
|
||||||
if (msg->FindInt32("midi:id", &id) == B_OK) {
|
if (msg->FindInt32("midi:id", &id) == B_OK) {
|
||||||
endpoint_t* endp = FindEndpoint(id);
|
endpoint_t* endpoint = _FindEndpoint(id);
|
||||||
if (endp != NULL)
|
if (endpoint != NULL)
|
||||||
RemoveEndpoint(NULL, endp);
|
_RemoveEndpoint(NULL, endpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiServerApp::OnChangeEndpoint(BMessage* msg)
|
MidiServerApp::_OnChangeEndpoint(BMessage* msg)
|
||||||
{
|
{
|
||||||
TRACE(("MidiServerApp::OnChangeEndpoint"))
|
TRACE(("MidiServerApp::_OnChangeEndpoint"))
|
||||||
|
|
||||||
endpoint_t* endp = NULL;
|
endpoint_t* endpoint = NULL;
|
||||||
status_t err;
|
status_t status;
|
||||||
|
|
||||||
app_t* app = WhichApp(msg);
|
app_t* app = _WhichApp(msg);
|
||||||
if (app == NULL)
|
if (app == NULL)
|
||||||
err = B_ERROR;
|
status = B_ERROR;
|
||||||
else {
|
else {
|
||||||
endp = WhichEndpoint(msg, app);
|
endpoint = _WhichEndpoint(msg, app);
|
||||||
if (endp == NULL)
|
if (endpoint == NULL)
|
||||||
err = B_BAD_VALUE;
|
status = B_BAD_VALUE;
|
||||||
else
|
else
|
||||||
err = B_OK;
|
status = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
reply.AddInt32("midi:result", err);
|
reply.AddInt32("midi:result", status);
|
||||||
|
|
||||||
if (SendReply(app, msg, &reply) && err == B_OK) {
|
if (_SendReply(app, msg, &reply) && status == B_OK) {
|
||||||
TRACE(("Endpoint %" B_PRId32 " (%p) changed", endp->id, endp))
|
TRACE(("Endpoint %" B_PRId32 " (%p) changed", endpoint->id, endpoint))
|
||||||
|
|
||||||
BMessage notify;
|
BMessage notify;
|
||||||
notify.what = MSG_ENDPOINT_CHANGED;
|
notify.what = MSG_ENDPOINT_CHANGED;
|
||||||
notify.AddInt32("midi:id", endp->id);
|
notify.AddInt32("midi:id", endpoint->id);
|
||||||
|
|
||||||
bool registered;
|
bool registered;
|
||||||
if (msg->FindBool("midi:registered", ®istered) == B_OK) {
|
if (msg->FindBool("midi:registered", ®istered) == B_OK) {
|
||||||
notify.AddBool("midi:registered", registered);
|
notify.AddBool("midi:registered", registered);
|
||||||
endp->registered = registered;
|
endpoint->registered = registered;
|
||||||
}
|
}
|
||||||
|
|
||||||
BString name;
|
BString name;
|
||||||
if (msg->FindString("midi:name", &name) == B_OK) {
|
if (msg->FindString("midi:name", &name) == B_OK) {
|
||||||
notify.AddString("midi:name", name);
|
notify.AddString("midi:name", name);
|
||||||
endp->name = name;
|
endpoint->name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMessage properties;
|
BMessage properties;
|
||||||
if (msg->FindMessage("midi:properties", &properties) == B_OK) {
|
if (msg->FindMessage("midi:properties", &properties) == B_OK) {
|
||||||
notify.AddMessage("midi:properties", &properties);
|
notify.AddMessage("midi:properties", &properties);
|
||||||
endp->properties = properties;
|
endpoint->properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
bigtime_t latency;
|
bigtime_t latency;
|
||||||
if (msg->FindInt64("midi:latency", &latency) == B_OK) {
|
if (msg->FindInt64("midi:latency", &latency) == B_OK) {
|
||||||
notify.AddInt64("midi:latency", latency);
|
notify.AddInt64("midi:latency", latency);
|
||||||
endp->latency = latency;
|
endpoint->latency = latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyAll(¬ify, app);
|
_NotifyAll(¬ify, app);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpEndpoints();
|
_DumpEndpoints();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiServerApp::OnConnectDisconnect(BMessage* msg)
|
MidiServerApp::_OnConnectDisconnect(BMessage* msg)
|
||||||
{
|
{
|
||||||
TRACE(("MidiServerApp::OnConnectDisconnect"))
|
TRACE(("MidiServerApp::_OnConnectDisconnect"))
|
||||||
|
|
||||||
bool mustConnect = (msg->what == MSG_CONNECT_ENDPOINTS);
|
bool mustConnect = msg->what == MSG_CONNECT_ENDPOINTS;
|
||||||
|
|
||||||
status_t err;
|
status_t status;
|
||||||
endpoint_t* prod = NULL;
|
endpoint_t* producer = NULL;
|
||||||
endpoint_t* cons = NULL;
|
endpoint_t* consumer = NULL;
|
||||||
|
|
||||||
app_t* app = WhichApp(msg);
|
app_t* app = _WhichApp(msg);
|
||||||
if (app == NULL)
|
if (app == NULL)
|
||||||
err = B_ERROR;
|
status = B_ERROR;
|
||||||
else {
|
else {
|
||||||
err = B_BAD_VALUE;
|
status = B_BAD_VALUE;
|
||||||
|
|
||||||
int32 prodId, consId;
|
int32 producerID;
|
||||||
if (msg->FindInt32("midi:producer", &prodId) == B_OK
|
int32 consumerID;
|
||||||
&& msg->FindInt32("midi:consumer", &consId) == B_OK) {
|
if (msg->FindInt32("midi:producer", &producerID) == B_OK
|
||||||
prod = FindEndpoint(prodId);
|
&& msg->FindInt32("midi:consumer", &consumerID) == B_OK) {
|
||||||
cons = FindEndpoint(consId);
|
producer = _FindEndpoint(producerID);
|
||||||
|
consumer = _FindEndpoint(consumerID);
|
||||||
|
|
||||||
if (prod != NULL && !prod->consumer) {
|
if (producer != NULL && !producer->consumer) {
|
||||||
if (cons != NULL && cons->consumer) {
|
if (consumer != NULL && consumer->consumer) {
|
||||||
// It is an error to connect two endpoints that
|
// It is an error to connect two endpoints that
|
||||||
// are already connected, or to disconnect two
|
// are already connected, or to disconnect two
|
||||||
// endpoints that are not connected at all.
|
// endpoints that are not connected at all.
|
||||||
|
|
||||||
if (mustConnect == prod->connections.HasItem(cons))
|
if (mustConnect == producer->connections.HasItem(consumer))
|
||||||
err = B_ERROR;
|
status = B_ERROR;
|
||||||
else
|
else
|
||||||
err = B_OK;
|
status = B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
reply.AddInt32("midi:result", err);
|
reply.AddInt32("midi:result", status);
|
||||||
|
|
||||||
if (SendReply(app, msg, &reply) && err == B_OK) {
|
if (_SendReply(app, msg, &reply) && status == B_OK) {
|
||||||
if (mustConnect) {
|
if (mustConnect) {
|
||||||
TRACE(("Connection made: %" B_PRId32 " ---> %" B_PRId32, prod->id,
|
TRACE(("Connection made: %" B_PRId32 " ---> %" B_PRId32,
|
||||||
cons->id))
|
producer->id, consumer->id))
|
||||||
|
|
||||||
prod->connections.AddItem(cons);
|
producer->connections.AddItem(consumer);
|
||||||
} else {
|
} else {
|
||||||
TRACE(("Connection broken: %" B_PRId32 " -X-> %" B_PRId32, prod->id,
|
TRACE(("Connection broken: %" B_PRId32 " -X-> %" B_PRId32,
|
||||||
cons->id))
|
producer->id, consumer->id))
|
||||||
|
|
||||||
prod->connections.RemoveItem(cons);
|
producer->connections.RemoveItem(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
BMessage notify;
|
BMessage notify;
|
||||||
MakeConnectedNotification(¬ify, prod, cons, mustConnect);
|
_MakeConnectedNotification(¬ify, producer, consumer, mustConnect);
|
||||||
NotifyAll(¬ify, app);
|
_NotifyAll(¬ify, app);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpEndpoints();
|
_DumpEndpoints();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Sends an app MSG_ENDPOINT_CREATED notifications for
|
||||||
|
all current endpoints. Used when the app registers.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
MidiServerApp::SendAllEndpoints(app_t* app)
|
MidiServerApp::_SendAllEndpoints(app_t* app)
|
||||||
{
|
{
|
||||||
ASSERT(app != NULL)
|
ASSERT(app != NULL)
|
||||||
|
|
||||||
BMessage notify;
|
BMessage notify;
|
||||||
|
|
||||||
for (int32 t = 0; t < CountEndpoints(); ++t) {
|
for (int32 t = 0; t < _CountEndpoints(); ++t) {
|
||||||
endpoint_t* endp = EndpointAt(t);
|
endpoint_t* endpoint = _EndpointAt(t);
|
||||||
|
|
||||||
MakeCreatedNotification(¬ify, endp);
|
_MakeCreatedNotification(¬ify, endpoint);
|
||||||
|
|
||||||
if (!SendNotification(app, ¬ify))
|
if (!_SendNotification(app, ¬ify))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,22 +385,25 @@ MidiServerApp::SendAllEndpoints(app_t* app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Sends an app MSG_ENDPOINTS_CONNECTED notifications for
|
||||||
|
all current connections. Used when the app registers.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
MidiServerApp::SendAllConnections(app_t* app)
|
MidiServerApp::_SendAllConnections(app_t* app)
|
||||||
{
|
{
|
||||||
ASSERT(app != NULL)
|
ASSERT(app != NULL)
|
||||||
|
|
||||||
BMessage notify;
|
BMessage notify;
|
||||||
|
|
||||||
for (int32 t = 0; t < CountEndpoints(); ++t) {
|
for (int32 t = 0; t < _CountEndpoints(); ++t) {
|
||||||
endpoint_t* prod = EndpointAt(t);
|
endpoint_t* producer = _EndpointAt(t);
|
||||||
if (!prod->consumer) {
|
if (!producer->consumer) {
|
||||||
for (int32 k = 0; k < CountConnections(prod); ++k) {
|
for (int32 k = 0; k < _CountConnections(producer); ++k) {
|
||||||
endpoint_t* cons = ConnectionAt(prod, k);
|
endpoint_t* consumer = _ConnectionAt(producer, k);
|
||||||
|
|
||||||
MakeConnectedNotification(¬ify, prod, cons, true);
|
_MakeConnectedNotification(¬ify, producer, consumer, true);
|
||||||
|
|
||||||
if (!SendNotification(app, ¬ify))
|
if (!_SendNotification(app, ¬ify))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,97 +413,111 @@ MidiServerApp::SendAllConnections(app_t* app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Adds the specified endpoint to the roster, and notifies
|
||||||
|
all other applications about this event.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
MidiServerApp::AddEndpoint(BMessage* msg, endpoint_t* endp)
|
MidiServerApp::_AddEndpoint(BMessage* msg, endpoint_t* endpoint)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
ASSERT(endp != NULL)
|
ASSERT(endpoint != NULL)
|
||||||
ASSERT(!endpoints.HasItem(endp))
|
ASSERT(!fEndpoints.HasItem(endpoint))
|
||||||
|
|
||||||
TRACE(("Endpoint %" B_PRId32 " (%p) added", endp->id, endp))
|
TRACE(("Endpoint %" B_PRId32 " (%p) added", endpoint->id, endpoint))
|
||||||
|
|
||||||
endpoints.AddItem(endp);
|
fEndpoints.AddItem(endpoint);
|
||||||
|
|
||||||
BMessage notify;
|
BMessage notify;
|
||||||
MakeCreatedNotification(¬ify, endp);
|
_MakeCreatedNotification(¬ify, endpoint);
|
||||||
NotifyAll(¬ify, endp->app);
|
_NotifyAll(¬ify, endpoint->app);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpEndpoints();
|
_DumpEndpoints();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Removes an endpoint from the roster, and notifies all
|
||||||
|
other apps about this event. "app" is the application
|
||||||
|
that the endpoint belongs to; if it is NULL, the app
|
||||||
|
no longer exists and we're purging the endpoint.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
MidiServerApp::RemoveEndpoint(app_t* app, endpoint_t* endp)
|
MidiServerApp::_RemoveEndpoint(app_t* app, endpoint_t* endpoint)
|
||||||
{
|
{
|
||||||
ASSERT(endp != NULL)
|
ASSERT(endpoint != NULL)
|
||||||
ASSERT(endpoints.HasItem(endp))
|
ASSERT(fEndpoints.HasItem(endpoint))
|
||||||
|
|
||||||
TRACE(("Endpoint %" B_PRId32 " (%p) removed", endp->id, endp))
|
TRACE(("Endpoint %" B_PRId32 " (%p) removed", endpoint->id, endpoint))
|
||||||
|
|
||||||
endpoints.RemoveItem(endp);
|
fEndpoints.RemoveItem(endpoint);
|
||||||
|
|
||||||
if (endp->consumer)
|
if (endpoint->consumer)
|
||||||
DisconnectDeadConsumer(endp);
|
_DisconnectDeadConsumer(endpoint);
|
||||||
|
|
||||||
BMessage notify;
|
BMessage notify;
|
||||||
notify.what = MSG_ENDPOINT_DELETED;
|
notify.what = MSG_ENDPOINT_DELETED;
|
||||||
notify.AddInt32("midi:id", endp->id);
|
notify.AddInt32("midi:id", endpoint->id);
|
||||||
NotifyAll(¬ify, app);
|
_NotifyAll(¬ify, app);
|
||||||
|
|
||||||
delete endp;
|
delete endpoint;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpEndpoints();
|
_DumpEndpoints();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Removes a consumer from the list of connections of
|
||||||
|
all the producers it is connected to, just before
|
||||||
|
we remove it from the roster.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
MidiServerApp::DisconnectDeadConsumer(endpoint_t* cons)
|
MidiServerApp::_DisconnectDeadConsumer(endpoint_t* consumer)
|
||||||
{
|
{
|
||||||
ASSERT(cons != NULL)
|
ASSERT(consumer != NULL)
|
||||||
ASSERT(cons->consumer)
|
ASSERT(consumer->consumer)
|
||||||
|
|
||||||
for (int32 t = 0; t < CountEndpoints(); ++t) {
|
for (int32 t = 0; t < _CountEndpoints(); ++t) {
|
||||||
endpoint_t* prod = EndpointAt(t);
|
endpoint_t* producer = _EndpointAt(t);
|
||||||
if (!prod->consumer)
|
if (!producer->consumer)
|
||||||
prod->connections.RemoveItem(cons);
|
producer->connections.RemoveItem(consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Fills up a MSG_ENDPOINT_CREATED message.
|
||||||
void
|
void
|
||||||
MidiServerApp::MakeCreatedNotification(BMessage* msg, endpoint_t* endp)
|
MidiServerApp::_MakeCreatedNotification(BMessage* msg, endpoint_t* endpoint)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
ASSERT(endp != NULL)
|
ASSERT(endpoint != NULL)
|
||||||
|
|
||||||
msg->MakeEmpty();
|
msg->MakeEmpty();
|
||||||
msg->what = MSG_ENDPOINT_CREATED;
|
msg->what = MSG_ENDPOINT_CREATED;
|
||||||
msg->AddInt32("midi:id", endp->id);
|
msg->AddInt32("midi:id", endpoint->id);
|
||||||
msg->AddBool("midi:consumer", endp->consumer);
|
msg->AddBool("midi:consumer", endpoint->consumer);
|
||||||
msg->AddBool("midi:registered", endp->registered);
|
msg->AddBool("midi:registered", endpoint->registered);
|
||||||
msg->AddString("midi:name", endp->name);
|
msg->AddString("midi:name", endpoint->name);
|
||||||
msg->AddMessage("midi:properties", &endp->properties);
|
msg->AddMessage("midi:properties", &endpoint->properties);
|
||||||
|
|
||||||
if (endp->consumer) {
|
if (endpoint->consumer) {
|
||||||
msg->AddInt32("midi:port", endp->port);
|
msg->AddInt32("midi:port", endpoint->port);
|
||||||
msg->AddInt64("midi:latency", endp->latency);
|
msg->AddInt64("midi:latency", endpoint->latency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Fills up a MSG_ENDPOINTS_(DIS)CONNECTED message.
|
||||||
void
|
void
|
||||||
MidiServerApp::MakeConnectedNotification(BMessage* msg, endpoint_t* prod,
|
MidiServerApp::_MakeConnectedNotification(BMessage* msg, endpoint_t* producer,
|
||||||
endpoint_t* cons, bool mustConnect)
|
endpoint_t* consumer, bool mustConnect)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
ASSERT(prod != NULL)
|
ASSERT(producer != NULL)
|
||||||
ASSERT(cons != NULL)
|
ASSERT(consumer != NULL)
|
||||||
ASSERT(!prod->consumer)
|
ASSERT(!producer->consumer)
|
||||||
ASSERT(cons->consumer)
|
ASSERT(consumer->consumer)
|
||||||
|
|
||||||
msg->MakeEmpty();
|
msg->MakeEmpty();
|
||||||
|
|
||||||
@@ -486,20 +526,23 @@ MidiServerApp::MakeConnectedNotification(BMessage* msg, endpoint_t* prod,
|
|||||||
else
|
else
|
||||||
msg->what = MSG_ENDPOINTS_DISCONNECTED;
|
msg->what = MSG_ENDPOINTS_DISCONNECTED;
|
||||||
|
|
||||||
msg->AddInt32("midi:producer", prod->id);
|
msg->AddInt32("midi:producer", producer->id);
|
||||||
msg->AddInt32("midi:consumer", cons->id);
|
msg->AddInt32("midi:consumer", consumer->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Figures out which application a message came from.
|
||||||
|
Returns NULL if the application is not registered.
|
||||||
|
*/
|
||||||
app_t*
|
app_t*
|
||||||
MidiServerApp::WhichApp(BMessage* msg)
|
MidiServerApp::_WhichApp(BMessage* msg)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
|
|
||||||
BMessenger retadr = msg->ReturnAddress();
|
BMessenger retadr = msg->ReturnAddress();
|
||||||
|
|
||||||
for (int32 t = 0; t < CountApps(); ++t) {
|
for (int32 t = 0; t < _CountApps(); ++t) {
|
||||||
app_t* app = AppAt(t);
|
app_t* app = _AppAt(t);
|
||||||
if (app->messenger.Team() == retadr.Team())
|
if (app->messenger.Team() == retadr.Team())
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
@@ -510,17 +553,22 @@ MidiServerApp::WhichApp(BMessage* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Looks at the "midi:id" field from a message, and returns
|
||||||
|
the endpoint object that corresponds to that ID. It also
|
||||||
|
checks whether the application specified by "app" really
|
||||||
|
owns the endpoint. Returns NULL on error.
|
||||||
|
*/
|
||||||
endpoint_t*
|
endpoint_t*
|
||||||
MidiServerApp::WhichEndpoint(BMessage* msg, app_t* app)
|
MidiServerApp::_WhichEndpoint(BMessage* msg, app_t* app)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
ASSERT(app != NULL)
|
ASSERT(app != NULL)
|
||||||
|
|
||||||
int32 id;
|
int32 id;
|
||||||
if (msg->FindInt32("midi:id", &id) == B_OK) {
|
if (msg->FindInt32("midi:id", &id) == B_OK) {
|
||||||
endpoint_t* endp = FindEndpoint(id);
|
endpoint_t* endpoint = _FindEndpoint(id);
|
||||||
if (endp != NULL && endp->app == app)
|
if (endpoint != NULL && endpoint->app == app)
|
||||||
return endp;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("Endpoint not found or wrong app"))
|
TRACE(("Endpoint not found or wrong app"))
|
||||||
@@ -528,14 +576,17 @@ MidiServerApp::WhichEndpoint(BMessage* msg, app_t* app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Returns the endpoint with the specified ID, or
|
||||||
|
\c NULL if no such endpoint exists on the roster.
|
||||||
|
*/
|
||||||
endpoint_t*
|
endpoint_t*
|
||||||
MidiServerApp::FindEndpoint(int32 id)
|
MidiServerApp::_FindEndpoint(int32 id)
|
||||||
{
|
{
|
||||||
if (id > 0) {
|
if (id > 0) {
|
||||||
for (int32 t = 0; t < CountEndpoints(); ++t) {
|
for (int32 t = 0; t < _CountEndpoints(); ++t) {
|
||||||
endpoint_t* endp = EndpointAt(t);
|
endpoint_t* endpoint = _EndpointAt(t);
|
||||||
if (endp->id == id)
|
if (endpoint->id == id)
|
||||||
return endp;
|
return endpoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,65 +595,78 @@ MidiServerApp::FindEndpoint(int32 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Sends notification messages to all registered apps,
|
||||||
|
except to the application that triggered the event.
|
||||||
|
The "except" app is allowed to be NULL.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
MidiServerApp::NotifyAll(BMessage* msg, app_t* except)
|
MidiServerApp::_NotifyAll(BMessage* msg, app_t* except)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
|
|
||||||
for (int32 t = CountApps() - 1; t >= 0; --t) {
|
for (int32 t = _CountApps() - 1; t >= 0; --t) {
|
||||||
app_t* app = AppAt(t);
|
app_t* app = _AppAt(t);
|
||||||
if (app != except) {
|
if (app != except && !_SendNotification(app, msg)) {
|
||||||
if (!SendNotification(app, msg)) {
|
delete (app_t*)fApps.RemoveItem(t);
|
||||||
delete (app_t*)apps.RemoveItem(t);
|
#ifdef DEBUG
|
||||||
|
_DumpApps();
|
||||||
#ifdef DEBUG
|
#endif
|
||||||
DumpApps();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Sends a notification message to an application, which is
|
||||||
|
not necessarily registered yet. Applications never reply
|
||||||
|
to such notification messages.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
MidiServerApp::SendNotification(app_t* app, BMessage* msg)
|
MidiServerApp::_SendNotification(app_t* app, BMessage* msg)
|
||||||
{
|
{
|
||||||
ASSERT(app != NULL)
|
ASSERT(app != NULL)
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
|
|
||||||
status_t err = app->messenger.SendMessage(msg, (BHandler*) NULL, TIMEOUT);
|
status_t status = app->messenger.SendMessage(msg, (BHandler*) NULL,
|
||||||
|
TIMEOUT);
|
||||||
|
if (status != B_OK)
|
||||||
|
_DeliveryError(app);
|
||||||
|
|
||||||
if (err != B_OK)
|
return status == B_OK;
|
||||||
DeliveryError(app);
|
|
||||||
|
|
||||||
return err == B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Sends a reply to a request made by an application.
|
||||||
|
If "app" is NULL, the application is not registered
|
||||||
|
(and the reply should contain an error code).
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
MidiServerApp::SendReply(app_t* app, BMessage* msg, BMessage* reply)
|
MidiServerApp::_SendReply(app_t* app, BMessage* msg, BMessage* reply)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
ASSERT(reply != NULL)
|
ASSERT(reply != NULL)
|
||||||
|
|
||||||
status_t err = msg->SendReply(reply, (BHandler*) NULL, TIMEOUT);
|
status_t status = msg->SendReply(reply, (BHandler*) NULL, TIMEOUT);
|
||||||
|
if (status != B_OK && app != NULL) {
|
||||||
if (err != B_OK && app != NULL) {
|
_DeliveryError(app);
|
||||||
DeliveryError(app);
|
fApps.RemoveItem(app);
|
||||||
apps.RemoveItem(app);
|
|
||||||
delete app;
|
delete app;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpApps();
|
_DumpApps();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return err == B_OK;
|
return status == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Removes an app and all of its endpoints from the roster
|
||||||
|
if a reply or notification message cannot be delivered.
|
||||||
|
(Waiting for communications to fail is actually our only
|
||||||
|
way to get rid of stale endpoints.)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
MidiServerApp::DeliveryError(app_t* app)
|
MidiServerApp::_DeliveryError(app_t* app)
|
||||||
{
|
{
|
||||||
ASSERT(app != NULL)
|
ASSERT(app != NULL)
|
||||||
|
|
||||||
@@ -619,12 +683,12 @@ MidiServerApp::DeliveryError(app_t* app)
|
|||||||
|
|
||||||
BMessage msg;
|
BMessage msg;
|
||||||
|
|
||||||
for (int32 t = 0; t < CountEndpoints(); ++t) {
|
for (int32 t = 0; t < _CountEndpoints(); ++t) {
|
||||||
endpoint_t* endp = EndpointAt(t);
|
endpoint_t* endpoint = _EndpointAt(t);
|
||||||
if (endp->app == app) {
|
if (endpoint->app == app) {
|
||||||
msg.MakeEmpty();
|
msg.MakeEmpty();
|
||||||
msg.what = MSG_PURGE_ENDPOINT;
|
msg.what = MSG_PURGE_ENDPOINT;
|
||||||
msg.AddInt32("midi:id", endp->id);
|
msg.AddInt32("midi:id", endpoint->id);
|
||||||
|
|
||||||
// It is not safe to post a message to your own
|
// It is not safe to post a message to your own
|
||||||
// looper's message queue, because you risk a
|
// looper's message queue, because you risk a
|
||||||
@@ -644,65 +708,65 @@ MidiServerApp::DeliveryError(app_t* app)
|
|||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
MidiServerApp::CountApps()
|
MidiServerApp::_CountApps()
|
||||||
{
|
{
|
||||||
return apps.CountItems();
|
return fApps.CountItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
app_t*
|
app_t*
|
||||||
MidiServerApp::AppAt(int32 index)
|
MidiServerApp::_AppAt(int32 index)
|
||||||
{
|
{
|
||||||
ASSERT(index >= 0 && index < CountApps())
|
ASSERT(index >= 0 && index < CountApps())
|
||||||
|
|
||||||
return (app_t*)apps.ItemAt(index);
|
return (app_t*)fApps.ItemAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
MidiServerApp::CountEndpoints()
|
MidiServerApp::_CountEndpoints()
|
||||||
{
|
{
|
||||||
return endpoints.CountItems();
|
return fEndpoints.CountItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
endpoint_t*
|
endpoint_t*
|
||||||
MidiServerApp::EndpointAt(int32 index)
|
MidiServerApp::_EndpointAt(int32 index)
|
||||||
{
|
{
|
||||||
ASSERT(index >= 0 && index < CountEndpoints())
|
ASSERT(index >= 0 && index < CountEndpoints())
|
||||||
|
|
||||||
return (endpoint_t*)endpoints.ItemAt(index);
|
return (endpoint_t*)fEndpoints.ItemAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
MidiServerApp::CountConnections(endpoint_t* prod)
|
MidiServerApp::_CountConnections(endpoint_t* producer)
|
||||||
{
|
{
|
||||||
ASSERT(prod != NULL)
|
ASSERT(producer != NULL)
|
||||||
ASSERT(!prod->consumer)
|
ASSERT(!producer->consumer)
|
||||||
|
|
||||||
return prod->connections.CountItems();
|
return producer->connections.CountItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
endpoint_t*
|
endpoint_t*
|
||||||
MidiServerApp::ConnectionAt(endpoint_t* prod, int32 index)
|
MidiServerApp::_ConnectionAt(endpoint_t* producer, int32 index)
|
||||||
{
|
{
|
||||||
ASSERT(prod != NULL)
|
ASSERT(producer != NULL)
|
||||||
ASSERT(!prod->consumer)
|
ASSERT(!producer->consumer)
|
||||||
ASSERT(index >= 0 && index < CountConnections(prod))
|
ASSERT(index >= 0 && index < _CountConnections(producer))
|
||||||
|
|
||||||
return (endpoint_t*)prod->connections.ItemAt(index);
|
return (endpoint_t*)producer->connections.ItemAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
MidiServerApp::DumpApps()
|
MidiServerApp::_DumpApps()
|
||||||
{
|
{
|
||||||
printf("*** START DumpApps\n");
|
printf("*** START DumpApps\n");
|
||||||
|
|
||||||
for (int32 t = 0; t < CountApps(); ++t) {
|
for (int32 t = 0; t < _CountApps(); ++t) {
|
||||||
app_t* app = AppAt(t);
|
app_t* app = AppAt(t);
|
||||||
|
|
||||||
printf("\tapp %" B_PRId32 " (%p): team %" B_PRId32 "\n", t, app,
|
printf("\tapp %" B_PRId32 " (%p): team %" B_PRId32 "\n", t, app,
|
||||||
@@ -711,41 +775,39 @@ MidiServerApp::DumpApps()
|
|||||||
|
|
||||||
printf("*** END DumpApps\n");
|
printf("*** END DumpApps\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
void
|
void
|
||||||
MidiServerApp::DumpEndpoints()
|
MidiServerApp::_DumpEndpoints()
|
||||||
{
|
{
|
||||||
printf("*** START DumpEndpoints\n");
|
printf("*** START DumpEndpoints\n");
|
||||||
|
|
||||||
for (int32 t = 0; t < CountEndpoints(); ++t) {
|
for (int32 t = 0; t < _CountEndpoints(); ++t) {
|
||||||
endpoint_t* endp = EndpointAt(t);
|
endpoint_t* endpoint = _EndpointAt(t);
|
||||||
|
|
||||||
printf("\tendpoint %" B_PRId32 " (%p):\n", t, endp);
|
printf("\tendpoint %" B_PRId32 " (%p):\n", t, endpoint);
|
||||||
printf("\t\tid %" B_PRId32 ", name '%s', %s, %s, app %p\n",
|
printf("\t\tid %" B_PRId32 ", name '%s', %s, %s, app %p\n",
|
||||||
endp->id, endp->name.String(),
|
endpoint->id, endpoint->name.String(),
|
||||||
endp->consumer ? "consumer" : "producer",
|
endpoint->consumer ? "consumer" : "producer",
|
||||||
endp->registered ? "registered" : "unregistered",
|
endpoint->registered ? "registered" : "unregistered",
|
||||||
endp->app);
|
endpoint->app);
|
||||||
printf("\t\tproperties: "); endp->properties.PrintToStream();
|
printf("\t\tproperties: "); endpoint->properties.PrintToStream();
|
||||||
|
|
||||||
if (endp->consumer)
|
if (endpoint->consumer)
|
||||||
printf("\t\tport %" B_PRId32 ", latency %" B_PRIdBIGTIME "\n",
|
printf("\t\tport %" B_PRId32 ", latency %" B_PRIdBIGTIME "\n",
|
||||||
endp->port, endp->latency);
|
endpoint->port, endpoint->latency);
|
||||||
else {
|
else {
|
||||||
printf("\t\tconnections:\n");
|
printf("\t\tconnections:\n");
|
||||||
for (int32 k = 0; k < CountConnections(endp); ++k) {
|
for (int32 k = 0; k < CountConnections(endpoint); ++k) {
|
||||||
endpoint_t* cons = ConnectionAt(endp, k);
|
endpoint_t* consumer = ConnectionAt(endpoint, k);
|
||||||
printf("\t\t\tid %" B_PRId32 " (%p)\n", cons->id, cons);
|
printf("\t\t\tid %" B_PRId32 " (%p)\n", consumer->id, consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("*** END DumpEndpoints\n");
|
printf("*** END DumpEndpoints\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
@@ -758,4 +820,3 @@ main()
|
|||||||
app.Run();
|
app.Run();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009, Haiku, Inc. All rights reserved.
|
* Copyright 2002-2015, Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -8,129 +8,92 @@
|
|||||||
#ifndef MIDI_SERVER_APP_H
|
#ifndef MIDI_SERVER_APP_H
|
||||||
#define MIDI_SERVER_APP_H
|
#define MIDI_SERVER_APP_H
|
||||||
|
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
|
|
||||||
#include "DeviceWatcher.h"
|
#include "DeviceWatcher.h"
|
||||||
|
|
||||||
|
|
||||||
struct app_t;
|
struct app_t;
|
||||||
struct endpoint_t;
|
struct endpoint_t;
|
||||||
|
|
||||||
// The heart of the midi_server. This BApplication subclass
|
|
||||||
// keeps the roster of endpoints and applications, processes
|
/*! The heart of the midi_server. This BApplication subclass
|
||||||
// incoming messages from libmidi2.so, and notifies the apps
|
keeps the roster of endpoints and applications, processes
|
||||||
// when something interesting happens.
|
incoming messages from libmidi2.so, and notifies the apps
|
||||||
class MidiServerApp : public BApplication
|
when something interesting happens.
|
||||||
{
|
*/
|
||||||
|
class MidiServerApp : public BApplication {
|
||||||
public:
|
public:
|
||||||
|
MidiServerApp();
|
||||||
|
virtual ~MidiServerApp();
|
||||||
|
|
||||||
MidiServerApp();
|
virtual void AboutRequested();
|
||||||
virtual ~MidiServerApp();
|
virtual void MessageReceived(BMessage* msg);
|
||||||
|
|
||||||
virtual void AboutRequested();
|
|
||||||
virtual void MessageReceived(BMessage* msg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef BApplication super;
|
typedef BApplication super;
|
||||||
|
|
||||||
void OnRegisterApp(BMessage* msg);
|
void _OnRegisterApp(BMessage* msg);
|
||||||
void OnCreateEndpoint(BMessage* msg);
|
void _OnCreateEndpoint(BMessage* msg);
|
||||||
void OnDeleteEndpoint(BMessage* msg);
|
void _OnDeleteEndpoint(BMessage* msg);
|
||||||
void OnPurgeEndpoint(BMessage* msg);
|
void _OnPurgeEndpoint(BMessage* msg);
|
||||||
void OnChangeEndpoint(BMessage* msg);
|
void _OnChangeEndpoint(BMessage* msg);
|
||||||
void OnConnectDisconnect(BMessage* msg);
|
void _OnConnectDisconnect(BMessage* msg);
|
||||||
|
|
||||||
// Sends an app MSG_ENDPOINT_CREATED notifications for
|
bool _SendAllEndpoints(app_t* app);
|
||||||
// all current endpoints. Used when the app registers.
|
bool _SendAllConnections(app_t* app);
|
||||||
bool SendAllEndpoints(app_t* app);
|
|
||||||
|
|
||||||
// Sends an app MSG_ENDPOINTS_CONNECTED notifications for
|
void _AddEndpoint(BMessage* msg, endpoint_t* endp);
|
||||||
// all current connections. Used when the app registers.
|
void _RemoveEndpoint(app_t* app, endpoint_t* endp);
|
||||||
bool SendAllConnections(app_t* app);
|
|
||||||
|
|
||||||
// Adds the specified endpoint to the roster, and notifies
|
void _DisconnectDeadConsumer(endpoint_t* cons);
|
||||||
// all other applications about this event.
|
|
||||||
void AddEndpoint(BMessage* msg, endpoint_t* endp);
|
|
||||||
|
|
||||||
// Removes an endpoint from the roster, and notifies all
|
void _MakeCreatedNotification(BMessage* msg,
|
||||||
// other apps about this event. "app" is the application
|
endpoint_t* endp);
|
||||||
// that the endpoint belongs to; if it is NULL, the app
|
void _MakeConnectedNotification(BMessage* msg,
|
||||||
// no longer exists and we're purging the endpoint.
|
endpoint_t* prod, endpoint_t* cons,
|
||||||
void RemoveEndpoint(app_t* app, endpoint_t* endp);
|
bool mustConnect);
|
||||||
|
|
||||||
// Removes a consumer from the list of connections of
|
app_t* _WhichApp(BMessage* msg);
|
||||||
// all the producers it is connected to, just before
|
endpoint_t* _WhichEndpoint(BMessage* msg, app_t* app);
|
||||||
// we remove it from the roster.
|
endpoint_t* _FindEndpoint(int32 id);
|
||||||
void DisconnectDeadConsumer(endpoint_t* cons);
|
|
||||||
|
|
||||||
// Fills up a MSG_ENDPOINT_CREATED message.
|
void _NotifyAll(BMessage* msg, app_t* except);
|
||||||
void MakeCreatedNotification(BMessage* msg, endpoint_t* endp);
|
bool _SendNotification(app_t* app, BMessage* msg);
|
||||||
|
bool _SendReply(app_t* app, BMessage* msg,
|
||||||
|
BMessage* reply);
|
||||||
|
|
||||||
// Fills up a MSG_ENDPOINTS_(DIS)CONNECTED message.
|
void _DeliveryError(app_t* app);
|
||||||
void MakeConnectedNotification(
|
|
||||||
BMessage* msg, endpoint_t* prod, endpoint_t* cons, bool mustConnect);
|
|
||||||
|
|
||||||
// Figures out which application a message came from.
|
int32 _CountApps();
|
||||||
// Returns NULL if the application is not registered.
|
app_t* _AppAt(int32 index);
|
||||||
app_t* WhichApp(BMessage* msg);
|
|
||||||
|
|
||||||
// Looks at the "midi:id" field from a message, and returns
|
int32 _CountEndpoints();
|
||||||
// the endpoint object that corresponds to that ID. It also
|
endpoint_t* _EndpointAt(int32 index);
|
||||||
// checks whether the application specified by "app" really
|
|
||||||
// owns the endpoint. Returns NULL on error.
|
|
||||||
endpoint_t* WhichEndpoint(BMessage* msg, app_t* app);
|
|
||||||
|
|
||||||
// Returns the endpoint with the specified ID, or
|
int32 _CountConnections(endpoint_t* prod);
|
||||||
// NULL if no such endpoint exists on the roster.
|
endpoint_t* _ConnectionAt(endpoint_t* prod, int32 index);
|
||||||
endpoint_t* FindEndpoint(int32 id);
|
|
||||||
|
|
||||||
// Sends notification messages to all registered apps,
|
#ifdef DEBUG
|
||||||
// except to the application that triggered the event.
|
void _DumpApps();
|
||||||
// The "except" app is allowed to be NULL.
|
void _DumpEndpoints();
|
||||||
void NotifyAll(BMessage* msg, app_t* except);
|
#endif
|
||||||
|
|
||||||
// Sends a notification message to an application, which is
|
private:
|
||||||
// not necessarily registered yet. Applications never reply
|
//! The registered applications.
|
||||||
// to such notification messages.
|
BList fApps;
|
||||||
bool SendNotification(app_t* app, BMessage* msg);
|
|
||||||
|
|
||||||
// Sends a reply to a request made by an application.
|
//! All the endpoints in the system.
|
||||||
// If "app" is NULL, the application is not registered
|
BList fEndpoints;
|
||||||
// (and the reply should contain an error code).
|
|
||||||
bool SendReply(app_t* app, BMessage* msg, BMessage* reply);
|
|
||||||
|
|
||||||
// Removes an app and all of its endpoints from the roster
|
//! The ID we will assign to the next new endpoint.
|
||||||
// if a reply or notification message cannot be delivered.
|
int32 fNextID;
|
||||||
// (Waiting for communications to fail is actually our only
|
|
||||||
// way to get rid of stale endpoints.)
|
|
||||||
void DeliveryError(app_t* app);
|
|
||||||
|
|
||||||
int32 CountApps();
|
//! Watch endpoints from /dev/midi drivers.
|
||||||
app_t* AppAt(int32 index);
|
DeviceWatcher* fDeviceWatcher;
|
||||||
|
|
||||||
int32 CountEndpoints();
|
|
||||||
endpoint_t* EndpointAt(int32 index);
|
|
||||||
|
|
||||||
int32 CountConnections(endpoint_t* prod);
|
|
||||||
endpoint_t* ConnectionAt(endpoint_t* prod, int32 index);
|
|
||||||
|
|
||||||
// The registered applications.
|
|
||||||
BList apps;
|
|
||||||
|
|
||||||
// All the endpoints in the system.
|
|
||||||
BList endpoints;
|
|
||||||
|
|
||||||
// The ID we will assign to the next new endpoint.
|
|
||||||
int32 nextId;
|
|
||||||
|
|
||||||
// Watch endpoints from /dev/midi drivers.
|
|
||||||
DeviceWatcher* fDeviceWatcher;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
void DumpApps();
|
|
||||||
void DumpEndpoints();
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // MIDI_SERVER_APP_H
|
#endif // MIDI_SERVER_APP_H
|
||||||
|
|||||||
Reference in New Issue
Block a user