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