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