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.