/* * PrinterDriver.cpp * Copyright 1999-2000 Y.Takagi. All Rights Reserved. * Copyright 2004 Michael Pfeiffer. */ #include "PrinterDriver.h" #include // for attr_info #include #include #include #include #include #include #include #include #include "AboutBox.h" #include "AddPrinterDlg.h" #include "DbgMsg.h" #include "Exports.h" #include "GraphicsDriver.h" #include "PrinterCap.h" #include "PrinterData.h" #include "UIDriver.h" #include "Preview.h" #include "PrintUtils.h" // Implementation of PrinterDriver PrinterDriver::PrinterDriver(BNode* spoolFolder) : fSpoolFolder(spoolFolder), fPrinterData(NULL), fPrinterCap(NULL), fGraphicsDriver(NULL) { } PrinterDriver::~PrinterDriver() { delete fGraphicsDriver; fGraphicsDriver = NULL; delete fPrinterCap; fPrinterCap = NULL; delete fPrinterData; fPrinterData = NULL; } PrinterData* PrinterDriver::InstantiatePrinterData(BNode* node) { return new PrinterData(node); } void PrinterDriver::InitPrinterDataAndCap() { fPrinterData = InstantiatePrinterData(fSpoolFolder); fPrinterData->Load(); // NOTE: moved the load above from the constructor of PrinterData as // we're inheriting from PrinterData and want our overridden versions // of load to be called fPrinterCap = InstantiatePrinterCap(fPrinterData); } void PrinterDriver::About() { BString copyright; copyright = "libprint Copyright © 1999-2000 Y.Takagi\n"; copyright << GetCopyright(); copyright << "All Rights Reserved."; AboutBox app(GetSignature(), GetDriverName(), GetVersion(), copyright.String()); app.Run(); } char* PrinterDriver::AddPrinter(char* printerName) { // print_server has created a spool folder with name printerName in // folder B_USER_PRINTERS_DIRECTORY. It can be used to store // settings in the folder attributes. DBGMSG((">%s: add_printer\n", GetDriverName())); DBGMSG(("\tprinter_name: %s\n", printerName)); DBGMSG(("<%s: add_printer\n", GetDriverName())); if (fPrinterCap->Supports(PrinterCap::kProtocolClass)) { if (fPrinterCap->CountCap(PrinterCap::kProtocolClass) > 1) { AddPrinterDlg *dialog; dialog = new AddPrinterDlg(fPrinterData, fPrinterCap); if (dialog->Go() != B_OK) { // dialog canceled return NULL; } } else { const ProtocolClassCap* pcCap; pcCap = (const ProtocolClassCap*)fPrinterCap->GetDefaultCap( PrinterCap::kProtocolClass); if (pcCap != NULL) { fPrinterData->SetProtocolClass(pcCap->fProtocolClass); fPrinterData->Save(); } } } return printerName; } BMessage* PrinterDriver::ConfigPage(BMessage* settings) { DBGMSG((">%s: config_page\n", GetDriverName())); DUMP_BMESSAGE(settings); DUMP_BNODE(fSpoolFolder); BMessage pageSettings(*settings); _MergeWithPreviousSettings(kAttrPageSettings, &pageSettings); UIDriver uiDriver(&pageSettings, fPrinterData, fPrinterCap); BMessage *result = uiDriver.ConfigPage(); _WriteSettings(kAttrPageSettings, result); DUMP_BMESSAGE(result); DBGMSG(("<%s: config_page\n", GetDriverName())); return result; } BMessage* PrinterDriver::ConfigJob(BMessage* settings) { DBGMSG((">%s: config_job\n", GetDriverName())); DUMP_BMESSAGE(settings); DUMP_BNODE(fSpoolFolder); BMessage jobSettings(*settings); _MergeWithPreviousSettings(kAttrJobSettings, &jobSettings); UIDriver uiDriver(&jobSettings, fPrinterData, fPrinterCap); BMessage *result = uiDriver.ConfigJob(); _WriteSettings(kAttrJobSettings, result); DUMP_BMESSAGE(result); DBGMSG(("<%s: config_job\n", GetDriverName())); return result; } BMessage* PrinterDriver::TakeJob(BFile* printJob, BMessage* settings) { DBGMSG((">%s: take_job\n", GetDriverName())); DUMP_BMESSAGE(settings); DUMP_BNODE(fSpoolFolder); fGraphicsDriver = InstantiateGraphicsDriver(settings, fPrinterData, fPrinterCap); const JobData* jobData = fGraphicsDriver->GetJobData(printJob); if (jobData != NULL && jobData->GetShowPreview()) { off_t offset = printJob->Position(); PreviewWindow *preview = new PreviewWindow(printJob, true); if (preview->Go() != B_OK) { return new BMessage('okok'); } printJob->Seek(offset, SEEK_SET); } BMessage *result = fGraphicsDriver->TakeJob(printJob); DUMP_BMESSAGE(result); DBGMSG(("<%s: take_job\n", GetDriverName())); return result; } // read settings from spool folder attribute bool PrinterDriver::_ReadSettings(const char* attrName, BMessage* settings) { attr_info info; ssize_t size; settings->MakeEmpty(); if (fSpoolFolder->GetAttrInfo(attrName, &info) == B_OK && info.size > 0) { BStackOrHeapArray data(info.size); if (!data.IsValid()) return false; size = fSpoolFolder->ReadAttr(attrName, B_MESSAGE_TYPE, 0, data, info.size); if (size == info.size && settings->Unflatten(data) == B_OK) { return true; } } return false; } // write settings to spool folder attribute void PrinterDriver::_WriteSettings(const char* attrName, BMessage* settings) { if (settings == NULL || settings->what != 'okok') return; status_t status; BMallocIO data; status = settings->Flatten(&data); if (status == B_OK) { fSpoolFolder->WriteAttr(attrName, B_MESSAGE_TYPE, 0, data.Buffer(), data.BufferLength()); } } // read settings from spool folder attribute and merge them to current settings void PrinterDriver::_MergeWithPreviousSettings(const char* attrName, BMessage* settings) { if (settings == NULL) return; BMessage stored; if (_ReadSettings(attrName, &stored)) { AddFields(&stored, settings); *settings = stored; } } // Implementation of PrinterDriverInstance class PrinterDriverInstance { public: PrinterDriverInstance(BNode* spoolFolder = NULL); ~PrinterDriverInstance(); PrinterDriver* GetPrinterDriver() { return fInstance; } private: PrinterDriver* fInstance; }; PrinterDriverInstance::PrinterDriverInstance(BNode* spoolFolder) { fInstance = instantiate_printer_driver(spoolFolder); if (fInstance != NULL) { fInstance->InitPrinterDataAndCap(); } } PrinterDriverInstance::~PrinterDriverInstance() { delete fInstance; fInstance = NULL; } // printer driver add-on functions char *add_printer(char *printerName) { BPath path; BNode folder; BNode* spoolFolder = NULL; // get spool folder if (find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK && path.Append(printerName) == B_OK && folder.SetTo(path.Path()) == B_OK) { spoolFolder = &folder; } PrinterDriverInstance instance(spoolFolder); return instance.GetPrinterDriver()->AddPrinter(printerName); } BMessage *config_page(BNode *spoolFolder, BMessage *settings) { PrinterDriverInstance instance(spoolFolder); return instance.GetPrinterDriver()->ConfigPage(settings); } BMessage *config_job(BNode *spoolFolder, BMessage *settings) { PrinterDriverInstance instance(spoolFolder); return instance.GetPrinterDriver()->ConfigJob(settings); } BMessage *take_job(BFile *printJob, BNode *spoolFolder, BMessage *settings) { PrinterDriverInstance instance(spoolFolder); return instance.GetPrinterDriver()->TakeJob(printJob, settings); } // main entry if printer driver is launched directly int main(int argc, char* argv[]) { PrinterDriverInstance instance; instance.GetPrinterDriver()->About(); return 0; }