home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckc095.zip / ckmcon.c < prev    next >
C/C++ Source or Header  |  1989-08-22  |  65KB  |  2,583 lines

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