|
|
Power 6/32 Unix version 1.21
/* D.L.Buck and Associates, Inc. - May, 1984
*
* COPYRIGHT NOTICE:
* Copyright c 1984 - An unpublished work by
* D.L.Buck and Associates, Inc.
*
* PROPRIETARY RIGHTS NOTICE:
* All rights reserved. This document and program contains
* proprietary information of D.L.Buck and Associates,Inc.
* of San Jose, California, U.S.A., embodying confidential
* information, ideas, and expressions, no part of which
* may be reproduced, or transmitted in any form or by any
* means, electronic, mechanical, or otherwise, without
* the written permission of D.L.Buck and Associates, Inc.
*
* NAME
* emsetup
* SYNOPSIS
* emsetup(term)
* char *term;
* DESCRIPTION
* NOTE: If terminal is to be managed, 'do_screen' must be
* set to a non-zero value. Otherwise, the package only
* manages the data structures fldstart, fldmax, fldattr,
* totfields, curfield, bufaddr, and cursaddr.
* emsetup() sets the terminal characteristics for emulation via
* ioctl, does keyboard mapping of special function keys via
* termcap, initializes the window curses uses to manipulate
* the cursor and the screen image, and the data structures
* used to attend to the screen image.
*
* ALGORITHM
* I. Initialize data structures
* A. screen-image cross-indices and arrays
* B. termcap key string structures and arrays
* The function key structure tcts defines function key
* name, where to find corresponding character string,
* default character string value, and value to return
* if that key has been pressed.
* C. terminal information structures
* These are used to save the original terminal
* characteristics and set the emulation characteristics.
*
* II. Set up function key table
* A. assign values defined in tcts structure to the
* function key table.
*
* III. Get terminal information
* A. terminal type
* B. termcap entry
* This is captured by tgetent(), which gets the
* terminal's termcap entry and saves it in a convenient
* buffer.
* C. get the number of lines, columns, and characters
* added by the standout mode from the entry.
* This information is captured by tgetnum(), which
* returns the numeric value for specified character-
* istics.
* D. put termcap's function key string values for each
* function into the function table.
* for each function key:
* get its string value from termcap
* (tgetstr() does this nicely)
*
* if no value was assigned in termcap:
* assign function key's string to
* the default value contained in the
* table
* set its length to 1
* else
* set the string value's length to
* the termcap string's length
*
* III. Set terminal characteristics
* A. do ioctls to get current characteristics
* B. save terminal's characteristics and baud rate
* C. set signal to call the cleanup routine if
* interrupt encountered
* cleanup() sets the original terminal characteristics
* and exits
* D. use ioctl to set the terminal characteristics for
* 3277 emulation.
*
* IV. Initialize the curses window
*/
static char s_emterm[] = "@(#)CCIemterm.c 1.24 REL";
#include <em.h>
#include "local.h"
#include <signal.h>
#include <ctype.h>
#ifndef v7
#ifndef DEBUG
#include <fcntl.h>
#endif
#endif
int do_screen; /* Set if caller wants display managed */
extern int initflag; /* set if initscr called */
extern FILE *aud;
extern char audname[];
extern char new_audnm[];
extern char auditlock[];
extern WINDOW *curscr;
int fldstart[MAXFIELDS]; /* Index of starting position of each
field's first data character.
Attribute characters are immediately
before each field. */
char fldattr[MAXFIELDS]; /* Attribute of each field */
int fldmax[MAXFIELDS]; /* Maximum width of each field */
int totfields; /* Total number of fields on screen */
int curfield; /* Current field number */
int bufaddr; /* Current buffer address, 0 to
MAXSCREENSIZE-1 */
int cursaddr; /* Current cursor address, 0 to
MAXSCREENSIZE-1 */
/* scrn_image is a replica of the current ASCII screen image, except that
attribute characters are replaced with ATTRCODE (see em.h) */
char scrn_image[MAXSCREENSIZE];
/* scrn_xref is a cross-reference into scrn_image. It contains the current
field number corresponding to each screen location.
For example, a screen containing two fields, one beginning at screen
position 10 and the other beginning at screen position 30, can be
visualized as follows (top row of numbers represent screen positions):
0 1 2 3 4 5
012345678901234567890123456789012345678901234567890...
111111111122222222222222222222333333333333333333333...
*/
int scrn_xref[MAXSCREENSIZE];
/* status indicates 3277 terminal status */
int status;
WINDOW *stat_scr;
int sigalrm(); /* for dealing with v7 alarm signals */
int COLS; /* number of columns */
int LINES; /* # lines on screen */
int SG; /* # chars added by SO */
char *SO; /* standout character sequence */
char *SE; /* standend character sequence */
char * S0; /* ESC string */
char * S1; /* ENTER string */
char * S2; /* CLEAR string */
char * S3; /* BACKTAB string */
char * S4; /* ERASE_EOF string */
char * S5; /* ERASE_INP string */
char * S6; /* INS string */
char * S7; /* DELCHAR string */
char * S8; /* DUP string */
char * S9; /* FM string */
char * bs; /* bs key */
char * cr; /* cr key */
char * kd; /* down arrow key */
char * kl; /* left arrow key */
char * kr; /* right arrow key */
char * ta; /* tab key string */
char * ku; /* up arrow key */
char * P1; /* pf1 string */
char * P2; /* pf2 string */
char * P3; /* pf3 string */
char * P4; /* pf4 string */
char * P5; /* pf5 string */
char * P6; /* pf6 string */
char * P7; /* pf7 string */
char * P8; /* pf8 string */
char * P9; /* pf9 string */
char * Pa; /* pf10 string */
char * Pb; /* pf11 string */
char * Pc; /* pf12 string */
char * A1; /* pa1 string */
char * A2; /* pa2 string */
char * A3; /* pa3 string */
char * SZ; /* reset string */
char * SH; /* help string */
char * ST; /* statistics string */
char * SP; /* print string */
struct tcts {
char em_name[4]; /* name of item in termcap entry */
char **em_s; /* addr of addr of corresponding char string */
char em_def; /* default single char. if none in termcap */
int em_keycode; /* value to be returned to caller if this
char. sequence arrives at the terminal */
};
struct tcts em_ktbl[] = {
{"bs", &bs, 010, BACKSP}, /* bs key */
{"cr", &cr, 015, CARRET}, /* CR key */
{"kd", &kd, 012, DOWN}, /* down arrow key */
{"kl", &kl, 010, LEFT}, /* left arrow key */
{"kr", &kr, 014, RIGHT}, /* right arrow key */
{"ku", &ku, 013, UPAR}, /* up arrow key */
{"ta", &ta, 011, TAB}, /* tab key */
{"S0", &S0, 033, ESC}, /* escape key */
{"S1", &S1, 016, ENTER}, /* enter key */
{"S2", &S2, 017, CLEAR}, /* clear key */
{"S3", &S3, 025, BACKTAB}, /* backtab string*/
{"S4", &S4, 031, ERASE_EOF}, /* erase eof string */
{"S5", &S5, 020, ERASE_INP}, /* erase input string*/
{"S6", &S6, 036, INS}, /* insert string */
{"S7", &S7, 0177, DELCHR}, /* delete character string */
{"S8", &S8, 034, DUP}, /* duplicate op. string */
{"S9", &S9, 035, FM}, /* field mark key */
{"P1", &P1, 021, PF1}, /* program function key 1 */
{"P2", &P2, 027, PF2}, /* program function key 2 */
{"P3", &P3, 005, PF3}, /* program function key 3 */
{"P4", &P4, 022, PF4}, /* program function key 4 */
{"P5", &P5, 024, PF5}, /* program function key 5 */
{"P6", &P6, 001, PF6}, /* program function key 6 */
{"P7", &P7, 023, PF7}, /* program function key 7 */
{"P8", &P8, 004, PF8}, /* program function key 8 */
{"P9", &P9, 006, PF9}, /* program function key 9 */
{"Pa", &Pa, 007, PF10}, /* program function key 10 */
{"Pb", &Pb, 026, PF11}, /* program function key 11 */
{"Pc", &Pc, 002, PF12}, /* program function key 12 */
{"A1", &A1, 032, PA1}, /* program attention key 1 */
{"A2", &A2, 030, PA2}, /* program attention key 2 */
{"A3", &A3, 003, PA3}, /* program attention key 3 */
{"SZ", &SZ, 0, RESET}, /* reset key */
{"SH", &SH, 0, HELP}, /* help key */
{"ST", &ST, 0, STATS}, /* statistics key */
{"SP", &SP, 0, PRINT}, /* print key */
{"", (char **)0, 000, 0} /* end of list */
};
#ifdef v7
struct tchars origtchar, termtchar;
struct sgttyb origtio, termio;
#else
struct termio origtio, termio;
#endif
char emarea[256], *emaptr = emarea;
/*
* The following character array, `kytrt', is used by the `getchar'
* routine to translate incoming keystrokes into 3270 keystrokes.
* It is built by examining the TERMCAP entry for this terminal
* for all special keystroke sequences.
* The resulting table has one element per ASCII character; the
* first incoming ASCII character is matched against this table,
* with the following results:
* kytrt[c] == 0 Not a special keystroke
* kytrt[c] == n, n <> 0 Special keystroke of max n chars
*/
char kytrt[128]; /* function key trt table */
#define max(a,b) ((a) > (b)?(a):(b))
emsetup(term) /* set up terminal attributes via em_ktbl */
char *term;
{
register struct tcts *tps; /* pointer into em_ktbl */
register char *sp; /* key string pointer */
char tbuf[1024]; /* buffer for tgetent */
char tname[20];
int ans; /* answer to help ? goes here */
int cleanwin(); /* cleanup before exiting */
/* tgetstr() gets the capability string for a particular function key
from the termcap database entry for this terminal. It decodes the
abbreviations used by termcap, returns the key string which
performs the function desired, and places it in a buffer
(emarea is used here).
for example, tgets for the clear screen function key on a
Zentec 8001 terminal would get:
cl=\EH\EJ
from /etc/termcap, and return the key sequence escape-H escape-J,
which clears the screen. */
char *tgetstr();
int cleanup();
if (term == (char *) 0) term = "dumb";
if (term[0] == '\0') term = "dumb";
if (tgetent(tbuf, term) != 1) {
fprintf(stderr,"em3277: terminal type <%s> unknown\n",
term);
return(1);
}
/* tgetnum is the numeric version of tgetstr -- it get the numeric
* value of the capability named from the /etc/termcap entry for this
* terminal. */
LINES = tgetnum("li");
COLS = tgetnum("co");
SG = tgetnum("sg");
if (SG == -1)
SG = 0;
for (tps = em_ktbl; tps->em_name[0]; ++tps) {
sp = *tps->em_s = tgetstr(tps->em_name,&emaptr);
if (sp == (char *)0) { /* doesn't appear - default */
*tps->em_s = &tps->em_def;
kytrt[tps->em_def] = 1; /* def. string is one char */
} else
kytrt[*sp] = max(strlen(sp), kytrt[*sp]);
}
/* get standout, standend sequences */
SO = tgetstr("so", &emaptr);
SE = tgetstr("se", &emaptr);
#ifdef v7
ioctl (0, TIOCGETC, &origtchar);
ioctl (0, TIOCGETP, &origtio);
#else
ioctl(0,TCGETA, &origtio);
#endif
signal(SIGHUP,cleanwin);
signal(SIGTERM,cleanwin);
cursaddr = 0;
if (do_screen) { /* screen to be managed */
My_term = TRUE; /* force curses to use stdout */
Def_term = term;
gettmode();
initscr(); /* set up virtual terminal screen */
initflag = 1; /* initscr has been called */
crmode(); /* set cbreak mode */
noecho(); /* turn off echo */
nonl(); /* turn off cr-lf mapping */
clearok(curscr,TRUE); /* clear screen next refresh */
/* Set up our 24x80 terminal screen */
vterm_scr = newwin(24,80,0,0);
wmove(vterm_scr,0,0);
werase(vterm_scr);
wrefresh(vterm_scr);
clearok(curscr,FALSE);
/* initialize help screen */
help_scr = newwin(24,80,0,0);
wmove(help_scr,0,0);
werase(help_scr);
/* fill with keyboard map */
tgetent(tbuf, term);
helpinit(term);
/* set up hidden subwindow behind status and command area */
sub_vterm = subwin(vterm_scr,2,80,22,0);
/* set up command window */
cmd_scr = newwin(1,80,LINES-1,0);
wmove(cmd_scr,0,0);
werase(cmd_scr);
/* set up status window */
stat_scr = newwin(1,80,LINES-2,0);
wmove(stat_scr,0,0);
werase(stat_scr);
/* disable interrupts */
#ifdef v7
ioctl (0, TIOCGETC, &termtchar);
termtchar.t_intrc = -1; /* disable DEL as INTR */
ioctl (0, TIOCSETC, &termtchar);
ioctl (0, TIOCGETP, &termio);
#else
ioctl(0, TCGETA, &termio);
termio.c_cc[VINTR] = -1; /* disable DEL as INTR */
termio.c_iflag |= BRKINT; /* break key is reset */
termio.c_iflag &= ~IXON; /* disable xon, xoff */
ioctl(0,TCSETA, &termio);
#endif
signal(SIGALRM,sigalrm);
/* ask if user wants a keyboard map */
wstandout(vterm_scr);
mvwaddstr(vterm_scr,0,0,"Would you like help? (Y/N):");
wmove(vterm_scr,0,30);
wstandend(vterm_scr);
wrefresh(vterm_scr);
while((ans=emgetchar()) == NOCHAR) continue;
if (ans == 'y' || ans == 'Y') {
werase(vterm_scr);
em_help();
}
clearok(curscr,TRUE);
}
return(0);
}
/* emgetchar() - get a character keyed in at the terminal and process it
* Called from emulate().
*
* ALGORITHM
* I. Read the character into a temporary character buffer, cbuf
* II. If nothing was read in, return NOCHAR
* III. If read returned -1, return ERROR
* IV. If character read in has a value in the key length array, it's
* a special function key character. Process it:
* A. for the length specified, read characters into cbuf
* B. search through the function key table for a string value
* match.
* C. if a match is found, return the function key code specified
* in the function key table.
* D. If no match is found, return OTHER.
* V. If the character is not a special function key, process it:
* A. if it's printable, return it
* B. otherwise, return OTHER
* VI. return
*/
#define ERROR -1
extern int errno;
int emgetchar()
{
register int nread;
register char cc;
register struct tcts *em_kyptr; /* ptr into em_ktbl */
register char *s;
extern char kytrt[];
char cbuf[10];
int nmax,nhave;
alarm(1);
nread = read(0,cbuf,1);
alarm(0);
if (nread < 0 && errno == EINTR) return NOCHAR;
if (nread < 0) return ERROR;
if (nread == 0)
return NOCHAR;
cc = cbuf[0];
nhave = nread;
if (nmax = kytrt[cc]) { /* Special keystroke sequence indicated */
while (nread > 0) {
/* Search em_ktbl for sequence of this length */
cbuf[nhave] = '\0'; /* Null-terminate */
for (em_kyptr = em_ktbl; em_kyptr->em_s; em_kyptr++)
if (strcmp(*(em_kyptr->em_s),cbuf)==0) {
return em_kyptr->em_keycode;
}
if (nhave >= nmax)
return OTHER;
nread = read(0, &cbuf[nhave], nmax-nhave);
nhave += nread;
cbuf[nhave] = '\0';
}
if (nread < 0)
return ERROR;
if (nread == 0)
return NOCHAR;
}
if (isprint(cc) || cc == ' ')
return cc;
else return OTHER;
}
/* cleanwin() - clean up before exiting em3277.
*
* ALGORITHM
* I. Finish off curses routines and close the window
* II. Reset the terminal characteristics to their original
* values
* III. Remove temp audit files, lock files, ...
*/
cleanwin()
{
if (initflag) {
endwin();
/* reset original terminal characteristics */
#ifdef v7
ioctl (0, TIOCSETC, &origtchar);
ioctl (0, TIOCSETP, &origtio);
#else
ioctl(0,TCSETA, &origtio);
#endif
}
/* remove temp audit files, lock files, etc.. */
if (aud) {
fclose(aud);
if (link(audname,new_audname) >= 0)
unlink(audname);
unlink(auditlock);
}
}
/* cleanup -- clean up before exiting em3277 */
cleanup()
{
cleanwin();
write(1,"\n",1); /* make screen pretty before leaving */
exit(0);
}
/* update the keyboard status */
updstat(val)
register int val;
{
status = val;
werase(stat_scr);
wstandout(stat_scr);
if (status & LOCK_OUT)
mvwaddstr(stat_scr,0,0,"Input Inhibited");
if (status & SYS_AVAIL)
mvwaddstr(stat_scr,0,20,"System Available");
if (status & INSERT_MODE)
mvwaddstr(stat_scr,0,40,"Insert Mode");
touchwin(stat_scr);
wstandend(stat_scr);
wrefresh(stat_scr);
}
/* sigalrm -- reset alarm signal (for no-delay reading under v7) */
sigalrm()
{
signal(SIGALRM,sigalrm);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.