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