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