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