/* $Id: ckmcon.c,v 1.8 91/12/27 21:43:15 fdc Exp $ * $Source: /uw/mackermit/RCS/ckmcon.c,v $ *------------------------------------------------------------------ * $Log: ckmcon.c,v $ * Revision 1.8 91/12/27 21:43:15 fdc * Change fatal to macfatal, make all lines less than 80 chars wide. * * Revision 1.7 91/12/15 23:16:49 rick * ut9 * * Revision 1.6 91/10/13 13:43:10 rick * UT(7) * * Revision 1.5 91/10/01 12:16:18 rick * UT(5) * * Revision 1.4 91/09/25 12:16:40 rick * Command window in TE. Multiple vt100 windows for command window. * * Revision 1.3 91/09/12 21:50:36 rick * UT(3). Install on watsun * * Revision 1.2 1991/09/10 22:21:39 rick * Update to UTexas(2) * * Revision 1.1 1991/09/10 19:17:47 rick * Initial revision * *------------------------------------------------------------------ * $Endlog$ */ /* Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New York. Permission is granted to any individual or institution to use this software as long as it is not sold for profit. This copyright notice must be retained. This software may not be included in commercial products without written permission of Columbia University. */ /* John A. Oberschelp for Emory University vt102 printer support 22 May 1989 */ /* Emory contact is Peter W. Day, ospwd@emoryu1.cc.emory.edu */ /* Paul Placeway, Ohio State -- added option to flashing cursor, made */ /* key macros use Pascal strings, so that a NUL (0x00) can be sent */ /* Enhanced by Clayton M. Elwell, Ohio State University 24 Nov 1987 -- */ /* added insert character */ /* Matthias Aebi, ECOFIN Research and Consulting, Ltd., Oct 1987 -- */ /* ported to MPW, changed the way keys work */ /* Version 0.8(35) - Jim Noble at Planning Research Corporation, June 1987. */ /* Ported to Megamax native Macintosh C compiler. */ /* From: DPVC@UORDBV.BITNET */ /* DPVC at U of R, Oct 1, add blinking cursor and mouse cursor movement */ /* DPVC at U of R, Sept. 26, fixed book-keeping for scrolling and inserting */ /* characters and lines */ /* DPVC at U of R, Sept. 25, to fix cursor positioning off the screen, and */ /* a few other, minor VT100 incompatibilities */ /* DPVC at the University of Rochester, Sept. 9, to add Block Cursor and */ /* ability to do VT100 graphics characters */ /* By CAM2 and DPVC at the University of Rochester on Sept 6, */ /* changed bolding from using TextStyle attributes to using a separate bold */ /* font */ /* By fdc June 20 1984 - Add parity to all outbound chars using software */ /* Also, ignore DEL (0177) characters on input. */ /* By Bill Schilit on May 29 1984 - Add Key set translation */ /* By Bill Catchings (WBC3) on Apr 24 - Add ^^, ^@ and ^_. Also use Pascal */ /* strings for output in the terminal emulator */ /* By WBC3 on Apr 23 - Add query terminal and be more fastidious about */ /* ignoring sequences we don't know about */ /* By WBC3 on Apr 22 - Fix tab stops to conform to the rest of the world! */ /* By Bill on Apr 21 - Fix immediate echo problems. */ /* do less cursor_erase, cursor_draw stuff */ /* * FILE ckmcon.c * * Module of mackermit: contains code for the terminal emulation * routine. PWP: This file contains the stuff to deal with parsing for * a vt??? terminal. For Macintosh screen handling things, see * ckmco2.c. */ #include "ckcdeb.h" #include "ckmdef.h" #include "ckmasm.h" /* Assembler code */ #include "ckmres.h" /* kermit resources */ #include "ckmcon.h" /* defines, etc. for terminal emulator */ #include "ckcasc.h" #include "ckmptp.h" /* ckm* Prototypes */ #include "ckmwin.h" /* text edit window structures */ /* Tab settings */ /* (UoR) do tapstops via an array: 0 means no tab, 1 means tab at that column. */ /* (PWP) Tabbing bug fixed by Eamonn McManus */ /* (PWP) remember that a tab is set by "tabstops[curcol] = 1", and curcol is zero-based */ char tabstops[MAXCOL + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 }; struct termw *ttermw; /* terminal window */ struct termw *ctermw; /* command window */ struct termw *termwl = NULL; /* list of termw */ extern int connected; extern int escape; char *querystring = ANS_VT100AVO; /* Answer we are a VT100 with AVO */ /* (UoR) used to be VT102 */ char *reportstring = "\033[0n"; /* (UoR) report that we're OK */ char *noprinter = "\033[?13n"; /* (UoR) report no printer */ extern Boolean have_128roms; /* true if we are a Plus or better */ /* Screen book keeping variables */ /* * (PWP) Note that in order to support scroll back, we do things a bit * differently than before. There is no linked list of lines (it doesn't * take all that much time to just copy the pointers around), and the * indexing in scr is done BACKWARDS (0 is the bottom line) since if we * shrink the window, we want to see the bottom most part. * * Doing this makes the handling of scrolling regions a bit tricky, but * it was so allready so this isn't much worse. */ /*****************************************/ /* extern CSParam controlparam; */ extern unsigned char dopar (); /* Terminal function declarations. */ extern int to_printer; /*JAO*/ extern int to_screen; /*JAO*/ extern int printer_is_on_line_num; /*JAO*/ #ifdef COMMENT extern Handle hPrintBuffer; /*JAO*/ extern long lPrintBufferSize; /*JAO*/ extern long lPrintBufferChars; /*JAO*/ extern long lPrintBufferAt; /*JAO*/ #endif /* COMMENT */ extern DialogPtr bufferingDialog; /*JAO*/ extern DialogPtr overflowingDialog; /*JAO*/ extern MenuHandle menus[]; /* handle on our menus */ /*JAO*/ /* pointer to function returning void, taking a termw pointer as the argument */ typedef void (*PFV_termwP) (struct termw *termw); /* Terminal control character function command table. */ #define MIN_CTRL 000 #define MAX_CTRL 037 PFV_termwP ctrl_table[MAX_CTRL - MIN_CTRL + 1] = { dummy, /* 0 (NUL) */ dummy, /* 1 */ dummy, /* 2 */ dummy, /* 3 */ dummy, /* 4 */ dummy, /* 5 (send answerback DON'T DO THIS!!!) */ dummy, /* 6 */ bell, /* 7 */ back_space, /* 10 */ tab, /* 11 */ line_feed, /* 12 */ line_feed, /* 13 (Vertical tab) */ line_feed, /* 14 (Form feed) */ carriage_return, /* 15 */ control_N, /* 16 (graphic set 1) *//* (UoR) */ control_O, /* 17 (graphic set 0) *//* (UoR) */ dummy, /* 20 */ dummy, /* 21 ("XOFF") */ dummy, /* 22 */ dummy, /* 23 ("XON") */ dummy, /* 24 */ dummy, /* 25 */ dummy, /* 26 */ dummy, /* 27 */ norm_char, /* 30 (CAN) */ dummy, /* 31 */ norm_char, /* 32 (SUB) */ escape_seq, /* 33 (Escape) */ dummy, /* 34 */ dummy, /* 35 */ dummy, /* 36 */ dummy /* 37 */ }; #define MIN_META 0200 #define MAX_META 0237 PFV_termwP meta_table[MAX_META - MIN_META + 1] = { dummy, /* 200 */ dummy, /* 201 */ dummy, /* 202 */ dummy, /* 203 */ line_feed, /* 204 (index) */ line_feed, /* 205 (next line) */ dummy, /* 206 */ dummy, /* 207 */ set_tab, /* 210 */ dummy, /* 211 */ dummy, /* 212 */ dummy, /* 213 */ dummy, /* 214 */ reverse_line_feed, /* 215 */ single_shift_2, /* 216 */ single_shift_3, /* 217 */ dcs_seq, /* 220 */ dummy, /* 221 */ dummy, /* 222 */ dummy, /* 223 */ dummy, /* 224 */ dummy, /* 225 */ dummy, /* 226 */ dummy, /* 227 */ dummy, /* 230 */ dummy, /* 231 */ dummy, /* 232 */ csi_seq, /* 233 */ norm_char, /* 234 (String Terminator) */ toss_till_st, /* 235 (Operating System Command) */ toss_till_st, /* 236 (Privacy Message) */ toss_till_st /* 237 (Applications Prog. Command) */ }; #define MIN_ESC 0060 #define MAX_ESC 0177 PFV_termwP esc_table[MAX_ESC - MIN_ESC + 1] = { dummy, /* 60 '0' */ dummy, /* 61 '1' */ dummy, /* 62 '2' */ line_dblh_top, /* 63 '3' */ line_dblh_bot, /* 64 '4' */ line_singw, /* 65 '5' */ line_dblw, /* 66 '6' */ cursor_save, /* 67 '7' */ cursor_restore, /* 70 '8' */ dummy, /* 71 '9' */ dummy, /* 72 */ dummy, /* 73 */ dummy, /* 74 '<' */ set_appl, /* 75 '=' */ reset_appl, /* 76 '>' */ dummy, /* 77 */ dummy, /* 100 */ dummy, /* 101 */ dummy, /* 102 */ dummy, /* 103 */ line_feed, /* 104 'D' */ new_line, /* 105 'E' *//* (UoR) */ start_selected, /* 106 'F' */ end_selected, /* 107 'G' */ set_tab, /* 110 'H' *//* (UoR) */ dummy, /* 111 */ dummy, /* 112 */ dummy, /* 113 */ dummy, /* 114 */ reverse_line_feed, /* 115 'M' */ single_shift_2, /* 116 'N' */ single_shift_3, /* 117 'O' */ dcs_seq, /* 120 'P' */ dummy, /* 121 */ dummy, /* 122 */ dummy, /* 123 */ dummy, /* 124 */ dummy, /* 125 */ dummy, /* 126 */ dummy, /* 127 */ dummy, /* 130 */ dummy, /* 131 */ query_terminal, /* 132 'Z' */ csi_seq, /* 133 '[' */ string_term, /* 134 '\' */ toss_till_st, /* 135 ']' */ toss_till_st, /* 136 '^' */ toss_till_st, /* 137 '_' */ dummy, /* 140 */ dummy, /* 141 */ dummy, /* 142 */ term_reset, /* 143 'c' */ dummy, /* 144 */ dummy, /* 145 */ dummy, /* 146 'f' */ dummy, /* 147 'g' */ dummy, /* 150 'h' */ dummy, /* 151 'i' */ dummy, /* 152 */ dummy, /* 153 */ dummy, /* 154 'l' */ dummy, /* 155 'm' */ lock_shift_2, /* 156 'n' */ lock_shift_3, /* 157 */ dummy, /* 160 'p' */ dummy, /* 161 'q' */ dummy, /* 162 'r' */ dummy, /* 163 */ dummy, /* 164 */ dummy, /* 165 */ dummy, /* 166 */ dummy, /* 167 */ dummy, /* 170 */ dummy, /* 171 */ dummy, /* 172 */ dummy, /* 173 */ lock_shift_3r, /* 174 '|' */ lock_shift_2r, /* 175 '}' */ lock_shift_1r, /* 176 '~' */ dummy /* 177 */ }; /* Terminal escape sequence function command table */ #define MIN_CSI 0100 #define MAX_CSI 0177 PFV_termwP csi_table[MAX_CSI - MIN_CSI + 1] = { insert_chars, /* 100 *//* CME */ cursor_up, /* 101 'A' */ cursor_down, /* 102 'B' */ cursor_right, /* 103 'C' */ cursor_left, /* 104 'D' */ dummy, /* 105 */ cursor_h_pos, /* 106 'F' */ dummy, /* 107 */ cursor_position, /* 110 'H' (PWP) */ dummy, /* 111 */ erase_display, /* 112 'J' */ clear_line, /* 113 'K' */ insert_line, /* 114 'L' */ delete_line, /* 115 'M' */ dummy, /* 116 */ dummy, /* 117 */ delete_char, /* 120 'P' */ dummy, /* 121 */ dummy, /* 122 */ dummy, /* 123 */ dummy, /* 124 */ dummy, /* 125 */ dummy, /* 126 */ dummy, /* 127 */ dummy, /* 130 */ dummy, /* 131 */ dummy, /* 132 */ dummy, /* 133 */ dummy, /* 134 */ dummy, /* 135 */ dummy, /* 136 */ dummy, /* 137 */ dummy, /* 140 */ dummy, /* 141 */ dummy, /* 142 */ query_terminal, /* 143 'c' */ dummy, /* 144 */ dummy, /* 145 */ cursor_position, /* 146 'f' */ clear_tab, /* 147 'g' *//* (UoR) */ insert_mode, /* 150 'h' */ printer_control, /* 151 'i' *//*JAO*/ dummy, /* 152 */ dummy, /* 153 */ end_insert_mode, /* 154 'l' */ text_mode, /* 155 'm' */ request_report, /* 156 'n' *//* (UoR) */ dummy, /* 157 */ set_compat, /* 160 'p' (PWP) */ set_charattr, /* 161 'q' (PWP) */ set_scroll_region, /* 162 'r' */ dummy, /* 163 */ dummy, /* 164 */ dummy, /* 165 */ dummy, /* 166 */ dummy, /* 167 */ dummy, /* 170 */ dummy, /* 171 */ dummy, /* 172 */ dummy, /* 173 */ dummy, /* 174 */ dummy, /* 175 */ dummy, /* 176 */ dummy /* 177 */ }; #ifdef COMMENT /* not done yet */ #define MINVT52ESCS 0040 #define MAXVT52ESCS 0137 PFV_termwP vt52table[MAXVT52ESCS - MINVT52ESCS + 1] = { dummy, /* 40 */ dummy, /* 41 */ dummy, /* 42 */ dummy, /* 43 '#' */ dummy, /* 44 */ dummy, /* 45 */ dummy, /* 46 */ dummy, /* 47 */ dummy, /* 50 '(' */ dummy, /* 51 ')' */ dummy, /* 52 */ dummy, /* 53 */ dummy, /* 54 */ dummy, /* 55 */ dummy, /* 56 */ dummy, /* 57 */ dummy, /* 60 */ dummy, /* 61 */ dummy, /* 62 */ dummy, /* 63 */ dummy, /* 64 */ dummy, /* 65 */ dummy, /* 66 */ cursor_save, /* 67 '7' */ cursor_restore, /* 70 '8' */ dummy, /* 71 */ dummy, /* 72 */ dummy, /* 73 */ vt320_mode, /* 74 '<' */ set_appl, /* 75 '=' */ reset_appl, /* 76 '>' */ dummy, /* 77 */ dummy, /* 100 */ cursor_up, /* 101 'A' */ cursor_down, /* 102 'B' */ cursor_right, /* 103 'C' */ cursor_left, /* 104 'D' */ clear_screen, /* 105 'E' */ h19_graph_mode, /* 106 */ end_h19graph_mode, /* 107 */ home_cursor, /* 110 'H' */ reverse_line_feed, /* 111 'I' */ clear_eop, /* 112 'J' */ clear_eol, /* 113 'K' */ insert_line, /* 114 'L' */ delete_line, /* 115 'M' */ delete_char, /* 116 'N' */ end_insert_mode, /* 117 'O' */ dummy, /* 120 */ dummy, /* 121 */ dummy, /* 122 */ dummy, /* 123 */ dummy, /* 124 */ dummy, /* 125 */ print_cur_line, /* 126 'V' */ start_printing, /* 127 'W' */ end_printing, /* 130 'X' */ h19_cursor_position, /* 131 'Y' */ query_terminal, /* 132 'Z' */ csi_seq, /* 133 '[' */ dummy, /* 134 */ dummy, /* 135 */ dummy, /* 136 */ dummy /* 137 */ }; #endif /* COMMENT */ static unsigned char char_map[128]; /* holds the current translation tbl */ static unsigned char nat_remaps[13][12] = { /* USA (ASCII) proper */ { '#', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' }, /* UK */ { 0xA3, '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' }, /* Dutch */ { 0xA3, 0xBE, 0xFF, 0xBD, '|', '^', '_', '`', 0xA8, 'f', 0xBC, 0xB4 }, /* Finnish */ { '#', '@', 0xC4, 0xD6, 0xC5, 0xDC, '_', 0xE9, 0xE4, 0xF6, 0xE5, 0xFC }, /* French */ { 0xA3, 0xE0, 0xB0, 0xE7, 0xA7, '^', '_', '`', 0xE9, 0xF9, 0xE8, 0xA8 }, /* French Canadian */ { '#', 0xE0, 0xE2, 0xE7, 0xEA, 0xEE, '_', 0xF4, 0xE9, 0xF9, 0xE8, 0xFB }, /* German */ { '#', 0xA7, 0xC4, 0xD6, 0xDC, '^', '_', '`', 0xE4, 0xF6, 0xFC, 0xDF }, /* Italian */ { 0xA3, 0xA7, 0xB0, 0xE7, 0xE9, '^', '_', 0xF9, 0xE0, 0xF2, 0xE8, 0xEC }, /* Norwegian/Danish */ { '#', '@', 0xC6, 0xD8, 0xC5, '^', '_', '`', 0xE6, 0xF8, 0xE5, '~' }, /* Portuguese */ { '#', '@', 0xC3, 0xC7, 0xD5, '^', '_', '`', 0xE3, 0xE7, 0xF5, '~' }, /* Spanish */ { 0xA3, 0xA7, 0xA1, 0xD1, 0xBF, '^', '_', '`', '`', 0xB0, 0xF1, 0xE7 }, /* Swedish */ { '#', 0xC9, 0xC4, 0xD6, 0xC5, 0xDC, '_', 0xE9, 0xE4, 0xF6, 0xE5, 0xFC }, /* Swiss */ { 0xF9, 0xE0, 0xE9, 0xE7, 0xEA, 0xEE, 0xE8, 0xF4, 0xE4, 0xF6, 0xFC, 0xFB } }; static struct { unsigned char fnum; unsigned char coffset; unsigned char lbound; unsigned char hbound; } vt_to_fmap[] = { {0, 0, ' ', 127}, /* US ASCII */ {0, 0, 0, 0}, /* unassigned */ {0, 32, '`', 127}, /* DEC VT100 graphics */ {1, 0, ' ', 127}, /* DEC VT300 technical font */ {0, 128, ' ', 127}, /* DEC International font (almost 8859/1 */ {0, 128, ' ', 128}, /* ISO Latin 1 */ {2, 0, ' ', 128}, /* ISO Latin 2 */ {2, 128, ' ', 128}, /* ISO Latin 3 */ {3, 0, ' ', 128}, /* ISO Latin 4 */ {4, 0, ' ', 128}, /* ISO Latin/Cyrilic */ {4, 128, ' ', 128}, /* ISO Latin/Arabic */ {5, 0, ' ', 128}, /* ISO Latin/Greek */ {5, 128, ' ', 128}, /* ISO Latin/Hebrew */ {3, 128, ' ', 128} /* ISO Latin 5 */ }; /****************************************************************************/ /* Input and process all the characters pending on the tty line */ /****************************************************************************/ inpchars (struct termw *termw) { register int rdcnt, i; unsigned char buf[1024]; GrafPtr savePort; if (termw->curlin < 0 || termw->curlin >= termw->screensize) macfatal("inpchars(): termw->curlin out of bounds:", termw->curlin); /* can be == when termw->autowraping */ if (termw->curcol < 0 || termw->curcol > MAXCOL) macfatal("inpchars(): termw->curcol out of bounds:", termw->curcol); if (termw->display_topline < (termw->screensize - MAX_SCREENSIZE) || termw->display_topline > 0) macfatal("inpchars(): termw->display_topline out of bounds:", termw->display_topline); /* * If there are any characters to get and draw, do so. */ if (ttchk() > 0) { GetPort (&savePort); SetPort (termw->window); cursor_erase (termw); /* remove cursor from screen */ screen_to_bottom(termw); /* slide the visible region to active area */ for (i = 0; i < 6; i++) { rdcnt = ttinm((char *) buf, sizeof(buf)); if (rdcnt <= 0) break; printem (termw, buf, rdcnt); } /* * allways update the screen after up to 6 tries at getting some data * and drawing it to the screen. This will give a slightly better * feel, because of less delay in some cases, and will be self-metering * anyway because if we update "too soon" one time, the next time we * will have more pending characters to draw, so efficiency is * maintained. */ if (termw->scroll_amount) flushscroll(termw); /* sync the screen */ if (termw->out_maxcol) flushbuf(termw); /* Flush any remaining characters */ cursor_draw(termw); /* put it back */ update_vscroll(termw); SetPort (savePort); } } /* inpchars */ /* * updatecommand * Update the command window. */ updatecommand (struct termw *termw) { Boolean changed; GrafPtr savePort; if (!termw) macfatal("updatecommand() called with term == NULL", 0); GetPort (&savePort); SetPort (termw->window); changed = FALSE; if (termw->scroll_amount || termw->out_maxcol) { changed = TRUE; screen_to_bottom(termw); /* slide the visible region to active area */ } if (termw->scroll_amount) flushscroll(termw); /* sync the screen */ if (termw->out_maxcol) flushbuf(termw); /* Flush any remaining characters */ /* if (changed) */ /* PWP: why only if changed??? */ cursor_draw(termw); /* put it back */ update_vscroll(termw); SetPort (savePort); } /****************************************************************************/ /* * (UoR) * * Print a PASCAL string to the screen (used to echo function and meta strings * in duplex mode). * */ /****************************************************************************/ printps (struct termw *termw, StringPtr s) { long w2; cursor_erase(termw); w2 = *s++; /* get count */ #ifdef COMMENT for (s2 = s; w2 > 0; w2--, s2++) printit (*s2); /* print it out, and perform special * functions */ #endif printem (termw, s, w2); if (termw->scroll_amount) flushscroll(termw); /* sync the screen */ if (termw->out_maxcol) flushbuf(termw); cursor_draw(termw); return; } /* printps */ /****************************************************************************/ /* * MLookup: * Lookup a given character in the apropriate character table, and * return a pointer to the appropriate function, if it exists. */ /****************************************************************************/ PFV_termwP mlookup (unsigned char index, PFV_termwP table[], int min, int max) { if (index > max || index < min) return ((PFV_termwP) NULL); /* Don't index out of range */ return (table[index - min]); } /* lookup */ /* tie off the current numeric argument */ void end_numarg (struct termw *termw) { long lnum = 0; /* can't be register */ if (termw->argcount < MAX_ARGCOUNT) { /* bounds */ if (termw->argptr > termw->paramarg[termw->argcount] + NUMBUFSIZ - 1) termw->argptr = termw->paramarg[termw->argcount] + NUMBUFSIZ - 1; *termw->argptr = '\0'; /* tie off parameter argument */ if (termw->numptr > termw->numbuf + NUMBUFSIZ - 1) termw->numptr = termw->numbuf + NUMBUFSIZ - 1; /* bounds */ *termw->numptr = '\0'; /* tie off number string */ if (termw->numptr > termw->numbuf) { /* if we had a number collected */ c2pstr(termw->numbuf); StringToNum (termw->numbuf, &lnum); /* Translate the numbers */ if (lnum < 0) lnum = 0; if (lnum > 9999) lnum = 9999; /* ANSI says between 0 and 9999 */ } else { lnum = 0; } termw->numarg[termw->argcount++] = lnum; } termw->argptr = termw->paramarg[termw->argcount]; /* Go to next number */ termw->numptr = termw->numbuf; /* reset buffer */ } #undef PREADJUST_HACK #ifdef PREADJUST_HACK /****************************************************************************/ /* * preadjust_for_linefeeds: * Counts how many linefeeds are in the current buffers worth of data, * and scrolls the screen far enough to account for all of them. */ /****************************************************************************/ void preadjust_for_linefeeds (struct termw *termw, register unsigned char *buf, register int count) { register unsigned char c; register unsigned char *cp; register int i; register int num_linefeeds; if (termw->smoothscroll) return; /* don't do this if smooth scrolling */ /* * Scan for how many line feeds we do in this batch */ num_linefeeds = 0; for (cp = buf, i = 0; i < count; i++) { c = *cp++; if (c == '\012') { num_linefeeds++; } else if (c && (c != '\015') && (c != '\0177') && (!(c & 0x60) || (c & 0x80))) { /* if c is a control or meta char, quit */ break; } } i = termw->curlin + num_linefeeds - termw->scrbot; if (i > (termw->curlin - 1)) i = termw->curlin - 1; if (i > 0) { /* scroll lines up */ scroll_screen (termw, termw->scrtop, termw->scrbot, -(i)); termw->curlin -= i; /* readjust curlin to reflect the prescroll */ } } #endif /* PREADJUST_HACK */ /****************************************************************************/ /* * Printem: * Draws character and updates buffer */ /****************************************************************************/ printem (struct termw *termw, register unsigned char *buf, register int count) { register unsigned char c; register unsigned char *cp; register int n; register PFV_termwP funp; GrafPtr savePort; GetPort (&savePort); SetPort (termw->window); #ifdef PREADJUST_HACK preadjust_for_linefeeds (termw, buf, count); #endif /* PREADJUST_HACK */ if (termw->cur_drawn) cursor_erase(termw); while (count-- > 0) { c = *buf++; if (!termw->eightbit_disp) c &= 0177; if ((c == 0) || (c == 0177)) /* ignore null characters */ continue; /* (PWP) Acording to vttest, vt100 series terminals will do control characters in the middle of an escape sequence. ick!. */ /* If it's a control char, do the apropriate function. */ if ((c & 0x60) == 0) { /* if control or meta-control character */ if (termw->dispcontchar) { /* this is counter-intuitive */ if (c >= 0x80) { if (funp = mlookup (c, meta_table, MIN_META, MAX_META)) (*funp) (termw); /* Do escape sequence function */ } else { if (funp = mlookup (c, ctrl_table, MIN_CTRL, MAX_CTRL)) (*funp) (termw); /* Do escape sequence function */ } continue; } else { /* if (!termw->dispcontchar) */ MDrawChars(termw, buf-1, 1); /* draw the control character */ /* if (termw->out_maxcol) flushbuf(termw); */ if (c == '\012') new_line(termw); continue; } } /* end if control */ switch (termw->charflg) { #ifdef COMMENT case CF_OUTC: /* Just output the char */ MDrawChar(termw,c); break; #endif /* COMMENT */ case CF_OUTC: /* ordinary character */ /* * Since most of the wierd things we do to characters are constant * for a given run of characters, we find out how many characters * we can do as a batch and do all of them. */ buf--; /* backup to this character again */ count++; cp = buf; /* save start of run */ n = count; /* Don't tell MDrawChars to draw more than will fit on a line */ if (n > (MAXCOL - termw->curcol)) n = (MAXCOL - termw->curcol); if (n <= 0) n = 1; /* sanity bounds check */ while (--n >= 0) { c = *buf; if (!(c & 0x60) || (c == '\177')) /* if a C or M-C character */ break; buf++; } /* buf now points to the first character we cannot handle */ MDrawChars (termw, cp, (buf - cp)); count -= (buf - cp); /* adjust count */ break; case CF_ESC: /* In a single char escape seq */ if ((termw->intermedptr < termw->intermedbuf) || (termw->intermedptr > &termw->intermedbuf[NUMBUFSIZ - 1])) { printerr ("intermedptr out of range:", (int)termw->intermedptr); termw->intermedptr = termw->intermedbuf; } /* * (PWP) Quoting from the DEC VT300 manual: * * ESC I F * 1/11 2/0 to 2/15 3/0 to 7/14 * (Zero or more (One character) * characters) */ /* (PWP) A hack for now, until I rework the char set handling */ if (c == '(') graphic_G0(termw); else if (c == ')' || c == '-') graphic_G1(termw); else if (c == '*' || c == '.') graphic_G2(termw); else if (c == '+' || c == '/') graphic_G3(termw); else if (c >= 0x20 && c <= 0x2F) { if (termw->intermedptr < &termw->intermedbuf[NUMBUFSIZ - 1]) *termw->intermedptr++ = c; /* Add the char to the num */ } else if (c >= 0x30) { termw->charflg = CF_OUTC; /* Reset flag to simple outputting */ *termw->intermedptr = '\0'; if (funp = mlookup (c, esc_table, MIN_ESC, MAX_ESC)) (*funp) (termw); /* Do escape sequence function */ } break; case CF_GS_0: /* (UoR) process graphic characters */ case CF_GS_1: case CF_GS_2: /* PWP: for vt200 mode */ case CF_GS_3: if (c >= 0x20 && c < 0x30) { /* Deal with the modifiers */ if (termw->intermedptr < &termw->intermedbuf[NUMBUFSIZ - 1]) *termw->intermedptr++ = c; /* Add the char to the num */ } else { *termw->intermedptr = '\0'; /* (this uses termw->charflg to select which set) */ set_char_set(termw, c); /* Reset flag for next character */ termw->charflg = CF_OUTC; } break; case CF_CSI: /* Multichar escape sequence */ case CF_DCS: /* device control string sequence */ if ((termw->intermedptr < termw->intermedbuf) || (termw->intermedptr > &termw->intermedbuf[NUMBUFSIZ - 1])) { printerr ("termw->intermedptr out of range:", (int)termw->intermedptr); termw->intermedptr = termw->intermedbuf; } if ((termw->argptr < termw->paramarg[termw->argcount]) || (termw->argptr > &termw->paramarg[termw->argcount][NUMBUFSIZ - 1])) { printerr ("termw->argptr out of range:", (int)termw->argptr); termw->argptr = termw->paramarg[termw->argcount]; } if ((termw->numptr < termw->numbuf) || (termw->numptr > &termw->numbuf[NUMBUFSIZ - 1])) { printerr ("termw->numptr out of range:", (int)termw->numptr); termw->numptr = termw->numbuf; } /* * (PWP) Also quoting from the DEC VT300 manual * (orignal NOTE: in italics): * * CSI P...P I...I F * ESC [ 3/0 to 3/15 2/0 to 2/15 4/0 to 7/14 * * NOTE: All parameters muyst be positive decimal integers. * Do not use a decimal point in a parameter -- the termial will * ignore the command. * * If the first character in a parameter string is the ? (3/15) * character, it indicates that DEC private parameters follow. * The terminal interprets private parameters according to * ANSI X3.64 and ISO 6429. */ if (c >= 0x30 && c < 0x40) { /* Deal with the modifiers */ if ((c == '0') && (termw->numptr == termw->numbuf)) { /* ignore the leading zero */ } else if (c >= '0' && c <= '9') { if (termw->numptr < &termw->numbuf[NUMBUFSIZ - 1]) *termw->numptr++ = c; /* Add the char to the num */ } else if (c == ';') { end_numarg(termw); } else { if (termw->argptr < &termw->paramarg[termw->argcount][NUMBUFSIZ - 1]) { /* Add the char to the parameter list */ *termw->argptr++ = c; } } } else if (c >= 0x20 && c < 0x30) { /* Intermediate chars */ /* (PWP) intermeadiate chars go in the termw->intermedbuf[] */ end_numarg(termw); /* tie off numeric argument */ if (termw->intermedptr < &termw->intermedbuf[NUMBUFSIZ - 1]) *termw->intermedptr++ = c; /* Add the char to the num */ } else if (c >= 0x40) { /* End of sequence */ termw->charflg = CF_OUTC; /* Back to simple outputting */ if (funp = mlookup (c, csi_table, MIN_CSI, MAX_CSI)) { /* if we didn't just do this */ if (termw->intermedptr == termw->intermedbuf) end_numarg(termw); /* tie off numeric argument */ *termw->intermedptr = '\0'; /* tie off intermediate */ (*funp) (termw); /* Do the escape sequence function */ } } break; case CF_TOSS: /* Ignore this char */ termw->charflg = CF_OUTC; /* Reset flag */ break; case CF_T_ST: /* (PWP) toss till String Terminator */ break; } } /* end while (count-- >= 0) */ SetPort (savePort); } /* printem */ set_char_set (struct termw *termw, unsigned char c) { int ninetysix = 0; /* are we talking about a 96 char. set */ int set = termw->charflg - CF_GS_0; /* which slot are we talking about? */ if (set > 3) { set -= 4; ninetysix = 1; } if (!termw->nat_char_mode) { /* if doing 8859 international sets */ if (!ninetysix) { /* 94 character set */ switch(c) { case '1': /* ALT ROM set (we claim ASCII) */ termw->graphicsinset[set] = ASCII_SET; break; case '5': if (termw->intermedbuf[0] == '%') /* DEC supplimental graphic */ termw->graphicsinset[set] = GRAF_SET; /* for now */ break; case '0': case '2': termw->graphicsinset[set] = GRAF_SET; break; case '>': termw->graphicsinset[set] = TECH_SET; break; case 'A': termw->graphicsinset[set] = ASCII_SET; break; case '<': /* DEC user-prefered supplemental set */ termw->graphicsinset[set] = GRAF_SET; break; case 'B': /* Allways ASCII half of an ISO set */ termw->graphicsinset[set] = ASCII_SET; break; } /* end switch(c) */ } else { /* 96 character set */ switch(c) { case '1': /* ALT ROM set (we claim ASCII) */ termw->graphicsinset[set] = ASCII_SET; break; case '<': /* DEC user-prefered supplemental set */ termw->graphicsinset[set] = GRAF_SET; break; case 'A': termw->graphicsinset[set] = LAT1_SET; break; #ifdef COMMENT case 'B': termw->graphicsinset[set] = LAT2_SET; break; case 'C': termw->graphicsinset[set] = LAT3_SET; break; case 'D': termw->graphicsinset[set] = LAT4_SET; break; case 'L': termw->graphicsinset[set] = LATCYR_SET; break; case '*': /* we don't know what this should be yet */ termw->graphicsinset[set] = LATARAB_SET; break; case 'F': termw->graphicsinset[set] = LATGREEK_SET; break; case 'H': termw->graphicsinset[set] = LATHEBREW_SET; break; case 'M': termw->graphicsinset[set] = LAT5_SET; break; #endif } /* end switch(c) */ } /* end if (ninetysix) */ } else { /* if in national character set mode */ switch (c) { /* the first set of these don't actually change the national mapping */ case '0': case '2': termw->graphicsinset[set] = GRAF_SET; return; /* don't change national mapping */ case '>': termw->graphicsinset[set] = TECH_SET; return; /* don't change national mapping */ /* the rest of these do change the national mapping */ case 'B': case '1': termw->nat_set = USA_NAT; break; case 'A': termw->nat_set = UK_NAT; break; case '4': termw->nat_set = DUTCH_NAT; break; case 'C': case '5': termw->nat_set = FINNISH_NAT; break; case 'R': termw->nat_set = FRENCH_NAT; break; case '9': case 'Q': termw->nat_set = FRENCHCAN_NAT; break; case 'K': termw->nat_set = GERMAN_NAT; break; case 'Y': termw->nat_set = ITALIAN_NAT; break; case '6': if (termw->intermedbuf[0] == '%') { termw->nat_set = PORTUGUESE_NAT; break; } /* else fall through to norwegian */ case '`': case 'E': termw->nat_set = NORWEGIAN_NAT; break; /* also Danish */ case 'Z': termw->nat_set = SPANISH_NAT; break; case '7': case 'H': termw->nat_set = SWEDISH_NAT; break; case '=': termw->nat_set = SWISS_NAT; break; } /* end switch(c) */ termw->graphicsinset[set] = ASCII_SET; set_char_map(termw); } } set_char_map (struct termw *termw) { register int i; for (i = 0; i < 128; i++) /* reset the character remapping map */ char_map[i] = (unsigned char) i; if (termw->nat_char_mode) { /* set the values for the national map */ char_map['#'] = nat_remaps[termw->nat_set][0]; char_map['@'] = nat_remaps[termw->nat_set][1]; char_map['['] = nat_remaps[termw->nat_set][2]; char_map['\\'] = nat_remaps[termw->nat_set][3]; char_map[']'] = nat_remaps[termw->nat_set][4]; char_map['^'] = nat_remaps[termw->nat_set][5]; char_map['_'] = nat_remaps[termw->nat_set][6]; char_map['`'] = nat_remaps[termw->nat_set][7]; char_map['{'] = nat_remaps[termw->nat_set][8]; char_map['|'] = nat_remaps[termw->nat_set][9]; char_map['}'] = nat_remaps[termw->nat_set][10]; char_map['~'] = nat_remaps[termw->nat_set][11]; } } /**************************************************************************** * draw a characer on the screen (or buffer it) * draw a bunch of characters on the screen (or at least lay them down on the * screen buffer and increment various pointers so we can draw them later). * * Assumes that we can draw all the given characters from where we are now * without overflowing the right edge of the screen (though we might write * up TO the right edge). We only do wrap checks and stuff AFTER adding the * characters to the screen buffer. ****************************************************************************/ void MDrawChars(struct termw *termw, register unsigned char *cp, int n) { /* while (--n >= 0) MDrawChar(termw, *cp++); */ register int cset; register unsigned char chr; if (n <= 0) /* sanity, just in case */ return; /* Are we about to wrap around? */ if (termw->curcol >= MAXCOL) { if (termw->autowrap) { /* If autowrap indicated wrap */ if (!termw->newline) carriage_return(termw); line_feed(termw); } else { back_space(termw); /* Otherwise just overwrite */ cp += n-1; /* setup to only print the last character */ n = 1; } } if (termw->old_Gl_set >= 0) { /* are we doing a single shift? */ int old = termw->old_Gl_set; /* save old Gl_set */ termw->old_Gl_set = -1; /* don't trigger this code recursively */ MDrawChars (termw, cp, 1); /* call ourselves to do this character */ cp++; n--; termw->Gl_set = old; /* restore old Gl_set */ if (n <= 0) /* if that was it, we are finished */ return; } if ((termw->out_maxcol == 0) || (termw->out_mincol > termw->curcol)) termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/ if (termw->insert) { /* Insert mode? */ termw->numarg[0] = n; insert_chars(termw); /* Open hole for char if requested */ } while (--n >= 0) { chr = *cp++; if (chr & 0x80) /* if a right-side (meta) character */ { if (termw->eightbit_disp) cset = termw->Gr_set; /* in the GR character set */ else cset = termw->Gl_set; /* in the GL character set */ chr &= 0177; /* trim to 7 bits */ } else { cset = termw->Gl_set; /* in the GL character set */ } if ((termw->nat_char_mode) || (termw->graphicsinset[cset] != ASCII_SET)) { if ((termw->nat_char_mode) && (termw->graphicsinset[cset] == ASCII_SET)) { chr = char_map[chr]; termw->textstyle &= STY_STY; /* reset to ASCII */ } else { if ((chr >= vt_to_fmap[termw->graphicsinset[cset]].lbound) && (chr <= vt_to_fmap[termw->graphicsinset[cset]].hbound)) { chr += vt_to_fmap[termw->graphicsinset[cset]].coffset; termw->textstyle = (termw->textstyle & STY_STY) | (vt_to_fmap[termw->graphicsinset[cset]].fnum) << 4; } else { termw->textstyle &= STY_STY; /* reset to ASCII */ } } } /* PWP: an inline version of: buf_char (chr); */ termw->scr[termw->curlin][termw->curcol] = chr; termw->scr_attrs[termw->curlin][termw->curcol] = (unsigned char) termw->textstyle; termw->curcol++; } /* Update the maximum of pending characters to reflect these ones */ if (termw->out_maxcol < termw->curcol) termw->out_maxcol = termw->curcol; /* count up one more char */ } #ifdef COMMENT /**************************************************************************** * draw a characer on the screen (or buffer it) * * ----------> WARNING WARNING WARNING!!! <----------- * If you change any of the if conditions that affect how a character is * drawn, you must also change the appropriate ifs in the CF_OUTC case * of printem(), since it incestiously knows about how this routine works ****************************************************************************/ void MDrawChar(struct termw *termw, register unsigned char chr) { /* register PFV_termwP funp; */ register int cset = termw->Gl_set; if (chr & 0x80) /* if a right-side (meta) character */ { cset = termw->Gr_set; /* then we are in the GR character set */ chr &= 0177; /* trim to 7 bits */ } if (termw->old_Gl_set >= 0) { /* are we doing a single shift? */ termw->Gl_set = termw->old_Gl_set; termw->old_Gl_set = -1; } if ((termw->nat_char_mode) && (termw->graphicsinset[cset] == ASCII_SET)) { chr = char_map[chr]; termw->textstyle &= STY_STY; /* reset to ASCII */ } else { if ((chr >= vt_to_fmap[termw->graphicsinset[cset]].lbound) && (chr <= vt_to_fmap[termw->graphicsinset[cset]].hbound)) { chr += vt_to_fmap[termw->graphicsinset[cset]].coffset; termw->textstyle = (termw->textstyle & STY_STY) | (vt_to_fmap[termw->graphicsinset[cset]].fnum) << 4; } else { termw->textstyle &= STY_STY; /* reset to ASCII */ } } if (termw->curcol >= MAXCOL) { /* Are we about to wrap around? */ if (termw->autowrap) { /* If autowrap indicated wrap */ if (termw->newline == FALSE) carriage_return(termw); line_feed(termw); } else { #ifdef COMMENT if (termw->scroll_amount) flushscroll(termw); /* sync the screen */ if (termw->out_maxcol) flushbuf(termw); /* make sure last char is shown */ #endif /* COMMENT */ back_space(termw); /* Otherwise just overwrite */ } } if (termw->insert) /* Insert mode? */ insert_char(termw); /* Open hole for char if requested */ /* PWP: an inline version of: buf_char (chr); */ if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol) termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/ if (termw->out_maxcol <= termw->curcol) termw->out_maxcol = termw->curcol + 1; /* count up one more char */ termw->scr[termw->curlin][termw->curcol] = chr; termw->scr_attrs[termw->curlin][termw->curcol] = (unsigned char) termw->textstyle; termw->curcol++; /* * Partial hack to handle double width characters. Add a space * after the real character. If it works, * will need to add code to handle insert mode, wraparound, etc. */ if (termw->dblw) { if (termw->insert) /* Insert mode? */ insert_char(termw); /* Open hole for char if requested */ /* PWP: an inline version of: buf_char (chr); */ if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol) /* No chars in buffer, init column*/ termw->out_mincol = termw->curcol; if (termw->out_maxcol <= termw->curcol) /* count up one more char */ termw->out_maxcol = termw->curcol + 1; termw->scr[termw->curlin][termw->curcol] = ' '; termw->scr_attrs[termw->curlin][termw->curcol] = (unsigned char) termw->textstyle; termw->curcol++; } } /* MDrawChar */ #endif /* COMMENT */ /****************************************************************************/ /* * Control character functions: * Each of the following allow the mac to simulate * the behavior of a terminal when given the proper * control character. */ /****************************************************************************/ void back_space (struct termw *termw) { if (termw->curcol > 0) relmove(termw,-1, 0); } /* back_space */ void erase_char (struct termw *termw) { termw->scr[termw->curlin][termw->curcol] = ' '; /* Erase char for update */ termw->scr_attrs[termw->curlin][termw->curcol] = 0; /* no attributes */ if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol) termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/ if (termw->out_maxcol <= termw->curcol) termw->out_maxcol = termw->curcol + 1; /* count up one more char */ } /* erase_char */ void tab (struct termw *termw) { int i; /* (UoR) find next tabstop */ i = termw->curcol + 1; while ((i < MAXCOL) && (tabstops[i] == 0)) i++; absmove(termw,i, termw->curlin); } /* tab */ /* PWP: if you change this, also change MDrawChar() above */ void line_feed (struct termw *termw) { if (to_printer) { /*JAO*/ if (termw->out_maxcol) flushbuf(termw); /* just in case */ #ifdef COMMENT (*hPrintBuffer)[lPrintBufferAt++] = 13; if (lPrintBufferAt == lPrintBufferSize) lPrintBufferAt = 0L; if (lPrintBufferChars == 1L) updatepstat(); lPrintBufferChars++; if (lPrintBufferChars == lPrintBufferSize) { overflowingDialog = GetNewDialog(OVERFLOWINGBOXID, NILPTR, (WindowPtr) - 1); DrawDialog(overflowingDialog); } #endif /* COMMENT */ add_to_print (1, "\015"); /* a return character */ } if (!to_screen) return; /* (PWP) A better place to log the session */ if (seslog) /* if logging is active then */ slog ((char *) termw->scr[termw->curlin], MAXCOL); /* write line to session log */ if (termw->newline) absmove(termw,0, termw->curlin); /* (UoR) perform termw->newline function */ if (termw->curlin == termw->scrbot) { scroll_screen(termw, termw->scrtop, termw->scrbot, -1); /* scroll lines up */ } else { if (termw->curlin >= termw->scrtop) /* if within scrolling region */ relmove(termw,0, 1); } } /* line_feed */ void reverse_line_feed (struct termw *termw) { if (termw->curlin == termw->scrtop) { /* scroll down in region */ scroll_screen(termw,termw->scrtop, termw->scrbot, 1); } else { if (termw->curlin <= termw->scrbot) /* if within scrolling region */ relmove(termw,0, -1); } } /* reverse_line_feed */ /* PWP: if you change this, also change MDrawChar() above */ void carriage_return (struct termw *termw) { if (termw->newline) line_feed(termw); /* (UoR) perform termw->newline function */ else absmove(termw,0, termw->curlin); } /* carriage_return */ void new_line (struct termw *termw) { carriage_return(termw); line_feed(termw); } /* new_line */ void clear_screen (struct termw *termw) { register int i; Rect r; if (termw->scroll_amount) flushscroll(termw); /* sync the screen */ if (termw->out_maxcol) flushbuf(termw); /* just in case */ makerect(termw,&r, 0, 0, termw->screensize, MAXCOL); /* The whole screen */ EraseRect (&r); for (i = 0; i < termw->screensize; i++) /* (PWP) clear from bottom up */ zeroline(termw, i, 1); /* Clear up the update records */ } /* clear_screen */ void push_clear_screen (struct termw *termw) { register int i, j, tlin; unsigned char *savedline, *savedattr; /* temporary to hold screen line pointer */ termw->display_totlines += termw->screensize; if (termw->display_totlines > MAX_SCREENSIZE) termw->display_totlines = MAX_SCREENSIZE; /* bounds */ /* top of saved buffer */ tlin = termw->screensize - termw->display_totlines; /* save cleared lines on scrollback buffer */ for (j = 0; j < termw->screensize; j++) { /* scroll screen buffer by one line */ savedline = termw->scr[tlin]; savedattr = termw->scr_attrs[tlin]; for (i = tlin+1; i <= botlin; i++) { termw->scr[i-1] = termw->scr[i]; termw->scr_attrs[i-1] = termw->scr_attrs[i]; } termw->scr[botlin] = savedline; termw->scr_attrs[botlin] = savedattr; } clear_screen(termw); } void vt_align (struct termw *termw) { register int l, c; if (termw->scroll_amount) flushscroll(termw); /* sync the screen */ if (termw->out_maxcol) flushbuf(termw); /* just in case */ for (l = 0; l < termw->screensize; l++) { absmove(termw,0, l); termw->out_mincol = termw->curcol; /* No chars in buffer, init column*/ for (c = 0; c < MAXCOL; c++) { termw->scr[l][c] = 'E'; termw->scr_attrs[l][c] = 0; } termw->out_maxcol = MAXCOL; /* Mark output buffer full */ flushbuf(termw); } absmove(termw,0, 0); } void home_cursor (struct termw *termw) { if (termw->relorigin) absmove(termw,0, termw->scrtop); else absmove(termw,0, 0); /* (UoR) correct for relative origin */ } /* home_cursor */ void bell (struct termw *termw) { Rect r; if (termw->visible_bell) { makerect(termw,&r, 0, 0, termw->screensize, MAXCOL); /* The whole screen */ InvertRect (&r); waitnoinput (); /* sleep for a bit (1/30 sec) */ InvertRect (&r); } else { SysBeep (3); } } /* bell */ /****************************************************************************/ /* does nothing. */ /****************************************************************************/ void dummy (struct termw *termw) { #pragma unused (termw) } /* dummy */ void toss_char (struct termw *termw) { termw->charflg = CF_TOSS; } /* toss_char */ void toss_till_st (struct termw *termw) { termw->charflg = CF_T_ST; } void norm_char (struct termw *termw) { termw->charflg = CF_OUTC; } void norm_home_clear_save(struct termw *termw) { norm_char(termw); home_cursor (termw); /* Go to the upper left */ clear_screen (termw); /* Clear the screen */ cursor_save (termw); /* Save this position */ } void escape_seq (struct termw *termw) { termw->intermedbuf[0] = '\0'; /* Initialize the numbers to zero */ termw->intermedptr = termw->intermedbuf; /* Place to put the next number */ termw->charflg = CF_ESC; /* Say we are in an escape sequence */ } /* escape_seq */ void csi_seq (struct termw *termw) { termw->argcount = 0; /* no arguments yet */ termw->numarg[0] = 0; /* Initialize the numbers to zero */ termw->paramarg[0][0] = '\0'; termw->argptr = termw->paramarg[0]; /* Place to put the next number */ termw->numbuf[0] = '\0'; /* init number buffer */ termw->numptr = termw->numbuf; termw->intermedbuf[0] = '\0'; /* Initialize the numbers to zero */ termw->intermedptr = termw->intermedbuf; /* Place to put the next number */ termw->charflg = CF_CSI; /* Say we are in a ESC [ sequence */ } /* csi_seq */ void dcs_seq (struct termw *termw) { csi_seq(termw); /* these are like CSI commands, but have strings too */ termw->charflg = CF_DCS; /* Say we are in a device control sequence */ } void string_term (struct termw *termw) { termw->charflg = CF_OUTC; } void vt320_mode(struct termw *termw) { #pragma unused (termw) } void graphic_G0 (struct termw *termw) { termw->charflg = CF_GS_0; } /* graphic_G0 */ void graphic_G1 (struct termw *termw) { termw->charflg = CF_GS_1; } /* graphic_G1 */ void graphic_G2 (struct termw *termw) { termw->charflg = CF_GS_2; } /* graphic_G1 */ void graphic_G3 (struct termw *termw) { termw->charflg = CF_GS_3; } /* graphic_G1 */ void control_N (struct termw *termw) { termw->Gl_set = 1; /* set to graphics set 1 */ } /* control_N */ /* shift in */ void control_O (struct termw *termw) { termw->Gl_set = 0; /* set to graphics set 0 */ } /* control_O */ void single_shift_2 (struct termw *termw) { termw->old_Gl_set = termw->Gl_set; termw->Gl_set = 2; } void single_shift_3 (struct termw *termw) { termw->old_Gl_set = termw->Gl_set; termw->Gl_set = 3; } void lock_shift_2 (struct termw *termw) { termw->Gl_set = 2; } void lock_shift_3 (struct termw *termw) { termw->Gl_set = 3; } void lock_shift_3r (struct termw *termw) { termw->Gr_set = 3; } void lock_shift_2r (struct termw *termw) { termw->Gr_set = 2; } void lock_shift_1r (struct termw *termw) { termw->Gr_set = 1; } void h19_graph_mode (struct termw *termw) { #pragma unused (termw) } void end_h19_graph_mode (struct termw *termw) { #pragma unused (termw) } void set_appl (struct termw *termw) { termw->appl_mode = TRUE; /* applications keypad mode */ } void reset_appl (struct termw *termw) { termw->appl_mode = FALSE; /* normal keypad mode */ } /* set vtNNN level of compatibility */ void set_compat (struct termw *termw) { if (termw->argcount < 2) termw->numarg[1] = 0; if (termw->argcount < 1) termw->numarg[0] = 0; if (termw->intermedbuf[0] == '"') { switch (termw->numarg[0]) { case 61: /* vt100 mode */ break; case 62: /* vt200 mode */ switch (termw->numarg[1]) { case 0: break; case 1: break; case 2: break; } } } } void set_charattr (struct termw *termw) { if (termw->intermedbuf[0] == '"') { switch (termw->numarg[0]) { case 0: /* all attributes off */ termw->ch_protect = FALSE; break; case 1: termw->ch_protect = TRUE; break; case 2: termw->ch_protect = FALSE; break; } } } void clear_line (struct termw *termw) { int i; if (termw->have_selection) maybe_nuke_selection (termw, termw->curlin, termw->curlin); switch (termw->numarg[0]) { case 0: /* Clear: here to the right */ for (i = termw->curcol; i < MAXCOL; i++) { termw->scr[termw->curlin][i] = ' '; termw->scr_attrs[termw->curlin][i] = 0; } if (termw->out_maxcol == 0 || termw->out_mincol > termw->curcol) termw->out_mincol = termw->curcol; termw->out_maxcol = MAXCOL; /* end of change */ break; case 1: /* Clear: left to here */ for (i = 0; i <= termw->curcol; i++) { termw->scr[termw->curlin][i] = ' '; termw->scr_attrs[termw->curlin][i] = 0; } termw->out_mincol = 0; /* start at beginning of line */ if (termw->out_maxcol <= termw->curcol) termw->out_maxcol = termw->curcol + 1; /* end of change */ break; case 2: /* Clear: entire line */ zeroline(termw, termw->curlin, 0); termw->out_mincol = 0; /* update the whole line */ termw->out_maxcol = MAXCOL; break; } } /* clear_line */ void erase_display(struct termw *termw) { int i; Rect r; switch (termw->numarg[0]) { case 0: /* clear from here to end */ if (termw->have_selection) maybe_nuke_selection (termw, termw->curlin, botlin); if ((termw->curlin == toplin) && (termw->curcol == 0)) { push_clear_screen(termw); /* save lines in scrollback buffer */ } else { clear_line(termw); /* Same termw->numarg[0] causes correct clear */ flushbuf(termw); makerect(termw, &r, termw->curlin + 1, 0, termw->screensize - termw->curlin - 1, MAXCOL); EraseRect (&r); for (i = termw->curlin + 1; i <= botlin; i++) zeroline(termw, i, 1); } break; case 1: /* clear from beginning to here */ if (termw->have_selection) maybe_nuke_selection (termw, toplin, termw->curlin); clear_line(termw); /* Same termw->numarg[0] causes correct clear */ flushbuf(termw); makerect(termw,&r, 0, 0, termw->curlin, MAXCOL); EraseRect (&r); for (i = toplin; i < termw->curlin; i++) zeroline(termw, i, 1); break; case 2: /* clear everything */ if (termw->have_selection) maybe_nuke_selection (termw, toplin, botlin); push_clear_screen(termw); /* save lines in scrollback buffer */ break; } } /* erase_display */ /****************************************************************************/ /**** All cursor moves need to check that they don't go beyond the margins */ /****************************************************************************/ void cursor_right (struct termw *termw) { if (termw->numarg[0] == 0) termw->numarg[0] = 1; relmove(termw,termw->numarg[0], 0); } /* cursor_right */ void cursor_left (struct termw *termw) { if (termw->numarg[0] == 0) termw->numarg[0] = 1; relmove(termw, -termw->numarg[0], 0); } /* cursor_left */ void cursor_up(struct termw *termw) { int abstop; /* (UoR) check that we don't pass scrtop */ abstop = termw->scrtop; if (termw->numarg[0] == 0) termw->numarg[0] = 1; if ((termw->curlin >= abstop) && (termw->curlin - termw->numarg[0] < abstop)) absmove(termw,termw->curcol, abstop); else relmove(termw,0, -termw->numarg[0]); } /* cursor_up */ void cursor_down (struct termw *termw) { int absbot; /* (UoR) check that we don't pass scrbot */ absbot = termw->scrbot; if (termw->numarg[0] == 0) termw->numarg[0] = 1; if ((termw->curlin <= absbot) && (termw->curlin + termw->numarg[0] > absbot)) absmove(termw,termw->curcol, absbot); else relmove(termw,0, termw->numarg[0]); } /* cursor_down */ void cursor_position (struct termw *termw) { if (termw->argcount < 2) termw->numarg[1] = 1; if (termw->argcount < 1) termw->numarg[0] = 1; if (termw->relorigin) absmove(termw,termw->numarg[1] - 1,termw->scrtop + termw->numarg[0] - 1); else absmove(termw,termw->numarg[1] - 1, termw->numarg[0] - 1); /* (UoR) moved "--" here from prev lines */ } /* cursor_position */ void cursor_h_pos (struct termw *termw) { absmove(termw,termw->numarg[0] - 1, termw->curlin); } /* cursor_h_pos */ /* ESC 7 */ void cursor_save (struct termw *termw) { termw->savcol = termw->curcol; /* Save the current line and column */ termw->savlin = termw->curlin; termw->savsty = termw->textstyle; /* (UoR) additions */ termw->savGl = termw->Gl_set; termw->savGr = termw->Gr_set; termw->savset[0] = termw->graphicsinset[0]; termw->savset[1] = termw->graphicsinset[1]; termw->savset[2] = termw->graphicsinset[2]; termw->savset[3] = termw->graphicsinset[3]; } /* cursor_save */ /* ESC 8 */ void cursor_restore (struct termw *termw) { if (termw->intermedbuf[0] == '#') { vt_align(termw); return; } /* Move to the old cursor position */ absmove(termw, termw->savcol, termw->savlin); termw->textstyle = termw->savsty; /* (UoR) additions */ termw->Gl_set = termw->savGl; termw->Gr_set = termw->savGr; termw->graphicsinset[0] = termw->savset[0]; termw->graphicsinset[1] = termw->savset[1]; termw->graphicsinset[2] = termw->savset[2]; termw->graphicsinset[3] = termw->savset[3]; } /* cursor_restore */ void set_scroll_region(struct termw *termw) { if (termw->argcount < 2) termw->numarg[1] = 0; if (--termw->numarg[0] < 0) termw->numarg[0] = 0; /* Make top of line (prev line) */ if (termw->numarg[1] == 0) termw->numarg[1] = termw->screensize; /* Zero means entire screen */ /* (UoR) make sure region is legal */ if (termw->numarg[0] < termw->numarg[1] - 1) { termw->topmargin = (termw->numarg[0] * termw->lineheight) + TOPMARGIN; termw->bottommargin = (termw->numarg[1] * termw->lineheight) + TOPMARGIN; termw->scrtop = termw->numarg[0]; termw->scrbot = termw->numarg[1] - 1; home_cursor (termw); /* We're supposed to home it! */ } } /* set_scroll_region */ /****************************************************************************/ /* aka Select Graphic Rendition */ /****************************************************************************/ void text_mode (struct termw *termw) { int i; if (termw->argcount == 0) { termw->argcount = 1; termw->numarg[0] = 0; } for (i = 0; i < termw->argcount; i++) { switch (termw->numarg[i]) { case 0: /* primary rendition */ termw->textstyle = 0; break; case 1: /* bold or increased intensity */ termw->textstyle |= VT_BOLD; break; case 4: /* underscore */ termw->textstyle |= VT_UNDER; /* (PWP) */ break; case 2: /* faint or decreased intensity or * secondary color */ case 3: /* italic */ case 5: /* slow blink (< 150/sec); (UoR) blink is * inverse */ case 6: /* fast blink (>= 150/sec) */ termw->textstyle |= VT_BLINK; break; case 7: /* reverse image */ termw->textstyle |= VT_INVERT; /* (PWP) */ break; case 21: /* ??? */ case 22: /* normal intensity */ termw->textstyle &= ~(VT_BOLD); /* (PWP) */ break; case 24: /* not underlined */ termw->textstyle &= ~(VT_UNDER); /* (PWP) */ break; case 25: /* not blinking */ termw->textstyle &= ~(VT_BLINK); /* (PWP) */ break; case 27: /* not reversed */ termw->textstyle &= ~(VT_INVERT); /* (PWP) */ break; } } } /* text_mode */ void line_dblh_top(struct termw *termw) { if (termw->intermedbuf[0] == '#') { termw->line_attrs[termw->curlin] = VT_DBLH_T; termw->out_mincol = 0; /* update the whole line */ termw->out_maxcol = MAXCOL; } } void line_dblh_bot(struct termw *termw) { if (termw->intermedbuf[0] == '#') { termw->line_attrs[termw->curlin] = VT_DBLH_B; termw->out_mincol = 0; /* update the whole line */ termw->out_maxcol = MAXCOL; } } /* single width line */ void line_singw(struct termw *termw) { if (termw->intermedbuf[0] == '#') { termw->line_attrs[termw->curlin] = VT_SNGL; termw->out_mincol = 0; /* update the whole line */ termw->out_maxcol = MAXCOL; } } /* double width line */ void line_dblw(struct termw *termw) { if (termw->intermedbuf[0] == '#') { termw->line_attrs[termw->curlin] = VT_DBLW; termw->out_mincol = 0; /* update the whole line */ termw->out_maxcol = MAXCOL; } } void start_selected(struct termw *termw) { #pragma unused (termw) } void end_selected(struct termw *termw) { #pragma unused (termw) } /****************************************************************************/ /* * (UoR) * * Insert and Delete lines (replacements for originals, which have * which have been deleted) * */ /****************************************************************************/ void insert_line(struct termw *termw) { int absbot; absbot = termw->scrbot; if ((termw->curlin >= termw->scrtop) && (termw->curlin <= absbot)) { if (termw->numarg[0] == 0) termw->numarg[0] = 1; if (termw->numarg[0] > absbot - termw->curlin + 1) termw->numarg[0] = absbot - termw->curlin + 1; scroll_screen(termw,termw->curlin, termw->scrbot, termw->numarg[0]); } } /* termw->insert_line */ void delete_line (struct termw *termw) { int absbot; absbot = termw->scrbot; if ((termw->curlin >= termw->scrtop) && (termw->curlin <= absbot)) { if (termw->numarg[0] == 0) termw->numarg[0] = 1; if (termw->numarg[0] > absbot - termw->curlin + 1) termw->numarg[0] = absbot - termw->curlin + 1; scroll_screen(termw,termw->curlin, termw->scrbot, -termw->numarg[0]); } } /* delete_line */ void delete_char (struct termw *termw) { int i; if (termw->numarg[0] == 0) termw->numarg[0] = 1; if (termw->numarg[0] > MAXCOL - termw->curcol - 1) termw->numarg[0] = MAXCOL - termw->curcol - 1; /* Shift them down *//* (UoR) used to assign using abscol */ for (i = termw->curcol; i < MAXCOL - termw->numarg[0]; i++) { termw->scr[termw->curlin][i] = termw->scr[termw->curlin][i + termw->numarg[0]]; termw->scr_attrs[termw->curlin][i] = termw->scr_attrs[termw->curlin][i + termw->numarg[0]]; } /* * Fill in holes with spaces * PWP 7/09/92 -- WOW! this has been wrong for about 4 years; * fixed spaces bug */ for (i = MAXCOL - termw->numarg[0]; i < MAXCOL; i++) { termw->scr[termw->curlin][i] = ' '; termw->scr_attrs[termw->curlin][i] = 0; } /* say the line is dirty from the current position to the end */ if (termw->out_mincol > termw->curcol) termw->out_mincol = termw->curcol; termw->out_maxcol = MAXCOL; } /* delete_char */ /****************************************************************************/ /* CME */ /****************************************************************************/ void insert_chars (struct termw *termw) { int i, n; n = termw->numarg[0]; if (n == 0) n = 1; if (n > MAXCOL - termw->curcol - 1) n = MAXCOL - termw->curcol - 1; /* Shift them up *//* (UoR) used to assign using abscol */ for (i = MAXCOL - 1; i >= termw->curcol + n; i--) { termw->scr[termw->curlin][i] = termw->scr[termw->curlin][i - n]; termw->scr_attrs[termw->curlin][i] = termw->scr_attrs[termw->curlin][i - n]; } /* * Fill in holes with spaces * PWP 1/07/91 -- WOW! this has been wrong for about 3 years; * fixed spaces bug */ for (i = termw->curcol; i < termw->curcol + n; i++) { termw->scr[termw->curlin][i] = ' '; termw->scr_attrs[termw->curlin][i] = 0; } /* say the line is dirty from the current position to the end */ if (termw->out_mincol > termw->curcol) termw->out_mincol = termw->curcol; termw->out_maxcol = MAXCOL; } /* termw->insert_chars */ void insert_char(struct termw *termw) { int i; /* Shift em up *//* (UoR) used to assign ...[i-1]=...[i] */ /* (UoR) used to assign using abscol */ for (i = MAXCOL - 1; i > termw->curcol; i--) { termw->scr[termw->curlin][i] = termw->scr[termw->curlin][i - 1]; termw->scr_attrs[termw->curlin][i] = termw->scr_attrs[termw->curlin][i-1]; } termw->scr[termw->curlin][termw->curcol] = ' '; termw->scr_attrs[termw->curlin][termw->curcol] = 0; /* say the line is dirty from the current position to the end */ if (termw->out_mincol > termw->curcol) termw->out_mincol = termw->curcol; termw->out_maxcol = MAXCOL; } /* termw->insert_char */ void insert_mode (struct termw *termw) { int i; if (termw->argcount < 1) { termw->numarg[0] = 0; termw->argcount = 1; } for (i = 0; i < termw->argcount; i++) { /* handle multiple arguments */ if (termw->paramarg[i][0] == '?') { set_mode (termw, termw->numarg[i]);/* do some of these calls */ } else if (termw->paramarg[i][0] == '>') { /* (PWP) Heath ANSI stuff */ set_heath_mode(termw, termw->numarg[i]); } else { switch (termw->numarg[i]) { case 20: /* termw->newline mode */ termw->newline = TRUE; break; case 12: /* send/recieve */ break; case 4: /* termw->insert mode */ termw->insert = TRUE; break; } } } } /* termw->insert_mode */ void end_insert_mode (struct termw *termw) { int i; if (termw->argcount < 1) { termw->numarg[0] = 0; termw->argcount = 1; } for (i = 0; i < termw->argcount; i++) { /* handle multiple arguments */ if (termw->paramarg[i][0] == '?') { reset_mode (termw, termw->numarg[i]); /* (UoR) do some of these calls */ } else if (termw->paramarg[i][0] == '>') { /* (PWP) Heath ANSI stuff */ reset_heath_mode(termw, termw->numarg[i]); } else { switch (termw->numarg[i]) { case 20: /* termw->newline mode */ termw->newline = FALSE; break; case 12: /* send/recieve */ break; case 4: /* termw->insert mode */ termw->insert = FALSE; break; } } } } /* end_termw->insert_mode */ /****************************************************************************/ void printer_control (struct termw *termw) { switch (termw->numarg[0]) { /* "ESC [ ? # i" */ case 5: /* Start printing */ if (to_printer) break; #ifdef COMMENT if (hPrintBuffer == 0L) { lPrintBufferSize = FreeMem(); do { lPrintBufferSize = (lPrintBufferSize >> 1) + (lPrintBufferSize >> 2); hPrintBuffer = NewHandle(lPrintBufferSize); } while (hPrintBuffer == NIL); lPrintBufferSize = (lPrintBufferSize * 2) / 3; SetHandleSize(hPrintBuffer, lPrintBufferSize); lPrintBufferAt = lPrintBufferChars = 0L; } else { (*hPrintBuffer)[lPrintBufferAt++] = 014; if (lPrintBufferAt == lPrintBufferSize) lPrintBufferAt = 0L; lPrintBufferChars++; } overflowingDialog = 0L; if (lPrintBufferChars == lPrintBufferSize) { /*JAOtemp*/ overflowingDialog = GetNewDialog(OVERFLOWINGBOXID, NILPTR, (WindowPtr) - 1); DrawDialog(overflowingDialog); /*JAOtemp*/ } /*JAOtemp*/ #endif /* COMMENT */ if ((*prntw->teh)->teLength != 0) /* if we already have stuff to print */ add_to_print (1, "\014"); /* add a formfeed character */ to_printer = TRUE; if (termw->paramarg[0][0] == '?') to_screen = TRUE; else to_screen = FALSE; upd_ptr_dlg(); break; case 4: /* Stop printing */ if (!to_printer) break; to_printer = FALSE; to_screen = TRUE; updatepstat(); upd_ptr_dlg(); break; } } /* end of printer_control */ /*JAO*/ /* * NOTE: this is called externally (outside of inpchars()). */ void invert_term (struct termw *termw) { if (termw->screeninvert) reset_mode (termw, 5); else set_mode (termw, 5); } /* invert_term */ /* we get here by ESC [ ? numarg[0]> h */ void set_mode (struct termw *termw, int arg) { switch (arg) { case 1: /* cursor key mode */ termw->curskey_mode = TRUE; break; case 2: /* keyboard lock */ break; /* we never do keyboard lock */ case 3: /* 132 column */ break; case 4: /* smooth scroll */ termw->smoothscroll = TRUE; break; case 5: /* reverse screen */ set_term_invert(termw, TRUE); break; case 6: /* relative origin mode */ termw->relorigin = TRUE; home_cursor (termw); break; case 7: /* auto wrap */ termw->autowrap = TRUE; break; case 8: /* auto repeat */ termw->autorepeat = TRUE; break; case 18: /* print form feed */ break; case 19: /* print extent */ break; case 25: /* text cursor enable */ break; case 38: /* Tektronics mode */ break; case 42: /* international character set */ termw->nat_char_mode = TRUE; set_char_map(termw); break; case 43: /* graphics expanded print */ break; case 44: /* graphics print color */ break; case 45: /* graphics print color syntax */ break; case 46: /* graphics print background */ break; case 47: /* graphics rotated print */ break; } } /* set_mode */ /* we get here by ESC [ ? numarg[0]> l */ void reset_mode (struct termw *termw, int arg) { switch (arg) { case 1: /* cursor key mode */ termw->curskey_mode = FALSE; break; case 2: /* keyboard lock */ break; /* we never do keyboard lock */ case 3: /* 132 column */ break; case 4: /* smooth scroll */ termw->smoothscroll = FALSE; break; case 5: /* reverse screen */ set_term_invert(termw, FALSE); break; case 6: /* relative origin mode */ termw->relorigin = FALSE; home_cursor (termw); break; case 7: /* auto wrap */ termw->autowrap = FALSE; break; case 8: /* auto repeat */ termw->autorepeat = FALSE; break; case 18: /* print form feed */ break; case 19: /* print extent */ break; case 25: /* text cursor enable */ break; case 38: /* Tektronics mode */ break; case 42: /* international character set */ termw->nat_char_mode = FALSE; set_char_map(termw); /* reset the display translate table */ break; case 43: /* graphics expanded print */ break; case 44: /* graphics print color */ break; case 45: /* graphics print color syntax */ break; case 46: /* graphics print background */ break; case 47: /* graphics rotated print */ break; } } /* reset_mode */ /* we get here by ESC [ > numarg[0]> h */ void set_heath_mode (struct termw *termw, int arg) { switch (arg) { case 1: /* enable status (25th) line */ case 2: /* disable key click */ case 3: /* enter hold screen mode (we never do this) */ break; case 4: /* block cursor */ termw->blockcursor = TRUE; break; case 5: /* show cursor */ termw->cursor_shown = TRUE; break; case 6: /* keypad shifted */ case 7: /* enter alternate keypad mode */ case 8: /* auto LF on CR */ case 9: /* auto CR on LF */ break; } } void reset_heath_mode (struct termw *termw, int arg) { switch (arg) { case 1: /* disable status (25th) line */ case 2: /* enable key click */ case 3: /* exit hold screen mode (we never do this) */ break; case 4: /* underline cursor */ termw->blockcursor = FALSE; break; case 5: /* hide cursor */ termw->cursor_shown = FALSE; break; case 6: /* keypad shifted */ case 7: /* enter alternate keypad mode */ case 8: /* auto LF on CR */ case 9: /* auto CR on LF */ break; } } void set_tab(struct termw *termw) { tabstops[termw->curcol] = 1; } /* set_tab */ void clear_tab(struct termw *termw) { int i; switch (termw->numarg[0]) { case 0: tabstops[termw->curcol] = 0; break; case 3: for (i = 0; i < MAXCOL; i++) tabstops[i] = 0; break; } } /* clear_tab */ /****************************************************************************/ /* (UoR) use for respoding to information requests */ /****************************************************************************/ void writereply (char *s) { long wrcnt, w2; int err; char *s2; w2 = wrcnt = strlen (s); /* How long is the string? */ for (s2 = s; w2 > 0; w2--, s2++) /* add parity */ *s2 = dopar (*s2); err = FSWrite (outnum, &wrcnt, s); /* Respond to the query */ if (err) printerr ("Bad Writeout:", err); } /* writereply */ void query_terminal (struct termw *termw) { #pragma unused (termw) writereply (querystring); } /* query_terminal */ /****************************************************************************/ /* (UoR) reports */ /****************************************************************************/ void request_report (struct termw *termw) { switch (termw->numarg[0]) { case 5: /* (UoR) report that we're OK */ writereply (reportstring); break; case 6: /* (UoR) reprt the cursor position */ position_report(termw); break; case 15: /* (UoR) report printer status */ if (termw->paramarg[0][0] == '?') writereply (noprinter); break; } } /* request_report */ void position_report(struct termw *termw) { int i; char buf[9]; char *report; i = 0; buf[i++] = '\033'; buf[i++] = '['; if (termw->curlin > 9) buf[i++] = '0' + (termw->curlin + 1) / 10; buf[i++] = '0' + (termw->curlin + 1) % 10; buf[i++] = ';'; if (termw->curcol > 9) buf[i++] = '0' + (termw->curcol + 1) / 10; buf[i++] = '0' + (termw->curcol + 1) % 10; buf[i++] = 'R'; buf[i] = '\0'; report = buf; writereply (report); } /* position_report */ /****************************************************************************/ /* Routine zeroline * * Zero (set to space) all the characters in absolute line lin. * */ /****************************************************************************/ void zeroline(struct termw *termw, int lin, int line_attrs_also) { register int i; register unsigned char *sc_cp, *at_cp; sc_cp = termw->scr[lin]; at_cp = termw->scr_attrs[lin]; i = MAXCOL; do { *sc_cp++ = ' '; *at_cp++ = 0; } while (--i > 0); *sc_cp = ' '; *at_cp = 0; if (line_attrs_also) termw->line_attrs[lin] = VT_SNGL; /* reset line attributes */ } /* zeroline */ /****************************************************************************/ /* Move a relative number of lines and chars. Both can be negative. */ /****************************************************************************/ void relmove(struct termw *termw, int hor, int ver) { /* * (UoR) use absmove, which checks * for cursor moving off screen. */ absmove(termw,termw->curcol + hor, termw->curlin + ver); } /* relmove */ /****************************************************************************/ /* Move to absolute position hor char and ver line. */ /****************************************************************************/ void absmove(struct termw *termw, int hor, int ver) { if (hor > MAXCOL - 1) hor = MAXCOL - 1; /* (UoR) make sure its on the screen */ if (hor < 0) hor = 0; if (ver > termw->screensize - 1) ver = termw->screensize - 1; if (ver < 0) ver = 0; if (termw->relorigin) { if (ver < termw->scrtop) ver = termw->scrtop; if (ver > termw->scrbot) ver = termw->scrbot; } if (termw->scroll_amount) { /* * If we have a saved scroll, and we are about to move outside of * the region that will get drawn in the process of doing the scroll, * then redraw the scrolling region now to avoid getting confused. */ if (termw->scroll_amount < 0) { /* FORWARD scrolling */ if ((ver < termw->saved_blin+termw->refresh_amount) || (ver > termw->saved_blin)) { flushscroll(termw); /* sync the screen */ } } else { /* REVERSE scrolling */ if ((ver < termw->saved_tlin) || (ver > termw->saved_tlin+termw->refresh_amount)) { flushscroll(termw); /* sync the screen */ } } } else { /* no saved scroll */ if (ver != termw->curlin) { if (termw->out_maxcol) flushbuf(termw); /* draw pending output */ } } termw->curcol = hor; termw->curlin = ver; } /* absmove */ /****************************************************************************/ /* dump the whole screen to the session log file */ /****************************************************************************/ void scrtolog(struct termw *termw) { int lin, i; lin = toplin; for (i = 0; i < termw->screensize; i++) { slog ((char *) termw->scr[lin], MAXCOL);/* write this line to session log */ lin++; /* lin = nxtlin[lin]; */ } } /* scrtolog */ void scrlasttolog(struct termw *termw) { /* write last line to session log*/ slog ((char *) termw->scr[termw->screensize-1], MAXCOL); } /* * doesc * Process an escape character argument * Returns FALSE normally, TRUE if quoted sequence. */ int doesc (char c) { CHAR d; char temp[100]; extern int cmask, cmdmsk; extern char ttname[]; extern char *sesfil; struct termw *termw; while (1) { if (c == escape) { /* Send escape character */ d = dopar(c); ttoc(d); return FALSE; } else /* Or else look it up below. */ if (isupper(c)) c = tolower(c); switch(c) { case 'c': /* Close connection */ case '\03': connected = 0; /* * force up the command window. */ termw = ctermw; kShowWindow(termw); kSelectWindow(termw->window); return FALSE; case 'b': /* Send a BREAK signal */ case '\02': ttsndb(); return FALSE; #ifdef notdef case 'h': /* Hangup */ case '\010': #ifdef SUNX25 if (network && (nettype == NET_SX25)) dox25clr = 1; else #endif /* SUNX25 */ dohangup = 1; connected = 0; printf("\r\n"); return FALSE; #ifdef SUNX25 case 'i': /* Send an X.25 interrupt packet */ case '\011': if (network && (nettype == NET_SX25)) (VOID) x25intr(0); printf("\r\n"); return FALSE; case 'r': /* Reset the X.25 virtual circuit */ case '\022': if (network && (nettype == NET_SX25)) (VOID) x25reset(); printf("\r\n"); return FALSE; #endif /* SUNX25 */ #endif /* notdef */ case 'q': #ifdef notdef quitnow = 1; #endif connected = 0; printf("\r\n"); return FALSE; case 's': /* Status */ printf("\r\nConnected thru "); printf(ttname); #ifdef SUNX25 if (network && (nettype == NET_SX25)) printf(", Link ID %d, LCN %d",linkid,lcn); #endif /* SUNX25 */ if (speed >= 0L) { sprintf(temp,", speed %ld",speed); printf(temp); } sprintf(temp,", %d terminal bits",(cmask == 0177) ? 7 : 8); printf(temp); if (parity) { printf(", "); switch (parity) { case 'e': printf("even"); break; case 'o': printf("odd"); break; case 's': printf("space"); break; case 'm': printf("mark"); break; } printf(" parity"); } if (seslog) { printf(", logging to "); printf(sesfil); } printf("\n"); return FALSE; #ifdef notdef case '?': /* Help */ c = hconne(); continue; #endif case '0': /* Send a null */ c = '\0'; d = dopar(c); ttoc(d); return FALSE; #ifdef notdef case 'z': case '\032': /* Suspend */ stptrap(0); return; case '@': /* Start inferior command processor */ case '!': conres(); /* Put console back to normal */ zshcmd(""); /* Fork a shell. */ if (conbin(escape) < 0) { printf("Error returning to remote session\n"); connected = 0; } return; #endif case SP: /* Space, ignore */ return FALSE; case CMDQ: return TRUE; /* Backslash escape */ default: /* Other */ putchar(BEL); /* Invalid esc arg, beep */ return FALSE; } } } /* * Junk so Emacs will set local variables to be compatible with Mac/MPW. * Should be at end of file. * This module uses 8 char tabs * * Local Variables: * tab-width: 8 * End: */