* Copyright 2008, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ithamar R. Adema
*/
#include "Transport.h"
#include <PrintTransportAddOn.h>
#include <Application.h>
#include <image.h>
#include <Entry.h>
BObjectList<Transport> Transport::sTransports;
Transport*
Transport::Find(const BString& name)
{
for (int32 index = 0; index < sTransports.CountItems(); index++) {
if (name == sTransports.ItemAt(index)->Name())
return sTransports.ItemAt(index);
}
return NULL;
}
Transport*
Transport::At(int32 index)
{
return sTransports.ItemAt(index);
}
void
Transport::Remove(Transport* transport)
{
sTransports.RemoveItem(transport);
}
int32
Transport::CountTransports()
{
return sTransports.CountItems();
}
status_t
Transport::Scan(directory_which which)
{
status_t result;
BPath path;
if ((result = find_directory(which, &path)) != B_OK)
return result;
if ((result = path.Append("Print/transport")) != B_OK)
return result;
BDirectory dir;
if ((result = dir.SetTo(path.Path())) != B_OK)
return result;
BEntry entry;
while(dir.GetNextEntry(&entry) == B_OK) {
if (!entry.IsFile())
continue;
if (entry.GetPath(&path) != B_OK)
continue;
if (Transport::Find(path.Leaf()) != NULL)
continue;
be_app->AddHandler(new Transport(path));
}
return B_OK;
}
Transport::Transport(const BPath& path)
: BHandler(B_EMPTY_STRING),
fPath(path),
fImageID(-1),
fFeatures(0)
{
image_id id = ::load_add_on(path.Path());
if (id < B_OK)
return;
int* transportFeaturesPointer;
if (get_image_symbol(id, B_TRANSPORT_FEATURES_SYMBOL,
B_SYMBOL_TYPE_DATA, (void**)&transportFeaturesPointer) != B_OK) {
unload_add_on(id);
} else {
fFeatures = *transportFeaturesPointer;
if (fFeatures & B_TRANSPORT_IS_HOTPLUG) {
fImageID = id;
} else {
::unload_add_on(id);
}
}
sTransports.AddItem(this);
}
Transport::~Transport()
{
sTransports.RemoveItem(this);
}
status_t
Transport::ListAvailablePorts(BMessage* msg)
{
status_t (*list_ports)(BMessage*);
image_id id = fImageID;
status_t rc = B_OK;
if (id == -1 && (id = load_add_on(fPath.Path())) < 0)
return id;
if ((rc = get_image_symbol(id, B_TRANSPORT_LIST_PORTS_SYMBOL,
B_SYMBOL_TYPE_TEXT, (void**)&list_ports)) != B_OK)
goto done;
rc = (*list_ports)(msg);
done:
if (fImageID != id)
unload_add_on(id);
return rc;
}
void
Transport::MessageReceived(BMessage* msg)
{
switch(msg->what) {
case B_GET_PROPERTY:
case B_SET_PROPERTY:
case B_CREATE_PROPERTY:
case B_DELETE_PROPERTY:
case B_COUNT_PROPERTIES:
case B_EXECUTE_PROPERTY:
HandleScriptingCommand(msg);
break;
default:
Inherited::MessageReceived(msg);
}
}