Till Kamppeter [Wed, 10 Nov 2021 19:20:47 +0000 (20:20 +0100)]
driverless: Do not execute if NO_DRIVERLESS_PPDS env variable is set
If we have a Printer Application which wants to make available all the
CUPS drivers installed on the system (in the directories where CUPOS
would look for them), we have on many systems also the driverless
utility of cups-filters installed, linked into /usr/lib/cups/backend,
to discover driverless IPP printers, and in /usr/lib/cups/driver, to
auto-generate CUPS PPD files for them.
The Printer Application is supposed to make printers available which
use the installed drivers but does not need to make available
driverless IPP printers. Therefore we do not want that the Printer
Application executes the driverless utility to discover printers and
list possible PPD files for them. But we also do not want to remove
the driverless utility.
Therefore we add in this commit a facility to de-activate the
driverless utility by the presence of the NO_DRIVERLESS_PPDS
environment variable. If the variable is defined, the utility exits
right away when it gets called, not doing anything. So a Printer
Application looking for printers and PPD files by running CUPS
backends and dynamich PPD generator executables for CUPS in their
usual places in the file system can set the variable and a perhaps
installed driverless utility will simply do nothing and so the Printer
Application will not list all driverless IPP as supported with a
"driverless" driver choice.
The driverless utility is only thought out as a retro-fit of
driverless printers into classic printer setup tools (and as debugging
tool) but not for PPD-retro-fitting Printer Applications.
Till Kamppeter [Tue, 9 Nov 2021 23:35:20 +0000 (00:35 +0100)]
Build system: ENABLE_... conditionals in Makefile.am only for file inclusion
In makefile.am use "if ENABLE_..." conditionals only to decide which
files get included in general "make" and "make install" processes, not
for compilation rules. This way single filters can be built by "make
NAME" regardless whether appropriate "--enable-..." arguments got
supplied to "./configure".
Now we can do "make pstops" and make "make rastertopwg" without
appropriate arguments for "./configure".
Till Kamppeter [Mon, 8 Nov 2021 20:16:26 +0000 (21:16 +0100)]
Build system: Updated after addition of the universal() filter function
Now, with the cUPS filters all converted to filter functions the
filter executables which are installed into /usr/lib/cups/filter are
only small code stubs which convert the CUPS filter command line
arguments into the filter data and parameters for calling the filter
function and then calling the filter function itself.
With the addition of the universal() filter function, which
automatically converts any supported input format into any supported
output format by automatically creating an appropriate filter chain
there are two ways for interfacing the filter functions with CUPS now:
1. One individual executable for each filter functions: This makes
cups-filters behave as before. CUPS creates chains of the filters
needed for converting the job data to the required output format.
2. A single universal filter executable: This internally chains the
filter functions for getting the input data into the desired output
format. This is less resource-consuming as less external executables
have to be called by CUPS for processing each print job.
cups-filters can be built with either individual filter executables or
the universal filter executable, or also with both. This is controlled
by the "./configure" script with the "--enable-universal-cups-filter"
and "--enable-individual-cups-filters" command line arguments. Default
is to build only the universal filter executable. MIME conversion
rules are installed appropriate to the installed CUPS filter
executables.
Also done:
- Re-arranged the MIME conversion rules for using the classic,
individual CUPS filter executables and for using the universal
filter executable
- Require the QPDF version 10.3.2 and so removed the "./configure"
switch for QPDF not supporting PCLm
- Require CUPS 2.2.2 or newer and removed the "./configure" switch for
using urftopdf instead of Apple Raster support of libcups.
pranshukharkwal [Sun, 7 Nov 2021 17:24:54 +0000 (22:54 +0530)]
libcupsfilters, universal: Add a universal filter function to replace chains of individual filters
To execute a print job CUPS usually has to turn the input data format into PDF, ptocess the PDF with page management functions, like N-up, only even/odd pages, page selection, scaling, ..., and then turn the PDF into a data format understood by the printer. For this it calls a chain of several filters in most cases which causes an overhead of starting individual processes and data input/output.
To reduce this overhead we have here a single, universal filter function which calls a chain of one or more suitable individual filter functions using the filterChain() filter function. It take the input and output format MIME types as parameters and automatically determines a suitable combination of filters to do the desired conversion.
For use with CUPS, to have (except printer drivers) only one single filter for everything, we have also a filter executable as for the individual filters and a MIME conversion rules file to tell CUPS that it converts a wide range of input formats into a wide range of output formats. To not require n * m lines in the conversion rule file to support n input and m output formats, we use an auxiliary input MIME type to reduce the number of lines to n + m, and to allow easy addition and modification of formats as each format is only mentioned once in the file.
This universal filter function is the GSoC 2021 project of Pranshu Kharkwal (Pull Request #421, https://gist.github.com/pranshukharkwal/9413499a6744049ef549159948392023). Thanks a lot!
Till Kamppeter [Sat, 6 Nov 2021 16:18:24 +0000 (17:18 +0100)]
libcupsfilters: In ieee1284NormalizeMakeAndModel() remove "series" from model
We remove "series" from the model names when normalizing now, so we
also get a match if the printer list entry has "series" but the search
term not, or vice-versa (when both printer list enries and search
terms are normalized).
Till Kamppeter [Mon, 1 Nov 2021 22:25:52 +0000 (23:25 +0100)]
libcupsfilters: In ieee1284NormalizeMakeAndModel() also consider " - " as separator
Before, ieee1284NormalizeMakeAndModel() only considered ',', ';', and
'(' as separator between printer model name and extra info (driver,
version, language, ...). Now we also consider " - " (isolated dash) as
such a separator.
Till Kamppeter [Fri, 29 Oct 2021 13:03:02 +0000 (15:03 +0200)]
libcupsfilters: In bannertopdf() get printer name from filter data
In the bannertopdf() filter function get the print queue name from the
filter data and not from the PRINTER environment variable, as the
filter data is the standard source for this item in a filter function.
Till Kamppeter [Fri, 29 Oct 2021 09:04:22 +0000 (11:04 +0200)]
bannertopdf() templates: Adeed instructions to PDF templates
With the change on the bannertopdf() filter function of the previous
commit the template PDF files can get directly fed into bannertopdf()
and the instructions for adding printer- and job-specific text can be
embedded in the templates.
This commit adds the appropriate instructions to each template file,
to not break PDF integrity to the end. So one can even modify the
instructions without breaking the template itself.
If feeding banner instruction files into bannertopdf() as before, the
embedded instructions get ignored.
Also added files with only the instructions, the data/*-append.txt
files. They are not actually used but only FYI.
Till Kamppeter [Fri, 29 Oct 2021 07:50:15 +0000 (09:50 +0200)]
Improved bannertopdf() filter function
Main reason of the improvements is to make the bannertopdf() filter function
more suitable for Printer Applications, conserving its functionality for
CUPS.
Changes:
- Instead of a pair of an instruction file
(application/vnd.cups-pdf-banner) and a template PDF file we can
only use the template PDF file now, sending it as input file to the
filter function instead of the instruction file. The instruction
file content can be added to the PDF file as PDF comments,
preferrably at the end. If no instructions are added to the template
file, default instructions are used.
- Job-/Printer-related text added to a template file without PDF form
(according to "Show" instruction) is now cleaned up, not showing lines
at all for fields for which no content is supplied, instead of showing
"(null)" or nothing as content.
- Page dimensions are now also shown in centimeters and not only in
inches.
Till Kamppeter [Tue, 26 Oct 2021 17:02:59 +0000 (19:02 +0200)]
libppd: Merged libppdc into libppd, *.drv support for PPD collections
CUPS PPD compiler (ppdc) was mainly ported into cups-filters to get
driver information file (*.drv) support for PPD file collections, so
that it gets easier to retro-fit CUPS drivers into Printer
Applications if the drivers provide their PPD files as a driver
information file.
In a first approach the ppdc functionality simply got added by an
additional shared library (libppdc), but this would cause circular
dependencies between libppdc and libppd. Therefore we simply merge the
two into one library.
In addition, all PPD legacy support is in a single library now.
Also note that the ppdc functions are written in C++, so you need to
declare a program which uses them as C++ (give it a *.cxx or *.cpp and
not the simple *.c file name extension), even if the program itself is
written in simple C.
The functions for handling PPD collections nw also take into account
any driver information file (*.drv) in the directories supplied to
them, in addition to the already supported static PPD files, PPD file
tarballs, and PPD-generating executables, both for enumerating
available PPDs/drivers and for loading the actual PPD files.
Till Kamppeter [Mon, 25 Oct 2021 23:02:28 +0000 (01:02 +0200)]
Ported CUPS' PPD compiler into cups-filters
Together with PPD files the PPD compiler, which generates PPD files
from driver information files (*.drv) is deprecated in CUPS and will
get removed in CUPS 3.x.
CUPS 3.x and later (and also earlier CUPS versions when sandboxed,
like in a Snap) do not support classic CUPS drivers any more and need
Printer Applications (emulations of driverless IPP printers) for
non-driverless printers.
For retro-fitting classic CUPS drivers, consisting of PPD files, CUPS
filters, and CUPS backends, into Printer Applications without needing
to rewrite the driver (which can be old and the printer it supports
not at hand for testing) we wrap the driver into the Printer
Application without changing the driver itself (usually with the
pappl-retrofit library). Therefore we need to be able to handle PPD
files and especially also the driver information files (*.drv) which
some drivers use to generate their PPD files on-the-fly. Therefore we
conserve CUPS' PPD compiler here to be able to pre-build the PPDs (or
even also generate them on-the-fly) when retro-fitting the drivers
into Printer Applications.
In contrary to recent CUPS we provide the PPD compiler code as a
shared library (libppdc), so that other projects, like pappl-retrofit
can use it.
Note that this is only for retro-fitting existing printer drivers.
This should not motivate you to create new printer drivers using PPD
files or driver information files. Therefore we will also not add new
features to this code or to the corresponding file formats.
Till Kamppeter [Sun, 24 Oct 2021 09:07:28 +0000 (11:07 +0200)]
libcupsfilters: In texttopdf() did redirrection of stdout to outputfd
The texttopdf() filter function was missing the redirection of stdout
to the output file descriptor of the function call, outputfd.
On error of parsing the charset configuration file and loading the
fonts exit(1) was called which would kill the caller in a filter
function. This is corrected now, too.
The files filter/pdfutils.c and filter/pdfutils.h got moved into
libcupsfilters, for the texttopdf() filter function. But they did not
get removed from the filter/ directory and the build rules for
filter/test_pdf[12].c not updated to use the pdfutils files of the
library now.
Till Kamppeter [Fri, 22 Oct 2021 19:20:52 +0000 (21:20 +0200)]
libcupsfilters: In ieee1284NormalizeMakeAndModel() fix parsing device IDs
Some IEEE-1284 device IDs have spaces before and after the
manufacturer and model names. These need to be removed when generating
make-and-model strings for display, sorting, ... THis especially leads
to duplicate manufacturer names (extra mention of manufacturer in
model name) not being recognized and removed.
Till Kamppeter [Wed, 20 Oct 2021 14:51:15 +0000 (16:51 +0200)]
libcupsfilters: In pwgtoraster() with PPD do not modify header via IPP options
In the pwgtoraster() filter function, if we have a PPD file, we do not
call cupsRasterParseIPPOptions() as it sets the Raster header entries
solely by the names and choice names of the IPP attributes and command
line options, regardless of what the PPD supports. This broke some
jobs.
If we have a PPD, we need to convert IPP attributes into proper PPD
options before calling the filter functions (what is done by
libpappl-retrofit for example).
Till Kamppeter [Tue, 19 Oct 2021 10:14:11 +0000 (12:14 +0200)]
libppd: Added "FXOutputMode" of Fuji Xerox to auto-mapping
Fuji Xerox has several high-end printers which take jobs in PDF from
the pre-driverless-IPP era, for which they had the "fxlinuxprint"
driver. The PPD contains an "FXOutputMode" option with an odd
"Quality2" choice for high quality. Now it is solved by an explicit
treatment of this option.
Till Kamppeter [Mon, 18 Oct 2021 21:38:37 +0000 (23:38 +0200)]
libcupsfilters: Let filterExternalCUPS() return 1 if filter gets a signal
If the CUPS filter or backend called by the filterExternalCUPS()
filter function stops on a signal (like for example signal 11,
segmentation fault) filterExternalCUPS() returns 1 now and not a value
> 256. Otherwise filterChain() will not see the failure (exit() only
passes on the last byte of its argument as exit code) and returns 0
for success, making a job with a crashed filter appear as succeeded.
Till Kamppeter [Mon, 18 Oct 2021 20:33:46 +0000 (22:33 +0200)]
libcupsfilters: Allow filter without path in filterExternalCUPS()
The filterExternalCUPS() function now also works if the filter (or
backend) is specified without absolute path. In this case the
CUPS_SERVERBIN environment variable (does not matter whether it was
set in the actual environment or in the parameters of
filterExternalCUPS()) is used to locate the filter or backend, using
the /filter or /backend subdirectory of the directory specified by
CUPS_SERVERBIN.
In addition, this directory is also added to the beginning of PATH, as
CUPS does, so that filters/backends can find auxiliary programs (or
other filters if they are a wrapper) in the same directory where they
themselves are located.
Till Kamppeter [Mon, 18 Oct 2021 20:26:51 +0000 (22:26 +0200)]
Sample PPDs: Useful "*Product:" name in the PCL-XL PPDs
The PCL-XL PPDs, pxlmono.ppd and pxlcolor.ppd, the product name was
"GPL Ghostscript" which could make make printer setup tools list these
PPDs with this name which does not say anything about the PPD, and
even consider the second one as duplicate of the first one (both
libpappl-retrofit and pyppd did this before they received their most
recent improvements).
Now they names are more useful and the PPDs always listed correctly.
Till Kamppeter [Tue, 12 Oct 2021 11:33:26 +0000 (13:33 +0200)]
libcupsfilters: Make cupsRasterParseIPPOptions() work correctly with PPDs
cupsRasterParseIPPOptions() interprets job options/IPP attributes and
their settings just bei their names. This works well when the
destination printer is not described by a PPD file.
If there is a PPD file, their can be weird option and choice names
which do not tell what they are good for, giving wrong
impressions. Only the PostScript or PJL code assigned to the choices
in the PPD file tells what they actually are supposed to do.
A good example for that is the "Resolution" option of Gutenprint. As
the developers of Gutenprint do not want to solely and directly set
the print resolution with this option (as was Adobe's idea for it),
and instead, do more things with it, as having an "Automatic" choice
or variants of the same resolution (for example different dithering
algorithms), but PPD standards require the choices to be "XXXxYYYdpi"
without exceptions, they come with names like "601x600dpi" for the
variants and the PPD's embedded PostScript code contains the actual
resolution.
To avoid that cupsRasterParseIPPOptions() mis-interprets such weird
PPD options, we check whether we are using a PPD (fortunately, we
receive the complete filter data now, in the era of filter functions)
and if so we refrain from parsing options which are in the PPD. Only
if set_defaults = 1 is set, we use them but via a call of
ppdRasterInterpretPPD() and not interpreting them by ourselves
option/choice-name-only.
Now the Gutenprint Printer Application works again.
Till Kamppeter [Tue, 12 Oct 2021 09:23:02 +0000 (11:23 +0200)]
libcupsfilters: Clean up "Kodak" manufacturer name
Some Kodak printers/PPD files report "Eastman Kodak Company", others
simply "Kodak" as manufacturer name. Let the
ieee1284NormalizeMakeAndModel() function use simply "Kodak" here.
Till Kamppeter [Wed, 22 Sep 2021 10:24:24 +0000 (12:24 +0200)]
libppd: Improved caching of PPD's page sizes and custom page size limits
1. If an PPD page size has non-standard dimensions, pwgMediaForSize()
returns "custom_WIDTHxHEIGHTuu_WIDTHxHEIGHTuu" and not NULL, while we
assume that we would get NULL in such a case. So consider "custom_..."
PWG page size names also as a PWG size not having been found. This
gives PWG page size nmaes of "pp_lowerppd_WIDTHxHEIGHTuu" style, much
more useful and the page size not being skipped by PAPPL's web
interface.
2. If the PPD defines a too high demension (something like ~30 m is
enough) for the maximum allowed custom page size, the generated PWG
page size name ("custom_max_WIDTHxHEIGHTuu") contains negative numbers
due to an integer overflow. If this happens, we sanitize the string
now replacing these negative numbers by a high integer value (10000
inches or 100000 mm). This PWG size name is used by PAPPL's web
interface to know about the allowed dimensions for a custom page
size. With a negative value the web interface inserts 0, making the
max dimension smaller than the min and with this clicks on the "Save
Changes" button on the "Media" web interface page of PAPPL are
silently ignored.
Add missing line continuation character in libcupsfilters-la_LIBADD
stanza. This fixes "make[2]: lm: No such file or directory" errors while
building.
Move fontembed library before cupsfilters library, this fixes
"/usr/bin/ld: cannot find -lfontembed" errors during install. This may
just be a workaround for dependency resolving issues elsewhere.
Till Kamppeter [Sun, 19 Sep 2021 21:39:27 +0000 (23:39 +0200)]
libppd: Fixed PPD URIs when generating dynamic PPDs
The PPD URIs of the PPD collection handling of libppd are not
identical with the PPD URIs of CUPS and so not identical with the PPD
URIs used by the dynamic PPD generator executables (the ones which are
in /usr/lib/cups/driver/ for CUPS). The difference is in the scheme,
the part before the colon. The schemes for the dynamic PPD generator
did not get extracted correctly. Most dynamic PPD generatores do not
use the scheme internally and therefore work also with the scheme
corrupted, like pyppd or HPLIP, but Gutenprint does not, as it checks
the version by the scheme,
This commit fixes the extraction of the scheme and so all dynamic PPD
generators should work now.
Till Kamppeter [Sun, 19 Sep 2021 17:32:33 +0000 (19:32 +0200)]
libcupsfilters: Let colord_get_profile_for_device_id() not return empty file name
If the function colord_get_profile_for_device_id() returns an empty
file name, the color generates an error message in the CUPS
error_log. Some print dialogs report every log message of level error
to the user even if the job got correctly printed.
Till Kamppeter [Wed, 15 Sep 2021 18:51:02 +0000 (20:51 +0200)]
libppd: In IPP-attr-to-PPD-option auto mapper consider "ColorMode" also with prefix
This way we also cover "cupsColorMode" for example which appears in
auto-generated PPDs for driverless IPP printers (in case we cannot
print directly to the printer but only have access via a CUPS queue).
Till Kamppeter [Fri, 3 Sep 2021 21:21:26 +0000 (23:21 +0200)]
libcupsfilters: In ghostscript() pass on LD_LIBRARY_PATH to Ghostscript
In unusual environments (are they still actually unusual?) like Snaps
or other sandboxed packages libraries are not always in standard
locations and the LD_LIBRARY_PATH environment variable tells about the
extra locations then. So when we continue to block out the caller's
environment variables when we call Ghostscript, we have to pass on at
least LD_LIBRARY_PATH.