1284 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1284 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
 | ||
|  *	This software is quasi-public; it may be used freely with
 | ||
|  *	like software, but may NOT be sold or made part of licensed
 | ||
|  *	products without permission of the author.
 | ||
|  */
 | ||
| /*
 | ||
|  *  EETERM	ELLE Terminal Driver.
 | ||
|  *	Directly supports DM2500, H-19, Omron 8025AG, Coherent/IBM-PC, TVI925.
 | ||
|  *	Others also supported if using TX_TERMCAP.
 | ||
|  */
 | ||
| 
 | ||
| #include "elle.h"
 | ||
| 
 | ||
| /* Define terminal indices (there may be holes but C preprocessor is too
 | ||
|  * stupid to let us close them).  Should be one TN_ definition for every
 | ||
|  * hardwired terminal type, even though whether or not it is actually
 | ||
|  * compiled depends on which TX_ switches are defined.
 | ||
|  */
 | ||
| #define TN_TERMCAP 0
 | ||
| #define TN_DM2500 1
 | ||
| #define TN_H19	  2
 | ||
| #define TN_OM8025 3
 | ||
| #define TN_COHIBM 4	/* Coherent IBM-PC console */
 | ||
| #define TN_TVI925 5
 | ||
| 
 | ||
| #if TX_COHIBM && !(TX_H19)	/* Ensure H19 defined if COHIBM is. */
 | ||
| #define TX_H19 1
 | ||
| #endif
 | ||
| 
 | ||
| #ifndef TXS_DEFAULT		/* If no default is explicitly specified */
 | ||
| #define TXS_DEFAULT "H19"	/* Then settle for H-19 */
 | ||
| #endif /*TXS_DEFAULT*/
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| extern char *tv_stype;	/* If set, specifies terminal type */
 | ||
| extern int tibfmsk;	/* Crock to mask off parity (meta) bit */
 | ||
| static int tv_padc;	/* Pad character to use */
 | ||
| static int tv_cspeed;	/* # msec per char (set from trm_ospeed) */
 | ||
| static int tv_type;	/* Index of selected terminal type */
 | ||
| 
 | ||
| /* Internal functions */
 | ||
| static void tpadn(), tpad();
 | ||
| 
 | ||
| /* Character speed table, indexed by system output speed value (0-017).
 | ||
|  * Value in table is 100 * <# msec used per character>.
 | ||
|  */
 | ||
| static int cspdtab[] =
 | ||
| {	/* Val    Idx Baud CPS  Time/char in msec */
 | ||
| 	0,	/*  0 Hangup -	----		*/
 | ||
| 	13333,	/*  1   50 7.5 133.33  (Baudot)	*/
 | ||
| 	10000,	/*  2   75  10 100.0   (Baudot)	*/
 | ||
| 	10000,	/*  3  110  10 100.0		*/
 | ||
| 	 8200,	/*  4 134.5 12.2 82.0 (IBM2741)	*/
 | ||
| 	 6666,	/*  5  150  15 	66.6666 	*/
 | ||
| 	 5000,	/*  6  200  20	50.0		*/
 | ||
| 	 3333,	/*  7  300  30	33.3333 	*/
 | ||
| 	 1666,	/*  8  600  60  16.6666 	*/
 | ||
| 	  833,	/*  9 1200 120   8.3333 	*/
 | ||
| 	  555,	/* 10 1800 180   5.5555 	*/
 | ||
| 	  416,	/* 11 2400 240   4.1666 	*/
 | ||
| 	  208,	/* 12 4800 480   2.0833		*/
 | ||
| 	  104,	/* 13 9600 960   1.04166	*/
 | ||
| 	0,	/* 14 Ext A  ?	 ?		*/
 | ||
| 	0	/* 15 Ext B  ?	 ?		*/
 | ||
| };
 | ||
| 
 | ||
| #if TX_TERMCAP
 | ||
| /* Declarations for TERMCAP stuff.  Only EETERM knows about them. */
 | ||
| 
 | ||
| /* Termcap routines */
 | ||
| extern int tgetent(), tgetnum(), tgetflag(), tputs();
 | ||
| extern char *tgetstr(), *tgoto();
 | ||
| static int getcap();		/* Internal routines */
 | ||
| static void putpad(), putnpad(), putpar();
 | ||
| 
 | ||
| /* Gross disgusting externals that must be defined for TERMCAP rtns */
 | ||
| char	PC;		/* Pad char */
 | ||
| char	*BC;		/* Backspace to use, if not ^H */
 | ||
| char	*UP;		/* Cursor up */
 | ||
| short	ospeed;		/* Terminal output speed */
 | ||
| 
 | ||
| /* Termcap numerical values/flags */
 | ||
| static int
 | ||
| 	tc_am,		/* TRUE if has auto-wrap */
 | ||
| 	tc_km;		/* TRUE if meta key exists */
 | ||
| 
 | ||
| /* Termcap capability strings we want to know about */
 | ||
| 
 | ||
| struct tcap { char tcicod1, tcicod2, *tccap; };
 | ||
