vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / print / drivers / gutenprint / GPParameterVisitor.cpp
blob78ee7167a1607c3a75a441c8a8d0034560efd0d7
1 /*
2 * Copyright 2010, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Michael Pfeiffer
7 */
8 #include "GPParameterVisitor.h"
10 #include <String.h>
13 const char* kJobMode = "JobMode";
14 const char* kJob = "Job";
16 const char* kPrintingMode = "PrintingMode";
17 const char* kColor = "Color";
18 const char* kBlackAndWhite = "BW";
20 const char* kResolution = "Resolution";
21 const char* kFakeResolutionKey = "";
23 const char* kPageSize = "PageSize";
25 const char* kChannelBitDepth = "ChannelBitDepth";
28 GPParameterVisitor::GPParameterVisitor()
30 fVariables(NULL),
31 fHasResolutionParameter(false)
36 GPParameterVisitor::~GPParameterVisitor()
41 void
42 GPParameterVisitor::Visit(const stp_printer_t* printer)
44 // this code is based on Gutenprint printer_options.c
45 const stp_vars_t* defaultVariables = stp_printer_get_defaults(printer);
46 stp_vars_t* variables = stp_vars_create_copy(defaultVariables);
47 fVariables = variables;
49 stp_set_string_parameter(variables, kJobMode, kJob);
51 stp_parameter_t printingMode;
52 stp_describe_parameter(variables, kPrintingMode, &printingMode);
53 bool isColorPrinter = stp_string_list_is_present(printingMode.bounds.str,
54 kColor) != 0;
55 stp_parameter_description_destroy(&printingMode);
57 if (isColorPrinter)
58 stp_set_string_parameter(variables, kPrintingMode, kColor);
59 else
60 stp_set_string_parameter(variables, kPrintingMode, kBlackAndWhite);
62 stp_set_string_parameter(variables, kChannelBitDepth, "8");
64 stp_parameter_list_t list = stp_get_parameter_list(variables);
65 int size = stp_parameter_list_count(list);
67 for (int i = 0; i < size; i ++) {
68 const stp_parameter_t* parameter = stp_parameter_list_param(list, i);
69 stp_parameter_t description;
70 stp_describe_parameter(fVariables, parameter->name, &description);
71 VisitParameter(list, parameter, &description);
72 stp_parameter_description_destroy(&description);
75 // TODO check if this can really happen
76 if (!fHasResolutionParameter) {
77 AddMissingResolution();
80 EndVisit();
82 stp_parameter_list_destroy(list);
83 stp_vars_destroy(variables);
84 fVariables = NULL;
88 void
89 GPParameterVisitor::AddMissingResolution()
91 // some printer definitions don't have resolution parameter
92 // however "libprint" needs to know it for rasterization
94 // TODO find out if other parameters influence the resolution
95 // e.g. color vs black and white
96 int x, y;
97 stp_describe_resolution(fVariables, &x, &y);
99 BeginParameter(kResolution, "Resolution", STP_PARAMETER_CLASS_FEATURE);
100 DefaultStringParameter(kResolution, kFakeResolutionKey);
101 StringParameterSize(kResolution, 1);
103 if (x <= 0 || y <= 0) {
104 // TODO decide if more resolutions (150, 600) should be possible
105 x = 300;
106 y = 300;
109 BString displayName;
110 if (x != y)
111 displayName << x << " x " << y << " DPI";
112 else
113 displayName << x << " DPI";
115 ResolutionParameter(kResolution, kFakeResolutionKey, displayName.String(),
116 x, y);
118 EndParameter(kResolution);
122 void
123 GPParameterVisitor::VisitParameter(stp_parameter_list_t list,
124 const stp_parameter_t* parameter, stp_parameter_t* description)
126 // TODO decide which parameters should be revealed to user
127 // e.g. up to STP_PARAMETER_LEVEL_ADVANCED4;
128 // const stp_parameter_level_t kMaxLevel = STP_PARAMETER_LEVEL_ADVANCED4;
129 const stp_parameter_level_t kMaxLevel = STP_PARAMETER_LEVEL_BASIC;
130 stp_parameter_class_t parameterClass = parameter->p_class;
131 if (parameter->read_only ||
132 (parameter->p_level > kMaxLevel
133 && strcmp(parameter->name, kResolution) != 0)
134 || (parameterClass != STP_PARAMETER_CLASS_OUTPUT
135 && parameterClass != STP_PARAMETER_CLASS_CORE
136 && parameterClass != STP_PARAMETER_CLASS_FEATURE))
137 return;
139 if (!description->is_active)
140 return;
142 switch (description->p_type) {
143 case STP_PARAMETER_TYPE_STRING_LIST:
144 if (!BeginParameter(description->name, description->text,
145 parameterClass))
146 return;
147 VisitStringList(description);
148 EndParameter(description->name);
149 break;
151 case STP_PARAMETER_TYPE_BOOLEAN:
152 VisitBooleanParameter(description, parameterClass);
153 break;
155 case STP_PARAMETER_TYPE_DOUBLE:
156 VisitDoubleParameter(description, parameterClass);
157 break;
159 case STP_PARAMETER_TYPE_INT:
160 VisitIntParameter(description, parameterClass);
161 break;
163 case STP_PARAMETER_TYPE_DIMENSION:
164 VisitDimensionParameter(description, parameterClass);
165 break;
167 default:
168 break;
174 void
175 GPParameterVisitor::VisitStringList(stp_parameter_t* parameter)
177 stp_string_list_t* list = parameter->bounds.str;
178 int count = stp_string_list_count(list);
179 if (count <= 0)
180 return;
182 const char* name = parameter->name;
183 if (parameter->is_mandatory)
184 DefaultStringParameter(name, parameter->deflt.str);
185 else
186 DefaultStringParameter(name, NULL);
188 StringParameterSize(name, count);
190 for (int i = 0; i < count; i ++) {
191 const stp_param_string_t* entry = stp_string_list_param(list, i);
192 const char* key = entry->name;
193 const char* displayName = entry->text;
194 if (strcmp(name, kResolution) == 0) {
195 stp_set_string_parameter(fVariables, kResolution, key);
197 int x, y;
198 stp_describe_resolution(fVariables, &x, &y);
200 ResolutionParameter(name, key, displayName, x, y);
202 fHasResolutionParameter = true;
203 } else if (strcmp(name, kPageSize) == 0) {
204 stp_set_string_parameter(fVariables, kPageSize, key);
206 int width;
207 int height;
208 stp_get_media_size(fVariables, &width, &height);
209 BSize pageSize(width, height);
211 int left, right, top, bottom;
212 stp_get_imageable_area(fVariables, &left, &right, &bottom, &top);
213 BRect imageableArea(left, top, right, bottom);
215 PageSizeParameter(name, key, displayName, pageSize, imageableArea);
216 } else {
217 StringParameter(name, key, displayName);
223 void
224 GPParameterVisitor::VisitBooleanParameter(stp_parameter_t* description,
225 stp_parameter_class_t parameterClass)
227 bool defaultValue = true;
228 if (description->is_mandatory)
229 defaultValue = description->deflt.boolean;
230 BooleanParameter(description->name, description->text, defaultValue,
231 parameterClass);
235 void
236 GPParameterVisitor::VisitDoubleParameter(stp_parameter_t* description,
237 stp_parameter_class_t parameterClass)
239 const char* name = description->name;
240 const char* text = description->text;
241 double lower = description->bounds.dbl.lower;
242 double upper = description->bounds.dbl.upper;
243 double defaultValue = description->deflt.dbl;
244 if (lower <= defaultValue && defaultValue <= upper)
245 DoubleParameter(name, text, lower, upper, defaultValue, parameterClass);
249 void
250 GPParameterVisitor::VisitIntParameter(stp_parameter_t* description,
251 stp_parameter_class_t parameterClass)
253 const char* name = description->name;
254 const char* text = description->text;
255 int lower = description->bounds.integer.lower;
256 int upper = description->bounds.integer.upper;
257 int defaultValue = description->deflt.integer;
258 if (lower <= defaultValue && defaultValue <= upper)
259 IntParameter(name, text, lower, upper, defaultValue, parameterClass);
263 void
264 GPParameterVisitor::VisitDimensionParameter(stp_parameter_t* description,
265 stp_parameter_class_t parameterClass)
267 const char* name = description->name;
268 const char* text = description->text;
269 int lower = description->bounds.dimension.lower;
270 int upper = description->bounds.dimension.upper;
271 int defaultValue = description->deflt.dimension;
272 if (lower <= defaultValue && defaultValue <= upper)
273 DimensionParameter(name, text, lower, upper, defaultValue,
274 parameterClass);