/* * 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 #include #include #include #include #include #include #include #include #include #include "ESDSinkNode.h" #include "ESDSinkAddOn.h" #include "ESDEndpoint.h" #include #include #include //#undef DEBUG //#define DEBUG 4 #include "debug.h" #include //#define MULTI_SAVE // instantiation function extern "C" _EXPORT BMediaAddOn * make_media_addon(image_id image) { CALLED(); return new ESDSinkAddOn(image); } // -------------------------------------------------------- // // ctor/dtor // -------------------------------------------------------- // 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; } // -------------------------------------------------------- // // BMediaAddOn impl // -------------------------------------------------------- // status_t ESDSinkAddOn::InitCheck( const char ** out_failure_text) { CALLED(); return B_OK; } int32 ESDSinkAddOn::CountFlavors() { CALLED(); //return fDevices.CountItems(); return 1; } status_t ESDSinkAddOn::GetFlavorAt( int32 n, const flavor_info ** out_info) { CALLED(); //if (n < 0 || n > fDevices.CountItems() - 1) { if (n < 0 || n > 1) { fprintf(stderr,"<- B_BAD_INDEX\n"); return B_BAD_INDEX; } //ESDEndpoint *device = (ESDEndpoint *) fDevices.ItemAt(n); flavor_info * infos = new flavor_info[1]; ESDSinkNode::GetFlavor(&infos[0], n); // infos[0].name = device->MD.friendly_name; (*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(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 // currently never called by the media kit. Seems it is not implemented. #if 0 ESDSinkNode * node = dynamic_cast(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;//false; } 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; // XXX: LEAK! PRINT(("AutoStart: in_count=%d\n", in_count)); // if (in_count < 1) // return EINVAL; *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)) { //fSettings.PrintToStream(); } else { PRINT(("Error unflattening settings file %s\n",path.Path())); } } }