Beware! The following commit will crash your system when open "Sounds"; I'll
look into this now. * Renamed the MMediaFilesManager to MediaFilesManager. * Got rid of its Map usage, we're using std::map now instead. * The media_server is using an unsafe method to transfer areas from the server to the client. I've changed this for the BMediaFiles API to use Haiku's new transfer_area() function. However, this seems to cause the above mentioned problems. * Improved naming and data exchange structures used for the BMediaFiles API. * Fixed BMediaFiles leaking its lists. * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34554 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -40,10 +40,10 @@ public:
|
||||
virtual status_t RemoveRefFor(const char* type,
|
||||
const char* item, const entry_ref& ref);
|
||||
|
||||
static const char B_SOUNDS[];
|
||||
|
||||
virtual status_t RemoveItem(const char* type, const char* item);
|
||||
|
||||
static const char B_SOUNDS[];
|
||||
|
||||
// TODO: Needs Perform() for FBC reasons!
|
||||
|
||||
private:
|
||||
@@ -58,6 +58,9 @@ private:
|
||||
virtual status_t _Reserved_MediaFiles_6(void*, ...);
|
||||
virtual status_t _Reserved_MediaFiles_7(void*, ...);
|
||||
|
||||
void _ClearTypes();
|
||||
void _ClearItems();
|
||||
|
||||
private:
|
||||
BList fTypes;
|
||||
int fTypeIndex;
|
||||
|
||||
@@ -50,7 +50,8 @@ status_t QueryPort(port_id requestport, int32 msgcode, request_data *request,
|
||||
struct request_data {
|
||||
port_id reply_port;
|
||||
|
||||
status_t SendReply(status_t result, reply_data *reply, int replysize) const;
|
||||
status_t SendReply(status_t result, reply_data* reply,
|
||||
size_t replySize) const;
|
||||
};
|
||||
|
||||
// The base struct used for all raw replys
|
||||
@@ -73,9 +74,15 @@ struct area_request_data : request_data {
|
||||
area_id area;
|
||||
};
|
||||
|
||||
// The base struct used for all requests requesting an area
|
||||
struct request_area_data : request_data {
|
||||
team_id team;
|
||||
};
|
||||
|
||||
// The base struct used for all replies using an area
|
||||
struct area_reply_data : reply_data {
|
||||
area_id area;
|
||||
void* address;
|
||||
};
|
||||
|
||||
} // namespace dataexchange
|
||||
@@ -128,12 +135,12 @@ enum {
|
||||
SERVER_RESCAN_DEFAULTS,
|
||||
SERVER_SET_NODE_CREATOR,
|
||||
SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT,
|
||||
SERVER_REWINDTYPES,
|
||||
SERVER_REWINDREFS,
|
||||
SERVER_GETREFFOR,
|
||||
SERVER_SETREFFOR,
|
||||
SERVER_REMOVEREFFOR,
|
||||
SERVER_REMOVEITEM,
|
||||
SERVER_GET_MEDIA_FILE_TYPES,
|
||||
SERVER_GET_MEDIA_FILE_ITEMS,
|
||||
SERVER_GET_REF_FOR,
|
||||
SERVER_SET_REF_FOR,
|
||||
SERVER_REMOVE_REF_FOR,
|
||||
SERVER_REMOVE_MEDIA_ITEM,
|
||||
SERVER_GET_FORMAT_FOR_DESCRIPTION,
|
||||
SERVER_GET_DESCRIPTION_FOR_FORMAT,
|
||||
SERVER_GET_READERS,
|
||||
@@ -760,54 +767,53 @@ struct server_unregister_buffer_command : command_data {
|
||||
media_buffer_id buffer_id;
|
||||
};
|
||||
|
||||
struct server_rewindtypes_request : request_data {
|
||||
struct server_get_media_types_request : request_area_data {
|
||||
};
|
||||
|
||||
struct server_rewindtypes_reply : area_reply_data {
|
||||
struct server_get_media_types_reply : area_reply_data {
|
||||
int32 count;
|
||||
};
|
||||
|
||||
struct server_rewindrefs_request : request_data {
|
||||
struct server_get_media_items_request : request_area_data {
|
||||
char type[B_MEDIA_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct server_rewindrefs_reply : area_reply_data {
|
||||
struct server_get_media_items_reply : area_reply_data {
|
||||
int32 count;
|
||||
};
|
||||
|
||||
struct server_getreffor_request : request_data {
|
||||
struct server_get_ref_for_request : request_data {
|
||||
char type[B_MEDIA_NAME_LENGTH];
|
||||
char item[B_MEDIA_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct server_getreffor_reply : reply_data {
|
||||
struct server_get_ref_for_reply : reply_data {
|
||||
xfer_entry_ref ref;
|
||||
};
|
||||
|
||||
struct server_setreffor_request : request_data {
|
||||
struct server_set_ref_for_request : request_data {
|
||||
char type[B_MEDIA_NAME_LENGTH];
|
||||
char item[B_MEDIA_NAME_LENGTH];
|
||||
xfer_entry_ref ref;
|
||||
};
|
||||
|
||||
struct server_setreffor_reply : reply_data {
|
||||
struct server_set_ref_for_reply : reply_data {
|
||||
};
|
||||
|
||||
struct server_removereffor_request : request_data {
|
||||
char type[B_MEDIA_NAME_LENGTH];
|
||||
char item[B_MEDIA_NAME_LENGTH];
|
||||
xfer_entry_ref ref;
|
||||
};
|
||||
|
||||
struct server_removereffor_reply : reply_data {
|
||||
};
|
||||
|
||||
struct server_removeitem_request : request_data {
|
||||
struct server_remove_ref_for_request : request_data {
|
||||
char type[B_MEDIA_NAME_LENGTH];
|
||||
char item[B_MEDIA_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct server_removeitem_reply : reply_data {
|
||||
struct server_remove_ref_for_reply : reply_data {
|
||||
};
|
||||
|
||||
struct server_remove_media_item_request : request_data {
|
||||
char type[B_MEDIA_NAME_LENGTH];
|
||||
char item[B_MEDIA_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct server_remove_media_item_reply : reply_data {
|
||||
};
|
||||
|
||||
struct server_get_decoder_for_format_request : request_data {
|
||||
|
||||
@@ -14,7 +14,7 @@ Server media_server :
|
||||
BufferManager.cpp
|
||||
DefaultManager.cpp
|
||||
FormatManager.cpp
|
||||
MMediaFilesManager.cpp
|
||||
MediaFilesManager.cpp
|
||||
NodeManager.cpp
|
||||
NotificationManager.cpp
|
||||
Queue.cpp
|
||||
@@ -23,10 +23,10 @@ Server media_server :
|
||||
AddOnMonitor.cpp
|
||||
AddOnMonitorHandler.cpp
|
||||
NodeMonitorHandler.cpp
|
||||
|
||||
|
||||
: be libmedia.so $(TARGET_LIBSTDC++)
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles AddOnMonitor.cpp
|
||||
AddOnMonitorHandler.cpp
|
||||
NodeMonitorHandler.cpp ] += [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) kits storage ] ;
|
||||
SEARCH on [ FGristFiles AddOnMonitor.cpp AddOnMonitorHandler.cpp
|
||||
NodeMonitorHandler.cpp ]
|
||||
+= [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) kits storage ] ;
|
||||
|
||||
@@ -1,414 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003, Jérôme Duval. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#include "debug.h"
|
||||
#include "MMediaFilesManager.h"
|
||||
#include "MediaSounds.h"
|
||||
|
||||
#include <Application.h>
|
||||
#include <Autolock.h>
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <MediaFiles.h>
|
||||
#include <Path.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
const char *kMediaFilesManagerSettingsDirectory = "Media";
|
||||
const char *kMediaFilesManagerSettingsFile = "MMediaFilesManager";
|
||||
|
||||
|
||||
MMediaFilesManager::MMediaFilesManager()
|
||||
: fLocker(new BLocker("media files manager locker")),
|
||||
fRegistryMap(new Map<BString, Map<BString, entry_ref> >),
|
||||
fRunner(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);
|
||||
|
||||
LoadState();
|
||||
#if DEBUG >=3
|
||||
Dump();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
MMediaFilesManager::~MMediaFilesManager()
|
||||
{
|
||||
CALLED();
|
||||
delete fRunner;
|
||||
delete fRegistryMap;
|
||||
delete fLocker;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
MMediaFilesManager::ReadPascalString(BFile &file, char **str)
|
||||
{
|
||||
uint32 len;
|
||||
*str = NULL;
|
||||
if (file.Read(&len, 4) < 4)
|
||||
return -1;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
*str = (char *)malloc(len);
|
||||
if (file.Read(*str, len) < (int32)len) {
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
return -1;
|
||||
}
|
||||
return (int32)len;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
MMediaFilesManager::WritePascalString(BFile &file, const char *str)
|
||||
{
|
||||
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
uint32 len = strlen(str) + 1;
|
||||
if (file.Write(&len, 4) < 4)
|
||||
return -1;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if (file.Write(str, len) < (int32)len) {
|
||||
return -1;
|
||||
}
|
||||
return (int32)len;
|
||||
}
|
||||
|
||||
|
||||
// this is called by the media_server *before* any add-ons have been loaded
|
||||
status_t
|
||||
MMediaFilesManager::LoadState()
|
||||
{
|
||||
CALLED();
|
||||
BPath path;
|
||||
status_t err = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (err >= B_OK)
|
||||
err = path.Append(kMediaFilesManagerSettingsDirectory);
|
||||
if (err >= B_OK)
|
||||
err = path.Append(kMediaFilesManagerSettingsFile);
|
||||
if (err < B_OK)
|
||||
return err;
|
||||
|
||||
BFile file(path.Path(), B_READ_ONLY);
|
||||
|
||||
uint32 category_count;
|
||||
if (file.Read(header, sizeof(uint32)*3) < (int32)sizeof(uint32)*3) {
|
||||
header[0] = 0xac00150c;
|
||||
header[1] = 0x18723462;
|
||||
header[2] = 0x00000001;
|
||||
return B_ERROR;
|
||||
}
|
||||
TRACE("0x%08lx %ld\n", header[0], header[0]);
|
||||
TRACE("0x%08lx %ld\n", header[1], header[1]);
|
||||
TRACE("0x%08lx %ld\n", header[2], header[2]);
|
||||
if (file.Read(&category_count, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||
return B_ERROR;
|
||||
while (category_count--) {
|
||||
char *str;
|
||||
char *key, *val;
|
||||
int32 len;
|
||||
len = ReadPascalString(file, &str);
|
||||
if (len < 0)
|
||||
return B_ERROR;
|
||||
if (len == 0)
|
||||
break;
|
||||
TRACE("%s {\n", str);
|
||||
do {
|
||||
len = ReadPascalString(file, &key);
|
||||
if (len < 0)
|
||||
return B_ERROR;
|
||||
if (len == 0)
|
||||
break;
|
||||
len = ReadPascalString(file, &val);
|
||||
if (len == 1) {
|
||||
free(val);
|
||||
val = strdup("(null)");
|
||||
}
|
||||
/*if (file.Read(&vol, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||
return B_ERROR;*/
|
||||
//TRACE(" %s: %s, volume: %f\n", key, val, *(float *)&vol);
|
||||
|
||||
entry_ref ref;
|
||||
if (len > 1) {
|
||||
BEntry entry(val);
|
||||
if (entry.Exists())
|
||||
entry.GetRef(&ref);
|
||||
}
|
||||
SetRefFor(str, key, ref, false);
|
||||
|
||||
free(key);
|
||||
free(val);
|
||||
} while (true);
|
||||
TRACE("}\n");
|
||||
free(str);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMediaFilesManager::SaveState()
|
||||
{
|
||||
CALLED();
|
||||
BPath path;
|
||||
status_t err = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (err >= B_OK)
|
||||
err = path.Append(kMediaFilesManagerSettingsDirectory);
|
||||
if (err >= B_OK) {
|
||||
err = create_directory(path.Path(),
|
||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
}
|
||||
if (err >= B_OK)
|
||||
err = path.Append(kMediaFilesManagerSettingsFile);
|
||||
if (err < B_OK)
|
||||
return err;
|
||||
|
||||
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
|
||||
uint32 zero = 0;
|
||||
|
||||
if (file.Write(header, sizeof(uint32)*3) < (int32)sizeof(uint32)*3)
|
||||
return B_ERROR;
|
||||
uint32 category_count = fRegistryMap->CountItems();
|
||||
if (file.Write(&category_count, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||
return B_ERROR;
|
||||
|
||||
BString *type = NULL;
|
||||
Map<BString, entry_ref> *map;
|
||||
BString *item = NULL;
|
||||
entry_ref *ref;
|
||||
for (fRegistryMap->Rewind(); fRegistryMap->GetNext(&map);) {
|
||||
fRegistryMap->GetCurrentKey(&type);
|
||||
|
||||
WritePascalString(file, type->String());
|
||||
|
||||
for (map->Rewind(); map->GetNext(&ref);) {
|
||||
map->GetCurrentKey(&item);
|
||||
BPath path(ref);
|
||||
|
||||
WritePascalString(file, item->String());
|
||||
WritePascalString(file, path.Path() ? path.Path() : "");
|
||||
|
||||
}
|
||||
|
||||
file.Write(&zero, sizeof(uint32));
|
||||
}
|
||||
file.Write(&zero, sizeof(uint32));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MMediaFilesManager::Dump()
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
|
||||
/* for each type, the registry map contains a map of item/entry_ref
|
||||
*/
|
||||
TRACE("MMediaFilesManager: registry map follows\n");
|
||||
BString *type = NULL;
|
||||
Map<BString, entry_ref> *map;
|
||||
BString *item = NULL;
|
||||
entry_ref *ref;
|
||||
for (fRegistryMap->Rewind(); fRegistryMap->GetNext(&map);) {
|
||||
fRegistryMap->GetCurrentKey(&type);
|
||||
|
||||
for (map->Rewind(); map->GetNext(&ref);) {
|
||||
map->GetCurrentKey(&item);
|
||||
BPath path(ref);
|
||||
TRACE(" type \"%s\", item \"%s\", path \"%s\"\n",
|
||||
type->String(), item->String(), (path.InitCheck() == B_OK) ? path.Path() : "INVALID");
|
||||
}
|
||||
}
|
||||
TRACE("MMediaFilesManager: list end\n");
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMediaFilesManager::RewindTypes(BString ***types, int32 *count)
|
||||
{
|
||||
CALLED();
|
||||
if (types == NULL || count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Map<BString, entry_ref> *map;
|
||||
BString *type = NULL;
|
||||
|
||||
*count = fRegistryMap->CountItems();
|
||||
*types = new BString*[*count];
|
||||
int32 i = 0;
|
||||
|
||||
for (fRegistryMap->Rewind(); i < *count && fRegistryMap->GetNext(&map); i++) {
|
||||
fRegistryMap->GetCurrentKey(&type);
|
||||
(*types)[i] = type;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMediaFilesManager::RewindRefs(const char* type, BString ***items, int32 *count)
|
||||
{
|
||||
CALLED();
|
||||
if (type == NULL || items == NULL || count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Map<BString, entry_ref> *map = NULL;
|
||||
entry_ref *ref;
|
||||
BString *item = NULL;
|
||||
|
||||
*count = 0;
|
||||
*items = NULL;
|
||||
|
||||
if (!fRegistryMap->Get(BString(type), &map))
|
||||
return B_OK;
|
||||
|
||||
*count = map->CountItems();
|
||||
*items = new BString*[*count];
|
||||
int32 i = 0;
|
||||
|
||||
for (map->Rewind(); i < *count && map->GetNext(&ref); i++) {
|
||||
map->GetCurrentKey(&item);
|
||||
(*items)[i] = item;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMediaFilesManager::GetRefFor(const char *type,
|
||||
const char *item,
|
||||
entry_ref **out_ref)
|
||||
{
|
||||
CALLED();
|
||||
Map <BString, entry_ref> *map = NULL;
|
||||
if (!fRegistryMap->Get(BString(type), &map))
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
if (!map->Get(BString(item), out_ref))
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMediaFilesManager::SetRefFor(const char *type,
|
||||
const char *item,
|
||||
const entry_ref &ref, bool save)
|
||||
{
|
||||
CALLED();
|
||||
TRACE("MMediaFilesManager::SetRefFor %s %s\n", type, item);
|
||||
|
||||
BString itemString(item);
|
||||
itemString.Truncate(B_MEDIA_NAME_LENGTH);
|
||||
BString typeString(type);
|
||||
Map <BString, entry_ref> *map;
|
||||
if (!fRegistryMap->Get(typeString, &map)) {
|
||||
map = new Map<BString, entry_ref>;
|
||||
fRegistryMap->Insert(typeString, *map);
|
||||
fRegistryMap->Get(typeString, &map);
|
||||
}
|
||||
|
||||
if (map->Has(itemString))
|
||||
map->Remove(itemString);
|
||||
map->Insert(itemString, ref);
|
||||
if (save)
|
||||
LaunchTimer();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMediaFilesManager::RemoveRefFor(const char *type,
|
||||
const char *item,
|
||||
const entry_ref &ref)
|
||||
{
|
||||
CALLED();
|
||||
BString itemString(item);
|
||||
BString typeString(type);
|
||||
Map <BString, entry_ref> *map;
|
||||
if (fRegistryMap->Get(typeString, &map)) {
|
||||
map->Remove(itemString);
|
||||
map->Insert(itemString, *(new entry_ref));
|
||||
LaunchTimer();
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMediaFilesManager::RemoveItem(const char *type,
|
||||
const char *item)
|
||||
{
|
||||
CALLED();
|
||||
BString itemString(item);
|
||||
BString typeString(type);
|
||||
Map <BString, entry_ref> *map;
|
||||
if (fRegistryMap->Get(typeString, &map)) {
|
||||
map->Remove(itemString);
|
||||
LaunchTimer();
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MMediaFilesManager::LaunchTimer()
|
||||
{
|
||||
if (!fRunner)
|
||||
fRunner = new BMessageRunner(be_app,
|
||||
new BMessage(MMEDIAFILESMANAGER_SAVE_TIMER), 3 * 1000000LL, 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MMediaFilesManager::TimerMessage()
|
||||
{
|
||||
SaveState();
|
||||
delete fRunner;
|
||||
fRunner = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MMediaFilesManager::HandleAddSystemBeepEvent(BMessage *msg)
|
||||
{
|
||||
uint32 flags;
|
||||
const char *name, *type;
|
||||
if ((msg->FindString(MEDIA_NAME_KEY, &name) != B_OK)
|
||||
|| (msg->FindString(MEDIA_TYPE_KEY, &type) != B_OK)
|
||||
|| (msg->FindInt32(MEDIA_FLAGS_KEY, (int32 *) &flags) != B_OK)) {
|
||||
msg->SendReply(B_BAD_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
entry_ref *pRef = NULL;
|
||||
if (GetRefFor(type, name, &pRef) == B_ENTRY_NOT_FOUND) {
|
||||
entry_ref ref;
|
||||
SetRefFor(type, name, ref);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003, Jérôme Duval. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <Locker.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <String.h>
|
||||
#include "TMap.h"
|
||||
#include "DataExchange.h"
|
||||
|
||||
#define MMEDIAFILESMANAGER_SAVE_TIMER 'mmst'
|
||||
|
||||
class MMediaFilesManager
|
||||
{
|
||||
public:
|
||||
MMediaFilesManager();
|
||||
~MMediaFilesManager();
|
||||
|
||||
status_t LoadState();
|
||||
status_t SaveState();
|
||||
|
||||
void Dump();
|
||||
|
||||
status_t RewindTypes(
|
||||
BString ***types,
|
||||
int32 *count);
|
||||
status_t RewindRefs(
|
||||
const char * type,
|
||||
BString ***items,
|
||||
int32 *count);
|
||||
status_t GetRefFor(
|
||||
const char * type,
|
||||
const char * item,
|
||||
entry_ref ** out_ref);
|
||||
status_t SetRefFor(
|
||||
const char * type,
|
||||
const char * item,
|
||||
const entry_ref & ref,
|
||||
bool save = true);
|
||||
status_t RemoveRefFor(
|
||||
const char * type,
|
||||
const char * item,
|
||||
const entry_ref & ref);
|
||||
|
||||
status_t RemoveItem(
|
||||
const char * type,
|
||||
const char * item);
|
||||
|
||||
void TimerMessage();
|
||||
|
||||
void HandleAddSystemBeepEvent(BMessage *msg);
|
||||
|
||||
private:
|
||||
static int32 ReadPascalString(BFile &file, char **str);
|
||||
static int32 WritePascalString(BFile &file, const char *str);
|
||||
void LaunchTimer();
|
||||
private:
|
||||
BLocker *fLocker;
|
||||
|
||||
Map<BString, Map<BString, entry_ref> > * fRegistryMap;
|
||||
|
||||
uint32 header[3];
|
||||
|
||||
BMessageRunner *fRunner;
|
||||
};
|
||||
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright 2003, Jérôme Duval. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "MediaFilesManager.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Autolock.h>
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <MediaFiles.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <MediaSounds.h>
|
||||
|
||||
|
||||
const char* kMediaFilesManagerSettingsDirectory = "Media";
|
||||
const char* kMediaFilesManagerSettingsFile = "MediaFilesManager";
|
||||
|
||||
const uint32 kHeader[] = {0xac00150c, 0x18723462, 0x00000001};
|
||||
|
||||
|
||||
MediaFilesManager::MediaFilesManager()
|
||||
:
|
||||
BLocker("media files manager"),
|
||||
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);
|
||||
|
||||
LoadState();
|
||||
#if DEBUG >=3
|
||||
Dump();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
MediaFilesManager::~MediaFilesManager()
|
||||
{
|
||||
CALLED();
|
||||
delete fSaveTimerRunner;
|
||||
}
|
||||
|
||||
|
||||
//! This is called by the media_server *before* any add-ons have been loaded.
|
||||
status_t
|
||||
MediaFilesManager::LoadState()
|
||||
{
|
||||
CALLED();
|
||||
BPath path;
|
||||
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (status == B_OK)
|
||||
status = path.Append(kMediaFilesManagerSettingsDirectory);
|
||||
if (status == B_OK)
|
||||
status = path.Append(kMediaFilesManagerSettingsFile);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BFile file;
|
||||
status = file.SetTo(path.Path(), B_READ_ONLY);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
uint32 header[3];
|
||||
if (file.Read(header, sizeof(header)) < (int32)sizeof(header))
|
||||
return B_ERROR;
|
||||
if (memcmp(header, kHeader, sizeof(kHeader)) != 0)
|
||||
return B_ERROR;
|
||||
|
||||
uint32 categoryCount;
|
||||
if (file.Read(&categoryCount, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||
return B_ERROR;
|
||||
|
||||
while (categoryCount--) {
|
||||
BString type;
|
||||
ssize_t length = _ReadSettingsString(file, type);
|
||||
if (length < 0)
|
||||
return length;
|
||||
if (length == 0)
|
||||
break;
|
||||
|
||||
TRACE("%s {\n", type.String());
|
||||
|
||||
do {
|
||||
BString key;
|
||||
length = _ReadSettingsString(file, key);
|
||||
if (length < 0)
|
||||
return length;
|
||||
if (length == 0)
|
||||
break;
|
||||
|
||||
BString value;
|
||||
length = _ReadSettingsString(file, value);
|
||||
|
||||
entry_ref ref;
|
||||
if (length > 1)
|
||||
get_ref_for_path(value.String(), &ref);
|
||||
|
||||
SetRefFor(type, key.String(), ref, false);
|
||||
} while (true);
|
||||
|
||||
TRACE("}\n");
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFilesManager::SaveState()
|
||||
{
|
||||
CALLED();
|
||||
BPath path;
|
||||
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (status == B_OK)
|
||||
status = path.Append(kMediaFilesManagerSettingsDirectory);
|
||||
if (status == B_OK) {
|
||||
status = create_directory(path.Path(),
|
||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
}
|
||||
if (status == B_OK)
|
||||
status = path.Append(kMediaFilesManagerSettingsFile);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BFile file;
|
||||
status = file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (file.Write(kHeader, sizeof(kHeader)) < (ssize_t)sizeof(kHeader))
|
||||
return B_ERROR;
|
||||
|
||||
BAutolock _(this);
|
||||
|
||||
uint32 categoryCount = fMap.size();
|
||||
if (file.Write(&categoryCount, sizeof(uint32)) < (ssize_t)sizeof(uint32))
|
||||
return B_ERROR;
|
||||
|
||||
uint32 zero = 0;
|
||||
|
||||
TypeMap::iterator iterator = fMap.begin();
|
||||
for (; iterator != fMap.end(); iterator++) {
|
||||
const BString& type = iterator->first;
|
||||
FileMap& fileMap = iterator->second;
|
||||
|
||||
_WriteSettingsString(file, type.String());
|
||||
|
||||
FileMap::iterator fileIterator = fileMap.begin();
|
||||
for (; fileIterator != fileMap.end(); fileIterator++) {
|
||||
const BString& item = fileIterator->first;
|
||||
BPath path(&fileIterator->second);
|
||||
|
||||
_WriteSettingsString(file, item.String());
|
||||
_WriteSettingsString(file, path.Path() ? path.Path() : "");
|
||||
}
|
||||
|
||||
file.Write(&zero, sizeof(uint32));
|
||||
}
|
||||
file.Write(&zero, sizeof(uint32));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MediaFilesManager::Dump()
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
printf("MediaFilesManager: types follow\n");
|
||||
|
||||
TypeMap::iterator iterator = fMap.begin();
|
||||
for (; iterator != fMap.end(); iterator++) {
|
||||
const BString& type = iterator->first;
|
||||
FileMap& fileMap = iterator->second;
|
||||
|
||||
FileMap::iterator fileIterator = fileMap.begin();
|
||||
for (; fileIterator != fileMap.end(); fileIterator++) {
|
||||
const BString& item = fileIterator->first;
|
||||
BPath path(&fileIterator->second);
|
||||
|
||||
printf(" type \"%s\", item \"%s\", path \"%s\"\n",
|
||||
type.String(), item.String(),
|
||||
path.InitCheck() == B_OK ? path.Path() : "INVALID");
|
||||
}
|
||||
}
|
||||
|
||||
printf("MediaFilesManager: list end\n");
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
MediaFilesManager::GetTypesArea(int32& count)
|
||||
{
|
||||
CALLED();
|
||||
BAutolock _(this);
|
||||
|
||||
count = fMap.size();
|
||||
|
||||
size_t size = (count * B_MEDIA_NAME_LENGTH + B_PAGE_SIZE - 1)
|
||||
& ~(B_PAGE_SIZE - 1);
|
||||
|
||||
char* start;
|
||||
area_id area = create_area("media types", (void**)&start, B_ANY_ADDRESS,
|
||||
size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (area < 0) {
|
||||
ERROR("MediaFilesManager::GetTypesArea(): failed to create area: %s\n",
|
||||
strerror(area));
|
||||
count = 0;
|
||||
return area;
|
||||
}
|
||||
|
||||
TypeMap::iterator iterator = fMap.begin();
|
||||
for (; iterator != fMap.end(); iterator++, start += B_MEDIA_NAME_LENGTH) {
|
||||
const BString& type = iterator->first;
|
||||
strncpy(start, type.String(), B_MEDIA_NAME_LENGTH);
|
||||
}
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
MediaFilesManager::GetItemsArea(const char* type, int32& count)
|
||||
{
|
||||
CALLED();
|
||||
if (type == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BAutolock _(this);
|
||||
|
||||
TypeMap::iterator found = fMap.find(BString(type));
|
||||
if (found == fMap.end()) {
|
||||
count = 0;
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
FileMap& fileMap = found->second;
|
||||
count = fileMap.size();
|
||||
|
||||
size_t size = (count * B_MEDIA_NAME_LENGTH + B_PAGE_SIZE - 1)
|
||||
& ~(B_PAGE_SIZE - 1);
|
||||
|
||||
char* start;
|
||||
area_id area = create_area("media refs", (void**)&start, B_ANY_ADDRESS,
|
||||
size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (area < 0) {
|
||||
ERROR("MediaFilesManager::GetRefsArea(): failed to create area: %s\n",
|
||||
strerror(area));
|
||||
count = 0;
|
||||
return area;
|
||||
}
|
||||
|
||||
FileMap::iterator iterator = fileMap.begin();
|
||||
for (; iterator != fileMap.end();
|
||||
iterator++, start += B_MEDIA_NAME_LENGTH) {
|
||||
const BString& item = iterator->first;
|
||||
strncpy(start, item.String(), B_MEDIA_NAME_LENGTH);
|
||||
}
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFilesManager::GetRefFor(const char* type, const char* item,
|
||||
entry_ref** _ref)
|
||||
{
|
||||
CALLED();
|
||||
BAutolock _(this);
|
||||
|
||||
TypeMap::iterator found = fMap.find(BString(type));
|
||||
if (found == fMap.end())
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
FileMap::iterator foundFile = found->second.find(item);
|
||||
if (foundFile == found->second.end())
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
*_ref = &foundFile->second;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFilesManager::SetRefFor(const char* _type, const char* _item,
|
||||
const entry_ref& ref, bool save)
|
||||
{
|
||||
CALLED();
|
||||
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);
|
||||
}
|
||||
|
||||
FileMap& fileMap = found->second;
|
||||
fileMap[item] = ref;
|
||||
} catch (std::bad_alloc& exception) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (save)
|
||||
_LaunchTimer();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFilesManager::InvalidateRefFor(const char* type, const char* item)
|
||||
{
|
||||
CALLED();
|
||||
BAutolock _(this);
|
||||
|
||||
TypeMap::iterator found = fMap.find(type);
|
||||
if (found == fMap.end())
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
FileMap& fileMap = found->second;
|
||||
|
||||
entry_ref emptyRef;
|
||||
fileMap[item] = emptyRef;
|
||||
|
||||
_LaunchTimer();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFilesManager::RemoveItem(const char *type, const char *item)
|
||||
{
|
||||
CALLED();
|
||||
BAutolock _(this);
|
||||
|
||||
TypeMap::iterator found = fMap.find(type);
|
||||
if (found == fMap.end())
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
found->second.erase(item);
|
||||
if (found->second.empty())
|
||||
fMap.erase(found);
|
||||
|
||||
_LaunchTimer();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MediaFilesManager::TimerMessage()
|
||||
{
|
||||
SaveState();
|
||||
|
||||
delete fSaveTimerRunner;
|
||||
fSaveTimerRunner = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MediaFilesManager::HandleAddSystemBeepEvent(BMessage* message)
|
||||
{
|
||||
const char* name;
|
||||
const char* type;
|
||||
uint32 flags;
|
||||
if (message->FindString(MEDIA_NAME_KEY, &name) != B_OK
|
||||
|| message->FindString(MEDIA_TYPE_KEY, &type) != B_OK
|
||||
|| message->FindInt32(MEDIA_FLAGS_KEY, (int32 *)&flags) != B_OK) {
|
||||
message->SendReply(B_BAD_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
entry_ref* ref = NULL;
|
||||
if (GetRefFor(type, name, &ref) == B_ENTRY_NOT_FOUND) {
|
||||
entry_ref newRef;
|
||||
SetRefFor(type, name, newRef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MediaFilesManager::_LaunchTimer()
|
||||
{
|
||||
if (fSaveTimerRunner == NULL) {
|
||||
BMessage timer(MEDIA_FILES_MANAGER_SAVE_TIMER);
|
||||
fSaveTimerRunner = new BMessageRunner(be_app, &timer, 3 * 1000000LL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static*/ int32
|
||||
MediaFilesManager::_ReadSettingsString(BFile& file, BString& string)
|
||||
{
|
||||
uint32 length;
|
||||
if (file.Read(&length, 4) < 4)
|
||||
return -1;
|
||||
|
||||
if (length == 0) {
|
||||
string.Truncate(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* buffer = string.LockBuffer(length);
|
||||
if (buffer == NULL)
|
||||
return -1;
|
||||
|
||||
ssize_t bytesRead = file.Read(buffer, length);
|
||||
string.UnlockBuffer(length);
|
||||
|
||||
if (bytesRead < (ssize_t)length)
|
||||
return -1;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFilesManager::_WriteSettingsString(BFile& file, const char* string)
|
||||
{
|
||||
if (string == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
uint32 length = strlen(string);
|
||||
if (file.Write(&length, 4) < 4)
|
||||
return B_ERROR;
|
||||
|
||||
if (length == 0)
|
||||
return B_OK;
|
||||
|
||||
if (file.Write(string, length) < (ssize_t)length)
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2003, Jérôme Duval. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <Locker.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <DataExchange.h>
|
||||
|
||||
|
||||
#define MEDIA_FILES_MANAGER_SAVE_TIMER 'mmst'
|
||||
|
||||
|
||||
class MediaFilesManager : BLocker {
|
||||
public:
|
||||
MediaFilesManager();
|
||||
~MediaFilesManager();
|
||||
|
||||
status_t LoadState();
|
||||
status_t SaveState();
|
||||
|
||||
void Dump();
|
||||
|
||||
area_id GetTypesArea(int32& count);
|
||||
area_id GetItemsArea(const char* type, int32& count);
|
||||
|
||||
status_t GetRefFor(const char* type, const char* item,
|
||||
entry_ref** _ref);
|
||||
status_t SetRefFor(const char* type, const char* item,
|
||||
const entry_ref& ref, bool save = true);
|
||||
status_t InvalidateRefFor(const char* type,
|
||||
const char* item);
|
||||
status_t RemoveItem(const char* type, const char* item);
|
||||
|
||||
void TimerMessage();
|
||||
|
||||
void HandleAddSystemBeepEvent(BMessage* message);
|
||||
|
||||
private:
|
||||
void _LaunchTimer();
|
||||
|
||||
static ssize_t _ReadSettingsString(BFile& file,
|
||||
BString& string);
|
||||
static status_t _WriteSettingsString(BFile& file,
|
||||
const char* string);
|
||||
|
||||
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;
|
||||
|
||||
TypeMap fMap;
|
||||
BMessageRunner* fSaveTimerRunner;
|
||||
};
|
||||
+151
-197
@@ -45,13 +45,15 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
|
||||
#include <MediaFormats.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#include <syscalls.h>
|
||||
|
||||
#include "AddOnManager.h"
|
||||
#include "AppManager.h"
|
||||
#include "BufferManager.h"
|
||||
#include "DataExchange.h"
|
||||
#include "FormatManager.h"
|
||||
#include "MediaMisc.h"
|
||||
#include "MMediaFilesManager.h"
|
||||
#include "MediaFilesManager.h"
|
||||
#include "NodeManager.h"
|
||||
#include "NotificationManager.h"
|
||||
#include "ServerInterface.h"
|
||||
@@ -59,86 +61,80 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
|
||||
#include "media_server.h"
|
||||
|
||||
|
||||
AddOnManager * gAddOnManager;
|
||||
AppManager * gAppManager;
|
||||
BufferManager * gBufferManager;
|
||||
FormatManager * gFormatManager;
|
||||
MMediaFilesManager * gMMediaFilesManager;
|
||||
NodeManager * gNodeManager;
|
||||
NotificationManager * gNotificationManager;
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
extern team_id team;
|
||||
} } // BPrivate::media
|
||||
AddOnManager* gAddOnManager;
|
||||
AppManager* gAppManager;
|
||||
BufferManager* gBufferManager;
|
||||
FormatManager* gFormatManager;
|
||||
MediaFilesManager* gMediaFilesManager;
|
||||
NodeManager* gNodeManager;
|
||||
NotificationManager* gNotificationManager;
|
||||
|
||||
|
||||
#define REPLY_TIMEOUT ((bigtime_t)500000)
|
||||
|
||||
class ServerApp : BApplication
|
||||
{
|
||||
|
||||
class ServerApp : BApplication {
|
||||
public:
|
||||
ServerApp();
|
||||
~ServerApp();
|
||||
|
||||
private:
|
||||
bool QuitRequested();
|
||||
void HandleMessage(int32 code, void *data, size_t size);
|
||||
void ArgvReceived(int32 argc, char **argv);
|
||||
|
||||
void StartAddonServer();
|
||||
void TerminateAddonServer();
|
||||
|
||||
/* functionality not yet implemented
|
||||
00014a00 T _ServerApp::_ServerApp(void)
|
||||
00014e1c T _ServerApp::~_ServerApp(void)
|
||||
00014ff4 T _ServerApp::MessageReceived(BMessage *);
|
||||
00015840 T _ServerApp::QuitRequested(void)
|
||||
00015b50 T _ServerApp::_DoNotify(command_data *)
|
||||
00015d18 T _ServerApp::_UnregisterApp(long, bool)
|
||||
00018e90 T _ServerApp::AddOnHost(void)
|
||||
00019530 T _ServerApp::AboutRequested(void)
|
||||
00019d04 T _ServerApp::AddPurgableBufferGroup(long, long, long, void *)
|
||||
00019db8 T _ServerApp::CancelPurgableBufferGroupCleanup(long)
|
||||
00019e50 T _ServerApp::DirtyWork(void)
|
||||
0001a4bc T _ServerApp::ArgvReceived(long, char **)
|
||||
0001a508 T _ServerApp::CleanupPurgedBufferGroup(_ServerApp::purgable_buffer_group const &, bool)
|
||||
0001a5dc T _ServerApp::DirtyWorkLaunch(void *)
|
||||
0001a634 T _ServerApp::SetQuitMode(bool)
|
||||
0001a648 T _ServerApp::IsQuitMode(void) const
|
||||
0001a658 T _ServerApp::BroadcastCurrentStateTo(BMessenger &)
|
||||
0001adcc T _ServerApp::ReadyToRun(void)
|
||||
*/
|
||||
|
||||
static int32 controlthread(void *arg);
|
||||
protected:
|
||||
virtual void ArgvReceived(int32 argc, char** argv);
|
||||
virtual void ReadyToRun();
|
||||
virtual bool QuitRequested();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
port_id control_port;
|
||||
thread_id control_thread;
|
||||
void _HandleMessage(int32 code, void* data,
|
||||
size_t size);
|
||||
void _LaunchAddOnServer();
|
||||
void _QuitAddOnServer();
|
||||
|
||||
BLocker *fLocker;
|
||||
private:
|
||||
port_id _ControlPort() const { return fControlPort; }
|
||||
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
virtual void ReadyToRun();
|
||||
typedef BApplication inherited;
|
||||
static int32 _ControlThread(void* arg);
|
||||
|
||||
BLocker fLocker;
|
||||
port_id fControlPort;
|
||||
thread_id fControlThread;
|
||||
};
|
||||
|
||||
|
||||
ServerApp::ServerApp()
|
||||
: BApplication(B_MEDIA_SERVER_SIGNATURE),
|
||||
fLocker(new BLocker("media server locker"))
|
||||
:
|
||||
BApplication(B_MEDIA_SERVER_SIGNATURE),
|
||||
fLocker("media server locker")
|
||||
{
|
||||
gNotificationManager = new NotificationManager;
|
||||
gBufferManager = new BufferManager;
|
||||
gAppManager = new AppManager;
|
||||
gNodeManager = new NodeManager;
|
||||
gMMediaFilesManager = new MMediaFilesManager;
|
||||
gMediaFilesManager = new MediaFilesManager;
|
||||
gFormatManager = new FormatManager;
|
||||
gAddOnManager = new AddOnManager;
|
||||
|
||||
control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
|
||||
control_thread = spawn_thread(controlthread, "media_server control", 105,
|
||||
fControlPort = create_port(64, MEDIA_SERVER_PORT_NAME);
|
||||
fControlThread = spawn_thread(_ControlThread, "media_server control", 105,
|
||||
this);
|
||||
resume_thread(control_thread);
|
||||
resume_thread(fControlThread);
|
||||
}
|
||||
|
||||
|
||||
ServerApp::~ServerApp()
|
||||
{
|
||||
TRACE("ServerApp::~ServerApp()\n");
|
||||
|
||||
delete_port(fControlPort);
|
||||
wait_for_thread(fControlThread, NULL);
|
||||
|
||||
delete gAddOnManager;
|
||||
delete gNotificationManager;
|
||||
delete gBufferManager;
|
||||
delete gAppManager;
|
||||
delete gNodeManager;
|
||||
delete gMediaFilesManager;
|
||||
delete gFormatManager;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,40 +145,25 @@ ServerApp::ReadyToRun()
|
||||
gFormatManager->LoadState();
|
||||
|
||||
// make sure any previous media_addon_server is gone
|
||||
TerminateAddonServer();
|
||||
_QuitAddOnServer();
|
||||
// and start a new one
|
||||
StartAddonServer();
|
||||
_LaunchAddOnServer();
|
||||
|
||||
gAddOnManager->LoadState();
|
||||
}
|
||||
|
||||
|
||||
ServerApp::~ServerApp()
|
||||
{
|
||||
TRACE("ServerApp::~ServerApp()\n");
|
||||
delete gAddOnManager;
|
||||
delete gNotificationManager;
|
||||
delete gBufferManager;
|
||||
delete gAppManager;
|
||||
delete gNodeManager;
|
||||
delete gMMediaFilesManager;
|
||||
delete gFormatManager;
|
||||
delete fLocker;
|
||||
delete_port(control_port);
|
||||
status_t err;
|
||||
wait_for_thread(control_thread,&err);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ServerApp::QuitRequested()
|
||||
{
|
||||
TRACE("ServerApp::QuitRequested()\n");
|
||||
gMMediaFilesManager->SaveState();
|
||||
gMediaFilesManager->SaveState();
|
||||
gNodeManager->SaveState();
|
||||
gFormatManager->SaveState();
|
||||
gAddOnManager->SaveState();
|
||||
TerminateAddonServer();
|
||||
|
||||
_QuitAddOnServer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -191,28 +172,27 @@ void
|
||||
ServerApp::ArgvReceived(int32 argc, char **argv)
|
||||
{
|
||||
for (int arg = 1; arg < argc; arg++) {
|
||||
if (strstr(argv[arg], "dump")) {
|
||||
if (strstr(argv[arg], "dump") != NULL) {
|
||||
gAppManager->Dump();
|
||||
gNodeManager->Dump();
|
||||
gBufferManager->Dump();
|
||||
gNotificationManager->Dump();
|
||||
gMMediaFilesManager->Dump();
|
||||
gMediaFilesManager->Dump();
|
||||
}
|
||||
if (strstr(argv[arg], "buffer")) {
|
||||
if (strstr(argv[arg], "buffer") != NULL)
|
||||
gBufferManager->Dump();
|
||||
}
|
||||
if (strstr(argv[arg], "node")) {
|
||||
if (strstr(argv[arg], "node") != NULL)
|
||||
gNodeManager->Dump();
|
||||
}
|
||||
if (strstr(argv[arg], "quit")) {
|
||||
if (strstr(argv[arg], "files") != NULL)
|
||||
gMediaFilesManager->Dump();
|
||||
if (strstr(argv[arg], "quit") != NULL)
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ServerApp::StartAddonServer()
|
||||
ServerApp::_LaunchAddOnServer()
|
||||
{
|
||||
// Try to launch media_addon_server by mime signature.
|
||||
// If it fails (for example on the Live CD, where the executable
|
||||
@@ -248,7 +228,7 @@ ServerApp::StartAddonServer()
|
||||
|
||||
|
||||
void
|
||||
ServerApp::TerminateAddonServer()
|
||||
ServerApp::_QuitAddOnServer()
|
||||
{
|
||||
// nothing to do if it's already terminated
|
||||
if (!be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE))
|
||||
@@ -291,7 +271,7 @@ ServerApp::TerminateAddonServer()
|
||||
|
||||
|
||||
void
|
||||
ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
ServerApp::_HandleMessage(int32 code, void* data, size_t size)
|
||||
{
|
||||
status_t rv;
|
||||
TRACE("ServerApp::HandleMessage %#lx enter\n", code);
|
||||
@@ -737,140 +717,115 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REWINDTYPES:
|
||||
case SERVER_GET_MEDIA_FILE_TYPES:
|
||||
{
|
||||
const server_rewindtypes_request *request
|
||||
= reinterpret_cast<const server_rewindtypes_request *>(data);
|
||||
server_rewindtypes_reply reply;
|
||||
const server_get_media_types_request& request
|
||||
= *reinterpret_cast<const server_get_media_types_request*>(
|
||||
data);
|
||||
|
||||
BString **types = NULL;
|
||||
|
||||
rv = gMMediaFilesManager->RewindTypes(
|
||||
&types, &reply.count);
|
||||
if (reply.count > 0) {
|
||||
// we create an area here, and pass it to the library,
|
||||
// where it will be deleted.
|
||||
char *start_addr;
|
||||
size_t size = ((reply.count * B_MEDIA_NAME_LENGTH)
|
||||
+ B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||
reply.area = create_area("rewind types",
|
||||
reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS,
|
||||
size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (reply.area < B_OK) {
|
||||
ERROR("SERVER_REWINDTYPES: failed to create area, "
|
||||
"error %s\n", strerror(reply.area));
|
||||
server_get_media_types_reply reply;
|
||||
reply.area = gMediaFilesManager->GetTypesArea(reply.count);
|
||||
if (reply.area >= 0) {
|
||||
// transfer the area to the target team
|
||||
status_t status = _kern_transfer_area(reply.area,
|
||||
&reply.address, B_ANY_ADDRESS, request.team);
|
||||
if (status != B_OK) {
|
||||
delete_area(reply.area);
|
||||
reply.area = B_ERROR;
|
||||
reply.count = 0;
|
||||
rv = B_ERROR;
|
||||
} else {
|
||||
for (int32 index = 0; index < reply.count; index++) {
|
||||
strncpy(start_addr + B_MEDIA_NAME_LENGTH * index,
|
||||
types[index]->String(), B_MEDIA_NAME_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] types;
|
||||
|
||||
rv = request->SendReply(rv, &reply, sizeof(reply));
|
||||
if (rv != B_OK) {
|
||||
status_t status = request.SendReply(
|
||||
reply.area < 0 ? reply.area : B_OK, &reply, sizeof(reply));
|
||||
if (status != B_OK) {
|
||||
// if we couldn't send the message, delete the area
|
||||
delete_area(reply.area);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REWINDREFS:
|
||||
case SERVER_GET_MEDIA_FILE_ITEMS:
|
||||
{
|
||||
const server_rewindrefs_request *request
|
||||
= reinterpret_cast<const server_rewindrefs_request *>(data);
|
||||
server_rewindrefs_reply reply;
|
||||
const server_get_media_items_request& request
|
||||
= *reinterpret_cast<const server_get_media_items_request*>(
|
||||
data);
|
||||
|
||||
BString **items = NULL;
|
||||
|
||||
rv = gMMediaFilesManager->RewindRefs(request->type,
|
||||
&items, &reply.count);
|
||||
// we create an area here, and pass it to the library,
|
||||
// where it will be deleted.
|
||||
if (reply.count > 0) {
|
||||
char *start_addr;
|
||||
size_t size = ((reply.count * B_MEDIA_NAME_LENGTH)
|
||||
+ B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||
reply.area = create_area("rewind refs",
|
||||
reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS,
|
||||
size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (reply.area < B_OK) {
|
||||
ERROR("SERVER_REWINDREFS: failed to create area, "
|
||||
"error %s\n", strerror(reply.area));
|
||||
server_get_media_items_reply reply;
|
||||
area_id area = gMediaFilesManager->GetItemsArea(request.type,
|
||||
reply.count);
|
||||
if (area >= 0) {
|
||||
// transfer the area to the target team
|
||||
reply.area = _kern_transfer_area(reply.area,
|
||||
&reply.address, B_ANY_ADDRESS, request.team);
|
||||
if (reply.area < 0) {
|
||||
delete_area(area);
|
||||
reply.area = B_ERROR;
|
||||
reply.count = 0;
|
||||
rv = B_ERROR;
|
||||
} else {
|
||||
for (int32 index = 0; index < reply.count; index++) {
|
||||
strncpy(start_addr + B_MEDIA_NAME_LENGTH * index,
|
||||
items[index]->String(), B_MEDIA_NAME_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
reply.area = area;
|
||||
|
||||
delete[] items;
|
||||
|
||||
rv = request->SendReply(rv, &reply, sizeof(reply));
|
||||
if (rv != B_OK) {
|
||||
status_t status = request.SendReply(
|
||||
reply.area < 0 ? reply.area : B_OK, &reply, sizeof(reply));
|
||||
if (status != B_OK) {
|
||||
// if we couldn't send the message, delete the area
|
||||
delete_area(reply.area);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GETREFFOR:
|
||||
case SERVER_GET_REF_FOR:
|
||||
{
|
||||
const server_getreffor_request *request
|
||||
= reinterpret_cast<const server_getreffor_request *>(data);
|
||||
server_getreffor_reply reply;
|
||||
entry_ref *ref;
|
||||
const server_get_ref_for_request* request
|
||||
= reinterpret_cast<const server_get_ref_for_request*>(data);
|
||||
server_get_ref_for_reply reply;
|
||||
entry_ref* ref;
|
||||
|
||||
rv = gMMediaFilesManager->GetRefFor(request->type, request->item,
|
||||
&ref);
|
||||
if (rv == B_OK)
|
||||
status_t status = gMediaFilesManager->GetRefFor(request->type,
|
||||
request->item, &ref);
|
||||
if (status == B_OK)
|
||||
reply.ref = *ref;
|
||||
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
request->SendReply(status, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_SETREFFOR:
|
||||
case SERVER_SET_REF_FOR:
|
||||
{
|
||||
const server_setreffor_request *request
|
||||
= reinterpret_cast<const server_setreffor_request *>(data);
|
||||
server_setreffor_reply reply;
|
||||
const server_set_ref_for_request* request
|
||||
= reinterpret_cast<const server_set_ref_for_request*>(data);
|
||||
server_set_ref_for_reply reply;
|
||||
entry_ref ref = request->ref;
|
||||
|
||||
rv = gMMediaFilesManager->SetRefFor(request->type, request->item,
|
||||
ref);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REMOVEREFFOR:
|
||||
{
|
||||
const server_removereffor_request *request
|
||||
= reinterpret_cast<const server_removereffor_request *>(data);
|
||||
server_removereffor_reply reply;
|
||||
entry_ref ref = request->ref;
|
||||
|
||||
rv = gMMediaFilesManager->RemoveRefFor(request->type,
|
||||
status_t status = gMediaFilesManager->SetRefFor(request->type,
|
||||
request->item, ref);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
request->SendReply(status, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REMOVEITEM:
|
||||
case SERVER_REMOVE_REF_FOR:
|
||||
{
|
||||
const server_removeitem_request *request
|
||||
= reinterpret_cast<const server_removeitem_request *>(data);
|
||||
server_removeitem_reply reply;
|
||||
const server_remove_ref_for_request* request
|
||||
= reinterpret_cast<const server_remove_ref_for_request*>(data);
|
||||
server_remove_ref_for_reply reply;
|
||||
|
||||
rv = gMMediaFilesManager->RemoveItem(request->type, request->item);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
status_t status = gMediaFilesManager->InvalidateRefFor(
|
||||
request->type, request->item);
|
||||
request->SendReply(status, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REMOVE_MEDIA_ITEM:
|
||||
{
|
||||
const server_remove_media_item_request* request
|
||||
= reinterpret_cast<const server_remove_media_item_request*>(
|
||||
data);
|
||||
server_remove_media_item_reply reply;
|
||||
|
||||
status_t status = gMediaFilesManager->RemoveItem(request->type,
|
||||
request->item);
|
||||
request->SendReply(status, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -951,26 +906,25 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ServerApp::controlthread(void *arg)
|
||||
status_t
|
||||
ServerApp::_ControlThread(void* _server)
|
||||
{
|
||||
ServerApp* server = (ServerApp*)_server;
|
||||
|
||||
char data[B_MEDIA_MESSAGE_SIZE];
|
||||
ServerApp *app;
|
||||
ssize_t size;
|
||||
int32 code;
|
||||
|
||||
app = (ServerApp *)arg;
|
||||
while ((size = read_port_etc(app->control_port, &code, data, sizeof(data),
|
||||
0, 0)) > 0) {
|
||||
app->HandleMessage(code, data, size);
|
||||
while ((size = read_port_etc(server->_ControlPort(), &code, data,
|
||||
sizeof(data), 0, 0)) > 0) {
|
||||
server->_HandleMessage(code, data, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ServerApp::MessageReceived(BMessage *msg)
|
||||
ServerApp::MessageReceived(BMessage* msg)
|
||||
{
|
||||
TRACE("ServerApp::MessageReceived %lx enter\n", msg->what);
|
||||
switch (msg->what) {
|
||||
@@ -980,8 +934,8 @@ ServerApp::MessageReceived(BMessage *msg)
|
||||
gNotificationManager->EnqueueMessage(msg);
|
||||
break;
|
||||
|
||||
case MMEDIAFILESMANAGER_SAVE_TIMER:
|
||||
gMMediaFilesManager->TimerMessage();
|
||||
case MEDIA_FILES_MANAGER_SAVE_TIMER:
|
||||
gMediaFilesManager->TimerMessage();
|
||||
break;
|
||||
|
||||
case MEDIA_SERVER_GET_FORMATS:
|
||||
@@ -993,10 +947,10 @@ ServerApp::MessageReceived(BMessage *msg)
|
||||
break;
|
||||
|
||||
case MEDIA_SERVER_ADD_SYSTEM_BEEP_EVENT:
|
||||
gMMediaFilesManager->HandleAddSystemBeepEvent(msg);
|
||||
gMediaFilesManager->HandleAddSystemBeepEvent(msg);
|
||||
break;
|
||||
default:
|
||||
inherited::MessageReceived(msg);
|
||||
BApplication::MessageReceived(msg);
|
||||
printf("\nmedia_server: unknown message received:\n");
|
||||
msg->PrintToStream();
|
||||
break;
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
/*
|
||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef MEDIA_SERVER_H
|
||||
#define MEDIA_SERVER_H
|
||||
|
||||
|
||||
class AppManager;
|
||||
class NodeManager;
|
||||
class BufferManager;
|
||||
class NotificationManager;
|
||||
class MMediaFilesManager;
|
||||
class MediaFilesManager;
|
||||
class AddOnManager;
|
||||
class FormatManager;
|
||||
|
||||
extern AppManager * gAppManager;
|
||||
extern NodeManager * gNodeManager;
|
||||
extern BufferManager * gBufferManager;
|
||||
extern NotificationManager * gNotificationManager;
|
||||
extern MMediaFilesManager * gMMediaFilesManager;
|
||||
extern AddOnManager *gAddOnManager;
|
||||
extern FormatManager *gFormatManager;
|
||||
extern AppManager* gAppManager;
|
||||
extern NodeManager* gNodeManager;
|
||||
extern BufferManager* gBufferManager;
|
||||
extern NotificationManager* gNotificationManager;
|
||||
extern MediaFilesManager* gMediaFilesManager;
|
||||
extern AddOnManager* gAddOnManager;
|
||||
extern FormatManager* gFormatManager;
|
||||
|
||||
#endif // MEDIA_SERVER_H
|
||||
|
||||
Reference in New Issue
Block a user