| static struct tcap tcap[] = {
 | ||
| #define TC_al	tcap[0].tccap	/* Add (insert) line */
 | ||
| 	{'a','l', 0},
 | ||
| #define TC_AL	tcap[1].tccap	/* Add N lines */
 | ||
| 	{'A','L', 0},
 | ||
| #define TC_bc	tcap[2].tccap	/* Backspace Char (for BC) */
 | ||
| 	{'b','c', 0},
 | ||
| #define TC_ce	tcap[3].tccap	/* Erase to end of line (CLEOL) */
 | ||
| 	{'c','e', 0},
 | ||
| #define TC_cl	tcap[4].tccap	/* Clear screen */
 | ||
| 	{'c','l', 0},
 | ||
| #define TC_cm	tcap[5].tccap	/* Cursor motion */
 | ||
| 	{'c','m', 0},
 | ||
| #define TC_dc	tcap[6].tccap	/* Delete char */
 | ||
| 	{'d','c', 0},
 | ||
| #define TC_DC	tcap[7].tccap	/* Delete N chars */
 | ||
| 	{'D','C', 0},
 | ||
| #define TC_dl	tcap[8].tccap	/* Delete line */
 | ||
| 	{'d','l', 0},
 | ||
| #define TC_DL	tcap[9].tccap	/* Delete N lines */
 | ||
| 	{'D','L', 0},
 | ||
| #define TC_dm	tcap[10].tccap	/* Delete mode on */
 | ||
| 	{'d','m', 0},
 | ||
| #define TC_ed	tcap[11].tccap	/* Delete mode off */
 | ||
| 	{'e','d', 0},
 | ||
| #define TC_ei	tcap[12].tccap	/* Insert mode off */
 | ||
| 	{'e','i', 0},
 | ||
| #define TC_ia	tcap[13].tccap	/* Add line while in insert mode (see note) */
 | ||
| 	{'i','a', 0},
 | ||
| #define TC_ic	tcap[14].tccap	/* Insert blank char */
 | ||
| 	{'i','c', 0},
 | ||
| #define TC_IC	tcap[15].tccap	/* Insert N blank chars */
 | ||
| 	{'I','C', 0},
 | ||
| #define TC_id	tcap[16].tccap	/* Delete line while in del mode (see note) */
 | ||
| 	{'i','d', 0},
 | ||
| #define TC_im	tcap[17].tccap	/* Insert mode on */
 | ||
| 	{'i','m', 0},
 | ||
| #define TC_ip	tcap[18].tccap	/* Padding to send after char insertion */
 | ||
| 	{'i','p', 0},
 | ||
| #define TC_mm	tcap[19].tccap	/* String to set (turn on) meta-key mode */
 | ||
| 	{'m','m', 0},
 | ||
| #define TC_mo	tcap[20].tccap	/* String to reset (turn off) meta-key mode */
 | ||
| 	{'m','o', 0},
 | ||
| #define TC_pc	tcap[21].tccap	/* Pad Char (for PC) */
 | ||
| 	{'p','c', 0},
 | ||
| #define TC_se	tcap[22].tccap	/* End standout mode */
 | ||
| 	{'s','e', 0},
 | ||
| #define TC_so	tcap[23].tccap	/* Enter standout mode */
 | ||
| 	{'s','o', 0},
 | ||
| #define TC_te	tcap[24].tccap	/* String to end programs that use termcap */
 | ||
| 	{'t','e', 0},
 | ||
| #define TC_ti	tcap[25].tccap	/* String to beg programs that use termcap */
 | ||
| 	{'t','i', 0},
 | ||
| #define TC_up	tcap[26].tccap	/* Move cursor up (for UP) */
 | ||
| 	{'u','p', 0},
 | ||
| #define TC_vb	tcap[27].tccap	/* Visible bell */
 | ||
| 	{'v','b', 0},
 | ||
| };
 | ||
| #define NTCAPS ((sizeof(tcap))/(sizeof(struct tcap)))	/* # entries */
 | ||
| 
 | ||
| /*
 | ||
|  * There are many other things that must be taken into account.
 | ||
|  * The termcap code here will probably not work for many termcap entries,
 | ||
|  * but the only sure way to find out which ones they are is to try them.
 | ||
|  */
 | ||
| /* Note that the "ia" and "id" strings are not defined by the TERMCAP doc;
 | ||
|  * their usage here is derived from examining other TERMCAP-using programs.
 | ||
|  * Sigh!!!!
 | ||
|  */
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| 
 | ||
| /* T_INIT is called once only at program startup, to identify the
 | ||
|  *	terminal type and set up any one-time things.
 | ||
|  * T_FATAL is only called if some routine detects an error related to the
 | ||
|  *	terminal specification, before any initialization is done.
 | ||
|  *	It prints a short error message and exits the program.
 | ||
|  * T_ENTER is called after TS_ENTER to set the terminal parameters for
 | ||
|  *	editing (as opposed to normal typeout).  It may be called
 | ||
|  *	several times.
 | ||
|  * T_EXIT is called before TS_EXIT to restore normal typeout modes.
 | ||
|  *	It is called on exit from the program, and perhaps other times.
 | ||
|  */
 | ||
| t_init()
 | ||
| {
 | ||
| 	char *getenv();
 | ||
| 
 | ||
| 	/* Set some default parameters */
 | ||
| 	scr_ht = 24;
 | ||
| 	scr_wid = 79;
 | ||
| 	trm_flags = 0;
 | ||
| 	tvc_cin = 1;		/* Assume 1 char per char I/D pos */
 | ||
| 	tvc_cdn = 1;
 | ||
| 	tvc_pos = 4;		/* Default abs-move cost is 4 chars */
 | ||
| 	tvc_bs = 1;		/* Default backspace cost is 1 char */
 | ||
| 	tv_cspeed = cspdtab[trm_ospeed];	/* Find # msec per char */
 | ||
| 
 | ||
| 	/* First must determine terminal type, and check for terminals
 | ||
| 	 * that are hardwired into ELLE. */
 | ||
| 	if(!tv_stype		/* String set in command line args? */
 | ||
| #if !(V6)
 | ||
| 	 && !(tv_stype = getenv("TERM"))	/* or given by TERM var? */
 | ||
| #endif /*-V6*/
 | ||
| 		) tv_stype = TXS_DEFAULT;	/* No, try using default */
 | ||
| 	if(0) ;			/* Sigh, stupid construct */
 | ||
| #if TX_H19
 | ||
| 	else if(ustrcmp(tv_stype,"H19")) tv_type = TN_H19;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_OM8025
 | ||
| 	else if(ustrcmp(tv_stype,"OM8025")) tv_type = TN_OM8025;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_DM2500
 | ||
| 	else if(ustrcmp(tv_stype,"DM2500")) tv_type = TN_DM2500;
 | ||
| 	else if(ustrcmp(tv_stype,"DM3025")) tv_type = TN_DM2500;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_COHIBM
 | ||
| 	else if(ustrcmp(tv_stype,"COHIBM")) tv_type = TN_COHIBM;
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_TVI925
 | ||
| 	else if(ustrcmp(tv_stype,"TVI925")) tv_type = TN_TVI925;
 | ||
| #endif /*TX_TVI925*/
 | ||
| #if TX_TERMCAP	/* This should be last thing */
 | ||
| 	else if(getcap(tv_stype)) tv_type = TN_TERMCAP;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| 	else t_fatal("type unknown");	/* Ugh, barf and exit */
 | ||
| 
 | ||
| 	/* Terminal selected, now initialize parameters for it. */
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tv_padc = 0177;		/* Use rubout for pad */
 | ||
| 			tvc_pos = 3;		/* Only 3 chars for abs mov */
 | ||
| 			tvc_ci = 2;
 | ||
| 		/*	tvc_cin = 1; */		/* Default is OK */
 | ||
| 			tvc_cd = 2;
 | ||
| 		/*	tvc_cdn = 1; */		/* Default is OK */
 | ||
| 			tvc_ld = 2;
 | ||
| 			tvc_ldn = 1;
 | ||
| 			tvc_li = 2;
 | ||
| 			tvc_lin = 1;
 | ||
| 			if(trm_ospeed == 13)	/* If 9600, */
 | ||
| 			  {	tvc_cin = 5;		/* Sigh, high cost */
 | ||
| 				tvc_cdn = 2;
 | ||
| 				tvc_lin = 18;
 | ||
| 				tvc_ldn = 2;
 | ||
| 			  }
 | ||
| 			trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL|TF_METAKEY;
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:			
 | ||
| 			trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
 | ||
| 			tvc_ci = 8;
 | ||
| 		/*	tvc_cin = 1; */	/* default is ok */
 | ||
| 			tvc_cd = 0;
 | ||
| 			tvc_cdn = 2;
 | ||
| 		/*	tvc_ld = 0; */	/* Default is OK */
 | ||
| 			tvc_ldn = 1 << (trm_ospeed - 7);
 | ||
| 		/*	tvc_li = 0; */	/* Default is OK */
 | ||
| 			tvc_lin = tvc_ldn;
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:
 | ||
| 			trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL|TF_METAKEY|TF_DIRVID;
 | ||
| 			/* Always use lowest possible costs */
 | ||
| 		/*	tvc_ci = 0; */	/* Default */
 | ||
| 			tvc_cin = 2;
 | ||
| 		/*	tvc_cd = 0; */	/* Default */
 | ||
| 			tvc_cdn = 2;
 | ||
| 		/*	tvc_ld = 0; */	/* Default */
 | ||
| 			tvc_ldn = 2;
 | ||
| 		/*	tvc_li = 0; */	/* Default */
 | ||
| 			tvc_lin = 2;
 | ||
| 			break;
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
 | ||
| 			tvc_pos = 6;
 | ||
| 		/*	tvc_ci = tvc_cd = 0; */	/* Default */
 | ||
| 			tvc_cin = 4;
 | ||
| 			tvc_cdn = 2;
 | ||
| 		/*	tvc_ld = tvc_li = 0; */	/* Default */
 | ||
| 			tvc_ldn = 10;		/* Crude approx */
 | ||
| 			tvc_lin = 10;
 | ||
| 			if(trm_ospeed > 7)	/* If faster than 300 baud */
 | ||
| 				trm_flags &= ~TF_IDLIN;	/* Turn off LID */
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
 | ||
| 			tvc_ci = tvc_cd = tvc_cin = tvc_cdn
 | ||
| 				= tvc_ldn = tvc_lin = 2;
 | ||
| 			break;
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| 	if(tibfmsk < 0)		/* If mask is still default -1, set it. */
 | ||
| 		tibfmsk = ((trm_flags&TF_METAKEY) ? 0377 : 0177);
 | ||
| }
 | ||
