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