Linux printing solution

99 views
Skip to first unread message

kdt...@gmail.com

unread,
Sep 9, 2006, 6:57:48 PM9/9/06
to Hardhats
Well, my printing seems to be working. I am using a Dell 1700,
controlling it with PCL escape codes. Here is my configuration for
anyone's future reference. All the escape sequences were entered in
fresh from a PCL reference.

Kevin

Select DEVICE NAME: s121-LAUGHLIN-LASER Laughlin_Office <TO BE
SET IN P
RE-OPEN EX.>
Display empty fields? No// (No)
Enter Output Device: HOME// TELNET

.01-NAME : S121-LAUGHLIN-LASER
.02-LOCATION OF TERMINAL : Laughlin_Office
1-$I : <TO BE SET IN PRE-OPEN EX.>
2-TYPE : HOST FILE SERVER
3-SUBTYPE : P-HPLASER-P12-DELL1700
7-NEAREST PHONE : 787-7000
11-PAGE LENGTH : 75
11.2-SUPPRESS FORM FEED AT CLOSE : YES
17-FORM CURRENTLY MOUNTED : Plain paper
19.7-PRE-OPEN EXECUTE : SET IO=$$GETJOBNM^TMGPRNTR()
19.8-POST-CLOSE EXECUTE : DO FINISH^TMGPRNTR("laughlin_laser")
Press [ENTER] to continue...


