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