174462Salfred/* 274462Salfred * Copyright 2008 Haiku Inc. All rights reserved. 3258578Shrs * Distributed under the terms of the MIT License. 4258578Shrs * 5258578Shrs * Authors: 6258578Shrs * Julun, <host.haiku@gmx.de 7258578Shrs */ 8258578Shrs 9258578Shrs#include <Printer.h> 10258578Shrs 11258578Shrs#include <FindDirectory.h> 12258578Shrs#include <NodeInfo.h> 13258578Shrs#include <NodeMonitor.h> 14258578Shrs 15258578Shrs 16258578Shrs#include <new> 1774462Salfred 18258578Shrs 19258578Shrsnamespace BPrivate { 20258578Shrs namespace Print { 21258578Shrs 22258578Shrs 23258578Shrs// TODO: remove, after pr_server.h cleanup 24258578Shrs 25258578Shrs// mime file types 26258578Shrs#define PSRV_PRINTER_MIMETYPE "application/x-vnd.Be.printer" 27258578Shrs 28258578Shrs 2974462Salfred// printer attributes 3074462Salfred#define PSRV_PRINTER_ATTR_STATE "state" 3174462Salfred#define PSRV_PRINTER_ATTR_COMMENTS "Comments" 3274462Salfred#define PSRV_PRINTER_ATTR_TRANSPORT "transport" 3374462Salfred#define PSRV_PRINTER_ATTR_DRIVER_NAME "Driver Name" 34136581Sobrien#define PSRV_PRINTER_ATTR_PRINTER_NAME "Printer Name" 35136581Sobrien#define PSRV_PRINTER_ATTR_DEFAULT_PRINTER "Default Printer" 3674462Salfred#define PSRV_PRINTER_ATTR_TRANSPORT_ADDRESS "transport_address" 3774462Salfred 3892990Sobrien 3992990Sobrien// message fields 4074462Salfred#define PSRV_FIELD_CURRENT_PRINTER "current_printer" 4174462Salfred 4274462Salfred 4374462SalfredBPrinter::BPrinter() 4474462Salfred : fListener(NULL) 4575094Siedowse{ 4674462Salfred memset(&fPrinterEntryRef, 0, sizeof(entry_ref)); 4774462Salfred} 48105189Siedowse 4974462Salfred 5074462SalfredBPrinter::BPrinter(const BEntry& entry) 5174462Salfred : fListener(NULL) 5290868Smike{ 5374462Salfred SetTo(entry); 54181344Sdfr} 5574462Salfred 5674462Salfred 5774462SalfredBPrinter::BPrinter(const BPrinter& printer) 5874462Salfred{ 5974462Salfred *this = printer; 6074462Salfred} 6174462Salfred 6274462Salfred 63156090SdeischenBPrinter::BPrinter(const node_ref& nodeRef) 6474462Salfred : fListener(NULL) 6574462Salfred{ 66167199Ssimon SetTo(nodeRef); 67167199Ssimon} 68167199Ssimon 69167199Ssimon 70167199SsimonBPrinter::BPrinter(const entry_ref& entryRef) 71167199Ssimon : fListener(NULL) 7274462Salfred , fPrinterEntryRef(entryRef) 73167199Ssimon{ 7474462Salfred} 7574462Salfred 7692905Sobrien 7792905SobrienBPrinter::BPrinter(const BDirectory& directory) 7895658Sdes : fListener(NULL) 7995658Sdes{ 8092905Sobrien SetTo(directory); 8195658Sdes} 8292905Sobrien 8399996Salfred 8492905SobrienBPrinter::~BPrinter() 8574462Salfred{ 8674462Salfred StopWatching(); 8774462Salfred} 8874462Salfred 8974462Salfred 9074462Salfredstatus_t 9174462SalfredBPrinter::SetTo(const BEntry& entry) 9274462Salfred{ 9374462Salfred StopWatching(); 9474462Salfred entry.GetRef(&fPrinterEntryRef); 9574462Salfred 9674462Salfred return InitCheck(); 9774462Salfred} 9874462Salfred 9974462Salfred 10074462Salfredstatus_t 10174462SalfredBPrinter::SetTo(const node_ref& nodeRef) 10274462Salfred{ 10374462Salfred SetTo(BDirectory(&nodeRef)); 10474462Salfred return InitCheck(); 10574462Salfred} 10675144Siedowse 10774462Salfred 108105189Siedowsestatus_t 10974462SalfredBPrinter::SetTo(const entry_ref& entryRef) 11074462Salfred{ 11174462Salfred StopWatching(); 11274462Salfred fPrinterEntryRef = entryRef; 11374462Salfred 11474462Salfred return InitCheck(); 11574462Salfred} 116181344Sdfr 117181344Sdfr 11874462Salfredstatus_t 11974462SalfredBPrinter::SetTo(const BDirectory& directory) 12074462Salfred{ 12174462Salfred StopWatching(); 12274462Salfred 12374462Salfred BEntry entry; 12474462Salfred directory.GetEntry(&entry); 12574462Salfred entry.GetRef(&fPrinterEntryRef); 12674462Salfred 12774462Salfred return InitCheck(); 12874462Salfred} 12974462Salfred 13074462Salfred 13174462Salfredvoid 132181344SdfrBPrinter::Unset() 13374462Salfred{ 13474462Salfred StopWatching(); 13574879Swpaul memset(&fPrinterEntryRef, 0, sizeof(entry_ref)); 13678678Siedowse} 13778678Siedowse 138105189Siedowse 139105189Siedowsebool 14074462SalfredBPrinter::IsValid() const 14174462Salfred{ 14274462Salfred BDirectory spoolDir(&fPrinterEntryRef); 14374462Salfred if (spoolDir.InitCheck() != B_OK) 14474462Salfred return false; 14574462Salfred 14674462Salfred BNode node(spoolDir); 14774462Salfred char type[B_MIME_TYPE_LENGTH]; 14874462Salfred BNodeInfo(&node).GetType(type); 14974462Salfred 15074462Salfred if (strcmp(type, PSRV_PRINTER_MIMETYPE) != 0) 15174462Salfred return false; 15274462Salfred 15374462Salfred return true; 15474462Salfred} 15574462Salfred 156287341Srodrigc 157287341Srodrigcstatus_t 158287341SrodrigcBPrinter::InitCheck() const 159287341Srodrigc{ 160287341Srodrigc BDirectory spoolDir(&fPrinterEntryRef); 161287341Srodrigc return spoolDir.InitCheck(); 162287341Srodrigc} 16374462Salfred 16474462Salfred 165287341Srodrigcbool 166287341SrodrigcBPrinter::IsFree() const 16774462Salfred{ 16874462Salfred return (State() == "free"); 16974462Salfred} 17074462Salfred 17174462Salfred 17274462Salfredbool 17374462SalfredBPrinter::IsDefault() const 17474462Salfred{ 17574462Salfred bool isDefault = false; 17674462Salfred 17774462Salfred BDirectory spoolDir(&fPrinterEntryRef); 17874462Salfred if (spoolDir.InitCheck() == B_OK) 17974462Salfred spoolDir.ReadAttr(PSRV_PRINTER_ATTR_DEFAULT_PRINTER, B_BOOL_TYPE, 0, 18074462Salfred &isDefault, sizeof(bool)); 18174462Salfred 18274462Salfred return isDefault; 18374462Salfred} 18474462Salfred 18574462Salfred 18674462Salfredbool 18774462SalfredBPrinter::IsShareable() const 18874462Salfred{ 18974462Salfred if (Name() == "Preview") 19074462Salfred return true; 19174462Salfred 19274462Salfred return false; 19374462Salfred} 19474462Salfred 19574462Salfred 19674462SalfredBString 19774462SalfredBPrinter::Name() const 19874462Salfred{ 19974462Salfred return _ReadAttribute(PSRV_PRINTER_ATTR_PRINTER_NAME); 20074462Salfred} 20174462Salfred 20274462Salfred 20374462SalfredBString 20474462SalfredBPrinter::State() const 20574462Salfred{ 20674462Salfred return _ReadAttribute(PSRV_PRINTER_ATTR_STATE); 20774462Salfred} 20874462Salfred 20974462Salfred 21074462SalfredBString 21174462SalfredBPrinter::Driver() const 21274462Salfred{ 21374462Salfred return _ReadAttribute(PSRV_PRINTER_ATTR_DRIVER_NAME); 21474462Salfred} 21574462Salfred 21674462Salfred 21774462SalfredBString 21874462SalfredBPrinter::Comments() const 21974462Salfred{ 22074462Salfred return _ReadAttribute(PSRV_PRINTER_ATTR_COMMENTS); 22174462Salfred} 22274462Salfred 22374462Salfred 22474462SalfredBString 22574462SalfredBPrinter::Transport() const 22674462Salfred{ 22774462Salfred return _ReadAttribute(PSRV_PRINTER_ATTR_TRANSPORT); 22874462Salfred} 22974462Salfred 23074462Salfred 23174462SalfredBString 23274462SalfredBPrinter::TransportAddress() const 23374462Salfred{ 23474462Salfred return _ReadAttribute(PSRV_PRINTER_ATTR_TRANSPORT_ADDRESS); 23574462Salfred} 23674462Salfred 23774462Salfred 23874462Salfredstatus_t 23974462SalfredBPrinter::DefaultSettings(BMessage& settings) 24074462Salfred{ 24174462Salfred status_t status = B_ERROR; 24274462Salfred image_id id = _LoadDriver(); 24374462Salfred if (id < 0) 24474462Salfred return status; 24574462Salfred 24674462Salfred typedef BMessage* (*default_settings_func_t)(BNode*); 24774462Salfred default_settings_func_t default_settings; 24874462Salfred if (get_image_symbol(id, "default_settings", B_SYMBOL_TYPE_TEXT 24974462Salfred , (void**)&default_settings) == B_OK) { 25074462Salfred BNode printerNode(&fPrinterEntryRef); 25174462Salfred BMessage *newSettings = default_settings(&printerNode); 25274462Salfred if (newSettings) { 25374462Salfred status = B_OK; 25474879Swpaul settings = *newSettings; 25578678Siedowse _AddPrinterName(settings); 25678678Siedowse } 25774462Salfred delete newSettings; 25874462Salfred } 25974462Salfred unload_add_on(id); 26074462Salfred return status; 261181344Sdfr} 262181344Sdfr 263181344Sdfr 26474462Salfredstatus_t 26574462SalfredBPrinter::StartWatching(const BMessenger& listener) 26674462Salfred{ 26774462Salfred StopWatching(); 26874462Salfred 269181344Sdfr if (!listener.IsValid()) 270181344Sdfr return B_BAD_VALUE; 27174462Salfred 27274462Salfred fListener = new(std::nothrow) BMessenger(listener); 27374462Salfred if (!fListener) 27474462Salfred return B_NO_MEMORY; 27574462Salfred 27674462Salfred node_ref nodeRef; 27774462Salfred nodeRef.device = fPrinterEntryRef.device; 27874462Salfred nodeRef.node = fPrinterEntryRef.directory; 27974462Salfred 28074462Salfred return watch_node(&nodeRef, B_WATCH_DIRECTORY, *fListener); 28174462Salfred} 28274462Salfred 28374462Salfred 28474462Salfredvoid 28574462SalfredBPrinter::StopWatching() 28674462Salfred{ 28774462Salfred if (fListener) { 28874462Salfred stop_watching(*fListener); 28974462Salfred delete fListener; 290105189Siedowse fListener = NULL; 291105189Siedowse } 29274462Salfred} 29374462Salfred 29474462Salfred 29574462SalfredBPrinter& 29674462SalfredBPrinter::operator=(const BPrinter& printer) 29774462Salfred{ 29874462Salfred if (this != &printer) { 29974462Salfred Unset(); 30074462Salfred fPrinterEntryRef = printer.fPrinterEntryRef; 30174462Salfred if (printer.fListener) 30274462Salfred StartWatching(*printer.fListener); 30374462Salfred } 30474462Salfred return *this; 30574462Salfred} 306287341Srodrigc 307287341Srodrigc 308287341Srodrigcbool 309287341SrodrigcBPrinter::operator==(const BPrinter& printer) const 310287341Srodrigc{ 311287341Srodrigc return (fPrinterEntryRef == printer.fPrinterEntryRef); 312287341Srodrigc} 313287341Srodrigc 314287341Srodrigc 31574462Salfredbool 316287341SrodrigcBPrinter::operator!=(const BPrinter& printer) const 317287341Srodrigc{ 31874462Salfred return (fPrinterEntryRef != printer.fPrinterEntryRef); 31974462Salfred} 32074462Salfred 321105189Siedowse 32274462Salfredstatus_t 32374462SalfredBPrinter::_Configure() const 32474462Salfred{ 32574462Salfred status_t status = B_ERROR; 326181344Sdfr image_id id = _LoadDriver(); 32774462Salfred if (id < 0) 32874462Salfred return status; 329105189Siedowse 330105189Siedowse BString printerName(_ReadAttribute(PSRV_PRINTER_ATTR_PRINTER_NAME)); 331105189Siedowse if (printerName.Length() > 0) { 33278678Siedowse typedef char* (*add_printer_func_t)(const char*); 33374462Salfred add_printer_func_t add_printer; 33474462Salfred if (get_image_symbol(id, "add_printer", B_SYMBOL_TYPE_TEXT 335278932Spfg , (void**)&add_printer) == B_OK) { 33674462Salfred if (add_printer(printerName.String()) != NULL) 337105189Siedowse status = B_OK; 33874879Swpaul } 33974462Salfred } else { 34090271Salfred status = B_ERROR; 34174462Salfred } 34274462Salfred unload_add_on(id); 34374462Salfred return status; 34474462Salfred} 34574462Salfred 34674462Salfred 34774462Salfredstatus_t 34874462SalfredBPrinter::_ConfigureJob(BMessage& settings) 34974462Salfred{ 35074462Salfred status_t status = B_ERROR; 35174462Salfred image_id id = _LoadDriver(); 35274462Salfred if (id < 0) 35374462Salfred return status; 35474462Salfred 35574462Salfred typedef BMessage* (*config_job_func_t)(BNode*, const BMessage*); 35674462Salfred config_job_func_t configure_job; 35774462Salfred if (get_image_symbol(id, "config_job", B_SYMBOL_TYPE_TEXT 35878678Siedowse , (void**)&configure_job) == B_OK) { 35978678Siedowse BNode printerNode(&fPrinterEntryRef); 36078678Siedowse BMessage *newSettings = configure_job(&printerNode, &settings); 36178678Siedowse if (newSettings && (newSettings->what == 'okok')) { 362105189Siedowse status = B_OK; 363105189Siedowse settings = *newSettings; 36478678Siedowse _AddPrinterName(settings); 36578678Siedowse } 36678678Siedowse delete newSettings; 36778678Siedowse } 36878678Siedowse unload_add_on(id); 36978678Siedowse return status; 37078678Siedowse} 37178678Siedowse 37278678Siedowse 37378678Siedowsestatus_t 37474462SalfredBPrinter::_ConfigurePage(BMessage& settings) 37574462Salfred{ 376105189Siedowse status_t status = B_ERROR; 377105189Siedowse image_id id = _LoadDriver(); 37874462Salfred if (id < 0) 379105189Siedowse return status; 380105189Siedowse 381105189Siedowse typedef BMessage* (*config_page_func_t)(BNode*, const BMessage*); 382105189Siedowse config_page_func_t configure_page; 383105189Siedowse if (get_image_symbol(id, "config_page", B_SYMBOL_TYPE_TEXT 384105189Siedowse , (void**)&configure_page) == B_OK) { 385105189Siedowse BNode printerNode(&fPrinterEntryRef); 386105189Siedowse BMessage *newSettings = configure_page(&printerNode, &settings); 387105189Siedowse if (newSettings && (newSettings->what == 'okok')) { 388105189Siedowse status = B_OK; 38974462Salfred settings = *newSettings; 390183039Sdfr _AddPrinterName(settings); 391183039Sdfr } 39274462Salfred delete newSettings; 39374462Salfred } 39474879Swpaul unload_add_on(id); 39574879Swpaul return status; 39674462Salfred} 397181344Sdfr 39874879Swpaul 399181344SdfrBPath 400181344SdfrBPrinter::_DriverPath() const 401181344Sdfr{ 402181344Sdfr BString driverName(_ReadAttribute(PSRV_PRINTER_ATTR_DRIVER_NAME)); 403181344Sdfr if (driverName.Length() <= 0) 40474879Swpaul return BPath(); 405181344Sdfr 406181344Sdfr directory_which directories[] = { 407181344Sdfr B_USER_ADDONS_DIRECTORY, 408181344Sdfr B_COMMON_ADDONS_DIRECTORY, 409181344Sdfr B_SYSTEM_ADDONS_DIRECTORY 410181344Sdfr }; 411181344Sdfr 412181344Sdfr BPath path; 413181344Sdfr driverName.Prepend("Print/"); 414181344Sdfr for (int32 i = 0; i < sizeof(directories) / sizeof(directories[0]); ++i) { 415181344Sdfr if (find_directory(directories[i], &path) == B_OK) { 416181344Sdfr path.Append(driverName.String()); 417181344Sdfr 418181344Sdfr BEntry driver(path.Path()); 419181344Sdfr if (driver.InitCheck() == B_OK && driver.Exists() && driver.IsFile()) 420181344Sdfr return path; 42174462Salfred } 42274462Salfred } 42374462Salfred return BPath(); 42474462Salfred} 42578678Siedowse 42674462Salfred 427105189Siedowseimage_id 428105189SiedowseBPrinter::_LoadDriver() const 42974462Salfred{ 43074462Salfred BPath driverPath(_DriverPath()); 43174462Salfred if (driverPath.InitCheck() != B_OK) 43274462Salfred return -1; 43374462Salfred 43474462Salfred return load_add_on(driverPath.Path()); 435105189Siedowse} 436105189Siedowse 43774462Salfred 43874879Swpaulvoid 43974879SwpaulBPrinter::_AddPrinterName(BMessage& settings) 44074879Swpaul{ 44174462Salfred settings.RemoveName(PSRV_FIELD_CURRENT_PRINTER); 44274462Salfred settings.AddString(PSRV_FIELD_CURRENT_PRINTER, Name()); 44374462Salfred} 44474462Salfred 44574462Salfred 44674462SalfredBString 447181344SdfrBPrinter::_ReadAttribute(const char* attribute) const 448181344Sdfr{ 449181344Sdfr BString value; 450181344Sdfr 451181344Sdfr BDirectory spoolDir(&fPrinterEntryRef); 452181344Sdfr if (spoolDir.InitCheck() == B_OK) 453181344Sdfr spoolDir.ReadAttrString(attribute, &value); 45474462Salfred 45574462Salfred return value; 456105189Siedowse} 457105189Siedowse 458105189Siedowse 459105189Siedowse } // namespace Print 460105189Siedowse} // namespace BPrivate 461105189Siedowse