ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ DB/C Newsletter ³ ³ September 1993 ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Editor's Notes The topic for this month's newsletter is printing. Printing has always been filled with surprises - because of operating systems, cables, paper jams, and many other things. Hopefully this article will help you cope with many of those surprises. DNW PRINTING One of the more complex issues encountered in designing a DB/C application is sending output to a printer. There are many reasons why printing has become an intricate subject. The primary reason is that printers may be connected by a number of ways, both directly to the workstation and indirectly through various local and network operating systems. This article will be organized by operating system. It will also highlight the portable printing methods since moving between operating systems can be a very relevant concern. Printing is also complicated by GUI environments. A GUI environment has the advantage of making your printing device independent, but it also makes printing a little more like painting on a graphical canvas. We will address these printing methods in the last segment of this article. PRINTING IN MS-DOS If the destination printer is locally connected to an MS-DOS workstation, direct-device printing should be used. The default device for direct printing is LPT1. Thus, a DB/C application that uses PRINT statements, without the aid of SPLOPEN/SPLCLOSE statements or DBC_PRINTER settings, will automatically send output to the printer connected to LPT1. Printing directly to other devices, such as LPT2 or COM1, will require the use of DBC_PRINTER run-time option or SPLOPEN/SPLCLOSE in your programs. The DBC_PRINTER run-time option may be used to specify a destination for printer output before your DB/C application is started. DBC_PRINTER specifes the new default print destination (presumably different from LPT1) of PRINT statements in a DB/C application. For example, if the destination printer was connected to LPT2, and not LPT1, the following MS-DOS command should be issued before DB/C is started: SET DBC_PRINTER=LPT2 If the DB/C application issues any PRINT statements, print data will be sent to the device connected to LPT2. Also note that when LPT1 and LPT2 are used, the data is printed using BIOS of the PC, bypassing MS-DOS. The SPLOPEN statement may also be used to print directly to a device. In general, the SPLOPEN statement is useful if multiple print destinations are required within the same program, perhaps even in overlapping areas of code. Non-simultaneous, multiple-destination printing can be achieved by placing PRINT statements between the appropriate SPLOPEN/SPLCLOSE verbs. Simultaneous, multiple-destination printing is achieved by using SPLOPEN/SPLCLOSE and PFILE variables with the "PRINT ;" syntax or by using the SPLOPEN option F with the SPLOPT verb. To SPLOPEN the device LPT2 at the first print statement, the following SPLOPEN statement should be issued: SPLOPEN "LPT2" Some networks provide methods of redirecting device output to a remote printer (e.g. CAPTURE in Novell Netware). If the device is accessed via the BIOS (which DB/C does by default), and is not accessed via MS-DOS OPEN and WRITE, the network redirector or shell may not know when printing has finished. The capture mechanism will wait until for a short period of time (a time-out) before it will actually begin printing (even if SPLCLOSE or RELEASE is used). To access LPT1 or LPT2 through MS-DOS, put a period after the name of the printer, like this: SET DBC_PRINTER=LPT1. SPLOPEN "LPT1." In these cases, the printer device will be opened when the first PRINT statement encountered. The only exception to this is if the SPLOPEN statement contains the A option. In this case, the printer device will be opened immediately. If a RELEASE or SPLCLOSE (which does an implicit RELEASE) is issued, an MS-DOS close of the device occurs and the redirected print output will immediately be spooled or printed. Note that if RELEASE is used in the SET DBC_PRINTER case, the device will automatically be reopened at the next occurrence of a PRINT statement. Device control characters are created in the print output when LPT1 or LPT2 is specified and therefore the D option is unnecessary. The D option should be specified if device control characters are required in print output that is being sent to a file. There is currently no way of directly detecting if a local printer is off-line. The SPLOPEN/SPLCLOSE verbs can be used to print directly to a Netware print queue. The SPLOPEN statement must include the P option which causes the print output to a spooled until a SPLCLOSE statement is executed, at which time the print job is submitted. No options are required on the SPLCLOSE statement. The SPLOPEN syntax for printing to a Netware queue is: SPLOPEN "queuename", "P" SPLOPEN "server/queuename", "P" SPLCLOSE can be used to submit a file to a Netware print queue after it has been opened or created by SPLOPEN. If the S option is used with SPLCLOSE, the print file will be submitted to the default Netware print queue to printer number 0. If another printer, is required, the "P=n" option may be used. The following example will submit the current print file 5 times to the Netware queue specified by printer number 3, and will delete the file after it has finished spooling: SPLCLOSE "S,P=003,N=5,D" Printer numbers can be assigned to Netware 3.11 and above Print Queues by using the SPOOL command from the colon prompt of the Netware Console or from the AUTOEXEC.NCF file. This command has the following syntax where "n" is the printer number and "queue" is the print queue name: SPOOL n queue There are other ways to print to a Netware queue. One way is by using the CAPTURE and ENDCAP commands. Another way is by spooling the print output to a file and using NPRINT (via ROLLLOUT) to submit the file. Neither of these methods is portable to other operating systems. The P option on SPLOPEN is more portable with UNIX, especially if the queuename can be changed dynamically to a UNIX "lp" command (which will be explained below). The DBC_PRINTER run-time option or the SPLOPEN/SPLCLOSE verbs can also be used if the direct printed output to a file. The DBC_PRINTER run-time option may specify a file name instead of a device name. The file is created (by replacing any existing file with the same name) and printer output is directed to it until DB/C terminates. The file created using DBC_PRINTER does not contain device control characters. The SPLOPEN statement can also be used to create a file. If the Q option is specified in the SPLOPEN statement, print output is be appended to the file. The C option on SPLOPEN causes the file to be a DB/C compressed type file. The D option causes device control characters to be put into the print file. Note that a file created with the D option may or may not be a valid TEXT type file, depending on whether the CR/LF characters are in the correct order and are at the end of the file. The C and D options are mutually exclusive. PRINTING IN UNIX In UNIX, printers are typically connected to the main processor and are given device names. A DB/C application program can print directly to such a device and lock out other users from the printer until the job is completed. Printers may also be connected to the terminals attached to the console. Printing to these local printers is not easy, but can be accomplished. UNIX systems typically include a print spooler program called lp. DB/C works with the lp spooler to provide queued printer output. Printing directly to a device with DB/C in UNIX has two requirements. The first is that the printer name must start with /dev/ so that DB/C knows it is a device and not a file (devices in UNIX are integrated into the file system). Also, DB/C requires that the users have WRITE permission to the output device. A printer device can be allocated by the use of the DBC_PRINTER run-time option or by using SPLOPEN/SPLCLOSE statements within the DB/C application. For example, before dbc is started (and using the "sh" shell), do the following command: DBC_PRINTER=/dev/lp2;export DBC_PRINTER or use the SPLOPEN statement in the DB/C program like this: SPLOPEN "/dev/lp2" The SPLOPEN/SPLCLOSE combination has the advantage of allowing multiple printer destinations in one program and in overlapping regions of code (see the MS-DOS discussion above). The DBC_PRINTER run-time option has the advantage of keeping system specific device names out of your program. If neither DBC_PRINTER nor SPLOPEN\SPLCLOSE is used, the default print device is /dev/lp. The UNIX operating system does not have a concept like OPEN EXCLUSIVE. Therefore, DB/C had to arbitrarily create a method to keep other users from accessing a printer while one program was using it. DB/C actually has two different locking mechanisms. The default locking mechanism is the creation of a "lock file" whenever the printing device is in use by DB/C. The lock file is created in the /tmp directory, so users must have READ/WRITE permissions to that directory. If a lock file exists for a desired printing device, the DB/C program waits until that lock file disappears. The naming convention for the device lock file is to replace "/dev/" with "/tmp/LCK..". For example: "/dev/tty10" becomes "/tmp/LCK..tty10" and "/dev/prt/tty20" becomes "/tmp/LCK..prt/tty20" In the case of the last example, where the printer device exists in a subdirectory of /dev, the directory /tmp/LCK..prt must exist and the user must have READ/WRITE permission to it. If this directory does not exist then the DB/C program will stop with the error P401 when the device is allocated. The second locking mechanism is used when the DBC_PRTLOCK=FCNTL run-time option is specified. In this case, a record lock (for WRITE) is placed on the device (from position 0 to the end of the file) locking out any other DB/C program until the device is released. The DISPLAY statement, not the PRINT statement, is used to print to a printer that is connnected directly to the terminal. The *PON control code sends the escape sequence to the terminal that causes printer port to be activated. Subsequent DISPLAY output is sent out the printer port. The *POFF control code deactivates the printer port. The only other DISPLAY codes recognized between *PON and *POFF are *C, *L and *N. *C causes a CR (carriage return) character to be sent, *L causes a LF (line feed) character to be sent, and *N causes CR followed by LF to be sent. For the *PON/*POFF capability to work, the AUXPORT_ON and AUXPORT_OFF functions must be defined in the current terminal definition file (specified by DBC_TERMDEF), or the mc5 and mc4 functions must be defined in the current terminfo entry. Printed output can also be piped to the lp spooler. The lp spooler will queue print jobs for any of the printers it manages. The most portable method is to use the P option on SPLOPEN. The pipe will be opened on SPLOPEN and closed when on SPLCLOSE statement (no other options are required). The following example specifies a printer named "printer1": SPLOPEN "lp -dprinter1", "P" Printed output can also be directed to a text file in the same manner as for other operating systems (see the MS-DOS description above). SPLCLOSE may be used to direct printed output to the lp spooler. The following example will spool to the file junk.prt and submit it printer lp1 via the lp spooler: SPLOPEN "junk.prt", "D" PRINT "HELLO WORLD!" SPLCLOSE "S, P=lp1" NOTE: The file junk.prt will remain after the example program completes, even if the D option is specified on SPLCLOSE. There is no way for the lp spooler to delete the file after it has completed and DB/C can not tell when lp has completed printing it. The preferred method of sending output to the lp spooler is to use SPLOPEN with the P option as discussed above. PRINTING IN VAX/VMS A DB/C program can print to any valid device name in VMS. A printer device can be specified by the DBC_PRINTER run-time option or by using SPLOPEN and SPLCLOSE. A printer device can be allocated exclusively in VMS, so no other locking mechanisms are imposed by DB/C. The default printer device name is "pta0:". The DBC_PRINTER run-time option may be used to specify the destination printer. The device is actually allocated by the first PRINT statement encountered. The device will be freed by a subsequent RELEASE statement and reallocated by the next PRINT statement following the RELEASE. The SPLOPEN and SPLCLOSE statement may be used to allocate a device for printing. The printer device is allocated when the first PRINT statement is executed, except when the A option is used in the SPLOPEN statement. In this case, the printer device to be allocated immediately. In both cases, SPLCLOSE and RELEASE causes the printer to be deallocated. Printed output can be directed to a file in the same manner as for MS-DOS and UNIX. A print file can be submitted to a VMS print queue by using the S option on the SPLCLOSE statement. The P option defines the destination queue. If P is not specified, the default queue is SYS$PRINT. Printed output can be directed to a printer connected directly to the terminal in the same manner as discussed above for UNIX. The *PON and *POFF capabilities are specified in the DBC_TERMDEF file in the same manner as for UNIX or they may be specified by SET_PRINTER_OUTPUT and SET_SCREEN_OUTPUT in the current termtable entry. PRINTING IN MS-WINDOWS & MACINTOSH GUI ENVIRONMENTS There are several GUI-only printing features available in the MS-Windows and Macintosh versions of DB/C. The device and file printing methods available in MS-DOS are also available in the MS-Windows version of DB/C. With the Macintosh version of DB/C, printer devices are supported only via the GUI-only printing features, but the standard file printing methods are also available. The concept behind printing in a GUI environment is that a print image is logically drawn on a page before it is sent to the printer. Device drivers handle the details of printing so that there is no such thing as device control characters. The SPLOPEN command is used to provide access to the extended graphical features available in the GUI environment. The following example opens the printer currently selected as the default in Windows, or selected in the Chooser on the Macintosh, and specifies a resolution of 300 dots per inch: SPLOPEN "DEFAULT(300)" PRINT statements that follow this statement will causes characters and lines to be drawn on the logical page. There are additional control codes available in the PRINT statement to control this drawing. These codes include: *FONT=, *P=:, *LINE=:, *WHITE, *BLACK, *BLUE, *GREEN, *YELLOW, *RED, *CYAN and *MAGENTA. is a character variable, literal or expression. and specify horizontal and vertical positions (in pixels) on the logical page. *FONT specifies the print font. *P specifies a new draw position. *LINE specifies that a line is drawn from the current draw position to the position specified in the *LINE. The color control codes specify that all drawing is to be done in that color. The *F control code causes all print output to go to the next (new) logcial page. In addition, the PRINT statement may contain image variables that are drawn on the logical page with the upper left corner at the current draw position. The SPLCLOSE statement (with no options) will cause the print pages to be printed on the printer. The SPLOPEN statement that allocates a printer in a GUI environment may contain the J option. This option specifies that a job setup dialog box is displayed. The job setup dialog prompts the user for information specific to this print job. Before the SPLOPEN statement is executed, the SPLOPT statement may be executed with the "S" option. This option causes a printer setup dialog box to be displayed. The printer setup dialog prompts the user for information specific to the printer. This information is retained across multiple SPLOPEN statements. Good printing! DB/C Class Schedule There are two DB/C classes scheduled for this month. The dates are September 20-23 and September 27-30. The classes are held in the Oak Brook, Illinois office of Subject, Wills & Company. For more information, contact Judi Tamkevic at (708) 572-0240.