1 /* 2 * Copyright 2001-2008, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar R. Adema 7 * Michael Pfeiffer 8 */ 9 #include "PrintServerApp.h" 10 11 #include "pr_server.h" 12 #include "Printer.h" 13 #include "ConfigWindow.h" 14 15 // BeOS API 16 #include <Alert.h> 17 #include <Autolock.h> 18 #include <Catalog.h> 19 #include <Locale.h> 20 #include <PrintJob.h> 21 22 23 #undef B_TRANSLATION_CONTEXT 24 #define B_TRANSLATION_CONTEXT "PrintServerApp" 25 26 27 struct AsyncThreadParams { 28 PrintServerApp* app; 29 Printer* printer; 30 BMessage* message; 31 32 AsyncThreadParams(PrintServerApp* app, Printer* p, BMessage* m) 33 : app(app) 34 , printer(p) 35 , message(m) 36 { 37 app->Acquire(); 38 if (printer) printer->Acquire(); 39 } 40 41 ~AsyncThreadParams() { 42 if (printer) printer->Release(); 43 delete message; 44 app->Release(); 45 } 46 47 BMessage* AcquireMessage() { 48 BMessage* m = message; message = NULL; return m; 49 } 50 }; 51 52 53 status_t 54 PrintServerApp::async_thread(void* data) 55 { 56 AsyncThreadParams* p = (AsyncThreadParams*)data; 57 58 Printer* printer = p->printer; 59 BMessage* msg = p->AcquireMessage(); 60 { 61 AutoReply sender(msg, 'stop'); 62 switch (msg->what) { 63 // Handle showing the config dialog 64 case PSRV_SHOW_PAGE_SETUP: { 65 case PSRV_SHOW_PRINT_SETUP: 66 if (printer) { 67 if (p->app->fUseConfigWindow) { 68 config_setup_kind kind = kJobSetup; 69 if (msg->what == PSRV_SHOW_PAGE_SETUP) 70 kind = kPageSetup; 71 ConfigWindow* w = new ConfigWindow(kind, printer, msg, 72 &sender); 73 w->Go(); 74 } else { 75 BMessage reply(*msg); 76 status_t status = B_ERROR; 77 if (msg->what == PSRV_SHOW_PAGE_SETUP) 78 status = printer->ConfigurePage(reply); 79 else 80 status = printer->ConfigureJob(reply); 81 82 if (status == B_OK) 83 sender.SetReply(&reply); 84 } 85 } else { 86 // If no default printer is set, give user 87 // choice of aborting or setting up a printer 88 int32 count = Printer::CountPrinters(); 89 BString alertText( 90 B_TRANSLATE("There are no printers set up.")); 91 if (count > 0) 92 alertText.SetTo(B_TRANSLATE( 93 "There is no default printer set up.")); 94 95 alertText.Append(" "); 96 alertText.Append( 97 B_TRANSLATE("Would you like to set one up now?")); 98 BAlert* alert = new BAlert("Info", alertText.String(), 99 B_TRANSLATE("No"), B_TRANSLATE("Yes")); 100 if (alert->Go() == 1) { 101 if (count == 0) 102 run_add_printer_panel(); 103 else 104 run_select_printer_panel(); 105 } 106 } 107 } break; 108 109 // Retrieve default configuration message from printer add-on 110 case PSRV_GET_DEFAULT_SETTINGS: { 111 if (printer) { 112 BMessage reply; 113 if (printer->GetDefaultSettings(reply) == B_OK) { 114 sender.SetReply(&reply); 115 break; 116 } 117 } 118 } break; 119 120 // Create a new printer 121 case PSRV_MAKE_PRINTER: { 122 BString driverName; 123 BString printerName; 124 BString transportName; 125 BString transportPath; 126 if (msg->FindString("driver", &driverName) == B_OK 127 && msg->FindString("transport", &transportName) == B_OK 128 && msg->FindString("transport path", &transportPath) == B_OK 129 && msg->FindString("printer name", &printerName) == B_OK) { 130 BString connection; 131 if (msg->FindString("connection", &connection) != B_OK) 132 connection = "Local"; 133 134 // then create the actual printer 135 if (p->app->CreatePrinter(printerName.String(), 136 driverName.String(), connection.String(), 137 transportName.String(), 138 transportPath.String()) == B_OK) { 139 // If printer was created ok, 140 // ask if it needs to be the default 141 BString text(B_TRANSLATE("Would you like to make @ " 142 "the default printer?")); 143 text.ReplaceFirst("@", printerName.String()); 144 BAlert* alert = new BAlert("", text.String(), 145 B_TRANSLATE("No"), B_TRANSLATE("Yes")); 146 if (alert->Go() == 1) 147 p->app->SelectPrinter(printerName.String()); 148 } 149 } 150 } break; 151 } 152 } 153 delete p; 154 return B_OK; 155 } 156 157 158 // Async. processing of received message 159 void 160 PrintServerApp::AsyncHandleMessage(BMessage* msg) 161 { 162 AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg); 163 164 thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY, 165 (void*)data); 166 167 if (tid > 0) { 168 resume_thread(tid); 169 } else { 170 delete data; 171 } 172 } 173 174 175 void 176 PrintServerApp::Handle_BeOSR5_Message(BMessage* msg) 177 { 178 switch(msg->what) { 179 // Get currently selected printer 180 case PSRV_GET_ACTIVE_PRINTER: { 181 BMessage reply('okok'); 182 BString printerName; 183 if (fDefaultPrinter) 184 printerName = fDefaultPrinter->Name(); 185 BString mime; 186 if (fUseConfigWindow && MimeTypeForSender(msg, mime)) { 187 BAutolock lock(gLock); 188 if (lock.IsLocked()) { 189 // override with printer for application 190 PrinterSettings* p = fSettings->FindPrinterSettings( 191 mime.String()); 192 if (p) 193 printerName = p->GetPrinter(); 194 } 195 } 196 reply.AddString("printer_name", printerName); 197 // BeOS knows not if color or not, so always color 198 reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER); 199 msg->SendReply(&reply); 200 } 201 break; 202 203 //make printer active (currently always quietly :)) 204 case PSRV_MAKE_PRINTER_ACTIVE_QUIETLY: 205 //make printer active quietly 206 case PSRV_MAKE_PRINTER_ACTIVE: { 207 BString newActivePrinter; 208 if (msg->FindString("printer",&newActivePrinter) == B_OK) { 209 SelectPrinter(newActivePrinter.String()); 210 } 211 } 212 break; 213 214 case PSRV_SHOW_PAGE_SETUP: 215 case PSRV_SHOW_PRINT_SETUP: 216 case PSRV_GET_DEFAULT_SETTINGS: 217 case PSRV_MAKE_PRINTER: 218 AsyncHandleMessage(DetachCurrentMessage()); 219 break; 220 221 // Tell printer addon to print a spooled job 222 case PSRV_PRINT_SPOOLED_JOB: 223 HandleSpooledJobs(); 224 break; 225 } 226 } 227 228