home *** CD-ROM | disk | FTP | other *** search
- /*
- * Program: Display routines
- *
- * Modifier: Donn Cave
- * University Computing Services
- * University of Washington
- * Seattle, WA 98195
- * Internet: donn@cac.washington.edu
- *
- * Date: 15 April 1992
- * Last Edited: 15 April 1992
- *
- * Copyright 1991 by the University of Washington
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appears in all copies and that both the
- * above copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the University of Washington not be
- * used in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. This software is made
- * available "as is", and
- * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
- * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
- * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
- /*
- tinfo - substitute for tcap, on systems that have terminfo.
- */
-
- #define termdef 1 /* don't define "term" external */
-
- #include <stdio.h>
- #include <sys/ioctl.h>
- #include <termios.h>
- #define NOMACROS
- #define timeout curses_timeout
- #include <curses.h>
- #define WINDOW our_WINDOW
- #undef timeout
- #undef NOMACROS
- #include <term.h>
- #include <signal.h>
- #include "osdep.h"
- #include "estruct.h"
- #include "edef.h"
- #include "pico.h"
-
- extern char *tigetstr ();
-
- #define NROW 24
- #define NCOL 80
- #define MARGIN 8
- #define SCRSIZ 64
- #define BEL 0x07
- #define ESC 0x1B
-
- extern int ttopen();
- extern int ttgetc();
- extern int ttputc();
- extern int ttflush();
- extern int ttclose();
-
- static int tinfomove();
- static int tinfoeeol();
- static int tinfoeeop();
- static int tinfobeep();
- static int tinforev();
- static int tinfoopen();
-
- extern int tput();
- extern char *tgoto();
-
- static char *UP, PC, *CM, *CE, *CL, *SO, *SE;
- /*
- * PICO extentions
- */
- static char *DL, /* delete line */
- *AL, /* insert line */
- *CS, /* define a scrolling region, vt100 */
- *IC, /* insert character, preferable to : */
- *IM, /* set insert mode and, */
- *EI, /* end insert mode */
- *DC, /* delete character */
- *DM, /* set delete mode and, */
- *ED, /* end delete mode */
- *SF, /* scroll text up */
- *SR; /* scroll text down */
-
- static char *KU, *KD, *KL, *KR;
- static char *KPPU, *KPPD, *KPHOME, *KPEND;
-
- struct KBSTREE *kpadseqs = NULL;
-
- TERM term = {
- NROW-1,
- NCOL,
- MARGIN,
- SCRSIZ,
- tinfoopen,
- ttclose,
- ttgetc,
- ttputc,
- ttflush,
- tinfomove,
- tinfoeeol,
- tinfoeeop,
- tinfobeep,
- tinforev
- };
-
-
- static tinfoopen()
- {
- char *t, *p;
- char *tv_stype;
- char *initstrng = "";
- char err_str[72];
- char *getenv();
- struct termios tty;
-
- #ifdef TIOCGWINSZ
- struct winsize win;
- if (ioctl(0, TIOCGWINSZ, &win) == 0) {
- term.t_ncol = (win.ws_col) ? win.ws_col : 80;
- term.t_nrow = (win.ws_row) ? win.ws_row - 1 : 23;
- }
- #endif
-
- /*
- * determine the terminal's communication speed and decide
- * if we need to do optimization ...
- */
- if (tcgetattr (1, &tty) == 0) {
- if(cfgetospeed (&tty) < B9600)
- optimize = TRUE;
- }
-
- if (Pmaster) {
- /*
- * setupterm() automatically retrieves the value
- * of the TERM variable.
- */
- int err;
- setupterm (0, 1, &err);
- if (err != 1) return FALSE;
- }
- else {
- /*
- * setupterm() issues a message and exits, if the
- * terminfo data base is gone or the term type is
- * unknown, if arg2 is 0.
- */
- setupterm (0, 1, 0);
- }
-
- t = tigetstr("pad");
- if(t)
- PC = *t;
-
- CL = tigetstr("clear");
- CM = tigetstr("cup");
- CE = tigetstr("el");
- UP = tigetstr("cuu1");
- SE = tigetstr("rmso");
- SO = tigetstr("smso");
- if (SO != NULL)
- revexist = TRUE;
-
- DL = tigetstr("dl1");
- AL = tigetstr("il1");
- CS = tigetstr("csr");
- IC = tigetstr("ich1");
- IM = tigetstr("smir");
- EI = tigetstr("rmir");
- DC = tigetstr("dch1");
- DM = tigetstr("smdc");
- ED = tigetstr("rmdc");
- SF = tigetstr("ind");
- SR = tigetstr("ri");
- if(DC == NULL && (DM == NULL || ED == NULL))
- delchar = FALSE;
- if(IC == NULL && (IM == NULL || EI == NULL))
- inschar = FALSE;
- if((CS==NULL || SF==NULL || SR==NULL) && (DL==NULL || AL==NULL))
- scrollexist = FALSE;
-
- if(CL == NULL || CM == NULL || UP == NULL){
- if(Pmaster == NULL){
- puts("Incomplete terminfo entry\n");
- exit(1);
- }
- }
- else{
- KPPU = tigetstr("kpp");
- KPPD = tigetstr("knp");
- KPHOME = tigetstr("khome");
- KU = tigetstr("kcuu1");
- KD = tigetstr("kcud1");
- KL = tigetstr("kcub1");
- KR = tigetstr("kcuf1");
- if(KU != NULL && (KL != NULL && (KR != NULL && KD != NULL))){
- kpinsert(KU,K_PAD_UP);
- kpinsert(KD,K_PAD_DOWN);
- kpinsert(KL,K_PAD_LEFT);
- kpinsert(KR,K_PAD_RIGHT);
-
- if(KPPU != NULL)
- kpinsert(KPPU,K_PAD_PREVPAGE);
- if(KPPD != NULL)
- kpinsert(KPPD,K_PAD_NEXTPAGE);
- if(KPHOME != NULL)
- kpinsert(KPHOME,K_PAD_HOME);
- }
- }
-
- /*
- * add default keypad sequences to the trie...
- */
- if(gmode&MDFKEY){
- /*
- * Initialize UW-modified NCSA telnet to use its functionkeys
- */
- if(Pmaster == NULL){
- puts("\033[99h");
- }
-
- /*
- * this is sort of a hack [no kidding], but it allows us to use
- * the function keys on pc's running telnet
- */
-
- /*
- * UW-NDC/UCS vt10[01] application mode.
- */
- kpinsert("OP",F1);
- kpinsert("OQ",F2);
- kpinsert("OR",F3);
- kpinsert("OS",F4);
- kpinsert("Op",F5);
- kpinsert("Oq",F6);
- kpinsert("Or",F7);
- kpinsert("Os",F8);
- kpinsert("Ot",F9);
- kpinsert("Ou",F10);
- kpinsert("Ov",F11);
- kpinsert("Ow",F12);
-
- /*
- * special keypad functions
- */
- kpinsert("[4J",K_PAD_PREVPAGE);
- kpinsert("[3J",K_PAD_NEXTPAGE);
- kpinsert("[2J",K_PAD_HOME);
- kpinsert("[N",K_PAD_END);
-
- /*
- * ANSI mode.
- */
- kpinsert("[=a",F1);
- kpinsert("[=b",F2);
- kpinsert("[=c",F3);
- kpinsert("[=d",F4);
- kpinsert("[=e",F5);
- kpinsert("[=f",F6);
- kpinsert("[=g",F7);
- kpinsert("[=h",F8);
- kpinsert("[=i",F9);
- kpinsert("[=j",F10);
- kpinsert("[=k",F11);
- kpinsert("[=l",F12);
-
- HelpKeyNames = funckeynames;
-
- }
- else{
- HelpKeyNames = NULL;
- }
-
- /*
- * DEC vt100, ANSI and cursor key mode.
- */
- kpinsert("OA",K_PAD_UP);
- kpinsert("OB",K_PAD_DOWN);
- kpinsert("OD",K_PAD_LEFT);
- kpinsert("OC",K_PAD_RIGHT);
-
- /*
- * DEC vt100, ANSI and cursor key mode reset.
- */
- kpinsert("[A",K_PAD_UP);
- kpinsert("[B",K_PAD_DOWN);
- kpinsert("[D",K_PAD_LEFT);
- kpinsert("[C",K_PAD_RIGHT);
-
- /*
- * DEC vt52 mode.
- */
- kpinsert("A",K_PAD_UP);
- kpinsert("B",K_PAD_DOWN);
- kpinsert("D",K_PAD_LEFT);
- kpinsert("C",K_PAD_RIGHT);
-
- /*
- * Sun Console sequences.
- */
- kpinsert("[215z",K_PAD_UP);
- kpinsert("[221z",K_PAD_DOWN);
- kpinsert("[217z",K_PAD_LEFT);
- kpinsert("[219z",K_PAD_RIGHT);
-
- if (CE == NULL) /* will we be able to use clear to EOL? */
- eolexist = FALSE;
-
- /* This is done ... */
- initstrng = tigetstr ("is2");
- /* ... on the assumption that this meant something in tcap.c */
- if(initstrng && *initstrng != '\0')
- puts(initstrng);
-
- ttopen();
- }
-
-
-
- #define newnode() (struct KBSTREE *)malloc(sizeof(struct KBSTREE))
- /*
- * kbinsert - insert a keystroke escape sequence into the global search
- * structure.
- */
- static kpinsert(kstr, kval)
- char *kstr;
- int kval;
- {
- register char *buf;
- register struct KBSTREE *temp;
- register struct KBSTREE *trail;
-
- if(kstr == NULL)
- return;
-
- temp = trail = kpadseqs;
- if(kstr[0] == '\033')
- buf = kstr+1; /* can the ^[ character */
- else
- buf = kstr;
-
- for(;;) {
- if(temp == NULL){
- temp = newnode();
- temp->value = *buf;
- temp->func = 0;
- temp->left = NULL;
- temp->down = NULL;
- if(kpadseqs == NULL)
- kpadseqs = temp;
- else
- trail->down = temp;
- }
- else{ /* first entry */
- while((temp != NULL) && (temp->value != *buf)){
- trail = temp;
- temp = temp->left;
- }
- if(temp == NULL){ /* add new val */
- temp = newnode();
- temp->value = *buf;
- temp->func = 0;
- temp->left = NULL;
- temp->down = NULL;
- trail->left = temp;
- }
- }
-
- if (*(++buf) == '\0'){
- break;
- }
- else{
- trail = temp;
- temp = temp->down;
- }
- }
-
- if(temp != NULL)
- temp->func = kval;
- }
-
-
- /*
- * tinfoinsert - insert a character at the current character position.
- * IC takes precedence.
- */
- tinfoinsert(ch)
- register char ch;
- {
- if(IC != NULL){
- putpad(IC);
- ttputc(ch);
- }
- else{
- putpad(IM);
- ttputc(ch);
- putpad(EI);
- }
- }
-
-
- /*
- * tinfodelete - delete a character at the current character position.
- */
- tinfodelete()
- {
- if(DM == NULL && ED == NULL)
- putpad(DC);
- else{
- putpad(DM);
- putpad(DC);
- putpad(ED);
- }
- }
-
-
- /*
- * tcapscrolldn() - open a line at the given row position.
- * use either region scrolling or deleteline/insertline
- * to open a new line.
- */
- tcapscrolldn(row, n)
- register int row;
- register int n;
- {
- register int i;
-
- if(CS != NULL){
- putpad(tgoto(CS, term.t_nrow - 3, row));
- tinfomove(row, 0);
- for(i = 0; i < n; i++)
- putpad( (SR != NULL && *SR != '\0') ? SR : "\n" );
- putpad(tgoto(CS, term.t_nrow, 0));
- tinfomove(row, 0);
- }
- else{
- /*
- * this code causes a jiggly motion of the keymenu when scrolling
- */
- for(i = 0; i < n; i++){
- tinfomove(term.t_nrow - 3, 0);
- putpad(DL);
- tinfomove(row, 0);
- putpad(AL);
- }
- #ifdef NOWIGGLYLINES
- /*
- * this code causes a sweeping motion up and down the display
- */
- tinfomove(term.t_nrow - 2 - n, 0);
- for(i = 0; i < n; i++)
- putpad(DL);
- tinfomove(row, 0);
- for(i = 0; i < n; i++)
- putpad(AL);
- #endif
- }
- }
-
-
- /*
- * tcapscrollup() - open a line at the given row position.
- * use either region scrolling or deleteline/insertline
- * to open a new line.
- */
- tcapscrollup(row, n)
- register int row;
- register int n;
- {
- register int i;
-
- if(CS != NULL){
- putpad(tgoto(CS, term.t_nrow - 3, row));
- /* setting scrolling region moves cursor to home */
- tinfomove(term.t_nrow-3, 0);
- for(i = 0;i < n; i++)
- putpad((SF == NULL || SF[0] == '\0') ? "\n" : SF);
- putpad(tgoto(CS, term.t_nrow, 0));
- tinfomove(2, 0);
- }
- else{
- for(i = 0; i < n; i++){
- tinfomove(row, 0);
- putpad(DL);
- tinfomove(term.t_nrow - 3, 0);
- putpad(AL);
- }
- #ifdef NOWIGGLYLINES
- /* see note above */
- tinfomove(row, 0);
- for(i = 0; i < n; i++)
- putpad(DL);
- tinfomove(term.t_nrow - 2 - n, 0);
- for(i = 0;i < n; i++)
- putpad(AL);
- #endif
- }
- }
-
-
-
- /*
- * o_insert - use terminfo to optimized character insert
- * returns: true if it optimized output, false otherwise
- */
- o_insert(c)
- char c;
- {
- if(inschar){
- tinfoinsert(c);
- return(1); /* no problems! */
- }
-
- return(0); /* can't do it. */
- }
-
-
- /*
- * o_delete - use terminfo to optimized character insert
- * returns true if it optimized output, false otherwise
- */
- o_delete()
- {
- if(delchar){
- tinfodelete();
- return(1); /* deleted, no problem! */
- }
-
- return(0); /* no dice. */
- }
-
-
- /*
- * scrollup - use terminal characteristics to optimize screen updates that
- * scroll up the display
- */
- o_scrollup()
- {
- }
-
-
- /*
- * scrolldown - use terminal characteristics to optimize screen updates that
- * scroll down the display
- */
- o_scrolldown()
- {
- }
-
-
- static tinfomove(row, col)
- register int row, col;
- {
- putpad(tgoto(CM, col, row));
- }
-
-
- static tinfoeeol()
- {
- putpad(CE);
- }
-
-
- static tinfoeeop()
- {
- putpad(CL);
- }
-
-
- static tinforev(state) /* change reverse video status */
- int state; /* FALSE = normal video, TRUE = rev video */
- {
- if (state) {
- if (SO != NULL)
- putpad(SO);
- } else {
- if (SE != NULL)
- putpad(SE);
- }
- }
-
-
- static tinfobeep()
- {
- ttputc(BEL);
- }
-
-
- static putpad(str)
- char *str;
- {
- tputs(str, 1, ttputc);
- }
-
-
- static putnpad(str, n)
- char *str;
- {
- tputs(str, n, ttputc);
- }
-