1/* 2 * Copyright 2008, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar R. Adema 7 */ 8 9#include "Transport.h" 10 11// BeOS API 12#include <PrintTransportAddOn.h> 13#include <Application.h> 14#include <image.h> 15#include <Entry.h> 16 17 18BObjectList<Transport> Transport::sTransports; 19 20 21// --------------------------------------------------------------- 22// Find [static] 23// 24// Searches the static object list for a transport object with the 25// specified name. 26// 27// Parameters: 28// name - Printer definition name we're looking for. 29// 30// Returns: 31// Pointer to Transport object, or NULL if not found. 32// --------------------------------------------------------------- 33Transport* 34Transport::Find(const BString& name) 35{ 36 // Look in list to find printer definition 37 for (int32 index = 0; index < sTransports.CountItems(); index++) { 38 if (name == sTransports.ItemAt(index)->Name()) 39 return sTransports.ItemAt(index); 40 } 41 42 // None found, so return NULL 43 return NULL; 44} 45 46 47Transport* 48Transport::At(int32 index) 49{ 50 return sTransports.ItemAt(index); 51} 52 53 54void 55Transport::Remove(Transport* transport) 56{ 57 sTransports.RemoveItem(transport); 58} 59 60 61int32 62Transport::CountTransports() 63{ 64 return sTransports.CountItems(); 65} 66 67 68status_t 69Transport::Scan(directory_which which) 70{ 71 status_t result; 72 BPath path; 73 74 // Try to find specified transport addon directory 75 if ((result = find_directory(which, &path)) != B_OK) 76 return result; 77 78 if ((result = path.Append("Print/transport")) != B_OK) 79 return result; 80 81 BDirectory dir; 82 if ((result = dir.SetTo(path.Path())) != B_OK) 83 return result; 84 85 // Walk over all entries in directory 86 BEntry entry; 87 while(dir.GetNextEntry(&entry) == B_OK) { 88 if (!entry.IsFile()) 89 continue; 90 91 if (entry.GetPath(&path) != B_OK) 92 continue; 93 94 // If we have loaded the transport from a previous scanned directory, 95 // ignore this one. 96 if (Transport::Find(path.Leaf()) != NULL) 97 continue; 98 99 be_app->AddHandler(new Transport(path)); 100 } 101 102 return B_OK; 103} 104 105 106// --------------------------------------------------------------- 107// Transport [constructor] 108// 109// Initializes the transport object with data read from the 110// attributes attached to the printer definition node. 111// 112// Parameters: 113// node - Printer definition node for this printer. 114// 115// Returns: 116// none. 117// --------------------------------------------------------------- 118Transport::Transport(const BPath& path) 119 : BHandler(B_EMPTY_STRING), 120 fPath(path), 121 fImageID(-1), 122 fFeatures(0) 123{ 124 // Load transport addon 125 image_id id = ::load_add_on(path.Path()); 126 if (id < B_OK) 127 return; 128 129 // Find transport_features symbol, to determine if we need to keep 130 // this transport loaded 131 int* transportFeaturesPointer; 132 if (get_image_symbol(id, B_TRANSPORT_FEATURES_SYMBOL, 133 B_SYMBOL_TYPE_DATA, (void**)&transportFeaturesPointer) != B_OK) { 134 unload_add_on(id); 135 } else { 136 fFeatures = *transportFeaturesPointer; 137 138 if (fFeatures & B_TRANSPORT_IS_HOTPLUG) { 139 // We are hotpluggable; so keep us loaded! 140 fImageID = id; 141 } else { 142 // No extended Transport support; so no need to keep loaded 143 ::unload_add_on(id); 144 } 145 } 146 147 sTransports.AddItem(this); 148} 149 150 151Transport::~Transport() 152{ 153 sTransports.RemoveItem(this); 154} 155 156 157status_t 158Transport::ListAvailablePorts(BMessage* msg) 159{ 160 status_t (*list_ports)(BMessage*); 161 image_id id = fImageID; 162 status_t rc = B_OK; 163 164 // Load image if not loaded yet 165 if (id == -1 && (id = load_add_on(fPath.Path())) < 0) 166 return id; 167 168 // Get pointer to addon function 169 if ((rc = get_image_symbol(id, B_TRANSPORT_LIST_PORTS_SYMBOL, 170 B_SYMBOL_TYPE_TEXT, (void**)&list_ports)) != B_OK) 171 goto done; 172 173 // run addon... 174 rc = (*list_ports)(msg); 175 176done: 177 // clean up if needed 178 if (fImageID != id) 179 unload_add_on(id); 180 181 return rc; 182} 183 184 185// --------------------------------------------------------------- 186// MessageReceived 187// 188// Handle scripting messages. 189// 190// Parameters: 191// msg - message. 192// --------------------------------------------------------------- 193void 194Transport::MessageReceived(BMessage* msg) 195{ 196 switch(msg->what) { 197 case B_GET_PROPERTY: 198 case B_SET_PROPERTY: 199 case B_CREATE_PROPERTY: 200 case B_DELETE_PROPERTY: 201 case B_COUNT_PROPERTIES: 202 case B_EXECUTE_PROPERTY: 203 HandleScriptingCommand(msg); 204 break; 205 206 default: 207 Inherited::MessageReceived(msg); 208 } 209} 210