xterm-49.patch.txt

XFree86 3.9k - xterm patch #49 - 1997/8/10 - T.Dickey <dickey@clark.net>
 
This patch implements the VT100/VT220 Media Copy (i.e., print-screen) control
sequences.
 
--------------------------------------------------------------------------------
 Imakefile        |    4 
 Makefile.in      |    4 
 VTPrsTbl.c       |    2 
 VTparse.def      |    1 
 VTparse.h        |    1 
 charproc.c       |   55 ++++++++-
 ctlseqs.ms       |   22 +++
 ptyx.h           |    7 -
 terminfo         |    4 
 xterm-49/print.c |  319 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 xterm.h          |    5 
 xterm.man        |   28 ++++
 12 files changed, 442 insertions, 10 deletions
--------------------------------------------------------------------------------
Index: Imakefile
--- xterm-48+/Imakefile Mon Jun 30 08:51:00 1997
+++ xterm-49/Imakefile  Sun Aug 10 14:03:21 1997
@@ -74,10 +74,10 @@
           MAINOBJ = main.o
 #endif
           SRCS1 = button.c charproc.c cursor.c data.c doublechr.c input.c \
-                 $(MAINSRC) menu.c misc.c screen.c scrollbar.c tabs.c \
+                 $(MAINSRC) menu.c misc.c print.c screen.c scrollbar.c tabs.c \
                  TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c $(EXTRASRC)
           OBJS1 = button.o charproc.o cursor.o data.o doublechr.o input.o \
-                 $(MAINOBJ) menu.o misc.o screen.o scrollbar.o tabs.o \
+                 $(MAINOBJ) menu.o misc.o print.o screen.o scrollbar.o tabs.o \
                  TekPrsTbl.o Tekproc.o util.o VTPrsTbl.o $(EXTRAOBJ)
           SRCS2 = resize.c
           OBJS2 = resize.o
Index: Makefile.in
--- xterm-48+/Makefile.in       Mon Jun 30 08:51:00 1997
+++ xterm-49/Makefile.in        Sun Aug 10 14:03:07 1997
@@ -39,10 +39,10 @@
 EXTRAOBJ       = @EXTRAOBJS@
 
           SRCS1 = button.c charproc.c cursor.c data.c doublechr.c input.c \
-                 main.c menu.c misc.c screen.c scrollbar.c tabs.c \
+                 main.c menu.c misc.c print.c screen.c scrollbar.c tabs.c \
                  TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c $(EXTRASRC)
           OBJS1 = button.o charproc.o cursor.o data.o doublechr.o input.o \
-                 main.o menu.o misc.o screen.o scrollbar.o tabs.o \
+                 main.o menu.o misc.o print.o screen.o scrollbar.o tabs.o \
                  TekPrsTbl.o Tekproc.o util.o VTPrsTbl.o $(EXTRAOBJ)
           SRCS2 = resize.c
           OBJS2 = resize.o
Index: VTPrsTbl.c
--- xterm-48+/VTPrsTbl.c        Mon Jun 30 08:51:00 1997
+++ xterm-49/VTPrsTbl.c Sun Aug 10 14:08:39 1997
@@ -1471,7 +1471,7 @@
 CASE_GROUND_STATE,
 /*     h               i               j               k       */
 CASE_DECSET,
-CASE_GROUND_STATE,
+CASE_DEC_MC,
 CASE_GROUND_STATE,
 CASE_GROUND_STATE,
 /*     l               m               n               o       */
Index: VTparse.def
--- xterm-48+/VTparse.def       Mon Jun 30 08:51:00 1997
+++ xterm-49/VTparse.def        Sun Aug 10 14:09:12 1997
@@ -120,3 +120,4 @@
 CASE_DECDHL
 CASE_DECSWL
 CASE_DECDWL
