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