1 /*****************************************************************************/ 2 // print_server Background Application. 3 // 4 // Version: 1.0.0d1 5 // 6 // The print_server manages the communication between applications and the 7 // printer and transport drivers. 8 // 9 // Authors 10 // Ithamar R. Adema 11 // Michael Pfeiffer 12 // 13 // This application and all source files used in its construction, except 14 // where noted, are licensed under the MIT License, and have been written 15 // and are: 16 // 17 // Copyright (c) 2001, 2002 OpenBeOS Project 18 // 19 // Permission is hereby granted, free of charge, to any person obtaining a 20 // copy of this software and associated documentation files (the "Software"), 21 // to deal in the Software without restriction, including without limitation 22 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 23 // and/or sell copies of the Software, and to permit persons to whom the 24 // Software is furnished to do so, subject to the following conditions: 25 // 26 // The above copyright notice and this permission notice shall be included 27 // in all copies or substantial portions of the Software. 28 // 29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 30 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 32 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 34 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 35 // DEALINGS IN THE SOFTWARE. 36 /*****************************************************************************/ 37 38 #include "PrintServerApp.h" 39 40 #include "pr_server.h" 41 #include "Printer.h" 42 #include "ConfigWindow.h" 43 44 // BeOS API 45 #include <Alert.h> 46 #include <Autolock.h> 47 #include <PrintJob.h> 48 49 struct AsyncThreadParams { 50 PrintServerApp* app; 51 Printer* printer; 52 BMessage* message; 53 54 AsyncThreadParams(PrintServerApp* app, Printer* p, BMessage* m) 55 : app(app) 56 , printer(p) 57 , message(m) 58 { 59 app->Acquire(); 60 if (printer) printer->Acquire(); 61 } 62 63 ~AsyncThreadParams() { 64 if (printer) printer->Release(); 65 delete message; 66 app->Release(); 67 } 68 69 BMessage* AcquireMessage() { 70 BMessage* m = message; message = NULL; return m; 71 } 72 }; 73 74 status_t PrintServerApp::async_thread(void* data) 75 { 76 AsyncThreadParams* p = (AsyncThreadParams*)data; 77 78 Printer* printer = p->printer; 79 BMessage* msg = p->AcquireMessage(); 80 81 { 82 AutoReply sender(msg, 'stop'); 83 switch (msg->what) { 84 // Handle showing the page config dialog 85 case PSRV_SHOW_PAGE_SETUP: { 86 BMessage reply(*msg); 87 if (printer != NULL) { 88 if (p->app->fUseConfigWindow) { 89 ConfigWindow* w = new ConfigWindow(kPageSetup, printer, msg, &sender); 90 w->Go(); 91 } else if (printer->ConfigurePage(reply) == B_OK) { 92 sender.SetReply(&reply); 93 } 94 } else { 95 // If no default printer, give user choice of aborting or setting up a printer 96 BAlert* alert = new BAlert("Info", "Hang on there! You don't have any printers set up!\nYou'll need to do that before trying to print\n\nWould you like to set up a printer now?", "No thanks", "Sure!"); 97 if (alert->Go() == 1) { 98 run_add_printer_panel(); 99 } 100 } 101 } 102 break; 103 104 // Handle showing the print config dialog 105 case PSRV_SHOW_PRINT_SETUP: { 106 if (printer == NULL) break; 107 if (p->app->fUseConfigWindow) { 108 ConfigWindow* w = new ConfigWindow(kJobSetup, printer, msg, &sender); 109 w->Go(); 110 } else { 111 BMessage reply(*msg); 112 if (printer->ConfigureJob(reply) == B_OK) { 113 sender.SetReply(&reply); 114 } 115 } 116 } 117 break; 118 119 // Retrieve default configuration message from printer add-on 120 case PSRV_GET_DEFAULT_SETTINGS: 121 if (printer != NULL) { 122 BMessage reply; 123 if (printer->GetDefaultSettings(reply) == B_OK) { 124 sender.SetReply(&reply); 125 break; 126 } 127 } 128 break; 129 130 // Create a new printer 131 case PSRV_MAKE_PRINTER: { 132 BString driverName, transportName, transportPath; 133 BString printerName, connection; 134 135 if (msg->FindString("driver", &driverName) == B_OK && 136 msg->FindString("transport", &transportName) == B_OK && 137 msg->FindString("transport path", &transportPath) == B_OK && 138 msg->FindString("printer name", &printerName) == B_OK 139 ) { 140 141 if (msg->FindString("connection", &connection) != B_OK) 142 connection = "Local"; 143 144 // then create the actual printer 145 if (p->app->CreatePrinter(printerName.String(), driverName.String(), 146 connection.String(), 147 transportName.String(), transportPath.String()) == B_OK) { 148 // If printer was created ok, ask if it needs to be the default 149 char buffer[256]; 150 ::sprintf(buffer, "Would you like to make %s the default\nprinter?", 151 printerName.String()); 152 153 BAlert* alert = new BAlert("", buffer, "No", "Yes"); 154 if (alert->Go() == 1) { 155 p->app->SelectPrinter(printerName.String()); 156 } 157 } 158 } 159 } 160 break; 161 } 162 } 163 164 delete p; 165 } 166 167 168 // Async. processing of received message 169 void PrintServerApp::AsyncHandleMessage(BMessage* msg) 170 { 171 AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg); 172 173 thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY, (void*)data); 174 175 if (tid > 0) { 176 resume_thread(tid); 177 } else { 178 delete data; 179 } 180 } 181 182 void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg) 183 { 184 switch(msg->what) { 185 // Get currently selected printer 186 case PSRV_GET_ACTIVE_PRINTER: { 187 BMessage reply('okok'); 188 BString printerName = fDefaultPrinter ? fDefaultPrinter->Name() : ""; 189 BString mime; 190 if (fUseConfigWindow && MimeTypeForSender(msg, mime)) { 191 BAutolock lock(gLock); 192 if (lock.IsLocked()) { 193 // override with printer for application 194 PrinterSettings* p = fSettings->FindPrinterSettings(mime.String()); 195 if (p) printerName = p->GetPrinter(); 196 } 197 } 198 reply.AddString("printer_name", printerName); 199 reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER); // BeOS knows not if color or not, so always color 200 msg->SendReply(&reply); 201 } 202 break; 203 204 //make printer active (currently always quietly :)) 205 case PSRV_MAKE_PRINTER_ACTIVE_QUIETLY: 206 //make printer active quietly 207 case PSRV_MAKE_PRINTER_ACTIVE: { 208 BString newActivePrinter; 209 if (msg->FindString("printer",&newActivePrinter) == B_OK) { 210 SelectPrinter(newActivePrinter.String()); 211 } 212 } 213 break; 214 215 #if 0 216 // Create a new printer 217 case PSRV_MAKE_PRINTER: { 218 BString driverName, transportName, transportPath; 219 BString printerName, connection; 220 221 if (msg->FindString("driver", &driverName) == B_OK && 222 msg->FindString("transport", &transportName) == B_OK && 223 msg->FindString("transport path", &transportPath) == B_OK && 224 msg->FindString("printer name", &printerName) == B_OK 225 ) { 226 227 if (msg->FindString("connection", &connection) != B_OK) 228 connection = "Local"; 229 230 // then create the actual printer 231 if (CreatePrinter(printerName.String(), driverName.String(), 232 connection.String(), 233 transportName.String(), transportPath.String()) == B_OK) { 234 // If printer was created ok, ask if it needs to be the default 235 char buffer[256]; 236 ::sprintf(buffer, "Would you like to make %s the default\nprinter?", 237 printerName.String()); 238 239 BAlert* alert = new BAlert("", buffer, "No", "Yes"); 240 if (alert->Go() == 1) { 241 SelectPrinter(printerName.String()); 242 } 243 } 244 } 245 } 246 break; 247 #endif 248 249 case PSRV_SHOW_PAGE_SETUP: 250 case PSRV_SHOW_PRINT_SETUP: 251 case PSRV_GET_DEFAULT_SETTINGS: 252 case PSRV_MAKE_PRINTER: 253 AsyncHandleMessage(DetachCurrentMessage()); 254 break; 255 256 // Tell printer addon to print a spooled job 257 case PSRV_PRINT_SPOOLED_JOB: 258 HandleSpooledJobs(); 259 break; 260 } 261 } 262