* Implemented support for setting/getting the audio gain in the
MediaFilesManager; the client protocol implementation is still missing. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34564 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003, Jérôme Duval. All rights reserved.
|
* Copyright 2003, Jérôme Duval. All rights reserved.
|
||||||
|
* Copyright 2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -30,20 +31,30 @@ MediaFilesManager::MediaFilesManager()
|
|||||||
fSaveTimerRunner(NULL)
|
fSaveTimerRunner(NULL)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
entry_ref ref;
|
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_BEEP, ref, false);
|
static const struct {
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_STARTUP, ref, false);
|
const char* type;
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_DOWN, ref, false);
|
const char* item;
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_REPEAT, ref, false);
|
} kInitialItems[] = {
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_UP, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_BEEP},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_DOWN, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_STARTUP},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_UP, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_DOWN},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ACTIVATED, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_REPEAT},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_CLOSE, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_UP},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_MINIMIZED, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_DOWN},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_OPEN, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_UP},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_RESTORED, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ACTIVATED},
|
||||||
SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ZOOMED, ref, false);
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_CLOSE},
|
||||||
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_MINIMIZED},
|
||||||
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_OPEN},
|
||||||
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_RESTORED},
|
||||||
|
{MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ZOOMED}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(kInitialItems) / sizeof(kInitialItems[0]);
|
||||||
|
i++) {
|
||||||
|
_SetItem(kInitialItems[i].type, kInitialItems[i].item);
|
||||||
|
}
|
||||||
|
|
||||||
_LoadState();
|
_LoadState();
|
||||||
#if DEBUG >=3
|
#if DEBUG >=3
|
||||||
@@ -69,23 +80,26 @@ MediaFilesManager::SaveState()
|
|||||||
TypeMap::iterator iterator = fMap.begin();
|
TypeMap::iterator iterator = fMap.begin();
|
||||||
for (; iterator != fMap.end(); iterator++) {
|
for (; iterator != fMap.end(); iterator++) {
|
||||||
const BString& type = iterator->first;
|
const BString& type = iterator->first;
|
||||||
FileMap& fileMap = iterator->second;
|
ItemMap& itemMap = iterator->second;
|
||||||
|
|
||||||
BMessage items;
|
BMessage items;
|
||||||
status = items.AddString("type", type.String());
|
status = items.AddString("type", type.String());
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
FileMap::iterator fileIterator = fileMap.begin();
|
ItemMap::iterator itemIterator = itemMap.begin();
|
||||||
for (; fileIterator != fileMap.end(); fileIterator++) {
|
for (; itemIterator != itemMap.end(); itemIterator++) {
|
||||||
const BString& item = fileIterator->first;
|
const BString& item = itemIterator->first;
|
||||||
BPath path(&fileIterator->second);
|
item_info& info = itemIterator->second;
|
||||||
|
|
||||||
status = items.AddString("item", item.String());
|
status = items.AddString("item", item.String());
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
|
BPath path(&info.ref);
|
||||||
status = items.AddString("path",
|
status = items.AddString("path",
|
||||||
path.Path() ? path.Path() : "");
|
path.Path() ? path.Path() : "");
|
||||||
}
|
}
|
||||||
|
if (status == B_OK)
|
||||||
|
status = items.AddFloat("gain", info.gain);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -115,16 +129,19 @@ MediaFilesManager::Dump()
|
|||||||
TypeMap::iterator iterator = fMap.begin();
|
TypeMap::iterator iterator = fMap.begin();
|
||||||
for (; iterator != fMap.end(); iterator++) {
|
for (; iterator != fMap.end(); iterator++) {
|
||||||
const BString& type = iterator->first;
|
const BString& type = iterator->first;
|
||||||
FileMap& fileMap = iterator->second;
|
ItemMap& itemMap = iterator->second;
|
||||||
|
|
||||||
FileMap::iterator fileIterator = fileMap.begin();
|
ItemMap::iterator fileIterator = itemMap.begin();
|
||||||
for (; fileIterator != fileMap.end(); fileIterator++) {
|
for (; fileIterator != itemMap.end(); fileIterator++) {
|
||||||
const BString& item = fileIterator->first;
|
const BString& item = fileIterator->first;
|
||||||
BPath path(&fileIterator->second);
|
const item_info& info = fileIterator->second;
|
||||||
|
|
||||||
printf(" type \"%s\", item \"%s\", path \"%s\"\n",
|
BPath path(&info.ref);
|
||||||
|
|
||||||
|
printf(" type \"%s\", item \"%s\", path \"%s\", gain %g\n",
|
||||||
type.String(), item.String(),
|
type.String(), item.String(),
|
||||||
path.InitCheck() == B_OK ? path.Path() : "INVALID");
|
path.InitCheck() == B_OK ? path.Path() : "INVALID",
|
||||||
|
info.gain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,8 +195,8 @@ MediaFilesManager::GetItemsArea(const char* type, int32& count)
|
|||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileMap& fileMap = found->second;
|
ItemMap& itemMap = found->second;
|
||||||
count = fileMap.size();
|
count = itemMap.size();
|
||||||
|
|
||||||
size_t size = (count * B_MEDIA_NAME_LENGTH + B_PAGE_SIZE - 1)
|
size_t size = (count * B_MEDIA_NAME_LENGTH + B_PAGE_SIZE - 1)
|
||||||
& ~(B_PAGE_SIZE - 1);
|
& ~(B_PAGE_SIZE - 1);
|
||||||
@@ -194,8 +211,8 @@ MediaFilesManager::GetItemsArea(const char* type, int32& count)
|
|||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileMap::iterator iterator = fileMap.begin();
|
ItemMap::iterator iterator = itemMap.begin();
|
||||||
for (; iterator != fileMap.end();
|
for (; iterator != itemMap.end();
|
||||||
iterator++, start += B_MEDIA_NAME_LENGTH) {
|
iterator++, start += B_MEDIA_NAME_LENGTH) {
|
||||||
const BString& item = iterator->first;
|
const BString& item = iterator->first;
|
||||||
strncpy(start, item.String(), B_MEDIA_NAME_LENGTH);
|
strncpy(start, item.String(), B_MEDIA_NAME_LENGTH);
|
||||||
@@ -212,59 +229,67 @@ MediaFilesManager::GetRefFor(const char* type, const char* item,
|
|||||||
CALLED();
|
CALLED();
|
||||||
BAutolock _(this);
|
BAutolock _(this);
|
||||||
|
|
||||||
TypeMap::iterator found = fMap.find(BString(type));
|
item_info* info;
|
||||||
if (found == fMap.end())
|
status_t status = _GetItem(type, item, info);
|
||||||
return B_NAME_NOT_FOUND;
|
if (status == B_OK)
|
||||||
|
*_ref = &info->ref;
|
||||||
|
|
||||||
FileMap::iterator foundFile = found->second.find(item);
|
return status;
|
||||||
if (foundFile == found->second.end())
|
|
||||||
return B_NAME_NOT_FOUND;
|
|
||||||
|
|
||||||
*_ref = &foundFile->second;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MediaFilesManager::SetRefFor(const char* _type, const char* _item,
|
MediaFilesManager::GetAudioGainFor(const char* type, const char* item,
|
||||||
const entry_ref& ref, bool save)
|
float* _gain)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
TRACE("MediaFilesManager::SetRefFor %s %s\n", _type, _item);
|
BAutolock _(this);
|
||||||
|
|
||||||
BString type(_type);
|
item_info* info;
|
||||||
type.Truncate(B_MEDIA_NAME_LENGTH);
|
status_t status = _GetItem(type, item, info);
|
||||||
BString item(_item);
|
if (status == B_OK)
|
||||||
item.Truncate(B_MEDIA_NAME_LENGTH);
|
*_gain = info->gain;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MediaFilesManager::SetRefFor(const char* type, const char* item,
|
||||||
|
const entry_ref& ref)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
TRACE("MediaFilesManager::SetRefFor %s %s\n", type, item);
|
||||||
|
|
||||||
BAutolock _(this);
|
BAutolock _(this);
|
||||||
|
|
||||||
try {
|
status_t status = _SetItem(type, item, &ref);
|
||||||
TypeMap::iterator found = fMap.find(type);
|
if (status == B_OK)
|
||||||
if (found == fMap.end()) {
|
|
||||||
// add new type
|
|
||||||
FileMap fileMap;
|
|
||||||
// TODO: For some reason, this does not work:
|
|
||||||
//found = fMap.insert(TypeMap::value_type(type, fileMap));
|
|
||||||
fMap[type] = fileMap;
|
|
||||||
found = fMap.find(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileMap& fileMap = found->second;
|
|
||||||
fileMap[item] = ref;
|
|
||||||
} catch (std::bad_alloc& exception) {
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save)
|
|
||||||
_LaunchTimer();
|
_LaunchTimer();
|
||||||
|
|
||||||
return B_OK;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MediaFilesManager::InvalidateRefFor(const char* type, const char* item)
|
MediaFilesManager::SetAudioGainFor(const char* type, const char* item,
|
||||||
|
float gain)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
TRACE("MediaFilesManager::SetAudioGainFor %s %s %g\n", type, item, gain);
|
||||||
|
|
||||||
|
BAutolock _(this);
|
||||||
|
|
||||||
|
status_t status = _SetItem(type, item, NULL, &gain);
|
||||||
|
if (status == B_OK)
|
||||||
|
_LaunchTimer();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MediaFilesManager::InvalidateItem(const char* type, const char* item)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
BAutolock _(this);
|
BAutolock _(this);
|
||||||
@@ -273,10 +298,8 @@ MediaFilesManager::InvalidateRefFor(const char* type, const char* item)
|
|||||||
if (found == fMap.end())
|
if (found == fMap.end())
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
FileMap& fileMap = found->second;
|
ItemMap& itemMap = found->second;
|
||||||
|
itemMap[item] = item_info();
|
||||||
entry_ref emptyRef;
|
|
||||||
fileMap[item] = emptyRef;
|
|
||||||
|
|
||||||
_LaunchTimer();
|
_LaunchTimer();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -343,6 +366,71 @@ MediaFilesManager::_LaunchTimer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! You need to have the manager locked when calling this method.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
MediaFilesManager::_GetItem(const char* type, const char* item,
|
||||||
|
item_info*& info)
|
||||||
|
{
|
||||||
|
ASSERT(IsLocked());
|
||||||
|
|
||||||
|
TypeMap::iterator found = fMap.find(type);
|
||||||
|
if (found == fMap.end())
|
||||||
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
ItemMap::iterator foundFile = found->second.find(item);
|
||||||
|
if (foundFile == found->second.end())
|
||||||
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
info = &foundFile->second;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! You need to have the manager locked when calling this method after
|
||||||
|
launch.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
MediaFilesManager::_SetItem(const char* _type, const char* _item,
|
||||||
|
const entry_ref* ref, const float* gain)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
TRACE("MediaFilesManager::_SetItem(%s, %s)\n", _type, _item);
|
||||||
|
|
||||||
|
BString type(_type);
|
||||||
|
type.Truncate(B_MEDIA_NAME_LENGTH);
|
||||||
|
BString item(_item);
|
||||||
|
item.Truncate(B_MEDIA_NAME_LENGTH);
|
||||||
|
|
||||||
|
try {
|
||||||
|
TypeMap::iterator found = fMap.find(type);
|
||||||
|
if (found == fMap.end()) {
|
||||||
|
// add new type
|
||||||
|
ItemMap itemMap;
|
||||||
|
// TODO: For some reason, this does not work:
|
||||||
|
//found = fMap.insert(TypeMap::value_type(type, itemMap));
|
||||||
|
fMap[type] = itemMap;
|
||||||
|
found = fMap.find(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMap& itemMap = found->second;
|
||||||
|
item_info info = itemMap[item];
|
||||||
|
|
||||||
|
// only update what we've got
|
||||||
|
if (gain != NULL)
|
||||||
|
info.gain = *gain;
|
||||||
|
if (ref != NULL)
|
||||||
|
info.ref = *ref;
|
||||||
|
|
||||||
|
itemMap[item] = info;
|
||||||
|
} catch (std::bad_alloc& exception) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MediaFilesManager::_OpenSettingsFile(BFile& file, int mode)
|
MediaFilesManager::_OpenSettingsFile(BFile& file, int mode)
|
||||||
{
|
{
|
||||||
@@ -397,11 +485,15 @@ MediaFilesManager::_LoadState()
|
|||||||
if (items.FindString("path", j, &path) != B_OK)
|
if (items.FindString("path", j, &path) != B_OK)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
|
float gain;
|
||||||
|
if (items.FindFloat("gain", j, &gain) != B_OK)
|
||||||
|
gain = 1.0f;
|
||||||
|
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
get_ref_for_path(path, &ref);
|
get_ref_for_path(path, &ref);
|
||||||
// it's okay for this to fail
|
// it's okay for this to fail
|
||||||
|
|
||||||
SetRefFor(type, item, ref, false);
|
_SetItem(type, item, &ref, &gain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,13 @@ public:
|
|||||||
|
|
||||||
status_t GetRefFor(const char* type, const char* item,
|
status_t GetRefFor(const char* type, const char* item,
|
||||||
entry_ref** _ref);
|
entry_ref** _ref);
|
||||||
|
status_t GetAudioGainFor(const char* type,
|
||||||
|
const char* item, float* _gain);
|
||||||
status_t SetRefFor(const char* type, const char* item,
|
status_t SetRefFor(const char* type, const char* item,
|
||||||
const entry_ref& ref, bool save = true);
|
const entry_ref& ref);
|
||||||
status_t InvalidateRefFor(const char* type,
|
status_t SetAudioGainFor(const char* type,
|
||||||
|
const char* item, float gain);
|
||||||
|
status_t InvalidateItem(const char* type,
|
||||||
const char* item);
|
const char* item);
|
||||||
status_t RemoveItem(const char* type, const char* item);
|
status_t RemoveItem(const char* type, const char* item);
|
||||||
|
|
||||||
@@ -43,14 +47,25 @@ public:
|
|||||||
void HandleAddSystemBeepEvent(BMessage* message);
|
void HandleAddSystemBeepEvent(BMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct item_info {
|
||||||
|
item_info() : gain(1.0f) {}
|
||||||
|
|
||||||
|
entry_ref ref;
|
||||||
|
float gain;
|
||||||
|
};
|
||||||
|
|
||||||
void _LaunchTimer();
|
void _LaunchTimer();
|
||||||
|
status_t _GetItem(const char* type, const char* item,
|
||||||
|
item_info*& info);
|
||||||
|
status_t _SetItem(const char* type, const char* item,
|
||||||
|
const entry_ref* ref = NULL,
|
||||||
|
const float* gain = NULL);
|
||||||
status_t _OpenSettingsFile(BFile& file, int mode);
|
status_t _OpenSettingsFile(BFile& file, int mode);
|
||||||
status_t _LoadState();
|
status_t _LoadState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// for each type, the map contains a map of item/entry_ref
|
typedef std::map<BString, item_info> ItemMap;
|
||||||
typedef std::map<BString, entry_ref> FileMap;
|
typedef std::map<BString, ItemMap> TypeMap;
|
||||||
typedef std::map<BString, FileMap> TypeMap;
|
|
||||||
|
|
||||||
TypeMap fMap;
|
TypeMap fMap;
|
||||||
BMessageRunner* fSaveTimerRunner;
|
BMessageRunner* fSaveTimerRunner;
|
||||||
|
|||||||
@@ -810,7 +810,7 @@ ServerApp::_HandleMessage(int32 code, void* data, size_t size)
|
|||||||
= reinterpret_cast<const server_remove_ref_for_request*>(data);
|
= reinterpret_cast<const server_remove_ref_for_request*>(data);
|
||||||
server_remove_ref_for_reply reply;
|
server_remove_ref_for_reply reply;
|
||||||
|
|
||||||
status_t status = gMediaFilesManager->InvalidateRefFor(
|
status_t status = gMediaFilesManager->InvalidateItem(
|
||||||
request->type, request->item);
|
request->type, request->item);
|
||||||
request->SendReply(status, &reply, sizeof(reply));
|
request->SendReply(status, &reply, sizeof(reply));
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user