home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
- *
- * io.c
- * cross system inkey and screen calls for
- * XENIX
- * SYSV
- * DOS
- *
- * TERMINAL SETUP AND RESET
- * tsetup() :
- * treset() :
- *
- * KEYBOARD SETUP AND RESET
- * kbsetup() :
- * kbreset() :
- *
- * CHARACTER AND KEYSTROKE
- * getch() :
- * inkey() :
- *
- * SCREEN CONTROL
- * cls() :
- * eol() :
- * rev() :
- * norm() :
- *
- *********************************************************************/
- /*LINTLIBRARY*/
- /*
- $Id: io.c,v 1.5 90/05/19 03:50:00 mark Exp Locker: mark $
- $Log: io.c,v $
- * Revision 1.5 90/05/19 03:50:00 mark
- * *** empty log message ***
- *
- * Revision 1.4 90/04/05 16:17:37 mark
- * corrected for lint
- *
- * Revision 1.3 90/02/10 12:42:24 mark
- * *** empty log message ***
- *
- * Revision 1.2 90/01/24 23:15:47 mark
- * ioctl flag INLCR added to kbsetup()
- * input key buffer tested each key read - fix Wyse50 arrow keys
- *
- * Revision 1.1 90/01/23 16:32:33 mark
- * Initial revision
- *
- */
-
- /*********************************************************************
- *
- * only one can be defined: XENIX_IO SYSV_IO DOS_IO
- *
- *********************************************************************/
- #ifdef XENIX_IO
- #undef SYSV_IO
- #undef DOS_IO
- #endif
-
- #ifdef SYSV_IO
- #undef XENIX_IO
- #undef DOS_IO
- #endif
-
- #ifdef DOS_IO
- #undef XENIX_IO
- #undef SYSV_IO
- #endif
-
- #include "io.h"
-
- #ifndef DOS_IO
- /*********************************************************************
- *
- * include files -- io.h is local
- *
- *********************************************************************/
- #include <stdio.h>
- #include <string.h>
- #include <memory.h>
- /*#include <termio.h>*/
-
- /*********************************************************************
- *
- * extra include files and variable definition
- * SYSV_IO uses alarm(), setjmp(), and lngjmp() system calls.
- *
- *********************************************************************/
- #ifdef SYSV_IO
- #include <setjmp.h>
- #include <signal.h>
- jmp_buf e_buff;
- char c_buff[5];
- #endif
-
- /*********************************************************************
- *
- * original terminal settings
- *
- *********************************************************************/
- static struct termio tsaved;
-
- /*********************************************************************
- *
- * character indexing buffers for function key mapping
- *
- *********************************************************************/
- char key1[256];
- char key2[256];
-
- /*********************************************************************
- *
- * structures containing terminal and keyboard definitions
- *
- *********************************************************************/
- struct crt_stru crt;
- struct fkey_stru spec;
-
- /*********************************************************************
- *
- * function prototypes
- *
- *********************************************************************/
- int ioctl();
- int read();
- char *getenv();
-
-
- /*********************************************************************
- *
- * tsetup
- * prepares the terminal for absolute cursor positioning
- * retrieves and saves the current terminals keyboard definition
- * sets the keyboard in character break mode
- *
- *********************************************************************/
- tsetup()
- {
- tinit();
- fillkeys();
- kbsetup();
- cps(crt.init);
- (void)fflush(stdout);
- }
-
- /*********************************************************************
- *
- * treset
- * resets the terminal to the state in which it was found
- *
- *********************************************************************/
- treset()
- {
- cps(crt.close);
- kbreset();
- tflush();
- }
-
- /*********************************************************************
- *
- * kbsetup
- * sets the keyboard in character break mode
- *
- *********************************************************************/
- int kbsetup()
- {
- struct termio tnew;
- int echo = 0; /* 0 == no echo | 1 == echo */
-
- (void)ioctl(0, TCGETA, &tsaved);
- tnew = tsaved;
-
- tnew.c_iflag &= INLCR;
-
- tnew.c_lflag &= ~ICANON;
- tnew.c_lflag &= ~ISIG;
- if(echo == 0)
- tnew.c_lflag &= ~ECHO;
- else
- tnew.c_lflag &= ECHO;
- tnew.c_cc[VMIN] = 1;
- tnew.c_cc[VTIME] = 0;
- (void)ioctl(0, TCSETA, &tnew);
- }
-
- /*********************************************************************
- *
- * kbreset
- * resets the keyboard to the state in which it was found
- *
- *********************************************************************/
- int kbreset()
- {
- (void)ioctl(0, TCSETA, &tsaved);
- }
-
- /*********************************************************************
- *
- * getch
- * character by character input function - cbreak mode
- *
- *********************************************************************/
- int getch()
- {
- char buf;
-
- (void)read(0, &buf, 1);
- if(buf == tsaved.c_cc[VEOF])
- return(EOF);
- return(buf);
- }
-
- /*********************************************************************
- *
- * flush the standard output file
- *
- *********************************************************************/
- refresh() { (void)fflush(stdout); }
- tflush() { (void)fflush(stdout); }
-
- /*********************************************************************
- *
- * position the cursor
- *
- *********************************************************************/
- cup(row,col)
- int row, col;
- {
- cps((char *)(tgoto(crt.dca,col,row)));
- }
-
- /*********************************************************************
- *
- * clear the screen
- *
- *********************************************************************/
- cls() { cps(crt.cls); cup(0,0); }
-
- /*********************************************************************
- *
- * clear to end of line
- *
- *********************************************************************/
- eol() { cps(crt.eol); }
- clreol() { cps(crt.eol); }
-
- /*********************************************************************
- *
- * set reverse video
- *
- *********************************************************************/
- rev() { cps(crt.rev); }
- revvid() { cps(crt.rev); }
-
- /*********************************************************************
- *
- * set normal video
- *
- *********************************************************************/
- norm() { cps(crt.norm); }
- normvid(){ cps(crt.norm); }
-
- /*********************************************************************
- *
- * output a string to the crt
- *
- *********************************************************************/
- cps(str)
- char *str;
- {
- char *tptr; tptr = str;
- while(*tptr) (void)putc(*(tptr++),stdout);
- tflush();
- }
-
- /*********************************************************************
- *
- * general purpose XENIX SYSV terminal setup routines
- * based on termcap database
- *
- *********************************************************************/
- /*********************************************************************
- *
- * compare checks the contents on the buffer kbuff
- * against the structure spec for special key
- * definitions. when a match is made a negative value
- * is returned, otherwise zero is returned.
- *
- *********************************************************************/
- int compare(kbuff)
- char *kbuff;
- {
- if(!strcmp(kbuff,spec.up)) { return(-101);
- } else if(!strcmp(kbuff,spec.down)) { return(-102);
- } else if(!strcmp(kbuff,spec.left)) { return(-103);
- } else if(!strcmp(kbuff,spec.right)) { return(-104);
- } else if(!strcmp(kbuff,spec.pu)) { return(-105);
- } else if(!strcmp(kbuff,spec.pd)) { return(-106);
- } else if(!strcmp(kbuff,spec.f1)) { return(-1);
- } else if(!strcmp(kbuff,spec.f2)) { return(-2);
- } else if(!strcmp(kbuff,spec.f3)) { return(-3);
- } else if(!strcmp(kbuff,spec.f4)) { return(-4);
- } else if(!strcmp(kbuff,spec.f5)) { return(-5);
- } else if(!strcmp(kbuff,spec.f6)) { return(-6);
- } else if(!strcmp(kbuff,spec.f7)) { return(-7);
- } else if(!strcmp(kbuff,spec.f8)) { return(-8);
- } else if(!strcmp(kbuff,spec.f9)) { return(-9);
- } else if(!strcmp(kbuff,spec.f10)) { return(-10);
- } return(0);
- }
-
- /*********************************************************************
- *
- * tinit
- * reads and parses the termcap entry pointed to by the
- * TERM environment variable
- *
- *********************************************************************/
- tinit()
- {
- char *cptr;
- char *tptr;
- char buff[1024];
-
- if((tptr = getenv("TERM")) == NULL) {
- (void)printf("Error initilizing terminal. Exiting ...\n");
- (void)exit(1);
- }
- tgetent(buff,tptr);
-
- /* terminal attribute initialization */
- cptr = crt.dca; tgetstr("cm",&cptr);
- cptr = crt.cls; tgetstr("cl",&cptr);
- cptr = crt.rev; tgetstr("so",&cptr);
- cptr = crt.norm; tgetstr("se",&cptr);
- cptr = crt.eol; tgetstr("ce",&cptr);
- cptr = crt.init; tgetstr("ti",&cptr);
- cptr = crt.close; tgetstr("te",&cptr);
- cptr = crt.uss; tgetstr("us",&cptr);
- cptr = crt.use; tgetstr("ue",&cptr);
-
- /* terminal special key initialization */
- cptr = spec.up; tgetstr("ku",&cptr);
- cptr = spec.down; tgetstr("kd",&cptr);
- cptr = spec.left; tgetstr("kl",&cptr);
- cptr = spec.right; tgetstr("kr",&cptr);
- cptr = spec.pu; tgetstr("pu",&cptr);
- cptr = spec.pd; tgetstr("pd",&cptr);
-
- /* function key initialization */
- cptr = spec.f1; tgetstr("k1",&cptr);
- cptr = spec.f2; tgetstr("k2",&cptr);
- cptr = spec.f3; tgetstr("k3",&cptr);
- cptr = spec.f4; tgetstr("k4",&cptr);
- cptr = spec.f5; tgetstr("k5",&cptr);
- cptr = spec.f6; tgetstr("k6",&cptr);
- cptr = spec.f7; tgetstr("k7",&cptr);
- cptr = spec.f8; tgetstr("k8",&cptr);
- cptr = spec.f9; tgetstr("k9",&cptr);
- cptr = spec.f10; tgetstr("k0",&cptr);
-
- /* miscellaneous integral values */
- crt.co = tgetnum("co");
- crt.li = tgetnum("li");
- crt.sg = tgetnum("sg");
- crt.ug = tgetnum("ug");
- crt.gg = tgetnum("gg");
- }
-
- /*********************************************************************
- *
- * fillkeys reads the zero'th postion of the members in structure spec
- * to be used in the masking of special characters
- *
- *********************************************************************/
- fillkeys()
- {
- memset(key1,0,sizeof(key1));
- memset(key2,0,sizeof(key2));
-
- key1[spec.up[0]] = 1; key2[spec.up[1]] = 1;
- key1[spec.down[0]] = 1; key2[spec.down[1]] = 1;
- key1[spec.left[0]] = 1; key2[spec.left[1]] = 1;
- key1[spec.right[0]] = 1; key2[spec.right[1]] = 1;
- key1[spec.pu[0]] = 1; key2[spec.pu[1]] = 1;
- key1[spec.pd[0]] = 1; key2[spec.pd[1]] = 1;
-
- key1[spec.f1[0]] = 1; key2[spec.f1[1]] = 1;
- key1[spec.f2[0]] = 1; key2[spec.f2[1]] = 1;
- key1[spec.f3[0]] = 1; key2[spec.f3[1]] = 1;
- key1[spec.f4[0]] = 1; key2[spec.f4[1]] = 1;
- key1[spec.f5[0]] = 1; key2[spec.f5[1]] = 1;
- key1[spec.f6[0]] = 1; key2[spec.f6[1]] = 1;
- key1[spec.f7[0]] = 1; key2[spec.f7[1]] = 1;
- key1[spec.f8[0]] = 1; key2[spec.f8[1]] = 1;
- key1[spec.f9[0]] = 1; key2[spec.f9[1]] = 1;
- key1[spec.f10[0]] = 1; key2[spec.f10[1]] = 1;
- }
-
-
- /*********************************************************************
- *
- * Inkey routines -- these tend to be non standard from system
- * to system. Each method has advantages and disadvantages.
- *
- * XENIX_IO uses rdchk() and nap()
- * SYSV_IO uses alarm(), setjmp(), and lngjmp()
- *
- *********************************************************************/
-
- #ifdef XENIX_IO
- /*********************************************************************
- *
- * XENIX_IO inkey
- * if > 0 return ascii code of character
- * if < 0 return number cooresponding to function key map
- *
- *********************************************************************/
- inkey()
- {
- char tbuf[10];
- int cnt = 0, ret;
-
- /* first char ! */
- tbuf[cnt] = (char)getch(); tbuf[++cnt] = '\0';
- if((ret = compare(tbuf)) < 0) { return(ret); }
-
- /* possible second char ? (i.e. [Escape] */
- if(!key1[tbuf[cnt-1]]) { return(tbuf[cnt-1]); }
- nap((long)PERIOD);
- if(!rdchk(0)) { return(tbuf[cnt-1]); }
-
- /* second char !!! */
- tbuf[cnt] = (char)getch(); tbuf[++cnt] = '\0';
- if((ret = compare(tbuf)) < 0) { return(ret); }
- if(!key2[tbuf[cnt-1]]) { return(0); }
-
- /* third char ! */
- if(rdchk(0)) { tbuf[cnt] = (char)getch(); tbuf[++cnt] = '\0'; }
- return(compare(tbuf));
- }
-
- #endif
-
- #ifdef SYSV_IO
- /*********************************************************************
- *
- * timeout
- * Called by signal when an alarm is set. Used to exit
- * the last call to getchar when no characters arrive within
- * one second.
- *
- *********************************************************************/
- int timeout()
- {
- longjmp(e_buff,1);
- }
-
- /*********************************************************************
- *
- * SYSV_IO inkey
- * if > 0 return ascii code of character
- * if < 0 return number cooresponding to function key map
- *
- *********************************************************************/
- int inkey()
- {
- int go = 1, keycnt = 0, maxkey = 3;
-
- memset(c_buff,(int)'\0',5);
- setjmp(e_buff);
-
- if(go) {
- go = 0;
- signal(SIGALRM,timeout);
- c_buff[keycnt] = getchar();
- if(!key1[c_buff[keycnt++]]) {
- keycnt = maxkey;
- }
-
- while(keycnt < maxkey) {
- if(compare(c_buff) < 0) {
- longjmp(e_buff,1);
- }
- alarm((unsigned) PERIOD);
- c_buff[keycnt++] = getchar();
- c_buff[keycnt] = '\0';
- alarm((unsigned) 0);
- }
- }
-
- if(strlen(c_buff) == 1) { return(c_buff[0]); }
- return(compare(c_buff));
- }
- #endif
- #endif
-
- #ifdef DOS_IO
- #include <dos.h>
-
- tsetup() { ; }
- treset() { ; }
- kbsetup() { ; }
- kbreset() { ; }
- tflush() { ; }
-
- inkey() {
- int ch;
- ch = getch();
- if(ch != 0) {
- return(ch);
- } else {
- ch = getch();
- switch(ch) {
- case 59 : ch = -1; break; /* F1 */
- case 60 : ch = -2; break; /* F2 */
- case 61 : ch = -3; break; /* F3 */
- case 62 : ch = -4; break; /* F4 */
- case 63 : ch = -5; break; /* F5 */
- case 64 : ch = -6; break; /* F6 */
- case 65 : ch = -7; break; /* F7 */
- case 66 : ch = -8; break; /* F8 */
- case 67 : ch = -9; break; /* F9 */
- case 68 : ch = -10; break; /* F10 */
- case 72 : ch = -101; break; /* UP */
- case 80 : ch = -102; break; /* DOWN */
- case 75 : ch = -103; break; /* LEFT */
- case 77 : ch = -104; break; /* RIGHT */
- case 73 : ch = -105; break; /* PGUP */
- case 81 : ch = -106; break; /* PGDOWN */
- default : ch = 0;
- }
- return(ch);
- }
- }
-
- /* sets reverse video */
- void rev()
- {
- (void)printf("\x1b[7m");
- }
-
- void revvid()
- {
- (void)printf("\x1b[7m");
- }
-
-
- /* sets low video */
- void norm()
- {
- (void)printf("\x1b[0m");
- }
-
- void normvid()
- {
- (void)printf("\x1b[0m");
- }
-
- /* clear to the end of current line */
- void eol()
- {
- (void)printf("\x1b[0K");
- }
-
- void clreol()
- {
- (void)printf("\x1b[0K");
- }
-
-
- /* clear terminal screen */
- void cls()
- {
- (void)printf("\x1b[2J");
- }
-
-
- /* position cursor on terminal */
- void cup(row,col)
- int row, col;
- {
- (void)printf("\x1b[%d;%dH",row,col);
- }
-
- void un_on()
- {
- (void)printf("\x1b[4m");
- }
-
- void un_off()
- {
- (void)printf("\x1b[0m");
- }
- #endif
-