* ESounD media addon for BeOS
*
* Copyright (c) 2006 FranΓ§ois Revol (revol@free.fr)
*
* Based on Multi Audio addon for Haiku,
* Copyright (c) 2002, 2003 Jerome Duval (jerome.duval@free.fr)
*
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
*
*/
#define _ZETA_TS_FIND_DIR_ 1
#include <MediaDefs.h>
#include <MediaAddOn.h>
#include <Errors.h>
#include <Node.h>
#include <Mime.h>
#include <StorageDefs.h>
#include <Path.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include "ESDSinkNode.h"
#include "ESDSinkAddOn.h"
#include "ESDEndpoint.h"
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "debug.h"
#include <Debug.h>
extern "C" _EXPORT BMediaAddOn * make_media_addon(image_id image) {
CALLED();
return new ESDSinkAddOn(image);
}
ESDSinkAddOn::~ESDSinkAddOn()
{
CALLED();
void *device = NULL;
for ( int32 i = 0; (device = fDevices.ItemAt(i)); i++ )
delete (ESDEndpoint *)device;
SaveSettings();
}
ESDSinkAddOn::ESDSinkAddOn(image_id image) :
BMediaAddOn(image),
fDevices()
{
CALLED();
fInitCheckStatus = B_NO_INIT;
LoadSettings();
if(SetupDefaultSinks()!=B_OK)
return;
fInitCheckStatus = B_OK;
}
status_t ESDSinkAddOn::InitCheck(
const char ** out_failure_text)
{
CALLED();
return B_OK;
}
int32 ESDSinkAddOn::CountFlavors()
{
CALLED();
return 1;
}
status_t ESDSinkAddOn::GetFlavorAt(
int32 n,
const flavor_info ** out_info)
{
CALLED();
if (n < 0 || n > 1) {
fprintf(stderr,"<- B_BAD_INDEX\n");
return B_BAD_INDEX;
}
flavor_info * infos = new flavor_info[1];
ESDSinkNode::GetFlavor(&infos[0], n);
(*out_info) = infos;
return B_OK;
}
BMediaNode * ESDSinkAddOn::InstantiateNodeFor(
const flavor_info * info,
BMessage * config,
status_t * out_error)
{
CALLED();
BString name = "ESounD Sink";
#ifdef MULTI_SAVE
ESDEndpoint *device = (ESDEndpoint *) fDevices.ItemAt(info->internal_id);
if (device)
device->GetFriendlyName(name);
if(fSettings.FindMessage(name.String(), config)==B_OK) {
fSettings.RemoveData(name.String());
}
#endif
ESDSinkNode * node
= new ESDSinkNode(this,
(char *)name.String(),
config);
if (node == 0) {
*out_error = B_NO_MEMORY;
fprintf(stderr,"<- B_NO_MEMORY\n");
} else {
*out_error = node->InitCheck();
}
return node;
}
status_t
ESDSinkAddOn::GetConfigurationFor(BMediaNode * your_node, BMessage * into_message)
{
CALLED();
#ifdef MULTI_SAVE
if (!into_message)
into_message = new BMessage();
ESDSinkNode * node = dynamic_cast<ESDSinkNode*>(your_node);
if (node == 0) {
fprintf(stderr,"<- B_BAD_TYPE\n");
return B_BAD_TYPE;
}
if(node->GetConfigurationFor(into_message)==B_OK) {
fSettings.AddMessage(your_node->Name(), into_message);
}
return B_OK;
#endif
#if 0
ESDSinkNode * node = dynamic_cast<ESDSinkNode*>(your_node);
if (node == 0) {
fprintf(stderr,"<- B_BAD_TYPE\n");
return B_BAD_TYPE;
}
return node->GetConfigurationFor(into_message);
#endif
return B_ERROR;
}
#if 0
bool ESDSinkAddOn::WantsAutoStart()
{
CALLED();
return true;
}
status_t ESDSinkAddOn::AutoStart(
int in_count,
BMediaNode ** out_node,
int32 * out_internal_id,
bool * out_has_more)
{
CALLED();
const flavor_info *fi;
status_t err;
PRINT(("AutoStart: in_count=%d\n", in_count));
*out_internal_id = 0;
*out_has_more = false;
err = GetFlavorAt(0, (const flavor_info **)&fi);
if (err < 0)
return err;
*out_node = InstantiateNodeFor((const flavor_info *)fi, NULL, &err);
delete fi;
if (err < 0)
return err;
return B_OK+1;
}
#endif
status_t
ESDSinkAddOn::SetupDefaultSinks()
{
CALLED();
#if 0
BDirectory root;
if(rootEntry!=NULL)
root.SetTo(rootEntry);
else if(rootPath!=NULL) {
root.SetTo(rootPath);
} else {
PRINT(("Error in ESDSinkAddOn::RecursiveScan null params\n"));
return B_ERROR;
}
BEntry entry;
while(root.GetNextEntry(&entry) > B_ERROR) {
if(entry.IsDirectory()) {
RecursiveScan(rootPath, &entry);
} else {
BPath path;
entry.GetPath(&path);
ESDEndpoint *device = new ESDEndpoint(path.Path() + strlen(rootPath), path.Path());
if (device) {
if (device->InitCheck() == B_OK)
fDevices.AddItem(device);
else
delete device;
}
}
}
#endif
return B_OK;
}
void
ESDSinkAddOn::SaveSettings(void)
{
CALLED();
BPath path;
if(find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
path.Append(SETTINGS_FILE);
BFile file(path.Path(),B_READ_WRITE|B_CREATE_FILE|B_ERASE_FILE);
if(file.InitCheck()==B_OK)
fSettings.Flatten(&file);
}
}
void
ESDSinkAddOn::LoadSettings(void)
{
CALLED();
fSettings.MakeEmpty();
BPath path;
if(find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
path.Append(SETTINGS_FILE);
BFile file(path.Path(),B_READ_ONLY);
if((file.InitCheck()==B_OK)&&(fSettings.Unflatten(&file)==B_OK))
{
} else {
PRINT(("Error unflattening settings file %s\n",path.Path()));
}
}
}