xref: /haiku/src/servers/print/Transport.cpp (revision dcd112f767b89f0cb5a1e93e0515361c1742c635)
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