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