bool CAMIDIEndpoints::Endpoint::GetEndpointInfo(EMode mode, EndpointInfo &info) { Endpoint *ept = this, *ept2; if (mode == kPairs) { if ((ept2 = ept->PairMate()) == NULL) return false; info.mSourceEndpoint = ept2->IOEndpoint(); info.mDestinationEndpoint = ept->IOEndpoint(); } else if (mode == kSources) { info.mSourceEndpoint = ept->IOEndpoint(); info.mDestinationEndpoint = NULL; } else { info.mSourceEndpoint = NULL; info.mDestinationEndpoint = ept->IOEndpoint(); } info.mUniqueID = ept->UniqueID(); if (ept->DriverOwned() && ept->Next() != NULL) { // add one item for all connected items CFMutableStringRef names = CFStringCreateMutable(NULL, 0); bool first = true; while (true) { ept = ept->Next(); if (ept == NULL) break; if (!first) { CFStringAppend(names, CFSTR(", ")); } else first = false; CFStringAppend(names, ept->Name()); } info.mDisplayName = names; } else { // a driver-owned endpoint with nothing connected externally, // or an external endpoint CFRetain(info.mDisplayName = ept->Name()); } return true; }
void CAMIDIEndpoints::UpdateFromCurrentState() { Clear(); UInt32 i, n; MIDIEndpointRef epRef; n = MIDIGetNumberOfSources(); mSources.reserve(n); for (i = 0; i < n; ++i) { epRef = MIDIGetSource(i); if (epRef) AddEndpoints(epRef, mSources); } n = MIDIGetNumberOfDestinations(); mDestinations.reserve(n); for (i = 0; i < n; ++i) { epRef = MIDIGetDestination(i); if (epRef) AddEndpoints(epRef, mDestinations); } // pairing for (EndpointList::iterator dit = mDestinations.begin(); dit != mDestinations.end(); ++dit) { Endpoint *ep = *dit; MIDIEntityRef destEntity = ep->Entity(); if (destEntity != NULL) { for (EndpointList::iterator eit = mSources.begin(); eit != mSources.end(); ++eit) { Endpoint *ep2 = *eit; MIDIEntityRef srcEntity = ep2->Entity(); if (srcEntity == destEntity && ep2->DriverOwned() == ep->DriverOwned()) { ep2->SetPairMate(ep); ep->SetPairMate(ep2); } } } } }
CAMIDIEndpoints::EndpointInfoList *CAMIDIEndpoints::GetEndpoints(EMode mode, UInt32 opts) { EndpointList &srcList = (mode == kSources) ? mSources : mDestinations; EndpointInfoList *list = new EndpointInfoList; EndpointInfo info; for (EndpointList::iterator it = srcList.begin(); it != srcList.end(); ++it) { Endpoint *ept = *it; if (ept->DriverOwned()) { // driver-owned endpoint if (ept->Next() == NULL) { // nothing connected externally if ((opts & kOptIncludeUnconnectedExternalPorts) || ept->EmbeddedOrVirtual()) { if (ept->GetEndpointInfo(mode, info)) list->push_back(new EndpointInfo(info)); } } else if (opts & kOptCombineByPort) { // add one item for all connected items if (ept->GetEndpointInfo(mode, info)) list->push_back(new EndpointInfo(info)); } // else it has external connections, which we'll pick up separately } else { // external endpoint if (!(opts & kOptCombineByPort)) { if (ept->GetEndpointInfo(mode, info)) list->push_back(new EndpointInfo(info)); } } } if (opts & kOptSortByName) { std::sort(list->begin(), list->end(), CompareEndpointsByName()); } return list; }