| 
 | ||
| /* T_FATAL(str) - prints error message and exits.
 | ||
| */
 | ||
| t_fatal(str)
 | ||
| char *str;
 | ||
| {	writerr("ELLE: \"");
 | ||
| 	writerr(tv_stype);
 | ||
| 	writerr("\" terminal ");
 | ||
| 	writerr(str);
 | ||
| 	writerr("\n");
 | ||
| 	exit(1);		/* Terminate with prejudice */
 | ||
| }
 | ||
| 
 | ||
| /* T_ENTER is called after TS_ENTER to set the terminal parameters for
 | ||
|  *	editing (as opposed to normal typeout).
 | ||
|  *	Standout mode must initially be off.
 | ||
|  */
 | ||
| 
 | ||
| t_enter()
 | ||
| {	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
|                         putpad(TC_ti);
 | ||
| 			if(tc_km) putpad(TC_mm);	/* Use meta if poss */
 | ||
| #if FX_SOWIND
 | ||
| 			t_standout(0);		/* Ensure standout mode off */
 | ||
| #endif
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(030);	/* Just in case, flush stray modes */
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* Note TN_H19 will exist too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			/* Enter ZDS (Heath) mode, then
 | ||
| 			 * Exit graphics mode (G) Exit ins-char mode (O)
 | ||
| 			 * exit rev video mode (q) exit hold-screen mode (\)
 | ||
| 			 * set cursor on (y5)
 | ||
| 			 */
 | ||
| 			tputz("\033[?2h\033G\033O\033q\033\\\033y5");
 | ||
| 			/* Set Discard-at-EOL (w)
 | ||
| 			 * Set no auto-CR (y9)
 | ||
| 			 * Enable 25th line (x1)
 | ||
| 			 */
 | ||
| 			tputz("\033w\033y9\033x1");
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| /* T_EXIT - Leave editing modes.  This function should restore
 | ||
| **	the terminal's modes to what they were before ELLE was started.
 | ||
| **	Standout mode is turned off.
 | ||
| */
 | ||
| 
 | ||
| t_exit()
 | ||
| {
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			if(tc_km) putpad(TC_mo);	/* Turn off meta */
 | ||
| 			putpad(TC_te);
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(035);	/* Turn on roll mode */
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* If this exists, TN_H19 will too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			tputz("\033v");		/* Turn EOL-wrap back on */
 | ||
| #if DNTTY
 | ||
| 			tputz("\033<");		/* Return to ANSI mode */
 | ||
| #endif /*DNTTY*/
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| /* T_CLEAR() - Clears the screen and homes the cursor.
 | ||
|  *	Always valid - ELLE refuses to support terminals without this.
 | ||
|  */
 | ||
| 
 | ||
| t_clear ()
 | ||
| {	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			putnpad(TC_cl,scr_ht);
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tputz("\036\036");	/* Double Master Clear */
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* Note TN_H19 will exist too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			tputz("\033E");
 | ||
| 		/*	tputn(zpadstr,9);	*/
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			tputz("\033H\033J");	/* Home then CLEOS */
 | ||
| 			tpad(1000);		/* One second!!!! */
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			tput(032);	/* ^Z */
 | ||
| 			break;
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| 	curs_lin = curs_col = 0;
 | ||
| }
 | ||
| 
 | ||
| /* T_CURPOS(y, x) - Absolute move.  Place cursor in given position
 | ||
|  *	regardless of where it currently is.
 | ||
|  *	Updates curs_lin, curs_col.
 | ||
|  *	Always valid -- ELLE refuses to support terminals without this.
 | ||
|  */
 | ||
| 
 | ||
| t_curpos (lin, col)
 | ||
| register int lin, col;
 | ||
| {
 | ||
| 	if(col > scr_wid)		/* Easiest to catch here */
 | ||
| 		col = scr_wid;
 | ||
| 
 | ||
| 	/* Do absolute positioning */
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			putpad(tgoto(TC_cm, col, lin));
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(014);
 | ||
| 			tput(col^0140);
 | ||
| 			tput(lin^0140);
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* If this exists, TN_H19 will too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			tputz("\033Y");
 | ||
| 			tput(lin+040);
 | ||
| 			tput(col+040);
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			tputz("\033\175");
 | ||
| 			tput(0100+((lin+1)>>4));
 | ||
| 			tput(0100+((lin+1)&017));
 | ||
| 			tput(0100+((col+1)>>4));
 | ||
| 			tput(0100+((col+1)&017));
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			tputz("\033=");
 | ||
| 			tput(lin+040);
 | ||
| 			tput(col+040);
 | ||
| 			break;
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| 	curs_lin = lin;
 | ||
| 	curs_col = col;
 | ||
| }
 | ||
| 
 | ||
| /* T_BACKSPACE() - Back up 1 character position.
 | ||
|  *	Updates curs_col.
 | ||
|  *	Only valid if tvc_bs has a "reasonable" value ( < 1000)
 | ||
|  */
 | ||
| 
 | ||
| t_backspace()
 | ||
| {
 | ||
| #if TX_TERMCAP
 | ||
| 	if(BC) tputz(BC);	/* Use alternate BS */
 | ||
| 	else
 | ||
| #endif
 | ||
| 	tput('\010');		/* Send BS */
 | ||
| 	--curs_col;
 | ||
| }
 | ||
| 
 | ||
| /* T_BELL() - Ring terminal's bell (or flash something, or whatever).
 | ||
|  *	Forces out all output thus far, to ensure immediate attention.
 | ||
|  *	This used to be an unbuffered feep, but was changed to use normal
 | ||
|  *	output path in order to avoid messing up terminal escape sequences.
 | ||
|  */
 | ||
| t_bell()
 | ||
| {
 | ||
| #if TXC_VISBEL && TX_TERMCAP
 | ||
| 	if(TC_vb)
 | ||
| 	        tputz(TC_vb);		/* Do visible bell if possible */
 | ||
| 	else
 | ||
| #endif
 | ||
|         tput(BELL);
 | ||
|         tbufls();       /* Force it out */
 | ||
| }
 | ||
| 
 | ||
| /* T_CLEOL() - Clear to End Of Line.
 | ||
|  *	Only valid if trm_flags has TF_CLEOL set.
 | ||
|  */
 | ||
| 
 | ||
| t_cleol ()
 | ||
| {
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			putpad(TC_ce);
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(027);
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* If this exists, TN_H19 will too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			tputz("\033K");
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			tputz("\033K");
 | ||
| 			tpad(41);	/* 1/25 sec padding */
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			tputz("\033T");
 | ||
| 			break;
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| /* T_INSLIN(n, bot) - Insert lines in window.
 | ||
|  *	n   - # blank lines to insert.
 | ||
|  *	bot - # of last line of current window
 | ||
|  *
 | ||
|  *		The current line is moved down and N blank lines inserted.
 | ||
|  *	Lines which are moved past bot are lost.
 | ||
|  *	May leave cursor in random place.
 | ||
|  *	Only valid if trm_flags has TF_IDLIN set.
 | ||
|  */
 | ||
| 
 | ||
| t_inslin (n, bot)
 | ||
| int   n;			/* number of lines */
 | ||
| int   bot;			/* line number of last line in window */
 | ||
| {	register  i, j;
 | ||
| 	int savc,savl;
 | ||
| 
 | ||
| 	if((i = n) <= 0) return;
 | ||
| 	if(bot < (scr_ht-1))
 | ||
| 	  {	savc = curs_col;
 | ||
| 		savl = curs_lin;
 | ||
| 		t_curpos(bot-i, 0);
 | ||
| 		t_dellin(i, scr_ht);
 | ||
| 		t_curpos(savl, savc);
 | ||
| 	  }
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			if(TC_AL)
 | ||
| 				putpar(TC_AL, i, i);
 | ||
| 			else if(TC_ia)
 | ||
| 			  {	putpad(TC_im);
 | ||
| 				do { putpad(TC_ia);
 | ||
| 				  } while(--i);
 | ||
| 				putpad(TC_ei);
 | ||
| 			  }
 | ||
| 			else
 | ||
| 				do { putnpad(TC_al, scr_ht - curs_lin);
 | ||
| 				  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(020);		/* Enter I/D mode */
 | ||
| 			do {	tput(012);		/* Insert line */
 | ||
| 			  	switch(trm_ospeed)
 | ||
| 				  {	case 13: j = 17; break;	/* 9600 */
 | ||
| 					case 12: j = 8; break;	/* 4800 */
 | ||
| 					case 11: j = 4; break;	/* 2400 */
 | ||
| 					case 9:  j = 2; break;	/* 1200 */
 | ||
| 					default: j = 0; break;
 | ||
| 				  }
 | ||
| 				tpadn(j);
 | ||
| 			  } while(--i);
 | ||
| 			tput(030);			/* Exit I/D mode */
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_H19
 | ||
| 	/* NOTE: H19 supposedly requires 19 ms for each line during line I/D
 | ||
| 	 * operations.
 | ||
| 	 * In actual practice, at 9600 baud 25 pads are necessary (24 wont work!)
 | ||
| 	 * for both I and D.  Plus esc-E needs 9 pads.
 | ||
| 	 */
 | ||
| 		case TN_H19:
 | ||
| 			do {	tputz("\033L");
 | ||
| 				switch(trm_ospeed)
 | ||
| 				  {	case 13: j = 25; break;
 | ||
| 					case 9:	j = 4; break;
 | ||
| 					case 7: j = 1; break;
 | ||
| 					default: j = 0; break;
 | ||
| 				  }
 | ||
| 				tpadn(j);
 | ||
| 			  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:
 | ||
| 			do {	tputz("\033L");  /* no padding required */
 | ||
| 		  	  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			do {	tputz("\033L");
 | ||
| 				tpad(100*(scr_ht - curs_lin));	/* .1 per moved line*/
 | ||
| 			  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			do tputz("\033E");
 | ||
| 			while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| /* T_DELLIN(n, bot) - Delete lines from window.
 | ||
|  *	n   - # lines to delete.
 | ||
|  *	bot - # of last line of current window.
 | ||
|  *		The current line, and N-1 following lines, are deleted.
 | ||
|  *	Blank lines are inserted past bot.
 | ||
|  *	Cursor should be left at original position.
 | ||
|  *	Only valid if trm_flags has TF_IDLIN set.
 | ||
|  */
 | ||
| t_dellin (n, bot)
 | ||
| int   n;			/* number of lines */
 | ||
| int   bot;			/* line number of last line in window */
 | ||
| {	register  i, j;
 | ||
| 	int savl, savc;
 | ||
| 
 | ||
| 	if((i = n) <= 0) return;
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			if(TC_DL)
 | ||
| 				putpar(TC_DL, i, i);
 | ||
| 			else if(TC_id)
 | ||
| 			  {	putpad(TC_dm);
 | ||
| 				do putpad(TC_id);
 | ||
| 				while(--i);
 | ||
| 				putpad(TC_ed);
 | ||
| 			  }
 | ||
| 			else
 | ||
| 				do { putnpad(TC_dl,scr_ht - curs_lin);
 | ||
| 				  } while(--i);
 | ||
| 
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(020);
 | ||
| 			do {	tput(032);
 | ||
| 			  	if(trm_ospeed >= 13)	/* 9600 */
 | ||
| 					tput(0177);
 | ||
| 			  } while(--i);
 | ||
| 			tput(030);
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			do {	tputz("\033M");
 | ||
| 				switch(trm_ospeed){
 | ||
| 					case 13: j = 25; break;
 | ||
| 					case 9:	j = 4; break;
 | ||
| 					case 7: j = 1; break;
 | ||
| 					default: j = 0; break;
 | ||
| 					}
 | ||
| 				tpadn(j);
 | ||
| 			  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:
 | ||
| 			do {	tputz("\033M");	  /* no padding required */
 | ||
| 			  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			do {	tputz("\033M");
 | ||
| 				tpad(100*(scr_ht - curs_lin));
 | ||
| 			  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			do {	tputz("\033R");
 | ||
| 			  } while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| 	if(bot < (scr_ht-1))
 | ||
| 	  {	savl = curs_lin;
 | ||
| 		savc = curs_col;
 | ||
| 		t_curpos(bot-n,0);
 | ||
| 		t_inslin(n,scr_ht);
 | ||
| 		t_curpos(savl,savc);
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| /* T_INSCHR(n, str) - Insert n chars in current line
 | ||
|  *	n   - # characters to insert
 | ||
|  *	str - Pointer to char string.  If 0, insert spaces.
 | ||
|  *
 | ||
|  *	Insert N characters from string str at current position.
 | ||
|  *	The cursor may move but curs_col must be updated.
 | ||
|  *	Only valid if trm_flags has TF_IDCHR set.
 | ||
|  */
 | ||
| t_inschr(n, str)
 | ||
| int n;
 | ||
| char *str;
 | ||
| {	register int i;
 | ||
| 	register char *cp;
 | ||
| 
 | ||
| 	if((i = n) <= 0) return;
 | ||
| 	cp = str;
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			putpad(TC_im);		/* Go into insert mode */
 | ||
| 			if(TC_IC)
 | ||
| 			  {	putpar(TC_IC, i, 1);
 | ||
| 				if(cp) tputn(cp, i);
 | ||
| 				else do tput(SP); while(--i);
 | ||
| 			  }
 | ||
| 			else do {
 | ||
| 				if(TC_ic) putpad(TC_ic);
 | ||
| 				if(cp) tput(*cp++);
 | ||
| 				else tput(SP);
 | ||
| 				if(TC_ip) putpad(TC_ip);
 | ||
| 			  } while(--i);
 | ||
| 			putpad(TC_ei);		/* Exit insert mode */
 | ||
| 			curs_col += n;
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* If this exists, TN_H19 will too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			tputz("\033@");		/* Enter ins char mode */
 | ||
| 			do {	if(cp) tput(*cp++);
 | ||
| 				else tput(SP);
 | ||
| 			  } while(--i);
 | ||
| 			tputz("\033O");		/* Exit ins char mode */
 | ||
| 			curs_col += n;
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(020);		/* Enter I/D mode */
 | ||
| 			if(trm_ospeed == 13)	/* 9600 baud lossage */
 | ||
| 			  {	do {
 | ||
| 					tputz(" \177");	/* SP and DEL */
 | ||
| 				  } while(--i);
 | ||
| 				tput(030);
 | ||
| 				i = n;
 | ||
| 				if(i < 3)	/* If close enough, */
 | ||
| 					tputn("\010\010", i);	/* use BSes */
 | ||
| 				else t_curpos(curs_lin, curs_col);
 | ||
| 			  }
 | ||
| 			else			/* Not 9600, can win */
 | ||
| 			  {	do { tput(034);
 | ||
| 				  } while(--i);
 | ||
| 				tput(030);
 | ||
| 				if(cp == 0) return;
 | ||
| 				i = n;
 | ||
| 			  }
 | ||
| 
 | ||
| 			do {	if(cp) tput(*cp++);
 | ||
| 				else tput(SP);
 | ||
| 			  } while(--i);
 | ||
| 			curs_col += n;
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			do {
 | ||
| 				tputz("\033@");
 | ||
| 				if(cp) tput(*cp++);
 | ||
| 				else tput(SP);
 | ||
| 			  } while(--i);
 | ||
| 			curs_col += n;
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			do {	tputz("\033Q");
 | ||
| 			  } while(--i);
 | ||
| 			if(cp)
 | ||
| 			  {	tputn(cp, n);
 | ||
| 				curs_col += n;
 | ||
| 			  }
 | ||
| 			break;
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| /* T_DELCHR(n) - Delete N chars in current line.
 | ||
|  *	Deletes the N characters to the right of the cursor.  Remaining
 | ||
|  *	chars are shifted left.  The cursor should not move.
 | ||
|  *	Only valid if trm_flags has TF_IDCHR set.
 | ||
|  */
 | ||
| t_delchr(n)		/* Delete N chars at current loc */
 | ||
| int n;
 | ||
| {	register int i;
 | ||
| 
 | ||
| 	if((i = n) <= 0) return;
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			putpad(TC_dm);	/* Enter delete mode */
 | ||
| 			if(TC_DC)
 | ||
| 				putpar(TC_DC, i, 1);
 | ||
| 			else do {	/* Delete char while in del mode */
 | ||
| 				putpad(TC_dc);
 | ||
| 			} while(--i);
 | ||
| 			putpad(TC_ed);	/* Exit delete mode */
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* If this exists, TN_H19 will too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			do tputz("\033N");
 | ||
| 			while(--i);
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| #if TX_DM2500
 | ||
| 		case TN_DM2500:
 | ||
| 			tput(020);		/* Enter I/D mode */
 | ||
| 			do if(trm_ospeed == 13)	/* 9600? */
 | ||
| 				tputz("\010\177");	/* BS and DEL */
 | ||
| 			  else tput(010);
 | ||
| 			while(--i);
 | ||
| 			tput(030);		/* Exit I/D mode */
 | ||
| 			break;
 | ||
| #endif /*TX_DM2500*/
 | ||
| #if TX_OM8025
 | ||
| 		case TN_OM8025:
 | ||
| 			do tputz("\033P");
 | ||
| 			while (--i);
 | ||
| 			break;
 | ||
| #endif /*TX_OM8025*/
 | ||
| #if TX_TVI925
 | ||
| 		case TN_TVI925:
 | ||
| 			do {	tputz("\033W");
 | ||
| 			  } while(--i);
 | ||
| #endif /*TX_TVI925*/
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| #if FX_SOWIND
 | ||
| 
 | ||
| /* T_STANDOUT(n) - Enter or leave standout mode.
 | ||
|  *	n   - 0 to return to normal display mode,
 | ||
|  *	      1 to enter standout display mode.
 | ||
|  *		This is usually reverse video but may be something else.
 | ||
|  *
 | ||
|  *	Only valid if trm_flags has TF_SO set.
 | ||
|  */
 | ||
| 
 | ||
| t_standout(on)
 | ||
| int on;
 | ||
| {
 | ||
| 	switch(tv_type)
 | ||
| 	  {
 | ||
| #if TX_TERMCAP
 | ||
| 		case TN_TERMCAP:
 | ||
| 			putpad(on ? TC_so : TC_se);
 | ||
| 			break;
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| 
 | ||
| #if TX_COHIBM
 | ||
| 		case TN_COHIBM:		/* Note TN_H19 will exist too */
 | ||
| #endif /*TX_COHIBM*/
 | ||
| #if TX_H19
 | ||
| 		case TN_H19:
 | ||
| 			tputz(on ? "\033p" : "\033q");
 | ||
| 			break;
 | ||
| #endif /*TX_H19*/
 | ||
| 	  }
 | ||
| }
 | ||
| #endif /*FX_SOWIND*/
 | ||
| 
 | ||
| 
 | ||
| /* TPADN(n) - Output N pad chars.
 | ||
|  */
 | ||
| static void
 | ||
| tpadn(n)
 | ||
| int n;
 | ||
| {	register int i, pad;
 | ||
| 	if((i = n) > 0)
 | ||
| 	  {	pad = tv_padc;
 | ||
| 		do { tput(pad);
 | ||
| 		  } while(--i);
 | ||
| 	  }
 | ||
| }
 | ||
| 
 | ||
| /* TPAD(msec) - Output padding for given # of milliseconds.
 | ||
|  */
 | ||
| static void
 | ||
| tpad(n)
 | ||
| int n;
 | ||
| {	register int i, i2;
 | ||
| 
 | ||
| 	i = n;
 | ||
| 	while(i > 0)
 | ||
| 	  {	if((i2 = 320) < i)	/* So can use integers */
 | ||
| 			i2 = i;
 | ||
| 		i -= i2;
 | ||
| 		i2 *= 100;
 | ||
| 		while((i2 -= tv_cspeed) > 0)
 | ||
| 			tput(tv_padc);
 | ||
| 	  }
 | ||
| }
 | ||
| #if TX_TERMCAP
 | ||
| /*
 | ||
|  * Print the string str, interpreting padding.
 | ||
|  */
 | ||
| int tput();	/* Our output function */
 | ||
| static void
 | ||
| putpad(str)
 | ||
| char *str;
 | ||
| {	if(str) tputs(str, 1, tput);	/* Invoke TERMCAP function */
 | ||
| }
 | ||
| static void
 | ||
| putnpad(str,n)
 | ||
| char *str;
 | ||
| int n;
 | ||
| {	if(str) tputs(str, n, tput);
 | ||
| }
 | ||
| static void
 | ||
| putpar(str, par, n)		/* Wish we had tparm() */
 | ||
| char *str;
 | ||
| int par,n;
 | ||
| {	putnpad(tgoto(str, 0, par), n);
 | ||
| }
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| 
 | ||
| /*
 | ||
|  * Read in the stuff from termcap upon startup.
 | ||
|  */
 | ||
| 
 | ||
| #if TX_TERMCAP
 | ||
| static int tstrlen(), tstrlp();
 | ||
| 
 | ||
| #ifndef TCAPSLEN
 | ||
| #define TCAPSLEN 1024	/* Default size of buffer for TERMCAP strings */
 | ||
| #endif /*-TCAPSLEN*/
 | ||
| 
 | ||
| static int
 | ||
| getcap(stype)
 | ||
| char *stype;
 | ||
| {	register char *t;
 | ||
| 	register int i;
 | ||
| 	int buflen;
 | ||
| 	char *tcbuf, *tcbptr;		/* Pointers into termcap buffer */
 | ||
| 	char tmpstr[4];
 | ||
| 	char tmpbuf[TCAPSLEN];		/* Allocate from stack */
 | ||
| 	char *malloc();
 | ||
| 	char *realloc();
 | ||
| 
 | ||
| 	/* First see if can find the terminal type. */
 | ||
| 	if((tgetent(tmpbuf, stype)) != 1)
 | ||
| 		return(0);
 | ||
| 
 | ||
| 	/* Found it!  Set up a string buffer to save the caps. */
 | ||
| 	if(!(tcbuf = malloc(TCAPSLEN)))	/* Get permanent buffer */
 | ||
| 		t_fatal(" - cannot allocate termcap buffer");
 | ||
| 	tcbptr = tcbuf;
 | ||
| 
 | ||
| 	/* Now gobble all the string caps that ELLE wants to know about. */
 | ||
| 	tmpstr[3] = '\0';
 | ||
| 	i = NTCAPS;
 | ||
| 	do {
 | ||
| 		tmpstr[0] = tcap[i].tcicod1;	/* Make str of the code */
 | ||
| 		tmpstr[1] = tcap[i].tcicod2;
 | ||
| 		tcap[i].tccap = tgetstr(tmpstr, &tcbptr);	/* Get cap */
 | ||
| 	} while(--i);
 | ||
| 	buflen = tcbptr - tcbuf;	/* String buffer done, finalize */
 | ||
| 	if(buflen >= TCAPSLEN)
 | ||
| 		t_fatal("description too big!");
 | ||
| 	realloc(tcbuf, buflen);		/* Free up unused part of buffer */
 | ||
| 					/* (this better not move it!!!) */
 | ||
| 
 | ||
| 	/* Now get the number/flag stuff that ELLE needs. */
 | ||
| 	tc_am = tgetflag("am");		/* auto wrap */
 | ||
| 	if (tgetflag("xn")) tc_am = 0;	/* auto wrap at 81st char, nice! */
 | ||
| 	tc_km = (tgetflag("km")		/* TTY has meta key */
 | ||
| 		|| tgetflag("MT"));	/* Alternate version of "km"?? */
 | ||
| 	scr_ht = tgetnum("li");		/* Set screen height (# lines) */
 | ||
| 	scr_wid = tgetnum("co");	/* Set screen width (# cols) */
 | ||
| 	ts_winsize();
 | ||
| 
 | ||
| 	/* Now initialize the stupid external vars that TERMCAP rtns want. */
 | ||
| 	if(TC_pc) PC = *TC_pc;	/* Pad char */
 | ||
| 	BC = TC_bc;		/* Backspace str (if no BS) */
 | ||
| 	UP = TC_up;		/* Cursor up */
 | ||
| 	ospeed = trm_ospeed;	/* Put output speed here */
 | ||
| 
 | ||
| 
 | ||
| 	/* Basic data extracted, now mull over it and set the remaining
 | ||
| 	 * ELLE variables
 | ||
| 	 */
 | ||
| #if FX_SOWIND
 | ||
| 	if(tgetnum("sg") <= 0)		/* If no magic cookie problems */
 | ||
| 	  {	if (TC_so && TC_se)	/* And have standout caps, */
 | ||
| 			trm_flags |= TF_SO;	/* Say has standout cap */
 | ||
| 	  }
 | ||
| #endif
 | ||
| 
 | ||
| 	if (!(TC_cm && TC_cl))
 | ||
| 		t_fatal("lacks cursor addressing or clear screen.");
 | ||
| 	tvc_pos = tstrlen(TC_cm);		/* Find cost of abs move */
 | ||
| 	if(BC)					/* Find cost of backspace */
 | ||
| 		tvc_bs = tstrlen(BC);
 | ||
| 
 | ||
| 	/* Find costs for doing I/D char operations */
 | ||
| 	if ((TC_im||TC_ic) && (TC_dm||TC_dc))
 | ||
| 	  {	trm_flags |= TF_IDCHR;
 | ||
| 		tvc_ci  = tstrlen(TC_im)+tstrlen(TC_ei);
 | ||
| 		tvc_cin = tstrlen(TC_ic)+1+tstrlen(TC_ip);
 | ||
| 		if(TC_IC)			/* If have multi-IC, use it */
 | ||
| 		  {	tvc_ci += tstrlp(TC_IC, 1);
 | ||
| 			tvc_cin = 1;
 | ||
| 		  }
 | ||
| 		tvc_cd  = tstrlen(TC_dm)+tstrlen(TC_ed);
 | ||
| 		tvc_cdn = tstrlen(TC_dc);
 | ||
| 		if(TC_DC)			/* If have multi-DC, use it */
 | ||
| 		  {	tvc_cd += tstrlp(TC_DC, 1);
 | ||
| 			tvc_cdn = 0;
 | ||
| 		  }
 | ||
| 	  }
 | ||
| 
 | ||
| 	/* Find costs for doing I/D line operations */
 | ||
| 	if ((TC_ia || TC_al) && (TC_id || TC_dl))
 | ||
| 	  {	trm_flags |= TF_IDLIN;
 | ||
| 		tvc_li = 0;			/* Usual case */
 | ||
| 		tvc_lin = tstrlen(TC_al);
 | ||
| 		if(TC_AL)			/* If have multi-IL, use it */
 | ||
| 		  {	tvc_li  = tstrlp(TC_AL, 1);
 | ||
| 			tvc_lin = tstrlp(TC_AL, 2) - tvc_lin;
 | ||
| 		  }
 | ||
| 		else if(TC_ia)
 | ||
| 		  {	tvc_li  = tstrlen(TC_im)+tstrlen(TC_ei);
 | ||
| 			tvc_lin = tstrlen(TC_ia);
 | ||
| 		  }
 | ||
| 
 | ||
| 		tvc_ld = 0;			/* Usual case */
 | ||
| 		tvc_ldn = tstrlen(TC_dl);
 | ||
| 		if(TC_DL)			/* If have multi-DL, use it */
 | ||
| 		  {	tvc_ld  = tstrlp(TC_DL, 1);
 | ||
| 			tvc_ldn = tstrlp(TC_DL, 2) - tvc_ld;
 | ||
| 		  }
 | ||
| 		else if(TC_id)
 | ||
| 		  {	tvc_ld = tstrlen(TC_dm)+tstrlen(TC_ed);
 | ||
| 			tvc_ldn = tstrlen(TC_id);
 | ||
| 		  }
 | ||
| 	  }
 | ||
| 
 | ||
| 	if (tc_am)
 | ||
| 	  {	scr_wid--;		/* For now, avoid invoking wrap. */
 | ||
| #if 0
 | ||
| 		trm_flags |= AUTOWRAP;	/* */
 | ||
| #endif
 | ||
| 	  }
 | ||
| 	if (TC_ce) trm_flags |= TF_CLEOL;		/* Term has CLEOL? */
 | ||
| 	if (tc_km) trm_flags |= TF_METAKEY;	/* Term has meta key? */
 | ||
| 
 | ||
| 	return(1);
 | ||
| }
 | ||
| 
 | ||
| /* Pair of routines which conspire in order to find # chars actually output
 | ||
|  * by a particular termcap string.
 | ||
|  */
 | ||
| static int _tslen;		/* Stored count */
 | ||
| static void _tslinc(ch) { _tslen++; }
 | ||
| static int
 | ||
| tstrlen(str)
 | ||
| char *str;
 | ||
| {	_tslen = 0;
 | ||
| 	if(str && str[0])
 | ||
| 		tputs(str, 1, _tslinc);	/* Mult padding by just 1 */
 | ||
| 	return(_tslen);
 | ||
| }
 | ||
| 
 | ||
| static int
 | ||
| tstrlp(str, par)		/* Same but with parameter */
 | ||
| char *str;
 | ||
| int par;
 | ||
| {
 | ||
| #if 0
 | ||
| 	if(str)
 | ||
| 	  {	char *cp = tgoto(str, 0, par);
 | ||
| 		int i = strlen(cp);
 | ||
| 		while(--i >= 0)
 | ||
| 			printf(" %o", *cp++);
 | ||
| 		printf("\n");
 | ||
| 	  }
 | ||
| #endif
 | ||
| 	return !str ? 0 : tstrlen(tgoto(str, 0, par));
 | ||
| }
 | ||
| #endif /*TX_TERMCAP*/
 | ||
| 
 | ||
| /* Direct-Video terminal output routine
 | ||
|  *	Currently only COHERENT has this capability.
 | ||
|  */
 | ||
| 
 | ||
| #if COHERENT
 | ||
| #include <sgtty.h>
 | ||
| 
 | ||
| struct vidctl {
 | ||
| 	int	v_position;		/* Position in video memory */
 | ||
| 	int	v_count;		/* Number of characters to transfer */
 | ||
| 	char	*v_buffer;		/* Character buffer to read/write */
 | ||
| };
 | ||
| /*
 | ||
|  * Attribute masks for TIOVPUTB - attributes occupy odd addresses
 | ||
|  * in video memory.
 | ||
|  */
 | ||
| #define	VNORM	0x07			/* Ordinary Video */
 | ||
| #define	VINTE	0x08			/* Intense video */
 | ||
| #define	VBLIN	0x80			/* Blinking video */
 | ||
| #define	VREVE	0x70			/* Reverse video */
 | ||
| #define	VUNDE	0x01			/* Underline video (mono board) */
 | ||
| 
 | ||
| /* T_DIRECT(line, col, string, len) - Do direct-video output of string.
 | ||
|  *	Puts the string ("len" chars in length) on the screen starting at
 | ||
|  *	the X,Y character position given by col, line.
 | ||
|  *	This routine is only called if terminal has the "TF_DIRVID" flag set.
 | ||
|  */
 | ||
| t_direct(lin, col, str, len)
 | ||
| int lin, col;
 | ||
| register char *str;
 | ||
| register int len;
 | ||
| {	register char *cp;
 | ||
| 	char vbuf[MAXLINE*2];
 | ||
| 	struct vidctl v;
 | ||
| 
 | ||
| 	if(len <= 0) return;
 | ||
| 	tbufls();		/* Ensure normal output is forced out */
 | ||
| 	v.v_position = (lin*80 + col)*2;
 | ||
| 	v.v_count = len*2;
 | ||
| 	v.v_buffer = cp = vbuf;
 | ||
| 	do {
 | ||
| 		*cp++ = *str++;
 | ||
| 		*cp++ = VNORM;
 | ||
| 	  } while(--len);
 | ||
| 	ioctl(1, TIOVPUTB, &v);
 | ||
| }
 | ||
| #endif /*COHERENT*/
 | ||
| 
 | ||
| /*
 | ||
|  * Terminal Output buffering routines
 | ||
|  */
 | ||
| 
 | ||
| static char tbuf[TOBFSIZ];	/* Output buffer */
 | ||
| static int tbufcnt = 0;		/* # chars of room left in buffer */
 | ||
| static char *tbufp = 0;		/* Pointer to deposit in buffer */
 | ||
| 
 | ||
| tput(ch)
 | ||
| int ch;
 | ||
| {	if(--tbufcnt < 0)
 | ||
| 		tbufls();
 | ||
| 	*tbufp++ = ch;
 | ||
| }
 | ||
| 
 | ||
| tputz(str)
 | ||
| char *str;
 | ||
| {	register int c;
 | ||
| 	register char *cp, *tp;
 | ||
| 	cp = str;
 | ||
| 	tp = tbufp;
 | ||
| 	while(c = *cp++)
 | ||
| 	  {	if(--tbufcnt < 0)
 | ||
| 		  {	tbufp = tp;
 | ||
| 			tbufls();
 | ||
| 			tp = tbufp;
 | ||
| 		  }
 | ||
| 		*tp++ = c;
 | ||
| 	  }
 | ||
| 	tbufp = tp;
 | ||
| }
 | ||
| 
 | ||
| tputn(str,cnt)
 | ||
| char *str;
 | ||
| int cnt;
 | ||
| {	register int c;
 | ||
| 	register char *cp, *tp;
 | ||
| 	cp = str;
 | ||
| 	tp = tbufp;
 | ||
| 	if((c = cnt) > 0)
 | ||
| 	do {
 | ||
| 		if(--tbufcnt < 0)
 | ||
| 		  {
 | ||
| 			tbufp = tp;
 | ||
| 			tbufls();
 | ||
| 			tp = tbufp;
 | ||
| 		  }
 | ||
| 		*tp++ = *cp++;
 | ||
| 	  } while(--c);
 | ||
| 	tbufp = tp;
 | ||
| }
 | ||
| 
 | ||
| tbufls()
 | ||
| {	register int cnt;
 | ||
| 
 | ||
| 	if(tbufp
 | ||
| 	  && (cnt = tbufp - tbuf) > 0)		/* # chars written */
 | ||
| 		write(1, tbuf, cnt);		/* Out they go */
 | ||
| 	tbufp = tbuf;
 | ||
| 	tbufcnt = TOBFSIZ-1;	/* Allow for usual expected decrement */
 | ||
| }
 | ||
| 
 | ||
| /*
 | ||
|  * Terminal Input buffering routines
 | ||
|  */
 | ||
| 
 | ||
| int tibfmsk = -1;		/* Mask AND'ed with input chars (external) */
 | ||
| static char tibuf[TIBFSIZ];	/* TTY input buffer */
 | ||
| static char *tibfp;		/* Pointer to read from buffer */
 | ||
| static int tibfcnt = 0;		/* # chars left to be read from buffer */
 | ||
| 
 | ||
| tgetc()
 | ||
| {
 | ||
| #if SUN
 | ||
| 	register int c;
 | ||
| 	extern int sun_winfd, sun_rdevf;
 | ||
| 
 | ||
| 	if(sun_winfd)
 | ||
| 	  {	if(!sun_rdevf)
 | ||
| 			return(sun_input(1)&tibfmsk);
 | ||
| 		sun_rdevf = 0;		/* Check mouse too, but only once! */
 | ||
| 		c = sun_input(0);
 | ||
| 		if(c != -1) c &= tibfmsk;
 | ||
| 		return(c);
 | ||
| 	  }
 | ||
| #endif /*SUN*/
 | ||
| 	while(--tibfcnt < 0)
 | ||
| 		tibfcnt = read(0,(tibfp = tibuf),TIBFSIZ);
 | ||
| 	return((*tibfp++)&tibfmsk);
 | ||
| }
 | ||
| 
 | ||
| tinwait()
 | ||
| {	return(tibfcnt > 0 || ts_inp());
 | ||
| }
 | 
