/* * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) * Distributed under the terms of the MIT License. */ #include #include #include #include #include #include #include #include #include #include #include "MultiAudioNode.h" #include "MultiAudioAddOn.h" #include "MultiAudioDevice.h" #include #include #include #include "debug.h" #define MULTI_SAVE // instantiation function extern "C" _EXPORT BMediaAddOn * make_media_addon(image_id image) { CALLED(); return new MultiAudioAddOn(image); } // -------------------------------------------------------- // // ctor/dtor // -------------------------------------------------------- // MultiAudioAddOn::~MultiAudioAddOn() { CALLED(); void *device = NULL; for (int32 i = 0; (device = fDevices.ItemAt(i)); i++) delete (MultiAudioDevice *)device; SaveSettings(); } MultiAudioAddOn::MultiAudioAddOn(image_id image) : BMediaAddOn(image), fDevices() { CALLED(); fInitCheckStatus = B_NO_INIT; if (RecursiveScan("/dev/audio/hmulti/") != B_OK) return; LoadSettings(); fInitCheckStatus = B_OK; } // -------------------------------------------------------- // // BMediaAddOn impl // -------------------------------------------------------- // status_t MultiAudioAddOn::InitCheck( const char ** out_failure_text) { CALLED(); return B_OK; } int32 MultiAudioAddOn::CountFlavors() { CALLED(); return fDevices.CountItems(); } status_t MultiAudioAddOn::GetFlavorAt( int32 n, const flavor_info ** out_info) { CALLED(); if (out_info == 0) { fprintf(stderr, "<- B_BAD_VALUE\n"); return B_BAD_VALUE; // we refuse to crash because you were stupid } if (n < 0 || n > fDevices.CountItems() - 1) { fprintf(stderr, "<- B_BAD_INDEX\n"); return B_BAD_INDEX; } MultiAudioDevice *device = (MultiAudioDevice *) fDevices.ItemAt(n); flavor_info * infos = new flavor_info[1]; MultiAudioNode::GetFlavor(&infos[0], n); infos[0].name = device->MD.friendly_name; (*out_info) = infos; return B_OK; } BMediaNode * MultiAudioAddOn::InstantiateNodeFor( const flavor_info * info, BMessage * config, status_t * out_error) { CALLED(); if (out_error == 0) { fprintf(stderr, "<- NULL\n"); return 0; // we refuse to crash because you were stupid } MultiAudioDevice *device = (MultiAudioDevice*)fDevices.ItemAt(info->internal_id); if (device == NULL) { *out_error = B_ERROR; return NULL; } #ifdef MULTI_SAVE if (fSettings.FindMessage(device->MD.friendly_name, config) == B_OK) { fSettings.RemoveData(device->MD.friendly_name); } #endif MultiAudioNode * node = new MultiAudioNode(this, device->MD.friendly_name, device, info->internal_id, config); if (node == 0) { *out_error = B_NO_MEMORY; fprintf(stderr, "<- B_NO_MEMORY\n"); } else { *out_error = node->InitCheck(); } return node; } status_t MultiAudioAddOn::GetConfigurationFor(BMediaNode * your_node, BMessage * into_message) { CALLED(); #ifdef MULTI_SAVE if (into_message == 0) { into_message = new BMessage(); MultiAudioNode * 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 (into_message == 0) { fprintf(stderr, "<- B_BAD_VALUE\n"); return B_BAD_VALUE; // we refuse to crash because you were stupid } MultiAudioNode * node = dynamic_cast(your_node); if (node == 0) { fprintf(stderr, "<- B_BAD_TYPE\n"); return B_BAD_TYPE; } return node->GetConfigurationFor(into_message); } bool MultiAudioAddOn::WantsAutoStart() { CALLED(); return false; } status_t MultiAudioAddOn::AutoStart( int in_count, BMediaNode ** out_node, int32 * out_internal_id, bool * out_has_more) { CALLED(); return B_OK; } status_t MultiAudioAddOn::RecursiveScan(char* rootPath, BEntry *rootEntry) { CALLED(); BDirectory root; if (rootEntry != NULL) root.SetTo(rootEntry); else if (rootPath != NULL) { root.SetTo(rootPath); } else { PRINT(("Error in MultiAudioAddOn::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); MultiAudioDevice *device = new MultiAudioDevice(path.Path() + strlen(rootPath), path.Path()); if (device) { if (device->InitCheck() == B_OK) fDevices.AddItem(device); else delete device; } } } return B_OK; } void MultiAudioAddOn::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 MultiAudioAddOn::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)) { PRINT_OBJECT(fSettings); } else { PRINT(("Error unflattening settings file %s\n", path.Path())); } } }