1 /* 2 3 Preview printer driver. 4 5 Copyright (c) 2003 OpenBeOS. 6 7 Authors: 8 Philippe Houdoin 9 Simon Gauvin 10 Michael Pfeiffer 11 12 Permission is hereby granted, free of charge, to any person obtaining a copy of 13 this software and associated documentation files (the "Software"), to deal in 14 the Software without restriction, including without limitation the rights to 15 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 16 of the Software, and to permit persons to whom the Software is furnished to do 17 so, subject to the following conditions: 18 19 The above copyright notice and this permission notice shall be included in all 20 copies or substantial portions of the Software. 21 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 THE 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 "PrinterSetupWindow.h" 41 #include "PageSetupWindow.h" 42 #include "JobSetupWindow.h" 43 44 // Private prototypes 45 // ------------------ 46 47 #ifdef CODEWARRIOR 48 #pragma mark [Constructor & destructor] 49 #endif 50 51 // Constructor & destructor 52 // ------------------------ 53 54 // -------------------------------------------------- 55 PrinterDriver::PrinterDriver(BNode* printerNode) 56 : fJobFile(NULL), 57 fPrinterNode(printerNode), 58 fJobMsg(NULL) 59 { 60 } 61 62 63 // -------------------------------------------------- 64 PrinterDriver::~PrinterDriver() 65 { 66 } 67 68 #ifdef CODEWARRIOR 69 #pragma mark [Public methods] 70 #endif 71 72 #ifdef B_BEOS_VERSION_DANO 73 struct print_file_header { 74 int32 version; 75 int32 page_count; 76 off_t first_page; 77 int32 _reserved_3_; 78 int32 _reserved_4_; 79 int32 _reserved_5_; 80 }; 81 #endif 82 83 84 // Public methods 85 // -------------- 86 87 status_t 88 PrinterDriver::PrintJob 89 ( 90 BFile *jobFile, // spool file 91 BMessage *jobMsg // job message 92 ) 93 { 94 print_file_header pfh; 95 status_t status; 96 BMessage *msg; 97 int32 page; 98 uint32 copy; 99 uint32 copies; 100 const int32 passes = 2; 101 102 fJobFile = jobFile; 103 fJobMsg = jobMsg; 104 105 if (!fJobFile || !fPrinterNode) 106 return B_ERROR; 107 108 if (fPrintTransport.Open(fPrinterNode) != B_OK) { 109 return B_ERROR; 110 } 111 if (fPrintTransport.IsPrintToFileCanceled()) { 112 return B_OK; 113 } 114 115 // read print file header 116 fJobFile->Seek(0, SEEK_SET); 117 fJobFile->Read(&pfh, sizeof(pfh)); 118 119 // read job message 120 fJobMsg = msg = new BMessage(); 121 msg->Unflatten(fJobFile); 122 123 if (msg->HasInt32("copies")) { 124 copies = msg->FindInt32("copies"); 125 } else { 126 copies = 1; 127 } 128 129 status = BeginJob(); 130 131 fPrinting = true; 132 for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) { 133 for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++) 134 { 135 for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) { 136 status = PrintPage(page, pfh.page_count); 137 } 138 139 // re-read job message for next page 140 fJobFile->Seek(sizeof(pfh), SEEK_SET); 141 msg->Unflatten(fJobFile); 142 } 143 } 144 145 status_t s = EndJob(); 146 if (status == B_OK) status = s; 147 148 delete fJobMsg; 149 150 return status; 151 } 152 153 /** 154 * This will stop the printing loop 155 * 156 * @param none 157 * @return void 158 */ 159 void 160 PrinterDriver::StopPrinting() 161 { 162 fPrinting = false; 163 } 164 165 166 // -------------------------------------------------- 167 status_t 168 PrinterDriver::BeginJob() 169 { 170 return B_OK; 171 } 172 173 174 // -------------------------------------------------- 175 status_t 176 PrinterDriver::PrintPage(int32 pageNumber, int32 pageCount) 177 { 178 char text[128]; 179 180 sprintf(text, "Faking print of page %ld/%ld...", pageNumber, pageCount); 181 BAlert *alert = new BAlert("PrinterDriver::PrintPage()", text, "Hmm?"); 182 alert->Go(); 183 return B_OK; 184 } 185 186 187 // -------------------------------------------------- 188 status_t 189 PrinterDriver::EndJob() 190 { 191 return B_OK; 192 } 193 194 195 BlockingWindow* PrinterDriver::NewPrinterSetupWindow(char* printerName) { 196 return NULL; 197 } 198 199 BlockingWindow* PrinterDriver::NewPageSetupWindow(BMessage *setupMsg, const char *printerName) { 200 return new PageSetupWindow(setupMsg, printerName); 201 } 202 203 BlockingWindow* PrinterDriver::NewJobSetupWindow(BMessage *jobMsg, const char *printerName) { 204 return new JobSetupWindow(jobMsg, printerName); 205 } 206 207 status_t PrinterDriver::Go(BlockingWindow* w) { 208 if (w) { 209 return w->Go(); 210 } else { 211 return B_OK; 212 } 213 } 214 215 // -------------------------------------------------- 216 status_t 217 PrinterDriver::PrinterSetup(char *printerName) 218 // name of printer, to attach printer settings 219 { 220 return Go(NewPrinterSetupWindow(printerName)); 221 } 222 223 224 // -------------------------------------------------- 225 status_t 226 PrinterDriver::PageSetup(BMessage *setupMsg, const char *printerName) 227 { 228 // check to see if the messag is built correctly... 229 if (setupMsg->HasFloat("scaling") != B_OK) { 230 #if HAS_PRINTER_SETTINGS 231 PrinterSettings *ps = new PrinterSettings(printerName); 232 233 if (ps->InitCheck() == B_OK) { 234 // first read the settings from the spool dir 235 if (ps->ReadSettings(setupMsg) != B_OK) { 236 // if there were none, then create a default set... 237 ps->GetDefaults(setupMsg); 238 // ...and save them 239 ps->WriteSettings(setupMsg); 240 } 241 } 242 #endif 243 } 244 245 return Go(NewPageSetupWindow(setupMsg, printerName)); 246 } 247 248 249 // -------------------------------------------------- 250 status_t 251 PrinterDriver::JobSetup(BMessage *jobMsg, const char *printerName) 252 { 253 // set default value if property not set 254 if (!jobMsg->HasInt32("copies")) 255 jobMsg->AddInt32("copies", 1); 256 257 if (!jobMsg->HasInt32("first_page")) 258 jobMsg->AddInt32("first_page", 1); 259 260 if (!jobMsg->HasInt32("last_page")) 261 jobMsg->AddInt32("last_page", MAX_INT32); 262 263 return Go(NewJobSetupWindow(jobMsg, printerName)); 264 } 265 266 // -------------------------------------------------- 267 BMessage* 268 PrinterDriver::GetDefaultSettings() 269 { 270 BMessage* msg = new BMessage(); 271 BRect paperRect(0, 0, letter_width, letter_height); 272 BRect printableRect(paperRect); 273 printableRect.InsetBy(10, 10); 274 msg->AddRect("paper_rect", paperRect); 275 msg->AddRect("printable_rect", printableRect); 276 msg->AddInt32("orientation", 0); 277 msg->AddInt32("xres", 300); 278 msg->AddInt32("yres", 300); 279 return msg; 280 } 281 282 #ifdef CODEWARRIOR 283 #pragma mark [Privates routines] 284 #endif 285 286 // Private routines 287 // ---------------- 288