161729fe2SMichael Pfeiffer /* 261729fe2SMichael Pfeiffer * Copyright 2001-2010, Haiku, Inc. All rights reserved. 361729fe2SMichael Pfeiffer * Distributed under the terms of the MIT License. 461729fe2SMichael Pfeiffer * 561729fe2SMichael Pfeiffer * Authors: 661729fe2SMichael Pfeiffer * Ithamar R. Adema 761729fe2SMichael Pfeiffer * Michael Pfeiffer 861729fe2SMichael Pfeiffer */ 961729fe2SMichael Pfeiffer #include "PrinterDriverAddOn.h" 1061729fe2SMichael Pfeiffer 1161729fe2SMichael Pfeiffer #include <File.h> 1261729fe2SMichael Pfeiffer 1361729fe2SMichael Pfeiffer #include "BeUtils.h" 1461729fe2SMichael Pfeiffer #include "pr_server.h" 1561729fe2SMichael Pfeiffer 1661729fe2SMichael Pfeiffer 1761729fe2SMichael Pfeiffer typedef BMessage* (*config_func_t)(BNode*, const BMessage*); 1861729fe2SMichael Pfeiffer typedef BMessage* (*take_job_func_t)(BFile*, BNode*, const BMessage*); 1961729fe2SMichael Pfeiffer typedef char* (*add_printer_func_t)(const char* printer_name); 2061729fe2SMichael Pfeiffer typedef BMessage* (*default_settings_t)(BNode*); 2161729fe2SMichael Pfeiffer 2261729fe2SMichael Pfeiffer static const char* kPrinterDriverFolderName = "Print"; 2361729fe2SMichael Pfeiffer 2461729fe2SMichael Pfeiffer 2561729fe2SMichael Pfeiffer PrinterDriverAddOn::PrinterDriverAddOn(const char* driver) 2661729fe2SMichael Pfeiffer : 2761729fe2SMichael Pfeiffer fAddOnID(-1) 2861729fe2SMichael Pfeiffer { 2961729fe2SMichael Pfeiffer BPath path; 3061729fe2SMichael Pfeiffer status_t result; 3161729fe2SMichael Pfeiffer result = FindPathToDriver(driver, &path); 3261729fe2SMichael Pfeiffer if (result != B_OK) 3361729fe2SMichael Pfeiffer return; 3461729fe2SMichael Pfeiffer 3561729fe2SMichael Pfeiffer fAddOnID = ::load_add_on(path.Path()); 3661729fe2SMichael Pfeiffer } 3761729fe2SMichael Pfeiffer 3861729fe2SMichael Pfeiffer 3961729fe2SMichael Pfeiffer PrinterDriverAddOn::~PrinterDriverAddOn() 4061729fe2SMichael Pfeiffer { 4161729fe2SMichael Pfeiffer if (IsLoaded()) { 4261729fe2SMichael Pfeiffer unload_add_on(fAddOnID); 4361729fe2SMichael Pfeiffer fAddOnID = -1; 4461729fe2SMichael Pfeiffer } 4561729fe2SMichael Pfeiffer } 4661729fe2SMichael Pfeiffer 4761729fe2SMichael Pfeiffer 4861729fe2SMichael Pfeiffer status_t 4961729fe2SMichael Pfeiffer PrinterDriverAddOn::AddPrinter(const char* spoolFolderName) 5061729fe2SMichael Pfeiffer { 5161729fe2SMichael Pfeiffer if (!IsLoaded()) 5261729fe2SMichael Pfeiffer return B_ERROR; 5361729fe2SMichael Pfeiffer 5461729fe2SMichael Pfeiffer add_printer_func_t func; 5561729fe2SMichael Pfeiffer status_t result = get_image_symbol(fAddOnID, "add_printer", 5661729fe2SMichael Pfeiffer B_SYMBOL_TYPE_TEXT, (void**)&func); 5761729fe2SMichael Pfeiffer if (result != B_OK) 5861729fe2SMichael Pfeiffer return result; 5961729fe2SMichael Pfeiffer 6061729fe2SMichael Pfeiffer if ((*func)(spoolFolderName) == NULL) 6161729fe2SMichael Pfeiffer return B_ERROR; 6261729fe2SMichael Pfeiffer return B_OK; 6361729fe2SMichael Pfeiffer } 6461729fe2SMichael Pfeiffer 6561729fe2SMichael Pfeiffer 6661729fe2SMichael Pfeiffer status_t 6761729fe2SMichael Pfeiffer PrinterDriverAddOn::ConfigPage(BDirectory* spoolFolder, BMessage* settings) 6861729fe2SMichael Pfeiffer { 6961729fe2SMichael Pfeiffer if (!IsLoaded()) 7061729fe2SMichael Pfeiffer return B_ERROR; 7161729fe2SMichael Pfeiffer 7261729fe2SMichael Pfeiffer config_func_t func; 7361729fe2SMichael Pfeiffer status_t result = get_image_symbol(fAddOnID, "config_page", 7461729fe2SMichael Pfeiffer B_SYMBOL_TYPE_TEXT, (void**)&func); 7561729fe2SMichael Pfeiffer if (result != B_OK) 7661729fe2SMichael Pfeiffer return result; 7761729fe2SMichael Pfeiffer 7861729fe2SMichael Pfeiffer BMessage* newSettings = (*func)(spoolFolder, settings); 7961729fe2SMichael Pfeiffer result = CopyValidSettings(settings, newSettings); 8061729fe2SMichael Pfeiffer delete newSettings; 8161729fe2SMichael Pfeiffer 8261729fe2SMichael Pfeiffer return result; 8361729fe2SMichael Pfeiffer } 8461729fe2SMichael Pfeiffer 8561729fe2SMichael Pfeiffer 8661729fe2SMichael Pfeiffer status_t 8761729fe2SMichael Pfeiffer PrinterDriverAddOn::ConfigJob(BDirectory* spoolFolder, BMessage* settings) 8861729fe2SMichael Pfeiffer { 8961729fe2SMichael Pfeiffer if (!IsLoaded()) 9061729fe2SMichael Pfeiffer return B_ERROR; 9161729fe2SMichael Pfeiffer 9261729fe2SMichael Pfeiffer config_func_t func; 9361729fe2SMichael Pfeiffer status_t result = get_image_symbol(fAddOnID, "config_job", 9461729fe2SMichael Pfeiffer B_SYMBOL_TYPE_TEXT, (void**)&func); 9561729fe2SMichael Pfeiffer if (result != B_OK) 9661729fe2SMichael Pfeiffer return result; 9761729fe2SMichael Pfeiffer 9861729fe2SMichael Pfeiffer BMessage* newSettings = (*func)(spoolFolder, settings); 9961729fe2SMichael Pfeiffer result = CopyValidSettings(settings, newSettings); 10061729fe2SMichael Pfeiffer delete newSettings; 10161729fe2SMichael Pfeiffer 10261729fe2SMichael Pfeiffer return result; 10361729fe2SMichael Pfeiffer } 10461729fe2SMichael Pfeiffer 10561729fe2SMichael Pfeiffer 10661729fe2SMichael Pfeiffer status_t 10761729fe2SMichael Pfeiffer PrinterDriverAddOn::DefaultSettings(BDirectory* spoolFolder, BMessage* settings) 10861729fe2SMichael Pfeiffer { 10961729fe2SMichael Pfeiffer if (!IsLoaded()) 11061729fe2SMichael Pfeiffer return B_ERROR; 11161729fe2SMichael Pfeiffer 11261729fe2SMichael Pfeiffer default_settings_t func; 11361729fe2SMichael Pfeiffer status_t result = get_image_symbol(fAddOnID, "default_settings", 11461729fe2SMichael Pfeiffer B_SYMBOL_TYPE_TEXT, (void**)&func); 11561729fe2SMichael Pfeiffer if (result != B_OK) 11661729fe2SMichael Pfeiffer return result; 11761729fe2SMichael Pfeiffer 11861729fe2SMichael Pfeiffer BMessage* newSettings = (*func)(spoolFolder); 11961729fe2SMichael Pfeiffer if (newSettings != NULL) { 12061729fe2SMichael Pfeiffer *settings = *newSettings; 12161729fe2SMichael Pfeiffer settings->what = 'okok'; 12261729fe2SMichael Pfeiffer } else 12361729fe2SMichael Pfeiffer result = B_ERROR; 12461729fe2SMichael Pfeiffer delete newSettings; 12561729fe2SMichael Pfeiffer 12661729fe2SMichael Pfeiffer return result; 12761729fe2SMichael Pfeiffer } 12861729fe2SMichael Pfeiffer 12961729fe2SMichael Pfeiffer 13061729fe2SMichael Pfeiffer status_t 13161729fe2SMichael Pfeiffer PrinterDriverAddOn::TakeJob(const char* spoolFile, BDirectory* spoolFolder) 13261729fe2SMichael Pfeiffer { 13361729fe2SMichael Pfeiffer if (!IsLoaded()) 13461729fe2SMichael Pfeiffer return B_ERROR; 13561729fe2SMichael Pfeiffer 13661729fe2SMichael Pfeiffer BFile file(spoolFile, B_READ_WRITE); 13761729fe2SMichael Pfeiffer take_job_func_t func; 13861729fe2SMichael Pfeiffer status_t result = get_image_symbol(fAddOnID, "take_job", B_SYMBOL_TYPE_TEXT, 13961729fe2SMichael Pfeiffer (void**)&func); 14061729fe2SMichael Pfeiffer if (result != B_OK) 14161729fe2SMichael Pfeiffer return result; 14261729fe2SMichael Pfeiffer 14361729fe2SMichael Pfeiffer // This seems to be required for legacy? 14461729fe2SMichael Pfeiffer // HP PCL3 add-on crashes without it! 14561729fe2SMichael Pfeiffer BMessage parameters(B_REFS_RECEIVED); 14661729fe2SMichael Pfeiffer parameters.AddInt32("file", (int32)&file); 14761729fe2SMichael Pfeiffer parameters.AddInt32("printer", (int32)spoolFolder); 14861729fe2SMichael Pfeiffer 14961729fe2SMichael Pfeiffer BMessage* message = (*func)(&file, spoolFolder, ¶meters); 15061729fe2SMichael Pfeiffer if (message == NULL || message->what != 'okok') 15161729fe2SMichael Pfeiffer result = B_ERROR; 15261729fe2SMichael Pfeiffer delete message; 15361729fe2SMichael Pfeiffer 15461729fe2SMichael Pfeiffer return result; 15561729fe2SMichael Pfeiffer } 15661729fe2SMichael Pfeiffer 15761729fe2SMichael Pfeiffer 15861729fe2SMichael Pfeiffer status_t 15961729fe2SMichael Pfeiffer PrinterDriverAddOn::FindPathToDriver(const char* driver, BPath* path) 16061729fe2SMichael Pfeiffer { 16161729fe2SMichael Pfeiffer status_t result; 162*3dfd9cb9SOliver Tappe result = ::TestForAddonExistence(driver, 163*3dfd9cb9SOliver Tappe B_USER_NONPACKAGED_ADDONS_DIRECTORY, kPrinterDriverFolderName, *path); 164*3dfd9cb9SOliver Tappe if (result == B_OK) 165*3dfd9cb9SOliver Tappe return B_OK; 166*3dfd9cb9SOliver Tappe 16761729fe2SMichael Pfeiffer result = ::TestForAddonExistence(driver, B_USER_ADDONS_DIRECTORY, 16861729fe2SMichael Pfeiffer kPrinterDriverFolderName, *path); 16961729fe2SMichael Pfeiffer if (result == B_OK) 17061729fe2SMichael Pfeiffer return B_OK; 17161729fe2SMichael Pfeiffer 172*3dfd9cb9SOliver Tappe result = ::TestForAddonExistence(driver, 173*3dfd9cb9SOliver Tappe B_COMMON_NONPACKAGED_ADDONS_DIRECTORY, kPrinterDriverFolderName, *path); 174*3dfd9cb9SOliver Tappe if (result == B_OK) 175*3dfd9cb9SOliver Tappe return B_OK; 176*3dfd9cb9SOliver Tappe 17761729fe2SMichael Pfeiffer result = ::TestForAddonExistence(driver, B_COMMON_ADDONS_DIRECTORY, 17861729fe2SMichael Pfeiffer kPrinterDriverFolderName, *path); 17961729fe2SMichael Pfeiffer if (result == B_OK) 18061729fe2SMichael Pfeiffer return B_OK; 18161729fe2SMichael Pfeiffer 182*3dfd9cb9SOliver Tappe result = ::TestForAddonExistence(driver, B_SYSTEM_ADDONS_DIRECTORY, 18361729fe2SMichael Pfeiffer kPrinterDriverFolderName, *path); 18461729fe2SMichael Pfeiffer return result; 18561729fe2SMichael Pfeiffer } 18661729fe2SMichael Pfeiffer 18761729fe2SMichael Pfeiffer 18861729fe2SMichael Pfeiffer bool 18961729fe2SMichael Pfeiffer PrinterDriverAddOn::IsLoaded() const 19061729fe2SMichael Pfeiffer { 19161729fe2SMichael Pfeiffer return fAddOnID > 0; 19261729fe2SMichael Pfeiffer } 19361729fe2SMichael Pfeiffer 19461729fe2SMichael Pfeiffer 19561729fe2SMichael Pfeiffer status_t 19661729fe2SMichael Pfeiffer PrinterDriverAddOn::CopyValidSettings(BMessage* settings, BMessage* newSettings) 19761729fe2SMichael Pfeiffer { 19861729fe2SMichael Pfeiffer if (newSettings != NULL && newSettings->what != 'baad') { 19961729fe2SMichael Pfeiffer *settings = *newSettings; 20061729fe2SMichael Pfeiffer settings->what = 'okok'; 20161729fe2SMichael Pfeiffer return B_OK; 20261729fe2SMichael Pfeiffer } 20361729fe2SMichael Pfeiffer return B_ERROR; 20461729fe2SMichael Pfeiffer } 205