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, ¶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
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