merged grml-quickconfig nonblocking branch
[grml-scripts.git] / usr_sbin / alignmargins
1 #! /usr/bin/perl
2 # Filename:      alignmargins
3 # Purpose:       adjust the margins and the position of the printed contents on the paper
4 # Authors:       (C) 2001 by Till Kamppeter
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       Free software under the terms of the GNU General Public License (GPL)
7 # Latest change: Son Mär 18 19:31:15 CET 2007 [mika]
8 ################################################################################
9 # Downloaded from http://www.linuxprinting.org/download/printing/alignmargins
10
11 $0 =~ m!^(.*)/[^/]+$!;
12 my $programpath = $1;
13 my $printcommand = '/usr/bin/lpr -P ';
14 my $egrep = '/bin/egrep';
15 my $cat = '/bin/cat';
16 my $cut = '/usr/bin/cut';
17 my $head = '/usr/bin/head';
18 my $tail = '/usr/bin/tail';
19 my $wc = '/usr/bin/wc';
20 my $adjustmentpagename = 'align.ps';
21 my $adjustmentpagepath = ($programpath ? "${programpath}:" : "") . '.:~:/usr/share/grml-scripts:/usr/share/alignmargins:/usr/local/share/alignmargins:/usr/share:/usr/local/share:/usr/share/printer-testpages:/usr/local/share/printer-testpages:/usr/share/ghostscript/*/lib:/usr/local/share/ghostscript/*/lib';
22 my $ppddir = '/etc/cups/ppd';
23 my $printerconffile = '/etc/cups/printers.conf';
24
25 # Find "ælign.ps"
26
27 my $adjustmentpage;
28 for $path (split(":", $adjustmentpagepath)) {
29     if (-r "$path/$adjustmentpagename") {
30         $adjustmentpage = "$path/$adjustmentpagename";
31         last;
32     }
33 }
34
35 # Are we running as root?
36
37 if (!(-w $printerconffile)) {die "\"alignmargins\" must be run logged in as \"root\"!";}
38
39 # Check whether there are local printer queues 
40
41 open NUMBEROFQUEUES, "$cat $printerconffile | $egrep '<Printer|<DefaultPrinter' | $wc -l |" or die "Cannot read local printer configuration!";
42  
43 my $nqueues = <NUMBEROFQUEUES>;
44 close NUMBEROFQUEUES;
45
46 # Ask the user which printer he wants to align
47
48 print "\n";
49 print "CUPS printer margin and offset alignment\n";
50 print "----------------------------------------\n";
51 print "\n";
52 print "(C) 2001 by Till Kamppeter\n";
53 print "Free software under the terms of the GNU General Public License (GPL)\n";
54 my $queue = "";
55
56 do {
57   print "\n";
58   print "With this program you can adjust the margins and the position of the\n";
59   print "printed contents on the paper. This way you get well-centered printouts and\n";
60   print "you can make use of the whole imageable area of your printer, The driver\n";
61   print "settings are overridden when this adjustment is used.\n";
62   print "\n";
63   print "This is especially important when your printer is used with a driver for\n";
64   print "another printer to which yours is compatible (for example many laser\n";
65   print "printers are compatible to the HP LaserJet printers). Your printer prints\n";
66   print "with this driver, but the non-printable margins are usually different or the\n";
67   print "contents is even not centered. With this program you can fix these problems\n";
68   print "\n";
69   print "The program can only be applied to local printer queues. The following\n";
70   print "queues are available:\n";
71   print "\n";
72
73   system "$cat $printerconffile | $egrep '<Printer|<DefaultPrinter' | $cut -d ' ' -f 2 | $cut -d '>' -f 1 | $cat -n";
74
75   print "\n";
76   print "Please enter the number of the desired printer and make sure that it is\n";
77   print "connected to your computer and turned on.\n";
78   print "\n";
79
80   print "Number: ";
81   my $input = <STDIN>;
82
83   if ( $input =~ m/^\s*(\d+)\D*/ ) {
84     my $number = $1;
85     if (($number > 0) && ($number <= $nqueues)) {
86       open QUEUE, "$cat $printerconffile | $egrep '<Printer|<DefaultPrinter' | $cut -d ' ' -f 2 | $cut -d '>' -f 1| $head -$number | $tail -1 |";
87       if (!$?) {
88         $queue = <QUEUE>; 
89         close QUEUE;
90       }
91     }
92   } else {
93     print "\nWrong input, try again!\n";
94   }
95 } until ($queue ne "");
96
97 chomp $queue;
98
99 print "\n";
100 print "Printing margin/offset adjustment page ...\n";
101 print "\n";
102
103 # The "%!" which is needed in a file to be recognized as a PostScript file
104 # is missing in the adjustment page, therefore it is preceeded to the file
105 # here.
106 if (system "(echo %!; $cat $adjustmentpage) | $printcommand$queue") {
107 die "Could not print the adjustment page.";
108 }
109
110 print "Please read the instructions on the margin adjustment page and determine the\n";
111 print "six numbers mentioned there. If you measure in cm and not in inches, devide\n";
112 print "the measured quantities by 2.54 before you insert them into the equations\n";
113 print "shown on the page. You do not need to create any file with PostScript\n";
114 print "commands, this program will insert your settings into your printer's\n";
115 print "configuration.\n";
116 print "\n";
117 print "If the adjustment page did not come out of your printer, this method cannot\n";
118 print "be applied, press Ctrl + C to stop this program. This can especially happen\n";
119 print "with very old PostScript printers.\n";
120 print "\n";
121 print "Note also that this adjustment does not necessarily work with every driver.\n";
122 print "The concept is taken from GhostScript and the implementation of this program\n";
123 print "is not much tested yet.\n";
124 print "\n";
125
126 print "Please enter your results now:\n";
127 print "\n";
128
129 my $ml = 9999999.;
130 my $mb = 9999999.;
131 my $mr = 9999999.;
132 my $mt = 9999999.;
133 my $x = 9999999.;
134 my $y = 9999999.;
135
136 do {
137   print "ml: ";
138   my $input = <STDIN>;
139
140   if ( $input =~ m/^\s*([+-]?[\d\.]+)\D*/ ) {
141     my $number = $1;
142     if (($number >= -100000) && ($number <= 100000)) {
143       $ml = $number * 1.;
144     }
145   } else {
146     print "Wrong input, try again!\n";
147   }
148 } until ($ml != 9999999.);
149
150 do {
151   print "mb: ";
152   my $input = <STDIN>;
153
154   if ( $input =~ m/^\s*([+-]?[\d\.]+)\D*/ ) {
155     my $number = $1;
156     if (($number >= -100000) && ($number <= 100000)) {
157       $mb = $number * 1.;
158     }
159   } else {
160     print "Wrong input, try again!\n";
161   }
162 } until ($mb != 9999999.);
163
164 do {
165   print "mr: ";
166   my $input = <STDIN>;
167
168   if ( $input =~ m/^\s*([+-]?[\d\.]+)\D*/ ) {
169     my $number = $1;
170     if (($number >= -100000) && ($number <= 100000)) {
171       $mr = $number * 1.;
172     }
173   } else {
174     print "Wrong input, try again!\n";
175   }
176 } until ($mr != 9999999.);
177
178 do {
179   print "mt: ";
180   my $input = <STDIN>;
181
182   if ( $input =~ m/^\s*([+-]?[\d\.]+)\D*/ ) {
183     my $number = $1;
184     if (($number >= -100000) && ($number <= 100000)) {
185       $mt = $number * 1.;
186     }
187   } else {
188     print "Wrong input, try again!\n";
189   }
190 } until ($mt != 9999999.);
191
192 do {
193   print "x: ";
194   my $input = <STDIN>;
195
196   if ( $input =~ m/^\s*([+-]?[\d\.]+)\D*/ ) {
197     my $number = $1;
198     if (($number >= -100000) && ($number <= 100000)) {
199       $x = $number * 1.;
200     }
201   } else {
202     print "Wrong input, try again!\n";
203   }
204 } until ($x != 9999999.);
205
206 do {
207   print "y: ";
208   my $input = <STDIN>;
209
210   if ( $input =~ m/^\s*([+-]?[\d\.]+)\D*/ ) {
211     my $number = $1;
212     if (($number >= -100000) && ($number <= 100000)) {
213       $y = $number * 1.;
214     }
215   } else {
216     print "Wrong input, try again!\n";
217   }
218 } until ($y != 9999999.);
219
220 my $ppdfilename = "$ppddir/$queue.ppd";
221 print "\n";
222 print "Saving your settings in $ppdfilename ...\n";
223 print "\n";
224
225 my @marginsoption = (
226   "*OpenUI *Margins/Page Margins/Offsets: PickOne\n",
227   "*DefaultMargins: Custom\n",
228   "*Margins Default/Driver Default: \"\"\n",
229   "*Margins Custom/Custom (set with 'alignmargins'): \"<</.HWMargins[$ml $mb $mr $mt] /Margins[$x $y]>>setpagedevice\"\n",
230   "*CloseUI: *Margins\n"
231 );
232
233 # Read PPD file of the chosen printer
234  
235 if (!(-f $ppdfilename)) {die "No PPD file $ppdfilename!"};
236 open PPDFILE, "$ppdfilename" or die "Can't open $ppdfilename!";
237 my @ppdfile = <PPDFILE>;
238 close PPDFILE;
239
240 # Remove an old margin adjustment option
241
242 ($_ =~ m!^\s*\*OpenUI\s*\*Margins/.*:! and $_="") foreach @ppdfile;
243 ($_ =~ m!^\s*\*DefaultMargins:! and $_="") foreach @ppdfile;
244 ($_ =~ m!^\s*\*Margins\s*.*/.*:! and $_="") foreach @ppdfile;
245 ($_ =~ m!^\s*\*CloseUI:\s*\*Margins! and $_="") foreach @ppdfile;
246
247 # Insert the new margin adjustment option
248
249 splice(@ppdfile,-1,0,@marginsoption);
250
251 # Write back PPD file
252
253 open PPDFILE, ">$ppdfilename" or die "Can't open $ppdfilename";
254 print PPDFILE @ppdfile;
255 close PPDFILE;
256
257 # Re-initialize CUPS (must be done after a "manual" change on the PPD file)
258
259 system("killall -HUP cupsd");
260
261 print "\n";
262 print "Done.\n";
263 print "\n";
264 print "Now your printer \"$queue\" will use the new margin and offset settings by\n";
265 print "default. You can turn them off by switching the option \"Page Margins/Offsets\"\n";
266 print "to \"Driver Default\" in kprinter, GTKlp, or XPP.\n";
267 print "\n";
268 print "On the command line (\"lpr\", \"lp\", \"lpoptions\", ...) use the option\n";
269 print "\"-o Margins=Default\" to turn off and \"-o Margins=Custom\" to turn on your\n";
270 print "settings.\n";
271 print "\n";
272
273 exit 0;
274
275 ## END OF FILE #################################################################