1/* 2 * Copyright 2001-2010, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar R. Adema 7 * Michael Pfeiffer 8 */ 9#include "PrinterDriverAddOn.h" 10 11#include <File.h> 12 13#include "BeUtils.h" 14#include "pr_server.h" 15 16 17typedef BMessage* (*config_func_t)(BNode*, const BMessage*); 18typedef BMessage* (*take_job_func_t)(BFile*, BNode*, const BMessage*); 19typedef char* (*add_printer_func_t)(const char* printer_name); 20typedef BMessage* (*default_settings_t)(BNode*); 21 22static const char* kPrinterDriverFolderName = "Print"; 23 24 25PrinterDriverAddOn::PrinterDriverAddOn(const char* driver) 26 : 27 fAddOnID(-1) 28{ 29 BPath path; 30 status_t result; 31 result = FindPathToDriver(driver, &path); 32 if (result != B_OK) 33 return; 34 35 fAddOnID = ::load_add_on(path.Path()); 36} 37 38 39PrinterDriverAddOn::~PrinterDriverAddOn() 40{ 41 if (IsLoaded()) { 42 unload_add_on(fAddOnID); 43 fAddOnID = -1; 44 } 45} 46 47 48status_t 49PrinterDriverAddOn::AddPrinter(const char* spoolFolderName) 50{ 51 if (!IsLoaded()) 52 return B_ERROR; 53 54 add_printer_func_t func; 55 status_t result = get_image_symbol(fAddOnID, "add_printer", 56 B_SYMBOL_TYPE_TEXT, (void**)&func); 57 if (result != B_OK) 58 return result; 59 60 if ((*func)(spoolFolderName) == NULL) 61 return B_ERROR; 62 return B_OK; 63} 64 65 66status_t 67PrinterDriverAddOn::ConfigPage(BDirectory* spoolFolder, BMessage* settings) 68{ 69 if (!IsLoaded()) 70 return B_ERROR; 71 72 config_func_t func; 73 status_t result = get_image_symbol(fAddOnID, "config_page", 74 B_SYMBOL_TYPE_TEXT, (void**)&func); 75 if (result != B_OK) 76 return result; 77 78 BMessage* newSettings = (*func)(spoolFolder, settings); 79 result = CopyValidSettings(settings, newSettings); 80 delete newSettings; 81 82 return result; 83} 84 85 86status_t 87PrinterDriverAddOn::ConfigJob(BDirectory* spoolFolder, BMessage* settings) 88{ 89 if (!IsLoaded()) 90 return B_ERROR; 91 92 config_func_t func; 93 status_t result = get_image_symbol(fAddOnID, "config_job", 94 B_SYMBOL_TYPE_TEXT, (void**)&func); 95 if (result != B_OK) 96 return result; 97 98 BMessage* newSettings = (*func)(spoolFolder, settings); 99 result = CopyValidSettings(settings, newSettings); 100 delete newSettings; 101 102 return result; 103} 104 105 106status_t 107PrinterDriverAddOn::DefaultSettings(BDirectory* spoolFolder, BMessage* settings) 108{ 109 if (!IsLoaded()) 110 return B_ERROR; 111 112 default_settings_t func; 113 status_t result = get_image_symbol(fAddOnID, "default_settings", 114 B_SYMBOL_TYPE_TEXT, (void**)&func); 115 if (result != B_OK) 116 return result; 117 118 BMessage* newSettings = (*func)(spoolFolder); 119 if (newSettings != NULL) { 120 *settings = *newSettings; 121 settings->what = 'okok'; 122 } else 123 result = B_ERROR; 124 delete newSettings; 125 126 return result; 127} 128 129 130status_t 131PrinterDriverAddOn::TakeJob(const char* spoolFile, BDirectory* spoolFolder) 132{ 133 if (!IsLoaded()) 134 return B_ERROR; 135 136 BFile file(spoolFile, B_READ_WRITE); 137 take_job_func_t func; 138 status_t result = get_image_symbol(fAddOnID, "take_job", B_SYMBOL_TYPE_TEXT, 139 (void**)&func); 140 if (result != B_OK) 141 return result; 142 143 // This seems to be required for legacy? 144 // HP PCL3 add-on crashes without it! 145 BMessage parameters(B_REFS_RECEIVED); 146 parameters.AddInt32("file", (addr_t)&file); 147 parameters.AddInt32("printer", (addr_t)spoolFolder); 148 149 BMessage* message = (*func)(&file, spoolFolder, ¶meters); 150 if (message == NULL || message->what != 'okok') 151 result = B_ERROR; 152 delete message; 153 154 return result; 155} 156 157 158status_t 159PrinterDriverAddOn::FindPathToDriver(const char* driver, BPath* path) 160{ 161 status_t result; 162 result = ::TestForAddonExistence(driver, 163 B_USER_NONPACKAGED_ADDONS_DIRECTORY, kPrinterDriverFolderName, *path); 164 if (result == B_OK) 165 return B_OK; 166 167 result = ::TestForAddonExistence(driver, B_USER_ADDONS_DIRECTORY, 168 kPrinterDriverFolderName, *path); 169 if (result == B_OK) 170 return B_OK; 171 172 result = ::TestForAddonExistence(driver, 173 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, kPrinterDriverFolderName, *path); 174 if (result == B_OK) 175 return B_OK; 176 177 result = ::TestForAddonExistence(driver, B_SYSTEM_ADDONS_DIRECTORY, 178 kPrinterDriverFolderName, *path); 179 return result; 180} 181 182 183bool 184PrinterDriverAddOn::IsLoaded() const 185{ 186 return fAddOnID > 0; 187} 188 189 190status_t 191PrinterDriverAddOn::CopyValidSettings(BMessage* settings, BMessage* newSettings) 192{ 193 if (newSettings != NULL && newSettings->what != 'baad') { 194 *settings = *newSettings; 195 settings->what = 'okok'; 196 return B_OK; 197 } 198 return B_ERROR; 199} 200