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 18 BObjectList<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 // --------------------------------------------------------------- 33 Transport* 34 Transport::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 47 Transport* 48 Transport::At(int32 index) 49 { 50 return sTransports.ItemAt(index); 51 } 52 53 54 void 55 Transport::Remove(Transport* transport) 56 { 57 sTransports.RemoveItem(transport); 58 } 59 60 61 int32 62 Transport::CountTransports() 63 { 64 return sTransports.CountItems(); 65 } 66 67 68 status_t 69 Transport::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 // --------------------------------------------------------------- 118 Transport::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 151 Transport::~Transport() 152 { 153 sTransports.RemoveItem(this); 154 } 155 156 157 status_t 158 Transport::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 176 done: 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 // --------------------------------------------------------------- 193 void 194 Transport::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