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