Als Druckerfilter wird der lpdfilter (lpdfilter) verwendet. Es folgt eine detaillierte Beschreibung des Ablauf eines Druckauftrages. Für eine exakte Analyse des Druckerfilters sind die Skripte des Druckerfilters (insbesondere /usr/lib/lpdfilter/bin/if) durchzusehen, ggf. ist gemäß dem Abschnitt 6.5.3. “Fehlersuche beim lpdfilter” vorzugehen.
Der Druckerfilter (/usr/lib/lpdfilter/bin/if) bestimmt die an ihn direkt vom Druckerspooler übergebenen Optionen bzw. liest er sie aus dem control file des Druckjobs und passend zur verwendeten Warteschlange aus den Dateien /etc/printcap und /etc/lpdfilter/warteschlange/conf (hier ist warteschlange durch den tatsächlichen Namen der Warteschlange zu ersetzen).
Wenn es eine ascii-Warteschlange ist, wird der Druckerfilter gezwungen, die zu druckenden Daten wie ASCII-Text zu behandeln. Wenn es keine ascii-Warteschlange ist, versucht der Druckerfilter den Typ der zu druckenden Daten automatisch zu bestimmen. Der Typ der zu druckenden Daten wird durch das Skript /usr/lib/lpdfilter/bin/guess bestimmt, das das Kommando file auf die zu druckenden Daten angewendet und mit dessen Ausgabe wird gemäß der Angaben in der Datei /etc/lpdfilter/types der Typ der zu druckenden Daten festgesetzt.
Je nach Typ der zu druckenden Daten und nach Art der Warteschlange erfolgt die weitere Umwandlung in druckerspezifische Daten:
Wenn es eine raw-Warteschlange ist, werden die zu druckenden Daten normalerweise direkt an den Drucker (oder an eine andere Warteschlange) weitergeleitet, es kann aber auch gemäß der Einstellungen in /etc/lpdfilter/warteschlange/conf eine einfache Umkodierung mit recode erfolgen. Für eine absolute raw-Warteschlange – also ganz ohne den lpdfilter – ist die Zeile :if=/usr/lib/lpdfilter/bin/if:\ in /etc/printcap bei der entsprechenden Warteschlange zu entfernen.
Wenn es keine raw-Warteschlange ist:
Wenn die Daten nicht PostScript sind, werden sie zuerst durch einen Aufruf von /usr/lib/lpdfilter/filter/typ2ps nach PostScript umgewandelt (hier ist typ durch den tatsächlich bestimmten Typ der zu druckenden Daten zu ersetzen). Insbesondere ASCII-Text wird gemäß /usr/lib/lpdfilter/filter/ascii2ps mit dem Programm a2ps gemäß der für die Warteschlange konfigurierten länderspezifischen Kodierung passend in PostScript umgewandelt, so dass länderspezifische Sonderzeichen auch in einfachem Text korrekt druckbar sind; siehe dazu die Manualpage von a2ps.
Die PostScript-Daten können ggf. nochmals umformatiert werden, sofern ein passendes Skript unter /etc/lpdfilter/warteschlange/pre (hier ist warteschlange durch den tatsächlichen Namen der Warteschlange zu ersetzen) existiert.
Die PostScript-Daten werden ggf. in eine andere Druckersprache umgewandelt.
Wenn ein PostScript-Drucker angeschlossen ist, werden die PostScript-Daten direkt an den Drucker (oder an eine andere Warteschlange) geschickt. Ggf. werden aber zusätzlich die Bash-Funktionen duplex und tray, die in /usr/lib/lpdfilter/global/functions definiert sind, aufgerufen, um Duplexdruck oder Papierschachtauswahl über PostScript-Kommandos zu ermöglichen – vorausgesetzt der PostScript-Drucker kann diese Kommandos entsprechend verarbeiten.
Wenn kein PostScript-Drucker angeschlossen ist, wird Ghostscript mit einem zur Druckersprache des jeweiligen Druckermodells passenden Ghostscript-Treiber verwendet, um die druckerspezifischen Daten zu erzeugen, die dann an den Drucker (oder an eine andere Warteschlange) geschickt werden.
Die Parameter für den Ghostscript-Aufruf sind entweder in der /etc/printcap direkt in der cm-Zeile oder in der Datei /etc/lpdfilter/warteschlange/upp (hier ist warteschlange durch den tatsächlichen Namen der Warteschlange zu ersetzen) gespeichert.
Die Ausgabe von Ghostscript kann ggf. nochmals umformatiert werden, sofern ein passendes Skript unter /etc/lpdfilter/warteschlange/post (hier ist warteschlange durch den tatsächlichen Namen der Warteschlange zu ersetzen) existiert.
Die druckerspezifischen Daten werden an den Drucker (oder an eine andere Warteschlange) geschickt. Dabei können vor und nach den druckerspezifischen Daten noch druckerspezifische Steuersequenzen geschickt werden, wenn diese in /etc/lpdfilter/warteschlange/conf eingetragen wurden.
Normalerweise wird das Drucksystem mit YaST konfiguriert, wie es im Abschnitt 5.3. “Drucker einrichten mit YaST” beschrieben ist, insbesondere wird dabei auch der lpdfilter konfiguriert.
Wird der lpdfilter mit YaST konfiguriert, so läuft die Filterung beim LPRng/lpdfilter-Drucksystem wie folgt ablaufen:
zu druckende Daten | v lpdfilter: nur noch Umwandlung nach PostScript | | |---- PPD-Datei passend zum Druckermodell | | (/etc/lpdfilter/warteschlange/ppd) v v foomatic-rip: Umwandlung in die Druckersprache mit Ghostscript | v Drucker
Für spezielle Einstellungen sind die Konfigurationsdateien des Druckerfilters manuell anzupassen. Jede Warteschlange hat ihre eigene separate Konfigurationsdatei /etc/lpdfilter/warteschlange/conf (hier ist warteschlange durch den tatsächlichen Namen der Warteschlange zu ersetzen), die auch Informationen zu jeder Option enthält.
Wenn die zu druckenden Daten nicht PostScript sind, werden sie standardmäßig durch einen Aufruf von /usr/lib/lpdfilter/filter/typ2ps nach PostScript umgewandelt (hier ist typ durch den Typ der zu druckenden Daten zu ersetzen).
Wenn unter /etc/lpdfilter/warteschlange/typ2ps ein passendes Skript abgelegt wird, wird dieses verwendet, um die Daten nach PostScript umzuwandeln. Dieses Skript bekommt die zu druckenden Daten über stdin und hat sie über stdout PostScript auszugeben.
Die PostScript-Daten können ggf. nochmals umformatiert werden, sofern ein passendes Skript unter /etc/lpdfilter/warteschlange/pre existiert. Auch eigene sog. PostScript-Preloads können hier mit einem passenden Skript hinzugeladen werden. Dieses Skript bekommt PostScript-Daten über stdin und hat sie über stdout PostScript auszugeben. Programme, um PostScript-Daten umzuformatieren, finden sich im psutils. Insbesondere das Programm pstops ermöglicht weitreichende Umformatierungen; siehe dazu die Manualpage von pstops.
Spezielle Ghostscript Parameter: Bei der Konfiguration mit YaST2 werden die Parameter für den Ghostscript-Aufruf in der Datei /etc/lpdfilter/warteschlange/upp (hier ist warteschlange durch den tatsächlichen Namen der Warteschlange zu ersetzen) gespeichert und in dieser Datei können spezielle Ghostscript Parameter manuell eingetragen werden. Zu Ghostscript Parametern siehe den Abschnitt 6.6. “Etwas über Ghostscript”.
Auch die Ausgabe von Ghostscript kann ggf. nochmals umformatiert werden, sofern ein passendes Skript unter /etc/lpdfilter/warteschlange/post (hier ist warteschlange durch den tatsächlichen Namen der Warteschlange zu ersetzen) existiert. Dieses Skript bekommt die Ausgabe von Ghostscript über stdin und es hat druckerspezifische Daten über stdout auszugeben.
Angenommen es gibt eine Warteschlange test bei der ASCII-Text mit vorangestellten Zeilennummern gedruckt werden soll und bei jeglicher Druckausgabe sollen immer zwei Seiten verkleinert auf einem Blatt gedruckt werden, dann könnten die folgenden Skripten /etc/lpdfilter/test/ascii2ps und /etc/lpdfilter/test/pre erstellt werden:
Beispiel 6.3. /etc/lpdfilter/test/ascii2ps: ASCII nach PostScript Umwandlung
#!/bin/bash cat -n - | a2ps -1 --stdin=' ' -o -
Beispiel 6.4. /etc/lpdfilter/test/pre: PostScript Umformatierung
#!/bin/bash pstops -q '2:0L@0.6(20cm,2cm)+1L@0.6(20cm,15cm)'
Diese Skripte müssen für jeden Benutzer ausführbar sein, was mit chmod erreicht werden kann:
chmod -v a+rx /etc/lpdfilter/test/ascii2ps chmod -v a+rx /etc/lpdfilter/test/pre
Der pstops-Aufruf funktioniert nur für PostScript-Dateien, die so erstellt wurden, dass eine Umformatierung möglich ist (was normalerweise der Fall sein sollte).
PostScript-Preloads sind kleine Dateien, die spezielle PostScript-Befehle enthalten und vor die eigentlichen Druckdaten vorgeschaltet werden, um einen PostScript-Drucker oder auch Ghostscript mit diesen speziellen Befehlen passend zu initialisieren. Üblicherweise werden Preloads verwendet, um bei einem PostScript-Drucker Duplex-Druck oder spezielle Papierschächte zu aktivieren oder um Randeinstellungen und Gammakorrektur passend zu setzten.
Voraussetzung ist, dass der PostScript-Drucker bzw. Ghostscript die unten angegebenen speziellen Befehle auch entsprechend verarbeiten kann (Ghostscript reagiert nicht auf Befehle für Duplex-Druck oder Papierschächte).
Angenommen, die betreffende Warteschlange heißt test.
Um Duplex-Druck ein- und auszuschalten, können Sie folgende Dateien /etc/lpdfilter/test/duplexon.ps und /etc/lpdfilter/test/duplexoff.ps erstellen:
Beispiel 6.5. /etc/lpdfilter/test/duplexon.ps: Duplex-Druck einschalten
%!PS
statusdict /setduplexmode known
{statusdict begin true setduplexmode end} if {} pop
Beispiel 6.6. /etc/lpdfilter/test/duplexoff.ps: Duplex-Druck ausschalten
%!PS
statusdict /setduplexmode known
{statusdict begin false setduplexmode end} if {} pop
Um die Rückseite bei Duplex-Druck um 180 Grad zu drehen, kann der folgedes PostScript-Code verwendet werden:
%!PS
statusdict /setduplexmode known
{statusdict begin true setduplexmode end} if {} pop
statusdict /settumble known
{statusdict begin true settumble end} if {} pop
Um den Standardpapierschacht mit der Nummer 0 oder den Papierschacht zum Beispiel mit der Nummer 2 zu aktivieren, erstellen Sie die Dateien /etc/lpdfilter/test/tray0.ps und /etc/lpdfilter/test/tray2.ps:
Beispiel 6.7. /etc/lpdfilter/test/tray0.ps: Papierschacht 0 aktivieren
%!PS
statusdict /setpapertray known
{statusdict begin 0 setpapertray end} if {} pop
Beispiel 6.8. /etc/lpdfilter/test/tray2.ps: Papierschacht 2 aktivieren
%!PS
statusdict /setpapertray known
{statusdict begin 2 setpapertray end} if {} pop
Um Randeinstellungen zu verändern, erstellen Sie folgende Datei /etc/lpdfilter/test/margin.ps:
Beispiel 6.9. /etc/lpdfilter/test/margin.ps: Randeinstellungen
%!PS << /.HWMargins [left bottom right top] /PageSize [width height] /Margins [left-offset top-offset] >> setpagedevice
Die Randeinstellungen left, bottom, right und top und die Papiergröße width und height sind in sog. Punkten anzugeben wobei ein Punkt die Größe 1/72 Zoll (also ca. 0.35 mm) hat. Die Rand-Offsets left-offset und top-offset dagegen sind in Rasterpunkten anzugeben und somit von der jeweiligen Auflösung abhängig.
Soll nur die Position des Ausdrucks auf dem Papier verschoben werden, genügt folgende Datei /etc/lpdfilter/test/offset.ps
Beispiel 6.10. /etc/lpdfilter/test/offset.ps: Position des Ausdrucks
%!PS << /Margins [left-offset top-offset] >> setpagedevice
Um die Helligkeitsverteilung der Farben zu verändern, erstellen Sie die Dateien /etc/lpdfilter/test/cmyk.ps und /etc/lpdfilter/test/rgb.ps:
Beispiel 6.11. /etc/lpdfilter/test/cmyk.ps: CMYK Gammakorrektur
%!PS
{cyan exp} {magenta exp} {yellow exp} {black exp}
setcolortransfer
Beispiel 6.12. /etc/lpdfilter/test/rgb.ps: RGB Gammakorrektur
%!PS
{red exp} {green exp} {blue exp} currenttransfer
setcolortransfer
Das Farbmodell (CMYK oder RGB) muss zu Ihrem Drucker passen. Die Werte, die für cyan, magenta, yellow, black, red, green und blue einzusetzen sind, müssen Sie durch Tests ermitteln. Normalerweise sind Werte zwischen 0.001 und 9.999 sinnvoll.
Die Wirkung der obigen Dateien testen Sie unter der grafischen Oberfläche am Bildschirm mit folgenden Befehlen: Ohne Gammakorrektur:
gs -r60 \ /usr/share/doc/packages/ghostscript/examples/colorcir.ps
Mit Gammakorrektur eines dieser Beispiele:
gs -r60 /etc/lpdfilter/test/cmyk.ps \
/usr/share/doc/packages/ghostscript/examples/colorcir.ps
gs -r60 /etc/lpdfilter/test/rgb.ps \
/usr/share/doc/packages/ghostscript/examples/colorcir.ps
Mit Strg + c wieder beenden.
Um den Drucker in den Grundzustand zurückzusetzen, erstellen Sie die Datei /etc/lpdfilter/test/reset.ps:
Zur Aktivierung einer PostScript-Preload-Datei kann folgendes Skript /etc/lpdfilter/test/pre erstellt werden:
Beispiel 6.14. /etc/lpdfilter/test/pre: PostScript-Preload laden
#!/bin/bash cat /etc/lpdfilter/test/preload.ps -
Dabei ist für preload.ps der passende Preload-Dateiname einzusetzen und außerdem muss das Skript für jeden Benutzer ausführbar und die Preload-Datei für jeden Benutzer lesbar sein, was mit chmod zu erreichen ist:
chmod -v a+rx /etc/lpdfilter/test/pre chmod -v a+r /etc/lpdfilter/test/preload.ps
Derselbe Mechanismus kann auch verwendet werden, um eine PostScript-Datei nicht nur vor, sondern auch nach den eigentlichen PostScript-Druckdaten an den Drucker zu schicken. Beispielsweise um den Drucker am Ende eines Druckjobs wieder in den Grundzustand zurückzusetzen, kann das Skript /etc/lpdfilter/test/pre folgendermaßen ergänzt werden:
Beispiel 6.15. /etc/lpdfilter/test/pre: PostScript-Preload und PostScript-Reset
#!/bin/bash cat /etc/lpdfilter/test/preload.ps - /etc/lpdfilter/test/reset.ps
Es soll eine Warteschlange gdi für einen GDI-Drucker eingerichtet werden. Derartige Drucker können zumeist nicht unter Linux verwendet werden; siehe oben den Abschnitt 5.2.3. “Zur GDI-Drucker Problematik”. Allerdings gibt es für manche GDI-Drucker spezielle Treiberprogramme, die normalerweise als Zusatz nach Ghostscript verwendet werden, indem das Treiberprogramm spezielle Ausgaben von Ghostscript in das druckerspezifische Format konvertiert. Solche Treiberprogramme ermöglichen aber oft nur eingeschränkten Ausdruck – zum Beispiel nur Schwarzweißdruck. Ghostscript und Treiberprogramm arbeiten dann wie folgt zusammen (vgl. unten den Abschnitt 6.6. “Etwas über Ghostscript”.)
Die PostScript-Daten werden von Ghostscript in ein Raster einzelner Bildpunkte aufgelöst und die Rasterdaten durch einen zum nachgeschalteten Treiberprogramm passenden Ghostscript-Treiber in geeignetem Format und in geeigneter Auflösung ausgegeben.
Die Rasterdaten werden durch das Treiberprogramm in das druckerspezifische Format konvertiert.
Es wird im Folgenden vorausgesetzt, dass ein zur vorliegenden Version von SUSE LINUX passendes Treiberprogramm für den Drucker vorhanden ist bzw. aus dem Internet heruntergeladen werden kann, dass dieses Treiberprogramm in obiger Weise arbeitet und dass Sie ggf. im Umgang mit Unix-Quellen (zum Beispiel mit .zip- oder .tar.gz-Archiven oder .rpm-Paketen) vertraut sind.
Nach dem Entpacken eines solchen Archivs gibt es normalerweise aktuelle Installationshinweise in Dateien namens README oder INSTALL oder in einem Unterverzeichnis namens doc. Bei .tar.gz-Archiven ist das eigentliche Treiberprogramm in der Regel zu compilieren und zu installieren.
Im Folgenden wird beispielsweise angenommen:
Das Treiberprogramm ist /usr/local/bin/printerdriver.
Als Ghostscript-Treiber wird pbmraw mit einer Auflösung von 600 dpi benötigt.
Der Drucker ist an der ersten parallelen Schnittstelle /dev/lp0 angeschlossen.
Welcher Ghostscript-Treiber und welche Auflösung tatsächlich zu nehmen ist, muss in der Dokumentation zum Treiberprogramm angegeben sein.
Zuerst wird die gdi-Warteschlange mit lprsetup (als Benutzer root) angelegt:
lprsetup -add gdi -lprng -device /dev/lp0 \ -driver pbmraw -dpi 600 -size a4dj -auto -sf
Dann ist folgendes Skript /etc/lpdfilter/gdi/post zu erstellen:
#!/bin/bash /usr/local/bin/printerdriver <treiberspezifische_parameter>
Gegebenenfalls sind treiberspezifische_parameter passend einzutragen. Welche treiberspezifischen Parameter tatsächlich zu nehmen sind, muss in der Dokumentation zum Treiberprogramm angegeben sein. Das Skript muss für jeden Benutzer ausführbar gemacht und dann der Druckerspooler neu gestartet werden:
chmod -v a+rx /etc/lpdfilter/gdi/post rclpd stop rclpd start
Nun kann jeder Benutzer so drucken:
lpr -Pgdi <datei>
Der passende Debug-Level wird aktiviert, indem das Kommentarzeichen # vor der entsprechenden Zeile im Haupt-Script /usr/lib/lpdfilter/bin/if des Druckerfilters entfernt wird.
Beispiel 6.16. /usr/lib/lpdfilter/bin/if: Debug-Level
# DEBUG="off" # DEBUG="low" # DEBUG="medium" # DEBUG="high"
Bei DEBUG="low" werden nur die stderr-Ausgaben von /usr/lib/lpdfilter/bin/if in einer Datei /tmp/lpdfilter.if-$$.XXXXXX (hierbei wird $$ durch die Prozessnummer und XXXXXX durch eine zufällige aber eindeutige Zeichenkombination ersetzt) gespeichert.
Bei DEBUG="medium" werden zusätzlich die stderr-Ausgaben der Skripte unter /usr/lib/lpdfilter/filter/, die von /usr/lib/lpdfilter/bin/if aufgerufen werden, in Dateien der Form /tmp/lpdfilter.name-$$.XXXXXX (hierbei wird name durch den Namen des aufgerufenen Skripts und $$.XXXXXX analog zu oben ersetzt) gespeichert.
Bei DEBUG="high" wird zusätzlich die Ausgabe nicht an den Drucker geschickt, sondern in einer Datei der Form /tmp/lpdfilter.out-$$.XXXXXX (hierbei wird $$.XXXXXX analog zu oben ersetzt) gespeichert.
Um nicht die Übersicht zu verlieren, sollten diese Dateien vor jedem neuen Test mit rm -v /tmp/lpdfilter* gelöscht werden.