Imported Upstream version 3.0.2-20080211
Didier Raboud
13 years ago
0 | 2008-01-29 Till Kamppeter <till.kamppeter@gmail.com> | |
1 | ||
2 | * foomatic-perl-data.c: Added "<patents>" tag to driver entries. Drivers | |
3 | which are free software but contain (possibly) patented algorithms | |
4 | (like JBIG compression) should be marked with this tag to warn users | |
5 | about the patent issues when auto-downloading the driver. | |
6 | ||
7 | 2007-12-13 Till Kamppeter <till.kamppeter@gmail.com> | |
8 | ||
9 | * foomatic-perl-data.c: Added "<group>" tag to driver entries. Drivers | |
10 | which differ only by their locales ("<locales>" tag) should have the | |
11 | same "<group>" tags. If the user queries a driver giving a locale | |
12 | he gets only the best matching from each group. | |
13 | ||
14 | 2007-12-12 Till Kamppeter <till.kamppeter@gmail.com> | |
15 | ||
16 | * lib/Foomatic/DB.pm: Allow localized queries by adding a "language" | |
17 | field to the data structure and calling foomatic-perl-data with | |
18 | an appropriate "-l" option. | |
19 | ||
20 | * foomatic-perl-data.c: Fixed "-l" option, with "-l" the debug mode | |
21 | was always activated. | |
22 | ||
23 | 2007-12-11 Till Kamppeter <till.kamppeter@gmail.com> | |
24 | ||
25 | * foomatic-perl-data.c: Added new XML tags "<licensetext>" (full | |
26 | text of the license), "<locales>" (locales for which this driver | |
27 | is recommended), "<requires>" (drivers which are required to be | |
28 | on the system to run this driver), and "<packages>" (explicit | |
29 | listing of downloadable package files). They were introduced to | |
30 | fulfill demands of the printer manufacturers. | |
31 | ||
32 | Allow internationalization in the "<license>", "<supplier>", and | |
33 | "<supportcontact>" fields. | |
34 | ||
35 | Fixed internationalization. Now it is at first tried to find a | |
36 | text version which matches the user-supplied locale ID exactly, | |
37 | then it is searched for a text version where the supplied locale | |
38 | ID matches at least the language (First two characters), and as | |
39 | last mean english text is shown. | |
40 | ||
41 | 2007-10-09 Till Kamppeter <till.kamppeter@gmail.com> | |
42 | ||
43 | * lib/Foomatic/DB.pm: The PPD gnerator for CUPS did not list the | |
44 | PPDs correctly on printer names containing a comma (Ubuntu bug | |
45 | #150985). | |
46 | ||
47 | 2007-08-20 Till Kamppeter <till.kamppeter@gmail.com> | |
48 | ||
49 | * lib/Foomatic/DB.pm: Let margins default to safer values (1/4 | |
50 | inch on the left and on the right, 1/2 inch at the top and the | |
51 | bottom) if no margins are defined in the Foomatic database. | |
52 | Before, the default margins were all zero. | |
53 | ||
54 | Allow an empty model name in the search term for the | |
55 | find_printer() function ("ricoh|"), This way one can also search | |
56 | all printers from a given manufacturer, where the given | |
57 | manufacturer name does not need to match exactly with the name | |
58 | in the database. | |
59 | ||
60 | Some improvements in cleaning the manufacturer names. | |
61 | ||
62 | Improvements in the perltoxml() function. | |
63 | ||
64 | 2007-07-18 Till Kamppeter <till.kamppeter@gmail.com> | |
65 | ||
66 | * README, foomatic-perl-data.c, lib/Foomatic/DB.pm: Added support | |
67 | for suppressing page accounting on a per-driver basis. If a | |
68 | driver XML file is marked with "<nopageaccounting/>" in its | |
69 | "<execution>" section, the line "*FoomaticNoPageAccounting: | |
70 | True" is added to the PPD file to let foomatic-rip suppress | |
71 | inserting the page accounting code into the PostScript data | |
72 | stream. | |
73 | ||
74 | 2007-07-11 Till Kamppeter <till.kamppeter@gmail.com> | |
75 | ||
76 | * Makefile.in, README, README.build-foomatic-filters-ppds, USAGE, | |
77 | configure.ac, foomatic-preferred-driver.in, | |
78 | foomatic-printermap-to-gimp-print-xml.in, | |
79 | foomatic-printermap-to-gutenprint-xml.in, debian/presubj, | |
80 | lib/Foomatic/DB.pm: Replaced "Gimp-Print" by "Gutenprint". | |
81 | ||
82 | 2007-07-10 Till Kamppeter <till.kamppeter@gmail.com> | |
83 | ||
84 | * lib/Foomatic/DB.pm: Allow group names preceeded by asterisks | |
85 | ('*') in PPD files ("*OpenGroup: ..."/"*CloseGroup: ..." lines). | |
86 | This is needed by the PPD for the KONICA MINOLTA magicolor 5430 | |
87 | DL, provided by KONICA MINOLTA and probably also by several | |
88 | other manufacturer-supplied PPD files. | |
89 | ||
90 | 2007-03-08 Till Kamppeter <till.kamppeter@gmail.com> | |
91 | ||
92 | * foomatic-perl-data.c: Let the PPD files listed in the XML version | |
93 | of the overview also get listed in the Perl version. | |
94 | ||
95 | 2007-03-04 Till Kamppeter <till.kamppeter@gmail.com> | |
96 | ||
97 | * lib/Foomatic/DB.pm: Improved find_printer() method. Now | |
98 | searches of make and model names do not consider other characters | |
99 | than letters and numbers any more. All other characters are and | |
100 | boundaries between letters and numbers are converted to single | |
101 | spaces. | |
102 | ||
103 | 2007-03-03 Till Kamppeter <till.kamppeter@gmail.com> | |
104 | ||
105 | * debian/control: "gimp-print" -> "gutenprint". | |
106 | ||
107 | 2007-02-28 Till Kamppeter <till.kamppeter@gmail.com> | |
108 | ||
109 | * lib/Foomatic/DB.pm: Added new find_printer() method, to find | |
110 | printer entries in the database based on IEEE-1284 device IDs | |
111 | (from printer auto-detection), make/model, make, or model. | |
112 | This is for a new search function on the site and also for | |
113 | finding driver packages by printer setup tools. | |
114 | ||
115 | * foomatic-searchprinter.in, configure.ac, Makefile.in: Added | |
116 | simple tool to find printers in the locally installed | |
117 | Foomatic database using the new find_printer() method. | |
118 | ||
119 | 2007-02-26 Till Kamppeter <till.kamppeter@gmail.com> | |
120 | ||
121 | * foomatic-perl-data.c, lib/Foomatic/DB.pm: Let "<obsolete>" tags | |
122 | in driver XML files be read and added to the Perl data structures | |
123 | of driver entries, printer/driver combos, and the overview. Let | |
124 | this info also be put into the PPDs and into the "DRV:" field | |
125 | of the device IDs. | |
126 | ||
127 | 2007-02-24 Till Kamppeter <till.kamppeter@gmail.com> | |
128 | ||
129 | * foomatic-perl-data.c: Let Perl data structure for driver XML | |
130 | files also contain the printer-specific exceptions of the driver | |
131 | functionality data. | |
132 | ||
133 | 2007-02-23 Till Kamppeter <till.kamppeter@gmail.com> | |
134 | ||
135 | * foomatic-perl-data.c, lib/Foomatic/DB.pm: Allow specifying | |
136 | manufacturer names along with the "<manufacturersupplied>" tag | |
137 | in the driver XML file. In this case in the PPDs and in the PPD | |
138 | lists the driver is only marked as supplied by the manufacturer | |
139 | if the printer manufacturer's name matches one of the given | |
140 | names. For example if a Brother printer is used with HPIJS, the | |
141 | driver is not considered manufacturer-suppiled. | |
142 | ||
143 | 2007-02-22 Till Kamppeter <till.kamppeter@gmail.com> | |
144 | ||
145 | * foomatic-combo-xml.c, foomatic-perl-data.c, lib/Foomatic/DB.pm: | |
146 | Let new driver data fields go into the generated PPD files and | |
147 | into the oberview output. To get this information into the PPD | |
148 | lists of CUPS 1.2.x when using on-the-fly PPD generation added | |
149 | a new "DRV:" field to the device ID which contains all the | |
150 | driver functionality information. | |
151 | ||
152 | 2007-02-21 Till Kamppeter <till.kamppeter@gmail.com> | |
153 | ||
154 | * foomatic-combo-xml.c, foomatic-perl-data.c: Added support for | |
155 | new data fields in the driver XML files. These data fields | |
156 | should describe the properties of the drivers in a better way to | |
157 | guide the user to find the best driver for his personal needs | |
158 | and also make printer setup tools clearly informing the user | |
159 | before downloading and installing a driver which is not part of | |
160 | the distribution. | |
161 | ||
162 | 2007-02-07 Till Kamppeter <till.kamppeter@gmail.com> | |
163 | ||
164 | * Foomatic-Devel-Ideas.txt, README, debian/README.Debian, | |
165 | debian/control, foomatic-filters-ppds-README, lib/Foomatic/DB.pm: | |
166 | Replaced "FSG OpenPrinting" by "OpenPrinting". | |
167 | ||
168 | 2007-02-06 Till Kamppeter <till.kamppeter@gmail.com> | |
169 | ||
170 | * foomatic-perl-data.c: Added support for more driver types: | |
171 | CUPS Raster, IJS, and OpenPrinting Vector. | |
172 | ||
173 | 2007-01-06 Till Kamppeter <till.kamppeter@gmail.com> | |
174 | ||
175 | * README, USAGE, README.build-foomatic-filters-ppds, | |
176 | foomatic-addpjloptions.8.in, foomatic-combo-xml.1.in, | |
177 | foomatic-compiledb.1.in, Foomatic-Devel-Ideas.txt, | |
178 | foomatic-filters-ppds-README, foomatic-kitload.8.in, | |
179 | foomatic-ppdfile.1.in, lib/Foomatic/DB.pm, debian/control, | |
180 | debian/copyright, debian/foomatic-bin.README.Debian, | |
181 | debian/README.Debian: Updated texts and links to have | |
182 | "http://www.openprinting.org/" and "FSG OpenPrinting". | |
183 | ||
184 | 2007-01-04 Till Kamppeter <till.kamppeter@gmail.com> | |
185 | ||
186 | * foomatic-ppdfile.1.in: Corrected mark-up in the man page for | |
187 | foomatic-ppdfile (Thanks to Eric Raymond for his man page | |
188 | verification bot). | |
189 | ||
190 | 2006-11-09 Till Kamppeter <till.kamppeter@gmx.net> | |
191 | ||
192 | * foomatic-combo-xml.c, foomatic-ppdfile.in, lib/Foomatic/DB.pm: | |
193 | Let the listing of auto-generatable PPD files for CUPS 1.2 | |
194 | ("foomatic-ppdfile list") not contain entries for combos of | |
195 | printers with driver entries with a ready-made PPD file, as | |
196 | these PPD files are usually listed by CUPS directly. | |
197 | ||
0 | 198 | 2006-09-25 Till Kamppeter <till.kamppeter@gmx.net> |
1 | 199 | |
2 | 200 | * Makefile.in: Added forgotten DESTDIR (upstream merge from Debian |
19 | 19 | which do not apply any more to the current state of Foomatic can be |
20 | 20 | commited to the appropriate CVS branch. |
21 | 21 | |
22 | The web interface of linuxprinting.org could have buttons than where | |
22 | The web interface of OpenPrinting could have buttons than where | |
23 | 23 | one can choose the driver or distro version for which one wants to |
24 | 24 | have the Foomatic data. |
25 | 25 |
147 | 147 | foomatic-cleanupdrivers foomatic-getpjloptions \ |
148 | 148 | foomatic-addpjloptions foomatic-compiledb foomatic-fix-xml \ |
149 | 149 | foomatic-nonumericalids foomatic-replaceoldprinterids \ |
150 | foomatic-ppd-options foomatic-printermap-to-gimp-print-xml \ | |
151 | foomatic-extract-text | |
150 | foomatic-ppd-options foomatic-printermap-to-gutenprint-xml \ | |
151 | foomatic-extract-text foomatic-searchprinter | |
152 | 152 | |
153 | 153 | # User programs and helper programs |
154 | 154 | BINFILES:=foomatic-printjob foomatic-configure \ |
155 | 155 | foomatic-combo-xml foomatic-perl-data \ |
156 | 156 | foomatic-ppdfile foomatic-compiledb \ |
157 | foomatic-ppd-options | |
157 | foomatic-ppd-options foomatic-searchprinter | |
158 | 158 | |
159 | 159 | # Administrative commands, only useful for admins |
160 | 160 | SBINFILES:=foomatic-kitload \ |
161 | 161 | foomatic-getpjloptions foomatic-addpjloptions \ |
162 | 162 | foomatic-preferred-driver foomatic-fix-xml \ |
163 | 163 | foomatic-nonumericalids foomatic-replaceoldprinterids \ |
164 | foomatic-printermap-to-gimp-print-xml \ | |
164 | foomatic-printermap-to-gutenprint-xml \ | |
165 | 165 | foomatic-cleanupdrivers foomatic-extract-text |
166 | 166 | |
167 | 167 | # Foomatic XML templates |
9 | 9 | print queues and handle jobs. |
10 | 10 | |
11 | 11 | |
12 | Grant Taylor <gtaylor@picante.com> | |
13 | Till Kamppeter <till.kamppeter@gmx.net> | |
14 | ||
15 | http://www.linuxprinting.org/ | |
12 | Till Kamppeter <till.kamppeter@gmail.com> | |
13 | ||
14 | http://www.openprinting.org/ | |
16 | 15 | |
17 | 16 | This README contains mainly info for developers. See the file USAGE if |
18 | 17 | you want to know how to use Foomatic. |
24 | 23 | This package and also the other Foomatic packages needed to run this |
25 | 24 | are under the GPL. See http://www.gnu.org/. |
26 | 25 | |
27 | If you spot a data error or any other bug, send mail describing the bug to | |
28 | foomatic-devel@linuxprinting.org | |
29 | ||
30 | General discussion happens in the foomatic-devel forum/list thing at | |
31 | www.linuxprinting.org. | |
26 | ||
27 | Bugs | |
28 | ---- | |
29 | ||
30 | If you spot a data error or any other bug, either post on the Foomatic | |
31 | developer mailing list | |
32 | ||
33 | http://lists.freestandards.org/mailman/listinfo/printing-foomatic | |
34 | ||
35 | or post on the OpenPrinting site support forum | |
36 | ||
37 | http://forums.openprinting.org/list.php?34 | |
32 | 38 | |
33 | 39 | |
34 | 40 | Intro |
36 | 42 | |
37 | 43 | This is the stable version of Foomatic. See |
38 | 44 | |
39 | http://www.linuxprinting.org/contribute.html#programming | |
40 | http://www.linuxprinting.org/pipermail/foomatic-devel/2002q3/thread.html | |
41 | http://www.linuxprinting.org/pipermail/foomatic-devel/2002q4/thread.html | |
42 | http://www.linuxprinting.org/kpfeifle/LinuxKongress2002/Tutorial/IV.Foomatic-Developer/IV.tutorial-handout-foomatic-development.html | |
45 | http://www.freestandards.org/en/OpenPrinting/Database/HowToContribute#programming | |
43 | 46 | |
44 | 47 | to know more about its development. |
45 | 48 | |
46 | 49 | Your suggestions, bug reports, patches, ... are welcome on |
47 | 50 | |
48 | http://www.linuxprinting.org/newsportal/thread.php3?name=linuxprinting.foomatic.devel | |
49 | ||
50 | This version is also the base of our web interface on | |
51 | ||
52 | http://www.linuxprinting.org/ | |
53 | ||
54 | Old roadmap which lead to Foomatic 2.0: | |
55 | http://www.linuxprinting.org/pipermail/foomatic-devel/2001q1/000073.html | |
56 | ||
57 | This version implements the new foomatic-rip/PPD-based architecture. | |
58 | ||
51 | http://forums.openprinting.org/list.php?34 | |
52 | ||
53 | This version is also the base of our database web interface on | |
54 | ||
55 | http://www.openprinting.org/ | |
59 | 56 | |
60 | 57 | |
61 | 58 | New features for Foomatic 3.0.x |
188 | 185 | Very High Quality |
189 | 186 | Photo |
190 | 187 | |
191 | For an Epson Stylus Color 680 with Gimp-Print it sets the options | |
192 | resolution, ditherering, and image type as follows: | |
188 | For an Epson Stylus Color 680 with Gutenprint it sets the options | |
189 | resolution, dithering, and image type as follows: | |
193 | 190 | |
194 | 191 | Choice Resolution Dither ImageType |
195 | 192 | ------------------------------------------------------------------ |
298 | 295 | - Added a facility to chnage all the cryptic numerical printer IDs |
299 | 296 | from the old PostGreSQL time to clear-text printer IDs. With a |
300 | 297 | translation function it is assured that one can still use the old |
301 | IDs, for example to not break links to the linuxprinting.org web | |
302 | site. | |
298 | IDs, for example to not break links to the old linuxprinting.org | |
299 | web site. | |
303 | 300 | |
304 | 301 | - The Foomatic database uses clear-text printer IDs for all printers |
305 | 302 | now. |
357 | 354 | |
358 | 355 | - Compatibility fixes for IRIX and the *BSD operating systems. |
359 | 356 | |
360 | - Script to update the "gimp-print" driver entry in the database | |
357 | - Script to update the "gutenprint" driver entry in the database | |
361 | 358 | using the src/foomatic/foomatic-printermap file of the source |
362 | tarball of Gimp-Print 4.2.x. | |
359 | tarball of Gutenprint 5.0.x. | |
363 | 360 | |
364 | 361 | - perltoxml() Perl function in DB.pm to generate XML database entries |
365 | 362 | from PPD files (thanks to Tim Waugh from Red Hat). |
479 | 476 | having an on-disk cache is not necessary. |
480 | 477 | |
481 | 478 | - The PPD files serve also for PPD-aware applications as Star Office, |
482 | Open Office, the GIMP (for printers not supported by Gimp-Print), GPR, | |
479 | Open Office, the GIMP (for printers not supported by Gutenprint), GPR, | |
483 | 480 | Windows/Mac clients using their PostScript driver (and the Linux/Unix |
484 | 481 | server using the Linux driver for the printer). They give access to |
485 | 482 | all the driver's options in the printing dialogs of said |
654 | 651 | |
655 | 652 | Instead of using "foomatic-configure" you can also generate the PPD file: |
656 | 653 | |
657 | ./foomatic-ppdfile -d lj5gray -p 62304 > lj4050.ppd | |
654 | ./foomatic-ppdfile -d lj5gray -p HP-LaserJet_4050 > lj4050.ppd | |
658 | 655 | |
659 | 656 | And set up the queue manually as described on |
660 | http://www.linuxprinting.org/ | |
657 | http://www.openprinting.org/ | |
661 | 658 | |
662 | 659 | For CUPS you can for example do: |
663 | 660 | |
670 | 667 | toplevel directory of a foomatic driver "kit". A "kit" is a |
671 | 668 | selection of XML source files arranged exactly as in the source/ |
672 | 669 | section of the master database (ie, opt/ driver/ printer/ subdirs). |
673 | The gimp-print's foomatic-generator produces exactly such a kit. | |
670 | The gutenprint's foomatic-generator produces exactly such a kit. | |
674 | 671 | |
675 | 672 | Foomatic-kitload is moderately paranoid about kits: the kit must |
676 | 673 | contain at least one of printer/ driver/ and opt/; the kit must |
961 | 958 | Grant also probably broke it in the xml rewrite. Till has |
962 | 959 | rewritten getexecdocs to produce documentation for a given printer |
963 | 960 | driver pair, it provides the data presented on the "Execution Details" |
964 | pages of linuxprinting.org. | |
961 | pages of OpenPrinting. | |
965 | 962 | |
966 | 963 | get_libdir |
967 | 964 | |
982 | 979 | |
983 | 980 | Composite options are introduced in "foomatic-db" from December 17, |
984 | 981 | 2002 ("20021217") or newer, "foomatic-db-hpijs" 1.3-2 or newer, and |
985 | Gimp-Print 4.2.5 or newer. "foomatic-filters" 2.9.1 or newer is needed | |
986 | for using them. Nested composite options are supported and introduced | |
987 | on August 1, 2003. | |
982 | Gimp-Print (now Gutenprint) 4.2.5 or newer. "foomatic-filters" 2.9.1 | |
983 | or newer is needed for using them. Nested composite options are | |
984 | supported and introduced on August 1, 2003. | |
988 | 985 | |
989 | 986 | "wget" (from www.gnu.org) is really a standard tool which nearly every |
990 | 987 | distribution includes. |
1028 | 1025 | # Every option exists independently from printers or drivers, because |
1029 | 1026 | # they might apply to arbitrary combinations of printers and/or |
1030 | 1027 | # drivers. In practice, some drivers have wholly unique options |
1031 | # (gimp-print/stp, for example), while others (lots of generic basic | |
1028 | # (gutenprint for example), while others (lots of generic basic | |
1032 | 1029 | # Ghostscript drivers, for example) share some options. |
1033 | 1030 | |
1034 | 1031 | <option type="enum" id="opt/2"> |
1335 | 1332 | |
1336 | 1333 | # Printer types can be <laser />, <led />, <inkjet />, <dotmatrix />, |
1337 | 1334 | # <impact />, <sublimation />, <transfer />. Other types we have to |
1338 | # add to the CGI script on linuxprinting.org to make the web interface | |
1335 | # add to the CGI script on OpenPrinting to make the web interface | |
1339 | 1336 | # displaying them properly. |
1340 | 1337 | |
1341 | 1338 | <laser/> |
1666 | 1663 | # by the PJL options would then be ignored by the printer, and so |
1667 | 1664 | # this kind of options does not make sense. Such driver are for |
1668 | 1665 | # example "hpijs" and "hl1250". |
1666 | ||
1667 | # And the driver's <execution> section can also contain a | |
1668 | # | |
1669 | # <nopageaccounting/> | |
1670 | # | |
1671 | # This suppresses the inserting of page accounting code (for CUPS) | |
1672 | # into the PostScript data stream. Some drivers lead to unexpected | |
1673 | # behavior with that. Especially for the generic PostScript driver | |
1674 | # (which does not use Ghostscript in most cases) the accounting code | |
1675 | # should not be inserted. | |
1669 | 1676 | |
1670 | 1677 | # The prototype defines what command the backends run to drive this |
1671 | 1678 | # printer. It must take postscript on stdin and generate "printer |
2567 | 2574 | *PPD-Adobe: "4.3" |
2568 | 2575 | *% |
2569 | 2576 | *% For information on using this, and to obtain the required backend |
2570 | *% script, consult http://www.linuxprinting.org/ | |
2577 | *% script, consult http://www.openprinting.org/ | |
2571 | 2578 | *% |
2572 | 2579 | *% This file is published under the GNU General Public License |
2573 | 2580 | *% |
3505 | 3512 | <code>: The command line prototype, with spots to insert option |
3506 | 3513 | settings ("%A", "%B", ...). |
3507 | 3514 | |
3515 | *FoomaticNoPageAccounting: <boolean value> | |
3516 | <value>: If True, no accounting code will be inserted into the | |
3517 | PostScript data stream. | |
3518 | ||
3508 | 3519 | *FoomaticRIPOption <name>: <type> <style> <spot> [<order>] |
3509 | 3520 | <name>: Option name; <type>: enum, bool, int, float; |
3510 | 3521 | <style>: CmdLine, JCL, PS, Composite; |
3 | 3 | |
4 | 4 | The foomatic-filters-ppds package is a simple way to use Foomatic |
5 | 5 | |
6 | Till Kamppeter <till.kamppeter@gmx.net> | |
6 | Till Kamppeter <till.kamppeter@gmail.com> | |
7 | 7 | |
8 | http://www.linuxprinting.org/ | |
8 | http://www.openprinting.org/ | |
9 | 9 | |
10 | 10 | |
11 | 11 | Introduction |
32 | 32 | |
33 | 33 | foomatic-db-hpijs |
34 | 34 | |
35 | To include support for Gimp-Print | |
35 | To include support for Gutenprint | |
36 | 36 | |
37 | Gimp-Print from http://gimp-print.sf.net/ | |
38 | ||
39 | To include support for Omni | |
40 | ||
41 | Omni from | |
42 | http://www-124.ibm.com/developerworks/oss/linux/projects/omni/ | |
37 | Gutenprint from http://gutenprint.sf.net/ | |
43 | 38 | |
44 | 39 | |
45 | 40 | How to build |
76 | 71 | ./foomatic-kitload -f -k ../foomatic-db-hoijs*/db/source/ |
77 | 72 | cd .. |
78 | 73 | |
79 | Add support for Gimp-Print (optional, <...> is the Gimp-Print source | |
74 | Add support for Gutenprint (optional, <...> is the Gutenprint source | |
80 | 75 | code directory): |
81 | 76 | |
82 | 77 | cd foomatic-db-engine* |
83 | ./foomatic-kitload -f -k <...>/src/foomatic/foomatic-db/gimp-print | |
84 | ./foomatic-kitload -f -k <...>/src/foomatic/foomatic-db/gimp-print-ijs | |
85 | cd .. | |
86 | ||
87 | Add support for Omni (optional): | |
88 | ||
89 | cd foomatic-db-engine* | |
90 | export PATH=$PATH:/opt/Omni/bin | |
91 | /opt/Omni/bin/OmniFoomaticGenerator | |
92 | ./foomatic-kitload -k foomatic-db/db/source | |
78 | ./foomatic-kitload -f -k <...>/src/foomatic/foomatic-db/gutenprint | |
79 | ./foomatic-kitload -f -k <...>/src/foomatic/foomatic-db/gutenprint-ijs | |
93 | 80 | cd .. |
94 | 81 | |
95 | 82 | Exclude unwished drivers or printers from being packaged by deleting |
9 | 9 | print queues and handle jobs. |
10 | 10 | |
11 | 11 | |
12 | Grant Taylor <gtaylor@picante.com> | |
13 | Till Kamppeter <till.kamppeter@gmx.net> | |
14 | http://www.linuxprinting.org/ | |
12 | Till Kamppeter <till.kamppeter@gmail.com> | |
13 | http://www.openprinting.org/ | |
15 | 14 | |
16 | 15 | This usage documentation file is written by Till Kamppeter |
17 | 16 | |
456 | 455 | -p HP-DeskJet_840C -d cdj880 -o PageSize=A4 |
457 | 456 | |
458 | 457 | If you have an HP LaserJet 4050, which is a PostScript printer, you |
459 | can get its PPD file from its Windows driver CD, http://hp.sf.net/, | |
460 | or http://www.linuxprinting.org/download/PPD/. After downloading it | |
461 | you can set up a queue as follows: | |
458 | can get its PPD file from its Windows driver CD, http://hplip.sf.net/, | |
459 | or http://www.openprinting.org/. After downloading it you can set up a | |
460 | queue as follows: | |
462 | 461 | |
463 | 462 | foomatic-configure -s pdq -n LJ4050 -c socket://printer:9100 |
464 | 463 | --ppd HP_LaserJet_4050_Series.ppd -o PageSize=A4 |
468 | 467 | ("file.ppd.gz") are also allowed here. |
469 | 468 | |
470 | 469 | In this example we set up an Epson Stylus Photo 1290 with the CUPS |
471 | driver of Gimp-Print, but with PDQ as the spooler: | |
470 | driver of Gutenprint, but with PDQ as the spooler: | |
472 | 471 | |
473 | 472 | foomatic-configure -s pdq -n Eps1290 -c usb:/dev/usb/lp0 |
474 | 473 | --ppd escp2-1290.ppd -o PageSize=A4 |
637 | 636 | to get information about how to get the PPD files and follow the |
638 | 637 | links on |
639 | 638 | |
640 | http://www.linuxprinting.org/foomatic.html | |
639 | http://www.openprinting.org/foomatic.html | |
641 | 640 | |
642 | 641 | to know how to set up a queue with these PPD files. |
643 | 642 | |
1223 | 1222 | |
1224 | 1223 | The GIMP (http://www.gimp.org/) |
1225 | 1224 | |
1226 | The GIMP uses the Gimp-Print plug-in | |
1227 | (http://gimp-print.sourceforge.net/) to print. If it is installed you | |
1225 | The GIMP uses the Gutenprint plug-in | |
1226 | (http://gutenprint.sourceforge.net/) to print. If it is installed you | |
1228 | 1227 | can click into the window with your image using the right mouse button |
1229 | 1228 | and then choose "File" and "Print". In the printing dialog choose your |
1230 | 1229 | printer queue (if it is not listed, click "New Printer ..." to create |
1231 | 1230 | a list entry) and click on "Setup Printer ...". If your printer is |
1232 | listed, it is supported by Gimp-Print and you do not need a PPD file | |
1231 | listed, it is supported by Gutenprint and you do not need a PPD file | |
1233 | 1232 | for using it with GIMP. If it is not listed, choose "PostScript Level |
1234 | 1233 | 2". Then an input field for a PPD file will appear. Enter the path and |
1235 | 1234 | name under which your PPD file is located (foomatic-configure puts it |
1251 | 1250 | Windows versions also from http://www.cups.org/) and the PPD file |
1252 | 1251 | (/etc/foomatic/<spooler>/<printer queue name>.ppd) assigned to the |
1253 | 1252 | queue. Then you don't need to install the Windows driver for your |
1254 | printer. On Epson inkjets driven by the current version of Gimp-Print | |
1253 | printer. On Epson inkjets driven by the current version of Gutenprint | |
1255 | 1254 | you could even obtain a better printout quality than with the Windows |
1256 | 1255 | driver. You can also do things as installing filters which parse the |
1257 | 1256 | PostScript and count the pages on your server which is not possible |
906 | 906 | else |
907 | 907 | echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 |
908 | 908 | fi |
909 | cd $ac_popdir | |
909 | cd "$ac_popdir" | |
910 | 910 | done |
911 | 911 | fi |
912 | 912 | |
1837 | 1837 | cat conftest.err >&5 |
1838 | 1838 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
1839 | 1839 | (exit $ac_status); } && |
1840 | { ac_try='test -z "$ac_c_werror_flag" | |
1841 | || test ! -s conftest.err' | |
1840 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
1842 | 1841 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
1843 | 1842 | (eval $ac_try) 2>&5 |
1844 | 1843 | ac_status=$? |
1896 | 1895 | cat conftest.err >&5 |
1897 | 1896 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
1898 | 1897 | (exit $ac_status); } && |
1899 | { ac_try='test -z "$ac_c_werror_flag" | |
1900 | || test ! -s conftest.err' | |
1898 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
1901 | 1899 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
1902 | 1900 | (eval $ac_try) 2>&5 |
1903 | 1901 | ac_status=$? |
2013 | 2011 | cat conftest.err >&5 |
2014 | 2012 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2015 | 2013 | (exit $ac_status); } && |
2016 | { ac_try='test -z "$ac_c_werror_flag" | |
2017 | || test ! -s conftest.err' | |
2014 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2018 | 2015 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2019 | 2016 | (eval $ac_try) 2>&5 |
2020 | 2017 | ac_status=$? |
2068 | 2065 | cat conftest.err >&5 |
2069 | 2066 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2070 | 2067 | (exit $ac_status); } && |
2071 | { ac_try='test -z "$ac_c_werror_flag" | |
2072 | || test ! -s conftest.err' | |
2068 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2073 | 2069 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2074 | 2070 | (eval $ac_try) 2>&5 |
2075 | 2071 | ac_status=$? |
2114 | 2110 | cat conftest.err >&5 |
2115 | 2111 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2116 | 2112 | (exit $ac_status); } && |
2117 | { ac_try='test -z "$ac_c_werror_flag" | |
2118 | || test ! -s conftest.err' | |
2113 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2119 | 2114 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2120 | 2115 | (eval $ac_try) 2>&5 |
2121 | 2116 | ac_status=$? |
2159 | 2154 | cat conftest.err >&5 |
2160 | 2155 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2161 | 2156 | (exit $ac_status); } && |
2162 | { ac_try='test -z "$ac_c_werror_flag" | |
2163 | || test ! -s conftest.err' | |
2157 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2164 | 2158 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2165 | 2159 | (eval $ac_try) 2>&5 |
2166 | 2160 | ac_status=$? |
2480 | 2474 | cat conftest.err >&5 |
2481 | 2475 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2482 | 2476 | (exit $ac_status); } && |
2483 | { ac_try='test -z "$ac_c_werror_flag" | |
2484 | || test ! -s conftest.err' | |
2477 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2485 | 2478 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2486 | 2479 | (eval $ac_try) 2>&5 |
2487 | 2480 | ac_status=$? |
2553 | 2546 | cat conftest.err >&5 |
2554 | 2547 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2555 | 2548 | (exit $ac_status); } && |
2556 | { ac_try='test -z "$ac_c_werror_flag" | |
2557 | || test ! -s conftest.err' | |
2549 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2558 | 2550 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2559 | 2551 | (eval $ac_try) 2>&5 |
2560 | 2552 | ac_status=$? |
2608 | 2600 | cat conftest.err >&5 |
2609 | 2601 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2610 | 2602 | (exit $ac_status); } && |
2611 | { ac_try='test -z "$ac_c_werror_flag" | |
2612 | || test ! -s conftest.err' | |
2603 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2613 | 2604 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2614 | 2605 | (eval $ac_try) 2>&5 |
2615 | 2606 | ac_status=$? |
2680 | 2671 | cat conftest.err >&5 |
2681 | 2672 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2682 | 2673 | (exit $ac_status); } && |
2683 | { ac_try='test -z "$ac_c_werror_flag" | |
2684 | || test ! -s conftest.err' | |
2674 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2685 | 2675 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2686 | 2676 | (eval $ac_try) 2>&5 |
2687 | 2677 | ac_status=$? |
2735 | 2725 | cat conftest.err >&5 |
2736 | 2726 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
2737 | 2727 | (exit $ac_status); } && |
2738 | { ac_try='test -z "$ac_c_werror_flag" | |
2739 | || test ! -s conftest.err' | |
2728 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
2740 | 2729 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
2741 | 2730 | (eval $ac_try) 2>&5 |
2742 | 2731 | ac_status=$? |
3053 | 3042 | cat conftest.err >&5 |
3054 | 3043 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
3055 | 3044 | (exit $ac_status); } && |
3056 | { ac_try='test -z "$ac_c_werror_flag" | |
3057 | || test ! -s conftest.err' | |
3045 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
3058 | 3046 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
3059 | 3047 | (eval $ac_try) 2>&5 |
3060 | 3048 | ac_status=$? |
3262 | 3250 | cat conftest.err >&5 |
3263 | 3251 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
3264 | 3252 | (exit $ac_status); } && |
3265 | { ac_try='test -z "$ac_c_werror_flag" | |
3266 | || test ! -s conftest.err' | |
3253 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
3267 | 3254 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
3268 | 3255 | (eval $ac_try) 2>&5 |
3269 | 3256 | ac_status=$? |
3373 | 3360 | cat conftest.err >&5 |
3374 | 3361 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
3375 | 3362 | (exit $ac_status); } && |
3376 | { ac_try='test -z "$ac_c_werror_flag" | |
3377 | || test ! -s conftest.err' | |
3363 | { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' | |
3378 | 3364 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 |
3379 | 3365 | (eval $ac_try) 2>&5 |
3380 | 3366 | ac_status=$? |
6310 | 6296 | test -n "$LOCAL_FOOMATIC_RIP" || LOCAL_FOOMATIC_RIP="../foomatic-filters/foomatic-rip" |
6311 | 6297 | |
6312 | 6298 | |
6313 | ac_config_files="$ac_config_files Makefile makeDefaults makeMan foomatic-configure foomatic-printjob foomatic-kitload foomatic-ppdfile foomatic-preferred-driver foomatic-cleanupdrivers foomatic-getpjloptions foomatic-addpjloptions foomatic-compiledb foomatic-fix-xml foomatic-nonumericalids foomatic-replaceoldprinterids foomatic-ppd-options foomatic-printermap-to-gimp-print-xml foomatic-extract-text" | |
6299 | ac_config_files="$ac_config_files Makefile makeDefaults makeMan foomatic-configure foomatic-printjob foomatic-kitload foomatic-ppdfile foomatic-preferred-driver foomatic-cleanupdrivers foomatic-getpjloptions foomatic-addpjloptions foomatic-compiledb foomatic-fix-xml foomatic-nonumericalids foomatic-replaceoldprinterids foomatic-ppd-options foomatic-printermap-to-gutenprint-xml foomatic-extract-text foomatic-searchprinter" | |
6314 | 6300 | cat >confcache <<\_ACEOF |
6315 | 6301 | # This file is a shell script that caches the results of configure |
6316 | 6302 | # tests run on this system so they can be shared between configure |
6878 | 6864 | "foomatic-nonumericalids" ) CONFIG_FILES="$CONFIG_FILES foomatic-nonumericalids" ;; |
6879 | 6865 | "foomatic-replaceoldprinterids" ) CONFIG_FILES="$CONFIG_FILES foomatic-replaceoldprinterids" ;; |
6880 | 6866 | "foomatic-ppd-options" ) CONFIG_FILES="$CONFIG_FILES foomatic-ppd-options" ;; |
6881 | "foomatic-printermap-to-gimp-print-xml" ) CONFIG_FILES="$CONFIG_FILES foomatic-printermap-to-gimp-print-xml" ;; | |
6867 | "foomatic-printermap-to-gutenprint-xml" ) CONFIG_FILES="$CONFIG_FILES foomatic-printermap-to-gutenprint-xml" ;; | |
6882 | 6868 | "foomatic-extract-text" ) CONFIG_FILES="$CONFIG_FILES foomatic-extract-text" ;; |
6869 | "foomatic-searchprinter" ) CONFIG_FILES="$CONFIG_FILES foomatic-searchprinter" ;; | |
6883 | 6870 | *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 |
6884 | 6871 | echo "$as_me: error: invalid argument: $ac_config_target" >&2;} |
6885 | 6872 | { (exit 1); exit 1; }; };; |
7216 | 7203 | *) ac_INSTALL=$ac_top_builddir$INSTALL ;; |
7217 | 7204 | esac |
7218 | 7205 | |
7219 | if test x"$ac_file" != x-; then | |
7220 | { echo "$as_me:$LINENO: creating $ac_file" >&5 | |
7221 | echo "$as_me: creating $ac_file" >&6;} | |
7222 | rm -f "$ac_file" | |
7223 | fi | |
7224 | 7206 | # Let's still pretend it is `configure' which instantiates (i.e., don't |
7225 | 7207 | # use $as_me), people would be surprised to read: |
7226 | 7208 | # /* config.h. Generated by config.status. */ |
7259 | 7241 | fi;; |
7260 | 7242 | esac |
7261 | 7243 | done` || { (exit 1); exit 1; } |
7244 | ||
7245 | if test x"$ac_file" != x-; then | |
7246 | { echo "$as_me:$LINENO: creating $ac_file" >&5 | |
7247 | echo "$as_me: creating $ac_file" >&6;} | |
7248 | rm -f "$ac_file" | |
7249 | fi | |
7262 | 7250 | _ACEOF |
7263 | 7251 | cat >>$CONFIG_STATUS <<_ACEOF |
7264 | 7252 | sed "$ac_vpsub |
296 | 296 | foomatic-getpjloptions foomatic-addpjloptions |
297 | 297 | foomatic-compiledb foomatic-fix-xml |
298 | 298 | foomatic-nonumericalids foomatic-replaceoldprinterids |
299 | foomatic-ppd-options foomatic-printermap-to-gimp-print-xml | |
300 | foomatic-extract-text | |
299 | foomatic-ppd-options foomatic-printermap-to-gutenprint-xml | |
300 | foomatic-extract-text foomatic-searchprinter | |
301 | 301 | ) |
302 | 302 | |
303 | 303 | dnl Finished |
0 | 0 | foomatic-db-engine for Debian |
1 | 1 | ----------------------------- |
2 | 2 | |
3 | Note that the structure of the LinuxPrinting.org (foomatic) printer | |
3 | Note that the structure of the OpenPrinting (foomatic) printer | |
4 | 4 | configuration system in Debian (and upstream) has changed from the 2.0 |
5 | series. There are now 3 core packages: | |
5 | series. There are 3 core packages: | |
6 | 6 | |
7 | 7 | * foomatic-db: Contains the foomatic printer database. |
8 | 8 | |
13 | 13 | |
14 | 14 | In addition, the new foomatic-db-hpijs package includes the database |
15 | 15 | entries for printers supported by the HPIJS print filter developed by |
16 | Hewlett-Packard for its consumer inkjet line of printers. | |
16 | Hewlett-Packard for their non-PostScript printers. | |
17 | 17 | |
18 | 18 | The foomatic-bin package is provided for upgrade purposes from |
19 | 19 | Foomatic 2.0, and can be purged after its dependencies have been |
50 | 50 | |
51 | 51 | driver: The driver backend to use. For most modern printers, one of: |
52 | 52 | hpijs (if you have foomatic-db-hpijs installed) |
53 | gimp-print (if you have foomatic-db-gimp-print installed) | |
54 | gimp-print-ijs (a hybrid that ijsgimpprint and hpijs to be installed) | |
53 | gutenprint (if you have foomatic-db-gutenprint installed) | |
55 | 54 | Postscript |
56 | pcl5 | |
57 | 55 | |
58 | 56 | Your best bet on these two items is looking them up in the database at |
59 | LinuxPrinting.org or looking through the XML files in | |
60 | /usr/share/foomatic/db/source/printer/ | |
57 | OpenPrinting (http://www.openprinting.org/) or looking through the | |
58 | XML files in /usr/share/foomatic/db/source/printer/ | |
61 | 59 | |
62 | 60 | spooler: one of: cups, lpd, lprng, ppd, direct, ppr, pdq, gnulpr |
63 | 61 | (You can omit the -s option and it will try to guess.) |
9 | 9 | Pre-Depends: bash (>= 2.05) |
10 | 10 | Depends: ${perl:Depends}, ${shlibs:Depends}, foomatic-db, foomatic-filters, wget | curl |
11 | 11 | Recommends: netcat |
12 | Suggests: foomatic-db-hpijs, foomatic-db-gimp-print, foomatic-gui | |
12 | Suggests: foomatic-db-hpijs, foomatic-db-gutenprint, foomatic-gui | |
13 | 13 | Conflicts: foomatic-bin (<< 2.9), foomatic-db (<< 2.9) |
14 | 14 | Replaces: foomatic-bin (<< 2.9) |
15 | Description: linuxprinting.org printer support - programs | |
15 | Description: OpenPrinting printer support - programs | |
16 | 16 | Foomatic is a printing system designed to make it easier to set up |
17 | 17 | common printers for use with Debian (and other operating systems). |
18 | 18 | It provides the "glue" between a print spooler (like CUPS or lpr) and |
29 | 29 | Hewlett-Packard and some other consumer inkjets using the HPIJS |
30 | 30 | backend developed by HP. |
31 | 31 | . |
32 | foomatic-db-gimp-print includes support for photo-quality printing | |
32 | foomatic-db-gutenprint includes support for photo-quality printing | |
33 | 33 | with many consumer inkjets (including those from HP and Epson). |
34 | 34 | . |
35 | 35 | foomatic-gui provides a GNOME-based setup tool for Foomatic printer |
36 | 36 | queues using the command-line tools provided in this package. |
37 | 37 | . |
38 | Home Page: http://www.linuxprinting.org/ | |
38 | Home Page: http://www.openprinting.org/ | |
39 | 39 | |
40 | 40 | Package: foomatic-bin |
41 | 41 | Architecture: all |
42 | 42 | Depends: foomatic-db (>> 2.9), foomatic-db-hpijs, foomatic-db-engine, foomatic-filters |
43 | Description: linuxprinting.org printer support - transition package | |
43 | Description: OpenPrinting printer support - transition package | |
44 | 44 | Release 3.0 of foomatic has reorganized the foomatic printing system. |
45 | 45 | This package is provided to facilitate a smooth upgrade from Foomatic |
46 | 46 | 2.0 or earlier. |
48 | 48 | Once you have installed the dependencies of this package, this |
49 | 49 | package can be safely purged from your system. |
50 | 50 | . |
51 | Home Page: http://www.linuxprinting.org/ | |
51 | Home Page: http://www.openprinting.org/ |
3 | 3 | It is now maintained by Chris Lawrence <lawrencc@debian.org>. |
4 | 4 | |
5 | 5 | The current package was produced from sources obtained from: |
6 | http://www.linuxprinting.org/download/foomatic/ | |
6 | http://www.openprinting.org/download/foomatic/ | |
7 | 7 | |
8 | Upstream Authors: Grant Taylor <gtaylor@picante.com>, | |
9 | Till Kamppeter <till.kamppeter@gmx.net> | |
8 | Upstream Authors: Founder: Grant Taylor <gtaylor@picante.com>, | |
9 | Current maintainer: Till Kamppeter <till.kamppeter@gmx.net> | |
10 | 10 | |
11 | 11 | License: |
12 | 12 |
6 | 6 | |
7 | 7 | For additional information on the Foomatic printing system, please see |
8 | 8 | /usr/share/doc/foomatic-db-engine/README.Debian or |
9 | http://www.linuxprinting.org/foomatic.html | |
9 | http://www.openprinting.org/foomatic.html | |
10 | 10 | |
11 | 11 | -- Chris Lawrence <lawrencc@debian.org>, Tue, 10 Jun 2003 17:49:37 -0500 |
1 | 1 | |
2 | 2 | - The spooler you are using (CUPS, lpd, LPRng, etc.). |
3 | 3 | - The printer make and model. |
4 | - Which driver you are using (hpijs, GIMP-Print, cdj*, etc.). | |
4 | - Which driver you are using (hpijs, Gutenprint, cdj*, etc.). | |
5 | 5 | - How you installed the printer PPD file (foomatic-configure, manually |
6 | 6 | following the HOWTO's instructions, foomatic-gui, etc.). |
7 | 7 |
78 | 78 | |
79 | 79 | .SH BUGS |
80 | 80 | |
81 | Please send bug reports to foomatic-devel@linuxprinting.org. | |
81 | Please post bug reports on | |
82 | ||
83 | http://lists.freestandards.org/mailman/listinfo/printing-foomatic | |
84 |
23 | 23 | .SH BUGS |
24 | 24 | This manpage needs editing. |
25 | 25 | |
26 | Please send bug reports to foomatic-devel@linuxprinting.org. | |
26 | Please post bug reports on | |
27 | ||
28 | http://lists.freestandards.org/mailman/listinfo/printing-foomatic | |
29 |
6 | 6 | * make Perl data structures out of the XML files are very slow and |
7 | 7 | * memory-consuming. |
8 | 8 | * |
9 | * Copyright 2001 by Till Kamppeter | |
9 | * Copyright 2001-2007 by Till Kamppeter | |
10 | 10 | * |
11 | 11 | * This program is free software; you can redistribute it and/or |
12 | 12 | * modify it under the terms of the GNU General Public License as |
42 | 42 | |
43 | 43 | typedef struct { /* structure for a driver entry (linear list) */ |
44 | 44 | char name[128]; /* Name of driver */ |
45 | char *functionality; /* Exceptions in driver | |
46 | functionality profile for this | |
47 | printer */ | |
45 | 48 | struct driverlist_t *next; /* pointer to next driver */ |
46 | 49 | } driverlist_t; |
47 | 50 | |
265 | 268 | int inargdefault = 0; |
266 | 269 | int infunctionality = 0; |
267 | 270 | int inunverified = 0; |
271 | int indfunctionality = 0; | |
272 | int incomments = 0; | |
268 | 273 | int printertobesaved = 0; |
269 | 274 | int printerentryfound = 0; |
270 | 275 | int constrainttoberemoved = 0; |
308 | 313 | char argdefault[256]; |
309 | 314 | char defaultline[256]; |
310 | 315 | char printerentry[1024*1024]; |
316 | char dfunctionalityentry[10240]; | |
311 | 317 | const char *scan; /* pointer for scanning through the file*/ |
312 | 318 | const char *lasttag = NULL; /* Start of last XML tag */ |
313 | 319 | const char *lasttagend = NULL; /* End of last XML tag */ |
318 | 324 | char *lastconstraints = NULL; /* Start of last <constraints> tag */ |
319 | 325 | char *lastoption = NULL; /* Start of last <option> tag */ |
320 | 326 | char *lastautodetect = NULL; /* Start of last <autodetect> tag */ |
327 | char *lastdfunctionality = NULL;/* Start of last <functionality> tag */ | |
328 | char *lastcomments = NULL; /* Start of last <comments> tag */ | |
329 | char *lastprototype = NULL; /* Start of last <prototype> tag */ | |
321 | 330 | static char make[256]; /* Printer make/model read from printer */ |
322 | 331 | static char model[256]; /* XML file needed by constraints in */ |
323 | 332 | /* option XML files */ |
324 | 333 | int comboconfirmed = 0; |
325 | 334 | int driverhasproto = 0; |
335 | int exceptionfound = 0; | |
326 | 336 | |
327 | 337 | char *s; |
328 | 338 | int l; |
333 | 343 | ppdlist_t *ppdlistpointer; |
334 | 344 | printerlist_t *plistpreventry; |
335 | 345 | driverlist_t *dlistpreventry; |
346 | driverlist_t *dlistnextentry; | |
336 | 347 | ppdlist_t *ppdlistpreventry; |
337 | 348 | ppdlist_t *ppdlist = NULL; |
338 | 349 | |
534 | 545 | } else if (operation == 3) { /* Driver XML file (Overview) */ |
535 | 546 | if (strcmp(currtagname, "printer") == 0) { |
536 | 547 | inprinter = nestinglevel + 1; |
537 | cprinter[0] = '\0'; | |
548 | if (tagtype == 1) { | |
549 | cprinter[0] = '\0'; | |
550 | dfunctionalityentry[0] = '\0'; | |
551 | } | |
538 | 552 | } else if (strcmp(currtagname, "id") == 0) { |
539 | 553 | inid = nestinglevel + 1; |
554 | } else if (strcmp(currtagname, "functionality") == 0) { | |
555 | indfunctionality = nestinglevel + 1; | |
556 | if (tagtype == 1) lastdfunctionality = (char*)lasttag; | |
540 | 557 | } else if (strcmp(currtagname, "execution") == 0) { |
541 | 558 | inexecution = nestinglevel + 1; |
542 | 559 | } else if (strcmp(currtagname, "prototype") == 0) { |
543 | 560 | inprototype = nestinglevel + 1; |
561 | if (tagtype == 1) lastprototype = (char*)lasttagend + 1; | |
544 | 562 | } else if (strcmp(currtagname, "printers") == 0) { |
545 | 563 | inprinters = nestinglevel + 1; |
564 | if (tagtype == 1) lastprinters = (char*)lasttagend + 1; | |
565 | } else if (strcmp(currtagname, "comments") == 0) { | |
566 | incomments = nestinglevel + 1; | |
567 | if (tagtype == 1) lastcomments = (char*)lasttagend + 1; | |
546 | 568 | } else if (strcmp(currtagname, "driver") == 0) { |
547 | 569 | indriver = nestinglevel + 1; |
548 | 570 | } |
1242 | 1264 | } |
1243 | 1265 | } else if (operation == 3) { /* Driver XML file (Overview) */ |
1244 | 1266 | if (nestinglevel < indriver) indriver = 0; |
1245 | if (nestinglevel < inprinters) inprinters = 0; | |
1246 | if (nestinglevel < inprinter) inprinter = 0; | |
1267 | if (nestinglevel < inprinters) { | |
1268 | inprinters = 0; | |
1269 | /* Remove the whole <printers> block */ | |
1270 | if (lastprinters != NULL) { | |
1271 | if (debug) | |
1272 | fprintf(stderr, " Removing <printers> block\n"); | |
1273 | memmove(lastprinters, scan + 1, | |
1274 | *data + datalength - scan); | |
1275 | datalength -= scan + 1 - lastprinters; | |
1276 | scan = lastprinters - 1; | |
1277 | } | |
1278 | } | |
1279 | if (nestinglevel < incomments) { | |
1280 | incomments = 0; | |
1281 | /* Remove the whole <comments> block */ | |
1282 | if ((lastcomments != NULL) && (!inprinter)) { | |
1283 | if (debug) | |
1284 | fprintf(stderr, " Removing <comments> block\n"); | |
1285 | memmove(lastcomments, scan + 1, | |
1286 | *data + datalength - scan); | |
1287 | datalength -= scan + 1 - lastcomments; | |
1288 | scan = lastcomments - 1; | |
1289 | } | |
1290 | } | |
1247 | 1291 | if (nestinglevel < inexecution) inexecution = 0; |
1248 | 1292 | if (nestinglevel < inid) { |
1249 | 1293 | inid = 0; |
1254 | 1298 | fprintf(stderr, |
1255 | 1299 | " Overview: Printer: %s Driver: %s\n", |
1256 | 1300 | cprinter, cdriver); |
1301 | } | |
1302 | if (nestinglevel < indfunctionality) { | |
1303 | indfunctionality = 0; | |
1304 | /* Save the functionality entry in a buffer to insert it | |
1305 | into the overview */ | |
1306 | if (lastdfunctionality != NULL) { | |
1307 | if (debug) fprintf(stderr, | |
1308 | " Saving <functionality> entry\n"); | |
1309 | memmove(dfunctionalityentry, lastdfunctionality, | |
1310 | scan + 1 - lastdfunctionality); | |
1311 | dfunctionalityentry[scan + 1 - lastdfunctionality] = '\0'; | |
1312 | if (debug) fprintf(stderr, | |
1313 | " <functionality> entry: %s\n", | |
1314 | dfunctionalityentry); | |
1315 | } | |
1316 | } | |
1317 | if (nestinglevel < inprinter) { | |
1318 | inprinter = 0; | |
1319 | if (debug) | |
1320 | fprintf(stderr, | |
1321 | " Overview: Add driver %s to printer %s (%s)\n", | |
1322 | cdriver, cprinter, dfunctionalityentry); | |
1257 | 1323 | /* Add this driver to the current printer's entry in the |
1258 | 1324 | printer list, create the printer entry if necessary */ |
1259 | 1325 | plistpointer = *printerlist; |
1287 | 1353 | dlistpointer = |
1288 | 1354 | (driverlist_t *)malloc(sizeof(driverlist_t)); |
1289 | 1355 | strcpy(dlistpointer->name, cdriver); |
1356 | if ((dfunctionalityentry != NULL) && | |
1357 | (dfunctionalityentry[0])) | |
1358 | dlistpointer->functionality = strdup(dfunctionalityentry); | |
1359 | else dlistpointer->functionality = NULL; | |
1290 | 1360 | dlistpointer->next = NULL; |
1291 | 1361 | if (dlistpreventry != NULL) |
1292 | 1362 | dlistpreventry->next = |
1331 | 1401 | dlistpointer = |
1332 | 1402 | (driverlist_t *)malloc(sizeof(driverlist_t)); |
1333 | 1403 | strcpy(dlistpointer->name, cdriver); |
1404 | dlistpointer->functionality = NULL; | |
1334 | 1405 | dlistpointer->next = NULL; |
1335 | 1406 | if (dlistpreventry != NULL) |
1336 | 1407 | dlistpreventry->next = |
1345 | 1416 | fprintf(stderr, " Driver entry does not produce PPDs!\n"); |
1346 | 1417 | return; |
1347 | 1418 | } |
1419 | } | |
1420 | /* Remove the whole <prototype> block */ | |
1421 | if (lastprototype != NULL) { | |
1422 | if (debug) | |
1423 | fprintf(stderr, " Removing <prototype> block\n"); | |
1424 | memmove(lastprototype, scan + 1, | |
1425 | *data + datalength - scan); | |
1426 | datalength -= scan + 1 - lastprototype; | |
1427 | scan = lastprototype - 1; | |
1348 | 1428 | } |
1349 | 1429 | } |
1350 | 1430 | } else if (operation == 4) { /* Printer XML file (Overview) */ |
1404 | 1484 | not have a ready-made PPD we must */ |
1405 | 1485 | (driverhasproto) || /* have a command line |
1406 | 1486 | prototype */ |
1407 | ((cppd[0] != '\0')))) { /* We have a ready-made | |
1408 | PPD file */ | |
1487 | ((cppd[0] != '\0')))) { /* or a ready-made | |
1488 | PPD file. */ | |
1409 | 1489 | if (debug) |
1410 | 1490 | fprintf(stderr, |
1411 | 1491 | " Overview: Printer: %s Driver: %s\n", |
1446 | 1526 | dlistpointer = |
1447 | 1527 | (driverlist_t *)malloc(sizeof(driverlist_t)); |
1448 | 1528 | strcpy(dlistpointer->name, cid); |
1529 | dlistpointer->functionality = NULL; | |
1449 | 1530 | dlistpointer->next = NULL; |
1450 | 1531 | if (dlistpreventry != NULL) |
1451 | 1532 | dlistpreventry->next = |
1455 | 1536 | } |
1456 | 1537 | } |
1457 | 1538 | if ((cid[0] != '\0') && (cppd[0] != '\0')) { |
1458 | if (debug) | |
1459 | fprintf(stderr, | |
1460 | " Adding Driver/PPD to list.\n"); | |
1461 | ppdlistpointer = ppdlist; | |
1462 | ppdlistpreventry = NULL; | |
1463 | if (debug) | |
1464 | fprintf(stderr, | |
1465 | " Going through list: "); | |
1466 | while (ppdlistpointer != NULL) { | |
1467 | ppdlistpreventry = ppdlistpointer; | |
1468 | ppdlistpointer = (ppdlist_t *)ppdlistpointer->next; | |
1539 | if ((pid == NULL) || (pid[0] == 'C')) { | |
1540 | /* CUPS should also show entries for ready-made | |
1541 | PPD files in the Foomatic database */ | |
1542 | if (debug) | |
1543 | fprintf(stderr, | |
1544 | " Adding Driver/PPD to list.\n"); | |
1545 | ppdlistpointer = ppdlist; | |
1546 | ppdlistpreventry = NULL; | |
1469 | 1547 | if (debug) |
1470 | 1548 | fprintf(stderr, |
1471 | "."); | |
1549 | " Going through list: "); | |
1550 | while (ppdlistpointer != NULL) { | |
1551 | ppdlistpreventry = ppdlistpointer; | |
1552 | ppdlistpointer = (ppdlist_t *)ppdlistpointer->next; | |
1553 | if (debug) | |
1554 | fprintf(stderr, | |
1555 | "."); | |
1556 | } | |
1557 | ppdlistpointer = | |
1558 | (ppdlist_t *)malloc(sizeof(ppdlist_t)); | |
1559 | strcpy(ppdlistpointer->driver, cid); | |
1560 | strcpy(ppdlistpointer->ppd, cppd); | |
1561 | ppdlistpointer->next = NULL; | |
1562 | if (ppdlistpreventry != NULL) | |
1563 | ppdlistpreventry->next = | |
1564 | (struct ppdlist_t *)ppdlistpointer; | |
1565 | else | |
1566 | ppdlist = ppdlistpointer; | |
1567 | if (debug) | |
1568 | fprintf(stderr, | |
1569 | " Driver/PPD in list: %s %s\n", | |
1570 | ppdlistpointer->driver, | |
1571 | ppdlistpointer->ppd); | |
1572 | } else if ((pid != NULL) && (pid[0] == 'c')) { | |
1573 | /* CUPS should not show entries for ready-made | |
1574 | PPD files in the Foomatic database */ | |
1575 | /* To suppress the printer/driver combo from the output | |
1576 | list we need to delete the appropriate driver | |
1577 | entry */ | |
1578 | plistpointer = *printerlist; | |
1579 | plistpreventry = NULL; | |
1580 | /* Search printer in list */ | |
1581 | while ((plistpointer != NULL) && | |
1582 | (strcmp(plistpointer->id, cprinter) != 0)) { | |
1583 | plistpreventry = plistpointer; | |
1584 | plistpointer = (printerlist_t *)(plistpointer->next); | |
1585 | } | |
1586 | /* If the printer is there, search for the driver */ | |
1587 | if (plistpointer != NULL) { | |
1588 | dlistpointer = plistpointer->drivers; | |
1589 | dlistpreventry = NULL; | |
1590 | while ((dlistpointer != NULL) && | |
1591 | (strcasecmp(dlistpointer->name, cid))) { | |
1592 | dlistpreventry = dlistpointer; | |
1593 | dlistpointer = | |
1594 | (driverlist_t *)(dlistpointer->next); | |
1595 | } | |
1596 | if (dlistpointer != NULL) { | |
1597 | dlistnextentry = | |
1598 | (driverlist_t *)(dlistpointer->next); | |
1599 | free(dlistpointer); | |
1600 | if (dlistpreventry != NULL) | |
1601 | dlistpreventry->next = | |
1602 | (struct driverlist_t *)dlistnextentry; | |
1603 | else | |
1604 | plistpointer->drivers = dlistnextentry; | |
1605 | } | |
1606 | } | |
1472 | 1607 | } |
1473 | ppdlistpointer = | |
1474 | (ppdlist_t *)malloc(sizeof(ppdlist_t)); | |
1475 | strcpy(ppdlistpointer->driver, cid); | |
1476 | strcpy(ppdlistpointer->ppd, cppd); | |
1477 | ppdlistpointer->next = NULL; | |
1478 | if (ppdlistpreventry != NULL) | |
1479 | ppdlistpreventry->next = | |
1480 | (struct ppdlist_t *)ppdlistpointer; | |
1481 | else | |
1482 | ppdlist = ppdlistpointer; | |
1483 | if (debug) | |
1484 | fprintf(stderr, | |
1485 | " Driver/PPD in list: %s %s\n", | |
1486 | ppdlistpointer->driver, | |
1487 | ppdlistpointer->ppd); | |
1488 | 1608 | } |
1489 | 1609 | } else strcpy(cdriver, currtagbody); |
1490 | 1610 | } |
1599 | 1719 | strcat((char *)(*data), " "); |
1600 | 1720 | strcat((char *)(*data), cautodetectentry); |
1601 | 1721 | } |
1602 | strcat((char *)(*data), "\n <drivers>\n"); | |
1603 | 1722 | plistpointer = *printerlist; |
1604 | 1723 | while ((plistpointer) && |
1605 | 1724 | (strcmp(plistpointer->id, cprinter) != 0)) |
1606 | 1725 | plistpointer = (printerlist_t *)(plistpointer->next); |
1607 | 1726 | if (plistpointer) { |
1727 | strcat((char *)(*data), "\n <drivers>\n"); | |
1608 | 1728 | dlistpointer = plistpointer->drivers; |
1729 | exceptionfound = 0; | |
1609 | 1730 | while (dlistpointer) { |
1610 | 1731 | strcat((char *)(*data), " <driver>"); |
1611 | 1732 | strcat((char *)(*data), dlistpointer->name); |
1612 | 1733 | strcat((char *)(*data), "</driver>\n"); |
1734 | if (dlistpointer->functionality != NULL) exceptionfound = 1; | |
1613 | 1735 | dlistpointer = (driverlist_t *)(dlistpointer->next); |
1614 | 1736 | } |
1737 | strcat((char *)(*data), " </drivers>\n"); | |
1738 | if (exceptionfound) { | |
1739 | strcat((char *)(*data), " <driverfunctionalityexceptions>\n"); | |
1740 | dlistpointer = plistpointer->drivers; | |
1741 | while (dlistpointer) { | |
1742 | if (dlistpointer->functionality != NULL) { | |
1743 | strcat((char *)(*data), | |
1744 | " <driverfunctionalityexception>\n"); | |
1745 | strcat((char *)(*data), " <driver>"); | |
1746 | strcat((char *)(*data), dlistpointer->name); | |
1747 | strcat((char *)(*data), "</driver>\n"); | |
1748 | strcat((char *)(*data), dlistpointer->functionality); | |
1749 | strcat((char *)(*data), | |
1750 | "\n </driverfunctionalityexception>\n"); | |
1751 | } | |
1752 | dlistpointer = (driverlist_t *)(dlistpointer->next); | |
1753 | } | |
1754 | strcat((char *)(*data), " </driverfunctionalityexceptions>\n"); | |
1755 | } | |
1615 | 1756 | } |
1616 | strcat((char *)(*data), " </drivers>\n"); | |
1617 | 1757 | if (ppdlist != NULL) { |
1618 | 1758 | strcat((char *)(*data), " <ppds>\n"); |
1619 | 1759 | ppdlistpointer = ppdlist; |
1678 | 1818 | char **defaultsettings = NULL; /* User-supplied option settings*/ |
1679 | 1819 | int num_defaultsettings = 0; |
1680 | 1820 | int overview = 0; |
1821 | int noreadymadeppds = 0; | |
1681 | 1822 | int nopjl = 0; |
1682 | 1823 | int debug = 0; |
1683 | 1824 | int debug2 = 0; |
1707 | 1848 | fprintf(stderr, " -C Generate overview XML file only\n"); |
1708 | 1849 | fprintf(stderr, " containing combos leading to a valid\n"); |
1709 | 1850 | fprintf(stderr, " PPD file (for CUPS PPD list)\n"); |
1851 | fprintf(stderr, " -n (used only with \"-C\") suppress the\n"); | |
1852 | fprintf(stderr, " printer/driver combos which point to \n"); | |
1853 | fprintf(stderr, " ready-made PPD file (CUPS usually \n"); | |
1854 | fprintf(stderr, " lists ready-made PPD files directly).\n"); | |
1710 | 1855 | fprintf(stderr, " -l dir Directory where the Foomatic database is located\n"); |
1711 | 1856 | fprintf(stderr, " -v Verbose (debug) mode\n"); |
1712 | 1857 | fprintf(stderr, " -vv Very Verbose (debug) mode\n"); |
1752 | 1897 | break; |
1753 | 1898 | case 'C' : /* Overview for CUPS PPD list */ |
1754 | 1899 | overview = 2; |
1900 | break; | |
1901 | case 'n' : /* suppress ready-made PPDs in overview for CUPS PPD list */ | |
1902 | noreadymadeppds = 1; | |
1755 | 1903 | break; |
1756 | 1904 | case 'l' : /* libdir */ |
1757 | 1905 | if (argv[i][2] != '\0') |
1951 | 2099 | |
1952 | 2100 | /* Mark overview mode */ |
1953 | 2101 | if (overview == 2) |
1954 | pid = "C"; | |
2102 | if (noreadymadeppds) | |
2103 | pid = "c"; | |
2104 | else | |
2105 | pid = "C"; | |
1955 | 2106 | else |
1956 | 2107 | pid = NULL; |
1957 | 2108 | |
1966 | 2117 | plistpointer->next = NULL; |
1967 | 2118 | printerlist = plistpointer; |
1968 | 2119 | } |
2120 | ||
2121 | printf("<overview>\n"); | |
1969 | 2122 | |
1970 | 2123 | /* Search the Foomatic driver directory and read all xml files found |
1971 | 2124 | there. Read out the printers which the driver supports and add them |
1996 | 2149 | parse(&driverbuffer, pid, NULL, driverfilename, &printerlist, 3, |
1997 | 2150 | (const char **)defaultsettings, num_defaultsettings, &nopjl, |
1998 | 2151 | idlist, debug2); |
1999 | /* Delete the driver file from memory */ | |
2000 | free((void *)driverbuffer); | |
2001 | driverbuffer = NULL; | |
2152 | if (driverbuffer != NULL) { | |
2153 | /* put it out */ | |
2154 | printf("%s\n", driverbuffer); | |
2155 | /* Delete the driver file from memory */ | |
2156 | free((void *)driverbuffer); | |
2157 | driverbuffer = NULL; | |
2158 | } | |
2002 | 2159 | } |
2003 | 2160 | } |
2004 | 2161 | closedir(driverdir); |
2010 | 2167 | dlistpointer = plistpointer->drivers; |
2011 | 2168 | while (dlistpointer) { |
2012 | 2169 | fprintf(stderr, " Driver: %s\n", dlistpointer->name); |
2170 | if (dlistpointer->functionality != NULL) | |
2171 | fprintf(stderr, " %s\n", dlistpointer->functionality); | |
2013 | 2172 | dlistpointer = (driverlist_t *)(dlistpointer->next); |
2014 | 2173 | } |
2015 | 2174 | plistpointer = (printerlist_t *)(plistpointer->next); |
2026 | 2185 | exit(1); |
2027 | 2186 | } |
2028 | 2187 | |
2029 | printf("<overview>\n"); | |
2030 | ||
2031 | 2188 | while((direntry = readdir(printerdir)) != NULL) { |
2032 | 2189 | sprintf(printerfilename, "%s/db/source/printer/%s", |
2033 | 2190 | libdir, direntry->d_name); |
49 | 49 | overwritten. So deleting the destination directory (rm -rf dir) and |
50 | 50 | calling foomatic-compiledb without the -f option is recommended. |
51 | 51 | |
52 | Please send bug reports to foomatic-devel@linuxprinting.org. | |
52 | Please post bug reports on | |
53 | ||
54 | http://lists.freestandards.org/mailman/listinfo/printing-foomatic | |
55 |
15 | 15 | |
16 | 16 | "./install --help" lists all options of the installer. |
17 | 17 | |
18 | Now you can set up print queues as shown on | |
18 | Now you can set up print queues as shown on the documentation pages of | |
19 | the OpenPrinting web site (http://www.openprinting.org/). | |
19 | 20 | |
20 | http://www.linuxprinting.org/foomatic2.9/cups-doc.html | |
21 | http://www.linuxprinting.org/foomatic2.9/lpd-doc.html | |
22 | http://www.linuxprinting.org/foomatic2.9/ppr-doc.html | |
23 | http://www.linuxprinting.org/foomatic2.9/pdq-doc.html | |
24 | http://www.linuxprinting.org/foomatic2.9/direct-doc.html | |
25 | http://www.linuxprinting.org/foomatic2.9/ppd-doc.html | |
26 | ||
27 | But instead of downloading the PPD files from linuxprinting.org you | |
28 | get them from | |
21 | But instead of downloading the PPD files from the OpenPrinting web | |
22 | site you get them from | |
29 | 23 | |
30 | 24 | /usr/local/share/ppd |
31 | 25 | |
37 | 31 | are already correctly installed on your system. |
38 | 32 | |
39 | 33 | If you are using CUPS, you can also set up a queue for every printer |
40 | supported by linuxprinting.org with the help of the web interface of | |
41 | CUPS. To do so, you have to restart the CUPS daemon so that your newly | |
42 | installed PPD files get known to CUPS. Use one of the following | |
43 | commands, depending on your system: | |
34 | supported by OpenPrinting with the help of the web interface of | |
35 | CUPS. To do so and if you are using CUPS 1.1.x or older, you have to | |
36 | restart the CUPS daemon so that your newly installed PPD files get | |
37 | known to CUPS. Use one of the following commands, depending on your | |
38 | system: | |
44 | 39 | |
45 | 40 | killall -HUP cupsd |
46 | 41 | /etc/init.d/cups restart |
42 | sudo /etc/init.d/cups restart | |
47 | 43 | /etc/rc.d/init.d/cups restart |
48 | 44 | /sbin/init.d/cups restart |
49 | 45 | /etc/software/init.d/cups restart |
46 | 46 | |
47 | 47 | .SH BUGS |
48 | 48 | |
49 | Please send bug reports to foomatic-devel@linuxprinting.org. | |
49 | Please post bug reports on | |
50 | ||
51 | http://lists.freestandards.org/mailman/listinfo/printing-foomatic | |
52 |
98 | 98 | xmlChar *name; |
99 | 99 | xmlChar *comment; |
100 | 100 | xmlChar *ppd; |
101 | /* functionality exceptions */ | |
102 | xmlChar *excmaxresx; | |
103 | xmlChar *excmaxresy; | |
104 | xmlChar *exccolor; | |
105 | xmlChar *exctext; | |
106 | xmlChar *exclineart; | |
107 | xmlChar *excgraphics; | |
108 | xmlChar *excphoto; | |
109 | xmlChar *excload; | |
110 | xmlChar *excspeed; | |
101 | 111 | } printerDrvEntry, *printerDrvEntryPtr; |
102 | ||
103 | /* | |
104 | * Records for the data of the overview | |
105 | */ | |
106 | ||
107 | typedef struct overviewPrinter { | |
108 | /* General info */ | |
109 | xmlChar *id; | |
110 | xmlChar *make; | |
111 | xmlChar *model; | |
112 | xmlChar *functionality; | |
113 | xmlChar *unverified; | |
114 | /* Printer auto-detection */ | |
115 | xmlChar *general_ieee; | |
116 | xmlChar *general_mfg; | |
117 | xmlChar *general_mdl; | |
118 | xmlChar *general_des; | |
119 | xmlChar *general_cmd; | |
120 | xmlChar *par_ieee; | |
121 | xmlChar *par_mfg; | |
122 | xmlChar *par_mdl; | |
123 | xmlChar *par_des; | |
124 | xmlChar *par_cmd; | |
125 | xmlChar *usb_ieee; | |
126 | xmlChar *usb_mfg; | |
127 | xmlChar *usb_mdl; | |
128 | xmlChar *usb_des; | |
129 | xmlChar *usb_cmd; | |
130 | xmlChar *snmp_ieee; | |
131 | xmlChar *snmp_mfg; | |
132 | xmlChar *snmp_mdl; | |
133 | xmlChar *snmp_des; | |
134 | xmlChar *snmp_cmd; | |
135 | /* Drivers */ | |
136 | xmlChar *driver; | |
137 | int num_drivers; | |
138 | xmlChar **drivers; | |
139 | } overviewPrinter, *overviewPrinterPtr; | |
140 | ||
141 | typedef struct overview { | |
142 | int num_overviewPrinters; | |
143 | overviewPrinterPtr *overviewPrinters; | |
144 | } overview, *overviewPtr; | |
145 | 112 | |
146 | 113 | /* |
147 | 114 | * Records for the data of a printer/driver combo |
220 | 187 | printerDrvEntryPtr *drivers; |
221 | 188 | /* Driver */ |
222 | 189 | xmlChar *driver; |
190 | xmlChar *driver_group; | |
223 | 191 | xmlChar *pcdriver; |
224 | 192 | xmlChar *driver_type; |
225 | 193 | xmlChar *driver_comment; |
226 | 194 | xmlChar *url; |
195 | xmlChar *driver_obsolete; | |
196 | xmlChar *supplier; | |
197 | xmlChar *manufacturersupplied; | |
198 | xmlChar *license; | |
199 | xmlChar *licensetext; | |
200 | xmlChar *free; | |
201 | xmlChar *patents; | |
202 | int num_supportcontacts; | |
203 | xmlChar **supportcontacts; | |
204 | xmlChar **supportcontacturls; | |
205 | xmlChar **supportcontactlevels; | |
206 | xmlChar *shortdescription; | |
207 | xmlChar *locales; | |
208 | int num_packages; | |
209 | xmlChar **packageurls; | |
210 | xmlChar **packagescopes; | |
211 | xmlChar *drvmaxresx; | |
212 | xmlChar *drvmaxresy; | |
213 | xmlChar *drvcolor; | |
214 | xmlChar *text; | |
215 | xmlChar *lineart; | |
216 | xmlChar *graphics; | |
217 | xmlChar *photo; | |
218 | xmlChar *load; | |
219 | xmlChar *speed; | |
220 | xmlChar *excmaxresx; | |
221 | xmlChar *excmaxresy; | |
222 | xmlChar *exccolor; | |
223 | xmlChar *exctext; | |
224 | xmlChar *exclineart; | |
225 | xmlChar *excgraphics; | |
226 | xmlChar *excphoto; | |
227 | xmlChar *excload; | |
228 | xmlChar *excspeed; | |
229 | int num_requires; | |
230 | xmlChar **requires; | |
231 | xmlChar **requiresversion; | |
227 | 232 | xmlChar *cmd; |
228 | 233 | xmlChar *nopjl; |
234 | xmlChar *nopageaccounting; | |
229 | 235 | xmlChar *driverppdentry; |
230 | 236 | xmlChar *comboppdentry; |
231 | 237 | marginsPtr drivermargins; |
304 | 310 | typedef struct drvPrnEntry { |
305 | 311 | xmlChar *id; |
306 | 312 | xmlChar *comment; |
313 | /* functionality exceptions */ | |
314 | xmlChar *excmaxresx; | |
315 | xmlChar *excmaxresy; | |
316 | xmlChar *exccolor; | |
317 | xmlChar *exctext; | |
318 | xmlChar *exclineart; | |
319 | xmlChar *excgraphics; | |
320 | xmlChar *excphoto; | |
321 | xmlChar *excload; | |
322 | xmlChar *excspeed; | |
307 | 323 | } drvPrnEntry, *drvPrnEntryPtr; |
308 | 324 | |
309 | 325 | typedef struct driverEntry { |
310 | 326 | xmlChar *id; |
311 | 327 | xmlChar *name; |
328 | xmlChar *group; | |
312 | 329 | xmlChar *url; |
330 | xmlChar *driver_obsolete; | |
331 | xmlChar *supplier; | |
332 | xmlChar *manufacturersupplied; | |
333 | xmlChar *license; | |
334 | xmlChar *licensetext; | |
335 | xmlChar *free; | |
336 | xmlChar *patents; | |
337 | int num_supportcontacts; | |
338 | xmlChar **supportcontacts; | |
339 | xmlChar **supportcontacturls; | |
340 | xmlChar **supportcontactlevels; | |
341 | xmlChar *shortdescription; | |
342 | xmlChar *locales; | |
343 | int num_packages; | |
344 | xmlChar **packageurls; | |
345 | xmlChar **packagescopes; | |
346 | xmlChar *maxresx; | |
347 | xmlChar *maxresy; | |
348 | xmlChar *color; | |
349 | xmlChar *text; | |
350 | xmlChar *lineart; | |
351 | xmlChar *graphics; | |
352 | xmlChar *photo; | |
353 | xmlChar *load; | |
354 | xmlChar *speed; | |
355 | int num_requires; | |
356 | xmlChar **requires; | |
357 | xmlChar **requiresversion; | |
313 | 358 | xmlChar *driver_type; |
314 | 359 | xmlChar *cmd; |
315 | 360 | xmlChar *driverppdentry; |
320 | 365 | } driverEntry, *driverEntryPtr; |
321 | 366 | |
322 | 367 | /* |
368 | * Records for the data of the overview | |
369 | */ | |
370 | ||
371 | typedef struct ppdFile { | |
372 | xmlChar *driver; | |
373 | xmlChar *filename; | |
374 | } ppdFile, *ppdFilePtr; | |
375 | ||
376 | typedef struct overviewPrinter { | |
377 | /* General info */ | |
378 | xmlChar *id; | |
379 | xmlChar *make; | |
380 | xmlChar *model; | |
381 | xmlChar *functionality; | |
382 | xmlChar *unverified; | |
383 | /* Printer auto-detection */ | |
384 | xmlChar *general_ieee; | |
385 | xmlChar *general_mfg; | |
386 | xmlChar *general_mdl; | |
387 | xmlChar *general_des; | |
388 | xmlChar *general_cmd; | |
389 | xmlChar *par_ieee; | |
390 | xmlChar *par_mfg; | |
391 | xmlChar *par_mdl; | |
392 | xmlChar *par_des; | |
393 | xmlChar *par_cmd; | |
394 | xmlChar *usb_ieee; | |
395 | xmlChar *usb_mfg; | |
396 | xmlChar *usb_mdl; | |
397 | xmlChar *usb_des; | |
398 | xmlChar *usb_cmd; | |
399 | xmlChar *snmp_ieee; | |
400 | xmlChar *snmp_mfg; | |
401 | xmlChar *snmp_mdl; | |
402 | xmlChar *snmp_des; | |
403 | xmlChar *snmp_cmd; | |
404 | /* Drivers */ | |
405 | xmlChar *driver; | |
406 | int num_drivers; | |
407 | printerDrvEntryPtr *drivers; | |
408 | /* PPD files */ | |
409 | int num_ppdfiles; | |
410 | ppdFilePtr *ppdfiles; | |
411 | } overviewPrinter, *overviewPrinterPtr; | |
412 | ||
413 | typedef struct overview { | |
414 | int num_overviewDrivers; | |
415 | driverEntryPtr *overviewDrivers; | |
416 | int num_overviewPrinters; | |
417 | overviewPrinterPtr *overviewPrinters; | |
418 | } overview, *overviewPtr; | |
419 | ||
420 | /* | |
323 | 421 | * Function to quote "'" and "\" in a string |
324 | 422 | */ |
325 | 423 | |
328 | 426 | xmlChar *dest, *s; |
329 | 427 | int offset = 0; |
330 | 428 | |
429 | if (str == NULL) return NULL; | |
331 | 430 | dest = xmlStrdup(str); |
332 | 431 | while ((s = (xmlChar *)xmlStrchr((const xmlChar *)(dest + offset), |
333 | 432 | (xmlChar)'\'')) || |
342 | 441 | offset += 2; |
343 | 442 | } |
344 | 443 | return(dest); |
444 | } | |
445 | ||
446 | /* | |
447 | * Function to read out localized text, choosing the translation into the | |
448 | * desirted language. Reads also simple text without language tags, for | |
449 | * backward compatibility for the case that a not yet localized database | |
450 | * field gets localized | |
451 | */ | |
452 | ||
453 | static void | |
454 | getLocalizedText(xmlDocPtr doc, /* I - The whole data tree */ | |
455 | xmlNodePtr node, /* I - Node of XML tree to work on */ | |
456 | xmlChar **ret, /* O - Text which was selected by the | |
457 | language */ | |
458 | xmlChar *language, /* I - User language */ | |
459 | int debug) { /* I - Debug mode flag */ | |
460 | xmlNodePtr cur1; /* XML node currently worked on */ | |
461 | ||
462 | cur1 = node->xmlChildrenNode; | |
463 | if (xmlStrcasecmp(cur1->name, "C") && xmlStrcasecmp(cur1->name, "POSIX")) { | |
464 | while (cur1 != NULL) { | |
465 | /* Exact match of locale ID */ | |
466 | if ((!xmlStrcasecmp(cur1->name, language))) { | |
467 | *ret = xmlStrdup | |
468 | (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1))); | |
469 | if (debug) | |
470 | fprintf | |
471 | (stderr, | |
472 | " Localized text with full locale ID matched (%s):\n\n%s\n\n", | |
473 | language, *ret); | |
474 | return; | |
475 | } | |
476 | cur1 = cur1->next; | |
477 | } | |
478 | cur1 = node->xmlChildrenNode; | |
479 | while (cur1 != NULL) { | |
480 | /* Fall back to match only the two-character language code */ | |
481 | if ((!xmlStrncasecmp(cur1->name, language, 2))) { | |
482 | *ret = xmlStrdup | |
483 | (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1))); | |
484 | if (debug) | |
485 | fprintf | |
486 | (stderr, | |
487 | " Localized text with only language ID matched (%s):\n\n%s\n\n", | |
488 | language, *ret); | |
489 | return; | |
490 | } | |
491 | cur1 = cur1->next; | |
492 | } | |
493 | cur1 = node->xmlChildrenNode; | |
494 | } | |
495 | while (cur1 != NULL) { | |
496 | /* Fall back to English */ | |
497 | if ((!xmlStrncasecmp(cur1->name, (const xmlChar *) "en", 2))) { | |
498 | *ret = xmlStrdup | |
499 | (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1))); | |
500 | if (debug) | |
501 | fprintf(stderr, " English text:\n\n%s\n\n", *ret); | |
502 | return; | |
503 | } | |
504 | cur1 = cur1->next; | |
505 | } | |
506 | cur1 = node->xmlChildrenNode; | |
507 | /* Fall back to non-localized text (allows backward compatibility if | |
508 | deciding on localizing a database item later */ | |
509 | *ret = xmlStrdup(perlquote(xmlNodeListGetString(doc, cur1, 1))); | |
510 | if (debug) | |
511 | fprintf(stderr, " Non-localized text:\n\n%s\n\n", *ret); | |
345 | 512 | } |
346 | 513 | |
347 | 514 | /* |
493 | 660 | xmlNodePtr cur1; /* XML node currently worked on */ |
494 | 661 | xmlNodePtr cur2; /* Another XML node pointer */ |
495 | 662 | xmlNodePtr cur3; /* Another XML node pointer */ |
663 | xmlNodePtr cur4; /* Another XML node pointer */ | |
496 | 664 | xmlChar *id; /* Full printer ID, with "printer/" */ |
497 | 665 | xmlChar *charset; |
666 | xmlChar *drivername; | |
498 | 667 | overviewPrinterPtr printer; |
668 | printerDrvEntryPtr dentry; /* An entry for a driver supporting this | |
669 | printer */ | |
670 | ppdFilePtr ppd; | |
671 | int driverfound; | |
672 | int i, j; | |
499 | 673 | |
500 | 674 | /* Allocate memory for the printer */ |
501 | 675 | ret->num_overviewPrinters ++; |
541 | 715 | printer->driver = NULL; |
542 | 716 | printer->num_drivers = 0; |
543 | 717 | printer->drivers = NULL; |
718 | printer->num_ppdfiles = 0; | |
719 | printer->ppdfiles = NULL; | |
544 | 720 | |
545 | 721 | /* Go through subnodes */ |
546 | 722 | cur1 = node->xmlChildrenNode; |
575 | 751 | cur2 = cur1->xmlChildrenNode; |
576 | 752 | while (cur2 != NULL) { |
577 | 753 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "driver"))) { |
578 | printer->num_drivers ++; | |
579 | printer->drivers = | |
580 | (xmlChar **)realloc((xmlChar **)printer->drivers, | |
581 | sizeof(xmlChar *) * printer->num_drivers); | |
582 | printer->drivers[printer->num_drivers-1] = | |
754 | drivername = | |
583 | 755 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); |
756 | driverfound = 0; | |
757 | for (i = 0; i < printer->num_drivers; i++) { | |
758 | dentry = printer->drivers[i]; | |
759 | if ((dentry->name != NULL) && | |
760 | (!xmlStrcmp(drivername, dentry->name))) { | |
761 | driverfound = 1; | |
762 | break; | |
763 | } | |
764 | } | |
765 | if (!driverfound) { | |
766 | printer->num_drivers ++; | |
767 | printer->drivers = | |
768 | (printerDrvEntryPtr *) | |
769 | realloc((printerDrvEntryPtr *)printer->drivers, | |
770 | sizeof(printerDrvEntryPtr) * | |
771 | printer->num_drivers); | |
772 | dentry = (printerDrvEntryPtr) malloc(sizeof(printerDrvEntry)); | |
773 | if (dentry == NULL) { | |
774 | fprintf(stderr,"Out of memory!\n"); | |
775 | xmlFreeDoc(doc); | |
776 | exit(1); | |
777 | } | |
778 | printer->drivers[printer->num_drivers-1] = dentry; | |
779 | memset(dentry, 0, sizeof(printerDrvEntry)); | |
780 | dentry->name = NULL; | |
781 | dentry->comment = NULL; | |
782 | dentry->ppd = NULL; | |
783 | dentry->excmaxresx = NULL; | |
784 | dentry->excmaxresy = NULL; | |
785 | dentry->exccolor = NULL; | |
786 | dentry->exctext = NULL; | |
787 | dentry->exclineart = NULL; | |
788 | dentry->excgraphics = NULL; | |
789 | dentry->excphoto = NULL; | |
790 | dentry->excload = NULL; | |
791 | dentry->excspeed = NULL; | |
792 | } | |
793 | dentry->name = drivername; | |
584 | 794 | if (debug) fprintf(stderr, " Printer works with: %s\n", |
585 | printer->drivers[printer->num_drivers-1]); | |
795 | dentry->name); | |
796 | } | |
797 | cur2 = cur2->next; | |
798 | } | |
799 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "driverfunctionalityexceptions"))) { | |
800 | cur2 = cur1->xmlChildrenNode; | |
801 | while (cur2 != NULL) { | |
802 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "driverfunctionalityexception"))) { | |
803 | drivername = NULL; | |
804 | dentry = NULL; | |
805 | cur3 = cur2->xmlChildrenNode; | |
806 | while (cur3 != NULL) { | |
807 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) "driver"))) { | |
808 | drivername = | |
809 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1)); | |
810 | if (debug) | |
811 | fprintf(stderr, " Functionality exceptions for driver: %s\n", | |
812 | drivername); | |
813 | if ((dentry != NULL) && (dentry->name == NULL)) { | |
814 | dentry->name = drivername; | |
815 | /* Check whether there is already an entry for this driver | |
816 | and delete this old entry */ | |
817 | for (i = 0; i < printer->num_drivers - 1; i++) { | |
818 | if ((printer->drivers[i]->name != NULL) && | |
819 | (!xmlStrcmp(drivername, printer->drivers[i]->name))) { | |
820 | for (j = i + 1; j < printer->num_drivers; j++) | |
821 | printer->drivers[j - 1] = printer->drivers[j]; | |
822 | printer->num_drivers --; | |
823 | printer->drivers = | |
824 | (printerDrvEntryPtr *) | |
825 | realloc((printerDrvEntryPtr *)printer->drivers, | |
826 | sizeof(printerDrvEntryPtr) * | |
827 | printer->num_drivers); | |
828 | break; | |
829 | } | |
830 | } | |
831 | } | |
832 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) { | |
833 | driverfound = 0; | |
834 | dentry = NULL; | |
835 | if (drivername != NULL) { | |
836 | for (i = 0; i < printer->num_drivers; i++) { | |
837 | dentry = printer->drivers[i]; | |
838 | if ((dentry->name != NULL) && | |
839 | (!xmlStrcmp(drivername, dentry->name))) { | |
840 | driverfound = 1; | |
841 | break; | |
842 | } | |
843 | } | |
844 | } | |
845 | if (!driverfound) { | |
846 | printer->num_drivers ++; | |
847 | printer->drivers = | |
848 | (printerDrvEntryPtr *) | |
849 | realloc((printerDrvEntryPtr *)printer->drivers, | |
850 | sizeof(printerDrvEntryPtr) * | |
851 | printer->num_drivers); | |
852 | dentry = (printerDrvEntryPtr) malloc(sizeof(printerDrvEntry)); | |
853 | if (dentry == NULL) { | |
854 | fprintf(stderr,"Out of memory!\n"); | |
855 | xmlFreeDoc(doc); | |
856 | exit(1); | |
857 | } | |
858 | printer->drivers[printer->num_drivers-1] = dentry; | |
859 | memset(dentry, 0, sizeof(printerDrvEntry)); | |
860 | dentry->name = NULL; | |
861 | dentry->comment = NULL; | |
862 | dentry->ppd = NULL; | |
863 | dentry->excmaxresx = NULL; | |
864 | dentry->excmaxresy = NULL; | |
865 | dentry->exccolor = NULL; | |
866 | dentry->exctext = NULL; | |
867 | dentry->exclineart = NULL; | |
868 | dentry->excgraphics = NULL; | |
869 | dentry->excphoto = NULL; | |
870 | dentry->excload = NULL; | |
871 | dentry->excspeed = NULL; | |
872 | } | |
873 | dentry->name = drivername; | |
874 | if (drivername != NULL) { | |
875 | if (debug) | |
876 | fprintf(stderr, " Functionality exceptions for driver: %s\n", | |
877 | dentry->name); | |
878 | } | |
879 | cur4 = cur3->xmlChildrenNode; | |
880 | while (cur4 != NULL) { | |
881 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) { | |
882 | dentry->excmaxresx = | |
883 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
884 | if (debug) | |
885 | fprintf(stderr, " Maximum X resolution: %s\n", | |
886 | dentry->excmaxresx); | |
887 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) { | |
888 | dentry->excmaxresy = | |
889 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
890 | if (debug) | |
891 | fprintf(stderr, " Maximum Y resolution: %s\n", | |
892 | dentry->excmaxresy); | |
893 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) { | |
894 | dentry->exccolor = (xmlChar *)"0"; | |
895 | if (debug) | |
896 | fprintf(stderr, " Color: %s\n", | |
897 | dentry->exccolor); | |
898 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) { | |
899 | dentry->exccolor = (xmlChar *)"1"; | |
900 | if (debug) | |
901 | fprintf(stderr, " Color: %s\n", | |
902 | dentry->exccolor); | |
903 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) { | |
904 | dentry->exctext = | |
905 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
906 | if (debug) | |
907 | fprintf(stderr, " Support level for text: %s\n", | |
908 | dentry->exctext); | |
909 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) { | |
910 | dentry->exclineart = | |
911 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
912 | if (debug) | |
913 | fprintf(stderr, " Support level for line art: %s\n", | |
914 | dentry->exclineart); | |
915 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) { | |
916 | dentry->excgraphics = | |
917 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
918 | if (debug) | |
919 | fprintf(stderr, " Support level for graphics: %s\n", | |
920 | dentry->excgraphics); | |
921 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) { | |
922 | dentry->excphoto = | |
923 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
924 | if (debug) | |
925 | fprintf(stderr, " Support level for photos: %s\n", | |
926 | dentry->excphoto); | |
927 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) { | |
928 | dentry->excload = | |
929 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
930 | if (debug) | |
931 | fprintf(stderr, " Expected relative system load: %s\n", | |
932 | dentry->excload); | |
933 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) { | |
934 | dentry->excspeed = | |
935 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
936 | if (debug) | |
937 | fprintf(stderr, " Expected relative driver speed: %s\n", | |
938 | dentry->excspeed); | |
939 | } | |
940 | cur4 = cur4->next; | |
941 | } | |
942 | } | |
943 | cur3 = cur3->next; | |
944 | } | |
945 | } | |
946 | cur2 = cur2->next; | |
947 | } | |
948 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "ppds"))) { | |
949 | cur2 = cur1->xmlChildrenNode; | |
950 | while (cur2 != NULL) { | |
951 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ppd"))) { | |
952 | printer->num_ppdfiles ++; | |
953 | printer->ppdfiles = | |
954 | (ppdFilePtr *) | |
955 | realloc((ppdFilePtr *)printer->ppdfiles, | |
956 | sizeof(ppdFilePtr) * | |
957 | printer->num_ppdfiles); | |
958 | ppd = (ppdFilePtr) malloc(sizeof(ppdFile)); | |
959 | if (ppd == NULL) { | |
960 | fprintf(stderr,"Out of memory!\n"); | |
961 | xmlFreeDoc(doc); | |
962 | exit(1); | |
963 | } | |
964 | printer->ppdfiles[printer->num_ppdfiles-1] = ppd; | |
965 | memset(ppd, 0, sizeof(ppdFile)); | |
966 | ppd->driver = NULL; | |
967 | ppd->filename = NULL; | |
968 | if (debug) fprintf(stderr, " Available ready-made PPD file:\n"); | |
969 | cur3 = cur2->xmlChildrenNode; | |
970 | while (cur3 != NULL) { | |
971 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) "driver"))) { | |
972 | ppd->driver = | |
973 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1)); | |
974 | if (debug) fprintf(stderr, " For driver: %s\n", | |
975 | ppd->driver); | |
976 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ppdfile"))) { | |
977 | ppd->filename = | |
978 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1)); | |
979 | if (debug) fprintf(stderr, " File name: %s\n", | |
980 | ppd->filename); | |
981 | } | |
982 | cur3 = cur3->next; | |
983 | } | |
586 | 984 | } |
587 | 985 | cur2 = cur2->next; |
588 | 986 | } |
841 | 1239 | dentry->name = NULL; |
842 | 1240 | dentry->comment = NULL; |
843 | 1241 | dentry->ppd = NULL; |
1242 | dentry->excmaxresx = NULL; | |
1243 | dentry->excmaxresy = NULL; | |
1244 | dentry->exccolor = NULL; | |
1245 | dentry->exctext = NULL; | |
1246 | dentry->exclineart = NULL; | |
1247 | dentry->excgraphics = NULL; | |
1248 | dentry->excphoto = NULL; | |
1249 | dentry->excload = NULL; | |
1250 | dentry->excspeed = NULL; | |
844 | 1251 | if (debug) fprintf(stderr, " Printer supported by drivers:\n"); |
845 | 1252 | cur3 = cur2->xmlChildrenNode; |
846 | 1253 | while (cur3 != NULL) { |
856 | 1263 | dentry->ppd = perlquote(dppd); |
857 | 1264 | if (debug) fprintf(stderr, " Ready-made PPD: %s\n", |
858 | 1265 | dentry->ppd); |
859 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) { | |
1266 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) { | |
860 | 1267 | cur4 = cur3->xmlChildrenNode; |
861 | 1268 | while (cur4 != NULL) { |
862 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) language))) { | |
863 | dentry->comment = | |
864 | perlquote(xmlNodeListGetString(doc, | |
865 | cur4->xmlChildrenNode, | |
866 | 1)); | |
867 | if (debug) fprintf(stderr, " Comment (%s): \n%s\n\n", | |
868 | language, dentry->comment); | |
869 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "en"))) { | |
870 | if (!dentry->comment) { | |
871 | dentry->comment = | |
872 | perlquote(xmlNodeListGetString(doc, | |
873 | cur4->xmlChildrenNode, | |
874 | 1)); | |
875 | if (debug) fprintf(stderr, " Comment (en): \n%s\n\n", | |
876 | dentry->comment); | |
877 | } | |
1269 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) { | |
1270 | dentry->excmaxresx = | |
1271 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1272 | if (debug) | |
1273 | fprintf(stderr, " Maximum X resolution: %s\n", | |
1274 | dentry->excmaxresx); | |
1275 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) { | |
1276 | dentry->excmaxresy = | |
1277 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1278 | if (debug) | |
1279 | fprintf(stderr, " Maximum Y resolution: %s\n", | |
1280 | dentry->excmaxresy); | |
1281 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) { | |
1282 | dentry->exccolor = (xmlChar *)"0"; | |
1283 | if (debug) | |
1284 | fprintf(stderr, " Color: %s\n", | |
1285 | dentry->exccolor); | |
1286 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) { | |
1287 | dentry->exccolor = (xmlChar *)"1"; | |
1288 | if (debug) | |
1289 | fprintf(stderr, " Color: %s\n", | |
1290 | dentry->exccolor); | |
1291 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) { | |
1292 | dentry->exctext = | |
1293 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1294 | if (debug) | |
1295 | fprintf(stderr, " Support level for text: %s\n", | |
1296 | dentry->exctext); | |
1297 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) { | |
1298 | dentry->exclineart = | |
1299 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1300 | if (debug) | |
1301 | fprintf(stderr, " Support level for line art: %s\n", | |
1302 | dentry->exclineart); | |
1303 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) { | |
1304 | dentry->excgraphics = | |
1305 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1306 | if (debug) | |
1307 | fprintf(stderr, " Support level for graphics: %s\n", | |
1308 | dentry->excgraphics); | |
1309 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) { | |
1310 | dentry->excphoto = | |
1311 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1312 | if (debug) | |
1313 | fprintf(stderr, " Support level for photos: %s\n", | |
1314 | dentry->excphoto); | |
1315 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) { | |
1316 | dentry->excload = | |
1317 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1318 | if (debug) | |
1319 | fprintf(stderr, " Expected relative system load: %s\n", | |
1320 | dentry->excload); | |
1321 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) { | |
1322 | dentry->excspeed = | |
1323 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1324 | if (debug) | |
1325 | fprintf(stderr, " Expected relative driver speed: %s\n", | |
1326 | dentry->excspeed); | |
878 | 1327 | } |
879 | 1328 | cur4 = cur4->next; |
880 | 1329 | } |
1330 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) { | |
1331 | if (debug) | |
1332 | fprintf(stderr, " Comments:\n"); | |
1333 | getLocalizedText(doc, cur3, &(dentry->comment), language, debug); | |
881 | 1334 | } |
882 | 1335 | cur3 = cur3->next; |
883 | 1336 | } |
1110 | 1563 | xmlNodePtr cur1; /* XML node currently worked on */ |
1111 | 1564 | xmlNodePtr cur2; /* Another XML node pointer */ |
1112 | 1565 | xmlNodePtr cur3; /* Another XML node pointer */ |
1566 | xmlNodePtr cur4; /* Another XML node pointer */ | |
1113 | 1567 | xmlChar *id; /* Full driver ID, with "driver/" */ |
1568 | xmlChar *level, *version, *scope; | |
1569 | xmlChar *url; | |
1114 | 1570 | |
1115 | 1571 | /* Initialization of entries */ |
1116 | 1572 | ret->driver = NULL; |
1573 | ret->driver_group = NULL; | |
1117 | 1574 | ret->driver_type = NULL; |
1118 | 1575 | ret->driver_comment = NULL; |
1119 | 1576 | ret->url = NULL; |
1577 | ret->supplier = NULL; | |
1578 | ret->driver_obsolete = NULL; | |
1579 | ret->manufacturersupplied = NULL; | |
1580 | ret->license = NULL; | |
1581 | ret->licensetext = NULL; | |
1582 | ret->free = NULL; | |
1583 | ret->patents = NULL; | |
1584 | ret->num_supportcontacts = 0; | |
1585 | ret->supportcontacts = NULL; | |
1586 | ret->supportcontacturls = NULL; | |
1587 | ret->supportcontactlevels = NULL; | |
1588 | ret->shortdescription = NULL; | |
1589 | ret->locales = NULL; | |
1590 | ret->num_packages = 0; | |
1591 | ret->packageurls = NULL; | |
1592 | ret->packagescopes = NULL; | |
1593 | ret->drvmaxresx = NULL; | |
1594 | ret->drvmaxresy = NULL; | |
1595 | ret->drvcolor = NULL; | |
1596 | ret->text = NULL; | |
1597 | ret->lineart = NULL; | |
1598 | ret->graphics = NULL; | |
1599 | ret->photo = NULL; | |
1600 | ret->load = NULL; | |
1601 | ret->speed = NULL; | |
1602 | ret->excmaxresx = NULL; | |
1603 | ret->excmaxresy = NULL; | |
1604 | ret->exccolor = NULL; | |
1605 | ret->exctext = NULL; | |
1606 | ret->exclineart = NULL; | |
1607 | ret->excgraphics = NULL; | |
1608 | ret->excphoto = NULL; | |
1609 | ret->excload = NULL; | |
1610 | ret->excspeed = NULL; | |
1611 | ret->num_requires = 0; | |
1612 | ret->requires = NULL; | |
1613 | ret->requiresversion = NULL; | |
1120 | 1614 | ret->cmd = NULL; |
1121 | 1615 | ret->nopjl = (xmlChar *)"0"; |
1616 | ret->nopageaccounting = (xmlChar *)"0"; | |
1122 | 1617 | ret->driverppdentry = NULL; |
1123 | 1618 | ret->comboppdentry = NULL; |
1124 | 1619 | ret->drivermargins = NULL; |
1140 | 1635 | ret->driver = |
1141 | 1636 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); |
1142 | 1637 | if (debug) fprintf(stderr, " Driver name: %s\n", ret->driver); |
1638 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "group"))) { | |
1639 | ret->driver_group = | |
1640 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); | |
1641 | if (debug) fprintf(stderr, " Driver group (for localization): %s\n", | |
1642 | ret->driver_group); | |
1143 | 1643 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "pcdriver"))) { |
1144 | 1644 | ret->pcdriver = |
1145 | 1645 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); |
1146 | if (debug) fprintf(stderr, " Driver part of PC file name in PPD: %s\n", ret->pcdriver); | |
1646 | if (debug) fprintf(stderr, " Driver part of PC file name in PPD: %s\n", | |
1647 | ret->pcdriver); | |
1147 | 1648 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "url"))) { |
1148 | 1649 | ret->url = |
1149 | 1650 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); |
1150 | 1651 | if (debug) fprintf(stderr, " Driver URL: %s\n", ret->url); |
1151 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "comments"))) { | |
1652 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "obsolete"))) { | |
1653 | ret->driver_obsolete = xmlGetProp(cur1, (const xmlChar *) "replace"); | |
1654 | if (ret->driver_obsolete == NULL) { | |
1655 | if (debug) fprintf(stderr, " No replacement driver found!\n"); | |
1656 | ret->driver_obsolete = (xmlChar *)"1"; | |
1657 | } | |
1658 | if (debug) fprintf(stderr, " Driver is obsolete: %s\n", | |
1659 | ret->driver_obsolete); | |
1660 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supplier"))) { | |
1661 | if (debug) | |
1662 | fprintf(stderr, " Driver supplier:\n"); | |
1663 | getLocalizedText(doc, cur1, &(ret->supplier), language, debug); | |
1664 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "manufacturersupplied"))) { | |
1665 | ret->manufacturersupplied = | |
1666 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); | |
1667 | if ((ret->manufacturersupplied == NULL) || | |
1668 | (ret->manufacturersupplied[0] == '\0')) | |
1669 | ret->manufacturersupplied = (xmlChar *)"1"; | |
1670 | if (debug) fprintf(stderr, " Driver supplied by manufacturer: %s\n", | |
1671 | ret->manufacturersupplied); | |
1672 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "thirdpartysupplied"))) { | |
1673 | ret->manufacturersupplied = (xmlChar *)"0"; | |
1674 | if (debug) fprintf(stderr, " Driver supplied by a third party\n"); | |
1675 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "license"))) { | |
1676 | if (debug) | |
1677 | fprintf(stderr, " Driver license:\n"); | |
1678 | getLocalizedText(doc, cur1, &(ret->license), language, debug); | |
1679 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "licensetext"))) { | |
1680 | if (debug) | |
1681 | fprintf(stderr, " Driver license text:\n"); | |
1682 | getLocalizedText(doc, cur1, &(ret->licensetext), language, debug); | |
1683 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "freesoftware"))) { | |
1684 | ret->free = (xmlChar *)"1"; | |
1685 | if (debug) fprintf(stderr, " Driver is free software\n"); | |
1686 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nonfreesoftware"))) { | |
1687 | ret->free = (xmlChar *)"0"; | |
1688 | if (debug) fprintf(stderr, " Driver is not free software\n"); | |
1689 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "patents"))) { | |
1690 | ret->patents = (xmlChar *)"1"; | |
1691 | if (debug) fprintf(stderr, " There are patents applying to this driver's code\n"); | |
1692 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nopatents"))) { | |
1693 | ret->patents = (xmlChar *)"0"; | |
1694 | if (debug) fprintf(stderr, " There are no patents applying to this driver's code\n"); | |
1695 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supportcontacts"))) { | |
1696 | cur2 = cur1->xmlChildrenNode; | |
1697 | if (debug) fprintf(stderr, " Driver support contacts:\n"); | |
1698 | while (cur2 != NULL) { | |
1699 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "supportcontact"))) { | |
1700 | ret->num_supportcontacts ++; | |
1701 | ret->supportcontacts = | |
1702 | (xmlChar **) | |
1703 | realloc((xmlChar **)ret->supportcontacts, | |
1704 | sizeof(xmlChar *) * | |
1705 | ret->num_supportcontacts); | |
1706 | ret->supportcontacturls = | |
1707 | (xmlChar **) | |
1708 | realloc((xmlChar **)ret->supportcontacturls, | |
1709 | sizeof(xmlChar *) * | |
1710 | ret->num_supportcontacts); | |
1711 | ret->supportcontactlevels = | |
1712 | (xmlChar **) | |
1713 | realloc((xmlChar **)ret->supportcontactlevels, | |
1714 | sizeof(xmlChar *) * | |
1715 | ret->num_supportcontacts); | |
1716 | level = xmlGetProp(cur2, (const xmlChar *) "level"); | |
1717 | if (level == NULL) { | |
1718 | level = (xmlChar *)"Unknown"; | |
1719 | } | |
1720 | url = xmlGetProp(cur2, (const xmlChar *) "url"); | |
1721 | ret->supportcontactlevels[ret->num_supportcontacts - 1] = level; | |
1722 | ret->supportcontacturls[ret->num_supportcontacts - 1] = url; | |
1723 | getLocalizedText | |
1724 | (doc, cur2, | |
1725 | &(ret->supportcontacts[ret->num_supportcontacts - 1]), | |
1726 | language, debug); | |
1727 | if (debug) | |
1728 | fprintf(stderr, " %s (%s):\n %s\n", | |
1729 | ret->supportcontacts[ret->num_supportcontacts - 1], | |
1730 | ret->supportcontactlevels[ret->num_supportcontacts - 1], | |
1731 | ret->supportcontacturls[ret->num_supportcontacts - 1]); | |
1732 | } | |
1733 | cur2 = cur2->next; | |
1734 | } | |
1735 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "shortdescription"))) { | |
1736 | if (debug) | |
1737 | fprintf(stderr, " Driver short description:\n"); | |
1738 | getLocalizedText(doc, cur1, &(ret->shortdescription), language, debug); | |
1739 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "locales"))) { | |
1740 | ret->locales = | |
1741 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); | |
1742 | if (debug) fprintf(stderr, " Driver list of locales: %s\n", ret->locales); | |
1743 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "packages"))) { | |
1744 | cur2 = cur1->xmlChildrenNode; | |
1745 | if (debug) fprintf(stderr, " Driver downloadable packages:\n"); | |
1746 | while (cur2 != NULL) { | |
1747 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "package"))) { | |
1748 | ret->num_packages ++; | |
1749 | ret->packageurls = | |
1750 | (xmlChar **) | |
1751 | realloc((xmlChar **)ret->packageurls, | |
1752 | sizeof(xmlChar *) * | |
1753 | ret->num_packages); | |
1754 | ret->packagescopes = | |
1755 | (xmlChar **) | |
1756 | realloc((xmlChar **)ret->packagescopes, | |
1757 | sizeof(xmlChar *) * | |
1758 | ret->num_packages); | |
1759 | scope = xmlGetProp(cur2, (const xmlChar *) "scope"); | |
1760 | ret->packageurls[ret->num_packages - 1] = | |
1761 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1762 | ret->packagescopes[ret->num_packages - 1] = perlquote(scope); | |
1763 | if (debug) | |
1764 | fprintf(stderr, " %s (%s)\n", | |
1765 | ret->packageurls[ret->num_packages - 1], | |
1766 | ret->packagescopes[ret->num_packages - 1]); | |
1767 | } | |
1768 | cur2 = cur2->next; | |
1769 | } | |
1770 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "functionality"))) { | |
1152 | 1771 | cur2 = cur1->xmlChildrenNode; |
1153 | 1772 | while (cur2 != NULL) { |
1154 | /*if ((!xmlStrcmp(cur2->name, (const xmlChar *) language))) {*/ | |
1155 | if ((!xmlStrcmp(cur2->name, language))) { | |
1156 | ret->driver_comment = | |
1773 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresx"))) { | |
1774 | ret->drvmaxresx = | |
1157 | 1775 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); |
1158 | if (debug) fprintf(stderr, " Driver Comment (%s):\n\n%s\n\n", | |
1159 | language, ret->driver_comment); | |
1160 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "en"))) { | |
1161 | if (!ret->driver_comment) { | |
1162 | ret->driver_comment = | |
1163 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, | |
1164 | 1)); | |
1165 | if (debug) fprintf(stderr, " Driver Comment (en):\n\n%s\n\n", | |
1166 | ret->driver_comment); | |
1167 | } | |
1168 | } | |
1776 | if (debug) | |
1777 | fprintf(stderr, " Driver functionality: Max X resolution: %s\n", | |
1778 | ret->drvmaxresx); | |
1779 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresy"))) { | |
1780 | ret->drvmaxresy = | |
1781 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1782 | if (debug) | |
1783 | fprintf(stderr, " Driver functionality: Max Y resolution: %s\n", | |
1784 | ret->drvmaxresy); | |
1785 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "color"))) { | |
1786 | ret->drvcolor = (xmlChar *)"1"; | |
1787 | if (debug) fprintf(stderr, " Driver functionality: Color\n"); | |
1788 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "monochrome"))) { | |
1789 | ret->drvcolor = (xmlChar *)"0"; | |
1790 | if (debug) fprintf(stderr, " Driver functionality: Monochrome\n"); | |
1791 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "text"))) { | |
1792 | ret->text = | |
1793 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1794 | if (debug) | |
1795 | fprintf(stderr, " Driver functionality: Text support rating: %s\n", | |
1796 | ret->text); | |
1797 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "lineart"))) { | |
1798 | ret->lineart = | |
1799 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1800 | if (debug) | |
1801 | fprintf(stderr, " Driver functionality: Line art support rating: %s\n", | |
1802 | ret->lineart); | |
1803 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "graphics"))) { | |
1804 | ret->graphics = | |
1805 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1806 | if (debug) | |
1807 | fprintf(stderr, " Driver functionality: Graphics support rating: %s\n", | |
1808 | ret->graphics); | |
1809 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "photo"))) { | |
1810 | ret->photo = | |
1811 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1812 | if (debug) | |
1813 | fprintf(stderr, " Driver functionality: Photo support rating: %s\n", | |
1814 | ret->photo); | |
1815 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "load"))) { | |
1816 | ret->load = | |
1817 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1818 | if (debug) | |
1819 | fprintf(stderr, " Driver functionality: System load rating: %s\n", | |
1820 | ret->load); | |
1821 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "speed"))) { | |
1822 | ret->speed = | |
1823 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1824 | if (debug) | |
1825 | fprintf(stderr, " Driver functionality: Speed rating: %s\n", | |
1826 | ret->speed); | |
1827 | } | |
1169 | 1828 | cur2 = cur2->next; |
1170 | 1829 | } |
1171 | 1830 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "execution"))) { |
1172 | 1831 | cur2 = cur1->xmlChildrenNode; |
1173 | 1832 | while (cur2 != NULL) { |
1174 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ghostscript"))) { | |
1833 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "requires"))) { | |
1834 | ret->num_requires ++; | |
1835 | ret->requires = | |
1836 | (xmlChar **) | |
1837 | realloc((xmlChar **)ret->requires, | |
1838 | sizeof(xmlChar *) * | |
1839 | ret->num_requires); | |
1840 | ret->requiresversion = | |
1841 | (xmlChar **) | |
1842 | realloc((xmlChar **)ret->requiresversion, | |
1843 | sizeof(xmlChar *) * | |
1844 | ret->num_requires); | |
1845 | version = xmlGetProp(cur2, (const xmlChar *) "version"); | |
1846 | ret->requires[ret->num_requires - 1] = | |
1847 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
1848 | ret->requiresversion[ret->num_requires - 1] = perlquote(version); | |
1849 | if (debug) | |
1850 | if (!version) | |
1851 | fprintf(stderr, " Driver requires driver: %s\n", | |
1852 | ret->requires[ret->num_requires - 1]); | |
1853 | else | |
1854 | fprintf(stderr, " Driver requires driver: %s (%s)\n", | |
1855 | ret->requires[ret->num_requires - 1], | |
1856 | ret->requiresversion[ret->num_requires - 1]); | |
1857 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "cups"))) { | |
1858 | ret->driver_type = (xmlChar *)"C"; | |
1859 | if (debug) fprintf(stderr, " Driver type: CUPS Raster\n"); | |
1860 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ijs"))) { | |
1861 | ret->driver_type = (xmlChar *)"I"; | |
1862 | if (debug) fprintf(stderr, " Driver type: IJS\n"); | |
1863 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "opvp"))) { | |
1864 | ret->driver_type = (xmlChar *)"V"; | |
1865 | if (debug) fprintf(stderr, " Driver type: OpenPrinting Vector\n"); | |
1866 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ghostscript"))) { | |
1175 | 1867 | ret->driver_type = (xmlChar *)"G"; |
1176 | if (debug) fprintf(stderr, " Driver type: GhostScript\n"); | |
1868 | if (debug) fprintf(stderr, " Driver type: GhostScript built-in\n"); | |
1177 | 1869 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "filter"))) { |
1178 | 1870 | ret->driver_type = (xmlChar *)"F"; |
1179 | 1871 | if (debug) fprintf(stderr, " Driver type: Filter\n"); |
1180 | 1872 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "uniprint"))) { |
1181 | 1873 | ret->driver_type = (xmlChar *)"U"; |
1182 | if (debug) fprintf(stderr, " Driver type: Uniprint\n"); | |
1874 | if (debug) fprintf(stderr, " Driver type: GhostScript Uniprint\n"); | |
1183 | 1875 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "postscript"))) { |
1184 | 1876 | ret->driver_type = (xmlChar *)"P"; |
1185 | 1877 | if (debug) fprintf(stderr, " Driver type: PostScript\n"); |
1186 | 1878 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "nopjl"))) { |
1187 | 1879 | ret->nopjl = (xmlChar *)"1"; |
1188 | 1880 | if (debug) fprintf(stderr, " Driver suppresses PJL options\n"); |
1881 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "nopageaccounting"))) { | |
1882 | ret->nopageaccounting = (xmlChar *)"1"; | |
1883 | if (debug) fprintf(stderr, " Driver suppresses CUPS page accounting\n"); | |
1189 | 1884 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "prototype"))) { |
1190 | 1885 | ret->cmd = |
1191 | 1886 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); |
1201 | 1896 | } |
1202 | 1897 | cur2 = cur2->next; |
1203 | 1898 | } |
1899 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "comments"))) { | |
1900 | if (debug) | |
1901 | fprintf(stderr, " Driver Comment:\n"); | |
1902 | getLocalizedText(doc, cur1, &(ret->driver_comment), language, debug); | |
1204 | 1903 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "printers"))) { |
1205 | 1904 | cur2 = cur1->xmlChildrenNode; |
1206 | 1905 | while (cur2 != NULL) { |
1217 | 1916 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "margins"))) { |
1218 | 1917 | parseMargins(doc, cur3, &(ret->combomargins), |
1219 | 1918 | language, debug); |
1919 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) { | |
1920 | cur4 = cur3->xmlChildrenNode; | |
1921 | while (cur4 != NULL) { | |
1922 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) { | |
1923 | ret->excmaxresx = | |
1924 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1925 | if (debug) | |
1926 | fprintf(stderr, " Combo exception: Maximum X resolution: %s\n", | |
1927 | ret->excmaxresx); | |
1928 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) { | |
1929 | ret->excmaxresy = | |
1930 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1931 | if (debug) | |
1932 | fprintf(stderr, " Combo exception: Maximum Y resolution: %s\n", | |
1933 | ret->excmaxresy); | |
1934 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) { | |
1935 | ret->exccolor = (xmlChar *)"0"; | |
1936 | if (debug) | |
1937 | fprintf(stderr, " Combo exception: Color: %s\n", | |
1938 | ret->exccolor); | |
1939 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) { | |
1940 | ret->exccolor = (xmlChar *)"1"; | |
1941 | if (debug) | |
1942 | fprintf(stderr, " Combo exception: Color: %s\n", | |
1943 | ret->exccolor); | |
1944 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) { | |
1945 | ret->exctext = | |
1946 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1947 | if (debug) | |
1948 | fprintf(stderr, " Combo exception: Support level for text: %s\n", | |
1949 | ret->exctext); | |
1950 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) { | |
1951 | ret->exclineart = | |
1952 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1953 | if (debug) | |
1954 | fprintf(stderr, " Combo exception: Support level for line art: %s\n", | |
1955 | ret->exclineart); | |
1956 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) { | |
1957 | ret->excgraphics = | |
1958 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1959 | if (debug) | |
1960 | fprintf(stderr, " Combo exception: Support level for graphics: %s\n", | |
1961 | ret->excgraphics); | |
1962 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) { | |
1963 | ret->excphoto = | |
1964 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1965 | if (debug) | |
1966 | fprintf(stderr, " Combo exception: Support level for photos: %s\n", | |
1967 | ret->excphoto); | |
1968 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) { | |
1969 | ret->excload = | |
1970 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1971 | if (debug) | |
1972 | fprintf(stderr, " Combo exception: Expected relative system load: %s\n", | |
1973 | ret->excload); | |
1974 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) { | |
1975 | ret->excspeed = | |
1976 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
1977 | if (debug) | |
1978 | fprintf(stderr, " Combo exception: Expected relative driver speed: %s\n", | |
1979 | ret->excspeed); | |
1980 | } | |
1981 | cur4 = cur4->next; | |
1982 | } | |
1220 | 1983 | } |
1221 | 1984 | cur3 = cur3->next; |
1222 | 1985 | } |
1283 | 2046 | cur2 = cur1->xmlChildrenNode; |
1284 | 2047 | while (cur2 != NULL) { |
1285 | 2048 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ev_shortname"))) { |
1286 | cur3 = cur2->xmlChildrenNode; | |
1287 | while (cur3 != NULL) { | |
1288 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) "en"))) { | |
1289 | enum_val->value = | |
1290 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, | |
1291 | 1)); | |
1292 | if (debug) fprintf(stderr, " Choice short name: %s\n", | |
1293 | enum_val->value); | |
1294 | } | |
1295 | cur3 = cur3->next; | |
1296 | } | |
2049 | if (debug) | |
2050 | fprintf(stderr, " Choice short name (do not translate):\n"); | |
2051 | getLocalizedText(doc, cur2, &(enum_val->value), "C", debug); | |
1297 | 2052 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ev_longname"))) { |
1298 | cur3 = cur2->xmlChildrenNode; | |
1299 | while (cur3 != NULL) { | |
1300 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) language))) { | |
1301 | enum_val->comment = | |
1302 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, | |
1303 | 1)); | |
1304 | if (debug) fprintf(stderr," Choice long name (%s): %s\n", | |
1305 | language, enum_val->comment); | |
1306 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "en"))) { | |
1307 | if (!enum_val->comment) { | |
1308 | enum_val->comment = | |
1309 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, | |
1310 | 1)); | |
1311 | if (debug) fprintf(stderr, | |
1312 | " Choice long name (en): %s\n", | |
1313 | enum_val->comment); | |
1314 | } | |
1315 | } | |
1316 | cur3 = cur3->next; | |
1317 | } | |
2053 | if (debug) | |
2054 | fprintf(stderr, " Choice long name:\n"); | |
2055 | getLocalizedText(doc, cur2, &(enum_val->comment), language, debug); | |
1318 | 2056 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ev_driverval"))) { |
1319 | 2057 | enum_val->driverval = |
1320 | 2058 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); |
1411 | 2149 | cur2 = cur1->xmlChildrenNode; |
1412 | 2150 | while (cur2 != NULL) { |
1413 | 2151 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_shortname"))) { |
1414 | cur3 = cur2->xmlChildrenNode; | |
1415 | while (cur3 != NULL) { | |
1416 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) "en"))) { | |
1417 | option->name = | |
1418 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, | |
1419 | 1)); | |
1420 | if (debug) fprintf(stderr, " Option short name: %s\n", | |
1421 | option->name); | |
1422 | } | |
1423 | cur3 = cur3->next; | |
1424 | } | |
2152 | if (debug) | |
2153 | fprintf(stderr, " Option short name (do not translate):\n"); | |
2154 | getLocalizedText(doc, cur2, &(option->name), "C", debug); | |
1425 | 2155 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_shortname_false"))) { |
1426 | cur3 = cur2->xmlChildrenNode; | |
1427 | while (cur3 != NULL) { | |
1428 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) "en"))) { | |
1429 | option->name_false = | |
1430 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, | |
1431 | 1)); | |
1432 | if (debug) fprintf(stderr, | |
1433 | " Option short name if false: %s\n", | |
1434 | option->name_false); | |
1435 | } | |
1436 | cur3 = cur3->next; | |
1437 | } | |
2156 | if (debug) | |
2157 | fprintf(stderr, | |
2158 | " Option short name if false (do not translate):\n"); | |
2159 | getLocalizedText(doc, cur2, &(option->name_false), "C", debug); | |
1438 | 2160 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_longname"))) { |
1439 | cur3 = cur2->xmlChildrenNode; | |
1440 | while (cur3 != NULL) { | |
1441 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) language))) { | |
1442 | option->comment = | |
1443 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, | |
1444 | 1)); | |
1445 | if (debug) fprintf(stderr, " Option long name (%s): %s\n", | |
1446 | language, option->comment); | |
1447 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "en"))) { | |
1448 | if (!option->comment) { | |
1449 | option->comment = | |
1450 | perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, | |
1451 | 1)); | |
1452 | if (debug) fprintf(stderr, | |
1453 | " Option long name (en): %s\n", | |
1454 | option->comment); | |
1455 | } | |
1456 | } | |
1457 | cur3 = cur3->next; | |
1458 | } | |
2161 | if (debug) | |
2162 | fprintf(stderr, " Option long name:\n"); | |
2163 | getLocalizedText(doc, cur2, &(option->comment), language, debug); | |
1459 | 2164 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_execution"))) { |
1460 | 2165 | cur3 = cur2->xmlChildrenNode; |
1461 | 2166 | while (cur3 != NULL) { |
1703 | 2408 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "color"))) { |
1704 | 2409 | ret->color = (xmlChar *)"1"; |
1705 | 2410 | if (debug) fprintf(stderr, " Color printer\n"); |
2411 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "monochrome"))) { | |
2412 | ret->color = (xmlChar *)"0"; | |
2413 | if (debug) fprintf(stderr, " Monochrome printer\n"); | |
1706 | 2414 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "resolution"))) { |
1707 | 2415 | cur3 = cur2->xmlChildrenNode; |
1708 | 2416 | while (cur3 != NULL) { |
1739 | 2447 | cur3 = cur2->xmlChildrenNode; |
1740 | 2448 | while (cur3 != NULL) { |
1741 | 2449 | if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) { |
1742 | cur4 = cur3->xmlChildrenNode; | |
1743 | while (cur4 != NULL) { | |
1744 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) language))) { | |
1745 | ret->refill = | |
1746 | perlquote(xmlNodeListGetString(doc, | |
1747 | cur4->xmlChildrenNode, | |
1748 | 1)); | |
1749 | if (debug) fprintf(stderr, | |
1750 | " Consumables (%s): %s\n", | |
1751 | language, ret->refill); | |
1752 | ||
1753 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "en"))) { | |
1754 | if (!ret->refill) { | |
1755 | ret->refill = | |
1756 | perlquote(xmlNodeListGetString(doc, | |
1757 | cur4->xmlChildrenNode, | |
1758 | 1)); | |
1759 | if (debug) fprintf(stderr, | |
1760 | " Consumables (en): %s\n", | |
1761 | ret->refill); | |
1762 | } | |
1763 | } | |
1764 | cur4 = cur4->next; | |
1765 | } | |
2450 | if (debug) | |
2451 | fprintf(stderr, " Consumables:\n"); | |
2452 | getLocalizedText(doc, cur3, &(ret->refill), language, debug); | |
1766 | 2453 | } |
1767 | 2454 | cur3 = cur3->next; |
1768 | 2455 | } |
2002 | 2689 | if (debug) fprintf(stderr, " Contributed URL: %s\n", |
2003 | 2690 | ret->contriburl); |
2004 | 2691 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "comments"))) { |
2005 | cur2 = cur1->xmlChildrenNode; | |
2006 | while (cur2 != NULL) { | |
2007 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) language))) { | |
2008 | ret->comment = | |
2009 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2010 | if (debug) fprintf(stderr, " Comment (%s):\n\n%s\n\n", | |
2011 | language, ret->comment); | |
2012 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "en"))) { | |
2013 | if (!ret->comment) { | |
2014 | ret->comment = | |
2015 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2016 | if (debug) fprintf(stderr, " Comment (en):\n\n%s\n\n", | |
2017 | ret->comment); | |
2018 | } | |
2019 | } | |
2020 | cur2 = cur2->next; | |
2021 | } | |
2692 | if (debug) | |
2693 | fprintf(stderr, " Comment:\n"); | |
2694 | getLocalizedText(doc, cur1, &(ret->comment), language, debug); | |
2022 | 2695 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "drivers"))) { |
2023 | 2696 | cur2 = cur1->xmlChildrenNode; |
2024 | 2697 | while (cur2 != NULL) { |
2040 | 2713 | dentry->name = NULL; |
2041 | 2714 | dentry->comment = NULL; |
2042 | 2715 | dentry->ppd = NULL; |
2716 | dentry->excmaxresx = NULL; | |
2717 | dentry->excmaxresy = NULL; | |
2718 | dentry->exccolor = NULL; | |
2719 | dentry->exctext = NULL; | |
2720 | dentry->exclineart = NULL; | |
2721 | dentry->excgraphics = NULL; | |
2722 | dentry->excphoto = NULL; | |
2723 | dentry->excload = NULL; | |
2724 | dentry->excspeed = NULL; | |
2043 | 2725 | if (debug) fprintf(stderr, " Printer supported by drivers:\n"); |
2044 | 2726 | cur3 = cur2->xmlChildrenNode; |
2045 | 2727 | while (cur3 != NULL) { |
2056 | 2738 | if (debug) fprintf(stderr, " Ready-made PPD: %s\n", |
2057 | 2739 | dentry->ppd); |
2058 | 2740 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) { |
2059 | cur4 = cur3->xmlChildrenNode; | |
2060 | while (cur4 != NULL) { | |
2061 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) language))) { | |
2062 | dentry->comment = | |
2063 | perlquote(xmlNodeListGetString(doc, | |
2064 | cur4->xmlChildrenNode, | |
2065 | 1)); | |
2066 | if (debug) fprintf(stderr, " Comment (%s): \n%s\n\n", | |
2067 | language, dentry->comment); | |
2068 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "en"))) { | |
2069 | if (!dentry->comment) { | |
2070 | dentry->comment = | |
2071 | perlquote(xmlNodeListGetString(doc, | |
2072 | cur4->xmlChildrenNode, | |
2073 | 1)); | |
2074 | if (debug) fprintf(stderr, " Comment (en): \n%s\n\n", | |
2075 | dentry->comment); | |
2076 | } | |
2077 | } | |
2078 | cur4 = cur4->next; | |
2079 | } | |
2741 | if (debug) | |
2742 | fprintf(stderr, " Comment:\n"); | |
2743 | getLocalizedText(doc, cur3, &(dentry->comment), language, debug); | |
2080 | 2744 | } |
2081 | 2745 | cur3 = cur3->next; |
2082 | 2746 | } |
2101 | 2765 | xmlNodePtr cur4; /* Another XML node pointer */ |
2102 | 2766 | xmlChar *id; /* Full driver ID, with "driver/" */ |
2103 | 2767 | drvPrnEntryPtr entry; /* An entry for a printer supported by this driver*/ |
2768 | xmlChar *url, *level, *version, *scope; | |
2104 | 2769 | |
2105 | 2770 | /* Initialization of entries */ |
2106 | 2771 | ret->id = NULL; |
2107 | 2772 | ret->name = NULL; |
2773 | ret->group = NULL; | |
2108 | 2774 | ret->url = NULL; |
2775 | ret->driver_obsolete = NULL; | |
2776 | ret->supplier = NULL; | |
2777 | ret->manufacturersupplied = NULL; | |
2778 | ret->license = NULL; | |
2779 | ret->licensetext = NULL; | |
2780 | ret->free = NULL; | |
2781 | ret->patents = NULL; | |
2782 | ret->num_supportcontacts = 0; | |
2783 | ret->supportcontacts = NULL; | |
2784 | ret->supportcontacturls = NULL; | |
2785 | ret->supportcontactlevels = NULL; | |
2786 | ret->shortdescription = NULL; | |
2787 | ret->locales = NULL; | |
2788 | ret->num_packages = 0; | |
2789 | ret->packageurls = NULL; | |
2790 | ret->packagescopes = NULL; | |
2791 | ret->maxresx = NULL; | |
2792 | ret->maxresy = NULL; | |
2793 | ret->color = NULL; | |
2794 | ret->text = NULL; | |
2795 | ret->lineart = NULL; | |
2796 | ret->graphics = NULL; | |
2797 | ret->photo = NULL; | |
2798 | ret->load = NULL; | |
2799 | ret->speed = NULL; | |
2800 | ret->num_requires = 0; | |
2801 | ret->requires = NULL; | |
2802 | ret->requiresversion = NULL; | |
2109 | 2803 | ret->driver_type = NULL; |
2110 | 2804 | ret->cmd = NULL; |
2111 | 2805 | ret->driverppdentry = NULL; |
2130 | 2824 | ret->name = |
2131 | 2825 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); |
2132 | 2826 | if (debug) fprintf(stderr, " Driver name: %s\n", ret->name); |
2827 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "group"))) { | |
2828 | ret->group = | |
2829 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); | |
2830 | if (debug) fprintf(stderr, " Driver group (for localization): %s\n", | |
2831 | ret->group); | |
2133 | 2832 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "url"))) { |
2134 | 2833 | ret->url = |
2135 | 2834 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); |
2136 | 2835 | if (debug) fprintf(stderr, " Driver URL: %s\n", ret->url); |
2836 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "obsolete"))) { | |
2837 | ret->driver_obsolete = xmlGetProp(cur1, (const xmlChar *) "replace"); | |
2838 | if (ret->driver_obsolete == NULL) { | |
2839 | if (debug) fprintf(stderr, " No replacement driver found!\n"); | |
2840 | ret->driver_obsolete = (xmlChar *)"1"; | |
2841 | } | |
2842 | if (debug) fprintf(stderr, " Driver is obsolete: %s\n", | |
2843 | ret->driver_obsolete); | |
2844 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supplier"))) { | |
2845 | if (debug) | |
2846 | fprintf(stderr, " Driver supplier:\n"); | |
2847 | getLocalizedText(doc, cur1, &(ret->supplier), language, debug); | |
2848 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "manufacturersupplied"))) { | |
2849 | ret->manufacturersupplied = | |
2850 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); | |
2851 | if ((ret->manufacturersupplied == NULL) || | |
2852 | (ret->manufacturersupplied[0] == '\0')) | |
2853 | ret->manufacturersupplied = (xmlChar *)"1"; | |
2854 | if (debug) fprintf(stderr, " Driver supplied by manufacturer: %s\n", | |
2855 | ret->manufacturersupplied); | |
2856 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "thirdpartysupplied"))) { | |
2857 | ret->manufacturersupplied = (xmlChar *)"0"; | |
2858 | if (debug) fprintf(stderr, " Driver supplied by a third party\n"); | |
2859 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "license"))) { | |
2860 | if (debug) | |
2861 | fprintf(stderr, " Driver license:\n"); | |
2862 | getLocalizedText(doc, cur1, &(ret->license), language, debug); | |
2863 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "licensetext"))) { | |
2864 | if (debug) | |
2865 | fprintf(stderr, " Driver license text:\n"); | |
2866 | getLocalizedText(doc, cur1, &(ret->licensetext), language, debug); | |
2867 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "freesoftware"))) { | |
2868 | ret->free = (xmlChar *)"1"; | |
2869 | if (debug) fprintf(stderr, " Driver is free software\n"); | |
2870 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nonfreesoftware"))) { | |
2871 | ret->free = (xmlChar *)"0"; | |
2872 | if (debug) fprintf(stderr, " Driver is not free software\n"); | |
2873 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "patents"))) { | |
2874 | ret->patents = (xmlChar *)"1"; | |
2875 | if (debug) fprintf(stderr, " There are patents applying to this driver's code\n"); | |
2876 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nopatents"))) { | |
2877 | ret->patents = (xmlChar *)"0"; | |
2878 | if (debug) fprintf(stderr, " There are no patents applying to this driver's code\n"); | |
2879 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supportcontacts"))) { | |
2880 | cur2 = cur1->xmlChildrenNode; | |
2881 | if (debug) fprintf(stderr, " Driver support contacts:\n"); | |
2882 | while (cur2 != NULL) { | |
2883 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "supportcontact"))) { | |
2884 | ret->num_supportcontacts ++; | |
2885 | ret->supportcontacts = | |
2886 | (xmlChar **) | |
2887 | realloc((xmlChar **)ret->supportcontacts, | |
2888 | sizeof(xmlChar *) * | |
2889 | ret->num_supportcontacts); | |
2890 | ret->supportcontacturls = | |
2891 | (xmlChar **) | |
2892 | realloc((xmlChar **)ret->supportcontacturls, | |
2893 | sizeof(xmlChar *) * | |
2894 | ret->num_supportcontacts); | |
2895 | ret->supportcontactlevels = | |
2896 | (xmlChar **) | |
2897 | realloc((xmlChar **)ret->supportcontactlevels, | |
2898 | sizeof(xmlChar *) * | |
2899 | ret->num_supportcontacts); | |
2900 | level = xmlGetProp(cur2, (const xmlChar *) "level"); | |
2901 | if (level == NULL) { | |
2902 | level = (xmlChar *)"Unknown"; | |
2903 | } | |
2904 | url = xmlGetProp(cur2, (const xmlChar *) "url"); | |
2905 | ret->supportcontactlevels[ret->num_supportcontacts - 1] = level; | |
2906 | ret->supportcontacturls[ret->num_supportcontacts - 1] = url; | |
2907 | getLocalizedText | |
2908 | (doc, cur2, | |
2909 | &(ret->supportcontacts[ret->num_supportcontacts - 1]), | |
2910 | language, debug); | |
2911 | if (debug) | |
2912 | fprintf(stderr, " %s (%s):\n %s\n", | |
2913 | ret->supportcontacts[ret->num_supportcontacts - 1], | |
2914 | ret->supportcontactlevels[ret->num_supportcontacts - 1], | |
2915 | ret->supportcontacturls[ret->num_supportcontacts - 1]); | |
2916 | } | |
2917 | cur2 = cur2->next; | |
2918 | } | |
2919 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "shortdescription"))) { | |
2920 | if (debug) | |
2921 | fprintf(stderr, " Driver short description:\n"); | |
2922 | getLocalizedText(doc, cur1, &(ret->shortdescription), language, debug); | |
2923 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "locales"))) { | |
2924 | ret->locales = | |
2925 | perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)); | |
2926 | if (debug) fprintf(stderr, " Driver list of locales: %s\n", ret->locales); | |
2927 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "packages"))) { | |
2928 | cur2 = cur1->xmlChildrenNode; | |
2929 | if (debug) fprintf(stderr, " Driver downloadable packages:\n"); | |
2930 | while (cur2 != NULL) { | |
2931 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "package"))) { | |
2932 | ret->num_packages ++; | |
2933 | ret->packageurls = | |
2934 | (xmlChar **) | |
2935 | realloc((xmlChar **)ret->packageurls, | |
2936 | sizeof(xmlChar *) * | |
2937 | ret->num_packages); | |
2938 | ret->packagescopes = | |
2939 | (xmlChar **) | |
2940 | realloc((xmlChar **)ret->packagescopes, | |
2941 | sizeof(xmlChar *) * | |
2942 | ret->num_packages); | |
2943 | scope = xmlGetProp(cur2, (const xmlChar *) "scope"); | |
2944 | ret->packageurls[ret->num_packages - 1] = | |
2945 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2946 | ret->packagescopes[ret->num_packages - 1] = perlquote(scope); | |
2947 | if (debug) | |
2948 | fprintf(stderr, " %s (%s)\n", | |
2949 | ret->packageurls[ret->num_packages - 1], | |
2950 | ret->packagescopes[ret->num_packages - 1]); | |
2951 | } | |
2952 | cur2 = cur2->next; | |
2953 | } | |
2954 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "functionality"))) { | |
2955 | cur2 = cur1->xmlChildrenNode; | |
2956 | while (cur2 != NULL) { | |
2957 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresx"))) { | |
2958 | ret->maxresx = | |
2959 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2960 | if (debug) | |
2961 | fprintf(stderr, " Driver functionality: Max X resolution: %s\n", | |
2962 | ret->maxresx); | |
2963 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresy"))) { | |
2964 | ret->maxresy = | |
2965 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2966 | if (debug) | |
2967 | fprintf(stderr, " Driver functionality: Max Y resolution: %s\n", | |
2968 | ret->maxresy); | |
2969 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "color"))) { | |
2970 | ret->color = (xmlChar *)"1"; | |
2971 | if (debug) fprintf(stderr, " Driver functionality: Color\n"); | |
2972 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "monochrome"))) { | |
2973 | ret->color = (xmlChar *)"0"; | |
2974 | if (debug) fprintf(stderr, " Driver functionality: Monochrome\n"); | |
2975 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "text"))) { | |
2976 | ret->text = | |
2977 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2978 | if (debug) | |
2979 | fprintf(stderr, " Driver functionality: Text support rating: %s\n", | |
2980 | ret->text); | |
2981 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "lineart"))) { | |
2982 | ret->lineart = | |
2983 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2984 | if (debug) | |
2985 | fprintf(stderr, " Driver functionality: Line art support rating: %s\n", | |
2986 | ret->lineart); | |
2987 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "graphics"))) { | |
2988 | ret->graphics = | |
2989 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2990 | if (debug) | |
2991 | fprintf(stderr, " Driver functionality: Graphics support rating: %s\n", | |
2992 | ret->graphics); | |
2993 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "photo"))) { | |
2994 | ret->photo = | |
2995 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2996 | if (debug) | |
2997 | fprintf(stderr, " Driver functionality: Photo support rating: %s\n", | |
2998 | ret->photo); | |
2999 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "load"))) { | |
3000 | ret->load = | |
3001 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
3002 | if (debug) | |
3003 | fprintf(stderr, " Driver functionality: System load rating: %s\n", | |
3004 | ret->load); | |
3005 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "speed"))) { | |
3006 | ret->speed = | |
3007 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
3008 | if (debug) | |
3009 | fprintf(stderr, " Driver functionality: Speed rating: %s\n", | |
3010 | ret->speed); | |
3011 | } | |
3012 | cur2 = cur2->next; | |
3013 | } | |
2137 | 3014 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "execution"))) { |
2138 | 3015 | cur2 = cur1->xmlChildrenNode; |
2139 | 3016 | while (cur2 != NULL) { |
2140 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ghostscript"))) { | |
3017 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) "requires"))) { | |
3018 | ret->num_requires ++; | |
3019 | ret->requires = | |
3020 | (xmlChar **) | |
3021 | realloc((xmlChar **)ret->requires, | |
3022 | sizeof(xmlChar *) * | |
3023 | ret->num_requires); | |
3024 | ret->requiresversion = | |
3025 | (xmlChar **) | |
3026 | realloc((xmlChar **)ret->requiresversion, | |
3027 | sizeof(xmlChar *) * | |
3028 | ret->num_requires); | |
3029 | version = xmlGetProp(cur2, (const xmlChar *) "version"); | |
3030 | ret->requires[ret->num_requires - 1] = | |
3031 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
3032 | ret->requiresversion[ret->num_requires - 1] = perlquote(version); | |
3033 | if (debug) | |
3034 | if (!version) | |
3035 | fprintf(stderr, " Driver requires driver: %s\n", | |
3036 | ret->requires[ret->num_requires - 1]); | |
3037 | else | |
3038 | fprintf(stderr, " Driver requires driver: %s (%s)\n", | |
3039 | ret->requires[ret->num_requires - 1], | |
3040 | ret->requiresversion[ret->num_requires - 1]); | |
3041 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "cups"))) { | |
3042 | ret->driver_type = (xmlChar *)"C"; | |
3043 | if (debug) fprintf(stderr, " Driver type: CUPS Raster\n"); | |
3044 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ijs"))) { | |
3045 | ret->driver_type = (xmlChar *)"I"; | |
3046 | if (debug) fprintf(stderr, " Driver type: IJS\n"); | |
3047 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "opvp"))) { | |
3048 | ret->driver_type = (xmlChar *)"V"; | |
3049 | if (debug) fprintf(stderr, " Driver type: OpenPrinting Vector\n"); | |
3050 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ghostscript"))) { | |
2141 | 3051 | ret->driver_type = (xmlChar *)"G"; |
2142 | if (debug) fprintf(stderr, " Driver type: GhostScript\n"); | |
3052 | if (debug) fprintf(stderr, " Driver type: GhostScript built-in\n"); | |
2143 | 3053 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "filter"))) { |
2144 | 3054 | ret->driver_type = (xmlChar *)"F"; |
2145 | 3055 | if (debug) fprintf(stderr, " Driver type: Filter\n"); |
2146 | 3056 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "uniprint"))) { |
2147 | 3057 | ret->driver_type = (xmlChar *)"U"; |
2148 | if (debug) fprintf(stderr, " Driver type: Uniprint\n"); | |
3058 | if (debug) fprintf(stderr, " Driver type: GhostScript Uniprint\n"); | |
2149 | 3059 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "postscript"))) { |
2150 | 3060 | ret->driver_type = (xmlChar *)"P"; |
2151 | 3061 | if (debug) fprintf(stderr, " Driver type: PostScript\n"); |
2165 | 3075 | cur2 = cur2->next; |
2166 | 3076 | } |
2167 | 3077 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "comments"))) { |
2168 | cur2 = cur1->xmlChildrenNode; | |
2169 | while (cur2 != NULL) { | |
2170 | if ((!xmlStrcmp(cur2->name, (const xmlChar *) language))) { | |
2171 | ret->comment = | |
2172 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2173 | if (debug) fprintf(stderr, " Comment (%s):\n\n%s\n\n", | |
2174 | language, ret->comment); | |
2175 | } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "en"))) { | |
2176 | if (!ret->comment) { | |
2177 | ret->comment = | |
2178 | perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1)); | |
2179 | if (debug) fprintf(stderr, " Comment (en):\n\n%s\n\n", | |
2180 | ret->comment); | |
2181 | } | |
2182 | } | |
2183 | cur2 = cur2->next; | |
2184 | } | |
3078 | if (debug) | |
3079 | fprintf(stderr, " Comment:\n"); | |
3080 | getLocalizedText(doc, cur1, &(ret->comment), language, debug); | |
2185 | 3081 | } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "printers"))) { |
2186 | 3082 | cur2 = cur1->xmlChildrenNode; |
2187 | 3083 | while (cur2 != NULL) { |
2201 | 3097 | memset(entry, 0, sizeof(drvPrnEntry)); |
2202 | 3098 | entry->id = NULL; |
2203 | 3099 | entry->comment = NULL; |
3100 | entry->excmaxresx = NULL; | |
3101 | entry->excmaxresy = NULL; | |
3102 | entry->exccolor = NULL; | |
3103 | entry->exctext = NULL; | |
3104 | entry->exclineart = NULL; | |
3105 | entry->excgraphics = NULL; | |
3106 | entry->excphoto = NULL; | |
3107 | entry->excload = NULL; | |
3108 | entry->excspeed = NULL; | |
2204 | 3109 | if (debug) fprintf(stderr, " Driver supports printer:\n"); |
2205 | 3110 | cur3 = cur2->xmlChildrenNode; |
2206 | 3111 | while (cur3 != NULL) { |
2211 | 3116 | if (debug) fprintf(stderr, " ID: %s\n", |
2212 | 3117 | entry->id); |
2213 | 3118 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) { |
3119 | if (debug) | |
3120 | fprintf(stderr, " Comment:\n"); | |
3121 | getLocalizedText(doc, cur3, &(entry->comment), language, debug); | |
3122 | } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) { | |
2214 | 3123 | cur4 = cur3->xmlChildrenNode; |
2215 | 3124 | while (cur4 != NULL) { |
2216 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) language))) { | |
2217 | entry->comment = | |
2218 | perlquote(xmlNodeListGetString(doc, | |
2219 | cur4->xmlChildrenNode, | |
2220 | 1)); | |
2221 | if (debug) fprintf(stderr, " Comment (%s): \n%s\n\n", | |
2222 | language, entry->comment); | |
2223 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "en"))) { | |
2224 | if (!entry->comment) { | |
2225 | entry->comment = | |
2226 | perlquote(xmlNodeListGetString(doc, | |
2227 | cur4->xmlChildrenNode, | |
2228 | 1)); | |
2229 | if (debug) fprintf(stderr, " Comment (en): \n%s\n\n", | |
2230 | entry->comment); | |
2231 | } | |
3125 | if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) { | |
3126 | entry->excmaxresx = | |
3127 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3128 | if (debug) | |
3129 | fprintf(stderr, " Printer exception: Maximum X resolution: %s\n", | |
3130 | entry->excmaxresx); | |
3131 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) { | |
3132 | entry->excmaxresy = | |
3133 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3134 | if (debug) | |
3135 | fprintf(stderr, " Printer exception: Maximum Y resolution: %s\n", | |
3136 | entry->excmaxresy); | |
3137 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) { | |
3138 | entry->exccolor = (xmlChar *)"0"; | |
3139 | if (debug) | |
3140 | fprintf(stderr, " Printer exception: Color: %s\n", | |
3141 | entry->exccolor); | |
3142 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) { | |
3143 | entry->exccolor = (xmlChar *)"1"; | |
3144 | if (debug) | |
3145 | fprintf(stderr, " Printer exception: Color: %s\n", | |
3146 | entry->exccolor); | |
3147 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) { | |
3148 | entry->exctext = | |
3149 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3150 | if (debug) | |
3151 | fprintf(stderr, " Printer exception: Support level for text: %s\n", | |
3152 | entry->exctext); | |
3153 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) { | |
3154 | entry->exclineart = | |
3155 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3156 | if (debug) | |
3157 | fprintf(stderr, " Printer exception: Support level for line art: %s\n", | |
3158 | entry->exclineart); | |
3159 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) { | |
3160 | entry->excgraphics = | |
3161 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3162 | if (debug) | |
3163 | fprintf(stderr, " Printer exception: Support level for graphics: %s\n", | |
3164 | entry->excgraphics); | |
3165 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) { | |
3166 | entry->excphoto = | |
3167 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3168 | if (debug) | |
3169 | fprintf(stderr, " Printer exception: Support level for photos: %s\n", | |
3170 | entry->excphoto); | |
3171 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) { | |
3172 | entry->excload = | |
3173 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3174 | if (debug) | |
3175 | fprintf(stderr, " Printer exception: Expected relative system load: %s\n", | |
3176 | entry->excload); | |
3177 | } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) { | |
3178 | entry->excspeed = | |
3179 | perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1)); | |
3180 | if (debug) | |
3181 | fprintf(stderr, " Printer exception: Expected relative driver speed: %s\n", | |
3182 | entry->excspeed); | |
2232 | 3183 | } |
2233 | 3184 | cur4 = cur4->next; |
2234 | 3185 | } |
2276 | 3227 | xmlDocPtr doc; /* Output of XML parser */ |
2277 | 3228 | overviewPtr ret; /* C data structure of overview */ |
2278 | 3229 | xmlNodePtr cur; /* XML node currently worked on */ |
3230 | driverEntryPtr driver; | |
2279 | 3231 | |
2280 | 3232 | /* |
2281 | 3233 | * build an XML tree from a file or stdin; |
2330 | 3282 | cur = cur->next; |
2331 | 3283 | continue; |
2332 | 3284 | } |
2333 | if (!xmlStrcmp(cur->name, (const xmlChar *) "printer")) { | |
3285 | if (!xmlStrcmp(cur->name, (const xmlChar *) "driver")) { | |
3286 | ret->num_overviewDrivers ++; | |
3287 | ret->overviewDrivers = | |
3288 | (driverEntryPtr *)realloc | |
3289 | ((driverEntryPtr *)(ret->overviewDrivers), | |
3290 | sizeof(driverEntryPtr) * ret->num_overviewDrivers); | |
3291 | driver = (driverEntryPtr) malloc(sizeof(driverEntry)); | |
3292 | if (driver == NULL) { | |
3293 | fprintf(stderr,"Out of memory!\n"); | |
3294 | xmlFreeDoc(doc); | |
3295 | exit(1); | |
3296 | } | |
3297 | ret->overviewDrivers[ret->num_overviewDrivers-1] = driver; | |
3298 | memset(driver, 0, sizeof(driverEntry)); | |
3299 | if (debug) fprintf(stderr, "--> Parsing driver data\n"); | |
3300 | parseDriverEntry(doc, cur, driver, language, debug); | |
3301 | } else if (!xmlStrcmp(cur->name, (const xmlChar *) "printer")) { | |
2334 | 3302 | if (debug) fprintf(stderr, "--> Parsing printer data\n"); |
2335 | 3303 | parseOverviewPrinter(doc, cur, ret, language, debug); |
2336 | 3304 | } |
2610 | 3578 | input */ |
2611 | 3579 | int debug) { /* Debug flag */ |
2612 | 3580 | |
2613 | int i, j; /* loop variables */ | |
3581 | int i, j, k, l; /* loop variables */ | |
2614 | 3582 | overviewPrinterPtr printer; |
2615 | 3583 | |
2616 | 3584 | printf("$VAR1 = [\n"); |
2693 | 3661 | } |
2694 | 3662 | if (printer->num_drivers > 0) { |
2695 | 3663 | printf(" 'drivers' => [\n"); |
3664 | for (j = 0; j < printer->num_drivers; j ++) | |
3665 | if (printer->drivers[j]->name != NULL) | |
3666 | printf(" '%s',\n", | |
3667 | printer->drivers[j]->name); | |
3668 | printf(" ],\n"); | |
3669 | printf(" 'driverproperties' => {\n"); | |
2696 | 3670 | for (j = 0; j < printer->num_drivers; j ++) { |
2697 | printf(" '%s',\n", | |
2698 | printer->drivers[j]); | |
2699 | } | |
2700 | printf(" ]\n"); | |
3671 | for (k = 0; k < overview->num_overviewDrivers; k ++) { | |
3672 | if (!xmlStrcmp(overview->overviewDrivers[k]->name, | |
3673 | printer->drivers[j]->name)) break; | |
3674 | } | |
3675 | if ((k < overview->num_overviewDrivers) && | |
3676 | (!xmlStrcmp(overview->overviewDrivers[k]->name, | |
3677 | printer->drivers[j]->name))) { | |
3678 | printf(" '%s' => {\n", | |
3679 | printer->drivers[j]->name); | |
3680 | if (overview->overviewDrivers[k]->group != NULL) { | |
3681 | printf(" 'group' => '%s',\n", | |
3682 | overview->overviewDrivers[k]->group); | |
3683 | } | |
3684 | if (overview->overviewDrivers[k]->url != NULL) { | |
3685 | printf(" 'url' => '%s',\n", | |
3686 | overview->overviewDrivers[k]->url); | |
3687 | } | |
3688 | if (overview->overviewDrivers[k]->driver_obsolete != NULL) { | |
3689 | printf(" 'obsolete' => '%s',\n", | |
3690 | overview->overviewDrivers[k]->driver_obsolete); | |
3691 | } | |
3692 | if (overview->overviewDrivers[k]->supplier != NULL) { | |
3693 | printf(" 'supplier' => '%s',\n", | |
3694 | overview->overviewDrivers[k]->supplier); | |
3695 | } | |
3696 | if (overview->overviewDrivers[k]->manufacturersupplied != NULL) { | |
3697 | printf(" 'manufacturersupplied' => '%s',\n", | |
3698 | overview->overviewDrivers[k]->manufacturersupplied); | |
3699 | } | |
3700 | if (overview->overviewDrivers[k]->license != NULL) { | |
3701 | printf(" 'license' => '%s',\n", | |
3702 | overview->overviewDrivers[k]->license); | |
3703 | } | |
3704 | if (overview->overviewDrivers[k]->licensetext != NULL) { | |
3705 | printf(" 'licensetext' => '%s',\n", | |
3706 | overview->overviewDrivers[k]->licensetext); | |
3707 | } | |
3708 | if (overview->overviewDrivers[k]->free != NULL) { | |
3709 | printf(" 'free' => '%s',\n", | |
3710 | overview->overviewDrivers[k]->free); | |
3711 | } | |
3712 | if (overview->overviewDrivers[k]->patents != NULL) { | |
3713 | printf(" 'patents' => '%s',\n", | |
3714 | overview->overviewDrivers[k]->patents); | |
3715 | } | |
3716 | if (overview->overviewDrivers[k]->num_supportcontacts != 0) { | |
3717 | printf(" 'supportcontacts' => [\n"); | |
3718 | for (l = 0; | |
3719 | l < overview->overviewDrivers[k]->num_supportcontacts; l ++) { | |
3720 | if (overview->overviewDrivers[k]->supportcontacturls[l] != | |
3721 | NULL) { | |
3722 | printf(" {\n"); | |
3723 | printf(" 'description' => '%s',\n", | |
3724 | overview->overviewDrivers[k]->supportcontacts[l]); | |
3725 | if (overview->overviewDrivers[k]->supportcontacturls[l] | |
3726 | != NULL) | |
3727 | printf(" 'url' => '%s',\n", | |
3728 | overview->overviewDrivers[k]->supportcontacturls[l]); | |
3729 | printf(" 'level' => '%s',\n", | |
3730 | overview->overviewDrivers[k]->supportcontactlevels[l]); | |
3731 | printf(" },\n"); | |
3732 | } | |
3733 | } | |
3734 | printf(" ],\n"); | |
3735 | } | |
3736 | if (overview->overviewDrivers[k]->shortdescription != NULL) { | |
3737 | printf(" 'shortdescription' => '%s',\n", | |
3738 | overview->overviewDrivers[k]->shortdescription); | |
3739 | } | |
3740 | if (overview->overviewDrivers[k]->locales != NULL) { | |
3741 | printf(" 'locales' => '%s',\n", | |
3742 | overview->overviewDrivers[k]->locales); | |
3743 | } | |
3744 | if (overview->overviewDrivers[k]->num_packages != 0) { | |
3745 | printf(" 'packages' => [\n"); | |
3746 | for (l = 0; | |
3747 | l < overview->overviewDrivers[k]->num_packages; l ++) { | |
3748 | if (overview->overviewDrivers[k]->packageurls[l] != | |
3749 | NULL) { | |
3750 | printf(" {\n"); | |
3751 | printf(" 'url' => '%s',\n", | |
3752 | overview->overviewDrivers[k]->packageurls[l]); | |
3753 | if (overview->overviewDrivers[k]->packagescopes[l] | |
3754 | != NULL) | |
3755 | printf(" 'scope' => '%s',\n", | |
3756 | overview->overviewDrivers[k]->packagescopes[l]); | |
3757 | printf(" },\n"); | |
3758 | } | |
3759 | } | |
3760 | printf(" ],\n"); | |
3761 | } | |
3762 | if (overview->overviewDrivers[k]->num_requires != 0) { | |
3763 | printf(" 'requires' => [\n"); | |
3764 | for (l = 0; | |
3765 | l < overview->overviewDrivers[k]->num_requires; l ++) { | |
3766 | if (overview->overviewDrivers[k]->requires[l] != | |
3767 | NULL) { | |
3768 | printf(" {\n"); | |
3769 | printf(" 'driver' => '%s',\n", | |
3770 | overview->overviewDrivers[k]->requires[l]); | |
3771 | if (overview->overviewDrivers[k]->requiresversion[l] | |
3772 | != NULL) | |
3773 | printf(" 'version' => '%s',\n", | |
3774 | overview->overviewDrivers[k]->requiresversion[l]); | |
3775 | printf(" },\n"); | |
3776 | } | |
3777 | } | |
3778 | printf(" ],\n"); | |
3779 | } | |
3780 | if (overview->overviewDrivers[k]->driver_type != NULL) { | |
3781 | printf(" 'type' => '%s',\n", | |
3782 | overview->overviewDrivers[k]->driver_type); | |
3783 | } | |
3784 | if (printer->drivers[j]->excmaxresx != NULL) { | |
3785 | printf(" 'drvmaxresx' => '%s',\n", | |
3786 | printer->drivers[j]->excmaxresx); | |
3787 | } else if (overview->overviewDrivers[k]->maxresx != NULL) { | |
3788 | printf(" 'drvmaxresx' => '%s',\n", | |
3789 | overview->overviewDrivers[k]->maxresx); | |
3790 | } | |
3791 | if (printer->drivers[j]->excmaxresy != NULL) { | |
3792 | printf(" 'drvmaxresy' => '%s',\n", | |
3793 | printer->drivers[j]->excmaxresy); | |
3794 | } else if (overview->overviewDrivers[k]->maxresy != NULL) { | |
3795 | printf(" 'drvmaxresy' => '%s',\n", | |
3796 | overview->overviewDrivers[k]->maxresy); | |
3797 | } | |
3798 | if (printer->drivers[j]->exccolor != NULL) { | |
3799 | printf(" 'drvcolor' => '%s',\n", | |
3800 | printer->drivers[j]->exccolor); | |
3801 | } else if (overview->overviewDrivers[k]->color != NULL) { | |
3802 | printf(" 'drvcolor' => '%s',\n", | |
3803 | overview->overviewDrivers[k]->color); | |
3804 | } | |
3805 | if (printer->drivers[j]->exctext != NULL) { | |
3806 | printf(" 'text' => '%s',\n", | |
3807 | printer->drivers[j]->exctext); | |
3808 | } else if (overview->overviewDrivers[k]->text != NULL) { | |
3809 | printf(" 'text' => '%s',\n", | |
3810 | overview->overviewDrivers[k]->text); | |
3811 | } | |
3812 | if (printer->drivers[j]->exclineart != NULL) { | |
3813 | printf(" 'lineart' => '%s',\n", | |
3814 | printer->drivers[j]->exclineart); | |
3815 | } else if (overview->overviewDrivers[k]->lineart != NULL) { | |
3816 | printf(" 'lineart' => '%s',\n", | |
3817 | overview->overviewDrivers[k]->lineart); | |
3818 | } | |
3819 | if (printer->drivers[j]->excgraphics != NULL) { | |
3820 | printf(" 'graphics' => '%s',\n", | |
3821 | printer->drivers[j]->excgraphics); | |
3822 | } else if (overview->overviewDrivers[k]->graphics != NULL) { | |
3823 | printf(" 'graphics' => '%s',\n", | |
3824 | overview->overviewDrivers[k]->graphics); | |
3825 | } | |
3826 | if (printer->drivers[j]->excphoto != NULL) { | |
3827 | printf(" 'photo' => '%s',\n", | |
3828 | printer->drivers[j]->excphoto); | |
3829 | } else if (overview->overviewDrivers[k]->photo != NULL) { | |
3830 | printf(" 'photo' => '%s',\n", | |
3831 | overview->overviewDrivers[k]->photo); | |
3832 | } | |
3833 | if (printer->drivers[j]->excload != NULL) { | |
3834 | printf(" 'load' => '%s',\n", | |
3835 | printer->drivers[j]->excload); | |
3836 | } else if (overview->overviewDrivers[k]->load != NULL) { | |
3837 | printf(" 'load' => '%s',\n", | |
3838 | overview->overviewDrivers[k]->load); | |
3839 | } | |
3840 | if (printer->drivers[j]->excspeed != NULL) { | |
3841 | printf(" 'speed' => '%s',\n", | |
3842 | printer->drivers[j]->excspeed); | |
3843 | } else if (overview->overviewDrivers[k]->speed != NULL) { | |
3844 | printf(" 'speed' => '%s',\n", | |
3845 | overview->overviewDrivers[k]->speed); | |
3846 | } | |
3847 | printf(" },\n"); | |
3848 | } | |
3849 | } | |
3850 | printf(" },\n"); | |
2701 | 3851 | } else { |
2702 | printf(" 'drivers' => []\n"); | |
3852 | printf(" 'drivers' => [],\n"); | |
3853 | } | |
3854 | if (printer->num_ppdfiles > 0) { | |
3855 | printf(" 'ppds' => [\n"); | |
3856 | for (j = 0; j < printer->num_ppdfiles; j ++) | |
3857 | if ((printer->ppdfiles[j]->driver != NULL) && | |
3858 | (printer->ppdfiles[j]->filename != NULL)) { | |
3859 | printf(" {\n"); | |
3860 | printf(" 'driver' => '%s',\n", | |
3861 | printer->ppdfiles[j]->driver); | |
3862 | printf(" 'ppdfile' => '%s',\n", | |
3863 | printer->ppdfiles[j]->filename); | |
3864 | printf(" },\n"); | |
3865 | } | |
3866 | printf(" ],\n"); | |
2703 | 3867 | } |
2704 | 3868 | printf(" },\n"); |
2705 | 3869 | } |
2927 | 4091 | printf(" 'snmp_cmd' => undef,\n"); |
2928 | 4092 | } |
2929 | 4093 | printf(" 'driver' => '%s',\n", combo->driver); |
4094 | if (combo->driver_group) { | |
4095 | printf(" 'group' => '%s',\n", combo->driver_group); | |
4096 | } | |
2930 | 4097 | if (combo->pcdriver) { |
2931 | 4098 | printf(" 'pcdriver' => '%s',\n", combo->pcdriver); |
2932 | 4099 | } else { |
2943 | 4110 | } else { |
2944 | 4111 | printf(" 'url' => undef,\n"); |
2945 | 4112 | } |
4113 | if (combo->driver_obsolete) { | |
4114 | printf(" 'obsolete' => '%s',\n", combo->driver_obsolete); | |
4115 | } | |
4116 | if (combo->supplier != NULL) { | |
4117 | printf(" 'supplier' => '%s',\n", | |
4118 | combo->supplier); | |
4119 | } | |
4120 | if (combo->manufacturersupplied != NULL) { | |
4121 | printf(" 'manufacturersupplied' => '%s',\n", | |
4122 | combo->manufacturersupplied); | |
4123 | } | |
4124 | if (combo->license != NULL) { | |
4125 | printf(" 'license' => '%s',\n", | |
4126 | combo->license); | |
4127 | } | |
4128 | if (combo->licensetext != NULL) { | |
4129 | printf(" 'licensetext' => '%s',\n", | |
4130 | combo->licensetext); | |
4131 | } | |
4132 | if (combo->free != NULL) { | |
4133 | printf(" 'free' => '%s',\n", | |
4134 | combo->free); | |
4135 | } | |
4136 | if (combo->patents != NULL) { | |
4137 | printf(" 'patents' => '%s',\n", | |
4138 | combo->patents); | |
4139 | } | |
4140 | if (combo->num_supportcontacts != 0) { | |
4141 | printf(" 'supportcontacts' => [\n"); | |
4142 | for (i = 0; | |
4143 | i < combo->num_supportcontacts; i ++) { | |
4144 | if (combo->supportcontacturls[i] != | |
4145 | NULL) { | |
4146 | printf(" {\n"); | |
4147 | printf(" 'description' => '%s',\n", | |
4148 | combo->supportcontacts[i]); | |
4149 | if (combo->supportcontacturls[i] | |
4150 | != NULL) | |
4151 | printf(" 'url' => '%s',\n", | |
4152 | combo->supportcontacturls[i]); | |
4153 | printf(" 'level' => '%s',\n", | |
4154 | combo->supportcontactlevels[i]); | |
4155 | printf(" },\n"); | |
4156 | } | |
4157 | } | |
4158 | printf(" ],\n"); | |
4159 | } | |
4160 | if (combo->shortdescription != NULL) { | |
4161 | printf(" 'shortdescription' => '%s',\n", | |
4162 | combo->shortdescription); | |
4163 | } | |
4164 | if (combo->locales != NULL) { | |
4165 | printf(" 'locales' => '%s',\n", | |
4166 | combo->locales); | |
4167 | } | |
4168 | if (combo->num_packages != 0) { | |
4169 | printf(" 'packages' => [\n"); | |
4170 | for (i = 0; | |
4171 | i < combo->num_packages; i ++) { | |
4172 | if (combo->packageurls[i] != | |
4173 | NULL) { | |
4174 | printf(" {\n"); | |
4175 | printf(" 'url' => '%s',\n", | |
4176 | combo->packageurls[i]); | |
4177 | if (combo->packagescopes[i] | |
4178 | != NULL) | |
4179 | printf(" 'scope' => '%s',\n", | |
4180 | combo->packagescopes[i]); | |
4181 | printf(" },\n"); | |
4182 | } | |
4183 | } | |
4184 | printf(" ],\n"); | |
4185 | } | |
4186 | if (combo->excmaxresx != NULL) { | |
4187 | printf(" 'drvmaxresx' => '%s',\n", | |
4188 | combo->excmaxresx); | |
4189 | } else if (combo->drvmaxresx != NULL) { | |
4190 | printf(" 'drvmaxresx' => '%s',\n", | |
4191 | combo->drvmaxresx); | |
4192 | } | |
4193 | if (combo->excmaxresy != NULL) { | |
4194 | printf(" 'drvmaxresy' => '%s',\n", | |
4195 | combo->excmaxresy); | |
4196 | } else if (combo->drvmaxresy != NULL) { | |
4197 | printf(" 'drvmaxresy' => '%s',\n", | |
4198 | combo->drvmaxresy); | |
4199 | } | |
4200 | if (combo->exccolor != NULL) { | |
4201 | printf(" 'drvcolor' => '%s',\n", | |
4202 | combo->exccolor); | |
4203 | } else if (combo->drvcolor != NULL) { | |
4204 | printf(" 'drvcolor' => '%s',\n", | |
4205 | combo->drvcolor); | |
4206 | } | |
4207 | if (combo->exctext != NULL) { | |
4208 | printf(" 'text' => '%s',\n", | |
4209 | combo->exctext); | |
4210 | } else if (combo->text != NULL) { | |
4211 | printf(" 'text' => '%s',\n", | |
4212 | combo->text); | |
4213 | } | |
4214 | if (combo->exclineart != NULL) { | |
4215 | printf(" 'lineart' => '%s',\n", | |
4216 | combo->exclineart); | |
4217 | } else if (combo->lineart != NULL) { | |
4218 | printf(" 'lineart' => '%s',\n", | |
4219 | combo->lineart); | |
4220 | } | |
4221 | if (combo->excgraphics != NULL) { | |
4222 | printf(" 'graphics' => '%s',\n", | |
4223 | combo->excgraphics); | |
4224 | } else if (combo->graphics != NULL) { | |
4225 | printf(" 'graphics' => '%s',\n", | |
4226 | combo->graphics); | |
4227 | } | |
4228 | if (combo->excphoto != NULL) { | |
4229 | printf(" 'photo' => '%s',\n", | |
4230 | combo->excphoto); | |
4231 | } else if (combo->photo != NULL) { | |
4232 | printf(" 'photo' => '%s',\n", | |
4233 | combo->photo); | |
4234 | } | |
4235 | if (combo->excload != NULL) { | |
4236 | printf(" 'load' => '%s',\n", | |
4237 | combo->excload); | |
4238 | } else if (combo->load != NULL) { | |
4239 | printf(" 'load' => '%s',\n", | |
4240 | combo->load); | |
4241 | } | |
4242 | if (combo->excspeed != NULL) { | |
4243 | printf(" 'speed' => '%s',\n", | |
4244 | combo->excspeed); | |
4245 | } else if (combo->speed != NULL) { | |
4246 | printf(" 'speed' => '%s',\n", | |
4247 | combo->speed); | |
4248 | } | |
4249 | if (combo->num_requires != 0) { | |
4250 | printf(" 'requires' => [\n"); | |
4251 | for (i = 0; | |
4252 | i < combo->num_requires; i ++) { | |
4253 | if (combo->requires[i] != | |
4254 | NULL) { | |
4255 | printf(" {\n"); | |
4256 | printf(" 'driver' => '%s',\n", | |
4257 | combo->requires[i]); | |
4258 | if (combo->requiresversion[i] | |
4259 | != NULL) | |
4260 | printf(" 'version' => '%s',\n", | |
4261 | combo->requiresversion[i]); | |
4262 | printf(" },\n"); | |
4263 | } | |
4264 | } | |
4265 | printf(" ],\n"); | |
4266 | } | |
2946 | 4267 | if (combo->cmd) { |
2947 | 4268 | printf(" 'cmd' => '%s',\n", combo->cmd); |
2948 | 4269 | } else { |
2952 | 4273 | printf(" 'drivernopjl' => %s,\n", combo->nopjl); |
2953 | 4274 | } else { |
2954 | 4275 | printf(" 'drivernopjl' => 0,\n"); |
4276 | } | |
4277 | if (combo->nopageaccounting) { | |
4278 | printf(" 'drivernopageaccounting' => %s,\n", combo->nopageaccounting); | |
4279 | } else { | |
4280 | printf(" 'drivernopageaccounting' => 0,\n"); | |
2955 | 4281 | } |
2956 | 4282 | if (combo->driverppdentry) { |
2957 | 4283 | printf(" 'driverppdentry' => '%s',\n", combo->driverppdentry); |
3273 | 4599 | xmlChar **printers; |
3274 | 4600 | printf("$VAR1 = {\n"); |
3275 | 4601 | printf(" 'name' => '%s',\n", driver->name); |
4602 | if (driver->group) { | |
4603 | printf(" 'group' => '%s',\n", driver->group); | |
4604 | } | |
3276 | 4605 | if (driver->url) { |
3277 | 4606 | printf(" 'url' => '%s',\n", driver->url); |
4607 | } | |
4608 | if (driver->driver_obsolete) { | |
4609 | printf(" 'obsolete' => '%s',\n", driver->driver_obsolete); | |
4610 | } | |
4611 | if (driver->supplier != NULL) { | |
4612 | printf(" 'supplier' => '%s',\n", | |
4613 | driver->supplier); | |
4614 | } | |
4615 | if (driver->manufacturersupplied != NULL) { | |
4616 | printf(" 'manufacturersupplied' => '%s',\n", | |
4617 | driver->manufacturersupplied); | |
4618 | } | |
4619 | if (driver->license != NULL) { | |
4620 | printf(" 'license' => '%s',\n", | |
4621 | driver->license); | |
4622 | } | |
4623 | if (driver->licensetext != NULL) { | |
4624 | printf(" 'licensetext' => '%s',\n", | |
4625 | driver->licensetext); | |
4626 | } | |
4627 | if (driver->free != NULL) { | |
4628 | printf(" 'free' => '%s',\n", | |
4629 | driver->free); | |
4630 | } | |
4631 | if (driver->patents != NULL) { | |
4632 | printf(" 'patents' => '%s',\n", | |
4633 | driver->patents); | |
4634 | } | |
4635 | if (driver->num_supportcontacts != 0) { | |
4636 | printf(" 'supportcontacts' => [\n"); | |
4637 | for (i = 0; | |
4638 | i < driver->num_supportcontacts; i ++) { | |
4639 | if (driver->supportcontacturls[i] != | |
4640 | NULL) { | |
4641 | printf(" {\n"); | |
4642 | printf(" 'description' => '%s',\n", | |
4643 | driver->supportcontacts[i]); | |
4644 | if (driver->supportcontacturls[i] | |
4645 | != NULL) | |
4646 | printf(" 'url' => '%s',\n", | |
4647 | driver->supportcontacturls[i]); | |
4648 | printf(" 'level' => '%s',\n", | |
4649 | driver->supportcontactlevels[i]); | |
4650 | printf(" },\n"); | |
4651 | } | |
4652 | } | |
4653 | printf(" ],\n"); | |
4654 | } | |
4655 | if (driver->shortdescription != NULL) { | |
4656 | printf(" 'shortdescription' => '%s',\n", | |
4657 | driver->shortdescription); | |
4658 | } | |
4659 | if (driver->locales != NULL) { | |
4660 | printf(" 'locales' => '%s',\n", | |
4661 | driver->locales); | |
4662 | } | |
4663 | if (driver->num_packages != 0) { | |
4664 | printf(" 'packages' => [\n"); | |
4665 | for (i = 0; | |
4666 | i < driver->num_packages; i ++) { | |
4667 | if (driver->packageurls[i] != | |
4668 | NULL) { | |
4669 | printf(" {\n"); | |
4670 | printf(" 'url' => '%s',\n", | |
4671 | driver->packageurls[i]); | |
4672 | if (driver->packagescopes[i] | |
4673 | != NULL) | |
4674 | printf(" 'scope' => '%s',\n", | |
4675 | driver->packagescopes[i]); | |
4676 | printf(" },\n"); | |
4677 | } | |
4678 | } | |
4679 | printf(" ],\n"); | |
4680 | } | |
4681 | if (driver->maxresx != NULL) { | |
4682 | printf(" 'drvmaxresx' => '%s',\n", | |
4683 | driver->maxresx); | |
4684 | } | |
4685 | if (driver->maxresy != NULL) { | |
4686 | printf(" 'drvmaxresy' => '%s',\n", | |
4687 | driver->maxresy); | |
4688 | } | |
4689 | if (driver->color != NULL) { | |
4690 | printf(" 'drvcolor' => '%s',\n", | |
4691 | driver->color); | |
4692 | } | |
4693 | if (driver->text != NULL) { | |
4694 | printf(" 'text' => '%s',\n", | |
4695 | driver->text); | |
4696 | } | |
4697 | if (driver->lineart != NULL) { | |
4698 | printf(" 'lineart' => '%s',\n", | |
4699 | driver->lineart); | |
4700 | } | |
4701 | if (driver->graphics != NULL) { | |
4702 | printf(" 'graphics' => '%s',\n", | |
4703 | driver->graphics); | |
4704 | } | |
4705 | if (driver->photo != NULL) { | |
4706 | printf(" 'photo' => '%s',\n", | |
4707 | driver->photo); | |
4708 | } | |
4709 | if (driver->load != NULL) { | |
4710 | printf(" 'load' => '%s',\n", | |
4711 | driver->load); | |
4712 | } | |
4713 | if (driver->speed != NULL) { | |
4714 | printf(" 'speed' => '%s',\n", | |
4715 | driver->speed); | |
4716 | } | |
4717 | if (driver->num_requires != 0) { | |
4718 | printf(" 'requires' => [\n"); | |
4719 | for (i = 0; | |
4720 | i < driver->num_requires; i ++) { | |
4721 | if (driver->requires[i] != | |
4722 | NULL) { | |
4723 | printf(" {\n"); | |
4724 | printf(" 'driver' => '%s',\n", | |
4725 | driver->requires[i]); | |
4726 | if (driver->requiresversion[i] | |
4727 | != NULL) | |
4728 | printf(" 'version' => '%s',\n", | |
4729 | driver->requiresversion[i]); | |
4730 | printf(" },\n"); | |
4731 | } | |
4732 | } | |
4733 | printf(" ],\n"); | |
3278 | 4734 | } |
3279 | 4735 | if (driver->driver_type) { |
3280 | 4736 | printf(" 'type' => '%s',\n", driver->driver_type); |
3305 | 4761 | printf(" 'comment' => '%s'\n", |
3306 | 4762 | driver->printers[i]->comment); |
3307 | 4763 | } |
4764 | if (driver->printers[i]->excmaxresx != NULL) { | |
4765 | printf(" 'excmaxresx' => '%s',\n", | |
4766 | driver->printers[i]->excmaxresx); | |
4767 | } | |
4768 | if (driver->printers[i]->excmaxresy != NULL) { | |
4769 | printf(" 'excmaxresy' => '%s',\n", | |
4770 | driver->printers[i]->excmaxresy); | |
4771 | } | |
4772 | if (driver->printers[i]->exccolor != NULL) { | |
4773 | printf(" 'exccolor' => '%s',\n", | |
4774 | driver->printers[i]->exccolor); | |
4775 | } | |
4776 | if (driver->printers[i]->exctext != NULL) { | |
4777 | printf(" 'exctext' => '%s',\n", | |
4778 | driver->printers[i]->exctext); | |
4779 | } | |
4780 | if (driver->printers[i]->exclineart != NULL) { | |
4781 | printf(" 'exclineart' => '%s',\n", | |
4782 | driver->printers[i]->exclineart); | |
4783 | } | |
4784 | if (driver->printers[i]->excgraphics != NULL) { | |
4785 | printf(" 'excgraphics' => '%s',\n", | |
4786 | driver->printers[i]->excgraphics); | |
4787 | } | |
4788 | if (driver->printers[i]->excphoto != NULL) { | |
4789 | printf(" 'excphoto' => '%s',\n", | |
4790 | driver->printers[i]->excphoto); | |
4791 | } | |
4792 | if (driver->printers[i]->excload != NULL) { | |
4793 | printf(" 'excload' => '%s',\n", | |
4794 | driver->printers[i]->excload); | |
4795 | } | |
4796 | if (driver->printers[i]->excspeed != NULL) { | |
4797 | printf(" 'excspeed' => '%s',\n", | |
4798 | driver->printers[i]->excspeed); | |
4799 | } | |
3308 | 4800 | printf(" },\n"); |
3309 | 4801 | } |
3310 | 4802 | printf(" ]\n"); |
3320 | 4812 | int i, j; /* loop variables */ |
3321 | 4813 | int debug = 0; /* Debug output level */ |
3322 | 4814 | xmlChar *setting; |
3323 | xmlChar *language = "en"; | |
4815 | xmlChar *language = "C"; | |
3324 | 4816 | xmlChar **defaultsettings = NULL; /* User-supplied option settings*/ |
3325 | 4817 | int num_defaultsettings = 0; |
3326 | 4818 | char *filename = NULL; |
3371 | 4863 | i ++; |
3372 | 4864 | language = (xmlChar *)(argv[i]); |
3373 | 4865 | } |
4866 | break; | |
3374 | 4867 | case 'v' : /* verbose */ |
3375 | 4868 | debug++; |
3376 | 4869 | j = 2; |
26 | 26 | printer entries or those whose name and/or model information |
27 | 27 | match a regular expression. |
28 | 28 | |
29 | .pp | |
29 | .PP | |
30 | 30 | The last form prints a help message and exits. |
31 | 31 | |
32 | 32 | .SS Options |
73 | 73 | .SH BUGS |
74 | 74 | None so far. |
75 | 75 | |
76 | Please send bug reports to foomatic-devel@linuxprinting.org. | |
76 | Please post bug reports on | |
77 | ||
78 | http://lists.freestandards.org/mailman/listinfo/printing-foomatic | |
79 |
26 | 26 | # This can be set by "OnlyRecommended Yes" or "OnlyRecommended No" in |
27 | 27 | # /etc/cups/foomatic.conf |
28 | 28 | my $onlyrecommended = 0; |
29 | ||
29 | # The Foomatic database does not only generate PPD files from Foomatic | |
30 | # XML data but also of ready-made PPDs mainly from printer manufacturers | |
31 | # for their PostScript printers. As these PPDs are often also linked to | |
32 | # the directories in which CUPS links directly to PPD files, duplicate | |
33 | # listing of these PPDs by CUPS would result. Therefore we suppress | |
34 | # listing the ready-made PPDs. This behaviour can be changed by using | |
35 | # "ListReadyMadePPDs Yes" or "ListReadyMadePPDs No" in | |
36 | # /etc/cups/foomatic.conf | |
37 | my $listreadymadeppds = 0; | |
30 | 38 | help() if !@ARGV; |
31 | 39 | #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w); |
32 | 40 | getopts("AP:d:p:hwt:"); |
56 | 64 | exit(0); |
57 | 65 | |
58 | 66 | sub cupslistppds { |
59 | my $db = Foomatic::DB->new(); | |
60 | $db->get_overview(1, 1); | |
61 | 67 | |
62 | 68 | # Read configuration in /etc/cups/foomatic.conf |
63 | 69 | my $conffilename; |
77 | 83 | /^\s*OnlyRecommended\s+(No|Off|False|0)\s*$/i) { |
78 | 84 | $onlyrecommended = 0; |
79 | 85 | } |
86 | if ($line =~ | |
87 | /^\s*ListReadyMadePPDs\s+(Yes|On|True|1)\s*$/i) { | |
88 | $listreadymadeppds = 1; | |
89 | } elsif ($line =~ | |
90 | /^\s*ListReadyMadePPDs\s+(No|Off|False|0)\s*$/i) { | |
91 | $listreadymadeppds = 0; | |
92 | } | |
80 | 93 | } |
81 | 94 | close CONF; |
82 | 95 | } |
96 | ||
97 | my $db = Foomatic::DB->new(); | |
98 | $db->get_overview(1, 1 + listreadymadeppds); | |
83 | 99 | |
84 | 100 | for my $printer (@{$db->{'overview'}}) { |
85 | 101 | my $poid = $printer->{'id'}; |
127 | 127 | # any other driver. |
128 | 128 | "pnm2ppa", # color |
129 | 129 | "pbm2ppa", # bw |
130 | # Lexmark 3200, the Gimp-Print support for this | |
130 | # Lexmark 3200, the Gutenprint support for this | |
131 | 131 | # printer is broken |
132 | 132 | "lxm3200-tweaked", |
133 | 133 | "lxm3200\$", |
135 | 135 | "lxm3200m", |
136 | 136 | "lxm3200p", |
137 | 137 | # Canon BJC-8200, these UPPs are probably better |
138 | # than Gimp-Print | |
138 | # than Gutenprint | |
139 | 139 | "bj8pa06n.upp", |
140 | 140 | "bj8oh06n.upp", |
141 | 141 | "bj8ts06n.upp", |
148 | 148 | "cdj970", # Duplex support |
149 | 149 | "DJ", # HP drivers, but no duplex |
150 | 150 | "chp2200", # HP driver |
151 | "gimp-print-ijs", # IJS plug-in driver of Gimp-Print | |
152 | "gimp-print", # Tray selection on laser, best | |
151 | "gutenprint-ijs", # IJS plug-in driver of Gutenprint | |
152 | "gutenprint", # Tray selection on laser, best | |
153 | 153 | # quality on inkjets (for HP HP's |
154 | # driver is better | |
155 | "stp", # Predecessor of Gimp-Print | |
154 | # driver is better) | |
155 | "gimp-print-ijs", # Old Gimp-Print driver | |
156 | "gimp-print", | |
157 | "stp", # Predecessor of Gimp-Print/Gutenprint | |
156 | 158 | "cdj1600", # Relatively good drivers for HP inkjets |
157 | "cdj890", # not covered by Gimp-Print or the HP | |
159 | "cdj890", # not covered by Gutenprint or the HP | |
158 | 160 | "cdj880", # drivers |
159 | 161 | "cdj850", |
160 | 162 | "cdj670", |
0 | #!@PERL@ | |
1 | ||
2 | # This script updates the printer list of the driver XML file of | |
3 | # Gimp-Print (db/source/driver/gimp-print.xml in foomatic-db package) | |
4 | # according to the file src/foomatic/foomatic-printermap of the source | |
5 | # tarball of Gimp-Print 4.2.x or later. | |
6 | # | |
7 | # Remarks: | |
8 | # | |
9 | # - Manually added printer entries will not be removed. They drop out | |
10 | # to the beginning of the printer list during the update. The same | |
11 | # happens to printers which are removed from the new foomatic-printermap | |
12 | # | |
13 | # - All printers of foomatic-printermap are put to the end of the list, | |
14 | # the order of foomatic-printermap is preserved. | |
15 | # | |
16 | # - The user will be informed by screen messages if the new | |
17 | # foomatic-printermap contains new printers which were neither in the | |
18 | # previous foomatic-printermap nor under the manually added printers. | |
19 | # | |
20 | # - A printer which was added manually before and is in foomatic-printermap | |
21 | # now will be removed from the list of manually added printers and added | |
22 | # to the list of printers from foomatic-printermap. | |
23 | ||
24 | #use strict; | |
25 | ||
26 | # Read out the program name with which we were called, but discard the path | |
27 | $0 =~ m!/([^/]+)\s*$!; | |
28 | my $progname = $1; | |
29 | my $debug = 0; | |
30 | ||
31 | my ($opt_f, $opt_g, $opt_h); | |
32 | use Getopt::Std; | |
33 | getopts("f:g:h") or $opt_h = 1; | |
34 | if ($opt_h) { | |
35 | print " | |
36 | foomatic-printermap-to-gimp-print-xml [ -f <foomatic-printermap> ] \ | |
37 | [ -g <gimp-print.xml> ] | |
38 | -f <foomatic-printermap>: File src/foomatic/foomatic-printermap of | |
39 | Gimp-Print source tarball (4.2.x or later). Default | |
40 | is foomatic-printermap in the current directory | |
41 | ||
42 | -g <gimp-print.xml>: File gimp-print.xml whose printer list should be | |
43 | updated. Default is the gimp-print.xml of the | |
44 | Foomatic database currently in use. | |
45 | ||
46 | This program updates the printer list of the driver XML file of | |
47 | Gimp-Print (db/source/driver/gimp-print.xml in foomatic-db package) | |
48 | according to the file src/foomatic/foomatic-printermap of the source | |
49 | tarball of Gimp-Print 4.2.x or later. | |
50 | ||
51 | "; | |
52 | exit 0; | |
53 | } | |
54 | ||
55 | # Determine gimp-print.xml file | |
56 | my $gimpprintxmlfile = $opt_g; | |
57 | if (!$gimpprintxmlfile) { | |
58 | use Foomatic::Defaults; | |
59 | $gimpprintxmlfile = "$libdir/db/source/driver/gimp-print.xml"; | |
60 | } | |
61 | ||
62 | # Determine foomatic-printermap file | |
63 | my $foomaticprintermapfile = $opt_f; | |
64 | if (!$foomaticprintermapfile) { | |
65 | $foomaticprintermapfile = "./foomatic-printermap"; | |
66 | } | |
67 | ||
68 | # Read list of printer IDs from Gimp-Print's foomatic-printermap | |
69 | open PM, "< $foomaticprintermapfile" or | |
70 | die "Cannot read $foomaticprintermapfile!\n"; | |
71 | my @printermap = <PM>; | |
72 | close PM; | |
73 | ||
74 | (s/^\s*\S+\s+\S+\s+(\S+)\s*$/$1/) foreach @printermap; | |
75 | ||
76 | #print $#printermap; | |
77 | ||
78 | # Read gimp-print.xml | |
79 | open GPX, "< $gimpprintxmlfile" or | |
80 | die "Cannot read $gimpprintxmlfile!\n"; | |
81 | my $gimpprintxml = join("", <GPX>); | |
82 | close GPX; | |
83 | ||
84 | # Remove printer list | |
85 | #$gimpprintxml =~ s!(<\s*printers\s*>).*(\n\s*<\s*/\s*printers\s*>)!$1$2!s; | |
86 | ||
87 | # Mark beginning of printer list from foomatic-printermap before deleting | |
88 | # these printer entries | |
89 | $gimpprintxml =~ s:\n <!-- The following printers are listed in the current foomatic-printermap -->:XXXXXXXXXX:s; | |
90 | ||
91 | # Remove only those printers which are in foomatic-printermap. We | |
92 | # re-add them in the next step, this way we have all printers of | |
93 | # foomatic-printermap together and in the order of | |
94 | # foomatic-printermap, and we have all manually added printers in the | |
95 | # beginning of the list, before the printers of foomatic-printermap | |
96 | # are listed. | |
97 | print STDERR "Removing old printer entries "; | |
98 | foreach my $printer (@printermap) { | |
99 | print STDERR "."; | |
100 | $gimpprintxml =~ s:\s*<\!\-\-[^<>]*?\-\->\s*<printer>\s*<id>\s*$printer\s*</id>.*?</printer>::s or | |
101 | $gimpprintxml =~ s:\s*<printer>\s*<id>\s*$printer\s*</id>.*?</printer>::s or | |
102 | print STDERR "\n\nNew printer: $printer\n\n"; | |
103 | } | |
104 | print STDERR "\n\n"; | |
105 | ||
106 | # Insert comment to mark the part of the list set up manually | |
107 | $gimpprintxml =~ s:(\n\s*<\s*printers\s*>)\n\s*<!--\s*Manually inserted printer entries\s*-->:$1:s; | |
108 | $gimpprintxml =~ s:(\n\s*<\s*printers\s*>):$1\n <!-- Manually inserted printer entries -->:s; | |
109 | ||
110 | # Insert comment to mark the part of the list generated from | |
111 | # foomatic-printermap | |
112 | $gimpprintxml =~ s:\n <!-- The following printers were deleted in the current foomatic-printermap -->::s; | |
113 | $gimpprintxml =~ s:\n <!-- The following printers are listed in the current foomatic-printermap -->::s; | |
114 | $gimpprintxml =~ s:XXXXXXXXXX:\n <!-- The following printers were deleted in the current foomatic-printermap -->:s; | |
115 | $gimpprintxml =~ s:(\n\s*<\s*/\s*printers\s*>):\n <!-- The following printers are listed in the current foomatic-printermap -->$1:s; | |
116 | ||
117 | # Insert printers of foomatic-printermap to the end of the list | |
118 | print STDERR "Inserting printer entries of foomatic-printermap "; | |
119 | foreach my $printer (@printermap) { | |
120 | print STDERR "."; | |
121 | $gimpprintxml =~ s:(\n\s*<\s*/\s*printers\s*>):\n <printer>\n <id>$printer</id>\n </printer>$1:s; | |
122 | } | |
123 | print STDERR "\n\n"; | |
124 | ||
125 | open GPX, "> $gimpprintxmlfile" or | |
126 | die "Cannot write $gimpprintxmlfile!\n"; | |
127 | print GPX $gimpprintxml; | |
128 | close GPX; | |
129 | ||
130 | exit 0; |
0 | #!@PERL@ | |
1 | ||
2 | # This script updates the printer list of the driver XML file of | |
3 | # Gutenprint (db/source/driver/gutenprint.xml in foomatic-db package) | |
4 | # according to the file src/foomatic/foomatic-printermap of the source | |
5 | # tarball of Gutenprint 5.0.x or later. | |
6 | # | |
7 | # Remarks: | |
8 | # | |
9 | # - Manually added printer entries will not be removed. They drop out | |
10 | # to the beginning of the printer list during the update. The same | |
11 | # happens to printers which are removed from the new foomatic-printermap | |
12 | # | |
13 | # - All printers of foomatic-printermap are put to the end of the list, | |
14 | # the order of foomatic-printermap is preserved. | |
15 | # | |
16 | # - The user will be informed by screen messages if the new | |
17 | # foomatic-printermap contains new printers which were neither in the | |
18 | # previous foomatic-printermap nor under the manually added printers. | |
19 | # | |
20 | # - A printer which was added manually before and is in foomatic-printermap | |
21 | # now will be removed from the list of manually added printers and added | |
22 | # to the list of printers from foomatic-printermap. | |
23 | ||
24 | #use strict; | |
25 | ||
26 | # Read out the program name with which we were called, but discard the path | |
27 | $0 =~ m!/([^/]+)\s*$!; | |
28 | my $progname = $1; | |
29 | my $debug = 0; | |
30 | ||
31 | my ($opt_f, $opt_g, $opt_h); | |
32 | use Getopt::Std; | |
33 | getopts("f:g:h") or $opt_h = 1; | |
34 | if ($opt_h) { | |
35 | print " | |
36 | foomatic-printermap-to-gutenprint-xml [ -f <foomatic-printermap> ] \ | |
37 | [ -g <gutenprint.xml> ] | |
38 | -f <foomatic-printermap>: File src/foomatic/foomatic-printermap of | |
39 | Gutenprint source tarball (4.2.x or later). Default | |
40 | is foomatic-printermap in the current directory | |
41 | ||
42 | -g <gutenprint.xml>: File gutenprint.xml whose printer list should be | |
43 | updated. Default is the gutenprint.xml of the | |
44 | Foomatic database currently in use. | |
45 | ||
46 | This program updates the printer list of the driver XML file of | |
47 | Gutenprint (db/source/driver/gutenprint.xml in foomatic-db package) | |
48 | according to the file src/foomatic/foomatic-printermap of the source | |
49 | tarball of Gutenprint 5.0.x or later. | |
50 | ||
51 | "; | |
52 | exit 0; | |
53 | } | |
54 | ||
55 | # Determine gutenprint.xml file | |
56 | my $gutenprintxmlfile = $opt_g; | |
57 | if (!$gutenprintxmlfile) { | |
58 | use Foomatic::Defaults; | |
59 | $gutenprintxmlfile = "$libdir/db/source/driver/gutenprint.xml"; | |
60 | } | |
61 | ||
62 | # Determine foomatic-printermap file | |
63 | my $foomaticprintermapfile = $opt_f; | |
64 | if (!$foomaticprintermapfile) { | |
65 | $foomaticprintermapfile = "./foomatic-printermap"; | |
66 | } | |
67 | ||
68 | # Read list of printer IDs from Gutenprint's foomatic-printermap | |
69 | open PM, "< $foomaticprintermapfile" or | |
70 | die "Cannot read $foomaticprintermapfile!\n"; | |
71 | my @printermap = <PM>; | |
72 | close PM; | |
73 | ||
74 | (s/^\s*\S+\s+\S+\s+(\S+)\s*$/$1/) foreach @printermap; | |
75 | ||
76 | #print $#printermap; | |
77 | ||
78 | # Read gutenprint.xml | |
79 | open GPX, "< $gutenprintxmlfile" or | |
80 | die "Cannot read $gutenprintxmlfile!\n"; | |
81 | my $gutenprintxml = join("", <GPX>); | |
82 | close GPX; | |
83 | ||
84 | # Remove printer list | |
85 | #$gutenprintxml =~ s!(<\s*printers\s*>).*(\n\s*<\s*/\s*printers\s*>)!$1$2!s; | |
86 | ||
87 | # Mark beginning of printer list from foomatic-printermap before deleting | |
88 | # these printer entries | |
89 | $gutenprintxml =~ s:\n <!-- The following printers are listed in the current foomatic-printermap -->:XXXXXXXXXX:s; | |
90 | ||
91 | # Remove only those printers which are in foomatic-printermap. We | |
92 | # re-add them in the next step, this way we have all printers of | |
93 | # foomatic-printermap together and in the order of | |
94 | # foomatic-printermap, and we have all manually added printers in the | |
95 | # beginning of the list, before the printers of foomatic-printermap | |
96 | # are listed. | |
97 | print STDERR "Removing old printer entries "; | |
98 | foreach my $printer (@printermap) { | |
99 | print STDERR "."; | |
100 | $gutenprintxml =~ s:\s*<\!\-\-[^<>]*?\-\->\s*<printer>\s*<id>\s*$printer\s*</id>.*?</printer>::s or | |
101 | $gutenprintxml =~ s:\s*<printer>\s*<id>\s*$printer\s*</id>.*?</printer>::s or | |
102 | print STDERR "\n\nNew printer: $printer\n\n"; | |
103 | } | |
104 | print STDERR "\n\n"; | |
105 | ||
106 | # Insert comment to mark the part of the list set up manually | |
107 | $gutenprintxml =~ s:(\n\s*<\s*printers\s*>)\n\s*<!--\s*Manually inserted printer entries\s*-->:$1:s; | |
108 | $gutenprintxml =~ s:(\n\s*<\s*printers\s*>):$1\n <!-- Manually inserted printer entries -->:s; | |
109 | ||
110 | # Insert comment to mark the part of the list generated from | |
111 | # foomatic-printermap | |
112 | $gutenprintxml =~ s:\n <!-- The following printers were deleted in the current foomatic-printermap -->::s; | |
113 | $gutenprintxml =~ s:\n <!-- The following printers are listed in the current foomatic-printermap -->::s; | |
114 | $gutenprintxml =~ s:XXXXXXXXXX:\n <!-- The following printers were deleted in the current foomatic-printermap -->:s; | |
115 | $gutenprintxml =~ s:(\n\s*<\s*/\s*printers\s*>):\n <!-- The following printers are listed in the current foomatic-printermap -->$1:s; | |
116 | ||
117 | # Insert printers of foomatic-printermap to the end of the list | |
118 | print STDERR "Inserting printer entries of foomatic-printermap "; | |
119 | foreach my $printer (@printermap) { | |
120 | print STDERR "."; | |
121 | $gutenprintxml =~ s:(\n\s*<\s*/\s*printers\s*>):\n <printer>\n <id>$printer</id>\n </printer>$1:s; | |
122 | } | |
123 | print STDERR "\n\n"; | |
124 | ||
125 | open GPX, "> $gutenprintxmlfile" or | |
126 | die "Cannot write $gutenprintxmlfile!\n"; | |
127 | print GPX $gutenprintxml; | |
128 | close GPX; | |
129 | ||
130 | exit 0; |
0 | #!@PERL@ | |
1 | # -*- Perl -*- | |
2 | ||
3 | # | |
4 | # This script searches for printers in the database. You can give the | |
5 | # printer manufacturer and model names or the IEEE-1284 device ID of | |
6 | # the printer. You will get one or more results sorted by how well they | |
7 | # match. Exact metch of the model-identifying parts of the IEEE-1284 device ID | |
8 | # counts highest. Run "foomatic-addpjloptions -h" to get help. | |
9 | # | |
10 | ||
11 | # | |
12 | # Till Kamppeter (till.kamppeter@gmx.net) | |
13 | # | |
14 | # Copyright 2007 Till Kamppeter | |
15 | # | |
16 | # This software may be freely redistributed under the terms of the GNU | |
17 | # General Public License (http://www.gnu.org/). | |
18 | # | |
19 | # You should have received a copy of the GNU General Public License | |
20 | # along with this program; if not, write to the Free Software | |
21 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 | # | |
23 | ||
24 | use strict; | |
25 | use FileHandle; | |
26 | ||
27 | sub usage(){ | |
28 | print STDERR <<EOF; | |
29 | Usage: foomatic-searchprinter [-mM] [-dD] <search term> | |
30 | foomatic-searchprinter -h | |
31 | ||
32 | <search term>: Manufacturer/model, separated by a space or a '|', | |
33 | IEEE-1284 device ID, manufacturer, model, Foomatic | |
34 | printer ID, or parts of any of the mentioned items | |
35 | ||
36 | -mM Search mode: | |
37 | M = 0: Match everything (default) | |
38 | M = 1: No matches on only the manufacturer | |
39 | M = 2: No matches on only the manufacturer or only the model | |
40 | M = 3: Exact matches of device ID, make/model, or Foomatic ID | |
41 | plus matches of the page description language in the | |
42 | device ID to appropriate "Generic" printers | |
43 | M = 4: Exact matches of device ID, make/model, or Foomatic ID | |
44 | only | |
45 | ||
46 | -dD Display results | |
47 | D = 0: Everything | |
48 | D = 1: Only best match class (default) | |
49 | D = 2: Only best match | |
50 | ||
51 | -h This help message | |
52 | ||
53 | EOF | |
54 | ||
55 | exit(1); | |
56 | } | |
57 | ||
58 | # Read command line options | |
59 | use Getopt::Std; | |
60 | # Help | |
61 | my $opt = {}; | |
62 | getopts("m:d:h",$opt) || usage(); | |
63 | ||
64 | # Show usage info | |
65 | if ($opt->{h}) { | |
66 | usage(); | |
67 | } | |
68 | ||
69 | # Options | |
70 | my $mode = 0; | |
71 | if (defined($opt->{m})) { | |
72 | $mode = $opt->{m}; | |
73 | usage() if ($mode < 0) || ($mode > 4); | |
74 | } | |
75 | ||
76 | my $output = 1; | |
77 | if (defined($opt->{d})) { | |
78 | $output = $opt->{d}; | |
79 | usage() if ($output < 0) || ($output > 2); | |
80 | } | |
81 | ||
82 | ||
83 | # Search term | |
84 | my $searchterm = join(' ', @ARGV); | |
85 | usage() if !$searchterm; | |
86 | ||
87 | use Foomatic::Defaults; | |
88 | use Foomatic::DB; | |
89 | ||
90 | my $db = new Foomatic::DB; | |
91 | ||
92 | print join("\n", $db->find_printer($searchterm, $mode, $output)) . "\n"; |
21 | 21 | sub new { |
22 | 22 | my $type = shift(@_); |
23 | 23 | my $this = bless {@_}, $type; |
24 | $this->{'language'} = "C"; | |
24 | 25 | return $this; |
25 | 26 | } |
26 | 27 | |
51 | 52 | return $oldid; |
52 | 53 | } |
53 | 54 | |
55 | # Set language for localized answers | |
56 | sub set_language { | |
57 | my ($this, $language) = @_; | |
58 | $this->{'language'} = $language; | |
59 | } | |
60 | ||
54 | 61 | # List of driver names |
55 | 62 | sub get_driverlist { |
56 | 63 | my ($this) = @_; |
70 | 77 | if ((!defined($this->{'overview'})) |
71 | 78 | or (defined($rebuild) and $rebuild)) { |
72 | 79 | my $otype = ($cupsppds ? '-C' : '-O'); |
80 | $otype .= ' -n' if ($cupsppds == 1); | |
73 | 81 | # Generate overview Perl data structure from database |
74 | 82 | my $VAR1; |
75 | eval (`$bindir/foomatic-combo-xml $otype -l '$libdir' | $bindir/foomatic-perl-data -O`) || | |
83 | eval (`$bindir/foomatic-combo-xml $otype -l '$libdir' | $bindir/foomatic-perl-data -O -l $this->{'language'}`) || | |
76 | 84 | die ("Could not run \"foomatic-combo-xml\"/\"foomatic-perl-data\"!"); |
77 | 85 | $this->{'overview'} = $VAR1; |
78 | 86 | } |
119 | 127 | # Generate printer Perl data structure from database |
120 | 128 | my $VAR1; |
121 | 129 | if (-r "$libdir/db/source/printer/$poid.xml") { |
122 | eval (`$bindir/foomatic-perl-data -P '$libdir/db/source/printer/$poid.xml'`) || | |
130 | eval (`$bindir/foomatic-perl-data -P -l $this->{'language'} '$libdir/db/source/printer/$poid.xml'`) || | |
123 | 131 | die ("Could not run \"foomatic-perl-data\"!"); |
124 | 132 | } else { |
125 | 133 | return undef; |
137 | 145 | # Generate driver Perl data structure from database |
138 | 146 | my $VAR1; |
139 | 147 | if (-r "$libdir/db/source/driver/$drv.xml") { |
140 | eval (`$bindir/foomatic-perl-data -D '$libdir/db/source/driver/$drv.xml'`) || | |
148 | eval (`$bindir/foomatic-perl-data -D -l $this->{'language'} '$libdir/db/source/driver/$drv.xml'`) || | |
141 | 149 | die ("Could not run \"foomatic-perl-data\"!"); |
142 | 150 | } else { |
143 | 151 | return undef; |
178 | 186 | } |
179 | 187 | |
180 | 188 | return undef; |
189 | } | |
190 | ||
191 | ||
192 | # Clean some manufacturer's names (for printer search function, taken | |
193 | # from printerdrake, printer setup tool of Mandriva Linux) | |
194 | sub clean_manufacturer_name { | |
195 | my ($make) = @_; | |
196 | $make =~ s/^Canon\W.*$/Canon/i; | |
197 | $make =~ s/^Lexmark.*$/Lexmark/i; | |
198 | $make =~ s/^Hewlett?[_\s\-]*Packard/HP/i; | |
199 | $make =~ s/^Seiko[_\s\-]*Epson/Epson/i; | |
200 | $make =~ s/^Kyocera[_\s\-]*Mita/Kyocera/i; | |
201 | $make =~ s/^CItoh/C.Itoh/i; | |
202 | $make =~ s/^Oki(|[_\s\-]*Data)\s*$/Okidata/i; | |
203 | $make =~ s/^(SilentWriter2?|ColorMate)/NEC/i; | |
204 | $make =~ s/^(XPrint|Majestix)/Xerox/i; | |
205 | $make =~ s/^QMS-PS/QMS/i; | |
206 | $make =~ s/^konica([_\s\-]|)minolta/KONICA MINOLTA/i; | |
207 | $make =~ s/^(Personal|LaserWriter)/Apple/i; | |
208 | $make =~ s/^Digital/DEC/i; | |
209 | $make =~ s/\s+Inc\.//i; | |
210 | $make =~ s/\s+Corp\.//i; | |
211 | $make =~ s/\s+SA\.//i; | |
212 | $make =~ s/\s+S\.\s*A\.//i; | |
213 | $make =~ s/\s+Ltd\.//i; | |
214 | $make =~ s/\s+International//i; | |
215 | $make =~ s/\s+Int\.//i; | |
216 | return $make; | |
217 | } | |
218 | ||
219 | # Guess manufacturer by description with only model name (for printer | |
220 | # search function, taken from printerdrake, printer setup tool of | |
221 | # Mandriva Linux) | |
222 | ||
223 | sub guessmake { | |
224 | ||
225 | my ($description) = @_; | |
226 | ||
227 | my $manufacturer; | |
228 | my $model; | |
229 | ||
230 | if ($description =~ | |
231 | /^\s*(DeskJet|LaserJet|OfficeJet|PSC|PhotoSmart)\b/i) { | |
232 | # HP printer | |
233 | $manufacturer = "HP"; | |
234 | $model = $description; | |
235 | } elsif ($description =~ | |
236 | /^\s*(Stylus|EPL|AcuLaser)\b/i) { | |
237 | # Epson printer | |
238 | $manufacturer = "Epson"; | |
239 | $model = $description; | |
240 | } elsif ($description =~ | |
241 | /^\s*(Aficio)\b/i) { | |
242 | # Ricoh printer | |
243 | $manufacturer = "Ricoh"; | |
244 | $model = $description; | |
245 | } elsif ($description =~ | |
246 | /^\s*(Optra|Color\s+JetPrinter)\b/i) { | |
247 | # Lexmark printer | |
248 | $manufacturer = "Lexmark"; | |
249 | $model = $description; | |
250 | } elsif ($description =~ | |
251 | /^\s*(imageRunner|Pixma|Pixus|BJC|LBP)\b/i) { | |
252 | # Canon printer | |
253 | $manufacturer = "Canon"; | |
254 | $model = $description; | |
255 | } elsif ($description =~ | |
256 | /^\s*(Phaser|DocuPrint|(Work|Document)\s*(Home|)Centre)\b/i) { | |
257 | # Xerox printer | |
258 | $manufacturer = "Xerox"; | |
259 | $model = $description; | |
260 | } elsif (($description =~ /^\s*(KONICA\s*MINOLTA)\s+(\S.*)$/i) || | |
261 | ($description =~ /^\s*(\S*)\s+(\S.*)$/)) { | |
262 | $manufacturer = $1 if $manufacturer eq ""; | |
263 | $model = $2 if $model eq ""; | |
264 | } | |
265 | return ($manufacturer, $model); | |
266 | } | |
267 | ||
268 | # Normalize a string, so that for a search only letters | |
269 | # (case-insensitive), numbers and boundaries between letter blocks and | |
270 | # number blocks are considered. The pipe '|' as separator between make | |
271 | # and model is also considered. Blocks of other characters are | |
272 | # replaced by a single space and boundaries between letters and | |
273 | # numbers are marked with a single space. | |
274 | sub normalize { | |
275 | my ($str) = @_; | |
276 | $str = lc($str); | |
277 | $str =~ s/\+/plus/g; | |
278 | $str =~ s/[^a-z0-9\|]+/ /g; | |
279 | $str =~ s/(?<=[a-z])(?=[0-9])/ /g; | |
280 | $str =~ s/(?<=[0-9])(?=[a-z])/ /g; | |
281 | return $str; | |
282 | } | |
283 | ||
284 | # Find a printer in the database based on an auto-detected device ID | |
285 | # or a user-typed search term | |
286 | sub find_printer { | |
287 | my ($this, $searchterm, $mode, $output) = @_; | |
288 | # $mode = 0: Everything (default) | |
289 | # $mode = 1: No matches on only the manufacturer | |
290 | # $mode = 2: No matches on only the manufacturer or only the model | |
291 | # $mode = 3: Exact matches of device ID, make/model, or Foomatic ID | |
292 | # plus matches of the page description language | |
293 | # $mode = 4: Exact matches of device ID, make/model, or Foomatic ID | |
294 | # only | |
295 | # $output = 0: Everything | |
296 | # $output = 1: Only best match class (default) | |
297 | # $output = 2: Only best match | |
298 | ||
299 | # Correct options | |
300 | $mode = 0 if !defined $mode; | |
301 | $mode = 0 if $mode < 0; | |
302 | $mode = 4 if $mode > 4; | |
303 | $output = 1 if !defined $output; | |
304 | $output = 0 if $output < 0; | |
305 | $output = 2 if $output > 2; | |
306 | ||
307 | my $over = $this->get_overview(); | |
308 | ||
309 | my %results; | |
310 | ||
311 | # Parse the search term | |
312 | my ($automake, $automodel, $autodescr, $autocmdset, $autosku); | |
313 | my $deviceid = 0; | |
314 | ||
315 | # Do we have a device ID? | |
316 | if ($searchterm =~ /(MFG|MANUFACTURER):([^;]+);/) { | |
317 | $automake = $2; | |
318 | $deviceid = 1; | |
319 | } | |
320 | if ($searchterm =~ /(MDL|MODEL):([^;]+);/) { | |
321 | $automodel = $2; | |
322 | $automodel =~ s/\s+$//; | |
323 | $deviceid = 1; | |
324 | } | |
325 | if ($searchterm =~ /(DES|DESCRIPTION):([^;]+);/) { | |
326 | $autodescr = $2; | |
327 | $autodescr =~ s/\s+$//; | |
328 | $deviceid = 1; | |
329 | } | |
330 | if ($searchterm =~ /(CMD|COMMAND\s?SET):([^;]+);/) { | |
331 | $autocmdset = $2; | |
332 | $deviceid = 1; | |
333 | } | |
334 | if ($searchterm =~ /(SKU):([^;]+);/) { | |
335 | $autosku = $2; | |
336 | $autosku =~ s/\s+$//; | |
337 | $deviceid = 1; | |
338 | } | |
339 | ||
340 | # Search term is not a device ID | |
341 | if (!$deviceid) { | |
342 | if ($searchterm =~ /^([^\|]+)\|([^\|]+|)(\|.*?|)$/) { | |
343 | $automake = $1; | |
344 | $automodel = $2; | |
345 | } else { | |
346 | $autodescr = $searchterm; | |
347 | } | |
348 | } | |
349 | ||
350 | # This is the algorithm used in printerdrake (printer setup tool | |
351 | # of Mandriva Linux) to match results of the printer auto-detection | |
352 | # with the printer database | |
353 | ||
354 | # Clean some manufacturer's names | |
355 | my $descrmake = clean_manufacturer_name($automake); | |
356 | ||
357 | # Generate data to match human-readable make/model names | |
358 | # of Foomatic database | |
359 | my $descr; | |
360 | if ($automake && $autosku) { | |
361 | $descr = "$descrmake|$autosku"; | |
362 | } elsif ($automake && $automodel) { | |
363 | $descr = "$descrmake|$automodel"; | |
364 | } elsif ($autodescr && (length($autodescr) > 5)) { | |
365 | my ($mf, $md) = | |
366 | guessmake($autodescr); | |
367 | $descrmake = clean_manufacturer_name($mf); | |
368 | $descr = "$descrmake|$md"; | |
369 | } elsif ($automodel) { | |
370 | my ($mf, $md) = | |
371 | guessmake($automodel); | |
372 | $descrmake = clean_manufacturer_name($mf); | |
373 | $descr = "$descrmake|$md"; | |
374 | } elsif ($automake) { | |
375 | $descr = "$descrmake|"; | |
376 | } | |
377 | ||
378 | # Remove manufacturer's name from the beginning of the | |
379 | # description (do not do this with manufacturer names which | |
380 | # contain odd characters) | |
381 | $descr =~ s/^$descrmake\|\s*$descrmake\s*/$descrmake|/i | |
382 | if $descrmake && | |
383 | $descrmake !~ m![\\/\(\)\[\]\|\.\$\@\%\*\?]!; | |
384 | ||
385 | # Clean up the description from noise which makes the best match | |
386 | # difficult | |
387 | $descr =~ s/\s+[Ss]eries//i; | |
388 | $descr =~ s/\s+\(?[Pp]rinter\)?$//i; | |
389 | ||
390 | # Try to find an exact match, check both whether the detected | |
391 | # make|model is in the make|model of the database entry and vice versa | |
392 | # If there is more than one matching database entry, the longest match | |
393 | # counts. | |
394 | my $matchlength = -1000; | |
395 | my $bestmatchlength = -1000; | |
396 | my $p; | |
397 | DBENTRY: for $p (@{$over}) { | |
398 | # Try to match the device ID string of the auto-detection | |
399 | if ($p->{make} =~ /Generic/i) { | |
400 | # Database entry for generic printer, check printer | |
401 | # languages (command set) | |
402 | if ($p->{model} =~ m!PCL\s*5/5e!i) { | |
403 | # Generic PCL 5/5e Printer | |
404 | if ($autocmdset =~ | |
405 | /(^|[:,])PCL\s*\-*\s*(5|)($|[,;])/i) { | |
406 | $matchlength = 70; | |
407 | $bestmatchlength = $matchlength if | |
408 | $bestmatchlength < $matchlength; | |
409 | $results{$p->{id}} = $matchlength if | |
410 | (!defined($results{$p->{id}}) || | |
411 | ($results{$p->{id}} < $matchlength)); | |
412 | next; | |
413 | } | |
414 | } elsif ($p->{model} =~ m!PCL\s*(6|XL)!i) { | |
415 | # Generic PCL 6/XL Printer | |
416 | if ($autocmdset =~ | |
417 | /(^|[:,])PCL\s*\-*\s*(6|XL)($|[,;])/i) { | |
418 | $matchlength = 80; | |
419 | $bestmatchlength = $matchlength if | |
420 | $bestmatchlength < $matchlength; | |
421 | $results{$p->{id}} = $matchlength if | |
422 | (!defined($results{$p->{id}}) || | |
423 | ($results{$p->{id}} < $matchlength)); | |
424 | next; | |
425 | } | |
426 | } elsif ($p->{model} =~ m!(PostScript)!i) { | |
427 | # Generic PostScript Printer | |
428 | if ($autocmdset =~ | |
429 | /(^|[:,])(PS|POSTSCRIPT)[^:;,]*($|[,;])/i) { | |
430 | $matchlength = 90; | |
431 | $bestmatchlength = $matchlength if | |
432 | $bestmatchlength < $matchlength; | |
433 | $results{$p->{id}} = $matchlength if | |
434 | (!defined($results{$p->{id}}) || | |
435 | ($results{$p->{id}} < $matchlength)); | |
436 | next; | |
437 | } | |
438 | } | |
439 | ||
440 | } else { | |
441 | # "Real" manufacturer, check manufacturer, model, and/or | |
442 | # description | |
443 | my $matched = 1; | |
444 | my ($mfg, $mdl, $des, $sku); | |
445 | my $ieee1284 = deviceIDfromDBEntry($p); | |
446 | if ($ieee1284 =~ /(MFG|MANUFACTURER):([^;]+);/) { | |
447 | $mfg = $2; | |
448 | } | |
449 | if ($ieee1284 =~ /(MDL|MODEL):([^;]+);/) { | |
450 | $mdl = $2; | |
451 | $mdl =~ s/\s+$//; | |
452 | } | |
453 | if ($ieee1284 =~ /(DES|DESCRIPTION):([^;]+);/) { | |
454 | $des = $2; | |
455 | $des =~ s/\s+$//; | |
456 | } | |
457 | if ($ieee1284 =~ /(SKU):([^;]+);/) { | |
458 | $sku = $2; | |
459 | $sku =~ s/\s+$//; | |
460 | } | |
461 | if ($mfg) { | |
462 | if ($mfg ne $automake) { | |
463 | $matched = 0; | |
464 | } | |
465 | } | |
466 | if ($mdl) { | |
467 | if ($mdl ne $automodel) { | |
468 | $matched = 0; | |
469 | } | |
470 | } | |
471 | if ($des) { | |
472 | if ($des ne $autodescr) { | |
473 | $matched = 0; | |
474 | } | |
475 | } | |
476 | if ($sku && $autosku) { | |
477 | if ($sku ne $autosku) { | |
478 | $matched = 0; | |
479 | } | |
480 | } | |
481 | if ($matched && | |
482 | ($des || ($mfg && ($mdl || ($sku && $autosku))))) { | |
483 | # Full match to known auto-detection data | |
484 | $matchlength = 1000; | |
485 | $bestmatchlength = $matchlength if | |
486 | $bestmatchlength < $matchlength; | |
487 | $results{$p->{id}} = $matchlength if | |
488 | (!defined($results{$p->{id}}) || | |
489 | ($results{$p->{id}} < $matchlength)); | |
490 | next; | |
491 | } | |
492 | } | |
493 | ||
494 | # Try to match the (human-readable) make and model of the | |
495 | # Foomatic database or of the PPD file | |
496 | my $dbmakemodel = "$p->{make}|$p->{model}"; | |
497 | ||
498 | # At first try to match make and model, then only model and | |
499 | # after that only make | |
500 | my $searchtasks = [[$descr, $dbmakemodel, 0], | |
501 | [$searchterm, $p->{model}, -200], | |
502 | [clean_manufacturer_name($searchterm), | |
503 | $p->{make}, -300], | |
504 | [$searchterm, $p->{id}, 0]]; | |
505 | ||
506 | foreach my $task (@{$searchtasks}) { | |
507 | ||
508 | # Do not try to match search terms or database entries without | |
509 | # real content | |
510 | next unless $task->[0] =~ /[a-z]/i; | |
511 | next unless $task->[1] =~ /[a-z]/i; | |
512 | ||
513 | # If make and model match exactly, we have found the correct | |
514 | # entry and we can stop searching human-readable makes and | |
515 | # models | |
516 | if (normalize($task->[1]) eq normalize($task->[0])) { | |
517 | $matchlength = 100; | |
518 | $bestmatchlength = $matchlength + $task->[2] if | |
519 | $bestmatchlength < $matchlength + $task->[2]; | |
520 | $results{$p->{id}} = $matchlength + $task->[2] if | |
521 | (!defined($results{$p->{id}}) || | |
522 | ($results{$p->{id}} < $matchlength)); | |
523 | next DBENTRY; | |
524 | } | |
525 | ||
526 | # Matching a part of the human-readable makes and models | |
527 | # should only be done if the search term is not the name of | |
528 | # an old model, otherwise the newest, not yet listed models | |
529 | # match with the oldest model of the manufacturer (as the | |
530 | # Epson Stylus Photo 900 with the original Epson Stylus Photo) | |
531 | my @badsearchterms = | |
532 | ("HP|DeskJet", | |
533 | "HP|LaserJet", | |
534 | "HP|DesignJet", | |
535 | "HP|OfficeJet", | |
536 | "HP|PhotoSmart", | |
537 | "EPSON|Stylus", | |
538 | "EPSON|Stylus Color", | |
539 | "EPSON|Stylus Photo", | |
540 | "EPSON|Stylus Pro", | |
541 | "XEROX|WorkCentre", | |
542 | "XEROX|DocuPrint"); | |
543 | if (!member($task->[0], @badsearchterms)) { | |
544 | my $searcht = normalize($task->[0]); | |
545 | my $lsearcht = length($searcht); | |
546 | $searcht =~ s!([\\/\(\)\[\]\|\.\$\@\%\*\?])!\\$1!g; | |
547 | my $s = normalize($task->[1]); | |
548 | if ((1 || $lsearcht >= $matchlength) && | |
549 | $s =~ m!$searcht!i) { | |
550 | $matchlength = $lsearcht; | |
551 | $bestmatchlength = $matchlength + $task->[2] if | |
552 | $bestmatchlength < $matchlength + $task->[2]; | |
553 | $results{$p->{id}} = $matchlength + $task->[2] if | |
554 | (!defined($results{$p->{id}}) || | |
555 | ($results{$p->{id}} < $matchlength)); | |
556 | } | |
557 | } | |
558 | if (!member($task->[1], @badsearchterms)) { | |
559 | my $searcht = normalize($task->[1]); | |
560 | my $lsearcht = length($searcht); | |
561 | $searcht =~ s!([\\/\(\)\[\]\|\.\$\@\%\*\?])!\\$1!g; | |
562 | my $s = normalize($task->[0]); | |
563 | if ((1 || $lsearcht >= $matchlength) && | |
564 | $s =~ m!$searcht!i) { | |
565 | $matchlength = $lsearcht; | |
566 | $bestmatchlength = $matchlength + $task->[2] if | |
567 | $bestmatchlength < $matchlength + $task->[2]; | |
568 | $results{$p->{id}} = $matchlength + $task->[2] if | |
569 | (!defined($results{$p->{id}}) || | |
570 | ($results{$p->{id}} < $matchlength)); | |
571 | } | |
572 | } | |
573 | } | |
574 | } | |
575 | ||
576 | return grep { | |
577 | ((($mode == 4) && ($results{$_} >= 100)) || | |
578 | (($mode == 3) && ($results{$_} > 60)) || | |
579 | (($mode == 2) && ($results{$_} > -100)) || | |
580 | (($mode == 1) && ($results{$_} > -200)) || | |
581 | ($mode == 0)) && | |
582 | (($output == 0) || | |
583 | (($output == 1) && | |
584 | !((($bestmatchlength >= 100) && ($results{$_} < 100)) || | |
585 | (($bestmatchlength >= 60) && ($results{$_} < 60)) || | |
586 | (($bestmatchlength >= 0) && ($results{$_} < 0)) || | |
587 | (($bestmatchlength >= -100) && ($results{$_} < -100)) || | |
588 | (($bestmatchlength >= -200) && ($results{$_} < -200)) || | |
589 | (($bestmatchlength >= -300) && ($results{$_} < -300)) || | |
590 | (($bestmatchlength >= -400) && ($results{$_} < -400)))) || | |
591 | (($output == 2) && | |
592 | ($results{$_} == $bestmatchlength))) | |
593 | } sort { $results{$b} <=> $results{$a} } keys(%results); | |
181 | 594 | } |
182 | 595 | |
183 | 596 | # This function sorts the options at first by their group membership and |
567 | 980 | # Generate Perl data structure from database |
568 | 981 | my %dat; # Our purpose in life... |
569 | 982 | my $VAR1; |
570 | eval (`$bindir/foomatic-combo-xml -d '$drv' -p '$poid' -l '$libdir' | $bindir/foomatic-perl-data -C`) || | |
983 | eval (`$bindir/foomatic-combo-xml -d '$drv' -p '$poid' -l '$libdir' | $bindir/foomatic-perl-data -C -l $this->{'language'}`) || | |
571 | 984 | die ("Could not run \"foomatic-combo-xml\"/" . |
572 | 985 | "\"foomatic-perl-data\"!"); |
573 | 986 | %dat = %{$VAR1}; |
582 | 995 | checklongnames($this->{'dat'}); |
583 | 996 | sortoptions($this->{'dat'}); |
584 | 997 | generalentries($this->{'dat'}); |
585 | ||
998 | if (defined($this->{'dat'}{'shortdescription'})) { | |
999 | $this->{'dat'}{'shortdescription'} =~ s/[\s\n\r]+/ /s; | |
1000 | $this->{'dat'}{'shortdescription'} =~ s/^\s+//; | |
1001 | $this->{'dat'}{'shortdescription'} =~ s/\s+$//; | |
1002 | } | |
586 | 1003 | return \%dat; |
587 | 1004 | } |
588 | 1005 | |
602 | 1019 | |
603 | 1020 | sub ppdfromvartoperl ($); |
604 | 1021 | sub ppdtoperl($); |
605 | sub perltoxml($); | |
1022 | sub perltoxml; | |
606 | 1023 | |
607 | 1024 | sub ppdtoperl($) { |
608 | 1025 | |
753 | 1170 | $line =~ m!^([^\"]*)\"!; |
754 | 1171 | $cmd .= $1; |
755 | 1172 | $dat->{'cmd'} = unhtmlify($cmd); |
1173 | } elsif (m!^\*FoomaticRIPNoPageAccounting:\s*(\S+)\s*$!) { | |
1174 | # "*FoomaticRIPNoPageAccounting: <boolean value>" | |
1175 | my $value = $1; | |
1176 | # Store the value | |
1177 | if ($value =~ /^True$/i) { | |
1178 | $dat->{'drivernopageaccounting'} = 1; | |
1179 | } else { | |
1180 | delete $dat->{'drivernopageaccounting'}; | |
1181 | } | |
756 | 1182 | } elsif (m!^\*CustomPageSize\s+True:\s*\"(.*)$!) { |
757 | 1183 | # "*CustomPageSize True: <code>" |
758 | 1184 | my $setting = "Custom"; |
792 | 1218 | $dat->{'args_byname'}{'PageSize'}{'vals_byname'}{$setting}{'driverval'} = $code; |
793 | 1219 | $dat->{'args_byname'}{'PageRegion'}{'vals_byname'}{$setting}{'driverval'} = $code; |
794 | 1220 | } |
795 | } elsif (m!^\*Open(Sub|)Group:\s*([^/]+)(/(.*)|)$!) { | |
1221 | } elsif (m!^\*Open(Sub|)Group:\s*\*?([^/]+?)(/(.*)|)$!) { | |
796 | 1222 | # "*Open[Sub]Group: <group>[/<translation>] |
797 | 1223 | my $group = $2; |
798 | 1224 | chomp($group) if $group; |
807 | 1233 | $currentgroup .= $group; |
808 | 1234 | push(@currentgrouptrans, |
809 | 1235 | unhexify($grouptrans, $dat->{"encoding"})); |
810 | } elsif (m!^\*Close(Sub|)Group:\s*([^/]+)$!) { | |
1236 | } elsif (m!^\*Close(Sub|)Group:\s*\*?([^/]+?)$!) { | |
811 | 1237 | # "*Close[Sub]Group: <group>" |
812 | 1238 | my $group = $2; |
813 | 1239 | chomp($group) if $group; |
1234 | 1660 | return $dat; |
1235 | 1661 | } |
1236 | 1662 | |
1237 | sub perltoxml ($) { | |
1238 | my ($this, $dat) = @_; | |
1239 | ||
1240 | my $xml = | |
1241 | "<foomatic><printer id=\"printer/" . $dat->{'id'} . "\">\n" . | |
1242 | " <make>" . $dat->{'make'} . "</make>\n" . | |
1243 | " <model>" . $dat->{'model'} . "</model>\n" . | |
1244 | " <comments><en /></comments>\n" . | |
1245 | "</printer>\n\n\n"; | |
1246 | ||
1247 | $xml .= | |
1248 | "<driver id=\"driver/" . $dat->{'driver'} . "\">\n" . | |
1249 | " <name>" . $dat->{'driver'} . "</name>\n" . | |
1250 | " <execution>\n" . | |
1251 | " <filter />\n" . | |
1252 | " <prototype>" . $dat->{'cmd'} . "</prototype>\n" . | |
1253 | " </execution>\n" . | |
1254 | "</driver>\n\n"; | |
1255 | ||
1256 | $xml .= "<options>\n"; | |
1257 | ||
1258 | foreach (@{$dat->{'args'}}) { | |
1259 | my $type = $_->{'type'}; | |
1260 | my $optname = $_->{'name'}; | |
1261 | $xml .= " <option type=\"$type\" " . | |
1262 | "id=\"opt/" . $dat->{'driver'} . "-" . $optname . "\">\n"; | |
1663 | sub perltoxml { | |
1664 | my ($this, $dat, $mode) = @_; | |
1665 | ||
1666 | my $xml = ""; | |
1667 | ||
1668 | $xml .= "<foomatic>\n" if !$mode || ($mode =~ /^c/i); | |
1669 | ||
1670 | if (!$mode || ($mode =~ /^[cp]/i)) { | |
1263 | 1671 | $xml .= |
1264 | " <arg_longname>\n" . | |
1265 | " <en>" . $_->{'comment'} . "</en>\n" . | |
1266 | " </arg_longname>\n" . | |
1267 | " <arg_shortname>\n" . | |
1268 | " <en>" . $_->{'name'} . "</en>\n" . | |
1269 | " </arg_shortname>\n" . | |
1270 | " <arg_execution>\n"; | |
1271 | $xml .= " <arg_group>" . $_->{'group'} . "</arg_group>\n" | |
1272 | if $_->{'group'}; | |
1273 | $xml .= " <arg_order>" . $_->{'order'} . "</arg_order>\n" | |
1274 | if $_->{'order'}; | |
1275 | $xml .= " <arg_spot>" . $_->{'spot'} . "</arg_spot>\n" | |
1276 | if $_->{'spot'}; | |
1277 | $xml .= " <arg_proto>" . $_->{'proto'} . "</arg_proto>\n" | |
1278 | if $_->{'proto'}; | |
1279 | $xml .= " </arg_execution>\n"; | |
1280 | ||
1281 | if ($type eq 'enum') { | |
1282 | $xml .= " <enum_vals>\n"; | |
1283 | my $vals_byname = $_->{'vals_byname'}; | |
1284 | foreach (keys(%{$vals_byname})) { | |
1285 | my $val = $vals_byname->{$_}; | |
1286 | $xml .= | |
1287 | " <enum_val id=\"ev/" . $dat->{'driver'} . "-" . | |
1288 | $optname . "-" . $_ . "\">\n"; | |
1289 | $xml .= | |
1290 | " <ev_longname>\n" . | |
1291 | " <en>" . $val->{'comment'} . "</en>\n" . | |
1292 | " </ev_longname>\n" . | |
1293 | " <ev_shortname>\n" . | |
1294 | " <en>$_</en>\n" . | |
1295 | " </ev_shortname>\n"; | |
1296 | ||
1297 | $xml .= | |
1298 | " <ev_driverval>" . | |
1299 | $val->{'driverval'} . | |
1300 | "</ev_driverval>\n" if $val->{'driverval'}; | |
1301 | ||
1302 | $xml .= " </enum_val>\n"; | |
1303 | } | |
1304 | } | |
1305 | ||
1306 | $xml .= " </option>\n"; | |
1307 | } | |
1308 | ||
1309 | $xml .= "</options>\n"; | |
1310 | ||
1672 | "<printer id=\"printer/" . $dat->{'id'} . "\">\n" . | |
1673 | " <make>" . $dat->{'make'} . "</make>\n" . | |
1674 | " <model>" . $dat->{'model'} . "</model>\n" . | |
1675 | " <mechanism>\n" . | |
1676 | ($dat->{'type'} ? " <" . $dat->{'type'} . "/>\n" : ()) . | |
1677 | ($dat->{'color'} ? " <color/>\n" : ()) . | |
1678 | ($dat->{'maxxres'} || $dat->{'maxyres'} ? | |
1679 | " <resolution>\n" . | |
1680 | " <dpi>\n" . | |
1681 | ($dat->{'maxxres'} ? | |
1682 | " <x>" . $dat->{'maxxres'} . "</x>\n" : ()) . | |
1683 | ($dat->{'maxyres'} ? | |
1684 | " <y>" . $dat->{'maxyres'} . "</y>\n" : ()) . | |
1685 | " </dpi>\n" . | |
1686 | " </resolution>\n" : ()) . | |
1687 | ||
1688 | " <comments><en /></comments>\n" . | |
1689 | "</printer>\n\n\n"; | |
1690 | } | |
1691 | ||
1692 | if (!$mode || ($mode =~ /^[cd]/i)) { | |
1693 | $xml .= | |
1694 | "<driver id=\"driver/" . $dat->{'driver'} . "\">\n" . | |
1695 | " <name>" . $dat->{'driver'} . "</name>\n" . | |
1696 | " <execution>\n" . | |
1697 | " <filter />\n" . | |
1698 | " <prototype>" . $dat->{'cmd'} . "</prototype>\n" . | |
1699 | " </execution>\n" . | |
1700 | "</driver>\n\n"; | |
1701 | } | |
1702 | ||
1703 | if (!$mode || ($mode =~ /^c/i)) { | |
1704 | $xml .= "<options>\n"; | |
1705 | ||
1706 | foreach (@{$dat->{'args'}}) { | |
1707 | my $type = $_->{'type'}; | |
1708 | my $optname = $_->{'name'}; | |
1709 | $xml .= " <option type=\"$type\" " . | |
1710 | "id=\"opt/" . $dat->{'driver'} . "-" . $optname . "\">\n"; | |
1711 | $xml .= | |
1712 | " <arg_longname>\n" . | |
1713 | " <en>" . $_->{'comment'} . "</en>\n" . | |
1714 | " </arg_longname>\n" . | |
1715 | " <arg_shortname>\n" . | |
1716 | " <en>" . $_->{'name'} . "</en>\n" . | |
1717 | " </arg_shortname>\n" . | |
1718 | " <arg_execution>\n"; | |
1719 | $xml .= " <arg_group>" . $_->{'group'} . "</arg_group>\n" | |
1720 | if $_->{'group'}; | |
1721 | $xml .= " <arg_order>" . $_->{'order'} . "</arg_order>\n" | |
1722 | if $_->{'order'}; | |
1723 | $xml .= " <arg_spot>" . $_->{'spot'} . "</arg_spot>\n" | |
1724 | if $_->{'spot'}; | |
1725 | $xml .= " <arg_proto>" . $_->{'proto'} . "</arg_proto>\n" | |
1726 | if $_->{'proto'}; | |
1727 | $xml .= " </arg_execution>\n"; | |
1728 | ||
1729 | if ($type eq 'enum') { | |
1730 | $xml .= " <enum_vals>\n"; | |
1731 | my $vals_byname = $_->{'vals_byname'}; | |
1732 | foreach (keys(%{$vals_byname})) { | |
1733 | my $val = $vals_byname->{$_}; | |
1734 | $xml .= | |
1735 | " <enum_val id=\"ev/" . $dat->{'driver'} . "-" . | |
1736 | $optname . "-" . $_ . "\">\n"; | |
1737 | $xml .= | |
1738 | " <ev_longname>\n" . | |
1739 | " <en>" . $val->{'comment'} . "</en>\n" . | |
1740 | " </ev_longname>\n" . | |
1741 | " <ev_shortname>\n" . | |
1742 | " <en>$_</en>\n" . | |
1743 | " </ev_shortname>\n"; | |
1744 | ||
1745 | $xml .= | |
1746 | " <ev_driverval>" . | |
1747 | $val->{'driverval'} . | |
1748 | "</ev_driverval>\n" if $val->{'driverval'}; | |
1749 | ||
1750 | $xml .= " </enum_val>\n"; | |
1751 | } | |
1752 | } | |
1753 | ||
1754 | $xml .= " </option>\n"; | |
1755 | } | |
1756 | ||
1757 | $xml .= "</options>\n"; | |
1758 | $xml .= "</foomatic>\n"; | |
1759 | } | |
1311 | 1760 | return $xml; |
1312 | 1761 | } |
1313 | 1762 | |
1652 | 2101 | } |
1653 | 2102 | |
1654 | 2103 | sub checksetting { |
1655 | # Check if there is already an choice record $setting in the $argname | |
2104 | # Check if there is already a choice record $setting in the $argname | |
1656 | 2105 | # argument in $dat, if not, create one |
1657 | 2106 | my ($dat, $argname, $setting) = @_; |
1658 | 2107 | return if |
1861 | 2310 | } |
1862 | 2311 | |
1863 | 2312 | # If the settings for "PageSize" and "PageRegion" are different, |
1864 | # set the one for "PageRegion" to the one for "PageSize" and issue | |
1865 | # a warning. | |
2313 | # set the one for "PageRegion" to the one for "PageSize". | |
1866 | 2314 | if ($dat->{'args_byname'}{'PageSize'}{$optionset} ne |
1867 | 2315 | $dat->{'args_byname'}{'PageRegion'}{$optionset}) { |
1868 | 2316 | $dat->{'args_byname'}{'PageRegion'}{$optionset} = |
1899 | 2347 | } |
1900 | 2348 | |
1901 | 2349 | # Do it! |
1902 | my $val; | |
2350 | my $val; | |
1903 | 2351 | if ($val=valbyname($dat->{'args_byname'}{$dest}, $value)) { |
1904 | 2352 | # Standard paper size |
1905 | 2353 | $dat->{'args_byname'}{$dest}{$optionset} = $val->{'value'}; |
2069 | 2517 | } |
2070 | 2518 | } |
2071 | 2519 | |
2072 | sub ppd1284DeviceID { | |
2073 | ||
2074 | # Clean up IEEE-1284 device ID to only contain the fields relevant | |
2075 | # to printer model auto-detection (MFG, MDL, DES, CMD, SKU), this | |
2076 | # the line length limit of PPDs does not get exceeded on very long | |
2077 | # ID strings. | |
2078 | ||
2079 | my ($id) = @_; | |
2080 | my $ppdid = ""; | |
2081 | ||
2082 | foreach my $field ("(MFG|MANUFACTURER)", "(MDL|MODEL)", "(CMD|COMMAND SET)", "(DES|DESCRIPTION)", "SKU") { | |
2083 | if ($id =~ m/(\b$field:[^:;]+;)/is) { | |
2084 | $ppdid .= $1; | |
2085 | } | |
2086 | } | |
2087 | ||
2088 | return $ppdid; | |
2089 | } | |
2090 | ||
2091 | sub getppdheaderdata { | |
2092 | ||
2093 | my ($dat, $driver, $recdriver) = @_; | |
2520 | sub deviceIDfromDBEntry { | |
2521 | ||
2522 | my ($dat) = @_; | |
2094 | 2523 | |
2095 | 2524 | # Complete IEEE 1284 ID string? |
2096 | 2525 | my $ieee1284; |
2138 | 2567 | $ieee1284 .= "CMD:$pnpcmd;" if $pnpcmd; |
2139 | 2568 | $ieee1284 .= "DES:$pnpdescription;" if $pnpdescription; |
2140 | 2569 | } |
2570 | return $ieee1284; | |
2571 | } | |
2572 | ||
2573 | sub ppd1284DeviceID { | |
2574 | ||
2575 | # Clean up IEEE-1284 device ID to only contain the fields relevant | |
2576 | # to printer model auto-detection (MFG, MDL, DES, CMD, SKU), thus | |
2577 | # the line length limit of PPDs does not get exceeded on very long | |
2578 | # ID strings. | |
2579 | ||
2580 | my ($id) = @_; | |
2581 | my $ppdid = ""; | |
2582 | ||
2583 | foreach my $field ("(MFG|MANUFACTURER)", "(MDL|MODEL)", "(CMD|COMMAND SET)", "(DES|DESCRIPTION)", "SKU", "DRV") { | |
2584 | if ($id =~ m/(\b$field:[^:;]+;)/is) { | |
2585 | $ppdid .= $1; | |
2586 | } | |
2587 | } | |
2588 | ||
2589 | return $ppdid; | |
2590 | } | |
2591 | ||
2592 | sub getppdheaderdata { | |
2593 | ||
2594 | my ($dat, $driver, $recdriver) = @_; | |
2595 | ||
2596 | my $ieee1284 = deviceIDfromDBEntry($dat); | |
2597 | ||
2598 | # Add driver profile to device ID string, so we get it into the | |
2599 | # PPD listing output of CUPS | |
2600 | my @profileitems = (); | |
2601 | my $profileelements = | |
2602 | [["manufacturersupplied", "M"], | |
2603 | ["obsolete", "O"], | |
2604 | ["free", "F"], | |
2605 | ["supportcontacts", "S"], | |
2606 | ["type", "T"], | |
2607 | ["drvmaxresx", "X"], | |
2608 | ["drvmaxresy", "Y"], | |
2609 | ["drvcolor", "C"], | |
2610 | ["text", "t"], | |
2611 | ["lineart", "l"], | |
2612 | ["graphics", "g"], | |
2613 | ["photo", "p"], | |
2614 | ["load", "d"], | |
2615 | ["speed", "s"]]; | |
2616 | my $drvfield = ''; | |
2617 | foreach my $item (@{$profileelements}) { | |
2618 | my ($perlkey, $devidkey) = @{$item}; | |
2619 | if ($perlkey eq "manufacturersupplied") { | |
2620 | my $ms; | |
2621 | if (defined($dat->{$perlkey})) { | |
2622 | $ms = $dat->{$perlkey}; | |
2623 | } elsif (defined($dat->{'driverproperties'}{$driver}{$perlkey})) { | |
2624 | $ms = $dat->{'driverproperties'}{$driver}{$perlkey}; | |
2625 | } | |
2626 | $drvfield .= "," . $devidkey . | |
2627 | ($ms eq "1" ? "1" : ($dat->{make} =~ m,^($ms)$,i ? "1" : "0")); | |
2628 | } elsif ($perlkey eq "supportcontacts") { | |
2629 | my $sc; | |
2630 | if (defined($dat->{$perlkey})) { | |
2631 | $sc = $dat->{$perlkey}; | |
2632 | } elsif (defined($dat->{'driverproperties'}{$driver}{$perlkey})) { | |
2633 | $sc = $dat->{'driverproperties'}{$driver}{$perlkey}; | |
2634 | } | |
2635 | if ($sc) { | |
2636 | my $commercial = 0; | |
2637 | my $voluntary = 0; | |
2638 | my $unknown = 0; | |
2639 | foreach my $entry (@{$sc}) { | |
2640 | if ($entry->{'level'} =~ /^commercial$/i) { | |
2641 | $commercial = 1; | |
2642 | } elsif ($entry->{'level'} =~ /^voluntary$/i) { | |
2643 | $voluntary = 1; | |
2644 | } else { | |
2645 | $unknown = 1; | |
2646 | } | |
2647 | } | |
2648 | $drvfield .= "," . $devidkey . ($commercial ? "c" : "") . | |
2649 | ($voluntary ? "v" : "") . ($unknown ? "u" : ""); | |
2650 | } | |
2651 | } else { | |
2652 | if (defined($dat->{$perlkey})) { | |
2653 | $drvfield .= "," . $devidkey . $dat->{$perlkey}; | |
2654 | } elsif (defined($dat->{'driverproperties'}{$driver}{$perlkey})) { | |
2655 | $drvfield .= "," . $devidkey . | |
2656 | $dat->{'driverproperties'}{$driver}{$perlkey}; | |
2657 | } | |
2658 | } | |
2659 | } | |
2660 | $ieee1284 .= "DRV:D$driver" . | |
2661 | ($recdriver ? ($driver eq $recdriver ? ",R1" : ",R0") : "") . | |
2662 | "$drvfield;"; | |
2141 | 2663 | |
2142 | 2664 | # Remove everything from the device ID which is not relevant to |
2143 | 2665 | # auto-detection of the printer model. |
2146 | 2668 | my $make = $dat->{'make'}; |
2147 | 2669 | my $model = $dat->{'model'}; |
2148 | 2670 | |
2671 | $ieee1284 =~ /(MFG|MANUFACTURER):([^;]+);/; | |
2672 | my $pnpmake = $2; | |
2149 | 2673 | $pnpmake = $make if !$pnpmake; |
2674 | $ieee1284 =~ /(MDL|MODEL):([^;]+);/; | |
2675 | my $pnpmodel = $2; | |
2150 | 2676 | $pnpmodel = $model if !$pnpmodel; |
2151 | 2677 | |
2152 | 2678 | # File name for the PPD file |
2153 | 2679 | my $filename = join('-',($dat->{'make'}, |
2154 | 2680 | $dat->{'model'}, |
2155 | 2681 | $driver));; |
2156 | $filename =~ s![ /\(\)]!_!g; | |
2682 | $filename =~ s![ /\(\)\,]!_!g; | |
2157 | 2683 | $filename =~ s![\+]!plus!g; |
2158 | 2684 | $filename =~ s!__+!_!g; |
2159 | 2685 | $filename =~ s!_$!!; |
2174 | 2700 | # evil special case. |
2175 | 2701 | $drivername = "stp-4.0" if $drivername eq 'stp'; |
2176 | 2702 | |
2177 | # Nickname for the PPPD file | |
2703 | # Nickname for the PPD file | |
2178 | 2704 | my $nickname = |
2179 | 2705 | "$make $model Foomatic/$drivername$driverrecommended"; |
2180 | 2706 | my $modelname = "$make $model"; |
2325 | 2851 | if ($cmdlinestr =~ /\n/s) { |
2326 | 2852 | push(@optionblob, "*End\n"); |
2327 | 2853 | } |
2854 | } | |
2855 | if ($dat->{'drivernopageaccounting'}) { | |
2856 | push(@optionblob, "*FoomaticRIPNoPageAccounting: True\n"); | |
2328 | 2857 | } |
2329 | 2858 | |
2330 | 2859 | # Search for composite options and prepare the member options |
3468 | 3997 | |
3469 | 3998 | my $headcomment = |
3470 | 3999 | "*% For information on using this, and to obtain the required backend |
3471 | *% script, consult http://www.linuxprinting.org/ | |
4000 | *% script, consult http://www.openprinting.org/ | |
3472 | 4001 | *% |
3473 | 4002 | *% This file is published under the GNU General Public License |
3474 | 4003 | *% |
3513 | 4042 | $drivername,$nickname,$modelname) = |
3514 | 4043 | getppdheaderdata($dat, $dat->{'driver'}, $dat->{'recdriver'}); |
3515 | 4044 | if ($ieee1284) { |
3516 | #$ieee1284 =~ s/;(.)/;\n $1/gs; | |
3517 | #$ieee1284 = "*1284DeviceID: \"\n " . $ieee1284 . "\n\"\n*End"; | |
3518 | #$ieee1284 =~ s/;(.)/;\n $1/gs; | |
3519 | 4045 | $ieee1284 = "*1284DeviceID: \"" . $ieee1284 . "\""; |
3520 | 4046 | } |
4047 | ||
4048 | # Add info about driver properties | |
4049 | my $drvproperties = ""; | |
4050 | $drvproperties .= "*driverName $dat->{'driver'}/$dat->{'driver'}" . | |
4051 | ($dat->{'shortdescription'} ? | |
4052 | " - $dat->{'shortdescription'}" : "") . | |
4053 | ": \"\"\n" if defined($dat->{'driver'}); | |
4054 | $drvproperties .= "*driverType $dat->{'type'}" . | |
4055 | ($dat->{'type'} eq "G" ? "/GhostScript built-in" : | |
4056 | ($dat->{'type'} eq "U" ? "/GhostScript Uniprint" : | |
4057 | ($dat->{'type'} eq "F" ? "/Filter" : | |
4058 | ($dat->{'type'} eq "C" ? "/CUPS Raster" : | |
4059 | ($dat->{'type'} eq "V" ? "/OpenPrinting Vector" : | |
4060 | ($dat->{'type'} eq "I" ? "/IJS" : | |
4061 | ($dat->{'type'} eq "P" ? "/PostScript" : ""))))))) . | |
4062 | ": \"\"\n" if defined($dat->{'type'}); | |
4063 | $drvproperties .= "*driverUrl: \"$dat->{'url'}\"\n" if | |
4064 | defined($dat->{'url'}); | |
4065 | if ((defined($dat->{'obsolete'})) && | |
4066 | ($dat->{'obsolete'} ne "0")) { | |
4067 | $drvproperties .= "*driverObsolete: True\n"; | |
4068 | if ($dat->{'obsolete'} ne "1") { | |
4069 | $drvproperties .= "*driverRecommendedReplacement: " . | |
4070 | "\"$dat->{'obsolete'}\"\n"; | |
4071 | } | |
4072 | } else { | |
4073 | $drvproperties .= "*driverObsolete: False\n"; | |
4074 | } | |
4075 | $drvproperties .= "*driverSupplier: \"$dat->{'supplier'}\"\n" if | |
4076 | defined($dat->{'supplier'}); | |
4077 | $drvproperties .= "*driverManufacturerSupplied: " . | |
4078 | ($dat->{'manufacturersupplied'} eq "1" ? "True" : | |
4079 | ($dat->{make} =~ m,^($dat->{'manufacturersupplied'})$,i ? "True" : | |
4080 | "False")) . "\n" if | |
4081 | defined($dat->{'manufacturersupplied'}); | |
4082 | $drvproperties .= "*driverLicense: \"$dat->{'license'}\"\n" if | |
4083 | defined($dat->{'license'}); | |
4084 | $drvproperties .= "*driverFreeSoftware: " . | |
4085 | ($dat->{'free'} ? "True" : "False") . "\n" if | |
4086 | defined($dat->{'free'}); | |
4087 | if (defined($dat->{'supportcontacts'})) { | |
4088 | foreach my $entry (@{$dat->{'supportcontacts'}}) { | |
4089 | my $uclevel = uc(substr($entry->{'level'}, 0, 1)) . | |
4090 | lc(substr($entry->{'level'}, 1)); | |
4091 | $drvproperties .= "*driverSupportContact${uclevel}: " . | |
4092 | "\"$entry->{'url'} $entry->{'description'}\"\n"; | |
4093 | } | |
4094 | } | |
4095 | if (defined($dat->{'drvmaxresx'}) || defined($dat->{'drvmaxresy'})) { | |
4096 | my ($maxresx, $maxresy); | |
4097 | $maxresx = $dat->{'drvmaxresx'} if defined($dat->{'drvmaxresx'}); | |
4098 | $maxresy = $dat->{'drvmaxresy'} if defined($dat->{'drvmaxresy'}); | |
4099 | $maxresx = $maxresy if !$maxresx; | |
4100 | $maxresy = $maxresx if !$maxresy; | |
4101 | $drvproperties .= "*driverMaxResolution: " . | |
4102 | "${maxresx} ${maxresy}\n"; | |
4103 | } | |
4104 | $drvproperties .= "*driverColor: " . | |
4105 | ($dat->{'drvcolor'} ? "True" : "False") . "\n" if | |
4106 | defined($dat->{'drvcolor'}); | |
4107 | $drvproperties .= "*driverTextSupport: $dat->{'text'}\n" if | |
4108 | defined($dat->{'text'}); | |
4109 | $drvproperties .= "*driverLineartSupport: $dat->{'lineart'}\n" if | |
4110 | defined($dat->{'lineart'}); | |
4111 | $drvproperties .= "*driverGraphicsSupport: $dat->{'graphics'}\n" if | |
4112 | defined($dat->{'graphics'}); | |
4113 | $drvproperties .= "*driverPhotoSupport: $dat->{'photo'}\n" if | |
4114 | defined($dat->{'photo'}); | |
4115 | $drvproperties .= "*driverSystemmLoad: $dat->{'load'}\n" if | |
4116 | defined($dat->{'load'}); | |
4117 | $drvproperties .= "*driverRenderingSpeed: $dat->{'speed'}\n" if | |
4118 | defined($dat->{'speed'}); | |
4119 | $drvproperties = "\n$drvproperties" if $drvproperties; | |
4120 | ||
3521 | 4121 | # Do not use "," or "+" in the *ShortNickName to make the Windows |
3522 | 4122 | # PostScript drivers happy |
3523 | 4123 | my $shortnickname = "$make $model $drivername"; |
3623 | 4223 | $tmpl =~ s!\@\@SHORTNICKNAME\@\@!$shortnickname!g; |
3624 | 4224 | $tmpl =~ s!\@\@COLOR\@\@!$color!g; |
3625 | 4225 | $tmpl =~ s!\@\@IEEE1284\@\@!$ieee1284!g; |
4226 | $tmpl =~ s!\@\@DRIVERPROPERTIES\@\@!$drvproperties!g; | |
3626 | 4227 | $tmpl =~ s!\@\@OTHERSTUFF\@\@!$otherstuff!g; |
3627 | 4228 | $tmpl =~ s!\@\@OPTIONS\@\@!$opts!g; |
3628 | 4229 | $tmpl =~ s!\@\@EXTRALINES\@\@!$extralines!g; |
3672 | 4273 | sub getmarginsformarginrecord { |
3673 | 4274 | my ($margins, $width, $height, $pagesize) = @_; |
3674 | 4275 | if (!defined($margins)) { |
3675 | # No margins defined? Return zero margins | |
3676 | return (0, $width, $height, 0); | |
4276 | # No margins defined? Return invalid margins | |
4277 | return (undef, undef, undef, undef); | |
3677 | 4278 | } |
3678 | 4279 | # Defaults |
3679 | 4280 | my $unit = 'pt'; |
3680 | 4281 | my $absolute = 0; |
3681 | my ($left, $right, $top, $bottom) = (0, $width, $height, 0); | |
4282 | my ($left, $right, $top, $bottom) = (undef, undef, undef, undef); | |
3682 | 4283 | # Check the general margins and then the particular paper size |
3683 | 4284 | for my $i ('_general', $pagesize) { |
3684 | 4285 | # Skip a section if it is not defined |
3730 | 4331 | sub getmargins { |
3731 | 4332 | my ($dat, $width, $height, $pagesize) = @_; |
3732 | 4333 | # Determine the unprintable margins |
3733 | # Zero margins when no margin info exists | |
3734 | my ($left, $right, $top, $bottom) = | |
3735 | (0, $width, $height, 0); | |
4334 | my ($left, $right, $top, $bottom) = (undef, undef, undef, undef); | |
3736 | 4335 | # Margins from printer database entry |
3737 | 4336 | my ($pleft, $pright, $ptop, $pbottom) = |
3738 | 4337 | getmarginsformarginrecord($dat->{'printermargins'}, |
3746 | 4345 | getmarginsformarginrecord($dat->{'combomargins'}, |
3747 | 4346 | $width, $height, $pagesize); |
3748 | 4347 | # Left margin |
3749 | if ($pleft > $left) {$left = $pleft}; | |
3750 | if ($dleft > $left) {$left = $dleft}; | |
3751 | if ($cleft > $left) {$left = $cleft}; | |
4348 | if (defined($pleft)) {$left = $pleft}; | |
4349 | if (defined($dleft) && | |
4350 | (!defined($left) || ($dleft > $left))) {$left = $dleft}; | |
4351 | if (defined($cleft) && | |
4352 | (!defined($left) || ($cleft > $left))) {$left = $cleft}; | |
3752 | 4353 | # Right margin |
3753 | if ($pright < $right) {$right = $pright}; | |
3754 | if ($dright < $right) {$right = $dright}; | |
3755 | if ($cright < $right) {$right = $cright}; | |
4354 | if (defined($pright)) {$right = $pright}; | |
4355 | if (defined($dright) && | |
4356 | (!defined($right) || ($dright < $right))) {$right = $dright}; | |
4357 | if (defined($cright) && | |
4358 | (!defined($right) || ($cright < $right))) {$right = $cright}; | |
3756 | 4359 | # Top margin |
3757 | if ($ptop < $top) {$top = $ptop}; | |
3758 | if ($dtop < $top) {$top = $dtop}; | |
3759 | if ($ctop < $top) {$top = $ctop}; | |
4360 | if (defined($ptop)) {$top = $ptop}; | |
4361 | if (defined($dtop) && | |
4362 | (!defined($top) || ($dtop < $top))) {$top = $dtop}; | |
4363 | if (defined($ctop) && | |
4364 | (!defined($top) || ($ctop < $top))) {$top = $ctop}; | |
3760 | 4365 | # Bottom margin |
3761 | if ($pbottom > $bottom) {$bottom = $pbottom}; | |
3762 | if ($dbottom > $bottom) {$bottom = $dbottom}; | |
3763 | if ($cbottom > $bottom) {$bottom = $cbottom}; | |
4366 | if (defined($pbottom)) {$bottom = $pbottom}; | |
4367 | if (defined($dbottom) && | |
4368 | (!defined($bottom) || ($dbottom > $bottom))) {$bottom = $dbottom}; | |
4369 | if (defined($cbottom) && | |
4370 | (!defined($bottom) || ($dbottom > $bottom))) {$bottom = $cbottom}; | |
4371 | # Safe margins when margin info is missing | |
4372 | my $tborder = 36; | |
4373 | my $bborder = 36; | |
4374 | my $lborder = 18; | |
4375 | my $rborder = 18; | |
4376 | $left = $lborder if !defined($left); | |
4377 | $right = $width - $rborder if !defined($right); | |
4378 | $top = $height - $tborder if !defined($top); | |
4379 | $bottom = $bborder if !defined($bottom); | |
3764 | 4380 | # If we entered with $width == 0 and $height == 0, we mean |
3765 | 4381 | # relative margins, so correct the signs |
3766 | 4382 | if ($width == 0) {$right = -$right}; |
3912 | 4528 | *LandscapeOrientation: Plus90 |
3913 | 4529 | *TTRasterizer: Type42 |
3914 | 4530 | \@\@IEEE1284\@\@ |
4531 | \@\@DRIVERPROPERTIES\@\@ | |
3915 | 4532 | \@\@EXTRALINES\@\@ |
3916 | 4533 | \@\@OTHERSTUFF\@\@ |
3917 | 4534 | |
3964 | 4581 | # files. |
3965 | 4582 | # |
3966 | 4583 | # The paper sizes in the list are all sizes known to GhostScript, all |
3967 | # of Gimp-Print, all sizes of HPIJS, and some others found in the data | |
4584 | # of Gutenprint, all sizes of HPIJS, and some others found in the data | |
3968 | 4585 | # of printer drivers. |
3969 | 4586 | |
3970 | 4587 | sub getpapersize { |
4195 | 4812 | } |
4196 | 4813 | |
4197 | 4814 | # Get documentation for the printer/driver pair to print out. For |
4198 | # "Execution Details" section of driver web pages on linuxprinting.org | |
4815 | # "Execution Details" section of driver web pages on OpenPrinting | |
4199 | 4816 | |
4200 | 4817 | sub getexecdocs { |
4201 | 4818 | |
4438 | 5055 | (defined($dat->{'pjl'}))) { |
4439 | 5056 | my @pjltmp; |
4440 | 5057 | push(@pjltmp, |
4441 | "This driver produces a PJL header with PJL commands internally, so commands in a PJL header sent to the printer before the output of this driver would be ignored. Therefore there are no PJL options available when using this driver.<P>"); | |
5058 | "This driver produces a PJL header with PJL commands internally and it is incompatible with extra PJL options merged into that header. Therefore there are no PJL options available when using this driver.<P>"); | |
4442 | 5059 | push(@docs, "<B>PJL</B><P>"); |
4443 | 5060 | push(@docs, @pjltmp); |
4444 | 5061 | } |