1 /* 2 * Copyright 2003-2007, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Philippe Houdoin 7 * Simon Gauvin 8 * Michael Pfeiffer 9 * Dr. Hartmut Reh 10 */ 11 12 #include <stdio.h> 13 #include <string.h> // for memset() 14 15 #include <StorageKit.h> 16 17 #include "PrinterDriver.h" 18 19 #include "PrinterSetupWindow.h" 20 #include "PageSetupWindow.h" 21 #include "JobSetupWindow.h" 22 23 // Private prototypes 24 // ------------------ 25 26 #ifdef CODEWARRIOR 27 #pragma mark [Constructor & destructor] 28 #endif 29 30 // Constructor & destructor 31 // ------------------------ 32 33 // -------------------------------------------------- 34 PrinterDriver::PrinterDriver(BNode* printerNode) 35 : fJobFile(NULL), 36 fPrinterNode(printerNode), 37 fJobMsg(NULL) 38 { 39 } 40 41 42 // -------------------------------------------------- 43 PrinterDriver::~PrinterDriver() 44 { 45 } 46 47 #ifdef CODEWARRIOR 48 #pragma mark [Public methods] 49 #endif 50 51 #ifdef B_BEOS_VERSION_DANO 52 struct print_file_header { 53 int32 version; 54 int32 page_count; 55 off_t first_page; 56 int32 _reserved_3_; 57 int32 _reserved_4_; 58 int32 _reserved_5_; 59 }; 60 #endif 61 62 63 // Public methods 64 // -------------- 65 66 status_t 67 PrinterDriver::PrintJob 68 ( 69 BFile *jobFile, // spool file 70 BMessage *jobMsg // job message 71 ) 72 { 73 print_file_header pfh; 74 status_t status; 75 BMessage *msg; 76 int32 page; 77 uint32 copy; 78 uint32 copies; 79 const int32 passes = 2; 80 81 fJobFile = jobFile; 82 fJobMsg = jobMsg; 83 84 if (!fJobFile || !fPrinterNode) 85 return B_ERROR; 86 87 // read print file header 88 fJobFile->Seek(0, SEEK_SET); 89 fJobFile->Read(&pfh, sizeof(pfh)); 90 91 // read job message 92 fJobMsg = msg = new BMessage(); 93 msg->Unflatten(fJobFile); 94 95 if (msg->HasInt32("copies")) { 96 copies = msg->FindInt32("copies"); 97 } else { 98 copies = 1; 99 } 100 101 status = BeginJob(); 102 103 fPrinting = true; 104 for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) { 105 for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++) 106 { 107 for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) { 108 status = PrintPage(page, pfh.page_count); 109 } 110 111 // re-read job message for next page 112 fJobFile->Seek(sizeof(pfh), SEEK_SET); 113 msg->Unflatten(fJobFile); 114 } 115 } 116 117 status_t s = EndJob(); 118 if (status == B_OK) status = s; 119 120 delete fJobMsg; 121 122 return status; 123 } 124 125 /** 126 * This will stop the printing loop 127 * 128 * @param none 129 * @return void 130 */ 131 void 132 PrinterDriver::StopPrinting() 133 { 134 fPrinting = false; 135 } 136 137 138 // -------------------------------------------------- 139 status_t 140 PrinterDriver::BeginJob() 141 { 142 return B_OK; 143 } 144 145 146 // -------------------------------------------------- 147 status_t 148 PrinterDriver::PrintPage(int32 pageNumber, int32 pageCount) 149 { 150 char text[128]; 151 152 sprintf(text, "Faking print of page %ld/%ld...", pageNumber, pageCount); 153 BAlert *alert = new BAlert("PrinterDriver::PrintPage()", text, "Hmm?"); 154 alert->Go(); 155 return B_OK; 156 } 157 158 159 // -------------------------------------------------- 160 status_t 161 PrinterDriver::EndJob() 162 { 163 return B_OK; 164 } 165 166 167 BlockingWindow* PrinterDriver::NewPrinterSetupWindow(char* printerName) { 168 return NULL; 169 } 170 171 BlockingWindow* PrinterDriver::NewPageSetupWindow(BMessage *setupMsg, const char *printerName) { 172 return new PageSetupWindow(setupMsg, printerName); 173 } 174 175 BlockingWindow* PrinterDriver::NewJobSetupWindow(BMessage *jobMsg, const char *printerName) { 176 return new JobSetupWindow(jobMsg, printerName); 177 } 178 179 status_t PrinterDriver::Go(BlockingWindow* w) { 180 if (w) { 181 return w->Go(); 182 } else { 183 return B_OK; 184 } 185 } 186 187 // -------------------------------------------------- 188 status_t 189 PrinterDriver::PrinterSetup(char *printerName) 190 // name of printer, to attach printer settings 191 { 192 return Go(NewPrinterSetupWindow(printerName)); 193 } 194 195 196 // -------------------------------------------------- 197 status_t 198 PrinterDriver::PageSetup(BMessage *setupMsg, const char *printerName) 199 { 200 // check to see if the messag is built correctly... 201 if (setupMsg->HasFloat("scaling") != B_OK) { 202 #if HAS_PRINTER_SETTINGS 203 PrinterSettings *ps = new PrinterSettings(printerName); 204 205 if (ps->InitCheck() == B_OK) { 206 // first read the settings from the spool dir 207 if (ps->ReadSettings(setupMsg) != B_OK) { 208 // if there were none, then create a default set... 209 ps->GetDefaults(setupMsg); 210 // ...and save them 211 ps->WriteSettings(setupMsg); 212 } 213 } 214 #endif 215 } 216 217 return Go(NewPageSetupWindow(setupMsg, printerName)); 218 } 219 220 221 // -------------------------------------------------- 222 status_t 223 PrinterDriver::JobSetup(BMessage *jobMsg, const char *printerName) 224 { 225 // set default value if property not set 226 if (!jobMsg->HasInt32("copies")) 227 jobMsg->AddInt32("copies", 1); 228 229 if (!jobMsg->HasInt32("first_page")) 230 jobMsg->AddInt32("first_page", 1); 231 232 if (!jobMsg->HasInt32("last_page")) 233 jobMsg->AddInt32("last_page", MAX_INT32); 234 235 return Go(NewJobSetupWindow(jobMsg, printerName)); 236 } 237 238 // -------------------------------------------------- 239 BMessage* 240 PrinterDriver::GetDefaultSettings() 241 { 242 BMessage* msg = new BMessage(); 243 BRect paperRect(0, 0, letter_width, letter_height); 244 BRect printableRect(paperRect); 245 printableRect.InsetBy(10, 10); 246 msg->AddRect("paper_rect", paperRect); 247 msg->AddRect("printable_rect", printableRect); 248 msg->AddInt32("orientation", 0); 249 msg->AddInt32("xres", 300); 250 msg->AddInt32("yres", 300); 251 return msg; 252 } 253 254 #ifdef CODEWARRIOR 255 #pragma mark [Privates routines] 256 #endif 257 258 // Private routines 259 // ---------------- 260