+CASE_DEC_MC
Index: VTparse.h
--- xterm-48+/VTparse.h Mon Jun 30 08:51:00 1997
+++ xterm-49/VTparse.h  Sun Aug 10 14:09:00 1997
@@ -182,3 +182,4 @@
 #define CASE_DECDHL 110
 #define CASE_DECSWL 111
 #define CASE_DECDWL 112
+#define CASE_DEC_MC 113
Index: charproc.c
--- xterm-48+/charproc.c        Tue Jul 29 15:13:30 1997
+++ xterm-49/charproc.c Sun Aug 10 20:08:53 1997
@@ -84,6 +84,7 @@
 #define read(f,b,s) nbio_read(f,b,s)
 #define write(f,b,s) nbio_write(f,b,s)
 #endif
+
 #include "VTparse.h"
 #include "data.h"
 #include "error.h"
@@ -208,6 +209,10 @@
 #define XtNpointerColor "pointerColor"
 #define XtNpointerColorBackground "pointerColorBackground"
 #define XtNpointerShape "pointerShape"
+#define XtNprinterControlMode "printerControlMode"
+#define XtNprinterCommand "printerCommand"
+#define XtNprinterExtent "printerExtent"
+#define XtNprinterFormFeed "printerFormFeed"
 #define XtNmultiClickTime "multiClickTime"
 #define XtNmultiScroll "multiScroll"
 #define XtNnMarginBell "nMarginBell"
@@ -290,6 +295,10 @@
 #define XtCResizeGravity "ResizeGravity"
 #define XtCReverseWrap "ReverseWrap"
 #define XtCAutoWrap "AutoWrap"
+#define XtCPrinterControlMode "PrinterControlMode"
+#define XtCPrinterCommand "PrinterCommand"
+#define XtCPrinterExtent "PrinterExtent"
+#define XtCPrinterFormFeed "PrinterFormFeed"
 #define XtCSaveLines "SaveLines"
 #define XtCScrollBar "ScrollBar"
 #define XtCScrollLines "ScrollLines"
@@ -338,6 +347,7 @@
 static  Boolean        defaultCOLORMODE   = DFT_COLORMODE;
 static  Boolean        defaultFALSE       = FALSE;
 static  Boolean        defaultTRUE        = TRUE;
+static  int    defaultZERO        = 0;
 static  int    defaultIntBorder   = DEFBORDER;
 static  int    defaultSaveLines   = SAVELINES;
 static int     defaultScrollLines = SCROLLLINES;
@@ -564,6 +574,18 @@
 {XtNpointerShape,XtCCursor, XtRCursor, sizeof(Cursor),
        XtOffsetOf(XtermWidgetRec, screen.pointer_cursor),
        XtRString, (XtPointer) "xterm"},
+{XtNprinterControlMode, XtCPrinterControlMode, XtRInt, sizeof(int),
+       XtOffsetOf(XtermWidgetRec, screen.printer_controlmode),
+        XtRInt, (XtPointer) &defaultZERO},
+{XtNprinterCommand,XtCPrinterCommand, XtRString, sizeof(String),
+       XtOffsetOf(XtermWidgetRec, screen.printer_command),
+       XtRString, (XtPointer) "lpr"},
+{XtNprinterExtent,XtCPrinterExtent, XtRBoolean, sizeof(String),
+       XtOffsetOf(XtermWidgetRec, screen.printer_extent),
+       XtRBoolean, (XtPointer) &defaultFALSE},
+{XtNprinterFormFeed,XtCPrinterFormFeed, XtRBoolean, sizeof(String),
+       XtOffsetOf(XtermWidgetRec, screen.printer_formfeed),
+       XtRBoolean, (XtPointer) &defaultFALSE},
 {XtNmultiClickTime,XtCMultiClickTime, XtRInt, sizeof(int),
        XtOffsetOf(XtermWidgetRec, screen.multiClickTime),
        XtRInt, (XtPointer) &defaultMultiClickTime},
@@ -934,6 +956,12 @@
             int thischar = -1;
            c = doinput();
 
