home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
ckc095.tar.gz
/
ckc095.tar
/
ckmcon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-22
|
63KB
|
2,583 lines
/* 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 Frank on June 20 - Add parity to all outbound chars using software */
/* Also, ignore DEL (0177) characters on input. */
/* By Bill on May 29 - Add Key set translation */
/* By 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"
#define __SEG__ ckmcon
#include <quickdraw.h>
#include <controls.h>
#include <files.h>
#include <events.h>
#include <windows.h>
#include <dialogs.h>
#include <menus.h>
#include <toolutils.h>
#include <osutils.h>
#include <ctype.h>
#include "ckmdef.h"
#include "ckmasm.h" /* Assembler code */
#include "ckmres.h" /* kermit resources */
#include "ckmcon.h" /* defines, etc. for terminal emulator */
RgnHandle dummyRgn; /* dummy region for ScrollRect */
/* 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 <emcmanus@csvax1.tcd.ie> */
short 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
};
extern int textstyle; /* (UoR) current style */
int screensize = INIT_SCREENSIZE, /* variable number of lines on screen */
topmargin, /* Edges of adjustable window */
bottommargin,
graphicsinset[4] = {ASCII_SET, ASCII_SET, LAT1_SET, LAT1_SET}, /* (UoR) current character sets */
Gl_set = 0, /* (UoR) current chosen set */
Gr_set = 1, /* (PWP) current chosen RH set */
old_Gl_set = -1; /* (PWP) set to come back to after single shift GL */
ch_protect = FALSE, /* Flag for protected characters (PWP) */
screeninvert = FALSE, /* (UoR) inverted screen flag */
insert = FALSE,
newline = FALSE, /* (UoR) linefeed mode by default */
autowrap = TRUE, /* Autowrap on by default */
relorigin = FALSE, /* (UoR) relative origin off */
autorepeat = TRUE, /* (UoR) auto repeat flag */
appl_mode = FALSE, /* (PWP) keypad application mode */
curskey_mode = FALSE, /* (PWP) cursor key application mode */
smoothscroll = FALSE, /* do smooth scrolling (PWP: or not) */
transparent = TRUE, /* do not show control characters */
blockcursor = TRUE, /* show block or underline cursor */
cursor_shown = TRUE, /* (PWP) show the cursor */
mouse_arrows = FALSE, /* mouse down in screen does arrow keys */
visible_bell = FALSE, /* true if we do blink instead of bell */
eightbit_disp = FALSE, /* do 8 bit wide to the screen */
nat_char_mode = FALSE, /* true if we are doing 7 bit national
character sets rather than ISO 8859 */
nat_set = 0; /* national char. set used */
blinkcursor = TRUE; /* true if we make the cursor blink */
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.
*/
ucharptr *scr, *scr_attrs; /* virtual screen, attributes pointer */
ucharptr real_scr[MAX_SCREENSIZE]; /* The real screen, including scrollback */
ucharptr real_attrs[MAX_SCREENSIZE]; /* the attributes of each character */
extern int display_topline; /* top line actually displayed */
extern int display_totlines; /* number of real lines in screen + scrollback */
int curlin, curcol; /* Cursor position */
int savcol, savlin; /* Cursor save variables */
int savsty, savfnt, savGl, savGr,
savmod, savset[4]; /* (UoR) cursor save variables */
int savund; /* PWP for saved underlining */
int scrtop, scrbot; /* Absolute scrolling region bounds */
/*****************************************/
/* Stuff for escape character processing */
#define CF_OUTC 0 /* Just output the char */
#define CF_ESC 1 /* In a single char escape seq */
#define CF_CSI 2 /* In a multi char '[' escape seq */
#define CF_TOSS 3 /* Toss this char */
#define CF_GS_0 4 /* (UoR) for graphics sequence 0, allways 94 char set */
#define CF_GS_1 5 /* (UoR) GS 1, 94 char. set */
#define CF_GS_2 6 /* (PWP) GS 2, 94 char. set */
#define CF_GS_3 7 /* (PWP) GS 3, 94 char. set */
#define CF_T_ST 8 /* (PWP) Toss chars till ST */
#define CF_DCS 9 /* (PWP) In a device control string sequence */
int charflg = CF_OUTC; /* state variable */
char intermedbuf[NUMBUFSIZ], *intermedptr; /* intermed. char buffer */
char paramarg[MAX_ARGCOUNT][NUMBUFSIZ], *argptr; /* (non-num) parameter buffer */
int numarg[MAX_ARGCOUNT], argcount; /* numeric argument buffer */
char numbuf[NUMBUFSIZ], *numptr; /* buffer for collecting numbers into numarg */
/*****************************************/
/* extern CSParam controlparam; */
extern unsigned char dopar ();
typedef void (*PFV) ();
/* Terminal function declarations. */
void
tab (), back_space (), carriage_return (), line_feed (), bell (),
csi_seq (), dcs_seq(), toss_char (), toss_till_st(), norm_char(),
escape_seq (), string_term(),
vt320_mode(), vt52_mode(),
text_mode (), clear_line (), erase_display (),
cursor_position (), cursor_up (), cursor_down (), cursor_right (),
cursor_left (), cursor_save (), cursor_restore (), set_scroll_region (),
reverse_line_feed (), dummy (), delete_char (), insert_mode (),
end_insert_mode (), insert_line (), delete_line (), query_terminal (),
insert_char (), insert_chars (),
erase_char(), cursor_h_pos(), home_cursor(),
/* (PWP) stuff for line width and height */
line_dblh_top(), line_dblh_bot(), line_singw(), line_dblw(),
printer_control (), /*JAO*/
/* (UoR) for VT100 graphic character set */
graphic_G0 (), graphic_G1 (), graphic_G2 (), graphic_G3 (),
control_N (), control_O (), single_shift_2(), single_shift_3(),
lock_shift_2(), lock_shift_3(), lock_shift_3r(), lock_shift_2r(),
lock_shift_1r(),
set_appl (), reset_appl (), set_compat(),
set_charattr(), start_selected(), end_selected(),
/* PWP: random support routines */
set_mode (), reset_mode(),
set_heath_mode (), reset_heath_mode(),
position_report(), zeroline(),
relmove(), absmove(),
/* (UoR) for other VT100 functions */
new_line (), request_report (), set_tab (), clear_tab ();
extern int to_printer; /*JAO*/
extern int to_screen; /*JAO*/
extern int printer_is_on_line_num; /*JAO*/
extern Handle hPrintBuffer; /*JAO*/
extern long lPrintBufferSize; /*JAO*/
extern long lPrintBufferChars; /*JAO*/
extern long lPrintBufferAt; /*JAO*/
extern DialogPtr bufferingDialog; /*JAO*/
extern DialogPtr overflowingDialog; /*JAO*/
extern MenuHandle menus[]; /* handle on our menus */ /*JAO*/
extern WindowPtr terminalWindow; /* the terminal window */
#ifdef COMMENT /* (PWP) this is done with a case statement below */
/* Terminal control character function command table. */
#define MINSINGCMDS 000
#define MAXSINGCMDS 037
PFV controltable[MAXSINGCMDS - MINSINGCMDS + 1] =
{
dummy, /* 0 */
dummy, /* 1 */
dummy, /* 2 */
dummy, /* 3 */
dummy, /* 4 */
dummy, /* 5 */
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 */
dummy, /* 22 */
dummy, /* 23 */
dummy, /* 24 */
dummy, /* 25 */
dummy, /* 26 */
dummy, /* 27 */
dummy, /* 30 */
dummy, /* 31 */
dummy, /* 32 */
escape_seq, /* 33 (Escape) */
dummy, /* 34 */
dummy, /* 35 */
dummy, /* 36 */
dummy /* 37 */
};
#endif /* COMMENT */
#define MIN_ESC 0060
#define MAX_ESC 0177
PFV 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 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 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 */
clear_eol, /* 113 */
insert_line, /* 114 */
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 ()
{
register int rdcnt;
register char *cp, *maxp;
static char buf[128];
if (curlin < 0 || curlin >= screensize)
fatal("inpchars(): curlin out of bounds:", curlin);
if (curcol < 0 || curcol > MAXCOL) /* PWP: can be == when autowraping */
fatal("inpchars(): curcol out of bounds:", curcol);
if (display_topline < (screensize - MAX_SCREENSIZE) || display_topline > 0)
fatal("inpchars(): display_topline out of bounds:", display_topline);
if ((rdcnt = ttinm(buf, sizeof(buf))) > 0) {
cursor_erase (); /* remove cursor from screen */
screen_to_bottom (); /* slide the visible region to active area */
maxp = buf + rdcnt;
if (parity)
for (cp = buf; cp < maxp; cp++) /* Output all those characters */
printit(*cp & 0177); /* strip off parity bits */
else
for (cp = buf; cp < maxp; cp++) /* Output all those characters */
printit(*cp);
if (!ttchk()) {
flushbuf (); /* Flush any remaining characters */
cursor_draw (); /* put it back */
update_vscroll();
}
}
} /* inpchars */
/****************************************************************************/
/*
* (UoR)
*
* Print a string to the screen (used to echo function and meta strings
* in duplex mode).
*
*/
/****************************************************************************/
printps (s)
char *s;
{
long w2;
char *s2;
cursor_erase ();
w2 = *s++; /* get count */
for (s2 = s; w2 > 0; w2--, s2++)
printit (*s2); /* print it out, and perform special
* functions */
flushbuf ();
cursor_draw ();
return;
} /* printps */
/****************************************************************************/
/*
* Lookup:
* Lookup a given character in the apropriate character table, and
* return a pointer to the appropriate function, if it exists.
*/
/****************************************************************************/
PFV
lookup (index, table, min, max)
unsigned char index;
PFV table[];
int min;
int max;
{
if (index > max || index < min)
return ((PFV) NULL); /* Don't index out of range */
return (table[index - min]);
} /* lookup */
/* tie off the current numeric argument */
void
end_numarg()
{
long lnum = 0; /* can't be register */
if (argcount < MAX_ARGCOUNT) {
if (argptr > paramarg[argcount] + NUMBUFSIZ - 1)
argptr = paramarg[argcount] + NUMBUFSIZ - 1; /* bounds */
*argptr = '\0'; /* tie off paramter argument */
if (numptr > numbuf + NUMBUFSIZ - 1)
numptr = numbuf + NUMBUFSIZ - 1; /* bounds */
*numptr = '\0'; /* tie off number string */
if (numptr > numbuf) { /* if we had a number collected */
StringToNum (numbuf, &lnum); /* Translate the numbers */
if (lnum < 0) lnum = 0;
if (lnum > 9999) lnum = 9999; /* ANSI says between 0 and 9999 */
} else {
lnum = 0;
}
numarg[argcount++] = lnum;
}
argptr = paramarg[argcount]; /* Go to next number */
numptr = numbuf; /* reset buffer */
}
/****************************************************************************/
/*
* Printit:
* Draws character and updates buffer
*/
/****************************************************************************/
printit (c)
register unsigned char c;
{
register PFV funp;
PFV lookup ();
int char_set = ASCII_SET;
if (!eightbit_disp)
c &= 0177;
if (c != 0) { /* (UoR) ignore null characters */
/* (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) { /* Is it a control or meta-control character? */
if (transparent) {
flushbuf ();
switch (c) { /* PWP: faster way to go about all this */
case 015: /* CR */
if (!newline) {
absmove (0, curlin);
return;
}
/* (UoR) perform newline function */
/* PWP: by falling through into next cases */
case 012: /* Line Feed */
case 013: /* Vertical Tab */
case 014: /* Form Feed */
case 0x84: /* Index */
case 0x85: /* Next Line */
/* PWP: inline version of line_feed(); */
if (to_printer) { /*JAO*/
(*hPrintBuffer)[lPrintBufferAt++] = 13;
if (lPrintBufferAt == lPrintBufferSize)
lPrintBufferAt = 0L;
lPrintBufferChars++;
if (lPrintBufferChars == lPrintBufferSize) {
overflowingDialog = GetNewDialog(OVERFLOWINGBOXID, NILPTR, (WindowPtr) - 1);
DrawDialog(overflowingDialog);
}
}
if (!to_screen) return;
/* (PWP) A better place to log the session */
if (seslog) /* if logging is active then */
slog (scr[curlin], MAXCOL); /* write line to session log */
if ((newline && (c != 0x84)) || (c == 0x85))
absmove (0, curlin); /* (UoR) perform newline function */
if (curlin == scrbot) {
scroll_screen (scrtop, curlin, -1); /* (UoR) scroll lines up */
} else {
if (curlin >= scrtop) /* (PWP) if within scrolling region */
relmove (0, 1);
}
return;
case 07:
bell();
return;
case 010:
back_space();
return;
case 011:
tab();
return;
case 016:
control_N(); /* 16 (graphic set 1) *//* (UoR) */
return;
case 017:
control_O(); /* 17 (graphic set 0) *//* (UoR) */
return;
case 005: /* 5 (send answerback message) */
case 021: /* DC1 (XON) */
case 023: /* DC3 (XOFF) */
return; /* we ignore this */
case 030: /* CAN (^X: cancel current esc sequence */
case 032: /* SUB (^Z: treated as CAN) */
norm_char(); /* back to normal input mode */
return;
case 033:
escape_seq(); /* 33 (Escape) */
return;
case 0:
return; /* never draw NULs */
case 0x88: /* Set hors. tab */
set_tab();
return;
case 0x8d: /* rev. index (scrolls) */
reverse_line_feed();
return;
case 0x8e: /* single shift G2 to GL */
single_shift_2();
return;
case 0x8f: /* single shift G3 to GL */
single_shift_3();
return;
case 0x90: /* device control string intro */
dcs_seq();
return;
case 0x9b: /* Control Seq. intro (like ESC [ ) */
csi_seq();
return;
case 0x9c: /* String Terminator (ST) */
norm_char(); /* Reset flag for next character */
return;
case 0x9d: /* Operating System Command (through ST) */
case 0x9e: /* Privacy Message (through ST) */
case 0x9f: /* Applications Prog. Command (through ST) */
toss_till_st(); /* toss them till ST */
return;
default:
return;
}
} else {
MDrawChar(c);
flushbuf ();
if (c == '\012')
new_line();
return;
}
} /* end if control */
switch (charflg) {
case CF_OUTC: /* Just output the char */
MDrawChar (c);
break;
case CF_ESC: /* In a single char escape seq */
if ((intermedptr < intermedbuf) || (intermedptr > &intermedbuf[NUMBUFSIZ - 1])) {
printerr ("intermedptr out of range:", intermedptr);
intermedptr = 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();
else if (c == ')' || c == '-')
graphic_G1();
else if (c == '*' || c == '.')
graphic_G2();
else if (c == '+' || c == '/')
graphic_G3();
else
if (c >= 0x20 && c <= 0x2F) {
if (intermedptr < &intermedbuf[NUMBUFSIZ - 1])
*intermedptr++ = c; /* Add the char to the num */
} else if (c >= 0x30) {
charflg = CF_OUTC; /* Reset flag to simple outputting */
*intermedptr = '\0';
if (funp = lookup (c, esc_table, MIN_ESC, MAX_ESC))
(*funp) (); /* 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 (intermedptr < &intermedbuf[NUMBUFSIZ - 1])
*intermedptr++ = c; /* Add the char to the num */
} else {
*intermedptr = '\0';
set_char_set(c); /* (this uses charflg to select which set) */
charflg = CF_OUTC; /* Reset flag for next character */
}
break;
case CF_CSI: /* Multichar escape sequence */
case CF_DCS: /* device control string sequence */
if ((intermedptr < intermedbuf) || (intermedptr > &intermedbuf[NUMBUFSIZ - 1])) {
printerr ("intermedptr out of range:", intermedptr);
intermedptr = intermedbuf;
}
if ((argptr < paramarg[argcount]) || (argptr > ¶marg[argcount][NUMBUFSIZ - 1])) {
printerr ("argptr out of range:", argptr);
argptr = paramarg[argcount];
}
if ((numptr < numbuf) || (numptr > &numbuf[NUMBUFSIZ - 1])) {
printerr ("numptr out of range:", numptr);
numptr = 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') && (numptr == numbuf)) {
/* ignore the leading zero */
} else if (c >= '0' && c <= '9') { /* PWP: was also '+' or '-' */
if (numptr < &numbuf[NUMBUFSIZ - 1])
*numptr++ = c; /* Add the char to the num */
} else if (c == ';') {
end_numarg();
} else {
if (argptr < ¶marg[argcount][NUMBUFSIZ - 1])
*argptr++ = c; /* Add the char to the parameter list */
}
} else if (c >= 0x20 && c < 0x30) { /* Intermediate chars */
/* (PWP) intermeadiate characters go in the intermedbuf[] */
end_numarg(); /* tie off numeric argument */
if (intermedptr < &intermedbuf[NUMBUFSIZ - 1])
*intermedptr++ = c; /* Add the char to the num */
} else if (c >= 0x40) { /* End of sequence */
charflg = CF_OUTC; /* Back to simple outputting */
if (funp = lookup (c, csi_table, MIN_CSI, MAX_CSI)) {
if (intermedptr == intermedbuf) /* if we didn't just do this */
end_numarg(); /* tie off numeric argument */
*intermedptr = '\0'; /* tie off intermediate */
(*funp) (); /* Do the escape sequence function */
}
}
break;
case CF_TOSS: /* Ignore this char */
charflg = CF_OUTC; /* Reset flag */
break;
case CF_T_ST: /* (PWP) toss till String Terminator */
break;
}
}
} /* printit */
set_char_set(c)
unsigned char c;
{
int ninetysix = 0; /* are we talking about a 96 char. set */
int set = charflg - CF_GS_0; /* which slot are we talking about? */
if (set > 3) {
set -= 4;
ninetysix = 1;
}
if (!nat_char_mode) { /* if doing 8859 international sets */
if (!ninetysix) { /* 94 character set */
switch(c) {
case '1': /* ALT ROM set (we claim ASCII) */
graphicsinset[set] = ASCII_SET;
break;
case '5':
if (intermedbuf[0] == '%') /* DEC supplimental graphic */
graphicsinset[set] = GRAF_SET; /* for now */
break;
case '0':
case '2':
graphicsinset[set] = GRAF_SET;
break;
case '>':
graphicsinset[set] = TECH_SET;
break;
case 'A':
graphicsinset[set] = ASCII_SET;
break;
case '<': /* DEC user-prefered supplemental set */
graphicsinset[set] = GRAF_SET;
break;
case 'B': /* Allways ASCII half of an ISO set */
graphicsinset[set] = ASCII_SET;
break;
} /* end switch(c) */
} else { /* 96 character set */
switch(c) {
case '1': /* ALT ROM set (we claim ASCII) */
graphicsinset[set] = ASCII_SET;
break;
case '<': /* DEC user-prefered supplemental set */
graphicsinset[set] = GRAF_SET;
break;
case 'A':
graphicsinset[set] = LAT1_SET;
break;
#ifdef COMMENT
case 'B':
graphicsinset[set] = LAT2_SET;
break;
case 'C':
graphicsinset[set] = LAT3_SET;
break;
case 'D':
graphicsinset[set] = LAT4_SET;
break;
case 'L':
graphicsinset[set] = LATCYR_SET;
break;
case '*': /* we don't know what this should be yet */
graphicsinset[set] = LATARAB_SET;
break;
case 'F':
graphicsinset[set] = LATGREEK_SET;
break;
case 'H':
graphicsinset[set] = LATHEBREW_SET;
break;
case 'M':
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':
graphicsinset[set] = GRAF_SET;
return; /* don't change national mapping */
case '>':
graphicsinset[set] = TECH_SET;
return; /* don't change national mapping */
/* the rest of these do change the national mapping */
case 'B':
case '1':
nat_set = USA_NAT;
break;
case 'A':
nat_set = UK_NAT;
break;
case '4':
nat_set = DUTCH_NAT;
break;
case 'C':
case '5':
nat_set = FINNISH_NAT;
break;
case 'R':
nat_set = FRENCH_NAT;
break;
case '9':
case 'Q':
nat_set = FRENCHCAN_NAT;
break;
case 'K':
nat_set = GERMAN_NAT;
break;
case 'Y':
nat_set = ITALIAN_NAT;
break;
case '6':
if (intermedbuf[0] == '%') {
nat_set = PORTUGUESE_NAT;
break;
}
/* else fall through to norwegian */
case '`':
case 'E':
nat_set = NORWEGIAN_NAT;
break; /* also Danish */
case 'Z':
nat_set = SPANISH_NAT;
break;
case '7':
case 'H':
nat_set = SWEDISH_NAT;
break;
case '=':
nat_set = SWISS_NAT;
break;
} /* end switch(c) */
graphicsinset[set] = ASCII_SET;
set_char_map();
}
}
set_char_map()
{
register int i;
for (i = 0; i < 128; i++) /* reset the character remapping map */
char_map[i] = (unsigned char) i;
if (nat_char_mode) {
char_map['#'] = nat_remaps[nat_set][0]; /* set the values for the national map */
char_map['@'] = nat_remaps[nat_set][1];
char_map['['] = nat_remaps[nat_set][2];
char_map['\\'] = nat_remaps[nat_set][3];
char_map[']'] = nat_remaps[nat_set][4];
char_map['^'] = nat_remaps[nat_set][5];
char_map['_'] = nat_remaps[nat_set][6];
char_map['`'] = nat_remaps[nat_set][7];
char_map['{'] = nat_remaps[nat_set][8];
char_map['|'] = nat_remaps[nat_set][9];
char_map['}'] = nat_remaps[nat_set][10];
char_map['~'] = nat_remaps[nat_set][11];
}
}
/****************************************************************************/
/* draw a characer on the screen (or buffer it) */
/****************************************************************************/
MDrawChar (chr)
register unsigned char chr;
{
register PFV funp;
extern char outbuf[MAXCOL + 1];
extern int outcnt, outcol;
register int cset = Gl_set;
if (chr & 0x80) /* if a right-side (meta) character */
cset = Gr_set; /* then we are in the GR character set */
chr &= 0177; /* trim to 7 bits */
if (old_Gl_set >= 0) { /* are we doing a single shift? */
Gl_set = old_Gl_set;
old_Gl_set = -1;
}
if ((nat_char_mode) && (graphicsinset[cset] == ASCII_SET)) {
chr = char_map[chr];
textstyle &= STY_STY; /* reset to ASCII */
set_style(textstyle);
} else {
if ((chr >= vt_to_fmap[graphicsinset[cset]].lbound) &&
(chr <= vt_to_fmap[graphicsinset[cset]].hbound)) {
chr += vt_to_fmap[graphicsinset[cset]].coffset;
textstyle = (textstyle & STY_STY) |
(vt_to_fmap[graphicsinset[cset]].fnum) << 4;
} else {
textstyle &= STY_STY; /* reset to ASCII */
}
set_style(textstyle);
}
if (curcol >= MAXCOL) { /* Are we about to wrap around? */
if (autowrap) { /* If autowrap indicated wrap */
flushbuf ();
if (newline == FALSE)
carriage_return ();
line_feed ();
} else {
flushbuf (); /* (UoR) make sure last char is shown */
back_space (); /* Otherwise just overwrite */
}
}
if (insert) { /* Insert mode? */
insert_char (); /* Open hole for char if requested */
/* erase_char (); */ /* Erase the old char */
MOVETOCHAR (curcol, curlin - display_topline);
DrawChar (chr & 0377);
} else { /* Otherwise just buffer the char */
/* PWP: an inline version of: buf_char (chr); */
if (outcnt == 0)
outcol = curcol; /* No chars in buffer, init column */
outbuf[outcnt++] = chr; /* Put in the buffer to output later */
}
scr[curlin][curcol] = chr;
scr_attrs[curlin][curcol] = (unsigned char) textstyle;
curcol++;
} /* MDrawChar */
/****************************************************************************/
/*
* 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 ()
{
if (curcol > 0)
relmove (-1, 0);
} /* back_space */
void
erase_char ()
{
Rect r;
scr[curlin][curcol] = ' '; /* Erase char for update */
scr_attrs[curlin][curcol] = 0; /* no attributes */
makerect (&r, curlin, curcol, 1, 1); /* One char by one line */
EraseRect (&r); /* (UoR) use InvertRect instead of FillRect */
if (textstyle | VT_INVERT)
InvertRect (&r);
} /* erase_char */
void
tab ()
{
int i;
/* (UoR) find next tabstop */
for (i = curcol + 1; (i < MAXCOL) && (tabstops[i] == 0); i++);
absmove (i, curlin);
} /* tab */
/* PWP: if you change this, also change MDrawChar() above */
void
line_feed ()
{
if (to_printer) { /*JAO*/
(*hPrintBuffer)[lPrintBufferAt++] = 13;
if (lPrintBufferAt == lPrintBufferSize)
lPrintBufferAt = 0L;
lPrintBufferChars++;
if (lPrintBufferChars == lPrintBufferSize) {
overflowingDialog = GetNewDialog(OVERFLOWINGBOXID, NILPTR, (WindowPtr) - 1);
DrawDialog(overflowingDialog);
}
}
if (newline)
absmove (0, curlin); /* (UoR) perform newline function */
/* (PWP) A better place to log the session */
if (seslog) /* if logging is active then */
slog (scr[curlin], MAXCOL); /* write line to session log */
if (curlin == scrbot) {
scroll_screen (scrtop, curlin, -1); /* (UoR) scroll lines up */
} else {
if (curlin >= scrtop) /* (PWP) if within scrolling region */
relmove (0, 1);
}
} /* line_feed */
void
reverse_line_feed ()
{
if (curlin == scrtop) {
scroll_screen (curlin, scrbot, 1); /* (UoR) scroll down in region */
} else {
if (curlin <= scrbot) /* (PWP) if within scrolling region */
relmove (0, -1);
}
} /* reverse_line_feed */
/* PWP: if you change this, also change MDrawChar() above */
void
carriage_return ()
{
if (newline)
line_feed (); /* (UoR) perform newline function */
else
absmove (0, curlin);
} /* carriage_return */
void
new_line ()
{
carriage_return ();
line_feed ();
} /* new_line */
void
clear_screen ()
{
register int i;
Rect r;
makerect (&r, 0, 0, screensize, MAXCOL); /* The whole screen */
EraseRect (&r);
for (i = 0; i < screensize; i++) /* (PWP) clear from bottom up */
zeroline (i); /* Clear up the update records */
} /* clear_screen */
void
push_clear_screen()
{
register int i, j, tlin;
char *savedline, *savedattr; /* temporary to hold screen line pointer */
display_totlines += screensize;
if (display_totlines > MAX_SCREENSIZE)
display_totlines = MAX_SCREENSIZE; /* bounds */
tlin = screensize - display_totlines; /* top of saved buffer */
/* save cleared lines on scrollback buffer */
for (j = 0; j < screensize; j++) {
/* scroll screen buffer by one line */
savedline = scr[tlin];
savedattr = scr_attrs[tlin];
for (i = tlin+1; i <= botlin; i++) {
scr[i-1] = scr[i];
scr_attrs[i-1] = scr_attrs[i];
}
scr[botlin] = savedline;
scr_attrs[botlin] = savedattr;
}
clear_screen();
}
void
vt_align()
{
register int l, c;
for (l = 0; l < screensize; l++) {
absmove (0, l);
if (outcnt == 0)
outcol = curcol; /* No chars in buffer, init column */
for (c = 0; c < MAXCOL; c++) {
scr[l][c] = 'E';
scr_attrs[l][c] = 0;
outbuf[outcnt++] = 'E'; /* Put in the buffer to output later */
}
flushbuf ();
}
absmove (0, 0);
}
void
home_cursor ()
{
if (relorigin)
absmove (0, scrtop);
else
absmove (0, 0); /* (UoR) correct for relative origin */
} /* home_cursor */
void
bell ()
{
Rect r;
if (visible_bell) {
makerect (&r, 0, 0, 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 ()
{
} /* dummy */
void
toss_char ()
{
charflg = CF_TOSS;
} /* toss_char */
void
toss_till_st ()
{
charflg = CF_T_ST;
}
void
norm_char ()
{
charflg = CF_OUTC;
}
void
escape_seq ()
{
intermedbuf[0] = '\0'; /* Initialize the numbers to zero */
intermedptr = intermedbuf; /* Place to put the next number */
charflg = CF_ESC; /* Say we are in an escape sequence */
} /* escape_seq */
void
csi_seq ()
{
argcount = 0; /* no arguments yet */
numarg[0] = 0; /* Initialize the numbers to zero */
paramarg[0][0] = '\0';
argptr = paramarg[0]; /* Place to put the next number */
numbuf[0] = '\0'; /* init number buffer */
numptr = numbuf;
intermedbuf[0] = '\0'; /* Initialize the numbers to zero */
intermedptr = intermedbuf; /* Place to put the next number */
charflg = CF_CSI; /* Say we are in a ESC [ sequence */
} /* csi_seq */
void
dcs_seq ()
{
csi_seq(); /* these are like CSI commands, but have strings too */
charflg = CF_DCS; /* Say we are in a device control sequence */
}
void
string_term()
{
charflg = CF_OUTC;
}
void
vt320_mode()
{
}
void
vt52_mode()
{
}
void
graphic_G0 () /* (UoR) do VT100 graphic characters */
{
charflg = CF_GS_0;
} /* graphic_G0 */
void
graphic_G1 ()
{
charflg = CF_GS_1;
} /* graphic_G1 */
void
graphic_G2 ()
{
charflg = CF_GS_2;
} /* graphic_G1 */
void
graphic_G3 ()
{
charflg = CF_GS_3;
} /* graphic_G1 */
void
control_N () /* shift out */
{
Gl_set = 1; /* set to graphics set 1 */
} /* control_N */
void
control_O () /* shift in */
{
Gl_set = 0; /* set to graphics set 0 */
} /* control_O */
void
single_shift_2()
{
old_Gl_set = Gl_set;
Gl_set = 2;
}
void
single_shift_3()
{
old_Gl_set = Gl_set;
Gl_set = 3;
}
void
lock_shift_2()
{
Gl_set = 2;
}
void
lock_shift_3()
{
Gl_set = 3;
}
void
lock_shift_3r()
{
Gr_set = 3;
}
void
lock_shift_2r()
{
Gr_set = 2;
}
void
lock_shift_1r()
{
Gr_set = 1;
}
void
h19_graph_mode()
{
}
void
end_h19_graph_mode()
{
}
void
set_appl ()
{
appl_mode = TRUE; /* applications keypad mode */
}
void
reset_appl ()
{
appl_mode = FALSE; /* normal keypad mode */
}
void
set_compat() /* set vtNNN level of compatibility */
{
if (argcount < 2) numarg[1] = 0;
if (argcount < 1) numarg[0] = 0;
if (intermedbuf[0] == '"') {
switch (numarg[0]) {
case 61: /* vt100 mode */
break;
case 62: /* vt200 mode */
switch (numarg[1]) {
case 0:
break;
case 1:
break;
case 2:
break;
}
}
}
}
void
set_charattr()
{
if (intermedbuf[0] == '"') {
switch (numarg[0]) {
case 0: /* all attributes off */
ch_protect = FALSE;
break;
case 1:
ch_protect = TRUE;
break;
case 2:
ch_protect = FALSE;
break;
}
}
}
void
clear_line ()
{
int i;
Rect r;
maybe_nuke_selection (curlin, curlin);
switch (numarg[0]) {
case 0: /* Clear: here to the right */
makerect (&r, curlin, curcol, 1, MAXCOL - curcol);
for (i = curcol; i < MAXCOL; i++) {
scr[curlin][i] = ' ';
scr_attrs[curlin][i] = 0;
}
break;
case 1: /* Clear: left to here */
makerect (&r, curlin, 0, 1, curcol + 1);
for (i = 0; i <= curcol; i++) {
scr[curlin][i] = ' ';
scr_attrs[curlin][i] = 0;
}
break;
case 2: /* Clear: entire line */
makerect (&r, curlin, 0, 1, MAXCOL);
zeroline (curlin);
break;
}
EraseRect (&r);
} /* clear_line */
void
erase_display ()
{
int i;
Rect r;
switch (numarg[0]) {
case 0: /* clear from here to end */
maybe_nuke_selection (curlin, botlin);
if ((curlin == toplin) && (curcol == 0)) {
push_clear_screen (); /* save lines in scrollback buffer */
} else {
clear_line (); /* Same numarg[0] causes correct clear */
makerect (&r, curlin + 1, 0, screensize - curlin - 1, MAXCOL);
/* (UoR) -1 added */
EraseRect (&r);
for (i = curlin + 1; i <= botlin; i++)
zeroline (i);
}
break;
case 1: /* clear from beginning to here */
maybe_nuke_selection (toplin, curlin);
clear_line (); /* Same numarg[0] causes correct clear */
makerect (&r, 0, 0, curlin, MAXCOL);
EraseRect (&r);
for (i = toplin; i < curlin; i++)
zeroline (i);
break;
case 2: /* clear everything */
maybe_nuke_selection (toplin, botlin);
push_clear_screen (); /* 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 ()
{
if (numarg[0] == 0) numarg[0] = 1;
relmove (numarg[0], 0);
} /* cursor_right */
void
cursor_left ()
{
if (numarg[0] == 0) numarg[0] = 1;
relmove (-numarg[0], 0);
} /* cursor_left */
void
cursor_up ()
{
int abstop; /* (UoR) check that we don't pass scrtop */
abstop = scrtop;
if (numarg[0] == 0) numarg[0] = 1;
if ((curlin >= abstop) && (curlin - numarg[0] < abstop))
absmove (curcol, abstop);
else
relmove (0, -numarg[0]);
} /* cursor_up */
void
cursor_down ()
{
int absbot; /* (UoR) check that we don't pass scrbot */
absbot = scrbot;
if (numarg[0] == 0) numarg[0] = 1;
if ((curlin <= absbot) && (curlin + numarg[0] > absbot))
absmove (curcol, absbot);
else
relmove (0, numarg[0]);
} /* cursor_down */
void
cursor_position ()
{
if (argcount < 2) numarg[1] = 1;
if (argcount < 1) numarg[0] = 1;
if (relorigin)
absmove (--numarg[1], scrtop + numarg[0] - 1); /* (UoR) */
else
absmove (--numarg[1], --numarg[0]); /* (UoR) moved "--" here from prev
* lines */
} /* cursor_position */
void
cursor_h_pos ()
{
absmove (--numarg[0], curlin);
} /* cursor_h_pos */
void
cursor_save () /* ESC 7 */
{
savcol = curcol; /* Save the current line and column */
savlin = curlin;
savsty = textstyle; /* (UoR) additions */
savGl = Gl_set;
savGr = Gr_set;
savset[0] = graphicsinset[0];
savset[1] = graphicsinset[1];
savset[2] = graphicsinset[2];
savset[3] = graphicsinset[3];
} /* cursor_save */
void
cursor_restore () /* ESC 8 */
{
if (intermedbuf[0] == '#') {
vt_align();
return;
}
absmove (savcol, savlin); /* Move to the old cursor position */
textstyle = savsty; /* (UoR) additions */
set_style(textstyle); /* new text face */
Gl_set = savGl;
Gr_set = savGr;
graphicsinset[0] = savset[0];
graphicsinset[1] = savset[1];
graphicsinset[2] = savset[2];
graphicsinset[3] = savset[3];
} /* cursor_restore */
void
set_scroll_region ()
{
if (argcount < 2) numarg[1] = 0;
if (--numarg[0] < 0)
numarg[0] = 0; /* Make top of line (prev line) */
if (numarg[1] == 0)
numarg[1] = screensize; /* Zero means entire screen */
if (numarg[0] < numarg[1] - 1) { /* (UoR) make sure region is legal */
topmargin = (numarg[0] * LINEHEIGHT) + TOPMARGIN;
bottommargin = (numarg[1] * LINEHEIGHT) + TOPMARGIN;
scrtop = numarg[0];
scrbot = numarg[1] - 1;
home_cursor (); /* We're supposed to home it! */
}
} /* set_scroll_region */
/****************************************************************************/
/* aka Select Graphic Rendition */
/****************************************************************************/
void
text_mode ()
{
int i;
if (argcount == 0) {
argcount = 1;
numarg[0] = 0;
}
for (i = 0; i < argcount; i++) {
switch (numarg[i]) {
case 0: /* primary rendition */
textstyle = 0;
break;
case 1: /* bold or increased intensity */
textstyle |= VT_BOLD;
break;
case 4: /* underscore */
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) */
textstyle |= VT_BLINK;
break;
case 7: /* reverse image */
textstyle |= VT_INVERT; /* (PWP) */
break;
case 21: /* ??? */
case 22: /* normal intensity */
textstyle &= ~(VT_BOLD); /* (PWP) */
break;
case 24: /* not underlined */
textstyle &= ~(VT_UNDER); /* (PWP) */
break;
case 25: /* not blinking */
textstyle &= ~(VT_BLINK); /* (PWP) */
break;
case 27: /* not reversed */
textstyle &= ~(VT_INVERT); /* (PWP) */
break;
}
set_style(textstyle); /* new text face */
}
} /* text_mode */
void
line_dblh_top() /* double height line, top half */
{
}
void
line_dblh_bot() /* double height line, bottom half */
{
}
void
line_singw() /* single width line */
{
}
void
line_dblw() /* double width line */
{
}
void
start_selected()
{
}
void
end_selected()
{
}
/****************************************************************************/
/*
* (UoR)
*
* Insert and Delete lines (replacements for originals, which have
* which have been deleted)
*
*/
/****************************************************************************/
void
insert_line ()
{
int i, absbot;
absbot = scrbot;
if ((curlin >= scrtop) && (curlin <= absbot)) {
if (numarg[0] == 0)
numarg[0] = 1;
if (numarg[0] > absbot - curlin + 1)
numarg[0] = absbot - curlin + 1;
for (i = 0; i < numarg[0]; i++)
scroll_screen (curlin, scrbot, 1);
}
} /* insert_line */
void
delete_line ()
{
int i, absbot;
absbot = scrbot;
if ((curlin >= scrtop) && (curlin <= absbot)) {
if (numarg[0] == 0)
numarg[0] = 1;
if (numarg[0] > absbot - curlin + 1)
numarg[0] = absbot - curlin + 1;
for (i = 0; i < numarg[0]; i++)
scroll_screen (curlin, scrbot, -1);
}
} /* delete_line */
void
delete_char ()
{
int i;
Rect r;
if (numarg[0] == 0)
numarg[0] = 1;
makerect (&r, curlin, curcol, 1, MAXCOL - curcol);
if (numarg[0] > MAXCOL - curcol - 1)
numarg[0] = MAXCOL - curcol - 1;
/* Scroll them out */
ScrollRect (&r, -CHARWIDTH * numarg[0], 0, dummyRgn);
/* Shift them down *//* (UoR) used to assign using abscol */
for (i = curcol; i < MAXCOL - numarg[0]; i++) {
scr[curlin][i] = scr[curlin][i + numarg[0]];
scr_attrs[curlin][i] = scr_attrs[curlin][i + numarg[0]];
}
/* Fill in holes with spaces */
while (i < MAXCOL) {
scr[curlin][i++] = ' ';
scr_attrs[curlin][i++] = 0;
}
} /* delete_char */
/****************************************************************************/
/* CME */
/****************************************************************************/
void
insert_chars ()
{
int i;
Rect r;
if (numarg[0] == 0)
numarg[0] = 1;
makerect (&r, curlin, curcol, 1, MAXCOL - curcol);
if (numarg[0] > MAXCOL - curcol - 1)
numarg[0] = MAXCOL - curcol - 1;
/* Scroll them out */
ScrollRect (&r, CHARWIDTH * numarg[0], 0, dummyRgn);
/* Shift them up *//* (UoR) used to assign using abscol */
for (i = MAXCOL - 1; i >= curcol + numarg[0]; i--) {
scr[curlin][i] = scr[curlin][i - numarg[0]];
scr_attrs[curlin][i] = scr_attrs[curlin][i - numarg[0]];
}
/* Fill in holes with spaces */
while (i > curcol) {
scr[curlin][--i] = ' ';
scr_attrs[curlin][--i] = 0;
}
} /* delete_char */
void
insert_char ()
{
int i;
Rect r;
makerect (&r, curlin, curcol, 1, MAXCOL - curcol);
ScrollRect (&r, CHARWIDTH, 0, dummyRgn);
/* Shift em up *//* (UoR) used to assign ...[i-1]=...[i] */
/* (UoR) used to assign using abscol */
for (i = MAXCOL - 1; i > curcol; i--) {
scr[curlin][i] = scr[curlin][i - 1];
scr_attrs[curlin][i] = scr_attrs[curlin][i - 1];
}
scr[curlin][curcol] = ' ';
scr_attrs[curlin][curcol] = 0;
} /* insert_char */
void
insert_mode ()
{
int i;
if (argcount < 1) {
numarg[0] = 0;
argcount = 1;
}
for (i = 0; i < argcount; i++) { /* handle multiple arguments */
if (paramarg[i][0] == '?') {
set_mode (numarg[i]); /* (UoR) do some of these calls */
} else if (paramarg[i][0] == '>') { /* (PWP) Heath ANSI stuff */
set_heath_mode(numarg[i]);
} else {
switch (numarg[i]) {
case 20: /* newline mode */
newline = TRUE;
break;
case 12: /* send/recieve */
break;
case 4: /* insert mode */
insert = TRUE;
break;
}
}
}
} /* insert_mode */
void
end_insert_mode ()
{
int i;
if (argcount < 1) {
numarg[0] = 0;
argcount = 1;
}
for (i = 0; i < argcount; i++) { /* handle multiple arguments */
if (paramarg[i][0] == '?') {
reset_mode (numarg[i]); /* (UoR) do some of these calls */
} else if (paramarg[i][0] == '>') { /* (PWP) Heath ANSI stuff */
reset_heath_mode(numarg[i]);
} else {
switch (numarg[i]) {
case 20: /* newline mode */
newline = FALSE;
break;
case 12: /* send/recieve */
break;
case 4: /* insert mode */
insert = FALSE;
break;
}
}
}
} /* end_insert_mode */
/****************************************************************************/
void
printer_control () /*JAO*/
{
extern char *NewHandle();
switch (numarg[0]) { /* "ESC [ ? # i" */
case 5: /*Start printing*/
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++] = 14;
if (lPrintBufferAt == lPrintBufferSize)
lPrintBufferAt = 0L;
lPrintBufferChars++;
}
bufferingDialog = GetNewDialog(BUFFERINGBOXID, NILPTR, (WindowPtr) - 1);
DrawDialog(bufferingDialog);
overflowingDialog = 0L;
if (lPrintBufferChars == lPrintBufferSize) { /*JAOtemp*/
overflowingDialog = GetNewDialog(OVERFLOWINGBOXID, NILPTR, (WindowPtr) - 1);
DrawDialog(overflowingDialog); /*JAOtemp*/
} /*JAOtemp*/
to_printer = TRUE;
if (paramarg[0][0] == '?')
to_screen = TRUE;
else
to_screen = TRUE; /*FALSE;*/
break;
case 4: /*Stop printing*/
if (overflowingDialog != 0L) {
DisposDialog(overflowingDialog);
}
DisposDialog(bufferingDialog);
to_printer = FALSE;
to_screen = TRUE;
EnableItem(menus[PRNT_MENU], 0);
DrawMenuBar();
break;
}
} /* end of printer_control */ /*JAO*/
void
invert_term ()
{
if (screeninvert)
reset_mode (5);
else
set_mode (5);
} /* invert_term */
void
set_mode (arg) /* we get here by ESC [ ? <numarg[0]> h */
int arg;
{
Rect r;
switch (arg) {
case 1: /* cursor key mode */
curskey_mode = TRUE;
break;
case 2: /* keyboard lock */
break; /* we never do keyboard lock */
case 3: /* 132 column */
break;
case 4: /* smooth scroll */
smoothscroll = TRUE;
break;
case 5: /* reverse screen */
if (screeninvert == FALSE) {
BackPat (qd.black); /* (UoR) use black background */
makerect (&r, 0, 0, screensize, MAXCOL);
InvertRect (&r);
screeninvert = TRUE;
}
break;
case 6: /* relative origin mode */
relorigin = TRUE;
home_cursor ();
break;
case 7: /* auto wrap */
autowrap = TRUE;
break;
case 8: /* auto repeat */
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 */
nat_char_mode = TRUE;
set_char_map();
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 */
void
reset_mode (arg) /* we get here by ESC [ ? <numarg[0]> l */
int arg;
{
Rect r;
switch (arg) {
case 1: /* cursor key mode */
curskey_mode = FALSE;
break;
case 2: /* keyboard lock */
break; /* we never do keyboard lock */
case 3: /* 132 column */
break;
case 4: /* smooth scroll */
smoothscroll = FALSE;
break;
case 5: /* reverse screen */
if (screeninvert) {
BackPat (qd.white);
makerect (&r, 0, 0, screensize, MAXCOL);
InvertRect (&r);
screeninvert = FALSE;
}
break;
case 6: /* relative origin mode */
relorigin = FALSE;
home_cursor ();
break;
case 7: /* auto wrap */
autowrap = FALSE;
break;
case 8: /* auto repeat */
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 */
nat_char_mode = FALSE;
set_char_map(); /* 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 */
void
set_heath_mode (arg) /* (PWP) we get here by ESC [ > <numarg[0]> h */
int arg;
{
Rect r;
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 */
blockcursor = TRUE;
break;
case 5: /* show cursor */
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 (arg) /* (PWP) we get here by ESC [ > <numarg[0]> h */
int arg;
{
Rect r;
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 */
blockcursor = FALSE;
break;
case 5: /* hide cursor */
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 ()
{
tabstops[curcol] = 1;
} /* set_tab */
void
clear_tab ()
{
int i;
switch (numarg[0]) {
case 0:
tabstops[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 (s)
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 ()
{
writereply (querystring);
} /* query_terminal */
/****************************************************************************/
/* (UoR) reports */
/****************************************************************************/
void
request_report ()
{
switch (numarg[0]) {
case 5: /* (UoR) report that we're OK */
writereply (reportstring);
break;
case 6: /* (UoR) reprt the cursor position */
position_report ();
break;
case 15: /* (UoR) report printer status */
if (paramarg[0][0] == '?')
writereply (noprinter);
break;
}
} /* request_report */
void
position_report ()
{
int i;
char buf[9];
char *report;
i = 0;
buf[i++] = '\033';
buf[i++] = '[';
if (curlin > 9)
buf[i++] = '0' + (curlin + 1) / 10;
buf[i++] = '0' + (curlin + 1) % 10;
buf[i++] = ';';
if (curcol > 9)
buf[i++] = '0' + (curcol + 1) / 10;
buf[i++] = '0' + (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 (lin)
int lin;
{
register int i;
Rect r;
for (i = 0; i < MAXCOL; i++) {
scr[lin][i] = ' ';
scr_attrs[lin][i] = 0;
}
} /* zeroline */
/****************************************************************************/
/* Move a relative number of lines and chars. Both can be negative. */
/****************************************************************************/
void
relmove (hor, ver)
{
absmove (curcol + hor, curlin + ver); /* (UoR) use absmove, which
* checks */
/* for cursor moving off screen */
} /* relmove */
/****************************************************************************/
/* Move to absolute position hor char and ver line. */
/****************************************************************************/
void
absmove (hor, ver)
{
if (hor > MAXCOL - 1)
hor = MAXCOL - 1; /* (UoR) make sure its on the screen */
if (hor < 0)
hor = 0;
if (ver > screensize - 1)
ver = screensize - 1;
if (ver < 0)
ver = 0;
if (relorigin) {
if (ver < scrtop)
ver = scrtop;
if (ver > scrbot)
ver = scrbot;
}
/* MOVETOCHAR (hor, ver - display_topline); */
curcol = hor;
curlin = ver;
} /* absmove */
/****************************************************************************/
/* dump the whole screen to the session log file */
/****************************************************************************/
void
scrtolog ()
{
int lin, i;
lin = toplin;
for (i = 0; i < screensize; i++) {
slog (scr[lin], MAXCOL);/* write this line to session log */
lin++; /* lin = nxtlin[lin]; */
}
} /* scrtolog */
void
scrlasttolog ()
{
slog (scr[screensize-1], MAXCOL); /* write last line to session log */
}