home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ckmcon.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  79KB  |  2,947 lines

  1. /* $Id: ckmcon.c,v 1.8 91/12/27 21:43:15 fdc Exp $
  2.  * $Source: /uw/mackermit/RCS/ckmcon.c,v $
  3.  *------------------------------------------------------------------
  4.  * $Log:    ckmcon.c,v $
  5.  * Revision 1.8  91/12/27  21:43:15  fdc
  6.  * Change fatal to macfatal, make all lines less than 80 chars wide.
  7.  * 
  8.  * Revision 1.7  91/12/15  23:16:49  rick
  9.  * ut9
  10.  * 
  11.  * Revision 1.6  91/10/13  13:43:10  rick
  12.  * UT(7)
  13.  * 
  14.  * Revision 1.5  91/10/01  12:16:18  rick
  15.  * UT(5)
  16.  * 
  17.  * Revision 1.4  91/09/25  12:16:40  rick
  18.  * Command window in TE. Multiple vt100 windows for command window.
  19.  * 
  20.  * Revision 1.3  91/09/12  21:50:36  rick
  21.  * UT(3). Install on watsun
  22.  * 
  23.  * Revision 1.2  1991/09/10  22:21:39  rick
  24.  * Update to UTexas(2)
  25.  *
  26.  * Revision 1.1  1991/09/10  19:17:47  rick
  27.  * Initial revision
  28.  *
  29.  *------------------------------------------------------------------
  30.  * $Endlog$
  31.  */
  32. /*
  33.   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
  34.   York.  Permission is granted to any individual or institution to use this
  35.   software as long as it is not sold for profit.  This copyright notice must be
  36.   retained.  This software may not be included in commercial products without
  37.   written permission of Columbia University.
  38. */
  39. /*
  40.   John A. Oberschelp for Emory University
  41.   vt102 printer support 22 May 1989
  42. */
  43. /* Emory contact is Peter W. Day, ospwd@emoryu1.cc.emory.edu */
  44. /* Paul Placeway, Ohio State -- added option to flashing cursor, made */
  45. /*  key macros use Pascal strings, so that a NUL (0x00) can be sent */
  46. /* Enhanced by Clayton M. Elwell, Ohio State University 24 Nov 1987 -- */
  47. /*  added insert character */
  48. /* Matthias Aebi, ECOFIN Research and Consulting, Ltd., Oct 1987 -- */
  49. /*  ported to MPW, changed the way keys work */
  50. /* Version 0.8(35) - Jim Noble at Planning Research Corporation, June 1987. */
  51. /* Ported to Megamax native Macintosh C compiler. */
  52. /* From: DPVC@UORDBV.BITNET */
  53. /* DPVC at U of R, Oct 1, add blinking cursor and mouse cursor movement */
  54. /* DPVC at U of R, Sept. 26, fixed book-keeping for scrolling and inserting */
  55. /*  characters and lines */
  56. /* DPVC at U of R, Sept. 25, to fix cursor positioning off the screen, and */
  57. /*  a few other, minor VT100 incompatibilities */
  58. /* DPVC at the University of Rochester, Sept. 9, to add Block Cursor and */
  59. /*  ability to do VT100 graphics characters */
  60. /* By CAM2 and DPVC at the University of Rochester on Sept 6, */
  61. /*  changed bolding from using TextStyle attributes to using a separate bold */
  62. /*  font */
  63. /* By fdc June 20 1984 - Add parity to all outbound chars using software */
  64. /*  Also, ignore DEL (0177) characters on input. */
  65. /* By Bill Schilit on May 29 1984 - Add Key set translation */
  66. /* By Bill Catchings (WBC3) on Apr 24 - Add ^^, ^@ and ^_.  Also use Pascal */
  67. /*  strings for output in the terminal emulator */
  68. /* By WBC3 on Apr 23 - Add query terminal and be more fastidious about */
  69. /*  ignoring sequences we don't know about */
  70. /* By WBC3 on Apr 22 - Fix tab stops to conform to the rest of the world! */
  71. /* By Bill on Apr 21 - Fix immediate echo problems. */
  72. /*  do less cursor_erase, cursor_draw stuff */
  73.  
  74. /*
  75.  * FILE ckmcon.c
  76.  *
  77.  * Module of mackermit: contains code for the terminal emulation
  78.  * routine.  PWP: This file contains the stuff to deal with parsing for
  79.  * a vt??? terminal.  For Macintosh screen handling things, see
  80.  * ckmco2.c.
  81.  */
  82.  
  83. #include "ckcdeb.h"
  84.  
  85. #include "ckmdef.h"
  86. #include "ckmasm.h"        /* Assembler code */
  87. #include "ckmres.h"        /* kermit resources */
  88.  
  89. #include "ckmcon.h"        /* defines, etc. for terminal emulator */
  90. #include "ckcasc.h"
  91. #include "ckmptp.h"        /* ckm* Prototypes */
  92. #include "ckmwin.h"        /* text edit window structures */
  93.  
  94. /* Tab settings */
  95.  
  96. /*
  97.   (UoR) do tapstops via an array: 0 means no tab, 1 means tab at that column.
  98. */
  99. /* (PWP) Tabbing bug fixed by Eamonn McManus <emcmanus@csvax1.tcd.ie> */
  100. /* (PWP) remember that a tab is set by "tabstops[curcol] = 1", and curcol
  101.    is zero-based */
  102. char tabstops[MAXCOL + 1] = {
  103.     0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
  104.     1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
  105.     1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
  106.     1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
  107.     1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
  108.     1
  109. };
  110.  
  111. struct termw *ttermw;            /* terminal window */
  112. struct termw *ctermw;            /* command window */
  113. struct termw *termwl = NULL;        /* list of termw */
  114.  
  115. extern int connected;
  116. extern int escape;
  117.  
  118. char *querystring = ANS_VT100AVO;    /* Answer we are a VT100 with AVO */
  119.  /* (UoR) used to be VT102 */
  120. char *reportstring = "\033[0n";    /* (UoR) report that we're OK */
  121. char *noprinter = "\033[?13n";    /* (UoR) report no printer */
  122.  
  123. extern Boolean have_128roms;    /* true if we are a Plus or better */
  124.  
  125. /* Screen book keeping variables */
  126. /*
  127.  * (PWP) Note that in order to support scroll back, we do things a bit
  128.  * differently than before.  There is no linked list of lines (it doesn't
  129.  * take all that much time to just copy the pointers around), and the
  130.  * indexing in scr is done BACKWARDS (0 is the bottom line) since if we
  131.  * shrink the window, we want to see the bottom most part.
  132.  *
  133.  * Doing this makes the handling of scrolling regions a bit tricky, but
  134.  * it was so allready so this isn't much worse.
  135.  */
  136.  
  137. /*****************************************/
  138.  
  139. /* extern CSParam controlparam; */
  140. extern unsigned char dopar ();
  141.  
  142. /* Terminal function declarations. */
  143.  
  144. extern    int        to_printer;        /*JAO*/
  145. extern    int        to_screen;        /*JAO*/
  146. extern    int        printer_is_on_line_num;    /*JAO*/
  147. #ifdef COMMENT
  148. extern    Handle    hPrintBuffer;            /*JAO*/
  149. extern    long    lPrintBufferSize;        /*JAO*/
  150. extern    long    lPrintBufferChars;        /*JAO*/
  151. extern    long    lPrintBufferAt;            /*JAO*/
  152. #endif /* COMMENT */
  153. extern    DialogPtr    bufferingDialog;    /*JAO*/
  154. extern    DialogPtr    overflowingDialog;    /*JAO*/
  155.  
  156. extern    MenuHandle menus[];    /* handle on our menus */  /*JAO*/
  157.  
  158. /* pointer to function returning void, taking a termw pointer as the argument */
  159. typedef void (*PFV_termwP) (struct termw *termw);
  160.  
  161. /* Terminal control character function command table. */
  162.  
  163. #define MIN_CTRL 000
  164. #define MAX_CTRL 037
  165.  
  166. PFV_termwP ctrl_table[MAX_CTRL - MIN_CTRL + 1] =
  167. {
  168.     dummy,            /* 0 (NUL) */
  169.     dummy,            /* 1 */
  170.     dummy,            /* 2 */
  171.     dummy,            /* 3 */
  172.     dummy,            /* 4 */
  173.     dummy,            /* 5 (send answerback DON'T DO THIS!!!) */
  174.     dummy,            /* 6 */
  175.     bell,            /* 7 */
  176.     back_space,            /* 10 */
  177.     tab,            /* 11 */
  178.     line_feed,            /* 12 */
  179.     line_feed,            /* 13 (Vertical tab) */
  180.     line_feed,            /* 14 (Form feed) */
  181.     carriage_return,        /* 15 */
  182.     control_N,            /* 16 (graphic set 1) *//* (UoR) */
  183.     control_O,            /* 17 (graphic set 0) *//* (UoR) */
  184.     dummy,            /* 20 */
  185.     dummy,            /* 21 ("XOFF") */
  186.     dummy,            /* 22 */
  187.     dummy,            /* 23 ("XON") */
  188.     dummy,            /* 24 */
  189.     dummy,            /* 25 */
  190.     dummy,            /* 26 */
  191.     dummy,            /* 27 */
  192.     norm_char,            /* 30 (CAN) */
  193.     dummy,            /* 31 */
  194.     norm_char,            /* 32 (SUB) */
  195.     escape_seq,            /* 33 (Escape) */
  196.     dummy,            /* 34 */
  197.     dummy,            /* 35 */
  198.     dummy,            /* 36 */
  199.     dummy            /* 37 */
  200. };
  201.  
  202.  
  203.  
  204. #define MIN_META 0200
  205. #define MAX_META 0237
  206.  
  207. PFV_termwP meta_table[MAX_META - MIN_META + 1] =
  208. {
  209.     dummy,            /* 200 */
  210.     dummy,            /* 201 */
  211.     dummy,            /* 202 */
  212.     dummy,            /* 203 */
  213.     line_feed,            /* 204 (index) */
  214.     line_feed,            /* 205 (next line) */
  215.     dummy,            /* 206 */
  216.     dummy,            /* 207 */
  217.     set_tab,            /* 210 */
  218.     dummy,            /* 211 */
  219.     dummy,            /* 212 */
  220.     dummy,            /* 213 */
  221.     dummy,            /* 214 */
  222.     reverse_line_feed,        /* 215 */
  223.     single_shift_2,        /* 216 */
  224.     single_shift_3,        /* 217 */
  225.     dcs_seq,            /* 220 */
  226.     dummy,            /* 221 */
  227.     dummy,            /* 222 */
  228.     dummy,            /* 223 */
  229.     dummy,            /* 224 */
  230.     dummy,            /* 225 */
  231.     dummy,            /* 226 */
  232.     dummy,            /* 227 */
  233.     dummy,            /* 230 */
  234.     dummy,            /* 231 */
  235.     dummy,            /* 232 */
  236.     csi_seq,            /* 233 */
  237.     norm_char,            /* 234 (String Terminator) */
  238.     toss_till_st,        /* 235 (Operating System Command) */
  239.     toss_till_st,        /* 236 (Privacy Message) */
  240.     toss_till_st        /* 237 (Applications Prog. Command) */
  241. };
  242.  
  243.  
  244.  
  245.  
  246. #define MIN_ESC        0060
  247. #define MAX_ESC        0177
  248.  
  249. PFV_termwP esc_table[MAX_ESC - MIN_ESC + 1] =
  250. {
  251.     dummy,            /* 60 '0' */
  252.     dummy,            /* 61 '1' */
  253.     dummy,            /* 62 '2' */
  254.     line_dblh_top,        /* 63 '3' */
  255.     line_dblh_bot,        /* 64 '4' */
  256.     line_singw,            /* 65 '5' */
  257.     line_dblw,            /* 66 '6' */
  258.     cursor_save,        /* 67 '7' */
  259.     cursor_restore,        /* 70 '8' */
  260.     dummy,            /* 71 '9' */
  261.     dummy,            /* 72 */
  262.     dummy,            /* 73 */
  263.     dummy,            /* 74 '<' */
  264.     set_appl,            /* 75 '=' */
  265.     reset_appl,            /* 76 '>' */
  266.     dummy,            /* 77 */
  267.     dummy,            /* 100 */
  268.     dummy,            /* 101 */
  269.     dummy,            /* 102 */
  270.     dummy,            /* 103 */
  271.     line_feed,            /* 104 'D' */
  272.     new_line,            /* 105 'E' *//* (UoR) */
  273.     start_selected,        /* 106 'F' */
  274.     end_selected,        /* 107 'G' */
  275.     set_tab,            /* 110 'H' *//* (UoR) */
  276.     dummy,            /* 111 */
  277.     dummy,            /* 112 */
  278.     dummy,            /* 113 */
  279.     dummy,            /* 114 */
  280.     reverse_line_feed,        /* 115 'M' */
  281.     single_shift_2,        /* 116 'N' */
  282.     single_shift_3,        /* 117 'O' */
  283.     dcs_seq,            /* 120 'P' */
  284.     dummy,            /* 121 */
  285.     dummy,            /* 122 */
  286.     dummy,            /* 123 */
  287.     dummy,            /* 124 */
  288.     dummy,            /* 125 */
  289.     dummy,            /* 126 */
  290.     dummy,            /* 127 */
  291.     dummy,            /* 130 */
  292.     dummy,            /* 131 */
  293.     query_terminal,        /* 132 'Z' */
  294.     csi_seq,            /* 133 '[' */
  295.     string_term,        /* 134 '\' */
  296.     toss_till_st,        /* 135 ']' */
  297.     toss_till_st,        /* 136 '^' */
  298.     toss_till_st,        /* 137 '_' */
  299.     dummy,            /* 140 */
  300.     dummy,            /* 141 */
  301.     dummy,            /* 142 */
  302.     term_reset,            /* 143 'c' */
  303.     dummy,            /* 144 */
  304.     dummy,            /* 145 */
  305.     dummy,            /* 146 'f' */
  306.     dummy,            /* 147 'g' */
  307.     dummy,            /* 150 'h' */
  308.     dummy,            /* 151 'i' */
  309.     dummy,            /* 152 */
  310.     dummy,            /* 153 */
  311.     dummy,            /* 154 'l' */
  312.     dummy,            /* 155 'm' */
  313.     lock_shift_2,        /* 156 'n' */
  314.     lock_shift_3,        /* 157 */
  315.     dummy,            /* 160 'p' */
  316.     dummy,            /* 161 'q' */
  317.     dummy,            /* 162 'r' */
  318.     dummy,            /* 163 */
  319.     dummy,            /* 164 */
  320.     dummy,            /* 165 */
  321.     dummy,            /* 166 */
  322.     dummy,            /* 167 */
  323.     dummy,            /* 170 */
  324.     dummy,            /* 171 */
  325.     dummy,            /* 172 */
  326.     dummy,            /* 173 */
  327.     lock_shift_3r,        /* 174 '|' */
  328.     lock_shift_2r,        /* 175 '}' */
  329.     lock_shift_1r,        /* 176 '~' */
  330.     dummy            /* 177 */
  331. };
  332.  
  333.  
  334.  
  335.  
  336. /* Terminal escape sequence function command table */
  337.  
  338. #define MIN_CSI 0100
  339. #define MAX_CSI 0177
  340.  
  341. PFV_termwP csi_table[MAX_CSI - MIN_CSI + 1] =
  342. {
  343.     insert_chars,        /* 100 *//* CME */
  344.     cursor_up,            /* 101 'A' */
  345.     cursor_down,        /* 102 'B' */
  346.     cursor_right,        /* 103 'C' */
  347.     cursor_left,        /* 104 'D' */
  348.     dummy,            /* 105 */
  349.     cursor_h_pos,        /* 106 'F' */
  350.     dummy,            /* 107 */
  351.     cursor_position,        /* 110 'H' (PWP) */
  352.     dummy,            /* 111 */
  353.     erase_display,        /* 112 'J' */
  354.     clear_line,            /* 113 'K' */
  355.     insert_line,        /* 114 'L' */
  356.     delete_line,        /* 115 'M' */
  357.     dummy,            /* 116 */
  358.     dummy,            /* 117 */
  359.     delete_char,        /* 120 'P' */
  360.     dummy,            /* 121 */
  361.     dummy,            /* 122 */
  362.     dummy,            /* 123 */
  363.     dummy,            /* 124 */
  364.     dummy,            /* 125 */
  365.     dummy,            /* 126 */
  366.     dummy,            /* 127 */
  367.     dummy,            /* 130 */
  368.     dummy,            /* 131 */
  369.     dummy,            /* 132 */
  370.     dummy,            /* 133 */
  371.     dummy,            /* 134 */
  372.     dummy,            /* 135 */
  373.     dummy,            /* 136 */
  374.     dummy,            /* 137 */
  375.     dummy,            /* 140 */
  376.     dummy,            /* 141 */
  377.     dummy,            /* 142 */
  378.     query_terminal,        /* 143 'c' */
  379.     dummy,            /* 144 */
  380.     dummy,            /* 145 */
  381.     cursor_position,        /* 146 'f' */
  382.     clear_tab,            /* 147 'g' *//* (UoR) */
  383.     insert_mode,        /* 150 'h' */
  384.     printer_control,        /* 151 'i' *//*JAO*/
  385.     dummy,            /* 152 */
  386.     dummy,            /* 153 */
  387.     end_insert_mode,        /* 154 'l' */
  388.     text_mode,            /* 155 'm' */
  389.     request_report,        /* 156 'n' *//* (UoR) */
  390.     dummy,            /* 157 */
  391.     set_compat,            /* 160 'p' (PWP) */
  392.     set_charattr,        /* 161 'q' (PWP) */
  393.     set_scroll_region,        /* 162 'r' */
  394.     dummy,            /* 163 */
  395.     dummy,            /* 164 */
  396.     dummy,            /* 165 */
  397.     dummy,            /* 166 */
  398.     dummy,            /* 167 */
  399.     dummy,            /* 170 */
  400.     dummy,            /* 171 */
  401.     dummy,            /* 172 */
  402.     dummy,            /* 173 */
  403.     dummy,            /* 174 */
  404.     dummy,            /* 175 */
  405.     dummy,            /* 176 */
  406.     dummy            /* 177 */
  407. };
  408.  
  409. #ifdef COMMENT        /* not done yet */
  410.  
  411. #define MINVT52ESCS 0040
  412. #define MAXVT52ESCS 0137
  413.  
  414. PFV_termwP vt52table[MAXVT52ESCS - MINVT52ESCS + 1] =
  415. {
  416.     dummy,            /* 40 */
  417.     dummy,            /* 41 */
  418.     dummy,            /* 42 */
  419.     dummy,            /* 43 '#' */
  420.     dummy,            /* 44 */
  421.     dummy,            /* 45 */
  422.     dummy,            /* 46 */
  423.     dummy,            /* 47 */
  424.     dummy,            /* 50 '(' */
  425.     dummy,            /* 51 ')' */
  426.     dummy,            /* 52 */
  427.     dummy,            /* 53 */
  428.     dummy,            /* 54 */
  429.     dummy,            /* 55 */
  430.     dummy,            /* 56 */
  431.     dummy,            /* 57 */
  432.     dummy,            /* 60 */
  433.     dummy,            /* 61 */
  434.     dummy,            /* 62 */
  435.     dummy,            /* 63 */
  436.     dummy,            /* 64 */
  437.     dummy,            /* 65 */
  438.     dummy,            /* 66 */
  439.     cursor_save,        /* 67 '7' */
  440.     cursor_restore,        /* 70 '8' */
  441.     dummy,            /* 71 */
  442.     dummy,            /* 72 */
  443.     dummy,            /* 73 */
  444.     vt320_mode,            /* 74 '<' */
  445.     set_appl,            /* 75 '=' */
  446.     reset_appl,            /* 76 '>' */
  447.     dummy,            /* 77 */
  448.     dummy,            /* 100 */
  449.     cursor_up,            /* 101 'A' */
  450.     cursor_down,        /* 102 'B' */
  451.     cursor_right,        /* 103 'C' */
  452.     cursor_left,        /* 104 'D' */
  453.     clear_screen,        /* 105 'E' */
  454.     h19_graph_mode,        /* 106 */
  455.     end_h19graph_mode,        /* 107 */
  456.     home_cursor,        /* 110 'H' */
  457.     reverse_line_feed,        /* 111 'I' */
  458.     clear_eop,            /* 112 'J' */
  459.     clear_eol,            /* 113 'K' */
  460.     insert_line,        /* 114 'L' */
  461.     delete_line,        /* 115 'M' */
  462.     delete_char,        /* 116 'N' */
  463.     end_insert_mode,        /* 117 'O' */
  464.     dummy,            /* 120 */
  465.     dummy,            /* 121 */
  466.     dummy,            /* 122 */
  467.     dummy,            /* 123 */
  468.     dummy,            /* 124 */
  469.     dummy,            /* 125 */
  470.     print_cur_line,        /* 126 'V' */
  471.     start_printing,        /* 127 'W' */
  472.     end_printing,        /* 130 'X' */
  473.     h19_cursor_position,    /* 131 'Y' */
  474.     query_terminal,        /* 132 'Z' */
  475.     csi_seq,            /* 133 '[' */
  476.     dummy,            /* 134 */
  477.     dummy,            /* 135 */
  478.     dummy,            /* 136 */
  479.     dummy            /* 137 */
  480. };
  481.  
  482. #endif /* COMMENT */
  483.  
  484. static unsigned char char_map[128];    /* holds the current translation tbl */
  485.  
  486. static unsigned char nat_remaps[13][12] = {
  487. /* USA (ASCII) proper */
  488.   {  '#',  '@',  '[', '\\',  ']',  '^',  '_',  '`',  '{',  '|',  '}',  '~' },
  489. /* UK */
  490.   { 0xA3,  '@',  '[', '\\',  ']',  '^',  '_',  '`',  '{',  '|',  '}',  '~' },
  491. /* Dutch */
  492.   { 0xA3, 0xBE, 0xFF, 0xBD,  '|',  '^',  '_',  '`', 0xA8,  'f', 0xBC, 0xB4 },
  493. /* Finnish */
  494.   {  '#',  '@', 0xC4, 0xD6, 0xC5, 0xDC,  '_', 0xE9, 0xE4, 0xF6, 0xE5, 0xFC },
  495. /* French */
  496.   { 0xA3, 0xE0, 0xB0, 0xE7, 0xA7,  '^',  '_',  '`', 0xE9, 0xF9, 0xE8, 0xA8 },
  497. /* French Canadian */
  498.   {  '#', 0xE0, 0xE2, 0xE7, 0xEA, 0xEE,  '_', 0xF4, 0xE9, 0xF9, 0xE8, 0xFB },
  499. /* German */
  500.   {  '#', 0xA7, 0xC4, 0xD6, 0xDC,  '^',  '_',  '`', 0xE4, 0xF6, 0xFC, 0xDF },
  501. /* Italian */
  502.   { 0xA3, 0xA7, 0xB0, 0xE7, 0xE9,  '^',  '_', 0xF9, 0xE0, 0xF2, 0xE8, 0xEC },
  503. /* Norwegian/Danish */
  504.   {  '#',  '@', 0xC6, 0xD8, 0xC5,  '^',  '_',  '`', 0xE6, 0xF8, 0xE5,  '~' },
  505. /* Portuguese */
  506.   {  '#',  '@', 0xC3, 0xC7, 0xD5,  '^',  '_',  '`', 0xE3, 0xE7, 0xF5,  '~' },
  507. /* Spanish */
  508.   { 0xA3, 0xA7, 0xA1, 0xD1, 0xBF,  '^',  '_',  '`',  '`', 0xB0, 0xF1, 0xE7 },
  509. /* Swedish */
  510.   {  '#', 0xC9, 0xC4, 0xD6, 0xC5, 0xDC,  '_', 0xE9, 0xE4, 0xF6, 0xE5, 0xFC },
  511. /* Swiss */
  512.   { 0xF9, 0xE0, 0xE9, 0xE7, 0xEA, 0xEE, 0xE8, 0xF4, 0xE4, 0xF6, 0xFC, 0xFB }
  513. };
  514.  
  515.  
  516. static struct {
  517.     unsigned char fnum;
  518.     unsigned char coffset;
  519.     unsigned char lbound;
  520.     unsigned char hbound;
  521. } vt_to_fmap[] = {
  522.     {0,    0,    ' ',    127},    /* US ASCII */
  523.     {0,    0,    0,    0},    /* unassigned */
  524.     {0,    32,    '`',    127},    /* DEC VT100 graphics */
  525.     {1,    0,    ' ',    127},    /* DEC VT300 technical font */
  526.     {0,    128,    ' ',    127},    /* DEC International font (almost 8859/1 */
  527.     {0,    128,    ' ',    128},    /* ISO Latin 1 */
  528.     {2,    0,    ' ',    128},    /* ISO Latin 2 */
  529.     {2,    128,    ' ',    128},    /* ISO Latin 3 */
  530.     {3,    0,    ' ',    128},    /* ISO Latin 4 */
  531.     {4,    0,    ' ',    128},    /* ISO Latin/Cyrilic */
  532.     {4,    128,    ' ',    128},    /* ISO Latin/Arabic */
  533.     {5,    0,    ' ',    128},    /* ISO Latin/Greek */
  534.     {5,    128,    ' ',    128},    /* ISO Latin/Hebrew */
  535.     {3,    128,    ' ',    128}    /* ISO Latin 5 */
  536. };
  537.  
  538. /****************************************************************************/
  539. /* Input and process all the characters pending on the tty line */
  540. /****************************************************************************/
  541. inpchars (struct termw *termw)
  542. {
  543.     register int rdcnt, i;
  544.     unsigned char buf[1024];
  545.     GrafPtr savePort;
  546.     
  547.     if (termw->curlin < 0 || termw->curlin >= termw->screensize)
  548.     macfatal("inpchars(): termw->curlin out of bounds:", termw->curlin);
  549.     /* can be == when termw->autowraping */
  550.     if (termw->curcol < 0 || termw->curcol > MAXCOL)
  551.     macfatal("inpchars(): termw->curcol out of bounds:", termw->curcol);
  552.     if (termw->display_topline < 
  553.     (termw->screensize - MAX_SCREENSIZE) || termw->display_topline > 0)
  554.     macfatal("inpchars(): termw->display_topline out of bounds:", 
  555.           termw->display_topline);
  556.  
  557.     /*
  558.      * If there are any characters to get and draw, do so.
  559.      */
  560.     if (ttchk() > 0) {
  561.     GetPort (&savePort);
  562.     SetPort (termw->window);
  563.     
  564.     cursor_erase (termw);        /* remove cursor from screen */
  565.     screen_to_bottom(termw);  /* slide the visible region to active area */
  566.  
  567.     for (i = 0; i < 6; i++) {
  568.         rdcnt = ttinm((char *) buf, sizeof(buf));
  569.  
  570.         if (rdcnt <= 0)
  571.         break;
  572.  
  573.         printem (termw, buf, rdcnt);
  574.     }
  575.  
  576.     /*
  577.      * allways update the screen after up to 6 tries at getting some data
  578.      * and drawing it to the screen.  This will give a slightly better
  579.      * feel, because of less delay in some cases, and will be self-metering
  580.      * anyway because if we update "too soon" one time, the next time we
  581.      * will have more pending characters to draw, so efficiency is
  582.      * maintained.
  583.      */
  584.     if (termw->scroll_amount)
  585.         flushscroll(termw);        /* sync the screen */
  586.     if (termw->out_maxcol) 
  587.         flushbuf(termw);        /* Flush any remaining characters */
  588.     cursor_draw(termw);        /* put it back */
  589.     update_vscroll(termw);
  590.  
  591.     SetPort (savePort);
  592.     }
  593.  
  594. }                /* inpchars */
  595.  
  596. /*
  597.  * updatecommand
  598.  * Update the command window.
  599.  */
  600. updatecommand (struct termw *termw)
  601. {
  602.     Boolean changed;
  603.     GrafPtr savePort;
  604.  
  605.     if (!termw)
  606.     macfatal("updatecommand() called with term == NULL", 0);
  607.  
  608.     GetPort (&savePort);
  609.     SetPort (termw->window);
  610.     
  611.     changed = FALSE;
  612.     if (termw->scroll_amount || termw->out_maxcol) {
  613.     changed = TRUE;
  614.     screen_to_bottom(termw);  /* slide the visible region to active area */
  615.     }
  616.  
  617.     if (termw->scroll_amount) 
  618.     flushscroll(termw);        /* sync the screen */
  619.     if (termw->out_maxcol) 
  620.     flushbuf(termw);        /* Flush any remaining characters */
  621.  
  622.     /* if (changed) */        /* PWP: why only if changed??? */
  623.     cursor_draw(termw);        /* put it back */
  624.     update_vscroll(termw);
  625.  
  626.     SetPort (savePort);
  627. }
  628.  
  629.  
  630. /****************************************************************************/
  631. /*
  632.  * (UoR)
  633.  *
  634.  * Print a PASCAL string to the screen (used to echo function and meta strings
  635.  * in duplex mode).
  636.  *
  637.  */
  638. /****************************************************************************/
  639. printps (struct termw *termw, StringPtr s)
  640. {
  641.     long w2;
  642.  
  643.     cursor_erase(termw);
  644.  
  645.     w2 = *s++;            /* get count */
  646.  
  647. #ifdef COMMENT
  648.     for (s2 = s; w2 > 0; w2--, s2++)
  649.     printit (*s2);        /* print it out, and perform special
  650.                  * functions */
  651. #endif
  652.  
  653.     printem (termw, s, w2);
  654.     
  655.     if (termw->scroll_amount) 
  656.     flushscroll(termw);    /* sync the screen */
  657.     if (termw->out_maxcol) 
  658.     flushbuf(termw);
  659.  
  660.     cursor_draw(termw);
  661.     return;
  662. }                /* printps */
  663.  
  664.  
  665. /****************************************************************************/
  666. /*
  667.  *   MLookup:
  668.  *      Lookup a given character in the apropriate character table, and
  669.  *      return a pointer to the appropriate function, if it exists.
  670.  */
  671. /****************************************************************************/
  672. PFV_termwP mlookup (unsigned char index, PFV_termwP table[], int min, int max)
  673. {
  674.     if (index > max || index < min)
  675.     return ((PFV_termwP) NULL);    /* Don't index out of range */
  676.     return (table[index - min]);
  677. }                /* lookup */
  678.  
  679. /* tie off the current numeric argument */
  680.  
  681. void end_numarg (struct termw *termw)
  682. {
  683.     long lnum = 0;    /* can't be register */
  684.  
  685.     if (termw->argcount < MAX_ARGCOUNT) {
  686.     /* bounds */
  687.     if (termw->argptr > termw->paramarg[termw->argcount] + NUMBUFSIZ - 1)
  688.         termw->argptr = termw->paramarg[termw->argcount] + NUMBUFSIZ - 1;
  689.     *termw->argptr = '\0';        /* tie off parameter argument */
  690.  
  691.     if (termw->numptr > termw->numbuf + NUMBUFSIZ - 1)
  692.         termw->numptr = termw->numbuf + NUMBUFSIZ - 1;    /* bounds */
  693.     *termw->numptr = '\0';        /* tie off number string */
  694.     if (termw->numptr > termw->numbuf) {    /* if we had a number collected */
  695.         c2pstr(termw->numbuf);
  696.         StringToNum (termw->numbuf, &lnum);    /* Translate the numbers */
  697.         if (lnum < 0) lnum = 0;
  698.         if (lnum > 9999) lnum = 9999;    /* ANSI says between 0 and 9999 */
  699.     } else {
  700.         lnum = 0;
  701.     }
  702.     termw->numarg[termw->argcount++] = lnum;
  703.     }
  704.     termw->argptr = termw->paramarg[termw->argcount];    /* Go to next number */
  705.     termw->numptr = termw->numbuf;            /* reset buffer */
  706. }
  707.  
  708. #undef PREADJUST_HACK
  709. #ifdef PREADJUST_HACK
  710. /****************************************************************************/
  711. /*
  712.  *  preadjust_for_linefeeds:
  713.  *      Counts how many linefeeds are in the current buffers worth of data,
  714.  *    and scrolls the screen far enough to account for all of them.
  715.  */
  716. /****************************************************************************/
  717. void
  718. preadjust_for_linefeeds (struct termw *termw, register unsigned char *buf,
  719.              register int count)
  720. {
  721.     register unsigned char c;
  722.     register unsigned char *cp;
  723.     register int i;
  724.     register int num_linefeeds;
  725.  
  726.     if (termw->smoothscroll)
  727.         return;        /* don't do this if smooth scrolling */
  728.     
  729.     /*
  730.      * Scan for how many line feeds we do in this batch
  731.      */
  732.     num_linefeeds = 0;
  733.     for (cp = buf, i = 0; i < count; i++) {
  734.     c = *cp++;
  735.     if (c == '\012') {
  736.         num_linefeeds++;
  737.     } else if (c && (c != '\015') && (c != '\0177')
  738.            && (!(c & 0x60) || (c & 0x80))) {
  739.            /* if c is a control or meta char, quit */
  740.         break;
  741.     }
  742.     }
  743.     
  744.     i = termw->curlin + num_linefeeds - termw->scrbot;
  745.     if (i > (termw->curlin - 1)) i = termw->curlin - 1;
  746.     if (i > 0) {
  747.     /* scroll lines up */
  748.     scroll_screen (termw, termw->scrtop, termw->scrbot, -(i));
  749.     termw->curlin -= i;    /* readjust curlin to reflect the prescroll */
  750.     }
  751. }
  752. #endif /* PREADJUST_HACK */
  753.  
  754.  
  755. /****************************************************************************/
  756. /*
  757.  *  Printem:
  758.  *      Draws character and updates buffer
  759.  */
  760. /****************************************************************************/
  761. printem (struct termw *termw, register unsigned char *buf, register int count)
  762. {
  763.     register unsigned char c;
  764.     register unsigned char *cp;
  765.     register int n;
  766.     register PFV_termwP funp;
  767.     GrafPtr savePort;
  768.  
  769.     GetPort (&savePort);
  770.     SetPort (termw->window);
  771.  
  772. #ifdef PREADJUST_HACK
  773.     preadjust_for_linefeeds (termw, buf, count);
  774. #endif /* PREADJUST_HACK */
  775.  
  776.     if (termw->cur_drawn)
  777.     cursor_erase(termw);
  778.  
  779.     while (count-- > 0) {
  780.     c = *buf++;
  781.         
  782.     if (!termw->eightbit_disp)
  783.         c &= 0177;
  784.     
  785.     if ((c == 0) || (c == 0177))           /* ignore null characters */
  786.         continue;
  787.         
  788.     /* (PWP) Acording to vttest, vt100 series terminals will
  789.        do control characters in the middle of an escape sequence.
  790.        ick!. */
  791.     /* If it's a control char, do the apropriate function. */
  792.  
  793.     if ((c & 0x60) == 0) {         /* if control or meta-control character */
  794.         if (termw->dispcontchar) {        /* this is counter-intuitive */
  795.         if (c >= 0x80) {
  796.             if (funp = mlookup (c, meta_table, MIN_META, MAX_META))
  797.             (*funp) (termw); /* Do escape sequence function */
  798.         } else {
  799.             if (funp = mlookup (c, ctrl_table, MIN_CTRL, MAX_CTRL))
  800.             (*funp) (termw); /* Do escape sequence function */
  801.         }
  802.         
  803.         continue;
  804.         
  805.         } else {        /* if (!termw->dispcontchar) */
  806.         MDrawChars(termw, buf-1, 1);    /* draw the control character */
  807.         /* if (termw->out_maxcol) flushbuf(termw); */
  808.         if (c == '\012')
  809.             new_line(termw);
  810.         continue;
  811.         }
  812.     }    /* end if control */
  813.     
  814.     switch (termw->charflg) {
  815.  
  816. #ifdef COMMENT
  817.       case CF_OUTC:    /* Just output the char */
  818.         MDrawChar(termw,c);
  819.         break;
  820. #endif /* COMMENT */
  821.  
  822.       case CF_OUTC:    /* ordinary character */
  823.         /*
  824.          * Since most of the wierd things we do to characters are constant
  825.          * for a given run of characters, we find out how many characters
  826.          * we can do as a batch and do all of them.
  827.          */
  828.         buf--;    /* backup to this character again */
  829.         count++;
  830.         cp = buf;    /* save start of run */
  831.         n = count;
  832.         /* Don't tell MDrawChars to draw more than will fit on a line */
  833.         if (n > (MAXCOL - termw->curcol))
  834.             n = (MAXCOL - termw->curcol);
  835.         if (n <= 0)
  836.             n = 1;        /* sanity bounds check */
  837.  
  838.         while (--n >= 0) {
  839.             c = *buf;
  840.         if (!(c & 0x60) || (c == '\177'))    /* if a C or M-C character */
  841.             break;
  842.         buf++;
  843.         }
  844.  
  845.         /* buf now points to the first character we cannot handle */
  846.         MDrawChars (termw, cp, (buf - cp));
  847.         count -= (buf - cp);    /* adjust count */
  848.         break;
  849.  
  850.       case CF_ESC:    /* In a single char escape seq */
  851.         if ((termw->intermedptr < termw->intermedbuf)
  852.         || (termw->intermedptr > &termw->intermedbuf[NUMBUFSIZ - 1]))
  853.         {
  854.         printerr ("intermedptr out of range:",
  855.               (int)termw->intermedptr);
  856.         termw->intermedptr = termw->intermedbuf;
  857.         }
  858.         /*
  859.          * (PWP) Quoting from the DEC VT300 manual:
  860.          *
  861.          *    ESC    I            F
  862.          *    1/11    2/0 to 2/15        3/0 to 7/14
  863.          *        (Zero or more        (One character)
  864.          *        characters)
  865.          */
  866.         /* (PWP) A hack for now, until I rework the char set handling */
  867.         if (c == '(')
  868.         graphic_G0(termw);
  869.         else if (c == ')' || c == '-')
  870.         graphic_G1(termw);
  871.         else if (c == '*' || c == '.')
  872.         graphic_G2(termw);
  873.         else if (c == '+' || c == '/')
  874.         graphic_G3(termw);
  875.         else 
  876.         
  877.         if (c >= 0x20 && c <= 0x2F) {
  878.         if (termw->intermedptr < &termw->intermedbuf[NUMBUFSIZ - 1])
  879.             *termw->intermedptr++ = c;    /* Add the char to the num */
  880.         } else if (c >= 0x30) {
  881.         termw->charflg = CF_OUTC; /* Reset flag to simple outputting */
  882.         *termw->intermedptr = '\0';
  883.         if (funp = mlookup (c, esc_table, MIN_ESC, MAX_ESC))
  884.             (*funp) (termw);    /* Do escape sequence function */
  885.         }
  886.         break;
  887.  
  888.       case CF_GS_0:    /* (UoR) process graphic characters */
  889.       case CF_GS_1:
  890.       case CF_GS_2:    /* PWP: for vt200 mode */
  891.       case CF_GS_3:
  892.         if (c >= 0x20 && c < 0x30) {    /* Deal with the modifiers */
  893.         if (termw->intermedptr < &termw->intermedbuf[NUMBUFSIZ - 1])
  894.             *termw->intermedptr++ = c;    /* Add the char to the num */
  895.         } else {
  896.         *termw->intermedptr = '\0';
  897.         /* (this uses termw->charflg to select which set) */    
  898.         set_char_set(termw, c);
  899.         /* Reset flag for next character */
  900.         termw->charflg = CF_OUTC;
  901.         }
  902.         break;
  903.  
  904.       case CF_CSI:    /* Multichar escape sequence */
  905.       case CF_DCS:    /* device control string sequence */
  906.         if ((termw->intermedptr < termw->intermedbuf) || 
  907.         (termw->intermedptr > &termw->intermedbuf[NUMBUFSIZ - 1])) {
  908.         printerr ("termw->intermedptr out of range:", 
  909.               (int)termw->intermedptr);
  910.         termw->intermedptr = termw->intermedbuf;
  911.         }
  912.         if ((termw->argptr < termw->paramarg[termw->argcount]) || 
  913.         (termw->argptr
  914.          > &termw->paramarg[termw->argcount][NUMBUFSIZ - 1])) {
  915.         printerr ("termw->argptr out of range:", (int)termw->argptr);
  916.         termw->argptr = termw->paramarg[termw->argcount];
  917.         }
  918.         if ((termw->numptr < termw->numbuf) || 
  919.         (termw->numptr > &termw->numbuf[NUMBUFSIZ - 1])) {
  920.         printerr ("termw->numptr out of range:", (int)termw->numptr);
  921.         termw->numptr = termw->numbuf;
  922.         }
  923.         /*
  924.          * (PWP) Also quoting from the DEC VT300 manual 
  925.          * (orignal NOTE: in italics):
  926.          *
  927.          *    CSI    P...P        I...I        F
  928.          *    ESC [    3/0 to 3/15    2/0 to 2/15    4/0 to 7/14
  929.          *
  930.          *    NOTE: All parameters muyst be positive decimal integers.
  931.          *    Do not use a decimal point in a parameter -- the termial will
  932.          *    ignore the command.
  933.          *
  934.          *    If the first character in a parameter string is the ? (3/15)
  935.          *    character, it indicates that DEC private parameters follow.
  936.          *    The terminal interprets private parameters according to 
  937.          * ANSI X3.64 and ISO 6429.
  938.          */
  939.         if (c >= 0x30 && c < 0x40) {    /* Deal with the modifiers */
  940.          if ((c == '0') && (termw->numptr == termw->numbuf)) {
  941.             /* ignore the leading zero */
  942.         } else if (c >= '0' && c <= '9') {
  943.             if (termw->numptr < &termw->numbuf[NUMBUFSIZ - 1])
  944.             *termw->numptr++ = c;    /* Add the char to the num */
  945.         } else if (c == ';') {
  946.             end_numarg(termw);
  947.         } else {
  948.             if (termw->argptr
  949.             < &termw->paramarg[termw->argcount][NUMBUFSIZ - 1])
  950.             {
  951.             /* Add the char to the parameter list */
  952.             *termw->argptr++ = c;
  953.             }
  954.         }
  955.         } else if (c >= 0x20 && c < 0x30) {           /* Intermediate chars */
  956.         /* (PWP) intermeadiate chars go in the termw->intermedbuf[] */
  957.         
  958.         end_numarg(termw);    /* tie off numeric argument */
  959.  
  960.         if (termw->intermedptr < &termw->intermedbuf[NUMBUFSIZ - 1])
  961.             *termw->intermedptr++ = c;    /* Add the char to the num */
  962.             
  963.         } else if (c >= 0x40) {        /* End of sequence */
  964.         termw->charflg = CF_OUTC;    /* Back to simple outputting */
  965.         if (funp = mlookup (c, csi_table, MIN_CSI, MAX_CSI)) {
  966.             /* if we didn't just do this */
  967.             if (termw->intermedptr == termw->intermedbuf)
  968.             end_numarg(termw);    /* tie off numeric argument */
  969.             *termw->intermedptr = '\0';    /* tie off intermediate */
  970.             (*funp) (termw);    /* Do the escape sequence function */
  971.         }
  972.         }
  973.         break;
  974.  
  975.       case CF_TOSS:    /* Ignore this char */
  976.         termw->charflg = CF_OUTC;    /* Reset flag */
  977.         break;
  978.         
  979.       case CF_T_ST:        /* (PWP) toss till String Terminator */
  980.         break;
  981.     }
  982.     }        /* end while (count-- >= 0) */
  983.  
  984.     SetPort (savePort);
  985. }                /* printem */
  986.  
  987. set_char_set (struct termw *termw, unsigned char c)
  988. {
  989.     int ninetysix = 0;        /* are we talking about a 96 char. set */
  990.     int set = termw->charflg - CF_GS_0;    /* which slot are we talking about? */
  991.     
  992.     if (set > 3) {
  993.     set -= 4;
  994.     ninetysix = 1;
  995.     }
  996.     
  997.     if (!termw->nat_char_mode) {    /* if doing 8859 international sets */
  998.         if (!ninetysix) {    /* 94 character set */
  999.         switch(c) {
  1000.           case '1':        /* ALT ROM set (we claim ASCII) */
  1001.         termw->graphicsinset[set] = ASCII_SET;
  1002.         break;
  1003.  
  1004.           case '5':
  1005.         if (termw->intermedbuf[0] == '%')
  1006.                 /* DEC supplimental graphic */
  1007.             termw->graphicsinset[set] = GRAF_SET;    /* for now */
  1008.         break;
  1009.  
  1010.           case '0':
  1011.           case '2':
  1012.         termw->graphicsinset[set] = GRAF_SET;
  1013.         break;
  1014.  
  1015.           case '>':
  1016.         termw->graphicsinset[set] = TECH_SET;
  1017.         break;
  1018.  
  1019.           case 'A':
  1020.         termw->graphicsinset[set] = ASCII_SET;
  1021.             break;
  1022.  
  1023.           case '<':        /* DEC user-prefered supplemental set */
  1024.         termw->graphicsinset[set] = GRAF_SET;
  1025.         break;
  1026.  
  1027.           case 'B':        /* Allways ASCII half of an ISO set */
  1028.         termw->graphicsinset[set] = ASCII_SET;
  1029.             break;
  1030.  
  1031.         } /* end switch(c) */
  1032.     } else {        /* 96 character set */
  1033.         switch(c) {
  1034.           case '1':        /* ALT ROM set (we claim ASCII) */
  1035.         termw->graphicsinset[set] = ASCII_SET;
  1036.         break;
  1037.  
  1038.           case '<':        /* DEC user-prefered supplemental set */
  1039.         termw->graphicsinset[set] = GRAF_SET;
  1040.         break;
  1041.  
  1042.           case 'A':
  1043.         termw->graphicsinset[set] = LAT1_SET;
  1044.         break;
  1045.  
  1046. #ifdef COMMENT
  1047.           case 'B':
  1048.         termw->graphicsinset[set] = LAT2_SET;
  1049.         break;
  1050.  
  1051.           case 'C':
  1052.         termw->graphicsinset[set] = LAT3_SET;
  1053.         break;
  1054.  
  1055.           case 'D':
  1056.         termw->graphicsinset[set] = LAT4_SET;
  1057.         break;
  1058.  
  1059.           case 'L':
  1060.         termw->graphicsinset[set] = LATCYR_SET;
  1061.         break;
  1062.  
  1063.           case '*':    /* we don't know what this should be yet */
  1064.         termw->graphicsinset[set] = LATARAB_SET;
  1065.         break;
  1066.  
  1067.           case 'F':
  1068.         termw->graphicsinset[set] = LATGREEK_SET;
  1069.         break;
  1070.  
  1071.           case 'H':
  1072.         termw->graphicsinset[set] = LATHEBREW_SET;
  1073.         break;
  1074.  
  1075.           case 'M':
  1076.         termw->graphicsinset[set] = LAT5_SET;
  1077.         break;
  1078. #endif
  1079.         } /* end switch(c) */
  1080.     } /* end if (ninetysix) */
  1081.  
  1082.     } else {            /* if in national character set mode */
  1083.     switch (c) {
  1084.  
  1085.  /* the first set of these don't actually change the national mapping */
  1086.  
  1087.       case '0':
  1088.       case '2':
  1089.         termw->graphicsinset[set] = GRAF_SET;
  1090.         return;    /* don't change national mapping */
  1091.  
  1092.       case '>':
  1093.         termw->graphicsinset[set] = TECH_SET;
  1094.         return;    /* don't change national mapping */
  1095.  
  1096.  /* the rest of these do change the national mapping */
  1097.  
  1098.       case 'B':
  1099.       case '1':
  1100.         termw->nat_set = USA_NAT;
  1101.         break;
  1102.  
  1103.       case 'A':
  1104.         termw->nat_set = UK_NAT;
  1105.         break;
  1106.         
  1107.       case '4':
  1108.         termw->nat_set = DUTCH_NAT;
  1109.         break;
  1110.         
  1111.       case 'C':
  1112.       case '5':
  1113.         termw->nat_set = FINNISH_NAT;
  1114.         break;
  1115.  
  1116.       case 'R':
  1117.         termw->nat_set = FRENCH_NAT;
  1118.         break;
  1119.         
  1120.       case '9':
  1121.       case 'Q':
  1122.         termw->nat_set = FRENCHCAN_NAT;
  1123.         break;
  1124.         
  1125.       case 'K':
  1126.         termw->nat_set = GERMAN_NAT;
  1127.         break;
  1128.         
  1129.       case 'Y':
  1130.         termw->nat_set = ITALIAN_NAT;
  1131.         break;
  1132.  
  1133.       case '6':
  1134.         if (termw->intermedbuf[0] == '%') {
  1135.         termw->nat_set = PORTUGUESE_NAT;
  1136.         break;
  1137.         }
  1138.         /* else fall through to norwegian */
  1139.       case '`':
  1140.       case 'E':
  1141.         termw->nat_set = NORWEGIAN_NAT;
  1142.         break;                /* also Danish */
  1143.  
  1144.       case 'Z':
  1145.         termw->nat_set = SPANISH_NAT;
  1146.         break;
  1147.  
  1148.       case '7':
  1149.       case 'H':
  1150.         termw->nat_set = SWEDISH_NAT;
  1151.         break;
  1152.  
  1153.       case '=':
  1154.         termw->nat_set = SWISS_NAT;
  1155.         break;
  1156.     } /* end switch(c) */
  1157.     termw->graphicsinset[set] = ASCII_SET;
  1158.     set_char_map(termw);
  1159.     }
  1160. }
  1161.  
  1162. set_char_map (struct termw *termw)
  1163. {
  1164.     register int i;
  1165.     
  1166.     for (i = 0; i < 128; i++)    /* reset the character remapping map */
  1167.         char_map[i] = (unsigned char) i;
  1168.     if (termw->nat_char_mode) {
  1169.     /* set the values for the national map */
  1170.     char_map['#'] = nat_remaps[termw->nat_set][0];
  1171.     char_map['@'] = nat_remaps[termw->nat_set][1];
  1172.     char_map['['] = nat_remaps[termw->nat_set][2];
  1173.     char_map['\\'] = nat_remaps[termw->nat_set][3];
  1174.     char_map[']'] = nat_remaps[termw->nat_set][4];
  1175.     char_map['^'] = nat_remaps[termw->nat_set][5];
  1176.     char_map['_'] = nat_remaps[termw->nat_set][6];
  1177.     char_map['`'] = nat_remaps[termw->nat_set][7];
  1178.     char_map['{'] = nat_remaps[termw->nat_set][8];
  1179.     char_map['|'] = nat_remaps[termw->nat_set][9];
  1180.     char_map['}'] = nat_remaps[termw->nat_set][10];
  1181.     char_map['~'] = nat_remaps[termw->nat_set][11];
  1182.     }
  1183. }
  1184.  
  1185.  
  1186. /****************************************************************************
  1187.  * draw a characer on the screen (or buffer it) 
  1188.  * draw a bunch of characters on the screen (or at least lay them down on the
  1189.  * screen buffer and increment various pointers so we can draw them later).
  1190.  *
  1191.  * Assumes that we can draw all the given characters from where we are now
  1192.  * without overflowing the right edge of the screen (though we might write
  1193.  * up TO the right edge).  We only do wrap checks and stuff AFTER adding the
  1194.  * characters to the screen buffer.
  1195.  ****************************************************************************/
  1196. void
  1197. MDrawChars(struct termw *termw, register unsigned char *cp, int n)
  1198. {
  1199. /*
  1200.     while (--n >= 0)
  1201.         MDrawChar(termw, *cp++);
  1202. */
  1203.  
  1204.     register int cset;
  1205.     register unsigned char chr;
  1206.     
  1207.     if (n <= 0)            /* sanity, just in case */
  1208.         return;
  1209.  
  1210.     /* Are we about to wrap around? */
  1211.     if (termw->curcol >= MAXCOL) {
  1212.     if (termw->autowrap) {    /* If autowrap indicated wrap */
  1213.         if (!termw->newline)
  1214.         carriage_return(termw);
  1215.         line_feed(termw);
  1216.     } else {
  1217.         back_space(termw);    /* Otherwise just overwrite */
  1218.         cp += n-1;        /* setup to only print the last character */
  1219.         n = 1;
  1220.     }
  1221.     }
  1222.     
  1223.     if (termw->old_Gl_set >= 0) {    /* are we doing a single shift? */
  1224.     int old = termw->old_Gl_set;    /* save old Gl_set */
  1225.     termw->old_Gl_set = -1;        /* don't trigger this code recursively */
  1226.     MDrawChars (termw, cp, 1);    /* call ourselves to do this character */
  1227.     cp++;
  1228.     n--;
  1229.     termw->Gl_set = old;        /* restore old Gl_set */
  1230.     if (n <= 0)            /* if that was it, we are finished */
  1231.             return;
  1232.     }
  1233.     
  1234.     if ((termw->out_maxcol == 0) || (termw->out_mincol > termw->curcol))
  1235.     termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/
  1236.  
  1237.     if (termw->insert) {        /* Insert mode? */
  1238.     termw->numarg[0] = n;
  1239.     insert_chars(termw);        /* Open hole for char if requested */
  1240.     }
  1241.  
  1242.     while (--n >= 0) {
  1243.         chr = *cp++;
  1244.  
  1245.     if (chr & 0x80)        /* if a right-side (meta) character */
  1246.     {
  1247.         if (termw->eightbit_disp)
  1248.         cset = termw->Gr_set;    /*  in the GR character set */
  1249.         else
  1250.         cset = termw->Gl_set;    /* in the GL character set */
  1251.         chr &= 0177;        /* trim to 7 bits */
  1252.     } else {
  1253.         cset = termw->Gl_set;    /* in the GL character set */
  1254.     }
  1255.  
  1256.     if ((termw->nat_char_mode)
  1257.         || (termw->graphicsinset[cset] != ASCII_SET)) {
  1258.         if ((termw->nat_char_mode)
  1259.         && (termw->graphicsinset[cset] == ASCII_SET)) {
  1260.         chr = char_map[chr];
  1261.         termw->textstyle &= STY_STY;    /* reset to ASCII */
  1262.         } else {
  1263.         if  ((chr >= vt_to_fmap[termw->graphicsinset[cset]].lbound) &&
  1264.              (chr <= vt_to_fmap[termw->graphicsinset[cset]].hbound)) {
  1265.             chr += vt_to_fmap[termw->graphicsinset[cset]].coffset;
  1266.             termw->textstyle = (termw->textstyle & STY_STY)
  1267.             | (vt_to_fmap[termw->graphicsinset[cset]].fnum) << 4;
  1268.         } else {
  1269.             termw->textstyle &= STY_STY;    /* reset to ASCII */
  1270.         }
  1271.         }
  1272.     }
  1273.     
  1274.     /* PWP: an inline version of: buf_char (chr); */
  1275.     termw->scr[termw->curlin][termw->curcol] = chr;
  1276.     termw->scr_attrs[termw->curlin][termw->curcol] = 
  1277.         (unsigned char) termw->textstyle;
  1278.     termw->curcol++;
  1279.     }
  1280.  
  1281.     /* Update the maximum of pending characters to reflect these ones */
  1282.     if (termw->out_maxcol < termw->curcol)
  1283.     termw->out_maxcol = termw->curcol;    /* count up one more char */
  1284. }
  1285.  
  1286. #ifdef COMMENT
  1287. /****************************************************************************
  1288.  * draw a characer on the screen (or buffer it) 
  1289.  *
  1290.  * ----------> WARNING WARNING WARNING!!!  <-----------
  1291.  * If you change any of the if conditions that affect how a character is
  1292.  * drawn, you must also change the appropriate ifs in the CF_OUTC case
  1293.  * of printem(), since it incestiously knows about how this routine works
  1294.  ****************************************************************************/
  1295. void MDrawChar(struct termw *termw, register unsigned char chr)
  1296. {
  1297.     /* register PFV_termwP funp; */
  1298.     register int cset = termw->Gl_set;
  1299.  
  1300.     if (chr & 0x80)        /* if a right-side (meta) character */
  1301.     {
  1302.     cset = termw->Gr_set;    /*  then we are in the GR character set */
  1303.     chr &= 0177;        /* trim to 7 bits */
  1304.     }
  1305.     
  1306.     if (termw->old_Gl_set >= 0) {    /* are we doing a single shift? */
  1307.     termw->Gl_set = termw->old_Gl_set;
  1308.     termw->old_Gl_set = -1;
  1309.     }
  1310.     
  1311.     if ((termw->nat_char_mode) && (termw->graphicsinset[cset] == ASCII_SET)) {
  1312.     chr = char_map[chr];
  1313.     termw->textstyle &= STY_STY;    /* reset to ASCII */
  1314.     } else {
  1315.     if  ((chr >= vt_to_fmap[termw->graphicsinset[cset]].lbound) &&
  1316.          (chr <= vt_to_fmap[termw->graphicsinset[cset]].hbound)) {
  1317.         chr += vt_to_fmap[termw->graphicsinset[cset]].coffset;
  1318.         termw->textstyle = (termw->textstyle & STY_STY) |
  1319.             (vt_to_fmap[termw->graphicsinset[cset]].fnum) << 4;
  1320.     } else {
  1321.         termw->textstyle &= STY_STY;    /* reset to ASCII */
  1322.     }
  1323.     }
  1324.  
  1325.     if (termw->curcol >= MAXCOL) {    /* Are we about to wrap around? */
  1326.     if (termw->autowrap) {    /* If autowrap indicated wrap */
  1327.         if (termw->newline == FALSE)
  1328.         carriage_return(termw);
  1329.         line_feed(termw);
  1330.     } else {
  1331. #ifdef COMMENT
  1332.         if (termw->scroll_amount) 
  1333.         flushscroll(termw);    /* sync the screen */
  1334.         if (termw->out_maxcol) 
  1335.         flushbuf(termw);    /* make sure last char is shown */
  1336. #endif /* COMMENT */
  1337.         back_space(termw);    /* Otherwise just overwrite */
  1338.     }
  1339.     }
  1340.     
  1341.     if (termw->insert)            /* Insert mode? */
  1342.     insert_char(termw);        /* Open hole for char if requested */
  1343.     
  1344.     /* PWP: an inline version of: buf_char (chr); */
  1345.     if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol)
  1346.     termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/
  1347.     if (termw->out_maxcol <= termw->curcol)
  1348.     termw->out_maxcol = termw->curcol + 1;    /* count up one more char */
  1349.     
  1350.     termw->scr[termw->curlin][termw->curcol] = chr;
  1351.     termw->scr_attrs[termw->curlin][termw->curcol] = 
  1352.     (unsigned char) termw->textstyle;
  1353.     termw->curcol++;
  1354.  
  1355.     /*
  1356.      * Partial hack to handle double width characters.  Add a space
  1357.      * after the real character. If it works,
  1358.      * will need to add code to handle insert mode, wraparound, etc.
  1359.      */
  1360.     if (termw->dblw) {
  1361.     if (termw->insert)        /* Insert mode? */
  1362.         insert_char(termw);        /* Open hole for char if requested */
  1363.         
  1364.     /* PWP: an inline version of: buf_char (chr); */
  1365.     if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol)
  1366.         /* No chars in buffer, init column*/
  1367.         termw->out_mincol = termw->curcol;
  1368.     if (termw->out_maxcol <= termw->curcol)
  1369.         /* count up one more char */
  1370.         termw->out_maxcol = termw->curcol + 1;
  1371.     
  1372.     termw->scr[termw->curlin][termw->curcol] = ' ';
  1373.     termw->scr_attrs[termw->curlin][termw->curcol] = 
  1374.         (unsigned char) termw->textstyle;
  1375.     termw->curcol++;
  1376.     }
  1377. }                /* MDrawChar */
  1378. #endif /* COMMENT */
  1379.  
  1380.  
  1381. /****************************************************************************/
  1382. /*
  1383.  *      Control character functions:
  1384.  *              Each of the following allow the mac to simulate
  1385.  *              the behavior of a terminal when given the proper
  1386.  *              control character.
  1387.  */
  1388. /****************************************************************************/
  1389.  
  1390. void back_space (struct termw *termw)
  1391. {
  1392.     if (termw->curcol > 0)
  1393.     relmove(termw,-1, 0);
  1394. }                /* back_space */
  1395.  
  1396.  
  1397. void erase_char (struct termw *termw)
  1398. {
  1399.     termw->scr[termw->curlin][termw->curcol] = ' ';    /* Erase char for update */
  1400.     termw->scr_attrs[termw->curlin][termw->curcol] = 0; /* no attributes */
  1401.  
  1402.     if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol)
  1403.     termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/
  1404.     if (termw->out_maxcol <= termw->curcol)
  1405.     termw->out_maxcol = termw->curcol + 1; /* count up one more char */
  1406.  
  1407. }                /* erase_char */
  1408.  
  1409.  
  1410. void tab (struct termw *termw)
  1411. {
  1412.     int i;
  1413.  
  1414.     /* (UoR) find next tabstop */
  1415.     i = termw->curcol + 1;
  1416.     while ((i < MAXCOL) && (tabstops[i] == 0))
  1417.         i++;
  1418.     absmove(termw,i, termw->curlin);
  1419. }                /* tab */
  1420.  
  1421.  
  1422. /* PWP: if you change this, also change MDrawChar() above */
  1423. void line_feed (struct termw *termw)
  1424. {
  1425.     if (to_printer) {                /*JAO*/
  1426.     if (termw->out_maxcol) 
  1427.         flushbuf(termw);        /* just in case */
  1428.  
  1429. #ifdef COMMENT
  1430.     (*hPrintBuffer)[lPrintBufferAt++] = 13;
  1431.     if (lPrintBufferAt == lPrintBufferSize)
  1432.         lPrintBufferAt = 0L;
  1433.     if (lPrintBufferChars == 1L)
  1434.         updatepstat();
  1435.     lPrintBufferChars++;
  1436.     if (lPrintBufferChars == lPrintBufferSize) {
  1437.         overflowingDialog =
  1438.           GetNewDialog(OVERFLOWINGBOXID, NILPTR, (WindowPtr) - 1);
  1439.         DrawDialog(overflowingDialog);
  1440.     }
  1441. #endif /* COMMENT */
  1442.  
  1443.     add_to_print (1, "\015");        /* a return character */
  1444.     }
  1445.     
  1446.     if (!to_screen)
  1447.     return;
  1448.     
  1449.     /* (PWP) A better place to log the session */
  1450.     if (seslog)            /* if logging is active then */
  1451.     slog ((char *) termw->scr[termw->curlin], MAXCOL);
  1452.                 /* write line to session log */
  1453.  
  1454.     if (termw->newline)
  1455.     absmove(termw,0, termw->curlin);
  1456.                 /* (UoR) perform termw->newline function */
  1457.  
  1458.     if (termw->curlin == termw->scrbot) {
  1459.     scroll_screen(termw, termw->scrtop, termw->scrbot, -1);
  1460.                 /* scroll lines up */
  1461.     } else {
  1462.     if (termw->curlin >= termw->scrtop) /* if within scrolling region */
  1463.         relmove(termw,0, 1);
  1464.     }
  1465. }                /* line_feed */
  1466.  
  1467.  
  1468. void reverse_line_feed (struct termw *termw)
  1469. {
  1470.     if (termw->curlin == termw->scrtop) {
  1471.     /* scroll down in region */
  1472.     scroll_screen(termw,termw->scrtop, termw->scrbot, 1);
  1473.     } else {
  1474.     if (termw->curlin <= termw->scrbot)   /* if within scrolling region */
  1475.         relmove(termw,0, -1);
  1476.     }
  1477. }                /* reverse_line_feed */
  1478.  
  1479.  
  1480.  
  1481. /* PWP: if you change this, also change MDrawChar() above */
  1482. void carriage_return (struct termw *termw)
  1483. {
  1484.     if (termw->newline)
  1485.     line_feed(termw);      /* (UoR) perform termw->newline function */
  1486.     else
  1487.     absmove(termw,0, termw->curlin);
  1488. }                /* carriage_return */
  1489.  
  1490.  
  1491. void new_line (struct termw *termw)
  1492. {
  1493.     carriage_return(termw);
  1494.     line_feed(termw);
  1495. }                /* new_line */
  1496.  
  1497. void clear_screen (struct termw *termw)
  1498. {
  1499.     register int i;
  1500.     Rect r;
  1501.  
  1502.     if (termw->scroll_amount) 
  1503.     flushscroll(termw);        /* sync the screen */
  1504.     if (termw->out_maxcol) 
  1505.     flushbuf(termw);        /* just in case */
  1506.  
  1507.     makerect(termw,&r, 0, 0, termw->screensize, MAXCOL); /* The whole screen */
  1508.     EraseRect (&r);
  1509.  
  1510.     for (i = 0; i < termw->screensize; i++) /* (PWP) clear from bottom up */
  1511.     zeroline(termw, i, 1);    /* Clear up the update records */
  1512. }                /* clear_screen */
  1513.  
  1514. void push_clear_screen (struct termw *termw)
  1515. {
  1516.     register int i, j, tlin;
  1517.     unsigned char *savedline, *savedattr;  /* temporary to hold screen line pointer */
  1518.  
  1519.     termw->display_totlines += termw->screensize;
  1520.     if (termw->display_totlines > MAX_SCREENSIZE)
  1521.     termw->display_totlines = MAX_SCREENSIZE; /* bounds */
  1522.     
  1523.     /* top of saved buffer */
  1524.     tlin = termw->screensize - termw->display_totlines; 
  1525.     
  1526.     /* save cleared lines on scrollback buffer */
  1527.     for (j = 0; j < termw->screensize; j++) {
  1528.     /* scroll screen buffer by one line */
  1529.      savedline = termw->scr[tlin];
  1530.     savedattr = termw->scr_attrs[tlin];
  1531.     for (i = tlin+1; i <= botlin; i++) {
  1532.             termw->scr[i-1] = termw->scr[i];
  1533.             termw->scr_attrs[i-1] = termw->scr_attrs[i];
  1534.     }
  1535.     termw->scr[botlin] = savedline;
  1536.     termw->scr_attrs[botlin] = savedattr;
  1537.     }
  1538.     clear_screen(termw);
  1539. }
  1540.  
  1541. void vt_align (struct termw *termw)
  1542. {
  1543.     register int l, c;
  1544.     
  1545.     if (termw->scroll_amount) 
  1546.     flushscroll(termw);    /* sync the screen */
  1547.     if (termw->out_maxcol) 
  1548.     flushbuf(termw);        /* just in case */
  1549.     
  1550.     for (l = 0; l < termw->screensize; l++) {
  1551.     absmove(termw,0, l);
  1552.     termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/
  1553.     for (c = 0; c < MAXCOL; c++) {
  1554.         termw->scr[l][c] = 'E';
  1555.         termw->scr_attrs[l][c] = 0;
  1556.     }
  1557.     termw->out_maxcol = MAXCOL;    /* Mark output buffer full */
  1558.     flushbuf(termw);
  1559.     }
  1560.     absmove(termw,0, 0);
  1561. }
  1562.  
  1563.  
  1564. void home_cursor (struct termw *termw)
  1565. {
  1566.     if (termw->relorigin)
  1567.     absmove(termw,0, termw->scrtop);
  1568.     else
  1569.     absmove(termw,0, 0);        /* (UoR) correct for relative origin */
  1570. }                /* home_cursor */
  1571.  
  1572.  
  1573. void bell (struct termw *termw)
  1574. {
  1575.     Rect r;
  1576.  
  1577.     if (termw->visible_bell) {
  1578.     makerect(termw,&r, 0, 0, termw->screensize, MAXCOL);
  1579.                 /* The whole screen */
  1580.     InvertRect (&r);
  1581.     waitnoinput ();        /* sleep for a bit (1/30 sec) */
  1582.     InvertRect (&r);
  1583.     } else {
  1584.     SysBeep (3);
  1585.     }
  1586. }                /* bell */
  1587.  
  1588.  
  1589. /****************************************************************************/
  1590. /* does nothing. */
  1591. /****************************************************************************/
  1592. void dummy (struct termw *termw)
  1593. {
  1594. #pragma unused (termw)
  1595. }                /* dummy */
  1596.  
  1597. void toss_char (struct termw *termw)
  1598. {
  1599.     termw->charflg = CF_TOSS;
  1600. }                /* toss_char */
  1601.  
  1602. void toss_till_st (struct termw *termw)
  1603. {
  1604.     termw->charflg = CF_T_ST;
  1605. }
  1606.  
  1607. void norm_char (struct termw *termw)
  1608. {
  1609.     termw->charflg = CF_OUTC;
  1610. }
  1611.  
  1612. void norm_home_clear_save(struct termw *termw)
  1613. {
  1614.     norm_char(termw);
  1615.     home_cursor (termw);        /* Go to the upper left */
  1616.     clear_screen (termw);        /* Clear the screen */
  1617.     cursor_save (termw);        /* Save this position */
  1618. }
  1619.  
  1620. void escape_seq (struct termw *termw)
  1621. {
  1622.     termw->intermedbuf[0] = '\0';    /* Initialize the numbers to zero */
  1623.     termw->intermedptr = termw->intermedbuf; /* Place to put the next number */
  1624.     termw->charflg = CF_ESC;        /* Say we are in an escape sequence */
  1625. }                    /* escape_seq */
  1626.  
  1627. void csi_seq (struct termw *termw)
  1628. {
  1629.     termw->argcount = 0;        /* no arguments yet */
  1630.     termw->numarg[0] = 0;        /* Initialize the numbers to zero */
  1631.  
  1632.     termw->paramarg[0][0] = '\0';
  1633.     termw->argptr = termw->paramarg[0];    /* Place to put the next number */
  1634.  
  1635.     termw->numbuf[0] = '\0';        /* init number buffer */
  1636.     termw->numptr = termw->numbuf;
  1637.     
  1638.     termw->intermedbuf[0] = '\0';    /* Initialize the numbers to zero */
  1639.     termw->intermedptr = termw->intermedbuf; /* Place to put the next number */
  1640.  
  1641.     termw->charflg = CF_CSI;        /* Say we are in a ESC [ sequence */
  1642. }                    /* csi_seq */
  1643.  
  1644. void dcs_seq (struct termw *termw)
  1645. {
  1646.     csi_seq(termw);      /* these are like CSI commands, but have strings too */
  1647.     termw->charflg = CF_DCS;        /* Say we are in a device control sequence */
  1648. }
  1649.  
  1650. void string_term (struct termw *termw)
  1651. {
  1652.     termw->charflg = CF_OUTC;
  1653. }
  1654.  
  1655. void vt320_mode(struct termw *termw)
  1656. {
  1657. #pragma unused (termw)
  1658. }
  1659.  
  1660. void graphic_G0 (struct termw *termw)
  1661. {
  1662.     termw->charflg = CF_GS_0;
  1663. }                /* graphic_G0 */
  1664.  
  1665.  
  1666. void graphic_G1 (struct termw *termw)
  1667. {
  1668.     termw->charflg = CF_GS_1;
  1669. }                /* graphic_G1 */
  1670.  
  1671.  
  1672. void graphic_G2 (struct termw *termw)
  1673. {
  1674.     termw->charflg = CF_GS_2;
  1675. }                /* graphic_G1 */
  1676.  
  1677.  
  1678. void graphic_G3 (struct termw *termw)
  1679. {
  1680.     termw->charflg = CF_GS_3;
  1681. }                /* graphic_G1 */
  1682.  
  1683.  
  1684. void control_N (struct termw *termw)
  1685. {
  1686.     termw->Gl_set = 1;        /* set to graphics set 1 */
  1687. }                /* control_N */
  1688.  
  1689.  
  1690. /* shift in */
  1691. void control_O (struct termw *termw)
  1692. {
  1693.     termw->Gl_set = 0;        /* set to graphics set 0 */
  1694. }                /* control_O */
  1695.  
  1696.  
  1697. void single_shift_2 (struct termw *termw)
  1698. {
  1699.     termw->old_Gl_set = termw->Gl_set;
  1700.     termw->Gl_set = 2;
  1701. }
  1702.  
  1703. void single_shift_3 (struct termw *termw)
  1704. {
  1705.     termw->old_Gl_set = termw->Gl_set;
  1706.     termw->Gl_set = 3;
  1707. }
  1708.  
  1709. void lock_shift_2 (struct termw *termw)
  1710. {
  1711.     termw->Gl_set = 2;
  1712. }
  1713.  
  1714. void lock_shift_3 (struct termw *termw)
  1715. {
  1716.     termw->Gl_set = 3;
  1717. }
  1718.  
  1719. void lock_shift_3r (struct termw *termw)
  1720. {
  1721.     termw->Gr_set = 3;
  1722. }
  1723.  
  1724. void lock_shift_2r (struct termw *termw)
  1725. {
  1726.     termw->Gr_set = 2;
  1727. }
  1728.  
  1729. void lock_shift_1r (struct termw *termw)
  1730. {
  1731.     termw->Gr_set = 1;
  1732. }
  1733.  
  1734. void h19_graph_mode (struct termw *termw)
  1735. {
  1736. #pragma unused (termw)
  1737. }
  1738.  
  1739. void end_h19_graph_mode (struct termw *termw)
  1740. {
  1741. #pragma unused (termw)
  1742. }
  1743.  
  1744. void set_appl  (struct termw *termw)
  1745. {
  1746.     termw->appl_mode = TRUE;        /* applications keypad mode */
  1747. }
  1748.  
  1749.  
  1750. void reset_appl  (struct termw *termw)
  1751. {
  1752.     termw->appl_mode = FALSE;        /* normal keypad mode */
  1753. }
  1754.  
  1755.  
  1756. /* set vtNNN level of compatibility */
  1757. void set_compat (struct termw *termw)
  1758. {
  1759.     if (termw->argcount < 2) termw->numarg[1] = 0;
  1760.     if (termw->argcount < 1) termw->numarg[0] = 0;
  1761.     if (termw->intermedbuf[0] == '"') {
  1762.     switch (termw->numarg[0]) {
  1763.       case 61:        /* vt100 mode */
  1764.         break;
  1765.         
  1766.       case 62:        /* vt200 mode */
  1767.         switch (termw->numarg[1]) {
  1768.           case 0:
  1769.         break;
  1770.         
  1771.           case 1:
  1772.         break;
  1773.         
  1774.           case 2:
  1775.         break;
  1776.         }
  1777.     }
  1778.     }
  1779. }
  1780.  
  1781. void set_charattr (struct termw *termw)
  1782. {
  1783.     if (termw->intermedbuf[0] == '"') {
  1784.         switch (termw->numarg[0]) {
  1785.       case 0:    /* all attributes off */
  1786.         termw->ch_protect = FALSE;
  1787.         break;
  1788.       
  1789.       case 1:
  1790.         termw->ch_protect = TRUE;
  1791.         break;
  1792.         
  1793.       case 2:
  1794.         termw->ch_protect = FALSE;
  1795.         break;
  1796.     }
  1797.     }
  1798. }
  1799.  
  1800.  
  1801. void clear_line (struct termw *termw)
  1802. {
  1803.     int i;
  1804.  
  1805.     if (termw->have_selection)
  1806.     maybe_nuke_selection (termw, termw->curlin, termw->curlin);
  1807.  
  1808.     switch (termw->numarg[0]) {
  1809.       case 0:            /* Clear:  here to the right */
  1810.     for (i = termw->curcol; i < MAXCOL; i++) {
  1811.         termw->scr[termw->curlin][i] = ' ';
  1812.         termw->scr_attrs[termw->curlin][i] = 0;
  1813.     }
  1814.     if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol)
  1815.         termw->out_mincol = termw->curcol;
  1816.     termw->out_maxcol = MAXCOL;    /* end of change */
  1817.  
  1818.     break;
  1819.  
  1820.       case 1:            /* Clear:  left to here */
  1821.     for (i = 0; i <= termw->curcol; i++) {
  1822.         termw->scr[termw->curlin][i] = ' ';
  1823.         termw->scr_attrs[termw->curlin][i] = 0;
  1824.     }
  1825.     termw->out_mincol = 0;        /* start at beginning of line */
  1826.     if (termw->out_maxcol <= termw->curcol)
  1827.         termw->out_maxcol = termw->curcol + 1; /* end of change */
  1828.     break;
  1829.  
  1830.       case 2:            /* Clear:  entire line */
  1831.     zeroline(termw, termw->curlin, 0);
  1832.     termw->out_mincol = 0;        /* update the whole line */
  1833.     termw->out_maxcol = MAXCOL;
  1834.     break;
  1835.     }
  1836. }                /* clear_line */
  1837.  
  1838.  
  1839. void erase_display(struct termw *termw)
  1840. {
  1841.     int i;
  1842.     Rect r;
  1843.  
  1844.     switch (termw->numarg[0]) {
  1845.       case 0:        /* clear from here to end */
  1846.     if (termw->have_selection)
  1847.         maybe_nuke_selection (termw, termw->curlin, botlin);
  1848.     if ((termw->curlin == toplin) && (termw->curcol == 0)) {
  1849.         push_clear_screen(termw);    /* save lines in scrollback buffer */
  1850.     } else {
  1851.         clear_line(termw);
  1852.                   /* Same termw->numarg[0] causes correct clear */
  1853.         flushbuf(termw);
  1854.         makerect(termw,
  1855.              &r,
  1856.              termw->curlin + 1,
  1857.              0,
  1858.              termw->screensize - termw->curlin - 1, 
  1859.              MAXCOL);
  1860.         EraseRect (&r);
  1861.         for (i = termw->curlin + 1; i <= botlin; i++)
  1862.         zeroline(termw, i, 1);
  1863.     }
  1864.     break;
  1865.  
  1866.       case 1:        /* clear from beginning to here */
  1867.     if (termw->have_selection)
  1868.         maybe_nuke_selection (termw, toplin, termw->curlin);
  1869.     clear_line(termw);        /* Same termw->numarg[0] causes correct clear */
  1870.     flushbuf(termw);
  1871.     makerect(termw,&r, 0, 0, termw->curlin, MAXCOL);
  1872.     EraseRect (&r);
  1873.     for (i = toplin; i < termw->curlin; i++)
  1874.         zeroline(termw, i, 1);
  1875.     break;
  1876.  
  1877.       case 2:        /* clear everything */
  1878.     if (termw->have_selection)
  1879.         maybe_nuke_selection (termw, toplin, botlin);
  1880.     push_clear_screen(termw);    /* save lines in scrollback buffer */
  1881.     break;
  1882.     }
  1883. }                /* erase_display */
  1884.  
  1885.  
  1886. /****************************************************************************/
  1887. /**** All cursor moves need to check that they don't go beyond the margins */
  1888. /****************************************************************************/
  1889. void cursor_right (struct termw *termw)
  1890. {
  1891.     if (termw->numarg[0] == 0) 
  1892.         termw->numarg[0] = 1;
  1893.     relmove(termw,termw->numarg[0], 0);
  1894. }                /* cursor_right */
  1895.  
  1896.  
  1897. void cursor_left (struct termw *termw)
  1898. {
  1899.     if (termw->numarg[0] == 0) 
  1900.         termw->numarg[0] = 1;
  1901.     relmove(termw, -termw->numarg[0], 0);
  1902. }                /* cursor_left */
  1903.  
  1904.  
  1905. void cursor_up(struct termw *termw)
  1906. {
  1907.     int abstop;            /* (UoR) check that we don't pass scrtop */
  1908.  
  1909.     abstop = termw->scrtop;
  1910.     if (termw->numarg[0] == 0) 
  1911.         termw->numarg[0] = 1;
  1912.     if ((termw->curlin >= abstop) &&
  1913.     (termw->curlin - termw->numarg[0] < abstop))
  1914.     absmove(termw,termw->curcol, abstop);
  1915.     else
  1916.     relmove(termw,0, -termw->numarg[0]);
  1917. }                /* cursor_up */
  1918.  
  1919.  
  1920. void cursor_down (struct termw *termw)
  1921. {
  1922.     int absbot;            /* (UoR) check that we don't pass scrbot */
  1923.  
  1924.     absbot = termw->scrbot;
  1925.     if (termw->numarg[0] == 0) 
  1926.         termw->numarg[0] = 1;
  1927.     if ((termw->curlin <= absbot) &&
  1928.     (termw->curlin + termw->numarg[0] > absbot))
  1929.     absmove(termw,termw->curcol, absbot);
  1930.     else
  1931.     relmove(termw,0, termw->numarg[0]);
  1932. }                /* cursor_down */
  1933.  
  1934.  
  1935. void cursor_position (struct termw *termw)
  1936. {
  1937.     if (termw->argcount < 2) 
  1938.         termw->numarg[1] = 1;
  1939.     if (termw->argcount < 1) 
  1940.         termw->numarg[0] = 1;
  1941.     if (termw->relorigin)
  1942.       absmove(termw,termw->numarg[1] - 1,termw->scrtop + termw->numarg[0] - 1);
  1943.     else
  1944.     absmove(termw,termw->numarg[1] - 1, termw->numarg[0] - 1);
  1945.     /* (UoR) moved "--" here from prev lines */
  1946. }                    /* cursor_position */
  1947.  
  1948. void cursor_h_pos (struct termw *termw)
  1949. {
  1950.     absmove(termw,termw->numarg[0] - 1, termw->curlin);
  1951. }                /* cursor_h_pos */
  1952.  
  1953.  
  1954. /* ESC 7 */
  1955. void cursor_save (struct termw *termw)
  1956. {
  1957.     termw->savcol = termw->curcol;        /* Save the current line and column */
  1958.     termw->savlin = termw->curlin;
  1959.  
  1960.     termw->savsty = termw->textstyle;        /* (UoR) additions */
  1961.     termw->savGl = termw->Gl_set;
  1962.     termw->savGr = termw->Gr_set;
  1963.     termw->savset[0] = termw->graphicsinset[0];
  1964.     termw->savset[1] = termw->graphicsinset[1];
  1965.     termw->savset[2] = termw->graphicsinset[2];
  1966.     termw->savset[3] = termw->graphicsinset[3];
  1967. }                /* cursor_save */
  1968.  
  1969.  
  1970. /* ESC 8 */
  1971. void cursor_restore (struct termw *termw)
  1972. {
  1973.     if (termw->intermedbuf[0] == '#') {
  1974.     vt_align(termw);
  1975.     return;
  1976.     }
  1977.     
  1978.     /* Move to the old cursor position */
  1979.     absmove(termw, termw->savcol, termw->savlin);
  1980.  
  1981.     termw->textstyle = termw->savsty;        /* (UoR) additions */
  1982.  
  1983.     termw->Gl_set = termw->savGl;
  1984.     termw->Gr_set = termw->savGr;
  1985.     termw->graphicsinset[0] = termw->savset[0];
  1986.     termw->graphicsinset[1] = termw->savset[1];
  1987.     termw->graphicsinset[2] = termw->savset[2];
  1988.     termw->graphicsinset[3] = termw->savset[3];
  1989. }                /* cursor_restore */
  1990.  
  1991. void set_scroll_region(struct termw *termw)
  1992. {
  1993.     if (termw->argcount < 2) termw->numarg[1] = 0;
  1994.     if (--termw->numarg[0] < 0)
  1995.     termw->numarg[0] = 0;        /* Make top of line (prev line) */
  1996.     if (termw->numarg[1] == 0)
  1997.     termw->numarg[1] = termw->screensize;        /* Zero means entire screen */
  1998.  
  1999.     /* (UoR) make sure region is legal */
  2000.     if (termw->numarg[0] < termw->numarg[1] - 1) {
  2001.       termw->topmargin = (termw->numarg[0] * termw->lineheight) + TOPMARGIN;
  2002.       termw->bottommargin = (termw->numarg[1] * termw->lineheight) + TOPMARGIN;
  2003.  
  2004.     termw->scrtop = termw->numarg[0];
  2005.     termw->scrbot = termw->numarg[1] - 1;
  2006.  
  2007.     home_cursor (termw);        /* We're supposed to home it! */
  2008.     }
  2009. }                /* set_scroll_region */
  2010.  
  2011.  
  2012.  
  2013. /****************************************************************************/
  2014. /* aka Select Graphic Rendition */
  2015. /****************************************************************************/
  2016. void text_mode (struct termw *termw)
  2017. {
  2018.     int i;
  2019.     
  2020.     if (termw->argcount == 0) {
  2021.     termw->argcount = 1;
  2022.     termw->numarg[0] = 0;
  2023.     }
  2024.     
  2025.     for (i = 0; i < termw->argcount; i++) {
  2026.     switch (termw->numarg[i]) {
  2027.       case 0:            /* primary rendition */
  2028.         termw->textstyle = 0;
  2029.         break;
  2030.  
  2031.       case 1:            /* bold or increased intensity */
  2032.         termw->textstyle |= VT_BOLD;
  2033.         break;
  2034.  
  2035.       case 4:        /* underscore */
  2036.         termw->textstyle |= VT_UNDER;    /* (PWP) */
  2037.         break;
  2038.  
  2039.       case 2:        /* faint or decreased intensity or
  2040.                  *  secondary color */
  2041.       case 3:        /* italic */
  2042.       case 5:        /* slow blink (< 150/sec); (UoR) blink is
  2043.                  * inverse */
  2044.       case 6:        /* fast blink (>= 150/sec) */
  2045.         termw->textstyle |= VT_BLINK;
  2046.         break;
  2047.         
  2048.       case 7:        /* reverse image */
  2049.         termw->textstyle |= VT_INVERT;    /* (PWP) */
  2050.         break;
  2051.  
  2052.       case 21:        /* ??? */
  2053.       case 22:        /* normal intensity */
  2054.         termw->textstyle &= ~(VT_BOLD);    /* (PWP) */
  2055.         break;
  2056.  
  2057.       case 24:        /* not underlined */
  2058.         termw->textstyle &= ~(VT_UNDER);    /* (PWP) */
  2059.         break;
  2060.  
  2061.       case 25:        /* not blinking */
  2062.         termw->textstyle &= ~(VT_BLINK);    /* (PWP) */
  2063.         break;
  2064.         
  2065.       case 27:        /* not reversed */
  2066.         termw->textstyle &= ~(VT_INVERT);    /* (PWP) */
  2067.         break;
  2068.     }
  2069.     }
  2070. }                /* text_mode */
  2071.  
  2072.  
  2073. void line_dblh_top(struct termw *termw)
  2074. {
  2075.     if (termw->intermedbuf[0] == '#') {
  2076.     termw->line_attrs[termw->curlin] = VT_DBLH_T;
  2077.     termw->out_mincol = 0;        /* update the whole line */
  2078.     termw->out_maxcol = MAXCOL;
  2079.     }
  2080. }
  2081.  
  2082. void line_dblh_bot(struct termw *termw)
  2083. {
  2084.     if (termw->intermedbuf[0] == '#') {
  2085.     termw->line_attrs[termw->curlin] = VT_DBLH_B;
  2086.     termw->out_mincol = 0;        /* update the whole line */
  2087.     termw->out_maxcol = MAXCOL;
  2088.     }
  2089. }
  2090.  
  2091. /* single width line */
  2092. void line_singw(struct termw *termw)
  2093. {
  2094.     if (termw->intermedbuf[0] == '#') {
  2095.     termw->line_attrs[termw->curlin] = VT_SNGL;
  2096.     termw->out_mincol = 0;        /* update the whole line */
  2097.     termw->out_maxcol = MAXCOL;
  2098.     }
  2099. }
  2100.  
  2101. /* double width line */
  2102. void line_dblw(struct termw *termw)
  2103. {
  2104.     if (termw->intermedbuf[0] == '#') {
  2105.     termw->line_attrs[termw->curlin] = VT_DBLW;
  2106.     termw->out_mincol = 0;        /* update the whole line */
  2107.     termw->out_maxcol = MAXCOL;
  2108.     }
  2109. }
  2110.  
  2111. void start_selected(struct termw *termw)
  2112. {
  2113. #pragma unused (termw)
  2114. }
  2115.  
  2116. void end_selected(struct termw *termw)
  2117. {
  2118. #pragma unused (termw)
  2119. }
  2120.  
  2121. /****************************************************************************/
  2122. /*
  2123.  * (UoR)
  2124.  *
  2125.  * Insert and Delete lines (replacements for originals, which have
  2126.  *   which have been deleted)
  2127.  *
  2128.  */
  2129. /****************************************************************************/
  2130. void insert_line(struct termw *termw)
  2131. {
  2132.     int absbot;
  2133.  
  2134.     absbot = termw->scrbot;
  2135.  
  2136.     if ((termw->curlin >= termw->scrtop) && (termw->curlin <= absbot)) {
  2137.     if (termw->numarg[0] == 0)
  2138.         termw->numarg[0] = 1;
  2139.     if (termw->numarg[0] > absbot - termw->curlin + 1)
  2140.         termw->numarg[0] = absbot - termw->curlin + 1;
  2141.  
  2142.     scroll_screen(termw,termw->curlin, termw->scrbot, termw->numarg[0]);
  2143.     }
  2144. }                /* termw->insert_line */
  2145.  
  2146.  
  2147. void delete_line (struct termw *termw)
  2148. {
  2149.     int absbot;
  2150.  
  2151.     absbot = termw->scrbot;
  2152.  
  2153.     if ((termw->curlin >= termw->scrtop) && (termw->curlin <= absbot)) {
  2154.     if (termw->numarg[0] == 0)
  2155.         termw->numarg[0] = 1;
  2156.     if (termw->numarg[0] > absbot - termw->curlin + 1)
  2157.         termw->numarg[0] = absbot - termw->curlin + 1;
  2158.  
  2159.     scroll_screen(termw,termw->curlin, termw->scrbot, -termw->numarg[0]);
  2160.     }
  2161. }                /* delete_line */
  2162.  
  2163.  
  2164. void delete_char (struct termw *termw)
  2165. {
  2166.     int i;
  2167.  
  2168.     if (termw->numarg[0] == 0)
  2169.     termw->numarg[0] = 1;
  2170.  
  2171.     if (termw->numarg[0] > MAXCOL - termw->curcol - 1)
  2172.     termw->numarg[0] = MAXCOL - termw->curcol - 1;
  2173.  
  2174.     /* Shift them down *//* (UoR) used to assign using abscol */
  2175.     for (i = termw->curcol; i < MAXCOL - termw->numarg[0]; i++) {
  2176.     termw->scr[termw->curlin][i] = 
  2177.         termw->scr[termw->curlin][i + termw->numarg[0]];
  2178.     termw->scr_attrs[termw->curlin][i] = 
  2179.         termw->scr_attrs[termw->curlin][i + termw->numarg[0]];
  2180.     }
  2181.     
  2182.     /*
  2183.      * Fill in holes with spaces
  2184.      * PWP 7/09/92 -- WOW! this has been wrong for about 4 years; 
  2185.      * fixed spaces bug 
  2186.      */
  2187.     for (i = MAXCOL - termw->numarg[0]; i < MAXCOL; i++) {
  2188.     termw->scr[termw->curlin][i] = ' ';
  2189.     termw->scr_attrs[termw->curlin][i] = 0;
  2190.     }
  2191.  
  2192.     /* say the line is dirty from the current position to the end */
  2193.     if (termw->out_mincol > termw->curcol)
  2194.     termw->out_mincol = termw->curcol;
  2195.     termw->out_maxcol = MAXCOL;
  2196. }                /* delete_char */
  2197.  
  2198.  
  2199.  
  2200. /****************************************************************************/
  2201. /* CME */
  2202. /****************************************************************************/
  2203. void insert_chars (struct termw *termw)
  2204. {
  2205.     int i, n;
  2206.  
  2207.     n = termw->numarg[0]; 
  2208.     
  2209.     if (n == 0)
  2210.     n = 1;
  2211.  
  2212.     if (n > MAXCOL - termw->curcol - 1)
  2213.     n = MAXCOL - termw->curcol - 1;
  2214.  
  2215.     /* Shift them up *//* (UoR) used to assign using abscol */
  2216.     for (i = MAXCOL - 1; i >= termw->curcol + n; i--) {
  2217.     termw->scr[termw->curlin][i] = termw->scr[termw->curlin][i - n];
  2218.     termw->scr_attrs[termw->curlin][i]
  2219.         = termw->scr_attrs[termw->curlin][i - n];
  2220.     }
  2221.     
  2222.     /* 
  2223.      * Fill in holes with spaces
  2224.      * PWP 1/07/91 -- WOW! this has been wrong for about 3 years; 
  2225.      * fixed spaces bug 
  2226.      */
  2227.     for (i = termw->curcol; i < termw->curcol + n; i++) {
  2228.     termw->scr[termw->curlin][i] = ' ';
  2229.     termw->scr_attrs[termw->curlin][i] = 0;
  2230.     }
  2231.  
  2232.     /* say the line is dirty from the current position to the end */
  2233.     if (termw->out_mincol > termw->curcol)
  2234.     termw->out_mincol = termw->curcol;
  2235.     termw->out_maxcol = MAXCOL;
  2236. }                /* termw->insert_chars */
  2237.  
  2238.  
  2239. void insert_char(struct termw *termw)
  2240. {
  2241.     int i;
  2242.  
  2243.     /* Shift em up *//* (UoR) used to assign ...[i-1]=...[i] */
  2244.     /* (UoR) used to assign using abscol */
  2245.  
  2246.     for (i = MAXCOL - 1; i > termw->curcol; i--) {
  2247.     termw->scr[termw->curlin][i] = termw->scr[termw->curlin][i - 1];
  2248.     termw->scr_attrs[termw->curlin][i]
  2249.         = termw->scr_attrs[termw->curlin][i-1];
  2250.     }
  2251.     
  2252.     termw->scr[termw->curlin][termw->curcol] = ' ';
  2253.     termw->scr_attrs[termw->curlin][termw->curcol] = 0;
  2254.  
  2255.  
  2256.     /* say the line is dirty from the current position to the end */
  2257.     if (termw->out_mincol > termw->curcol)
  2258.     termw->out_mincol = termw->curcol;
  2259.     termw->out_maxcol = MAXCOL;
  2260. }                /* termw->insert_char */
  2261.  
  2262.  
  2263. void insert_mode (struct termw *termw)
  2264. {
  2265.     int i;
  2266.  
  2267.     if (termw->argcount < 1) {
  2268.     termw->numarg[0] = 0;
  2269.     termw->argcount = 1;
  2270.     }
  2271.     for (i = 0; i < termw->argcount; i++) {    /* handle multiple arguments */
  2272.     if (termw->paramarg[i][0] == '?') {
  2273.         set_mode (termw, termw->numarg[i]);/* do some of these calls */
  2274.     } else if (termw->paramarg[i][0] == '>') { /* (PWP) Heath ANSI stuff */
  2275.         set_heath_mode(termw, termw->numarg[i]);
  2276.     } else {
  2277.         switch (termw->numarg[i]) {
  2278.           case 20:        /* termw->newline mode */
  2279.         termw->newline = TRUE;
  2280.         break;
  2281.  
  2282.           case 12:        /* send/recieve */
  2283.         break;
  2284.     
  2285.           case 4:        /* termw->insert mode */
  2286.         termw->insert = TRUE;
  2287.         break;
  2288.         }
  2289.     }
  2290.     }
  2291. }                /* termw->insert_mode */
  2292.  
  2293.  
  2294. void end_insert_mode (struct termw *termw)
  2295. {
  2296.     int i;
  2297.     
  2298.     if (termw->argcount < 1) {
  2299.     termw->numarg[0] = 0;
  2300.     termw->argcount = 1;
  2301.     }
  2302.     for (i = 0; i < termw->argcount; i++) {    /* handle multiple arguments */
  2303.     if (termw->paramarg[i][0] == '?') {
  2304.         reset_mode (termw, termw->numarg[i]);
  2305.                 /* (UoR) do some of these calls */
  2306.     } else if (termw->paramarg[i][0] == '>') {
  2307.                 /* (PWP) Heath ANSI stuff */
  2308.         reset_heath_mode(termw, termw->numarg[i]);
  2309.     } else {
  2310.         switch (termw->numarg[i]) {
  2311.           case 20:        /* termw->newline mode */
  2312.         termw->newline = FALSE;
  2313.         break;
  2314.  
  2315.           case 12:        /* send/recieve */
  2316.         break;
  2317.     
  2318.           case 4:        /* termw->insert mode */
  2319.         termw->insert = FALSE;
  2320.         break;
  2321.         }
  2322.     }
  2323.     }
  2324. }                /* end_termw->insert_mode */
  2325.  
  2326. /****************************************************************************/
  2327.  
  2328. void printer_control (struct termw *termw)
  2329. {
  2330.     switch (termw->numarg[0]) {        /* "ESC [ ? # i" */
  2331.       case 5: /* Start printing */
  2332.     if (to_printer)
  2333.         break;
  2334. #ifdef COMMENT
  2335.     if (hPrintBuffer == 0L) {
  2336.         lPrintBufferSize = FreeMem();
  2337.         do {
  2338.         lPrintBufferSize = (lPrintBufferSize >> 1)
  2339.              + (lPrintBufferSize >> 2);
  2340.         hPrintBuffer = NewHandle(lPrintBufferSize);
  2341.         } while (hPrintBuffer == NIL);
  2342.         lPrintBufferSize = (lPrintBufferSize * 2) / 3;
  2343.         SetHandleSize(hPrintBuffer, lPrintBufferSize);
  2344.         lPrintBufferAt = lPrintBufferChars = 0L;
  2345.     } else {
  2346.         (*hPrintBuffer)[lPrintBufferAt++] = 014;
  2347.         if (lPrintBufferAt == lPrintBufferSize)
  2348.             lPrintBufferAt = 0L;
  2349.         lPrintBufferChars++;
  2350.     }
  2351.     overflowingDialog = 0L;
  2352.     if (lPrintBufferChars == lPrintBufferSize) {           /*JAOtemp*/
  2353.         overflowingDialog = GetNewDialog(OVERFLOWINGBOXID, NILPTR, 
  2354.                          (WindowPtr) - 1);
  2355.         DrawDialog(overflowingDialog);               /*JAOtemp*/
  2356.     }                               /*JAOtemp*/
  2357. #endif /* COMMENT */
  2358.  
  2359.     if ((*prntw->teh)->teLength != 0)    /* if we already have stuff to print */
  2360.         add_to_print (1, "\014");        /* add a formfeed character */
  2361.     
  2362.     to_printer = TRUE;
  2363.     if (termw->paramarg[0][0] == '?')
  2364.         to_screen  = TRUE;
  2365.     else
  2366.         to_screen  = FALSE;
  2367.     upd_ptr_dlg();
  2368.     break;
  2369.  
  2370.       case 4: /* Stop printing */
  2371.     if (!to_printer)
  2372.         break;
  2373.     to_printer = FALSE;
  2374.     to_screen  = TRUE;
  2375.     updatepstat();
  2376.     upd_ptr_dlg();
  2377.     break;
  2378.     }
  2379. }    /* end of printer_control */        /*JAO*/
  2380.  
  2381.  
  2382. /*
  2383.  * NOTE: this is called externally (outside of inpchars()).
  2384.  */
  2385. void invert_term (struct termw *termw)
  2386. {
  2387.     if (termw->screeninvert)
  2388.     reset_mode (termw, 5);
  2389.     else
  2390.     set_mode (termw, 5);
  2391. }                /* invert_term */
  2392.  
  2393. /* we get here by ESC [ ? <termw->numarg[0]> h */
  2394. void set_mode (struct termw *termw, int arg)
  2395. {
  2396.     switch (arg) {
  2397.       case 1:        /* cursor key mode */
  2398.     termw->curskey_mode = TRUE;
  2399.     break;
  2400.     
  2401.       case 2:        /* keyboard lock */
  2402.     break;        /* we never do keyboard lock */
  2403.     
  2404.       case 3:        /* 132 column */
  2405.     break;
  2406.     
  2407.       case 4:        /* smooth scroll */
  2408.         termw->smoothscroll = TRUE;
  2409.     break;
  2410.     
  2411.       case 5:        /* reverse screen */
  2412.     set_term_invert(termw, TRUE);
  2413.     break;
  2414.  
  2415.       case 6:        /* relative origin mode */
  2416.     termw->relorigin = TRUE;
  2417.     home_cursor (termw);
  2418.     break;
  2419.  
  2420.       case 7:        /* auto wrap */
  2421.     termw->autowrap = TRUE;
  2422.     break;
  2423.  
  2424.       case 8:        /* auto repeat */
  2425.     termw->autorepeat = TRUE;
  2426.     break;
  2427.  
  2428.       case 18:        /* print form feed */
  2429.     break;
  2430.  
  2431.       case 19:        /* print extent */
  2432.     break;
  2433.  
  2434.       case 25:        /* text cursor enable */
  2435.     break;
  2436.  
  2437.       case 38:        /* Tektronics mode */
  2438.     break;
  2439.  
  2440.       case 42:        /* international character set */
  2441.     termw->nat_char_mode = TRUE;
  2442.     set_char_map(termw);
  2443.     break;
  2444.  
  2445.       case 43:        /* graphics expanded print */
  2446.     break;
  2447.  
  2448.       case 44:        /* graphics print color */
  2449.     break;
  2450.  
  2451.       case 45:        /* graphics print color syntax */
  2452.     break;
  2453.  
  2454.       case 46:        /* graphics print background */
  2455.     break;
  2456.  
  2457.       case 47:        /* graphics rotated print */
  2458.     break;
  2459.     }
  2460. }                /* set_mode */
  2461.  
  2462.  
  2463. /* we get here by ESC [ ? <termw->numarg[0]> l */
  2464. void reset_mode (struct termw *termw, int arg)
  2465. {
  2466.     switch (arg) {
  2467.       case 1:        /* cursor key mode */
  2468.     termw->curskey_mode = FALSE;
  2469.     break;
  2470.     
  2471.       case 2:        /* keyboard lock */
  2472.     break;        /* we never do keyboard lock */
  2473.     
  2474.       case 3:        /* 132 column */
  2475.     break;
  2476.     
  2477.       case 4:        /* smooth scroll */
  2478.         termw->smoothscroll = FALSE;
  2479.     break;
  2480.     
  2481.       case 5:        /* reverse screen */
  2482.     set_term_invert(termw, FALSE);
  2483.     break;
  2484.  
  2485.       case 6:        /* relative origin mode */
  2486.     termw->relorigin = FALSE;
  2487.     home_cursor (termw);
  2488.     break;
  2489.  
  2490.       case 7:        /* auto wrap */
  2491.     termw->autowrap = FALSE;
  2492.     break;
  2493.  
  2494.       case 8:        /* auto repeat */
  2495.     termw->autorepeat = FALSE;
  2496.     break;
  2497.  
  2498.       case 18:        /* print form feed */
  2499.     break;
  2500.  
  2501.       case 19:        /* print extent */
  2502.     break;
  2503.  
  2504.       case 25:        /* text cursor enable */
  2505.     break;
  2506.  
  2507.       case 38:        /* Tektronics mode */
  2508.     break;
  2509.  
  2510.       case 42:        /* international character set */
  2511.     termw->nat_char_mode = FALSE;
  2512.     set_char_map(termw);    /* reset the display translate table */
  2513.     break;
  2514.  
  2515.       case 43:        /* graphics expanded print */
  2516.     break;
  2517.  
  2518.       case 44:        /* graphics print color */
  2519.     break;
  2520.  
  2521.       case 45:        /* graphics print color syntax */
  2522.     break;
  2523.  
  2524.       case 46:        /* graphics print background */
  2525.     break;
  2526.  
  2527.       case 47:        /* graphics rotated print */
  2528.     break;
  2529.     }
  2530. }                /* reset_mode */
  2531.  
  2532. /* we get here by ESC [ > <termw->numarg[0]> h */
  2533. void set_heath_mode (struct termw *termw, int arg)
  2534. {
  2535.     switch (arg) {
  2536.       case 1:        /* enable status (25th) line */
  2537.       case 2:        /* disable key click */
  2538.       case 3:        /* enter hold screen mode (we never do this) */
  2539.     break;
  2540.  
  2541.       case 4:        /* block cursor */
  2542.     termw->blockcursor = TRUE;
  2543.     break;
  2544.  
  2545.       case 5:        /* show cursor */
  2546.     termw->cursor_shown = TRUE;
  2547.     break;
  2548.  
  2549.       case 6:        /* keypad shifted */
  2550.       case 7:        /* enter alternate keypad mode */
  2551.       case 8:        /* auto LF on CR */
  2552.       case 9:        /* auto CR on LF */
  2553.     break;
  2554.     }
  2555. }
  2556.  
  2557. void reset_heath_mode (struct termw *termw, int arg)
  2558. {
  2559.     switch (arg) {
  2560.       case 1:        /* disable status (25th) line */
  2561.       case 2:        /* enable key click */
  2562.       case 3:        /* exit hold screen mode (we never do this) */
  2563.     break;
  2564.  
  2565.       case 4:        /* underline cursor */
  2566.     termw->blockcursor = FALSE;
  2567.     break;
  2568.  
  2569.       case 5:        /* hide cursor */
  2570.     termw->cursor_shown = FALSE;
  2571.     break;
  2572.  
  2573.       case 6:        /* keypad shifted */
  2574.       case 7:        /* enter alternate keypad mode */
  2575.       case 8:        /* auto LF on CR */
  2576.       case 9:        /* auto CR on LF */
  2577.     break;
  2578.     }
  2579. }
  2580.  
  2581. void set_tab(struct termw *termw)
  2582. {
  2583.     tabstops[termw->curcol] = 1;
  2584. }                /* set_tab */
  2585.  
  2586.  
  2587. void clear_tab(struct termw *termw)
  2588. {
  2589.     int i;
  2590.  
  2591.     switch (termw->numarg[0]) {
  2592.       case 0:
  2593.     tabstops[termw->curcol] = 0;
  2594.     break;
  2595.  
  2596.       case 3:
  2597.     for (i = 0; i < MAXCOL; i++)
  2598.         tabstops[i] = 0;
  2599.     break;
  2600.     }
  2601. }                /* clear_tab */
  2602.  
  2603.  
  2604.  
  2605. /****************************************************************************/
  2606. /* (UoR) use for respoding to information requests */
  2607. /****************************************************************************/
  2608. void writereply (char *s)
  2609. {
  2610.     long wrcnt, w2;
  2611.     int err;
  2612.     char *s2;
  2613.  
  2614.     w2 = wrcnt = strlen (s);    /* How long is the string? */
  2615.     for (s2 = s; w2 > 0; w2--, s2++)    /* add parity */
  2616.     *s2 = dopar (*s2);
  2617.     err = FSWrite (outnum, &wrcnt, s);    /* Respond to the query */
  2618.     if (err)
  2619.     printerr ("Bad Writeout:", err);
  2620. }                /* writereply */
  2621.  
  2622.  
  2623. void query_terminal (struct termw *termw)
  2624. {
  2625. #pragma unused (termw)
  2626.     writereply (querystring);
  2627. }                /* query_terminal */
  2628.  
  2629.  
  2630.  
  2631. /****************************************************************************/
  2632. /* (UoR) reports */
  2633. /****************************************************************************/
  2634. void request_report (struct termw *termw)
  2635. {
  2636.     switch (termw->numarg[0]) {
  2637.       case 5:            /* (UoR) report that we're OK */
  2638.     writereply (reportstring);
  2639.     break;
  2640.  
  2641.       case 6:            /* (UoR) reprt the cursor position */
  2642.     position_report(termw);
  2643.     break;
  2644.  
  2645.       case 15:            /* (UoR) report printer status */
  2646.     if (termw->paramarg[0][0] == '?')
  2647.         writereply (noprinter);
  2648.     break;
  2649.     }
  2650. }                /* request_report */
  2651.  
  2652.  
  2653. void position_report(struct termw *termw)
  2654. {
  2655.     int i;
  2656.     char buf[9];
  2657.     char *report;
  2658.  
  2659.     i = 0;
  2660.     buf[i++] = '\033';
  2661.     buf[i++] = '[';
  2662.     if (termw->curlin > 9)
  2663.     buf[i++] = '0' + (termw->curlin + 1) / 10;
  2664.     buf[i++] = '0' + (termw->curlin + 1) % 10;
  2665.     buf[i++] = ';';
  2666.     if (termw->curcol > 9)
  2667.     buf[i++] = '0' + (termw->curcol + 1) / 10;
  2668.     buf[i++] = '0' + (termw->curcol + 1) % 10;
  2669.     buf[i++] = 'R';
  2670.     buf[i] = '\0';
  2671.     report = buf;
  2672.     writereply (report);
  2673. }                /* position_report */
  2674.  
  2675.  
  2676.  
  2677. /****************************************************************************/
  2678. /* Routine zeroline
  2679.  *
  2680.  * Zero (set to space) all the characters in absolute line lin.
  2681.  *
  2682.  */
  2683. /****************************************************************************/
  2684. void zeroline(struct termw *termw, int lin, int line_attrs_also)
  2685. {
  2686.     register int i;
  2687.     register unsigned char *sc_cp, *at_cp;
  2688.  
  2689.     sc_cp = termw->scr[lin];
  2690.     at_cp = termw->scr_attrs[lin];
  2691.     i = MAXCOL;
  2692.     
  2693.     do {
  2694.     *sc_cp++ = ' ';
  2695.     *at_cp++ = 0;
  2696.     } while (--i > 0);
  2697.     
  2698.     *sc_cp = ' ';
  2699.     *at_cp = 0;
  2700.     if (line_attrs_also)
  2701.     termw->line_attrs[lin] = VT_SNGL;    /* reset line attributes */
  2702. }                /* zeroline */
  2703.  
  2704.  
  2705.  
  2706. /****************************************************************************/
  2707. /* Move a relative number of lines and chars.  Both can be negative. */
  2708. /****************************************************************************/
  2709. void relmove(struct termw *termw, int hor, int ver)
  2710. {
  2711.     /* 
  2712.      * (UoR) use absmove, which checks 
  2713.      * for cursor moving off screen.
  2714.      */
  2715.     absmove(termw,termw->curcol + hor, termw->curlin + ver);
  2716. }                /* relmove */
  2717.  
  2718.  
  2719. /****************************************************************************/
  2720. /* Move to absolute position hor char and ver line. */
  2721. /****************************************************************************/
  2722. void absmove(struct termw *termw, int hor, int ver)
  2723. {
  2724.     if (hor > MAXCOL - 1)
  2725.     hor = MAXCOL - 1;    /* (UoR) make sure its on the screen */
  2726.     if (hor < 0)
  2727.     hor = 0;
  2728.     if (ver > termw->screensize - 1)
  2729.     ver = termw->screensize - 1;
  2730.     if (ver < 0)
  2731.     ver = 0;
  2732.     if (termw->relorigin) {
  2733.     if (ver < termw->scrtop)
  2734.         ver = termw->scrtop;
  2735.     if (ver > termw->scrbot)
  2736.         ver = termw->scrbot;
  2737.     }
  2738.     
  2739.     if (termw->scroll_amount) {
  2740.     /*
  2741.      * If we have a saved scroll, and we are about to move outside of
  2742.      * the region that will get drawn in the process of doing the scroll,
  2743.      * then redraw the scrolling region now to avoid getting confused.
  2744.      */
  2745.     if (termw->scroll_amount < 0) {        /* FORWARD scrolling */
  2746.         if ((ver < termw->saved_blin+termw->refresh_amount)
  2747.               || (ver > termw->saved_blin))
  2748.         {
  2749.         flushscroll(termw);        /* sync the screen */
  2750.         }
  2751.     } else {                /* REVERSE scrolling */
  2752.         if ((ver < termw->saved_tlin)
  2753.               || (ver > termw->saved_tlin+termw->refresh_amount))
  2754.         {
  2755.         flushscroll(termw);        /* sync the screen */
  2756.         }
  2757.     }
  2758.     } else {    /* no saved scroll */
  2759.     if (ver != termw->curlin) {
  2760.         if (termw->out_maxcol)
  2761.         flushbuf(termw);        /* draw pending output */
  2762.     }
  2763.     }
  2764.  
  2765.     termw->curcol = hor;
  2766.     termw->curlin = ver;
  2767. }                /* absmove */
  2768.  
  2769.  
  2770.  
  2771. /****************************************************************************/
  2772. /* dump the whole screen to the session log file */
  2773. /****************************************************************************/
  2774. void scrtolog(struct termw *termw)
  2775. {
  2776.     int lin, i;
  2777.  
  2778.     lin = toplin;
  2779.     for (i = 0; i < termw->screensize; i++) {
  2780.     slog ((char *) termw->scr[lin], MAXCOL);/* write this line to session log */
  2781.     lin++;        /* lin = nxtlin[lin]; */
  2782.     }
  2783. }                /* scrtolog */
  2784.  
  2785. void scrlasttolog(struct termw *termw)
  2786. {
  2787.     /* write last line to session log*/
  2788.     slog ((char *) termw->scr[termw->screensize-1], MAXCOL);
  2789. }
  2790.  
  2791.  
  2792. /*
  2793.  * doesc
  2794.  * Process an escape character argument  
  2795.  * Returns FALSE normally, TRUE if quoted sequence.
  2796.  */
  2797. int doesc (char c)
  2798. {
  2799.     CHAR d;
  2800.     char temp[100];
  2801.     extern int cmask, cmdmsk;
  2802.     extern char ttname[];
  2803.     extern char *sesfil;
  2804.     struct termw *termw;
  2805.   
  2806.     while (1) {
  2807.     if (c == escape) {        /* Send escape character */
  2808.         d = dopar(c); 
  2809.         ttoc(d); 
  2810.         return FALSE;
  2811.         } else                /* Or else look it up below. */
  2812.         if (isupper(c)) 
  2813.         c = tolower(c);
  2814.  
  2815.     switch(c) {
  2816.  
  2817.     case 'c':            /* Close connection */
  2818.     case '\03':
  2819.         connected = 0; 
  2820.         /*
  2821.          * force up the command window.
  2822.          */
  2823.         termw = ctermw;
  2824.         kShowWindow(termw);
  2825.         kSelectWindow(termw->window);
  2826.         return FALSE;
  2827.  
  2828.     case 'b':            /* Send a BREAK signal */
  2829.     case '\02':
  2830.         ttsndb(); 
  2831.         return FALSE;
  2832.  
  2833. #ifdef notdef
  2834.     case 'h':            /* Hangup */
  2835.     case '\010':
  2836. #ifdef SUNX25
  2837.             if (network && (nettype == NET_SX25)) dox25clr = 1;
  2838.             else
  2839. #endif /* SUNX25 */
  2840.         dohangup = 1; 
  2841.         connected = 0; 
  2842.         printf("\r\n"); 
  2843.         return FALSE;
  2844.  
  2845. #ifdef SUNX25
  2846.         case 'i':                       /* Send an X.25 interrupt packet */
  2847.         case '\011':
  2848.             if (network && (nettype == NET_SX25)) (VOID) x25intr(0);
  2849.             printf("\r\n"); 
  2850.         return FALSE;
  2851.  
  2852.         case 'r':                       /* Reset the X.25 virtual circuit */
  2853.         case '\022':
  2854.             if (network && (nettype == NET_SX25)) (VOID) x25reset();
  2855.             printf("\r\n"); 
  2856.         return FALSE;
  2857. #endif /* SUNX25 */
  2858. #endif /* notdef */
  2859.  
  2860.     case 'q':
  2861. #ifdef notdef
  2862.         quitnow = 1; 
  2863. #endif
  2864.         connected = 0; 
  2865.         printf("\r\n"); 
  2866.         return FALSE;
  2867.  
  2868.     case 's':            /* Status */
  2869.         printf("\r\nConnected thru ");
  2870.         printf(ttname);
  2871. #ifdef SUNX25
  2872.             if (network && (nettype == NET_SX25))
  2873.                 printf(", Link ID %d, LCN %d",linkid,lcn);
  2874. #endif /* SUNX25 */
  2875.         if (speed >= 0L) {
  2876.         sprintf(temp,", speed %ld",speed); 
  2877.         printf(temp);
  2878.         }
  2879.         sprintf(temp,", %d terminal bits",(cmask == 0177) ? 7 : 8);
  2880.         printf(temp);
  2881.         if (parity) {
  2882.         printf(", ");
  2883.         switch (parity) {
  2884.             case 'e': printf("even");  break;
  2885.             case 'o': printf("odd");   break;
  2886.             case 's': printf("space"); break;
  2887.             case 'm': printf("mark");  break;
  2888.         }
  2889.         printf(" parity");
  2890.         }
  2891.         if (seslog) {
  2892.         printf(", logging to "); 
  2893.         printf(sesfil);
  2894.             }
  2895.         printf("\n"); 
  2896.         return FALSE;
  2897.  
  2898. #ifdef notdef
  2899.     case '?':            /* Help */
  2900.         c = hconne(); 
  2901.         continue;
  2902. #endif
  2903.  
  2904.     case '0':            /* Send a null */
  2905.         c = '\0'; 
  2906.         d = dopar(c); 
  2907.         ttoc(d); 
  2908.         return FALSE;
  2909.  
  2910. #ifdef notdef
  2911.     case 'z': case '\032':        /* Suspend */
  2912.         stptrap(0); return;
  2913.  
  2914.     case '@':            /* Start inferior command processor */
  2915.     case '!':
  2916.         conres();            /* Put console back to normal */
  2917.         zshcmd("");            /* Fork a shell. */
  2918.         if (conbin(escape) < 0) {
  2919.         printf("Error returning to remote session\n");
  2920.         connected = 0;
  2921.         }
  2922.         return;
  2923. #endif
  2924.  
  2925.     case SP:            /* Space, ignore */
  2926.         return FALSE;
  2927.  
  2928.     case CMDQ:
  2929.         return TRUE;        /* Backslash escape */
  2930.  
  2931.     default:            /* Other */
  2932.         putchar(BEL);         /* Invalid esc arg, beep */ 
  2933.         return FALSE;
  2934.         }
  2935.     }
  2936. }
  2937.  
  2938. /*
  2939.  * Junk so Emacs will set local variables to be compatible with Mac/MPW.
  2940.  * Should be at end of file.
  2941.  * This module uses 8 char tabs
  2942.  * 
  2943.  * Local Variables:
  2944.  * tab-width: 8
  2945.  * End:
  2946.  */
  2947.