Mercurial > hg > forks > pwpunix
diff pwplib/tty.c @ 0:acb5694e93d9
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 18 May 2010 04:25:44 +0300 |
parents | |
children | c60e531d19cd |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pwplib/tty.c Tue May 18 04:25:44 2010 +0300 @@ -0,0 +1,287 @@ +#include "config.h" +#ifdef DRIVE_TTY + +#include "pwplib.h" + +#define __TTY_C + +#include "tty.h" + +/****************/ + +#ifdef HAVE_TTYSTUFF + +void tty_restore_termios() +{ + tcsetattr(STDIN,TCSADRAIN,&pwp_tty.setup); +} + +void tty_init_termios() +{ + struct termios t; + tcgetattr(STDIN,&t); + memcpy(&pwp_tty.setup,&t,sizeof(struct termios)); + + t.c_lflag=ISIG; /* &=~(ECHO+ECHOE+ECHOK+ECHONL+NOFLSH);*/ + +/* t.c_lflag=t.c_oflag=0; */ + t.c_cc[VMIN]=1; + t.c_cc[VTIME]=0; + tcsetattr(STDIN,TCSADRAIN,&t); + + pwp_regdestr(tty_restore_termios); +} + +void tty_getwinsize() +{ +# ifdef TIOCGWINSZ + {struct winsize wsz; + if(ioctl(0,TIOCGWINSZ,&wsz)>=0){ + pwp_tty.width=wsz.ws_col;pwp_tty.height=wsz.ws_row; + if(pwp_tty.width>0 && pwp_tty.height>0) return; + }} +# endif + + {char*tmp; + pwp_tty.height=((tmp=getenv("LINES"))?atoi(tmp):0); + pwp_tty.width=((tmp=getenv("COLUMNS"))?atoi(tmp):0); + if(pwp_tty.height>0 && pwp_tty.width>0)return;} + + pwp_tty.height=24; + pwp_tty.width=80; +} + +void tty_write(u8*data,int lgt) +{ + if(lgt<0)lgt=strlen(data); + + write(pwp_tty.fd,data,lgt); + pwplib.timer_counter+=lgt; +} + +/******************************************************************/ + +void tty_probe_raw() +{ + fd_set fdset; + struct timeval timeout; + + tty_init_termios(); + + memset((void*)&fdset,0,sizeof(fd_set)); + FD_SET(0,&fdset); + timeout.tv_sec=0; + timeout.tv_usec=250000; + + write(STDOUT,"\33[c",3*sizeof(char)); + + usleep(250000); /* give it some time to react */ + + select(0,&fdset,NULL,NULL,&timeout); + + if(FD_ISSET(STDIN,&fdset)) + { + char buf[40],*b; + int lgt,num; + + lgt=read(STDIN,buf,40*sizeof(char))/sizeof(char); + + if(lgt<3) return; + if( (buf[0]!=27) || + (buf[1]!='[') || + (buf[2]!='?')) return; + + b=buf+3;lgt-=3;num=0; + + pwp_tty.type=TTY_VT1XX; + pwp_tty.minor=0; + pwp_tty.vtcap=0; + + while(lgt) + { + char c=*b++; + if(c>='0' && c<='9') + num=(num*10)+c-'0'; + else + { + /*fprintf(stderr,"NUMBAH %d\n",num);*/ + if(num>=62) + { + pwp_tty.type =TTY_VT2XX; + pwp_tty.minor=20+(num-60)*100; + } + else + if(num<32)pwp_tty.vtcap|=(1<<num); + + num=0; + } + lgt--; + } + + if(pwp_tty.vtcap&(1<<3)) /* ReGIS */ + { + if(pwp_tty.minor==220) + pwp_tty.minor=240; + if(pwp_tty.minor==320) + { + pwp_tty.minor=330; + /* how to check 340? */ + } + /* ... otherz */ + } + + /* protection from vt2xx wannabes - enable after lag fix */ +#ifdef DRIVE_TTY_VT2XX +/* if( (pwp_tty.type==TTY_VT2XX) && + (!(pwp_tty.vtcap&(1<<7)))) + { + pwp_tty.type=TTY_VT1XX; + }*/ +#else + if(pwp_tty.type=TTY_VT2XX)pwp_tty.type=TTY_VT1XX; +#endif + + } + else + pwp_tty.type=TTY_DUMB; + + tty_restore_termios(); +} + +/******************************************************************/ + +int tty_probe() +{ + char*tt; + + pwp_tty.type=TTY_DUMB; + + pwpwrite("* getting terminal type..\n"); + + tt=pwplib.set.term; + if(tt==NULL) + { + tty_probe_raw(); + tt=getenv("TERM"); + if(tt==NULL)return pwp_tty.type; + } + + if(tt[0]=='x')pwp_tty.type=TTY_XVT_MONO; + + if( (!strcmp(tt,"xterm-color")) || + (!strcmp(tt,"aixterm")) + ) + { + return TTY_XVT_COLOR; + } + + if( (pwp_tty.type==TTY_VT1XX) || + (pwp_tty.type==TTY_DUMB)) + { + if(tt[0]=='v') + { + pwp_tty.minor=atoi(tt+2); + + if(pwp_tty.minor>=200 && pwp_tty.type!=TTY_VT1XX) + return TTY_VT2XX; + else return TTY_VT1XX; + } + + if(tt[0]=='a') + return TTY_ANSISYS; + + if(tt[0]=='l') + return TTY_LINUX; + + if(!strcmp(tt,"dumb")) + return TTY_DUMB; + } + + return pwp_tty.type; +} + +#endif + +/******************************************************************/ + +int tty_init() +{ +#ifdef HAVE_TTYSTUFF + + int colors=2,chars=2,rasters=1; + + pwp_tty.fd=2; /* stderr */ + + tty_init_termios(); + + tty_getwinsize(); + pwp_tty.type=tty_probe(); +#endif + pwplib.videobuf.width=pwp_tty.width; + pwplib.videobuf.height=pwp_tty.height; + pwplib.videobuf.d=malloc(pwplib.videobuf.width* + pwplib.videobuf.height*sizeof(u16)); +#ifdef HAVE_TTYSTUFF + pwp_tty.prevbuf=malloc(pwplib.videobuf.width* + pwplib.videobuf.height*sizeof(u16)); + + pwpwrite("* terminal on stdout: "); + + switch((int)pwp_tty.type) + { + case(TTY_DUMB): + pwpwrite("dumb or unsupported\n"); + tty_dumb_init(); + break; + + case(TTY_VT2XX): +#ifdef DRIVE_TTY_VT2XX + { + char buf[40]; + sprintf(buf,"vt220/compatible (vt%d)\n",pwp_tty.minor); + pwpwrite(buf); + } + tty_vt2xx_init(); + break; +#endif + case(TTY_VT1XX): + pwpwrite("vt100/compatible"); + if(pwp_tty.minor>=200) + { char buf[40]; + sprintf(buf," (a vt%d wannabe)\n",pwp_tty.minor); + pwpwrite(buf); + } + else pwpwrite("\n"); + tty_vt1xx_init(); + break; + + +# ifdef DRIVE_LINUXCON + case(TTY_LINUX): + pwpwrite("linux console\n"); + tty_linux_init(); + break; +# endif + + case(TTY_XVT_COLOR): + pwpwrite("xterm/compatible with color\n"); + tty_ansicol_init(); + break; + + case(TTY_XVT_MONO): + pwpwrite("xterm (monochrome)\n"); + tty_vt1xx_init(); + break; + + case(TTY_ANSISYS): + pwpwrite("msdos ansi or compatible\n"); + tty_ansisys_init(); + break; + } +#endif + return 1; +} + +#endif + +