xref: /haiku/src/kits/print/PrinterDriverAddOn.cpp (revision 4b7e219688450694efc9d1890f83f816758c16d3)
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, &parameters);
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