]>
Commit | Line | Data |
---|---|---|
ac884b6a | 1 | // |
503b54c9 | 2 | // PPD file import methods for the CUPS PPD Compiler. |
ac884b6a | 3 | // |
503b54c9 MS |
4 | // Copyright 2007-2011 by Apple Inc. |
5 | // Copyright 2002-2006 by Easy Software Products. | |
ac884b6a | 6 | // |
e3101897 | 7 | // Licensed under Apache License v2.0. See the file "LICENSE" for more information. |
ac884b6a MS |
8 | // |
9 | ||
10 | // | |
11 | // Include necessary headers... | |
12 | // | |
13 | ||
38e73f87 | 14 | #include "ppdc-private.h" |
ac884b6a MS |
15 | #include <cups/ppd.h> |
16 | ||
17 | ||
18 | // | |
19 | // 'ppdcSource::import_ppd()' - Import a PPD file. | |
20 | // | |
21 | ||
22 | int // O - 1 on success, 0 on failure | |
23 | ppdcSource::import_ppd(const char *f) // I - Filename | |
24 | { | |
25 | int i, j, k; // Looping vars | |
26 | cups_file_t *fp; // File | |
27 | char line[256], // Comment line | |
28 | *ptr; // Pointer into line | |
f11a948a | 29 | int cost; // Cost for filter |
ac884b6a MS |
30 | ppd_file_t *ppd; // PPD file data |
31 | ppd_group_t *group; // PPD group | |
32 | ppd_option_t *option; // PPD option | |
33 | ppd_choice_t *choice; // PPD choice | |
34 | ppd_attr_t *attr; // PPD attribute | |
35 | ppd_const_t *constraint; // PPD UI constraint | |
36 | ppd_const_t *constraint2; // Temp PPD UI constraint | |
37 | ppd_size_t *size; // PPD page size | |
38 | ppdcDriver *driver; // Driver | |
f11a948a | 39 | ppdcFilter *filter; // Current filter |
ac884b6a MS |
40 | ppdcFont *font; // Font |
41 | ppdcGroup *cgroup; // UI group | |
42 | ppdcOption *coption; // UI option | |
43 | ppdcChoice *cchoice; // UI choice | |
44 | ppdcConstraint *cconstraint; // UI constraint | |
45 | ppdcMediaSize *csize; // Media size | |
46 | ||
47 | ||
48 | // Try opening the PPD file... | |
49 | if ((ppd = ppdOpenFile(f)) == NULL) | |
50 | return (0); | |
51 | ||
52 | // All PPD files need a PCFileName attribute... | |
53 | if (!ppd->pcfilename) | |
54 | { | |
55 | ppdClose(ppd); | |
56 | return (0); | |
57 | } | |
58 | ||
59 | // See if the driver has already been imported... | |
60 | if ((driver = find_driver(ppd->pcfilename)) == NULL) | |
61 | { | |
62 | // Create a new PPD file... | |
63 | if ((fp = cupsFileOpen(f, "r")) == NULL) | |
64 | { | |
65 | ppdClose(ppd); | |
66 | return (0); | |
67 | } | |
68 | ||
69 | driver = new ppdcDriver(); | |
70 | driver->type = PPDC_DRIVER_PS; | |
71 | ||
72 | drivers->add(driver); | |
73 | ||
74 | // Read the initial comments from the PPD file and use them as the | |
75 | // copyright/license text... | |
76 | cupsFileGets(fp, line, sizeof(line)); | |
77 | // Skip *PPD-Adobe-M.m | |
78 | ||
79 | while (cupsFileGets(fp, line, sizeof(line))) | |
80 | if (strncmp(line, "*%", 2)) | |
81 | break; | |
f11a948a | 82 | else if (strncmp(line, "*%%%% ", 6)) |
ac884b6a MS |
83 | { |
84 | for (ptr = line + 2; isspace(*ptr); ptr ++); | |
85 | ||
86 | driver->add_copyright(ptr); | |
87 | } | |
88 | ||
89 | cupsFileClose(fp); | |
90 | ||
91 | // Then add the stuff from the PPD file... | |
92 | if (ppd->modelname && ppd->manufacturer && | |
88f9aafc | 93 | !_cups_strncasecmp(ppd->modelname, ppd->manufacturer, |
ac884b6a MS |
94 | strlen(ppd->manufacturer))) |
95 | { | |
96 | ptr = ppd->modelname + strlen(ppd->manufacturer); | |
97 | ||
98 | while (isspace(*ptr)) | |
99 | ptr ++; | |
100 | } | |
101 | else | |
102 | ptr = ppd->modelname; | |
103 | ||
f11a948a MS |
104 | if (ppd->nickname) |
105 | driver->add_attr(new ppdcAttr("NickName", NULL, NULL, ppd->nickname)); | |
106 | ||
107 | if (ppd->shortnickname) | |
108 | driver->add_attr(new ppdcAttr("ShortNickName", NULL, NULL, | |
109 | ppd->shortnickname)); | |
110 | ||
111 | driver->manufacturer = new ppdcString(ppd->manufacturer); | |
112 | driver->model_name = new ppdcString(ptr); | |
113 | driver->pc_file_name = new ppdcString(ppd->pcfilename); | |
ac884b6a | 114 | attr = ppdFindAttr(ppd, "FileVersion", NULL); |
f11a948a MS |
115 | driver->version = new ppdcString(attr ? attr->value : NULL); |
116 | driver->model_number = ppd->model_number; | |
117 | driver->manual_copies = ppd->manual_copies; | |
118 | driver->color_device = ppd->color_device; | |
119 | driver->throughput = ppd->throughput; | |
120 | driver->variable_paper_size = ppd->variable_sizes; | |
121 | driver->max_width = ppd->custom_max[0]; | |
122 | driver->max_length = ppd->custom_max[1]; | |
123 | driver->min_width = ppd->custom_min[0]; | |
124 | driver->min_length = ppd->custom_min[1]; | |
125 | driver->left_margin = ppd->custom_margins[0]; | |
126 | driver->bottom_margin = ppd->custom_margins[1]; | |
127 | driver->right_margin = ppd->custom_margins[2]; | |
128 | driver->top_margin = ppd->custom_margins[3]; | |
129 | ||
130 | for (i = 0; i < ppd->num_filters; i ++) | |
131 | { | |
132 | strlcpy(line, ppd->filters[i], sizeof(line)); | |
133 | ||
134 | for (ptr = line; *ptr; ptr ++) | |
135 | if (isspace(*ptr & 255)) | |
136 | break; | |
137 | *ptr++ = '\0'; | |
138 | ||
139 | cost = strtol(ptr, &ptr, 10); | |
140 | ||
141 | while (isspace(*ptr & 255)) | |
142 | ptr ++; | |
143 | ||
144 | filter = new ppdcFilter(line, ptr, cost); | |
145 | driver->add_filter(filter); | |
146 | } | |
ac884b6a MS |
147 | |
148 | attr = ppdFindAttr(ppd, "DefaultFont", NULL); | |
149 | driver->default_font = new ppdcString(attr ? attr->value : NULL); | |
150 | ||
151 | // Collect media sizes... | |
152 | ppd_option_t *region_option, // PageRegion option | |
153 | *size_option; // PageSize option | |
154 | ppd_choice_t *region_choice, // PageRegion choice | |
155 | *size_choice; // PageSize choice | |
156 | ||
157 | region_option = ppdFindOption(ppd, "PageRegion"); | |
158 | size_option = ppdFindOption(ppd, "PageSize"); | |
159 | ||
160 | for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) | |
161 | { | |
162 | // Don't do custom size here... | |
88f9aafc | 163 | if (!_cups_strcasecmp(size->name, "Custom")) |
ac884b6a MS |
164 | continue; |
165 | ||
166 | // Get the code for the PageSize and PageRegion options... | |
167 | region_choice = ppdFindChoice(region_option, size->name); | |
168 | size_choice = ppdFindChoice(size_option, size->name); | |
169 | ||
170 | // Create a new media size record and add it to the driver... | |
171 | csize = new ppdcMediaSize(size->name, size_choice->text, size->width, | |
172 | size->length, size->left, size->bottom, | |
173 | size->width - size->right, | |
174 | size->length - size->top, | |
175 | size_choice->code, region_choice->code); | |
176 | ||
177 | driver->add_size(csize); | |
178 | ||
88f9aafc | 179 | if (!_cups_strcasecmp(size_option->defchoice, size->name)) |
ac884b6a MS |
180 | driver->set_default_size(csize); |
181 | } | |
182 | ||
183 | // Now all of the options... | |
184 | for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) | |
185 | { | |
186 | cgroup = new ppdcGroup(group->name, group->text); | |
187 | driver->add_group(cgroup); | |
188 | ||
189 | for (j = group->num_options, option = group->options; j > 0; j --, option ++) | |
190 | { | |
191 | if (!strcmp(option->keyword, "PageSize") || !strcmp(option->keyword, "PageRegion")) | |
192 | continue; | |
f11a948a | 193 | |
ac884b6a MS |
194 | coption = new ppdcOption((ppdcOptType)option->ui, option->keyword, |
195 | option->text, (ppdcOptSection)option->section, | |
196 | option->order); | |
197 | cgroup->add_option(coption); | |
198 | ||
199 | for (k = option->num_choices, choice = option->choices; k > 0; k --, choice ++) | |
200 | { | |
f11a948a MS |
201 | if (!strcmp(choice->choice, "Custom")) |
202 | continue; | |
203 | ||
ac884b6a MS |
204 | cchoice = new ppdcChoice(choice->choice, choice->text, choice->code); |
205 | coption->add_choice(cchoice); | |
206 | ||
88f9aafc | 207 | if (!_cups_strcasecmp(option->defchoice, choice->choice)) |
ac884b6a MS |
208 | coption->set_defchoice(cchoice); |
209 | } | |
210 | } | |
211 | } | |
212 | ||
213 | // Now the constraints... | |
214 | for (i = ppd->num_consts, constraint = ppd->consts; | |
215 | i > 0; | |
216 | i --, constraint ++) | |
217 | { | |
f11a948a MS |
218 | // Look for mirrored constraints... |
219 | for (j = i - 1, constraint2 = constraint + 1; | |
ac884b6a MS |
220 | j > 0; |
221 | j --, constraint2 ++) | |
f11a948a MS |
222 | if (!strcmp(constraint->option1, constraint2->option2) && |
223 | !strcmp(constraint->choice1, constraint2->choice2) && | |
ac884b6a | 224 | !strcmp(constraint->option2, constraint2->option1) && |
f11a948a | 225 | !strcmp(constraint->choice2, constraint2->choice1)) |
ac884b6a MS |
226 | break; |
227 | ||
228 | if (j) | |
229 | continue; | |
230 | ||
f11a948a MS |
231 | cconstraint = new ppdcConstraint(constraint->option2, constraint->choice2, |
232 | constraint->option1, constraint->choice1); | |
ac884b6a MS |
233 | driver->add_constraint(cconstraint); |
234 | } | |
235 | ||
236 | for (i = 0; i < ppd->num_attrs; i ++) | |
237 | { | |
238 | attr = ppd->attrs[i]; | |
239 | ||
240 | if (!strcmp(attr->name, "Font")) | |
241 | { | |
242 | // Font... | |
243 | char encoding[256], // Encoding string | |
244 | version[256], // Version string | |
245 | charset[256], // Charset string | |
246 | status[256]; // Status string | |
247 | ppdcFontStatus fstatus; // Status enumeration | |
248 | ||
249 | ||
250 | if (sscanf(attr->value, "%s%*[^\"]\"%[^\"]\"%s%s", encoding, version, | |
251 | charset, status) != 4) | |
252 | { | |
0837b7e8 MS |
253 | _cupsLangPrintf(stderr, _("ppdc: Bad font attribute: %s"), |
254 | attr->value); | |
ac884b6a MS |
255 | continue; |
256 | } | |
257 | ||
258 | if (!strcmp(status, "ROM")) | |
259 | fstatus = PPDC_FONT_ROM; | |
260 | else | |
261 | fstatus = PPDC_FONT_DISK; | |
262 | ||
263 | font = new ppdcFont(attr->spec, encoding, version, charset, fstatus); | |
264 | ||
265 | driver->add_font(font); | |
266 | } | |
f11a948a MS |
267 | else if (!strcmp(attr->name, "CustomPageSize")) |
268 | { | |
269 | driver->set_custom_size_code(attr->value); | |
270 | } | |
ac884b6a MS |
271 | else if ((strncmp(attr->name, "Default", 7) || |
272 | !strcmp(attr->name, "DefaultColorSpace")) && | |
273 | strcmp(attr->name, "ColorDevice") && | |
274 | strcmp(attr->name, "Manufacturer") && | |
275 | strcmp(attr->name, "ModelName") && | |
276 | strcmp(attr->name, "MaxMediaHeight") && | |
277 | strcmp(attr->name, "MaxMediaWidth") && | |
278 | strcmp(attr->name, "NickName") && | |
f11a948a | 279 | strcmp(attr->name, "ParamCustomPageSize") && |
ac884b6a MS |
280 | strcmp(attr->name, "ShortNickName") && |
281 | strcmp(attr->name, "Throughput") && | |
282 | strcmp(attr->name, "PCFileName") && | |
283 | strcmp(attr->name, "FileVersion") && | |
284 | strcmp(attr->name, "FormatVersion") && | |
f11a948a | 285 | strcmp(attr->name, "HWMargins") && |
ac884b6a MS |
286 | strcmp(attr->name, "VariablePaperSize") && |
287 | strcmp(attr->name, "LanguageEncoding") && | |
f11a948a MS |
288 | strcmp(attr->name, "LanguageVersion") && |
289 | strcmp(attr->name, "cupsFilter") && | |
290 | strcmp(attr->name, "cupsFlipDuplex") && | |
291 | strcmp(attr->name, "cupsLanguages") && | |
292 | strcmp(attr->name, "cupsManualCopies") && | |
293 | strcmp(attr->name, "cupsModelNumber") && | |
294 | strcmp(attr->name, "cupsVersion")) | |
ac884b6a | 295 | { |
f11a948a MS |
296 | if ((ptr = strchr(attr->name, '.')) != NULL && |
297 | ((ptr - attr->name) == 2 || (ptr - attr->name) == 5)) | |
298 | { | |
299 | // Might be a localization attribute; test further... | |
300 | if (isalpha(attr->name[0] & 255) && | |
301 | isalpha(attr->name[1] & 255) && | |
302 | (attr->name[2] == '.' || | |
303 | (attr->name[2] == '_' && isalpha(attr->name[3] & 255) && | |
304 | isalpha(attr->name[4] & 255)))) | |
305 | continue; | |
306 | } | |
307 | ||
ac884b6a MS |
308 | // Attribute... |
309 | driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text, | |
310 | attr->value)); | |
311 | } | |
312 | else if (!strncmp(attr->name, "Default", 7) && | |
313 | !ppdFindOption(ppd, attr->name + 7) && | |
314 | strcmp(attr->name, "DefaultFont") && | |
315 | strcmp(attr->name, "DefaultImageableArea") && | |
316 | strcmp(attr->name, "DefaultPaperDimension") && | |
317 | strcmp(attr->name, "DefaultFont")) | |
318 | { | |
319 | // Default attribute... | |
320 | driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text, | |
321 | attr->value)); | |
322 | } | |
323 | } | |
324 | } | |
325 | ||
326 | return (1); | |
327 | } |