Author: axeld Date: 2009-12-08 19:49:54 +0100 (Tue, 08 Dec 2009) New Revision: 34564 Changeset: http://dev.haiku-os.org/changeset/34564/haiku Modified: haiku/trunk/src/servers/media/MediaFilesManager.cpp haiku/trunk/src/servers/media/MediaFilesManager.h haiku/trunk/src/servers/media/media_server.cpp Log: * Implemented support for setting/getting the audio gain in the MediaFilesManager; the client protocol implementation is still missing. Modified: haiku/trunk/src/servers/media/MediaFilesManager.cpp =================================================================== --- haiku/trunk/src/servers/media/MediaFilesManager.cpp 2009-12-08 18:25:11 UTC (rev 34563) +++ haiku/trunk/src/servers/media/MediaFilesManager.cpp 2009-12-08 18:49:54 UTC (rev 34564) @@ -1,5 +1,6 @@ /* * Copyright 2003, Jérôme Duval. All rights reserved. + * Copyright 2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. */ @@ -30,21 +31,31 @@ fSaveTimerRunner(NULL) { CALLED(); - entry_ref ref; - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_BEEP, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_STARTUP, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_DOWN, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_REPEAT, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_UP, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_DOWN, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_UP, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ACTIVATED, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_CLOSE, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_MINIMIZED, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_OPEN, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_RESTORED, ref, false); - SetRefFor(MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ZOOMED, ref, false); + static const struct { + const char* type; + const char* item; + } kInitialItems[] = { + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_BEEP}, + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_STARTUP}, + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_DOWN}, + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_REPEAT}, + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_KEY_UP}, + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_DOWN}, + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_MOUSE_UP}, + {MEDIA_TYPE_SOUNDS, MEDIA_SOUNDS_WINDOW_ACTIVATED}, + {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(); #if DEBUG >=3 Dump(); @@ -69,23 +80,26 @@ TypeMap::iterator iterator = fMap.begin(); for (; iterator != fMap.end(); iterator++) { const BString& type = iterator->first; - FileMap& fileMap = iterator->second; + ItemMap& itemMap = iterator->second; BMessage items; status = items.AddString("type", type.String()); if (status != B_OK) return status; - FileMap::iterator fileIterator = fileMap.begin(); - for (; fileIterator != fileMap.end(); fileIterator++) { - const BString& item = fileIterator->first; - BPath path(&fileIterator->second); + ItemMap::iterator itemIterator = itemMap.begin(); + for (; itemIterator != itemMap.end(); itemIterator++) { + const BString& item = itemIterator->first; + item_info& info = itemIterator->second; status = items.AddString("item", item.String()); if (status == B_OK) { + BPath path(&info.ref); status = items.AddString("path", path.Path() ? path.Path() : ""); } + if (status == B_OK) + status = items.AddFloat("gain", info.gain); if (status != B_OK) return status; } @@ -115,16 +129,19 @@ TypeMap::iterator iterator = fMap.begin(); for (; iterator != fMap.end(); iterator++) { const BString& type = iterator->first; - FileMap& fileMap = iterator->second; + ItemMap& itemMap = iterator->second; - FileMap::iterator fileIterator = fileMap.begin(); - for (; fileIterator != fileMap.end(); fileIterator++) { + ItemMap::iterator fileIterator = itemMap.begin(); + for (; fileIterator != itemMap.end(); fileIterator++) { 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(), - path.InitCheck() == B_OK ? path.Path() : "INVALID"); + path.InitCheck() == B_OK ? path.Path() : "INVALID", + info.gain); } } @@ -178,8 +195,8 @@ return B_NAME_NOT_FOUND; } - FileMap& fileMap = found->second; - count = fileMap.size(); + ItemMap& itemMap = found->second; + count = itemMap.size(); size_t size = (count * B_MEDIA_NAME_LENGTH + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); @@ -194,8 +211,8 @@ return area; } - FileMap::iterator iterator = fileMap.begin(); - for (; iterator != fileMap.end(); + ItemMap::iterator iterator = itemMap.begin(); + for (; iterator != itemMap.end(); iterator++, start += B_MEDIA_NAME_LENGTH) { const BString& item = iterator->first; strncpy(start, item.String(), B_MEDIA_NAME_LENGTH); @@ -212,59 +229,67 @@ CALLED(); BAutolock _(this); - TypeMap::iterator found = fMap.find(BString(type)); - if (found == fMap.end()) - return B_NAME_NOT_FOUND; + item_info* info; + status_t status = _GetItem(type, item, info); + if (status == B_OK) + *_ref = &info->ref; - FileMap::iterator foundFile = found->second.find(item); - if (foundFile == found->second.end()) - return B_NAME_NOT_FOUND; + return status; +} - *_ref = &foundFile->second; - return B_OK; + +status_t +MediaFilesManager::GetAudioGainFor(const char* type, const char* item, + float* _gain) +{ + CALLED(); + BAutolock _(this); + + item_info* info; + status_t status = _GetItem(type, item, info); + if (status == B_OK) + *_gain = info->gain; + + return status; } status_t -MediaFilesManager::SetRefFor(const char* _type, const char* _item, - const entry_ref& ref, bool save) +MediaFilesManager::SetRefFor(const char* type, const char* item, + const entry_ref& ref) { CALLED(); - TRACE("MediaFilesManager::SetRefFor %s %s\n", _type, _item); + TRACE("MediaFilesManager::SetRefFor %s %s\n", type, item); - BString type(_type); - type.Truncate(B_MEDIA_NAME_LENGTH); - BString item(_item); - item.Truncate(B_MEDIA_NAME_LENGTH); - BAutolock _(this); - try { - TypeMap::iterator found = fMap.find(type); - 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); - } + status_t status = _SetItem(type, item, &ref); + if (status == B_OK) + _LaunchTimer(); - FileMap& fileMap = found->second; - fileMap[item] = ref; - } catch (std::bad_alloc& exception) { - return B_NO_MEMORY; - } + return status; +} - if (save) + +status_t +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 B_OK; + return status; } status_t -MediaFilesManager::InvalidateRefFor(const char* type, const char* item) +MediaFilesManager::InvalidateItem(const char* type, const char* item) { CALLED(); BAutolock _(this); @@ -273,11 +298,9 @@ if (found == fMap.end()) return B_NAME_NOT_FOUND; - FileMap& fileMap = found->second; + ItemMap& itemMap = found->second; + itemMap[item] = item_info(); - entry_ref emptyRef; - fileMap[item] = emptyRef; - _LaunchTimer(); return B_OK; } @@ -343,7 +366,72 @@ } +/*! 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 MediaFilesManager::_OpenSettingsFile(BFile& file, int mode) { bool createFile = (mode & O_ACCMODE) != O_RDONLY; @@ -397,11 +485,15 @@ if (items.FindString("path", j, &path) != B_OK) return B_BAD_DATA; + float gain; + if (items.FindFloat("gain", j, &gain) != B_OK) + gain = 1.0f; + entry_ref ref; get_ref_for_path(path, &ref); // it's okay for this to fail - SetRefFor(type, item, ref, false); + _SetItem(type, item, &ref, &gain); } } Modified: haiku/trunk/src/servers/media/MediaFilesManager.h =================================================================== --- haiku/trunk/src/servers/media/MediaFilesManager.h 2009-12-08 18:25:11 UTC (rev 34563) +++ haiku/trunk/src/servers/media/MediaFilesManager.h 2009-12-08 18:49:54 UTC (rev 34564) @@ -32,9 +32,13 @@ status_t GetRefFor(const char* type, const char* item, entry_ref** _ref); + status_t GetAudioGainFor(const char* type, + const char* item, float* _gain); status_t SetRefFor(const char* type, const char* item, - const entry_ref& ref, bool save = true); - status_t InvalidateRefFor(const char* type, + const entry_ref& ref); + status_t SetAudioGainFor(const char* type, + const char* item, float gain); + status_t InvalidateItem(const char* type, const char* item); status_t RemoveItem(const char* type, const char* item); @@ -43,14 +47,25 @@ void HandleAddSystemBeepEvent(BMessage* message); private: + struct item_info { + item_info() : gain(1.0f) {} + + entry_ref ref; + float gain; + }; + 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 _LoadState(); private: - // for each type, the map contains a map of item/entry_ref - typedef std::map<BString, entry_ref> FileMap; - typedef std::map<BString, FileMap> TypeMap; + typedef std::map<BString, item_info> ItemMap; + typedef std::map<BString, ItemMap> TypeMap; TypeMap fMap; BMessageRunner* fSaveTimerRunner; Modified: haiku/trunk/src/servers/media/media_server.cpp =================================================================== --- haiku/trunk/src/servers/media/media_server.cpp 2009-12-08 18:25:11 UTC (rev 34563) +++ haiku/trunk/src/servers/media/media_server.cpp 2009-12-08 18:49:54 UTC (rev 34564) @@ -810,7 +810,7 @@ = reinterpret_cast<const server_remove_ref_for_request*>(data); server_remove_ref_for_reply reply; - status_t status = gMediaFilesManager->InvalidateRefFor( + status_t status = gMediaFilesManager->InvalidateItem( request->type, request->item); request->SendReply(status, &reply, sizeof(reply)); break;