AddOnManager improved, initializations, message handling improved

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8610 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2004-08-19 22:09:27 +00:00
parent 5359f0d4cc
commit 173f7185f4
6 changed files with 347 additions and 264 deletions
+130 -102
View File
@@ -2,7 +2,8 @@
** Copyright 2004, the OpenBeOS project. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
**
** Authors: Marcus Overhagen, Axel Dörfler
** Author : Jérôme Duval
** Original authors: Marcus Overhagen, Axel Dörfler
*/
@@ -18,36 +19,16 @@
#include <string.h>
#include "AddOnManager.h"
// #pragma mark ImageLoader
/** The ImageLoader class is a convenience class to temporarily load
* an image file, and unload it on deconstruction automatically.
*/
class ImageLoader {
public:
ImageLoader(BPath &path)
{
fImage = load_add_on(path.Path());
}
~ImageLoader()
{
if (fImage >= B_OK)
unload_add_on(fImage);
}
status_t InitCheck() const { return fImage; }
image_id Image() const { return fImage; }
private:
image_id fImage;
};
#include "InputServer.h"
// #pragma mark -
#if DEBUG>=1
#define EXIT() printf("EXIT %s\n", __PRETTY_FUNCTION__)
#define CALLED() printf("CALLED %s\n", __PRETTY_FUNCTION__)
#else
#define EXIT() ((void)0)
#define CALLED() ((void)0)
#endif
AddOnManager::AddOnManager()
:
@@ -74,59 +55,6 @@ AddOnManager::SaveState()
}
/*status_t
AddOnManager::GetDecoderForFormat(xfer_entry_ref *_decoderRef,
const media_format &format)
{
if ((format.type == B_MEDIA_ENCODED_VIDEO
|| format.type == B_MEDIA_ENCODED_AUDIO
|| format.type == B_MEDIA_MULTISTREAM)
&& format.Encoding() == 0)
return B_MEDIA_BAD_FORMAT;
if (format.type == B_MEDIA_NO_TYPE
|| format.type == B_MEDIA_UNKNOWN_TYPE)
return B_MEDIA_BAD_FORMAT;
BAutolock locker(fLock);
printf("AddOnManager::GetDecoderForFormat: searching decoder for encoding %ld\n", format.Encoding());
decoder_info *info;
for (fDecoderList.Rewind(); fDecoderList.GetNext(&info);) {
media_format *decoderFormat;
for (info->formats.Rewind(); info->formats.GetNext(&decoderFormat);) {
// check if the decoder matches the supplied format
if (!decoderFormat->Matches(&format))
continue;
printf("AddOnManager::GetDecoderForFormat: found decoder %s for encoding %ld\n",
info->ref.name, decoderFormat->Encoding());
*_decoderRef = info->ref;
return B_OK;
}
}
return B_ENTRY_NOT_FOUND;
}
status_t
AddOnManager::GetReaders(xfer_entry_ref *out_res, int32 *out_count, int32 max_count)
{
BAutolock locker(fLock);
*out_count = 0;
fReaderList.Rewind();
reader_info *info;
for (*out_count = 0; fReaderList.GetNext(&info) && *out_count <= max_count; *out_count += 1)
out_res[*out_count] = info->ref;
return B_OK;
}*/
status_t
AddOnManager::RegisterAddOn(BEntry &entry)
{
@@ -139,9 +67,10 @@ AddOnManager::RegisterAddOn(BEntry &entry)
printf("AddOnManager::RegisterAddOn(): trying to load \"%s\"\n", path.Path());
ImageLoader loader(path);
if ((status = loader.InitCheck()) < B_OK)
return status;
image_id addon_image = load_add_on(path.Path());
if (addon_image < B_OK)
return addon_image;
BEntry parent;
entry.GetParent(&parent);
@@ -151,66 +80,150 @@ AddOnManager::RegisterAddOn(BEntry &entry)
if (pathString.FindFirst("input_server/devices")>0) {
BInputServerDevice *(*instantiate_func)();
if (get_image_symbol(loader.Image(), "instantiate_input_device",
if (get_image_symbol(addon_image, "instantiate_input_device",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
printf("AddOnManager::RegisterAddOn(): can't find instantiate_input_device in \"%s\"\n",
path.Path());
return B_BAD_TYPE;
goto exit_error;
}
BInputServerDevice *isd = (*instantiate_func)();
if (isd == NULL) {
printf("AddOnManager::RegisterAddOn(): instantiate_input_device in \"%s\" returned NULL\n",
path.Path());
return B_ERROR;
goto exit_error;
}
status_t status = isd->InitCheck();
if (status != B_OK) {
printf("AddOnManager::RegisterAddOn(): BInputServerDevice.InitCheck in \"%s\" returned %s\n",
path.Path(), strerror(status));
delete isd;
goto exit_error;
}
RegisterDevice(isd, ref);
RegisterDevice(isd, ref, addon_image);
} else if (pathString.FindFirst("input_server/filters")>0) {
BInputServerFilter *(*instantiate_func)();
if (get_image_symbol(loader.Image(), "instantiate_input_filter",
if (get_image_symbol(addon_image, "instantiate_input_filter",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
printf("AddOnManager::RegisterAddOn(): can't find instantiate_input_filter in \"%s\"\n",
path.Path());
return B_BAD_TYPE;
goto exit_error;
}
BInputServerFilter *isf = (*instantiate_func)();
if (isf == NULL) {
printf("AddOnManager::RegisterAddOn(): instantiate_input_filter in \"%s\" returned NULL\n",
path.Path());
return B_ERROR;
goto exit_error;
}
status_t status = isf->InitCheck();
if (status != B_OK) {
printf("AddOnManager::RegisterAddOn(): BInputServerFilter.InitCheck in \"%s\" returned %s\n",
path.Path(), strerror(status));
delete isf;
goto exit_error;
}
RegisterFilter(isf, ref);
RegisterFilter(isf, ref, addon_image);
} else if (pathString.FindFirst("input_server/methods")>0) {
BInputServerMethod *(*instantiate_func)();
if (get_image_symbol(loader.Image(), "instantiate_input_method",
if (get_image_symbol(addon_image, "instantiate_input_method",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
printf("AddOnManager::RegisterAddOn(): can't find instantiate_input_method in \"%s\"\n",
path.Path());
return B_BAD_TYPE;
goto exit_error;
}
BInputServerMethod *ism = (*instantiate_func)();
if (ism == NULL) {
printf("AddOnManager::RegisterAddOn(): instantiate_input_method in \"%s\" returned NULL\n",
path.Path());
return B_ERROR;
goto exit_error;
}
status_t status = ism->InitCheck();
if (status != B_OK) {
printf("AddOnManager::RegisterAddOn(): BInputServerMethod.InitCheck in \"%s\" returned %s\n",
path.Path(), strerror(status));
delete ism;
goto exit_error;
}
RegisterMethod(ism, ref);
RegisterMethod(ism, ref, addon_image);
}
return B_OK;
exit_error:
unload_add_on(addon_image);
return status;
}
status_t
AddOnManager::UnregisterAddOn(BEntry &entry)
{
BPath path(&entry);
entry_ref ref;
status_t status = entry.GetRef(&ref);
if (status < B_OK)
return status;
PRINT(("AddOnManager::UnregisterAddOn(): trying to unload \"%s\"\n", path.Path()));
BEntry parent;
entry.GetParent(&parent);
BPath parentPath(&parent);
BString pathString = parentPath.Path();
BAutolock locker(fLock);
if (pathString.FindFirst("input_server/devices")>0) {
device_info *pinfo;
for (fDeviceList.Rewind(); fDeviceList.GetNext(&pinfo);) {
if (!strcmp(pinfo->ref.name, ref.name)) {
delete pinfo->isd;
delete pinfo->addon;
if (pinfo->addon_image >= B_OK)
unload_add_on(pinfo->addon_image);
fDeviceList.RemoveCurrent();
break;
}
}
} else if (pathString.FindFirst("input_server/filters")>0) {
filter_info *pinfo;
for (fFilterList.Rewind(); fFilterList.GetNext(&pinfo);) {
if (!strcmp(pinfo->ref.name, ref.name)) {
delete pinfo->isf;
if (pinfo->addon_image >= B_OK)
unload_add_on(pinfo->addon_image);
fFilterList.RemoveCurrent();
break;
}
}
} else if (pathString.FindFirst("input_server/methods")>0) {
method_info *pinfo;
for (fMethodList.Rewind(); fMethodList.GetNext(&pinfo);) {
if (!strcmp(pinfo->ref.name, ref.name)) {
delete pinfo->ism;
delete pinfo->addon;
if (pinfo->addon_image >= B_OK)
unload_add_on(pinfo->addon_image);
fMethodList.RemoveCurrent();
break;
}
}
}
return B_OK;
}
void
AddOnManager::RegisterAddOns()
{
@@ -224,6 +237,7 @@ AddOnManager::RegisterAddOns()
virtual void AddOnCreated(const add_on_entry_info * entry_info) {
}
virtual void AddOnEnabled(const add_on_entry_info * entry_info) {
CALLED();
entry_ref ref;
make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node,
entry_info->name, &ref);
@@ -231,6 +245,12 @@ AddOnManager::RegisterAddOns()
fManager->RegisterAddOn(entry);
}
virtual void AddOnDisabled(const add_on_entry_info * entry_info) {
CALLED();
entry_ref ref;
make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node,
entry_info->name, &ref);
BEntry entry(&ref, false);
fManager->UnregisterAddOn(entry);
}
virtual void AddOnRemoved(const add_on_entry_info * entry_info) {
}
@@ -253,7 +273,7 @@ AddOnManager::RegisterAddOns()
BDirectory directory;
BPath path;
for (uint i = 0 ; i < sizeof(directories) / sizeof(directory_which) ; i++)
for (uint j = 0 ; j < 2 ; j++) {
for (uint j = 0 ; j < sizeof(subDirectories) / sizeof(char[24]) ; j++) {
if ((find_directory(directories[i], &path) == B_OK)
&& (path.Append(subDirectories[j]) == B_OK)
&& (directory.SetTo(path.Path()) == B_OK)
@@ -272,7 +292,7 @@ AddOnManager::RegisterAddOns()
void
AddOnManager::RegisterDevice(BInputServerDevice *isd, const entry_ref &ref)
AddOnManager::RegisterDevice(BInputServerDevice *device, const entry_ref &ref, image_id addon_image)
{
BAutolock locker(fLock);
@@ -288,13 +308,16 @@ AddOnManager::RegisterDevice(BInputServerDevice *isd, const entry_ref &ref)
device_info info;
info.ref = ref;
info.addon_image = addon_image;
info.isd = device;
info.addon = new _BDeviceAddOn_;
fDeviceList.Insert(info);
}
void
AddOnManager::RegisterFilter(BInputServerFilter *filter, const entry_ref &ref)
AddOnManager::RegisterFilter(BInputServerFilter *filter, const entry_ref &ref, image_id addon_image)
{
BAutolock locker(fLock);
@@ -310,13 +333,15 @@ AddOnManager::RegisterFilter(BInputServerFilter *filter, const entry_ref &ref)
filter_info info;
info.ref = ref;
info.addon_image = addon_image;
info.isf = filter;
fFilterList.Insert(info);
}
void
AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref)
AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref, image_id addon_image)
{
BAutolock locker(fLock);
@@ -332,6 +357,9 @@ AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref)
method_info info;
info.ref = ref;
info.addon_image = addon_image;
info.ism = method;
info.addon = new _BMethodAddOn_;
fMethodList.Insert(info);
}