1 /* GyS-TermIO v2.0 (for GySmail v3) (C) 1999 A'rpi/ESP-team */
6 #if !defined(__OS2__) && !defined(__MORPHOS__)
17 #include <sys/types.h>
19 #include <sys/ioctl.h>
26 #ifdef HAVE_SYS_TERMIOS_H
27 #include <sys/termios.h>
36 static struct termios tio_orig
;
38 static int getch2_len
=0;
39 static char getch2_buf
[BUF_LEN
];
43 char * erase_to_end_of_line
= NULL
;
50 static keycode_st getch2_keys
[MAX_KEYS
];
51 static int getch2_key_db
=0;
58 extern int tgetent (char *BUFFER
, char *TERMTYPE
);
59 extern int tgetnum (char *NAME
);
60 extern int tgetflag (char *NAME
);
61 extern char *tgetstr (char *NAME
, char **AREA
);
64 static char term_buffer
[4096];
65 static char term_buffer2
[4096];
66 static char *term_p
=term_buffer2
;
68 static void termcap_add(char *id
,int code
){
69 char *p
=tgetstr(id
,&term_p
);
71 if(getch2_key_db
>=MAX_KEYS
) return;
72 getch2_keys
[getch2_key_db
].len
=strlen(p
);
73 strncpy(getch2_keys
[getch2_key_db
].chars
,p
,8);
74 getch2_keys
[getch2_key_db
].code
=code
;
76 /* printf("%s=%s\n",id,p); */
81 int load_termcap(char *termtype
){
82 if(!termtype
) termtype
=getenv("TERM");
83 if(!termtype
) termtype
="unknown";
84 success
=tgetent(term_buffer
, termtype
);
85 if(success
<0){ printf("Could not access the 'termcap' data base.\n"); return 0; }
86 if(success
==0){ printf("Terminal type `%s' is not defined.\n", termtype
);return 0;}
88 screen_width
=tgetnum("co");
89 screen_height
=tgetnum("li");
90 if(screen_width
<1 || screen_width
>255) screen_width
=80;
91 if(screen_height
<1 || screen_height
>255) screen_height
=24;
92 erase_to_end_of_line
= tgetstr("cd",&term_p
);
94 termcap_add("kP",KEY_PGUP
);
95 termcap_add("kN",KEY_PGDWN
);
96 termcap_add("kh",KEY_HOME
);
97 termcap_add("kH",KEY_END
);
98 termcap_add("kI",KEY_INS
);
99 termcap_add("kD",KEY_DEL
);
100 termcap_add("kb",KEY_BS
);
101 termcap_add("kl",KEY_LEFT
);
102 termcap_add("kd",KEY_DOWN
);
103 termcap_add("ku",KEY_UP
);
104 termcap_add("kr",KEY_RIGHT
);
105 termcap_add("k0",KEY_F
+0);
106 termcap_add("k1",KEY_F
+1);
107 termcap_add("k2",KEY_F
+2);
108 termcap_add("k3",KEY_F
+3);
109 termcap_add("k4",KEY_F
+4);
110 termcap_add("k5",KEY_F
+5);
111 termcap_add("k6",KEY_F
+6);
112 termcap_add("k7",KEY_F
+7);
113 termcap_add("k8",KEY_F
+8);
114 termcap_add("k9",KEY_F
+9);
115 termcap_add("k;",KEY_F
+10);
116 return getch2_key_db
;
121 void get_screen_size(void){
124 if (ioctl(0, TIOCGWINSZ
, &ws
) < 0 || !ws
.ws_row
|| !ws
.ws_col
) return;
125 /* printf("Using IOCTL\n"); */
126 screen_width
=ws
.ws_col
;
127 screen_height
=ws
.ws_row
;
131 int getch2(int time
){
136 while(!getch2_len
|| (getch2_len
==1 && getch2_buf
[0]==27)){
140 /* Watch stdin (fd 0) to see when it has input. */
141 FD_ZERO(&rfds
); FD_SET(0,&rfds
);
142 /* Wait up to 'time' microseconds. */
143 tv
.tv_sec
=time
/1000; tv
.tv_usec
= (time
%1000)*1000;
144 retval
=select(1, &rfds
, NULL
, NULL
, &tv
);
145 if(retval
<=0) return -1;
146 /* Data is available now. */
147 retval
=read(0,&getch2_buf
[getch2_len
],BUF_LEN
-getch2_len
);
148 if(retval
<1) return -1;
152 /* First find in the TERMCAP database: */
153 for(i
=0;i
<getch2_key_db
;i
++){
154 if((len
=getch2_keys
[i
].len
)<=getch2_len
)
155 if(memcmp(getch2_keys
[i
].chars
,getch2_buf
,len
)==0){
156 code
=getch2_keys
[i
].code
; goto found
;
159 len
=1;code
=getch2_buf
[0];
160 /* Check the well-known codes... */
162 if(code
=='A'-64){ code
=KEY_HOME
; goto found
;}
163 if(code
=='E'-64){ code
=KEY_END
; goto found
;}
164 if(code
=='D'-64){ code
=KEY_DEL
; goto found
;}
165 if(code
=='H'-64){ code
=KEY_BS
; goto found
;}
166 if(code
=='U'-64){ code
=KEY_PGUP
; goto found
;}
167 if(code
=='V'-64){ code
=KEY_PGDWN
; goto found
;}
168 if(code
==8 || code
==127){ code
=KEY_BS
; goto found
;}
169 if(code
==10 || code
==13){
172 if(c
==10 || c
==13) if(c
!=code
) len
=2;
177 } else if(getch2_len
>1){
179 if(c
==27){ code
=KEY_ESC
; len
=2; goto found
;}
180 if(c
>='0' && c
<='9'){ code
=c
-'0'+KEY_F
; len
=2; goto found
;}
181 if(getch2_len
>=4 && c
=='[' && getch2_buf
[2]=='['){
183 if(c
>='A' && c
<'A'+12){ code
=KEY_F
+1+c
-'A';len
=4;goto found
;}
185 if(c
=='[' || c
=='O') if(getch2_len
>=3){
187 static short int ctable
[]={ KEY_UP
,KEY_DOWN
,KEY_RIGHT
,KEY_LEFT
,0,
188 KEY_END
,KEY_PGDWN
,KEY_HOME
,KEY_PGUP
,0,0,KEY_INS
,0,0,0,
189 KEY_F
+1,KEY_F
+2,KEY_F
+3,KEY_F
+4};
191 if(ctable
[c
-'A']){ code
=ctable
[c
-'A']; len
=3; goto found
;}
193 if(getch2_len
>=4 && c
=='[' && getch2_buf
[3]=='~'){
195 int ctable
[8]={KEY_HOME
,KEY_INS
,KEY_DEL
,KEY_END
,KEY_PGUP
,KEY_PGDWN
,KEY_HOME
,KEY_END
};
196 if(c
>='1' && c
<='8'){ code
=ctable
[c
-'1']; len
=4; goto found
;}
198 if(getch2_len
>=5 && c
=='[' && getch2_buf
[4]=='~'){
199 int i
=getch2_buf
[2]-'0';
200 int j
=getch2_buf
[3]-'0';
201 if(i
>=0 && i
<=9 && j
>=0 && j
<=9){
202 static short int ftable
[20]={
203 11,12,13,14,15, 17,18,19,20,21,
204 23,24,25,26,28, 29,31,32,33,34 };
206 for(i
=0;i
<20;i
++) if(ftable
[i
]==a
){ code
=KEY_F
+1+i
;len
=5;goto found
;}
211 if((getch2_len
-=len
)>0){
213 for(i
=0;i
<getch2_len
;i
++) getch2_buf
[i
]=getch2_buf
[len
+i
];
218 static int getch2_status
=0;
220 void getch2_enable(void){
222 struct termios tio_new
;
223 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__) || defined(_AIX)
224 tcgetattr(0,&tio_orig
);
225 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__)
226 ioctl(0,TIOCGETA
,&tio_orig
);
228 ioctl(0,TCGETS
,&tio_orig
);
231 tio_new
.c_lflag
&= ~(ICANON
|ECHO
); /* Clear ICANON and ECHO. */
232 tio_new
.c_cc
[VMIN
] = 1;
233 tio_new
.c_cc
[VTIME
] = 0;
234 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__) || defined(_AIX)
235 tcsetattr(0,TCSANOW
,&tio_new
);
236 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__)
237 ioctl(0,TIOCSETA
,&tio_new
);
239 ioctl(0,TCSETS
,&tio_new
);
245 void getch2_disable(void){
246 if(!getch2_status
) return; // already disabled / never enabled
248 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__) || defined(_AIX)
249 tcsetattr(0,TCSANOW
,&tio_orig
);
250 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__)
251 ioctl(0,TIOCSETA
,&tio_orig
);
253 ioctl(0,TCSETS
,&tio_orig
);