+           /* Intercept characters for printer controller mode */
+           if (screen->printer_controlmode == 2) {
+               if ((c = xtermPrinterControl(c)) == 0)
+                   continue;
+           }
+
            /* Accumulate string for APC, DCS, PM, OSC, SOS controls */
            if (parsestate == sos_table) {
                if (string_size == 0) {
@@ -1077,6 +1105,7 @@
                        /*
                         * form feed, line feed, vertical tab
                         */
+                       xtermAutoPrint(c);
                        Index(screen, 1);
                        if (term->flags & LINEFEED)
                                CarriageReturn(screen);
@@ -1607,7 +1636,12 @@
                        break;
 
                 case CASE_MC:
-                       /* FIXME: implement media control */
+                       xtermMediaControl(param[0], FALSE);
+                       parsestate = groundtable;
+                       break;
+
+                case CASE_DEC_MC:
+                       xtermMediaControl(param[0], TRUE);
                        parsestate = groundtable;
                        break;
 
@@ -2416,6 +2450,7 @@
                            /* mark that we had to wrap this line */
                            ScrnSetAttributes(screen, screen->cur_row, 0,
                                              LINEWRAPPED, LINEWRAPPED, 1);
+                           xtermAutoPrint('\n');
                            Index(screen, 1);
                            screen->cur_col = 0;
                            screen->do_wrap = 0;
@@ -2616,6 +2651,18 @@
                        else
                                screen->send_mouse_pos = 0;
                        break;
+               case 18:                /* DECPFF: print form feed */
+                       if(func == bitset)
+                               screen->printer_formfeed = ON;
+                       else
+                               screen->printer_formfeed = OFF;
+                       break;
+               case 19:                /* DECPEX: print extent */
+                       if(func == bitset)
+                               screen->printer_extent = ON;
+                       else
+                               screen->printer_extent = OFF;
+                       break;
                case 25:                /* DECTCEM: Show/hide cursor (VT200) */
                        if(func == bitset)
                                screen->cursor_set = ON;
@@ -3493,6 +3540,12 @@
    new->screen.highlight_selection = request->screen.highlight_selection;
    new->screen.always_highlight = request->screen.always_highlight;
    new->screen.pointer_cursor = request->screen.pointer_cursor;
+
+   new->screen.printer_command = request->screen.printer_command;
+   new->screen.printer_extent = request->screen.printer_extent;
+   new->screen.printer_formfeed = request->screen.printer_formfeed;
+   new->screen.printer_controlmode = request->screen.printer_controlmode;
+
    new->screen.input_eight_bits = request->screen.input_eight_bits;
    new->screen.output_eight_bits = request->screen.output_eight_bits;
    new->screen.control_eight_bits = request->screen.control_eight_bits;
Index: ctlseqs.ms
--- xterm-48+/ctlseqs.ms        Mon Jun 30 08:51:00 1997
+++ xterm-49/ctlseqs.ms Sun Aug 10 20:50:56 1997
@@ -526,7 +526,7 @@
   \*(Ps = \*1 \(-> Erase Above
   \*(Ps = \*2 \(-> Erase All
 .
-.IP \\*(Cs\\*(Ps\\*s\\*?\\*s\\*J
+.IP \\*(Cs\\*?\\*(Ps\\*s\\*J
 Erase in Display (DECSED)
   \*(Ps = \*0 \(-> Selective Erase Below (default)
   \*(Ps = \*1 \(-> Selective Erase Above
@@ -538,7 +538,7 @@
   \*(Ps = \*1 \(-> Erase to Left
   \*(Ps = \*2 \(-> Erase All
 .
-.IP \\*(Cs\\*(Ps\\*s\\*?\\*s\\*K
+.IP \\*(Cs\\*?\\*(Ps\\*s\\*K
 Erase in Line (DECSEL)
   \*(Ps = \*0 \(-> Selective Erase to Right (default)
   \*(Ps = \*1 \(-> Selective Erase to Left
@@ -600,6 +600,18 @@
   \*(Ps = \*4 \(-> Insert Mode (IRM)
   \*(Ps = \*2\*0 \(-> Automatic Newline (LNM)
 .
+.IP \\*(Cs\\*(Pm\\*s\\*i
+Media Copy (MC)
+  \*(Ps = \*0 \(-> Print screen (default)
+  \*(Ps = \*4 \(-> Turn off printer controller mode
+  \*(Ps = \*5 \(-> Turn on printer controller mode
+.
+.IP \\*(Cs\\*?\\*(Pm\\*s\\*i
+Media Copy (MC, DEC-specific)
+  \*(Ps = \*1 \(-> Print line containing cursor
+  \*(Ps = \*4 \(-> Turn off autoprint mode
+  \*(Ps = \*5 \(-> Turn on autoprint mode
+.
 .IP \\*(Cs\\*(Pm\\*s\\*l
 Reset Mode (RM)
   \*(Ps = \*4 \(-> Replace Mode (IRM)
@@ -667,7 +679,7 @@
   \*(Ps = \*6 \(-> Report Cursor Position (CPR) [row;column] as
 \*(Cs\*(Ir\*s\*;\*(Ic\*s\*R
 .
-.IP \\*(Cs\\*(Ps\\*s\\*?\\*n
+.IP \\*(Cs\\*?\\*(Ps\\*s\\*n
 Device Status Report (DSR, DEC-specific)
   \*(Ps = \*6 \(-> Report Cursor Position (CPR) [row;column] as
 \*(Cs\*?\*(Ir\*s\*;\*(Ic\*s\*R
@@ -749,6 +761,8 @@
   \*(Ps = \*8 \(-> Auto-repeat Keys (DECARM)
   \*(Ps = \*9 \(-> Send Mouse X & Y on button press.
 See the section \fBMouse Tracking\fP.
+  \*(Ps = \*1\*8 \(-> Print form feed (DECPFF)
+  \*(Ps = \*1\*9 \(-> Set print extent to full screen (DECPEX)
   \*(Ps = \*2\*5 \(-> Show Cursor (DECTCEM)
   \*(Ps = \*3\*8 \(-> Enter Tektronix Mode (DECTEK)
   \*(Ps = \*4\*0 \(-> Allow 80 \z\(<-\(-> 132 Mode
@@ -775,6 +789,8 @@
   \*(Ps = \*7 \(-> No Wraparound Mode (DECAWM)
   \*(Ps = \*8 \(-> No Auto-repeat Keys (DECARM)
   \*(Ps = \*9 \(-> Don't Send Mouse X & Y on button press
+  \*(Ps = \*1\*8 \(-> Don't print form feed (DECPFF)
+  \*(Ps = \*1\*9 \(-> Limit print to scrolling region (DECPEX)
   \*(Ps = \*2\*5 \(-> Hide Cursor (DECTCEM)
   \*(Ps = \*4\*0 \(-> Disallow 80 \z\(<-\(-> 132 Mode
   \*(Ps = \*4\*1 \(-> No \fImore\fP(1) fix (see \fIcurses\fP resource)
Index: print.c
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-49/print.c    Sun Aug 10 20:55:28 1997
@@ -0,0 +1,319 @@
+/*
+ * $XFree86:$
+ */
+
+/************************************************************
+
+Copyright 1997 by Thomas E. Dickey <dickey@clark.net>
+
+                        All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name(s) of the above copyright
+holders shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization.
+
+********************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <xtermcfg.h>
+#endif
+
+#include <stdio.h>
+
+#include "ptyx.h"
+#include "data.h"
+#include "xterm.h"
+
+#define SGR_MASK (BOLD|UNDERLINE|INVERSE)
+
+static void charToPrinter PROTO((int chr));
+static void printCursorLine PROTO((void));
+static void printLine PROTO((int row, int chr));
+static void printPage PROTO((void));
+static void send_CharSet PROTO((int row));
+static void send_SGR PROTO((unsigned attr));
+static void stringToPrinter PROTO((char * str));
+
+static FILE *Printer;
+
+static void printCursorLine()
+{
+       register TScreen *screen = &term->screen;
+       TRACE(("printCursorLine\n"))
+       printLine(screen->cur_row, '\n');
+}
+
+/*
+ * DEC's manual doesn't document whether trailing blanks are removed, or what
+ * happens with a line that is entirely blank.  This function prints the
+ * characters that xterm would allow as a selection (which may include blanks).
+ */
+static void printLine(row, chr)
+       int row;
+       int chr;
+{
+       register TScreen *screen = &term->screen;
+       Char *c = SCRN_BUF_CHARS(screen, row);
+       Char *a = SCRN_BUF_ATTRS(screen, row);
+       Char attr = *a & SGR_MASK;
+       int last = screen->max_col;
+
+       TRACE(("printLine(row=%d, chr=%d)\n", row, chr))
+
+       while (last > 0) {
+               if ((a[last-1] & CHARDRAWN) == 0)
+                       last--;
+               else
+                       break;
+       }
+       if (last) {
+               send_CharSet(row);      /* FIXME: is this needed? */
+               send_SGR(0);
+               while (last--) {
+                       if (((*a & SGR_MASK) != attr) && *c) {
+                               send_SGR(attr = (*a & SGR_MASK));
+                       }
+                       charToPrinter(*c ? *c : ' ');
+                       c++;
+                       a++;
+               }
+               send_SGR(0);
+       }
+       charToPrinter('\r');
+       charToPrinter(chr);
+}
+
+static void printPage()
+{
+       register TScreen *screen = &term->screen;
+       int top = screen->printer_extent ? 0 : screen->top_marg;
+       int bot = screen->printer_extent ? screen->max_row : screen->bot_marg;
+
+       TRACE(("printPage, rows %d..%d\n", top, bot))
+
+       while (top <= bot)
+               printLine(top++, '\n');
+       if (screen->printer_formfeed)
+               charToPrinter('\f');
+}
+
+static void send_CharSet(row)
+       int row;
+{
+#if OPT_DEC_CHRSET
+       register TScreen *screen = &term->screen;
+       char *msg = 0;
+
+       switch (SCRN_BUF_CSETS(screen, row)[0]) {
+       case CSET_SWL:
+               msg = "\033#5";
+               break;
+       case CSET_DHL_TOP:
+               msg = "\033#3";
+               break;
+       case CSET_DHL_BOT:
+               msg = "\033#4";
+               break;
+       case CSET_DWL:
+               msg = "\033#6";
+               break;
+       }
+       if (msg != 0)
+               stringToPrinter(msg);
+#endif /* OPT_DEC_CHRSET */
+}
+
+static void send_SGR(attr)
+       unsigned attr;
+{
+       char msg[80];
+       strcpy(msg, "\033[0");
+       if (attr & BOLD)
+               strcat(msg, ";1");
+       if (attr & UNDERLINE)
+               strcat(msg, ";2");
+       if (attr & INVERSE)     /* typo? DEC documents this as invisible */
+               strcat(msg, ";7");
+       strcat(msg, "m");
+       stringToPrinter(msg);
+}
+
+/*
+ * This implementation only knows how to write to a pipe.
+ */
+static void charToPrinter(chr)
+       int chr;
+{
+       static int initialized;
+       if (!initialized) {
+               register TScreen *screen = &term->screen;
+               Printer = popen(screen->printer_command, "w");
+               initialized++;
+       }
+       if (Printer != 0)
+               fputc(chr, Printer);
+}
+
+static void stringToPrinter(str)
+       char *str;
+{
+       while (*str)
+               charToPrinter(*str++);
+}
+
+/*
+ * This module implements the MC (Media Copy) and related printing control
+ * sequences for VTxxx emulation.  This is based on the description in the
+ * VT330/VT340 Programmer Reference Manual EK-VT3XX-TP-001 (Digital Equipment
+ * Corp., March 1987).
+ */
+void xtermMediaControl (param, private)
+       int param;
+       int private;
+{
+       register TScreen *screen = &term->screen;
+
+       TRACE(("MediaCopy param=%d, private=%d\n", param, private))
+
+       if (private) {
+               switch (param) {
+               case  1:
+                       printCursorLine();
+                       break;
+               case  4:
+                       screen->printer_controlmode = 0;
+                       TRACE(("Reset autoprint mode\n"))
+                       break;
+               case  5:
+                       screen->printer_controlmode = 1;
+                       TRACE(("Set autoprint mode\n"))
+                       break;
+               }
+       } else {
+               switch (param) {
+               case -1:
+               case  0:
+                       printPage();
+                       break;
+               case  4:
+                       screen->printer_controlmode = 0;
+                       TRACE(("Reset printer controller mode\n"))
+                       break;
+               case  5:
+                       screen->printer_controlmode = 2;
+                       TRACE(("Set printer controller mode\n"))
+                       break;
+               }
+       }
+}
+
+/*
+ * When in autoprint mode, the printer prints a line from the screen when you
+ * move the cursor off that line with an LF, FF, or VT character, or an
+ * autowrap occurs.  The printed line ends with a CR and the character (LF, FF
+ * or VT) that moved the cursor off the previous line.
+ */
+void xtermAutoPrint(chr)
+       int chr;
+{
+       register TScreen *screen = &term->screen;
+
+       if (screen->printer_controlmode == 1) {
+               TRACE(("AutoPrint %d\n", chr))
+               printLine(screen->cursor_row, chr);
+               if (Printer != 0)
+                       fflush(Printer);
+       }
+}
+
+/*
+ * When in printer controller mode, the terminal send received characters to
+ * the printer without displaying them on the screen. The terminal sends all
+ * characters and control sequences to the printer, except NUL, XON, XOFF, and
+ * the printer controller sequences.
+ *
+ * This function eats characters, returning 0 as long as it must buffer or
+ * divert to the printer.  We're only invoked here when in printer controller
+ * mode, and handle the exit from that mode.
+ */
+#define LB '['
+
+int xtermPrinterControl(chr)
+       int chr;
+{
+       register TScreen *screen = &term->screen;
+
+       static struct {
+               Char seq[5];
+               int active;
+       } tbl[] = {
+               { { CSI,     '5', 'i' }, 2 },
+               { { CSI,     '4', 'i' }, 0 },
+               { { ESC, LB, '5', 'i' }, 2 },
+               { { ESC, LB, '4', 'i' }, 0 },
+       };
+
+       static Char bfr[10];
+       static Size_t length;
+       Size_t n;
+
+       TRACE(("In printer:%d\n", chr))
+
+       switch (chr) {
+       case 0:
+       case 'Q' & 0x1f:
+       case 'S' & 0x1f:
+               return 0;       /* ignored by application */
+
+       case CSI:
+       case ESC:
+       case '[':
+       case '4':
+       case '5':
+       case 'i':
+               bfr[length++] = chr;
+               for (n = 0; n < sizeof(tbl)/sizeof(tbl[0]); n++) {
+                       Size_t len = strlen(tbl[n].seq);
+
+                       if (length == len
+                        && strcmp(bfr, tbl[n].seq) == 0) {
+                               screen->printer_controlmode = tbl[n].active;
+                               length = 0;
+                               return 0;
+                       } else if (len > length
+                        && strncmp(bfr, tbl[n].seq, length) == 0) {
+                               return 0;
+                       }
+               }
+               length--;
+
+               /* FALLTHRU */
+
+       default:
+               for (n = 0; n < length; n++)
+                       charToPrinter(bfr[n]);
+               bfr[0] = chr;
+               length = 1;
+               return 0;
+       }
+}
Index: ptyx.h
--- xterm-48+/ptyx.h    Tue Jul 29 15:13:30 1997
+++ xterm-49/ptyx.h     Sun Aug 10 19:18:03 1997
@@ -517,6 +517,11 @@
 #endif /* NO_ACTIVE_ICON */
        Cursor pointer_cursor;          /* pointer cursor in window     */
 
+       String printer_command;         /* pipe/shell command string    */
+       Boolean printer_extent;         /* print complete page          */
+       Boolean printer_formfeed;       /* print formfeed per function  */
+       int printer_controlmode;        /* 0=off, 1=auto, 2=controller  */
+
        /* Terminal fonts must be of the same size and of fixed width */
        XFontStruct     *fnt_norm;      /* normal font of terminal      */
        XFontStruct     *fnt_bold;      /* bold font of terminal        */
@@ -547,7 +552,7 @@
        int             scrolllines;    /* number of lines to button scroll */
        Boolean         scrollttyoutput; /* scroll to bottom on tty output */
        Boolean         scrollkey;      /* scroll to bottom on key      */
-       
+
        ScrnBuf         buf;            /* ptr to visible screen buf (main) */
        ScrnBuf         allbuf;         /* screen buffer (may include
                                           lines scrolled off top)      */
Index: terminfo
--- xterm-48+/terminfo  Tue Jul 29 15:13:30 1997
+++ xterm-49/terminfo   Sun Aug 10 21:07:36 1997
@@ -6,6 +6,7 @@
        am,
        bce,
        km,
+       mc5i,
        mir,
        msgr,
        xenl,
@@ -94,6 +95,9 @@
        knp=\E[6~,
        kpp=\E[5~,
        kslt=\E[4~,
+       mc0=\E[i, 
+       mc4=\E[4i,
+       mc5=\E[5i,
        meml=\El,
        memu=\Em,
        op=\E[39;49m,
Index: xterm.h
--- xterm-48+/xterm.h   Sun Jul  6 14:36:26 1997
+++ xterm-49/xterm.h    Sun Aug 10 16:22:53 1997
@@ -148,6 +148,11 @@
 extern void FlushLog PROTO((TScreen *screen));
 #endif
 
+/* print.c */
+extern int xtermPrinterControl PROTO((int chr));
+extern void xtermAutoPrint PROTO((int chr));
+extern void xtermMediaControl PROTO((int param, int private));
+
 /* screen.c */
 extern Bool non_blank_line PROTO((ScrnBuf sb, int row, int col, int len));
 extern ScrnBuf Allocate PROTO((int nrow, int ncol, Char **addr));
Index: xterm.man
--- xterm-48+/xterm.man Mon Jun 30 08:51:00 1997
+++ xterm-49/xterm.man  Sun Aug 10 20:28:27 1997
@@ -856,6 +856,34 @@
 .B "pointerShape (\fPclass\fB Cursor)"
 Specifies the name of the shape of the pointer.  The default is ``xterm.''
 .TP 8
+.B "printerControlMode (\fPclass\fB PrinterControlMode)"
+Specifies the printer control mode.
+A ``1'' selects autoprint mode, which causes
+.I xterm
+to print a line from the screen when you move the cursor off that
+line with a line feed, form feed or vertical tab character, or an
+autowrap occurs.
+Autoprint mode is overridden by printer controller mode (a ``2''),
+which causes all of the output to be directed to the printer.
+The default is ``0.''
+.TP 8
+.B "printerCommand (\fPclass\fB PrinterCommand)"
+Specifies a shell command to which
+.I xterm
+will open a pipe when the first
+MC (Media Copy) command is initiated.
+The default is ``lpr.''
+.TP 8
+.B "printerExtent (\fPclass\fB PrinterExtent)"
+Controls whether a print page function will print the entire page (true), or
+only the the portion within the scrolling margins (false).
+The default is ``false.''
+.TP 8
+.B "printerFormFeed (\fPclass\fB PrinterFormFeed)"
+Controls whether a form feed is sent to the printer at the end of a print
+page function.
+The default is ``false.''
+.TP 8
 .B "dynamicColors (\fPclass\fB DynamicColors)"
 Specifies whether or not dynamic modification of colors using the escape
 sequence is allowed.