1/* 2 3PDF Writer printer driver. 4 5Copyright (c) 2001-2003 OpenBeOS. 6 7Authors: 8 Philippe Houdoin 9 Simon Gauvin 10 Michael Pfeiffer 11 12Permission is hereby granted, free of charge, to any person obtaining a copy of 13this software and associated documentation files (the "Software"), to deal in 14the Software without restriction, including without limitation the rights to 15use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 16of the Software, and to permit persons to whom the Software is furnished to do 17so, subject to the following conditions: 18 19The above copyright notice and this permission notice shall be included in all 20copies or substantial portions of the Software. 21 22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28THE SOFTWARE. 29 30*/ 31 32 33#include <stdio.h> 34#include <string.h> // for memset() 35 36#include <StorageKit.h> 37 38#include "PrinterDriver.h" 39 40#include "PageSetupWindow.h" 41#include "JobSetupWindow.h" 42#include "StatusWindow.h" 43#include "PrinterSettings.h" 44#include "Report.h" 45 46// Private prototypes 47// ------------------ 48 49#ifdef CODEWARRIOR 50 #pragma mark [Constructor & destructor] 51#endif 52 53// Constructor & destructor 54// ------------------------ 55 56// -------------------------------------------------- 57PrinterDriver::PrinterDriver() 58 : fJobFile(NULL), 59 fPrinterNode(NULL), 60 fJobMsg(NULL) 61{ 62} 63 64 65// -------------------------------------------------- 66PrinterDriver::~PrinterDriver() 67{ 68} 69 70#ifdef CODEWARRIOR 71 #pragma mark [Public methods] 72#endif 73 74#ifdef B_BEOS_VERSION_DANO 75struct print_file_header { 76 int32 version; 77 int32 page_count; 78 off_t first_page; 79 int32 _reserved_3_; 80 int32 _reserved_4_; 81 int32 _reserved_5_; 82}; 83#endif 84 85// Public methods 86// -------------- 87 88status_t 89PrinterDriver::PrintJob 90 ( 91 BFile *jobFile, // spool file 92 BNode *printerNode, // printer node, used by OpenTransport() to find & load transport add-on 93 BMessage *jobMsg // job message 94 ) 95{ 96 print_file_header pfh; 97 status_t status; 98 BMessage *msg; 99 int32 page; 100 uint32 copy; 101 uint32 copies; 102 const int32 passes = 2; 103 104 fJobFile = jobFile; 105 fPrinterNode = printerNode; 106 fJobMsg = jobMsg; 107 108 if (!fJobFile || !fPrinterNode) 109 return B_ERROR; 110 111 if (fPrintTransport.Open(fPrinterNode) != B_OK) { 112 return B_ERROR; 113 } 114 if (fPrintTransport.IsPrintToFileCanceled()) { 115 return B_OK; 116 } 117 118 // read print file header 119 fJobFile->Seek(0, SEEK_SET); 120 fJobFile->Read(&pfh, sizeof(pfh)); 121 122 // read job message 123 fJobMsg = msg = new BMessage(); 124 msg->Unflatten(fJobFile); 125 // We have to load the settings here for Dano/Zeta because they don't store 126 // all fields from the message returned by config_job in the job file! 127 PrinterSettings::Read(printerNode, msg, PrinterSettings::kJobSettings); 128 129 if (msg->HasInt32("copies")) { 130 copies = msg->FindInt32("copies"); 131 } else { 132 copies = 1; 133 } 134 135 // force creation of Report object 136 Report::Instance(); 137 138 // show status window 139 StatusWindow* statusWindow = new StatusWindow(passes, pfh.page_count, this); 140 141 status = BeginJob(); 142 143 fPrinting = true; 144 for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) { 145 for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++) 146 { 147 for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) { 148 statusWindow->NextPage(); 149 status = PrintPage(page, pfh.page_count); 150 } 151 152 // re-read job message for next page 153 fJobFile->Seek(sizeof(pfh), SEEK_SET); 154 msg->Unflatten(fJobFile); 155 } 156 } 157 158 status_t s = EndJob(); 159 if (status == B_OK) status = s; 160 161 delete fJobMsg; 162 163 // close status window 164 if (Report::Instance()->CountItems() != 0) { 165 statusWindow->WaitForClose(); 166 } 167 if (statusWindow->Lock()) { 168 statusWindow->Quit(); 169 } 170 171 // delete Report object 172 Report::Instance()->Free(); 173 174 return status; 175} 176 177/** 178 * This will stop the printing loop 179 * 180 * @param none 181 * @return void 182 */ 183void 184PrinterDriver::StopPrinting() 185{ 186 fPrinting = false; 187} 188 189 190// -------------------------------------------------- 191status_t 192PrinterDriver::BeginJob() 193{ 194 return B_OK; 195} 196 197 198// -------------------------------------------------- 199status_t 200PrinterDriver::PrintPage(int32 pageNumber, int32 pageCount) 201{ 202 char text[128]; 203 204 sprintf(text, "Faking print of page %" B_PRId32 "/%" B_PRId32 "...", pageNumber, pageCount); 205 BAlert *alert = new BAlert("PrinterDriver::PrintPage()", text, "Hmm?"); 206 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 207 alert->Go(); 208 return B_OK; 209} 210 211 212// -------------------------------------------------- 213status_t 214PrinterDriver::EndJob() 215{ 216 return B_OK; 217} 218 219 220// -------------------------------------------------- 221status_t 222PrinterDriver::PrinterSetup(char *printerName) 223 // name of printer, to attach printer settings 224{ 225 return B_OK; 226} 227 228 229// -------------------------------------------------- 230status_t 231PrinterDriver::PageSetup(BMessage *setupMsg, const char *printerName) 232{ 233 PageSetupWindow *psw; 234 235 psw = new PageSetupWindow(setupMsg, printerName); 236 return psw->Go(); 237} 238 239 240// -------------------------------------------------- 241status_t 242PrinterDriver::JobSetup(BMessage *jobMsg, const char *printerName) 243{ 244 // set default value if property not set 245 if (!jobMsg->HasInt32("copies")) 246 jobMsg->AddInt32("copies", 1); 247 248 if (!jobMsg->HasInt32("first_page")) 249 jobMsg->AddInt32("first_page", 1); 250 251 if (!jobMsg->HasInt32("last_page")) 252 jobMsg->AddInt32("last_page", MAX_INT32); 253 254 JobSetupWindow * jsw; 255 256 jsw = new JobSetupWindow(jobMsg, printerName); 257 return jsw->Go(); 258} 259 260#ifdef CODEWARRIOR 261 #pragma mark [Privates routines] 262#endif 263 264// Private routines 265// ---------------- 266