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 "Printer.h" 11 12 // BeOS API 13 #include <PropertyInfo.h> 14 15 // ANSI C 16 #include <stdio.h> 17 18 static property_info prop_list[] = { 19 { "ActivePrinter", { B_GET_PROPERTY, B_SET_PROPERTY }, { B_DIRECT_SPECIFIER }, 20 "Retrieve or select the active printer" }, 21 { "Printer", { B_GET_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER, B_REVERSE_INDEX_SPECIFIER }, 22 "Retrieve a specific printer" }, 23 { "Printer", { B_CREATE_PROPERTY }, { B_DIRECT_SPECIFIER }, 24 "Create a new printer" }, 25 { "Printer", { B_DELETE_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER, B_REVERSE_INDEX_SPECIFIER }, 26 "Delete a specific printer" }, 27 { "Printers", { B_COUNT_PROPERTIES }, { B_DIRECT_SPECIFIER }, 28 "Return the number of available printers" }, 29 { "UseConfigWindow", { B_GET_PROPERTY, B_SET_PROPERTY }, { B_DIRECT_SPECIFIER }, 30 "Show configuration window" }, 31 { 0 } // terminate list 32 }; 33 34 void 35 PrintServerApp::HandleScriptingCommand(BMessage* msg) 36 { 37 BString propName; 38 BMessage spec; 39 int32 idx; 40 41 if (msg->GetCurrentSpecifier(&idx,&spec) == B_OK && 42 spec.FindString("property",&propName) == B_OK) { 43 switch(msg->what) { 44 case B_GET_PROPERTY: 45 if (propName == "ActivePrinter") { 46 BMessage reply(B_REPLY); 47 reply.AddString("result", fDefaultPrinter ? fDefaultPrinter->Name() : ""); 48 reply.AddInt32("error", B_OK); 49 msg->SendReply(&reply); 50 } else if (propName == "UseConfigWindow") { 51 BMessage reply(B_REPLY); 52 reply.AddString("result", fUseConfigWindow ? "true" : "false"); 53 reply.AddInt32("error", B_OK); 54 msg->SendReply(&reply); 55 } 56 break; 57 58 case B_SET_PROPERTY: 59 if (propName == "ActivePrinter") { 60 BString newActivePrinter; 61 if (msg->FindString("data", &newActivePrinter) == B_OK) { 62 BMessage reply(B_REPLY); 63 reply.AddInt32("error", SelectPrinter(newActivePrinter.String())); 64 msg->SendReply(&reply); 65 } 66 } else if (propName == "UseConfigWindow") { 67 bool useConfigWindow; 68 if (msg->FindBool("data", &useConfigWindow) == B_OK) { 69 fUseConfigWindow = useConfigWindow; 70 BMessage reply(B_REPLY); 71 reply.AddInt32("error", fUseConfigWindow); 72 msg->SendReply(&reply); 73 } 74 } 75 break; 76 77 case B_CREATE_PROPERTY: 78 if (propName == "Printer") { 79 BString name, driver, transport, config; 80 81 if (msg->FindString("name", &name) == B_OK && 82 msg->FindString("driver", &driver) == B_OK && 83 msg->FindString("transport", &transport) == B_OK && 84 msg->FindString("config", &config) == B_OK) { 85 BMessage reply(B_REPLY); 86 reply.AddInt32("error", CreatePrinter(name.String(), driver.String(), 87 "Local", transport.String(), config.String())); 88 msg->SendReply(&reply); 89 } 90 } 91 break; 92 93 case B_DELETE_PROPERTY: { 94 Printer* printer = GetPrinterFromSpecifier(&spec); 95 status_t rc = B_BAD_VALUE; 96 97 if (printer != NULL) { 98 rc=printer->Remove(); 99 } 100 101 BMessage reply(B_REPLY); 102 reply.AddInt32("error", rc); 103 msg->SendReply(&reply); 104 } 105 break; 106 107 case B_COUNT_PROPERTIES: 108 if (propName == "Printers") { 109 BMessage reply(B_REPLY); 110 reply.AddInt32("result", Printer::CountPrinters()); 111 reply.AddInt32("error", B_OK); 112 msg->SendReply(&reply); 113 } 114 break; 115 } 116 } 117 } 118 119 Printer* PrintServerApp::GetPrinterFromSpecifier(BMessage* msg) 120 { 121 switch(msg->what) { 122 case B_NAME_SPECIFIER: { 123 BString name; 124 if (msg->FindString("name", &name) == B_OK) { 125 return Printer::Find(name.String()); 126 } 127 break; 128 } 129 130 case B_INDEX_SPECIFIER: { 131 int32 idx; 132 if (msg->FindInt32("index", &idx) == B_OK) { 133 return Printer::At(idx); 134 } 135 break; 136 } 137 138 case B_REVERSE_INDEX_SPECIFIER: { 139 int32 idx; 140 if (msg->FindInt32("index", &idx) == B_OK) { 141 return Printer::At(Printer::CountPrinters() - idx); 142 } 143 break; 144 } 145 } 146 147 return NULL; 148 } 149 150 BHandler* 151 PrintServerApp::ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec, 152 int32 form, const char* prop) 153 { 154 BPropertyInfo prop_info(prop_list); 155 BHandler* rc = NULL; 156 157 int32 idx; 158 switch( idx=prop_info.FindMatch(msg,0,spec,form,prop) ) { 159 case B_ERROR: 160 rc = Inherited::ResolveSpecifier(msg,index,spec,form,prop); 161 162 // GET Printer [arg] 163 case 1: 164 if ((rc=GetPrinterFromSpecifier(spec)) == NULL) { 165 BMessage reply(B_REPLY); 166 reply.AddInt32("error", B_BAD_INDEX); 167 msg->SendReply(&reply); 168 } 169 else 170 msg->PopSpecifier(); 171 break; 172 173 default: 174 rc = this; 175 } 176 177 return rc; 178 } 179 180 status_t 181 PrintServerApp::GetSupportedSuites(BMessage* msg) 182 { 183 msg->AddString("suites", "suite/vnd.OpenBeOS-printserver"); 184 185 BPropertyInfo prop_info(prop_list); 186 msg->AddFlat("messages", &prop_info); 187 188 return Inherited::GetSupportedSuites(msg); 189 } 190