Select TERMINAL TYPE NAME: `199 P-HPLASER-P12-DELL1700
LASER PRINTER PORTRAIT MODE 12 CPI
Display empty fields? No// (No)
Enter Output Device: HOME// TELNET

.01-NAME : P-HPLASER-P12-DELL1700
1-RIGHT MARGIN : 96
2-FORM FEED : $C(13,12)
3-PAGE LENGTH : 79
4-BACK SPACE : $C(8)
6-OPEN EXECUTE : W
$C(27)_"(s12H"_$C(27)_"&a7L"_$C(27)_"&l8D"_$C(27)_"&l6E"
_$C(27)_"&l80F"
6.1-TEXT :
set # CPI -- ESC (s#H set left margin to # columns -- ESC &a#L set
lines/inc
h to # -- ESC &l#D set top margin to # lines -- ESC &l#E set text
length to #
lines -- ESC &l#F set page length to # lines -- Esc &l#P
7-CLOSE EXECUTE : W *27,"E"
10-10 PITCH : $C(27)_"(s12H"
12-12 PITCH : W $C(27)_"(s10H"
12.1-16 PITCH : W $C(27)_"(s8H"
12.11-DEFAULT PITCH : $C(27)_"(s10H"
12.12-X PITCH : $C(27)_"(s"_X_"H"
12.13-6 LINES PER INCH : $C(27)_"&16D"
12.14-8 LINES PER INCH : $C(27)_"&18D"
12.15-DEFAULT LINES PER INCH : $C(27)_"&18D"
12.16-X LINES PER INCH : $C(27)_"&l"_X_"D"
20-RESET : $C(27)_"E"
23-UNDERLINE ON : $C(27)_"&d0D"
24-UNDERLINE OFF : $C(27)_"&d@"
26-PROPORTIONAL SPACING : $C(27)_"(s1P"
27-HIGH INTENSITY (BOLD) : $C(27)_"(s3B"
28-LOW INTENSITY (UNBOLD) : $C(27)_"(0B"
29-NORMAL INTENSITY (RESET) : $C(27)_"(0B"
66-ITALICS ON : $C(27)_"(s1S"
67-ITALICS OFF : $(27)_"(s0S"
99-DESCRIPTION : LASER PRINTER PORTRAIT MODE 12 CPI
110.1-TEXT :

I had to implement a klunky manual line counter to compensate for $Y
wrapping, to allow a page length of 75 ($Y was wrapping at 65)

Kevin Toppenberg

unread,
Sep 9, 2006, 7:01:59 PM9/9/06
to Hardhats
Here is the site I used for PCL codes reference

http://printers.necsam.com/public/printers/pclcodes/pcl5hp.htm

Kevin

Steven McPhelan

unread,
Sep 9, 2006, 9:02:36 PM9/9/06
to Hard...@googlegroups.com
Comments:
1. You should not put code in the POST CLOSE EXECUTE field unless you absolutely must.  You set up your terminal type to be 10 pitch, 8 lines per inch and then reset the printer to default settings.  That field is in the Device file.  So you have to set that field for every device you set up using those PCL commands.  You should put the post close execute logic in the CLOSE EXECUTE field in the Terminal Type file.  This way every device that may use that terminal type will execute that code.  The Device file POST CLOSE EXECUTE field is useful if there is something you wish to do the file prior to submiting it to LPR.  If all your post close execute does is submit the file to a print queue, then you could put the command to C IO and then D your-routine.  I believe there is also an IO* variable that needs Killing.  I would have to review the VA's recommended setup for a terminal type that submits a file to a VMS print queue.
 
2. Your commands in the OPEN execute has duplicative functions: $C(27)_"&a7L"_$C(27)_"&l8D"  I have always just used the 7L syntax.  I find that 7L will allow me to print 66 lines in the normal 60line window for most laser printers.  However, since you want 75 lines per page, I would eliminate the 7L and leave the 8D.
 
3. You should not put a right margin in the DEVICE FILE unless really needed.  Let the Terminal Type file control the right margin.
 
4. On your printer, the $C(27)_"E" in the close execute apparently does not cause a hard page feed.  This is not true for all printers.  Many laser printers (notably HP printers) interpret the reset command to reset and print the printer buffer even if it is empty.   Plus you used the W *27 syntax.  W *27 and W $C(27) may not be treated EXACTLY the same by the M implementation.  The VA has standardized on using the $C(27) syntax since that one is well defined within the M ANSI standards.
 
5. In 67-ITALICS OFF : $(27)_"(s0S" where is the C
 
 
 
--
Steve
"Not only is the universe stranger than we imagine, it is stranger than we can imagine." -- Sir Arthur Eddington

kdt...@gmail.com

unread,
Sep 9, 2006, 10:49:54 PM9/9/06
to Hardhats
Steve,

Thanks for your feedback. See below:

Steven McPhelan wrote:
> Comments:
> 1. You should not put code in the POST CLOSE EXECUTE field unless you
> absolutely must. You set up your terminal type to be 10 pitch, 8 lines per
> inch and then reset the printer to default settings. That field is in the
> Device file. So you have to set that field for every device you set up
> using those PCL commands. You should put the post close execute logic in
> the CLOSE EXECUTE field in the Terminal Type file. This way every device
> that may use that terminal type will execute that code. The Device file
> POST CLOSE EXECUTE field is useful if there is something you wish to do the
> file prior to submiting it to LPR. If all your post close execute does is
> submit the file to a print queue, then you could put the command to C IO and
> then D your-routine. I believe there is also an IO* variable that needs
> Killing. I would have to review the VA's recommended setup for a terminal
> type that submits a file to a VMS print queue.

I am not completely following you here. I think you are saying that if
I would move my Open & Close execute commands from the DEVICE file into
the TEMINAL TYPE file that any device using that TERMINAL TYPE would
automatically have the functionality of my system. I don't think this
is correct because my system depends on the DEVICE being a HFS. I.e.
opening a channel to a file for output to go to. Thus, in the Open
Execute for the TERMINAL FILE, the command is to WRITE (to an already
opened IO channel). But the Open Execute of the DEVICE file is to set
up the name of the IO channel/file to use. Likewise, the Close Execute
of the TERMINAL FILE is called before the IO channel is closed, but the
Close Execute of the DEVICE file is called AFTER the IO channel is
closed, so I can use that time to send the file on to lpr.

Also, you mentioned that I set up pitch, font etc and then reset the
printer. If that was true, then why do the settings work? I don't
think that the Close Execute is called until the end of the printing.
I could easily take that final ESC E out, but that was there from the
P-HPLASER-P12 record that I started with and modified. That is why the
*27 format is used. I don't actually understand the syntax of *X.

>
> 2. Your commands in the OPEN execute has duplicative functions:
> $C(27)_"&a7L"_$C(27)_"&l8D" I have always just used the 7L syntax. I find
> that 7L will allow me to print 66 lines in the normal 60line window for most
> laser printers. However, since you want 75 lines per page, I would
> eliminate the 7L and leave the 8D.

I think you are think of some different codes than what I am using

ESC &a7L sets the left margin to 7 colums. Without this, my text was
showing up way over on the left, with only about a 1/4" margin

Esc &l8D sets the lines/inch to 8.

So these are not conflicting. I don't really have much experience with
this in the long term, but I did spend about 8 hours today poring over
a reference, and printing out about 200 pages trying this and that to
get what I wanted.. :-)

>
> 3. You should not put a right margin in the DEVICE FILE unless really
> needed. Let the Terminal Type file control the right margin.

Isn't this value used to set IOM? This is needed by a variety of
purposes, isn't it?

>
> 4. On your printer, the $C(27)_"E" in the close execute apparently does not
> cause a hard page feed. This is not true for all printers. Many laser
> printers (notably HP printers) interpret the reset command to reset and
> print the printer buffer even if it is empty. Plus you used the W *27
> syntax. W *27 and W $C(27) may not be treated EXACTLY the same by the M
> implementation. The VA has standardized on using the $C(27) syntax since
> that one is well defined within the M ANSI standards.

Good point. Perhaps I should just take it out. It was a left over
from a former record that I overwrote. As above, what exactly is
happening with *X?

>
> 5. In 67-ITALICS OFF : $(27)_"(s0S" where is the C
>

Good catch. I'll have to fix that. But while we are talking about
italics, is this code ever executed? VistA doesn't support formating
of text does it?

I really appreciate your feedback on this.

Thanks
Kevin

K.S. Bhaskar

unread,
Sep 10, 2006, 11:25:43 AM9/10/06
to Hard...@googlegroups.com
I have not spent the time following the discussions on the guts of
setting up printers, but I would like to throw a curve ball.

VistA printing was evidently written for the days when operating systems
were more primitive, and so it has an entire infrastructure for managing
printers. Operating systems today provide a printing infrastructure (in
the case of Linux, multiple choices of infrastructures - I use CUPS), so
that if an applications generates Postscript output, the OS can spool
and print to just about any printer. Is it possible to define a
Postscript printer in VistA, generate output to a temporary file, and
call the Linux print spooler to print it? If so, why not do it? If
not, what does it take to get VistA to do this?

Of course, this approach may not work for specialized printers such as
bar code / label printers, but it should work for virtually all office
and home printers.

-- Bhaskar

kdt...@gmail.com

unread,
Sep 10, 2006, 2:01:19 PM9/10/06
to Hardhats

K.S. Bhaskar wrote:
...

Is it possible to define a
> Postscript printer in VistA, generate output to a temporary file, and
> call the Linux print spooler to print it? If so, why not do it? If
> not, what does it take to get VistA to do this?
>

Bhaskar, it is possible to write output to a temporary file and then
pass it to a linux printer. That is the approach of my setup. Now the
vistA printer I am using just puts out text. I.e. the report is
created by code opening the file, and then sending various WRITE's to
the IO channel with the header, body and footer. I don't know anything
about postscript, but I assume that it involves complex formating etc.
I think that the code creating various reports would have to know about
supplying this special formatting etc.

But I was hoping you would have an answer how to keep GT.M from
wrapping $Y after writing 65 lines of output. I can't figure that part
out.

Thanks
Kevin

kdt...@gmail.com

unread,
Sep 10, 2006, 2:02:57 PM9/10/06
to Hardhats

kdt...@gmail.com wrote:
> Well, my printing seems to be working...

Let me add another detail for future reference: the Linux Printer is
defined as a TEXT ONLY printer, i.e. it does not use any drivers. I
assume this just passes the data straight through to the printer, so
that VistA's printer controll sequences don't get mangled.

Kevin

JohnLeo Zimmer, MD

unread,
Sep 10, 2006, 5:39:49 PM9/10/06
to Hard...@googlegroups.com
K.S. Bhaskar wrote:
>
> VistA printing was evidently written for the days when operating systems
> were more primitive, and so it has an entire infrastructure for managing
> printers.

[jlz] This is correct... also, in the DHCP days, the printers were HP
and others, Kyocera for one, that used HP's PCL. The TERMINAL TYPE file
has entries for many such printers with escape sequences that talk PCL.

(On can do some fancy things by using MUMPS to talk PCL direct to the
printer.)

> Operating systems today provide a printing infrastructure (in
> the case of Linux, multiple choices of infrastructures - I use CUPS), so
> that if an applications generates Postscript output, the OS can spool
> and print to just about any printer. Is it possible to define a
> Postscript printer in VistA, generate output to a temporary file, and
> call the Linux print spooler to print it? If so, why not do it?

[jlz]... or to filter PCL output into Postscript/Ghostscript for output.
... or try CUPS raw output to a PCL-5 device.
I am working in that direction myself.

> If not, what does it take to get VistA to do this?

[jlz] Knowledge and skill with Postscript, I imagine. And for the simple
output that Vista general produces it should take only a little of that.
To to pictures and graphs, etc. I think we'll be out in Linux anyway.

Gregory Woodhouse

unread,
Sep 10, 2006, 7:11:20 PM9/10/06
to Hard...@googlegroups.com
On Sep 10, 2006, at 8:25 AM, K.S. Bhaskar wrote:

I have not spent the time following the discussions on the guts of 

setting up printers, but I would like to throw a curve ball.


VistA printing was evidently written for the days when operating systems 

were more primitive, and so it has an entire infrastructure for managing 

printers. 


I think this is true of much of the VistA infrastructure in general. In many ways, I liken it to Windows 3.1 (and this is not meant as a slight): It provides services not available from the underlying OS (or MUMPS implementation) using a program or programs running in user space (Windows was originally a program that ran under DOS). one thing I had always hoped for was to see Fileman and the VistA Kernel develop into a true standalone system, though this is an idea that doesn't seem to have a lot of traction. Be that as it may, it is certainly true that many of the services provided by Kernel could profitably be moved to the system level -- or at least this is my opinion. Still, a basic principle of VistA has long been portability across platforms. That means portability across both MUMPS implementations and operating systems. Now, if the standard can ever be updated, then I don't think it is at all unreasonable, say, to provide a standard interface to POSIX services.

Operating systems today provide a printing infrastructure (in 

the case of Linux, multiple choices of infrastructures - I use CUPS), so 

that if an applications generates Postscript output, the OS can spool 

and print to just about any printer.  Is it possible to define a 

Postscript printer in VistA, generate output to a temporary file, and 

call the Linux print spooler to print it?  If so, why not do it?  If 

not, what does it take to get VistA to do this?


I see no reason why this could not be done. The temporary file approach isn't even necessary, you could write to a FIFO instead, though the temporary file approach is reasonably common. 


Of course, this approach may not work for specialized printers such as 

bar code / label printers, but it should work for virtually all office 

and home printers.


Well, they may not use PostScript, but I see no reason why a suitable driver could not be developed for use within the VistA environment.


-- Bhaskar


Gregory Woodhouse

"We may with advantage at times forget what we know."
--Publilius Cyrus, c. 100 B.C.



JohnLeo Zimmer, MD

unread,
Sep 10, 2006, 11:13:05 PM9/10/06
to Hard...@googlegroups.com
Here is a bare bones DEVICE to print from GT.M.
It's running on an Ubuntu system with CUPS.

NAME: PRINTSERVER $I: /tmp/vistaprint.txt
LOCATION OF TERMINAL: lpr OPEN COUNT: 1
POST-CLOSE EXECUTE: X "ZSYSTEM ""lpr -r /tmp/vistaprint.txt"""
SUBTYPE: P-OTHER80 TYPE: HOST FILE SERVER


regards,
JohnLeoZ

Mike Schrom

unread,
Sep 11, 2006, 9:03:51 AM9/11/06
to Hard...@googlegroups.com

Gregory Woodhouse wrote:

>
> I think this is true of much of the VistA infrastructure in general. In
> many ways, I liken it to Windows 3.1 (and this is not meant as a
> slight): It provides services not available from the underlying OS (or
> MUMPS implementation) using a program or programs running in user space
> (Windows was originally a program that ran under DOS).

This remains a problem for many legacy applications. I had to scrap a
brand new HP printer (actually I gave it to my wife!)which couldn't
print from my DOS practice management application, because the PM system
tried to issue calls directly to the printer, bypassing Windows (2000 or
XP). The print-to-file option didn't work either because the PM system's
method of issuing OS commands just issued DOS commands, so I had to
leave the app, and open the text file from Windows to get the printer to
print.


Mike

K.S. Bhaskar

unread,
Sep 11, 2006, 11:12:52 AM9/11/06
to Hard...@googlegroups.com

kdt...@gmail.com wrote, on 09/10/2006 02:01 PM:

[KSB] <...snip...

> But I was hoping you would have an answer how to keep GT.M from
> wrapping $Y after writing 65 lines of output. I can't figure that part
> out.

[KSB] Hope this helps (watch out for line breaks introduced by mailers):

sh-3.1$ mumps -run iodemo
iodemo ;; demonstrate use of $x and wrapping
ZPrint
Set file="/tmp/gtm"_$J_".tmp" Open file:(variable:nowrap)
Use file Do io
Use file:(wrap:width=65) Do io
Close file
ZSYstem "cat "_file
Quit
;
io ;; actual IO
For i=1:1:3 Do
.For j=1:1:6 Write
$Justify(i,2),",",$Justify(j,2),":",$Justify($x,3),",",$Justify($y,3)
.Write " EOL",!
Quit
1, 1: 6, 0 1, 2: 19, 0 1, 3: 32, 0 1, 4: 45, 0 1, 5: 58, 0 1, 6:
71, 0 EOL
2, 1: 6, 1 2, 2: 19, 1 2, 3: 32, 1 2, 4: 45, 1 2, 5: 58, 1 2, 6:
71, 1 EOL
3, 1: 6, 2 3, 2: 19, 2 3, 3: 32, 2 3, 4: 45, 2 3, 5: 58, 2 3, 6:
71, 2 EOL
1, 1: 6, 3 1, 2: 19, 3 1, 3: 32, 3 1, 4: 45, 3 1, 5: 58, 3
1, 6: 6, 4 EOL
2, 1: 6, 5 2, 2: 19, 5 2, 3: 32, 5 2, 4: 45, 5 2, 5: 58, 5
2, 6: 6, 6 EOL
3, 1: 6, 7 3, 2: 19, 7 3, 3: 32, 7 3, 4: 45, 7 3, 5: 58, 7
3, 6: 6, 8 EOL
sh-3.1$

-- Bhaskar

Kevin Toppenberg

unread,
Sep 12, 2006, 12:47:14 PM9/12/06
to Hard...@googlegroups.com
Bhaskar (or others),

Thanks for this reply. You have showed me about wrapping in the $X
direction. But I can't see how to affect wrapping in the $Y
direction, i.e. page length.

I ran you code and got your same results. I then changed your line:


For i=1:1:3 Do

to
For i=1:1:70 Do
and re-ran it. Even when [nowrap] is specified, I still see wrapping at $Y=65.

Is there a way around this? I didn't seen any LENGTH or HEIGHT
parameters in the manual. But I tried them anyway. HEIGHT gives a
compile error. LENGTH is accepted, but doesn't change the $Y wrapping
point.
Use file:(wrap:width=65:length=70) <---- no help.

Any ideas?

Thanks
Kevin

kdt...@gmail.com

unread,
Sep 12, 2006, 1:09:21 PM9/12/06
to Hardhats
Sorry, this does work after all. I read the manual and looked at the
code more carefully.

The syntax is:
USE file:(wrap:width=123:length=123)

Thanks
Kevin


Kevin Toppenberg wrote:
> Bhaskar (or others),
>
> Thanks for this reply. You have showed me about wrapping in the $X
> direction. But I can't see how to affect wrapping in the $Y
> direction, i.e. page length.

...

Reply all
Reply to author
Forward
0 new messages