1 /*
2 * Copyright 2010, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Michael Pfeiffer
7 */
8 #include "GPCapabilityExtractor.h"
9
10 #include "PrinterCap.h"
11
12
13 const char* kInputSlot = "InputSlot";
14
15
16 #if 1
17 #define GP_PRINT(...) \
18 fprintf(stderr, __VA_ARGS__)
19 #else
20 #define GP_PRINT(...) \
21 {}
22 #endif
23
GPCapabilityExtractor(GPCapabilities * capabilities)24 GPCapabilityExtractor::GPCapabilityExtractor(GPCapabilities* capabilities)
25 :
26 fState(kIgnoreParameter),
27 fCapabilities(capabilities),
28 fIndex(0),
29 fNextDriverSpecificCategoryID(PrinterCap::kDriverSpecificCapabilitiesBegin)
30 {
31
32 }
33
34
35 bool
BeginParameter(const char * name,const char * displayName,stp_parameter_class_t parameterClass)36 GPCapabilityExtractor::BeginParameter(const char* name, const char* displayName,
37 stp_parameter_class_t parameterClass)
38 {
39 fState = kIgnoreParameter;
40 if (strcmp(kPageSize, name) == 0) {
41 GP_PRINT("Supported parameter: %s\n", name);
42 fState = kExtractPageSizeParameter;
43 } else if (strcmp(kResolution, name) == 0) {
44 GP_PRINT("Supported parameter: %s\n", name);
45 fState = kExtractResolutionParameter;
46 } else if (strcmp(kInputSlot, name) == 0) {
47 GP_PRINT("Supported parameter: %s\n", name);
48 fState = kExtractInputSlotParameter;
49 } else if (strcmp(kPrintingMode, name) == 0) {
50 GP_PRINT("Supported parameter: %s\n", name);
51 fState = kExtractPrintingModeParameter;
52 } else {
53 GP_PRINT("Parameter: %s - %s\n", name, displayName);
54 if (!Supportsed(parameterClass))
55 return false;
56
57 fState = kExtractParameter;
58 DriverSpecificCap* capability = new DriverSpecificCap(displayName,
59 fNextDriverSpecificCategoryID, DriverSpecificCap::kList);
60 capability->fKey = name;
61
62 fDriverSpecificCategories.push_back(capability);
63 }
64 return true;
65 }
66
67
68 void
DefaultStringParameter(const char * name,const char * key)69 GPCapabilityExtractor::DefaultStringParameter(const char* name,
70 const char* key)
71 {
72 if (key == NULL)
73 fDefaultKey = "";
74 else
75 fDefaultKey = key;
76 }
77
78
79 void
StringParameterSize(const char * name,int size)80 GPCapabilityExtractor::StringParameterSize(const char* name, int size)
81 {
82 fIndex = 0;
83
84 switch (fState) {
85 case kExtractPageSizeParameter:
86 fCapabilities->fPageSizes.SetSize(size);
87 break;
88
89 case kExtractResolutionParameter:
90 fCapabilities->fResolutions.SetSize(size);
91 break;
92
93 case kExtractInputSlotParameter:
94 fCapabilities->fInputSlots.SetSize(size);
95 break;
96
97 case kExtractPrintingModeParameter:
98 fCapabilities->fPrintingModes.SetSize(size);
99 break;
100
101 case kExtractParameter:
102 fState = kExtractListParameter;
103 fCapabilities->fDriverSpecificCapabilities[
104 fNextDriverSpecificCategoryID].SetSize(size);
105 break;
106
107 default:
108 break;
109 }
110 }
111
112
113 void
StringParameter(const char * name,const char * key,const char * displayName)114 GPCapabilityExtractor::StringParameter(const char* name, const char* key,
115 const char* displayName)
116 {
117 bool isDefault = fDefaultKey == key;
118 EnumCap* capability;
119
120 switch (fState) {
121 case kExtractResolutionParameter:
122 GP_PRINT("GPCapabilityExtractor: ResolutionParameter expected\n");
123 break;
124
125 case kExtractInputSlotParameter:
126 capability = new PaperSourceCap(displayName, isDefault,
127 static_cast<JobData::PaperSource>(fIndex));
128 AddCapability(fCapabilities->fInputSlots, capability, key);
129 break;
130
131 case kExtractPrintingModeParameter:
132 capability = new ColorCap(displayName, isDefault,
133 static_cast<JobData::Color>(fIndex));
134 AddCapability(fCapabilities->fPrintingModes, capability, key);
135 break;
136
137 case kExtractListParameter:
138 capability = new ListItemCap(displayName, isDefault, fIndex);
139 AddCapability(fCapabilities->fDriverSpecificCapabilities[
140 fNextDriverSpecificCategoryID], capability, key);
141 break;
142
143 default:
144 break;
145 }
146
147 }
148
149
150 void
ResolutionParameter(const char * name,const char * key,const char * displayName,int x,int y)151 GPCapabilityExtractor::ResolutionParameter(const char* name, const char* key,
152 const char* displayName, int x, int y)
153 {
154 bool isDefault = fDefaultKey == key;
155 EnumCap* capability;
156 int resolution;
157
158 switch (fState) {
159 case kExtractResolutionParameter:
160 if (x <= 0 || y <= 0) {
161 // usually this is the entry for the "Default" resolution
162 // if we want to show this in the UI, we need a way to
163 // determine the resolution (x and y) for it, because
164 // libprint needs it for rasterization
165 fCapabilities->fResolutions.DecreaseSize();
166 break;
167 }
168
169 // TODO remove this workaround when libprint supports x != y too
170 // for now use the maximum resolution to render the page bands
171 resolution = max_c(x, y);
172
173 capability = new ResolutionCap(displayName, isDefault, fIndex,
174 resolution, resolution);
175 AddCapability(fCapabilities->fResolutions, capability, key);
176 break;
177
178 default:
179 break;
180 }
181 }
182
183
184 void
PageSizeParameter(const char * name,const char * key,const char * displayName,BSize pageSize,BRect imageableArea)185 GPCapabilityExtractor::PageSizeParameter(const char* name, const char* key,
186 const char* displayName, BSize pageSize, BRect imageableArea)
187 {
188 bool isDefault = fDefaultKey == key;
189 EnumCap* capability;
190
191 switch (fState) {
192 case kExtractPageSizeParameter:
193 capability = new PaperCap(displayName, isDefault,
194 static_cast<JobData::Paper>(fIndex),
195 BRect(0, 0, pageSize.width, pageSize.height),
196 imageableArea);
197 AddCapability(fCapabilities->fPageSizes, capability, key);
198 break;
199
200 default:
201 break;
202 }
203 }
204
205
206 void
EndParameter(const char * name)207 GPCapabilityExtractor::EndParameter(const char* name)
208 {
209 if (fState == kExtractListParameter) {
210 fNextDriverSpecificCategoryID ++;
211 }
212 }
213
214
215 void
BooleanParameter(const char * name,const char * displayName,bool defaultValue,stp_parameter_class_t parameterClass)216 GPCapabilityExtractor::BooleanParameter(const char* name,
217 const char* displayName, bool defaultValue,
218 stp_parameter_class_t parameterClass)
219 {
220 if (!Supportsed(parameterClass))
221 return;
222
223 BooleanCap* capability = new BooleanCap(displayName, defaultValue);
224 AddDriverSpecificCapability(name, displayName, DriverSpecificCap::kBoolean,
225 capability);
226 }
227
228
229 void
DoubleParameter(const char * name,const char * displayName,double lower,double upper,double defaultValue,stp_parameter_class_t parameterClass)230 GPCapabilityExtractor::DoubleParameter(const char* name,
231 const char* displayName, double lower, double upper, double defaultValue,
232 stp_parameter_class_t parameterClass)
233 {
234 if (!Supportsed(parameterClass))
235 return;
236
237 DoubleRangeCap* capability = new DoubleRangeCap(displayName, lower, upper,
238 defaultValue);
239 AddDriverSpecificCapability(name, displayName,
240 DriverSpecificCap::kDoubleRange, capability);
241 }
242
243
244 void
IntParameter(const char * name,const char * displayName,int lower,int upper,int defaultValue,stp_parameter_class_t parameterClass)245 GPCapabilityExtractor::IntParameter(const char* name, const char* displayName,
246 int lower, int upper, int defaultValue,
247 stp_parameter_class_t parameterClass)
248 {
249 if (!Supportsed(parameterClass))
250 return;
251
252 IntRangeCap* capability = new IntRangeCap(displayName, lower, upper,
253 defaultValue);
254 AddDriverSpecificCapability(name, displayName, DriverSpecificCap::kIntRange,
255 capability);
256 }
257
258
259 void
DimensionParameter(const char * name,const char * displayName,int lower,int upper,int defaultValue,stp_parameter_class_t parameterClass)260 GPCapabilityExtractor::DimensionParameter(const char* name,
261 const char* displayName, int lower, int upper, int defaultValue,
262 stp_parameter_class_t parameterClass)
263 {
264 if (!Supportsed(parameterClass))
265 return;
266
267 IntRangeCap* capability = new IntRangeCap(displayName, lower, upper,
268 defaultValue);
269 AddDriverSpecificCapability(name, displayName,
270 DriverSpecificCap::kIntDimension, capability);
271 }
272
273
274 void
EndVisit()275 GPCapabilityExtractor::EndVisit()
276 {
277 if (fCapabilities->fInputSlots.Size() == 0)
278 AddDefaultInputSlot();
279 SetDriverSpecificCategories();
280 }
281
282
283 bool
Supportsed(stp_parameter_class_t parameterClass)284 GPCapabilityExtractor::Supportsed(stp_parameter_class_t parameterClass)
285 {
286 return parameterClass == STP_PARAMETER_CLASS_FEATURE
287 || parameterClass == STP_PARAMETER_CLASS_OUTPUT;
288 }
289
290
291 void
AddDefaultInputSlot()292 GPCapabilityExtractor::AddDefaultInputSlot()
293 {
294 BeginParameter(kInputSlot, "Input Slot", STP_PARAMETER_CLASS_FEATURE);
295 DefaultStringParameter(kInputSlot, "");
296 StringParameterSize(kInputSlot, 1);
297 StringParameter(kInputSlot, "", "Default");
298 EndParameter(kInputSlot);
299 }
300
301
302 void
SetDriverSpecificCategories()303 GPCapabilityExtractor::SetDriverSpecificCategories()
304 {
305 int size = fDriverSpecificCategories.size();
306 if (size == 0)
307 return;
308
309 fCapabilities->fDriverSpecificCategories.SetSize(size);
310 struct BaseCap** array = fCapabilities->fDriverSpecificCategories.Array();
311 list<DriverSpecificCap*>::iterator it = fDriverSpecificCategories.begin();
312 for (int index = 0; it != fDriverSpecificCategories.end(); it ++,
313 index ++) {
314 array[index] = *it;
315 }
316 }
317
318 void
AddCapability(GPArray<struct BaseCap> & array,EnumCap * capability,const char * key)319 GPCapabilityExtractor::AddCapability(GPArray<struct BaseCap>& array,
320 EnumCap* capability, const char* key)
321 {
322 capability->fKey = key;
323 array.Array()[fIndex] = capability;
324 fIndex ++;
325 }
326
327
328 void
AddDriverSpecificCapability(const char * name,const char * displayName,DriverSpecificCap::Type type,BaseCap * capability)329 GPCapabilityExtractor::AddDriverSpecificCapability(const char* name,
330 const char* displayName, DriverSpecificCap::Type type, BaseCap* capability)
331 {
332 DriverSpecificCap* parent = new DriverSpecificCap(displayName,
333 fNextDriverSpecificCategoryID, type);
334 parent->fKey = name;
335
336 fDriverSpecificCategories.push_back(parent);
337
338 GPArray<struct BaseCap>& array = fCapabilities->fDriverSpecificCapabilities
339 [fNextDriverSpecificCategoryID];
340 array.SetSize(1);
341 array.Array()[0] = capability;
342
343 fNextDriverSpecificCategoryID++;
344 }
345