* Copyright (c) 1999-2000, Eric Moon.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MediaIcon.h"
#include "MediaIconBits.h"
#include "AddOnHostProtocol.h"
#include <Application.h>
#include <Roster.h>
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaRoster.h>
#include <MediaAddOn.h>
#include <NodeInfo.h>
#include <String.h>
#include <IconUtils.h>
__USE_CORTEX_NAMESPACE
#include <Debug.h>
#define D_ALLOC(x)
#define D_INTERNAL(x)
MediaIcon::MediaIcon(
const live_node_info &nodeInfo,
icon_size size)
: BBitmap(BRect(0.0, 0.0, size - 1.0, size - 1.0), B_RGBA32),
m_size(size),
m_nodeKind(nodeInfo.node.kind) {
D_ALLOC(("MediaIcon::MediaIcon(live_node_info '%s')\n", nodeInfo.name));
_findIconFor(nodeInfo);
}
MediaIcon::MediaIcon(
const dormant_node_info &nodeInfo,
icon_size size)
: BBitmap(BRect(0.0, 0.0, size - 1.0, size - 1.0), B_RGBA32),
m_size(size),
m_nodeKind(0) {
D_ALLOC(("MediaIcon::MediaIcon(dormant_node_info '%s')\n", nodeInfo.name));
_findIconFor(nodeInfo);
}
MediaIcon::~MediaIcon() {
D_ALLOC(("MediaIcon::~MediaIcon()\n"));
}
bool MediaIcon::_isPhysicalInput() const {
D_INTERNAL(("MediaIcon::_isPhysicalInput()\n"));
return ((m_nodeKind & B_PHYSICAL_INPUT)
&& (m_nodeKind & B_BUFFER_PRODUCER));
}
bool MediaIcon::_isPhysicalOutput() const {
D_INTERNAL(("MediaIcon::_isPhysicalOutput()\n"));
return ((m_nodeKind & B_PHYSICAL_OUTPUT)
&& (m_nodeKind & B_BUFFER_CONSUMER));;
}
bool MediaIcon::_isProducer() const {
D_INTERNAL(("MediaIcon::_isProducer()\n"));
return (!(m_nodeKind & B_BUFFER_CONSUMER) &&
(m_nodeKind & B_BUFFER_PRODUCER) &&
!(m_nodeKind & B_PHYSICAL_INPUT) &&
!(m_nodeKind & B_PHYSICAL_OUTPUT));
}
bool MediaIcon::_isFilter() const {
D_INTERNAL(("MediaIcon::_isFilter()\n"));
return ( (m_nodeKind & B_BUFFER_CONSUMER) &&
(m_nodeKind & B_BUFFER_PRODUCER) &&
!(m_nodeKind & B_PHYSICAL_INPUT) &&
!(m_nodeKind & B_PHYSICAL_OUTPUT));
}
bool MediaIcon::_isConsumer() const {
D_INTERNAL(("MediaIcon::_isConsumer()\n"));
return ( (m_nodeKind & B_BUFFER_CONSUMER) &&
!(m_nodeKind & B_BUFFER_PRODUCER) &&
!(m_nodeKind & B_PHYSICAL_INPUT) &&
!(m_nodeKind & B_PHYSICAL_OUTPUT));
}
bool MediaIcon::_isSystemMixer() const {
D_INTERNAL(("MediaIcon::_isSystemMixer()\n"));
return (m_nodeKind & B_SYSTEM_MIXER);
}
bool MediaIcon::_isTimeSource() const {
D_INTERNAL(("MediaIcon::_isTimeSource()\n"));
return ((m_nodeKind & B_TIME_SOURCE) &&
!(m_nodeKind & B_PHYSICAL_INPUT) &&
!(m_nodeKind & B_PHYSICAL_OUTPUT));
}
void MediaIcon::_findIconFor(
const live_node_info &nodeInfo) {
D_INTERNAL(("MediaIcon::_findIconFor(live_node_info)\n"));
BMediaRoster *roster = BMediaRoster::CurrentRoster();
if (m_nodeKind & B_FILE_INTERFACE) {
entry_ref ref;
if ((roster && (roster->GetRefFor(nodeInfo.node, &ref) == B_OK))
&& (BNodeInfo::GetTrackerIcon(&ref, this, m_size) == B_OK)) {
return;
}
}
dormant_node_info dormantNodeInfo;
if (roster
&& (roster->GetDormantNodeFor(nodeInfo.node, &dormantNodeInfo) == B_OK)) {
D_INTERNAL((" -> instantiated from dormant node\n"));
_findIconFor(dormantNodeInfo);
}
else {
D_INTERNAL((" -> application internal node\n"));
port_info portInfo;
app_info appInfo;
if ((get_port_info(nodeInfo.node.port, &portInfo) == B_OK)
&& (be_roster->GetRunningAppInfo(portInfo.team, &appInfo) == B_OK)) {
D_INTERNAL((" -> application info found: %s\n", appInfo.signature));
app_info thisAppInfo;
if ((be_app->GetAppInfo(&thisAppInfo) != B_OK)
|| ((strcmp(appInfo.signature, thisAppInfo.signature) != 0)
&& (strcmp(appInfo.signature, addon_host::g_appSignature) != 0))) {
BNodeInfo::GetTrackerIcon(&appInfo.ref, this, m_size);
return;
}
}
bool audioIn = false, audioOut = false, videoIn = false, videoOut = false;
_getMediaTypesFor(nodeInfo, &audioIn, &audioOut, &videoIn, &videoOut);
_findDefaultIconFor(audioIn, audioOut, videoIn, videoOut);
}
}
void
MediaIcon::_findIconFor(const dormant_node_info &nodeInfo)
{
D_INTERNAL(("MediaIcon::_findIconFor(dormant_node_info)\n"));
dormant_flavor_info flavorInfo;
BMediaRoster *roster = BMediaRoster::CurrentRoster();
status_t error = roster->GetDormantFlavorInfoFor(nodeInfo, &flavorInfo);
if (error == B_OK) {
m_nodeKind = flavorInfo.kinds;
bool audioIn = false, audioOut = false;
bool videoIn = false, videoOut = false;
_getMediaTypesFor(flavorInfo, &audioIn, &audioOut, &videoIn, &videoOut);
_findDefaultIconFor(audioIn, audioOut, videoIn, videoOut);
} else if (BString(nodeInfo.name).Compare("System clock") == 0) {
BIconUtils::GetVectorIcon(M_TIME_SOURCE_ICON,
sizeof(M_TIME_SOURCE_ICON), this);
} else {
BIconUtils::GetVectorIcon(M_GENERIC_ICON,
sizeof(M_GENERIC_ICON), this);
}
}
void
MediaIcon::_getMediaTypesFor(const live_node_info &nodeInfo, bool *audioIn,
bool *audioOut, bool *videoIn, bool *videoOut)
{
D_INTERNAL(("MediaIcon::_getMediaTypeFor(live_node_info)\n"));
const int32 numberOfInputs = 4;
int32 numberOfFreeInputs, numberOfConnectedInputs;
media_input inputs[numberOfInputs];
const int32 numberOfOutputs = 4;
int32 numberOfFreeOutputs, numberOfConnectedOutputs;
media_output outputs[numberOfOutputs];
BMediaRoster *roster = BMediaRoster::CurrentRoster();
if (roster->GetFreeInputsFor(nodeInfo.node, inputs, numberOfInputs,
&numberOfFreeInputs) == B_OK) {
for (int32 i = 0; i < numberOfFreeInputs; i++) {
if ((inputs[i].format.type == B_MEDIA_RAW_AUDIO)
|| (inputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
*audioIn = true;
continue;
}
if ((inputs[i].format.type == B_MEDIA_RAW_VIDEO)
|| (inputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
*videoIn = true;
}
}
}
if (roster->GetConnectedInputsFor(nodeInfo.node, inputs, numberOfInputs,
&numberOfConnectedInputs) == B_OK) {
for (int32 i = 0; i < numberOfConnectedInputs; i++) {
if ((inputs[i].format.type == B_MEDIA_RAW_AUDIO)
|| (inputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
*audioIn = true;
continue;
}
if ((inputs[i].format.type == B_MEDIA_RAW_VIDEO)
|| (inputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
*videoIn = true;
}
}
}
if (roster->GetFreeOutputsFor(nodeInfo.node, outputs, numberOfOutputs,
&numberOfFreeOutputs) == B_OK) {
for (int32 i = 0; i < numberOfFreeOutputs; i++) {
if ((outputs[i].format.type == B_MEDIA_RAW_AUDIO)
|| (outputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
*audioOut = true;
continue;
}
if ((outputs[i].format.type == B_MEDIA_RAW_VIDEO)
|| (outputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
*videoOut = true;
}
}
}
if (roster->GetConnectedOutputsFor(nodeInfo.node, outputs, numberOfOutputs,
&numberOfConnectedOutputs) == B_OK) {
for (int32 i = 0; i < numberOfConnectedOutputs; i++) {
if ((outputs[i].format.type == B_MEDIA_RAW_AUDIO)
|| (outputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
*audioOut = true;
continue;
}
if ((outputs[i].format.type == B_MEDIA_RAW_VIDEO)
|| (outputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
*videoOut = true;
}
}
}
}
void MediaIcon::_getMediaTypesFor(
const dormant_flavor_info &flavorInfo,
bool *audioIn,
bool *audioOut,
bool *videoIn,
bool *videoOut) {
D_INTERNAL(("MediaIcon::_getMediaTypeFor(dormant_flavor_info)\n"));
for (int32 i = 0; i < flavorInfo.in_format_count; i++) {
if ((flavorInfo.in_formats[i].type == B_MEDIA_RAW_AUDIO)
|| (flavorInfo.in_formats[i].type == B_MEDIA_ENCODED_AUDIO)) {
*audioIn = true;
continue;
}
if ((flavorInfo.in_formats[i].type == B_MEDIA_RAW_VIDEO)
|| (flavorInfo.in_formats[i].type == B_MEDIA_ENCODED_VIDEO)) {
*videoIn = true;
}
}
for (int32 i = 0; i < flavorInfo.out_format_count; i++) {
if ((flavorInfo.out_formats[i].type == B_MEDIA_RAW_AUDIO)
|| (flavorInfo.out_formats[i].type == B_MEDIA_ENCODED_AUDIO)) {
*audioOut = true;
continue;
}
if ((flavorInfo.out_formats[i].type == B_MEDIA_RAW_VIDEO)
|| (flavorInfo.out_formats[i].type == B_MEDIA_ENCODED_VIDEO)) {
*videoOut = true;
}
}
}
void MediaIcon::_findDefaultIconFor(
bool audioIn,
bool audioOut,
bool videoIn,
bool videoOut) {
D_INTERNAL(("MediaIcon::_findDefaultIcon()\n"));
if (_isTimeSource()) {
BIconUtils::GetVectorIcon(M_TIME_SOURCE_ICON,
sizeof(M_TIME_SOURCE_ICON), this);
return;
}
if (_isSystemMixer()) {
BIconUtils::GetVectorIcon(M_AUDIO_MIXER_ICON,
sizeof(M_AUDIO_MIXER_ICON), this);
return;
}
if (m_nodeKind & B_FILE_INTERFACE) {
if (_isProducer()) {
BIconUtils::GetVectorIcon(M_FILE_READER_ICON,
sizeof(M_FILE_READER_ICON), this);
return;
} else {
BIconUtils::GetVectorIcon(M_FILE_WRITER_ICON,
sizeof(M_FILE_WRITER_ICON), this);
return;
}
}
if (_isPhysicalInput()) {
if (audioIn) {
BIconUtils::GetVectorIcon(M_AUDIO_DEVICE_ICON,
sizeof(M_AUDIO_DEVICE_ICON), this);
return;
} else if (audioOut) {
BIconUtils::GetVectorIcon(M_AUDIO_INPUT_ICON,
sizeof(M_AUDIO_INPUT_ICON), this);
return;
} else if (videoOut) {
BIconUtils::GetVectorIcon(M_VIDEO_INPUT_ICON,
sizeof(M_VIDEO_INPUT_ICON), this);
return;
}
}
if (_isPhysicalOutput()) {
if (audioIn) {
BIconUtils::GetVectorIcon(M_AUDIO_OUTPUT_ICON,
sizeof(M_AUDIO_OUTPUT_ICON), this);
return;
} else if (videoIn) {
BIconUtils::GetVectorIcon(M_VIDEO_OUTPUT_ICON,
sizeof(M_VIDEO_OUTPUT_ICON), this);
return;
}
}
if (_isProducer()) {
if (audioOut) {
BIconUtils::GetVectorIcon(M_AUDIO_PRODUCER_ICON,
sizeof(M_AUDIO_PRODUCER_ICON), this);
return;
} else if (videoOut) {
BIconUtils::GetVectorIcon(M_VIDEO_PRODUCER_ICON,
sizeof(M_VIDEO_PRODUCER_ICON), this);
return;
}
}
if (_isFilter()) {
if (audioIn && audioOut && !videoIn && !videoOut) {
BIconUtils::GetVectorIcon(M_AUDIO_FILTER_ICON,
sizeof(M_AUDIO_FILTER_ICON), this);
return;
} else if (audioIn && !videoIn && videoOut) {
BIconUtils::GetVectorIcon(M_AUDIO_CONSUMER_ICON,
sizeof(M_AUDIO_CONSUMER_ICON), this);
return;
} else if (!audioIn && !audioOut && videoIn && videoOut) {
BIconUtils::GetVectorIcon(M_VIDEO_FILTER_ICON,
sizeof(M_VIDEO_FILTER_ICON), this);
return;
}
}
if (_isConsumer()) {
if (audioIn) {
BIconUtils::GetVectorIcon(M_AUDIO_CONSUMER_ICON,
sizeof(M_AUDIO_CONSUMER_ICON), this);
return;
} else if (videoIn) {
BIconUtils::GetVectorIcon(M_VIDEO_CONSUMER_ICON,
sizeof(M_VIDEO_CONSUMER_ICON), this);
return;
}
}
BIconUtils::GetVectorIcon(M_GENERIC_ICON, sizeof(M_GENERIC_ICON), this);
}