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