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