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 17 typedef BMessage* (*config_func_t)(BNode*, const BMessage*); 18 typedef BMessage* (*take_job_func_t)(BFile*, BNode*, const BMessage*); 19 typedef char* (*add_printer_func_t)(const char* printer_name); 20 typedef BMessage* (*default_settings_t)(BNode*); 21 22 static const char* kPrinterDriverFolderName = "Print"; 23 24 25 PrinterDriverAddOn::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 39 PrinterDriverAddOn::~PrinterDriverAddOn() 40 { 41 if (IsLoaded()) { 42 unload_add_on(fAddOnID); 43 fAddOnID = -1; 44 } 45 } 46 47 48 status_t 49 PrinterDriverAddOn::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 66 status_t 67 PrinterDriverAddOn::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 86 status_t 87 PrinterDriverAddOn::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 106 status_t 107 PrinterDriverAddOn::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 130 status_t 131 PrinterDriverAddOn::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 158 status_t 159 PrinterDriverAddOn::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 183 bool 184 PrinterDriverAddOn::IsLoaded() const 185 { 186 return fAddOnID > 0; 187 } 188 189 190 status_t 191 PrinterDriverAddOn::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