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
];
49 static keycode_st getch2_keys
[MAX_KEYS
];
50 static int getch2_key_db
=0;
57 extern int tgetent (char *BUFFER
, char *TERMTYPE
);
58 extern int tgetnum (char *NAME
);
59 extern int tgetflag (char *NAME
);
60 extern char *tgetstr (char *NAME
, char **AREA
);
63 static char term_buffer
[4096];
64 static char term_buffer2
[4096];
65 static char *term_p
=term_buffer2
;
67 static void termcap_add(char *id
,int code
){
68 char *p
=tgetstr(id
,&term_p
);
70 if(getch2_key_db
>=MAX_KEYS
) return;
71 getch2_keys
[getch2_key_db
].len
=strlen(p
);
72 strncpy(getch2_keys
[getch2_key_db
].chars
,p
,8);
73 getch2_keys
[getch2_key_db
].code
=code
;
75 /* printf("%s=%s\n",id,p); */
80 int load_termcap(char *termtype
){
81 if(!termtype
) termtype
=getenv("TERM");
82 if(!termtype
) termtype
="unknown";
83 success
=tgetent(term_buffer
, termtype
);
84 if(success
<0){ printf("Could not access the 'termcap' data base.\n"); return 0; }
85 if(success
==0){ printf("Terminal type `%s' is not defined.\n", termtype
);return 0;}
87 screen_width
=tgetnum("co");
88 screen_height
=tgetnum("li");
89 if(screen_width
<1 || screen_width
>255) screen_width
=80;
90 if(screen_height
<1 || screen_height
>255) screen_height
=24;
92 termcap_add("kP",KEY_PGUP
);
93 termcap_add("kN",KEY_PGDWN
);
94 termcap_add("kh",KEY_HOME
);
95 termcap_add("kH",KEY_END
);
96 termcap_add("kI",KEY_INS
);
97 termcap_add("kD",KEY_DEL
);
98 termcap_add("kb",KEY_BS
);
99 termcap_add("kl",KEY_LEFT
);
100 termcap_add("kd",KEY_DOWN
);
101 termcap_add("ku",KEY_UP
);
102 termcap_add("kr",KEY_RIGHT
);
103 termcap_add("k0",KEY_F
+0);
104 termcap_add("k1",KEY_F
+1);
105 termcap_add("k2",KEY_F
+2);
106 termcap_add("k3",KEY_F
+3);
107 termcap_add("k4",KEY_F
+4);
108 termcap_add("k5",KEY_F
+5);
109 termcap_add("k6",KEY_F
+6);
110 termcap_add("k7",KEY_F
+7);
111 termcap_add("k8",KEY_F
+8);
112 termcap_add("k9",KEY_F
+9);
113 termcap_add("k;",KEY_F
+10);
114 return getch2_key_db
;
119 void get_screen_size(){
122 if (ioctl(0, TIOCGWINSZ
, &ws
) < 0 || !ws
.ws_row
|| !ws
.ws_col
) return;
123 /* printf("Using IOCTL\n"); */
124 screen_width
=ws
.ws_col
;
125 screen_height
=ws
.ws_row
;
129 int getch2(int time
){
134 while(!getch2_len
|| (getch2_len
==1 && getch2_buf
[0]==27)){
138 /* Watch stdin (fd 0) to see when it has input. */
139 FD_ZERO(&rfds
); FD_SET(0,&rfds
);
140 /* Wait up to 'time' microseconds. */
141 tv
.tv_sec
=time
/1000; tv
.tv_usec
= (time
%1000)*1000;
142 retval
=select(1, &rfds
, NULL
, NULL
, &tv
);
143 if(retval
<=0) return -1;
144 /* Data is available now. */
145 retval
=read(0,&getch2_buf
[getch2_len
],BUF_LEN
-getch2_len
);
146 if(retval
<1) return -1;
150 /* First find in the TERMCAP database: */
151 for(i
=0;i
<getch2_key_db
;i
++){
152 if((len
=getch2_keys
[i
].len
)<=getch2_len
)
153 if(memcmp(getch2_keys
[i
].chars
,getch2_buf
,len
)==0){
154 code
=getch2_keys
[i
].code
; goto found
;
157 len
=1;code
=getch2_buf
[0];
158 /* Check the well-known codes... */
160 if(code
=='A'-64){ code
=KEY_HOME
; goto found
;}
161 if(code
=='E'-64){ code
=KEY_END
; goto found
;}
162 if(code
=='D'-64){ code
=KEY_DEL
; goto found
;}
163 if(code
=='H'-64){ code
=KEY_BS
; goto found
;}
164 if(code
=='U'-64){ code
=KEY_PGUP
; goto found
;}
165 if(code
=='V'-64){ code
=KEY_PGDWN
; goto found
;}
166 if(code
==8 || code
==127){ code
=KEY_BS
; goto found
;}
167 if(code
==10 || code
==13){
170 if(c
==10 || c
==13) if(c
!=code
) len
=2;
175 } else if(getch2_len
>1){
177 if(c
==27){ code
=KEY_ESC
; len
=2; goto found
;}
178 if(c
>='0' && c
<='9'){ code
=c
-'0'+KEY_F
; len
=2; goto found
;}
179 if(getch2_len
>=4 && c
=='[' && getch2_buf
[2]=='['){
181 if(c
>='A' && c
<'A'+12){ code
=KEY_F
+1+c
-'A';len
=4;goto found
;}
183 if(c
=='[' || c
=='O') if(getch2_len
>=3){
185 static short int ctable
[]={ KEY_UP
,KEY_DOWN
,KEY_RIGHT
,KEY_LEFT
,0,
186 KEY_END
,KEY_PGDWN
,KEY_HOME
,KEY_PGUP
,0,0,KEY_INS
,0,0,0,
187 KEY_F
+1,KEY_F
+2,KEY_F
+3,KEY_F
+4};
189 if(ctable
[c
-'A']){ code
=ctable
[c
-'A']; len
=3; goto found
;}
191 if(getch2_len
>=4 && c
=='[' && getch2_buf
[3]=='~'){
193 int ctable
[8]={KEY_HOME
,KEY_INS
,KEY_DEL
,KEY_END
,KEY_PGUP
,KEY_PGDWN
,KEY_HOME
,KEY_END
};
194 if(c
>='1' && c
<='8'){ code
=ctable
[c
-'1']; len
=4; goto found
;}
196 if(getch2_len
>=5 && c
=='[' && getch2_buf
[4]=='~'){
197 int i
=getch2_buf
[2]-'0';
198 int j
=getch2_buf
[3]-'0';
199 if(i
>=0 && i
<=9 && j
>=0 && j
<=9){
200 static short int ftable
[20]={
201 11,12,13,14,15, 17,18,19,20,21,
202 23,24,25,26,28, 29,31,32,33,34 };
204 for(i
=0;i
<20;i
++) if(ftable
[i
]==a
){ code
=KEY_F
+1+i
;len
=5;goto found
;}
209 if((getch2_len
-=len
)>0){
211 for(i
=0;i
<getch2_len
;i
++) getch2_buf
[i
]=getch2_buf
[len
+i
];
216 static int getch2_status
=0;
218 void getch2_enable(){
220 struct termios tio_new
;
221 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__)
222 tcgetattr(0,&tio_orig
);
223 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__)
224 ioctl(0,TIOCGETA
,&tio_orig
);
226 ioctl(0,TCGETS
,&tio_orig
);
229 tio_new
.c_lflag
&= ~(ICANON
|ECHO
); /* Clear ICANON and ECHO. */
230 tio_new
.c_cc
[VMIN
] = 1;
231 tio_new
.c_cc
[VTIME
] = 0;
232 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__)
233 tcsetattr(0,TCSANOW
,&tio_new
);
234 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__)
235 ioctl(0,TIOCSETA
,&tio_new
);
237 ioctl(0,TCSETS
,&tio_new
);
243 void getch2_disable(){
244 if(!getch2_status
) return; // already disabled / never enabled
246 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__)
247 tcsetattr(0,TCSANOW
,&tio_orig
);
248 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__)
249 ioctl(0,TIOCSETA
,&tio_orig
);
251 ioctl(0,TCSETS
,&tio_orig
);