]>
Commit | Line | Data |
---|---|---|
ac884b6a MS |
1 | // |
2 | // "$Id$" | |
3 | // | |
4 | // PPD file import methods for the CUPS PPD Compiler. | |
5 | // | |
6 | // Copyright 2007 by Apple Inc. | |
7 | // Copyright 2002-2006 by Easy Software Products. | |
8 | // | |
9 | // These coded instructions, statements, and computer programs are the | |
10 | // property of Apple Inc. and are protected by Federal copyright | |
11 | // law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | // which should have been included with this file. If this file is | |
13 | // file is missing or damaged, see the license at "http://www.cups.org/". | |
14 | // | |
15 | // Contents: | |
16 | // | |
17 | // ppdcSource::import_ppd() - Import a PPD file. | |
18 | // ppd_gets() - Get a line from a PPD file. | |
19 | // | |
20 | ||
21 | // | |
22 | // Include necessary headers... | |
23 | // | |
24 | ||
25 | #include "ppdc.h" | |
26 | #include <cups/ppd.h> | |
27 | ||
28 | ||
29 | // | |
30 | // 'ppdcSource::import_ppd()' - Import a PPD file. | |
31 | // | |
32 | ||
33 | int // O - 1 on success, 0 on failure | |
34 | ppdcSource::import_ppd(const char *f) // I - Filename | |
35 | { | |
36 | int i, j, k; // Looping vars | |
37 | cups_file_t *fp; // File | |
38 | char line[256], // Comment line | |
39 | *ptr; // Pointer into line | |
40 | ppd_file_t *ppd; // PPD file data | |
41 | ppd_group_t *group; // PPD group | |
42 | ppd_option_t *option; // PPD option | |
43 | ppd_choice_t *choice; // PPD choice | |
44 | ppd_attr_t *attr; // PPD attribute | |
45 | ppd_const_t *constraint; // PPD UI constraint | |
46 | ppd_const_t *constraint2; // Temp PPD UI constraint | |
47 | ppd_size_t *size; // PPD page size | |
48 | ppdcDriver *driver; // Driver | |
49 | ppdcFont *font; // Font | |
50 | ppdcGroup *cgroup; // UI group | |
51 | ppdcOption *coption; // UI option | |
52 | ppdcChoice *cchoice; // UI choice | |
53 | ppdcConstraint *cconstraint; // UI constraint | |
54 | ppdcMediaSize *csize; // Media size | |
55 | ||
56 | ||
57 | // Try opening the PPD file... | |
58 | if ((ppd = ppdOpenFile(f)) == NULL) | |
59 | return (0); | |
60 | ||
61 | // All PPD files need a PCFileName attribute... | |
62 | if (!ppd->pcfilename) | |
63 | { | |
64 | ppdClose(ppd); | |
65 | return (0); | |
66 | } | |
67 | ||
68 | // See if the driver has already been imported... | |
69 | if ((driver = find_driver(ppd->pcfilename)) == NULL) | |
70 | { | |
71 | // Create a new PPD file... | |
72 | if ((fp = cupsFileOpen(f, "r")) == NULL) | |
73 | { | |
74 | ppdClose(ppd); | |
75 | return (0); | |
76 | } | |
77 | ||
78 | driver = new ppdcDriver(); | |
79 | driver->type = PPDC_DRIVER_PS; | |
80 | ||
81 | drivers->add(driver); | |
82 | ||
83 | // Read the initial comments from the PPD file and use them as the | |
84 | // copyright/license text... | |
85 | cupsFileGets(fp, line, sizeof(line)); | |
86 | // Skip *PPD-Adobe-M.m | |
87 | ||
88 | while (cupsFileGets(fp, line, sizeof(line))) | |
89 | if (strncmp(line, "*%", 2)) | |
90 | break; | |
91 | else | |
92 | { | |
93 | for (ptr = line + 2; isspace(*ptr); ptr ++); | |
94 | ||
95 | driver->add_copyright(ptr); | |
96 | } | |
97 | ||
98 | cupsFileClose(fp); | |
99 | ||
100 | // Then add the stuff from the PPD file... | |
101 | if (ppd->modelname && ppd->manufacturer && | |
102 | !strncasecmp(ppd->modelname, ppd->manufacturer, | |
103 | strlen(ppd->manufacturer))) | |
104 | { | |
105 | ptr = ppd->modelname + strlen(ppd->manufacturer); | |
106 | ||
107 | while (isspace(*ptr)) | |
108 | ptr ++; | |
109 | } | |
110 | else | |
111 | ptr = ppd->modelname; | |
112 | ||
113 | driver->manufacturer = new ppdcString(ppd->manufacturer); | |
114 | driver->model_name = new ppdcString(ptr); | |
115 | driver->pc_file_name = new ppdcString(ppd->pcfilename); | |
116 | attr = ppdFindAttr(ppd, "FileVersion", NULL); | |
117 | driver->version = new ppdcString(attr ? attr->value : NULL); | |
118 | driver->model_number = ppd->model_number; | |
119 | driver->manual_copies = ppd->manual_copies; | |
120 | driver->color_device = ppd->color_device; | |
121 | driver->throughput = ppd->throughput; | |
122 | ||
123 | attr = ppdFindAttr(ppd, "DefaultFont", NULL); | |
124 | driver->default_font = new ppdcString(attr ? attr->value : NULL); | |
125 | ||
126 | // Collect media sizes... | |
127 | ppd_option_t *region_option, // PageRegion option | |
128 | *size_option; // PageSize option | |
129 | ppd_choice_t *region_choice, // PageRegion choice | |
130 | *size_choice; // PageSize choice | |
131 | ||
132 | region_option = ppdFindOption(ppd, "PageRegion"); | |
133 | size_option = ppdFindOption(ppd, "PageSize"); | |
134 | ||
135 | for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) | |
136 | { | |
137 | // Don't do custom size here... | |
138 | if (!strcasecmp(size->name, "Custom")) | |
139 | continue; | |
140 | ||
141 | // Get the code for the PageSize and PageRegion options... | |
142 | region_choice = ppdFindChoice(region_option, size->name); | |
143 | size_choice = ppdFindChoice(size_option, size->name); | |
144 | ||
145 | // Create a new media size record and add it to the driver... | |
146 | csize = new ppdcMediaSize(size->name, size_choice->text, size->width, | |
147 | size->length, size->left, size->bottom, | |
148 | size->width - size->right, | |
149 | size->length - size->top, | |
150 | size_choice->code, region_choice->code); | |
151 | ||
152 | driver->add_size(csize); | |
153 | ||
154 | if (!strcasecmp(size_option->defchoice, size->name)) | |
155 | driver->set_default_size(csize); | |
156 | } | |
157 | ||
158 | // Now all of the options... | |
159 | for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) | |
160 | { | |
161 | cgroup = new ppdcGroup(group->name, group->text); | |
162 | driver->add_group(cgroup); | |
163 | ||
164 | for (j = group->num_options, option = group->options; j > 0; j --, option ++) | |
165 | { | |
166 | if (!strcmp(option->keyword, "PageSize") || !strcmp(option->keyword, "PageRegion")) | |
167 | continue; | |
168 | ||
169 | coption = new ppdcOption((ppdcOptType)option->ui, option->keyword, | |
170 | option->text, (ppdcOptSection)option->section, | |
171 | option->order); | |
172 | cgroup->add_option(coption); | |
173 | ||
174 | for (k = option->num_choices, choice = option->choices; k > 0; k --, choice ++) | |
175 | { | |
176 | cchoice = new ppdcChoice(choice->choice, choice->text, choice->code); | |
177 | coption->add_choice(cchoice); | |
178 | ||
179 | if (!strcasecmp(option->defchoice, choice->choice)) | |
180 | coption->set_defchoice(cchoice); | |
181 | } | |
182 | } | |
183 | } | |
184 | ||
185 | // Now the constraints... | |
186 | for (i = ppd->num_consts, constraint = ppd->consts; | |
187 | i > 0; | |
188 | i --, constraint ++) | |
189 | { | |
190 | for (j = i - 1, constraint2 = constraint; | |
191 | j > 0; | |
192 | j --, constraint2 ++) | |
193 | if (constraint != constraint2 && | |
194 | !strcmp(constraint->option1, constraint2->option2) && | |
195 | (constraint->choice1 == constraint2->choice2 || | |
196 | (constraint->choice1 && constraint2->choice2 && | |
197 | !strcmp(constraint->choice1, constraint2->choice2))) && | |
198 | !strcmp(constraint->option2, constraint2->option1) && | |
199 | (constraint->choice2 == constraint2->choice1 || | |
200 | (constraint->choice2 && constraint2->choice1 && | |
201 | !strcmp(constraint->choice2, constraint2->choice1)))) | |
202 | break; | |
203 | ||
204 | if (j) | |
205 | continue; | |
206 | ||
207 | cconstraint = new ppdcConstraint(constraint->option1, constraint->choice1, | |
208 | constraint->option2, constraint->choice2); | |
209 | driver->add_constraint(cconstraint); | |
210 | } | |
211 | ||
212 | for (i = 0; i < ppd->num_attrs; i ++) | |
213 | { | |
214 | attr = ppd->attrs[i]; | |
215 | ||
216 | if (!strcmp(attr->name, "Font")) | |
217 | { | |
218 | // Font... | |
219 | char encoding[256], // Encoding string | |
220 | version[256], // Version string | |
221 | charset[256], // Charset string | |
222 | status[256]; // Status string | |
223 | ppdcFontStatus fstatus; // Status enumeration | |
224 | ||
225 | ||
226 | if (sscanf(attr->value, "%s%*[^\"]\"%[^\"]\"%s%s", encoding, version, | |
227 | charset, status) != 4) | |
228 | { | |
229 | fprintf(stderr, "Bad font attribute: %s\n", attr->value); | |
230 | continue; | |
231 | } | |
232 | ||
233 | if (!strcmp(status, "ROM")) | |
234 | fstatus = PPDC_FONT_ROM; | |
235 | else | |
236 | fstatus = PPDC_FONT_DISK; | |
237 | ||
238 | font = new ppdcFont(attr->spec, encoding, version, charset, fstatus); | |
239 | ||
240 | driver->add_font(font); | |
241 | } | |
242 | else if ((strncmp(attr->name, "Default", 7) || | |
243 | !strcmp(attr->name, "DefaultColorSpace")) && | |
244 | strcmp(attr->name, "ColorDevice") && | |
245 | strcmp(attr->name, "Manufacturer") && | |
246 | strcmp(attr->name, "ModelName") && | |
247 | strcmp(attr->name, "MaxMediaHeight") && | |
248 | strcmp(attr->name, "MaxMediaWidth") && | |
249 | strcmp(attr->name, "NickName") && | |
250 | strcmp(attr->name, "ShortNickName") && | |
251 | strcmp(attr->name, "Throughput") && | |
252 | strcmp(attr->name, "PCFileName") && | |
253 | strcmp(attr->name, "FileVersion") && | |
254 | strcmp(attr->name, "FormatVersion") && | |
255 | strcmp(attr->name, "VariablePaperSize") && | |
256 | strcmp(attr->name, "LanguageEncoding") && | |
257 | strcmp(attr->name, "LanguageVersion")) | |
258 | { | |
259 | // Attribute... | |
260 | driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text, | |
261 | attr->value)); | |
262 | } | |
263 | else if (!strncmp(attr->name, "Default", 7) && | |
264 | !ppdFindOption(ppd, attr->name + 7) && | |
265 | strcmp(attr->name, "DefaultFont") && | |
266 | strcmp(attr->name, "DefaultImageableArea") && | |
267 | strcmp(attr->name, "DefaultPaperDimension") && | |
268 | strcmp(attr->name, "DefaultFont")) | |
269 | { | |
270 | // Default attribute... | |
271 | driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text, | |
272 | attr->value)); | |
273 | } | |
274 | } | |
275 | } | |
276 | ||
277 | return (1); | |
278 | } | |
279 | ||
280 | ||
281 | // | |
282 | // End of "$Id$". | |
283 | // |