xref: /haiku/src/servers/print/PrintServerApp.Scripting.cpp (revision 4b3b81da9e459443d75329cfd08bc9a57ad02653)
1 /*
2  * Copyright 2001-2006, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ithamar R. Adema
7  */
8 #include "PrintServerApp.h"
9 
10 #include "Transport.h"
11 #include "Printer.h"
12 
13 	// BeOS API
14 #include <PropertyInfo.h>
15 
16 	// ANSI C
17 #include <stdio.h>
18 
19 static property_info prop_list[] = {
20 	{ "ActivePrinter", { B_GET_PROPERTY, B_SET_PROPERTY }, { B_DIRECT_SPECIFIER },
21 		"Retrieve or select the active printer" },
22 	{ "Printer", { B_GET_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER, B_REVERSE_INDEX_SPECIFIER },
23 		"Retrieve a specific printer" },
24 	{ "Printer", { B_CREATE_PROPERTY }, { B_DIRECT_SPECIFIER },
25 		"Create a new printer" },
26 	{ "Printer", { B_DELETE_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER, B_REVERSE_INDEX_SPECIFIER },
27 		"Delete a specific printer" },
28 	{ "Printers", { B_COUNT_PROPERTIES }, { B_DIRECT_SPECIFIER },
29 		"Return the number of available printers" },
30 	{ "Transport", { B_GET_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER, B_REVERSE_INDEX_SPECIFIER },
31 		"Retrieve a specific transport" },
32 	{ "Transports", { B_COUNT_PROPERTIES }, { B_DIRECT_SPECIFIER },
33 		"Return the number of available transports" },
34 	{ "UseConfigWindow", { B_GET_PROPERTY, B_SET_PROPERTY }, { B_DIRECT_SPECIFIER },
35 		"Show configuration window" },
36 	{ 0 } // terminate list
37 };
38 
39 void
40 PrintServerApp::HandleScriptingCommand(BMessage* msg)
41 {
42 	BString propName;
43 	BMessage spec;
44 	int32 idx;
45 
46 	if (msg->GetCurrentSpecifier(&idx,&spec) == B_OK &&
47 		spec.FindString("property",&propName) == B_OK) {
48 		switch(msg->what) {
49 			case B_GET_PROPERTY:
50 				if (propName == "ActivePrinter") {
51 					BMessage reply(B_REPLY);
52 					reply.AddString("result", fDefaultPrinter ? fDefaultPrinter->Name() : "");
53 					reply.AddInt32("error", B_OK);
54 					msg->SendReply(&reply);
55 				} else if (propName == "UseConfigWindow") {
56 					BMessage reply(B_REPLY);
57 					reply.AddString("result", fUseConfigWindow ? "true" : "false");
58 					reply.AddInt32("error", B_OK);
59 					msg->SendReply(&reply);
60 				}
61 				break;
62 
63 			case B_SET_PROPERTY:
64 				if (propName == "ActivePrinter") {
65 					BString newActivePrinter;
66 					if (msg->FindString("data", &newActivePrinter) == B_OK) {
67 						BMessage reply(B_REPLY);
68 						reply.AddInt32("error", SelectPrinter(newActivePrinter.String()));
69 						msg->SendReply(&reply);
70 					}
71 				} else if (propName == "UseConfigWindow") {
72 					bool useConfigWindow;
73 					if (msg->FindBool("data", &useConfigWindow) == B_OK) {
74 						fUseConfigWindow = useConfigWindow;
75 						BMessage reply(B_REPLY);
76 						reply.AddInt32("error", fUseConfigWindow);
77 						msg->SendReply(&reply);
78 					}
79 				}
80 				break;
81 
82 			case B_CREATE_PROPERTY:
83 				if (propName == "Printer") {
84 					BString name, driver, transport, config;
85 
86 					if (msg->FindString("name", &name) == B_OK &&
87 						msg->FindString("driver", &driver) == B_OK &&
88 						msg->FindString("transport", &transport) == B_OK &&
89 						msg->FindString("config", &config) == B_OK) {
90 						BMessage reply(B_REPLY);
91 						reply.AddInt32("error", CreatePrinter(name.String(), driver.String(),
92 													"Local", transport.String(), config.String()));
93 						msg->SendReply(&reply);
94 					}
95 				}
96 				break;
97 
98 			case B_DELETE_PROPERTY: {
99 					Printer* printer = GetPrinterFromSpecifier(&spec);
100 					status_t rc = B_BAD_VALUE;
101 
102 					if (printer != NULL) {
103 						rc=printer->Remove();
104 					}
105 
106 					BMessage reply(B_REPLY);
107 					reply.AddInt32("error", rc);
108 					msg->SendReply(&reply);
109 				}
110 				break;
111 
112 			case B_COUNT_PROPERTIES:
113 				if (propName == "Printers") {
114 					BMessage reply(B_REPLY);
115 					reply.AddInt32("result", Printer::CountPrinters());
116 					reply.AddInt32("error", B_OK);
117 					msg->SendReply(&reply);
118 				} else if (propName == "Transports") {
119 					BMessage reply(B_REPLY);
120 					reply.AddInt32("result", Transport::CountTransports());
121 					reply.AddInt32("error", B_OK);
122 					msg->SendReply(&reply);
123 				}
124 				break;
125 		}
126 	}
127 }
128 
129 Printer* PrintServerApp::GetPrinterFromSpecifier(BMessage* msg)
130 {
131 	switch(msg->what) {
132 		case B_NAME_SPECIFIER: {
133 			BString name;
134 			if (msg->FindString("name", &name) == B_OK) {
135 				return Printer::Find(name.String());
136 			}
137 			break;
138 		}
139 
140 		case B_INDEX_SPECIFIER: {
141 			int32 idx;
142 			if (msg->FindInt32("index", &idx) == B_OK) {
143 				return Printer::At(idx);
144 			}
145 			break;
146 		}
147 
148 		case B_REVERSE_INDEX_SPECIFIER: {
149 			int32 idx;
150 			if (msg->FindInt32("index", &idx) == B_OK) {
151 				return Printer::At(Printer::CountPrinters() - idx);
152 			}
153 			break;
154 		}
155 	}
156 
157 	return NULL;
158 }
159 
160 Transport* PrintServerApp::GetTransportFromSpecifier(BMessage* msg)
161 {
162 	switch(msg->what) {
163 		case B_NAME_SPECIFIER: {
164 			BString name;
165 			if (msg->FindString("name", &name) == B_OK) {
166 				return Transport::Find(name);
167 			}
168 			break;
169 		}
170 
171 		case B_INDEX_SPECIFIER: {
172 			int32 idx;
173 			if (msg->FindInt32("index", &idx) == B_OK) {
174 				return Transport::At(idx);
175 			}
176 			break;
177 		}
178 
179 		case B_REVERSE_INDEX_SPECIFIER: {
180 			int32 idx;
181 			if (msg->FindInt32("index", &idx) == B_OK) {
182 				return Transport::At(Transport::CountTransports() - idx);
183 			}
184 			break;
185 		}
186 	}
187 
188 	return NULL;
189 }
190 
191 BHandler*
192 PrintServerApp::ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec,
193 								int32 form, const char* prop)
194 {
195 	BPropertyInfo prop_info(prop_list);
196 	BHandler* rc = NULL;
197 
198 	int32 idx;
199 	switch( idx=prop_info.FindMatch(msg,0,spec,form,prop) ) {
200 		case B_ERROR:
201 			rc = Inherited::ResolveSpecifier(msg,index,spec,form,prop);
202 
203 			// GET Printer [arg]
204 		case 1:
205 			if ((rc=GetPrinterFromSpecifier(spec)) == NULL) {
206 				BMessage reply(B_REPLY);
207 				reply.AddInt32("error", B_BAD_INDEX);
208 				msg->SendReply(&reply);
209 			}
210 			else
211 				msg->PopSpecifier();
212 			break;
213 
214 			// GET Transport [arg]
215 		case 5:
216 			if ((rc=GetTransportFromSpecifier(spec)) == NULL) {
217 				BMessage reply(B_REPLY);
218 				reply.AddInt32("error", B_BAD_INDEX);
219 				msg->SendReply(&reply);
220 			}
221 			else
222 				msg->PopSpecifier();
223 			break;
224 
225 		default:
226 			rc = this;
227 	}
228 
229 	return rc;
230 }
231 
232 status_t
233 PrintServerApp::GetSupportedSuites(BMessage* msg)
234 {
235 	msg->AddString("suites", "suite/vnd.OpenBeOS-printserver");
236 
237 	BPropertyInfo prop_info(prop_list);
238 	msg->AddFlat("messages", &prop_info);
239 
240 	return Inherited::GetSupportedSuites(msg);
241 }
242