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