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
PrinterDriverAddOn(const char * driver)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
~PrinterDriverAddOn()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
AddPrinter(const char * spoolFolderName)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
ConfigPage(BDirectory * spoolFolder,BMessage * settings)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
ConfigJob(BDirectory * spoolFolder,BMessage * settings)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
DefaultSettings(BDirectory * spoolFolder,BMessage * settings)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
TakeJob(const char * spoolFile,BDirectory * spoolFolder)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);
1467f4d1af4SSergei Reznikov parameters.AddInt32("file", (addr_t)&file);
1477f4d1af4SSergei Reznikov parameters.AddInt32("printer", (addr_t)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
FindPathToDriver(const char * driver,BPath * path)15961729fe2SMichael Pfeiffer PrinterDriverAddOn::FindPathToDriver(const char* driver, BPath* path)
16061729fe2SMichael Pfeiffer {
16161729fe2SMichael Pfeiffer status_t result;
1623dfd9cb9SOliver Tappe result = ::TestForAddonExistence(driver,
1633dfd9cb9SOliver Tappe B_USER_NONPACKAGED_ADDONS_DIRECTORY, kPrinterDriverFolderName, *path);
1643dfd9cb9SOliver Tappe if (result == B_OK)
1653dfd9cb9SOliver Tappe return B_OK;
1663dfd9cb9SOliver 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
1723dfd9cb9SOliver Tappe result = ::TestForAddonExistence(driver,
173*4b7e2196SIngo Weinhold B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, kPrinterDriverFolderName, *path);
17461729fe2SMichael Pfeiffer if (result == B_OK)
17561729fe2SMichael Pfeiffer return B_OK;
17661729fe2SMichael Pfeiffer
1773dfd9cb9SOliver Tappe result = ::TestForAddonExistence(driver, B_SYSTEM_ADDONS_DIRECTORY,
17861729fe2SMichael Pfeiffer kPrinterDriverFolderName, *path);
17961729fe2SMichael Pfeiffer return result;
18061729fe2SMichael Pfeiffer }
18161729fe2SMichael Pfeiffer
18261729fe2SMichael Pfeiffer
18361729fe2SMichael Pfeiffer bool
IsLoaded() const18461729fe2SMichael Pfeiffer PrinterDriverAddOn::IsLoaded() const
18561729fe2SMichael Pfeiffer {
18661729fe2SMichael Pfeiffer return fAddOnID > 0;
18761729fe2SMichael Pfeiffer }
18861729fe2SMichael Pfeiffer
18961729fe2SMichael Pfeiffer
19061729fe2SMichael Pfeiffer status_t
CopyValidSettings(BMessage * settings,BMessage * newSettings)19161729fe2SMichael Pfeiffer PrinterDriverAddOn::CopyValidSettings(BMessage* settings, BMessage* newSettings)
19261729fe2SMichael Pfeiffer {
19361729fe2SMichael Pfeiffer if (newSettings != NULL && newSettings->what != 'baad') {
19461729fe2SMichael Pfeiffer *settings = *newSettings;
19561729fe2SMichael Pfeiffer settings->what = 'okok';
19661729fe2SMichael Pfeiffer return B_OK;
19761729fe2SMichael Pfeiffer }
19861729fe2SMichael Pfeiffer return B_ERROR;
19961729fe2SMichael Pfeiffer }
200