1 /* 2 * Copyright 2001-2006, 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 { 53 AutoReply sender(msg, 'stop'); 54 switch (msg->what) { 55 // Handle showing the page config dialog 56 case PSRV_SHOW_PAGE_SETUP: { 57 BMessage reply(*msg); 58 if (printer != NULL) { 59 if (p->app->fUseConfigWindow) { 60 ConfigWindow* w = new ConfigWindow(kPageSetup, printer, msg, &sender); 61 w->Go(); 62 } else if (printer->ConfigurePage(reply) == B_OK) { 63 sender.SetReply(&reply); 64 } 65 } else { 66 // If no default printer, give user choice of aborting or setting up a printer 67 BAlert* alert = new BAlert("Info", "There are no printers set up. Would you set one up now?", "No", "Yes"); 68 if (alert->Go() == 1) { 69 run_add_printer_panel(); 70 } 71 } 72 } 73 break; 74 75 // Handle showing the print config dialog 76 case PSRV_SHOW_PRINT_SETUP: { 77 if (printer == NULL) break; 78 if (p->app->fUseConfigWindow) { 79 ConfigWindow* w = new ConfigWindow(kJobSetup, printer, msg, &sender); 80 w->Go(); 81 } else { 82 BMessage reply(*msg); 83 if (printer->ConfigureJob(reply) == B_OK) { 84 sender.SetReply(&reply); 85 } 86 } 87 } 88 break; 89 90 // Retrieve default configuration message from printer add-on 91 case PSRV_GET_DEFAULT_SETTINGS: 92 if (printer != NULL) { 93 BMessage reply; 94 if (printer->GetDefaultSettings(reply) == B_OK) { 95 sender.SetReply(&reply); 96 break; 97 } 98 } 99 break; 100 101 // Create a new printer 102 case PSRV_MAKE_PRINTER: { 103 BString driverName, transportName, transportPath; 104 BString printerName, connection; 105 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 ) { 111 112 if (msg->FindString("connection", &connection) != B_OK) 113 connection = "Local"; 114 115 // then create the actual printer 116 if (p->app->CreatePrinter(printerName.String(), driverName.String(), 117 connection.String(), 118 transportName.String(), transportPath.String()) == B_OK) { 119 // If printer was created ok, ask if it needs to be the default 120 char buffer[256]; 121 ::sprintf(buffer, "Would you like to make %s the default printer?", 122 printerName.String()); 123 124 BAlert* alert = new BAlert("", buffer, "No", "Yes"); 125 if (alert->Go() == 1) { 126 p->app->SelectPrinter(printerName.String()); 127 } 128 } 129 } 130 } 131 break; 132 } 133 } 134 135 delete p; 136 137 return B_OK; 138 } 139 140 141 // Async. processing of received message 142 void PrintServerApp::AsyncHandleMessage(BMessage* msg) 143 { 144 AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg); 145 146 thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY, (void*)data); 147 148 if (tid > 0) { 149 resume_thread(tid); 150 } else { 151 delete data; 152 } 153 } 154 155 void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg) 156 { 157 switch(msg->what) { 158 // Get currently selected printer 159 case PSRV_GET_ACTIVE_PRINTER: { 160 BMessage reply('okok'); 161 BString printerName = fDefaultPrinter ? fDefaultPrinter->Name() : ""; 162 BString mime; 163 if (fUseConfigWindow && MimeTypeForSender(msg, mime)) { 164 BAutolock lock(gLock); 165 if (lock.IsLocked()) { 166 // override with printer for application 167 PrinterSettings* p = fSettings->FindPrinterSettings(mime.String()); 168 if (p) printerName = p->GetPrinter(); 169 } 170 } 171 reply.AddString("printer_name", printerName); 172 reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER); // BeOS knows not if color or not, so always color 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