xref: /haiku/src/kits/print/PrinterDriverAddOn.cpp (revision 4b7e219688450694efc9d1890f83f816758c16d3)
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 
PrinterDriverAddOn(const char * driver)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 
~PrinterDriverAddOn()39 PrinterDriverAddOn::~PrinterDriverAddOn()
40 {
41 	if (IsLoaded()) {
42 		unload_add_on(fAddOnID);
43 		fAddOnID = -1;
44 	}
45 }
46 
47 
48 status_t
AddPrinter(const char * spoolFolderName)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
ConfigPage(BDirectory * spoolFolder,BMessage * settings)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
ConfigJob(BDirectory * spoolFolder,BMessage * settings)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
DefaultSettings(BDirectory * spoolFolder,BMessage * settings)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
TakeJob(const char * spoolFile,BDirectory * spoolFolder)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, &parameters);
150 	if (message == NULL || message->what != 'okok')
151 		result = B_ERROR;
152 	delete message;
153 
154 	return result;
155 }
156 
157 
158 status_t
FindPathToDriver(const char * driver,BPath * path)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
IsLoaded() const184 PrinterDriverAddOn::IsLoaded() const
185 {
186 	return fAddOnID > 0;
187 }
188 
189 
190 status_t
CopyValidSettings(BMessage * settings,BMessage * newSettings)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