Mercurial > mplayer.hg
annotate osdep/getch2.c @ 13394:455a5056801f
New generic 'portable anymap' video output driver. It supports portable
pixmaps and graymaps in both raw and ASCII mode. Besides PPM and PGM, it
can also output PGMYUV files which are PGM files with the U and V plane
appended to the bottom of the Y image (bottom left and bottom right). All
files can be written to the current directory, to a specified output directory
or to multiple subdirectories if the filesystem can't handle the amount of
files in one directory anymore.
Note: This driver is not yet activated and will not be compiled and linked
to libvo. A separate patch will take care of that. This is just for adding
the file to the repository.
author | ivo |
---|---|
date | Mon, 20 Sep 2004 00:54:57 +0000 |
parents | cacdfa298d37 |
children | 3758536dcef3 |
rev | line source |
---|---|
1 | 1 /* GyS-TermIO v2.0 (for GySmail v3) (C) 1999 A'rpi/ESP-team */ |
2 | |
3 #include "../config.h" | |
4 | |
5 //#define USE_TERMCAP | |
12122 | 6 #if !defined(__OS2__) && !defined(__MORPHOS__) |
1 | 7 #define USE_IOCTL |
5300 | 8 #endif |
1 | 9 |
10 #define MAX_KEYS 64 | |
11 #define BUF_LEN 256 | |
12 | |
13 #include <stdio.h> | |
14 #include <stdlib.h> | |
15 #include <string.h> | |
16 #include <sys/time.h> | |
17 #include <sys/types.h> | |
18 #ifdef USE_IOCTL | |
19 #include <sys/ioctl.h> | |
20 #endif | |
3281
310c0b9bea21
detect termios.h if no sys/termios.h (qnx getch2 support working)
alex
parents:
3014
diff
changeset
|
21 |
3009 | 22 #ifdef HAVE_TERMIOS |
3281
310c0b9bea21
detect termios.h if no sys/termios.h (qnx getch2 support working)
alex
parents:
3014
diff
changeset
|
23 #ifdef HAVE_TERMIOS_H |
310c0b9bea21
detect termios.h if no sys/termios.h (qnx getch2 support working)
alex
parents:
3014
diff
changeset
|
24 #include <termios.h> |
310c0b9bea21
detect termios.h if no sys/termios.h (qnx getch2 support working)
alex
parents:
3014
diff
changeset
|
25 #endif |
3282 | 26 #ifdef HAVE_SYS_TERMIOS_H |
1 | 27 #include <sys/termios.h> |
3009 | 28 #endif |
3281
310c0b9bea21
detect termios.h if no sys/termios.h (qnx getch2 support working)
alex
parents:
3014
diff
changeset
|
29 #endif |
310c0b9bea21
detect termios.h if no sys/termios.h (qnx getch2 support working)
alex
parents:
3014
diff
changeset
|
30 |
1 | 31 #include <unistd.h> |
32 | |
33 #include "keycodes.h" | |
34 | |
3009 | 35 #ifdef HAVE_TERMIOS |
1 | 36 static struct termios tio_orig; |
3009 | 37 #endif |
1 | 38 static int getch2_len=0; |
39 static char getch2_buf[BUF_LEN]; | |
40 | |
41 int screen_width=80; | |
42 int screen_height=24; | |
43 | |
44 typedef struct { | |
45 int len; | |
46 int code; | |
47 char chars[8]; | |
48 } keycode_st; | |
49 static keycode_st getch2_keys[MAX_KEYS]; | |
50 static int getch2_key_db=0; | |
51 | |
52 #ifdef USE_TERMCAP | |
53 | |
54 #if 0 | |
55 #include <termcap.h> | |
56 #else | |
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); | |
61 #endif | |
62 | |
63 static char term_buffer[4096]; | |
64 static char term_buffer2[4096]; | |
65 static char *term_p=term_buffer2; | |
66 | |
67 static void termcap_add(char *id,int code){ | |
68 char *p=tgetstr(id,&term_p); | |
69 if(!p) return; | |
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; | |
74 ++getch2_key_db; | |
75 /* printf("%s=%s\n",id,p); */ | |
76 } | |
77 | |
78 static int success=0; | |
79 | |
80 int load_termcap(char *termtype){ | |
81 if(!termtype) termtype=getenv("TERM"); | |
8889
18427eee9205
The attached little patch fixes a core dump on termcap systems when
arpi
parents:
8016
diff
changeset
|
82 if(!termtype) termtype="unknown"; |
1 | 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;} | |
86 | |
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; | |
91 | |
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; | |
115 } | |
116 | |
117 #endif | |
118 | |
119 void get_screen_size(){ | |
120 #ifdef USE_IOCTL | |
121 struct winsize ws; | |
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; | |
126 #endif | |
127 } | |
128 | |
129 int getch2(int time){ | |
130 int len=0; | |
131 int code=0; | |
132 int i=0; | |
133 | |
134 while(!getch2_len || (getch2_len==1 && getch2_buf[0]==27)){ | |
135 fd_set rfds; | |
136 struct timeval tv; | |
137 int retval; | |
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); | |
3014
16576e05b93a
Profiling fix by Artur Skawina <skawina@geocities.com>
atmos4
parents:
3009
diff
changeset
|
143 if(retval<=0) return -1; |
1 | 144 /* Data is available now. */ |
145 retval=read(0,&getch2_buf[getch2_len],BUF_LEN-getch2_len); | |
146 if(retval<1) return -1; | |
147 getch2_len+=retval; | |
148 } | |
149 | |
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; | |
155 } | |
156 } | |
157 len=1;code=getch2_buf[0]; | |
158 /* Check the well-known codes... */ | |
159 if(code!=27){ | |
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){ | |
168 if(getch2_len>1){ | |
169 int c=getch2_buf[1]; | |
170 if(c==10 || c==13) if(c!=code) len=2; | |
171 } | |
172 code=KEY_ENTER; | |
173 goto found; | |
174 } | |
175 } else if(getch2_len>1){ | |
176 int c=getch2_buf[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]=='['){ | |
180 int c=getch2_buf[3]; | |
181 if(c>='A' && c<'A'+12){ code=KEY_F+1+c-'A';len=4;goto found;} | |
182 } | |
183 if(c=='[' || c=='O') if(getch2_len>=3){ | |
184 int c=getch2_buf[2]; | |
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}; | |
188 if(c>='A' && c<='S') | |
189 if(ctable[c-'A']){ code=ctable[c-'A']; len=3; goto found;} | |
190 } | |
191 if(getch2_len>=4 && c=='[' && getch2_buf[3]=='~'){ | |
192 int c=getch2_buf[2]; | |
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;} | |
195 } | |
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 }; | |
203 int a=i*10+j; | |
204 for(i=0;i<20;i++) if(ftable[i]==a){ code=KEY_F+1+i;len=5;goto found;} | |
205 } | |
206 } | |
207 } | |
208 found: | |
209 if((getch2_len-=len)>0){ | |
210 int i; | |
211 for(i=0;i<getch2_len;i++) getch2_buf[i]=getch2_buf[len+i]; | |
212 } | |
213 return code; | |
214 } | |
215 | |
1632 | 216 static int getch2_status=0; |
217 | |
1 | 218 void getch2_enable(){ |
3009 | 219 #ifdef HAVE_TERMIOS |
1 | 220 struct termios tio_new; |
12063
e11fc0ef72db
The attached patch fixes a minor build problem on GNU/k*BSD: getch2.c should
diego
parents:
9380
diff
changeset
|
221 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
222 tcgetattr(0,&tio_orig); |
5948 | 223 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
224 ioctl(0,TIOCGETA,&tio_orig); |
958
162a78d3cc08
FreeBSD support by Vladimir Kushnir vkushnir@Alfacom.net
arpi_esp
parents:
1
diff
changeset
|
225 #else |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
226 ioctl(0,TCGETS,&tio_orig); |
958
162a78d3cc08
FreeBSD support by Vladimir Kushnir vkushnir@Alfacom.net
arpi_esp
parents:
1
diff
changeset
|
227 #endif |
1 | 228 tio_new=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; | |
12063
e11fc0ef72db
The attached patch fixes a minor build problem on GNU/k*BSD: getch2.c should
diego
parents:
9380
diff
changeset
|
232 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
233 tcsetattr(0,TCSANOW,&tio_new); |
5948 | 234 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
235 ioctl(0,TIOCSETA,&tio_new); |
958
162a78d3cc08
FreeBSD support by Vladimir Kushnir vkushnir@Alfacom.net
arpi_esp
parents:
1
diff
changeset
|
236 #else |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
237 ioctl(0,TCSETS,&tio_new); |
958
162a78d3cc08
FreeBSD support by Vladimir Kushnir vkushnir@Alfacom.net
arpi_esp
parents:
1
diff
changeset
|
238 #endif |
3009 | 239 #endif |
1632 | 240 getch2_status=1; |
1 | 241 } |
242 | |
243 void getch2_disable(){ | |
1632 | 244 if(!getch2_status) return; // already disabled / never enabled |
3009 | 245 #ifdef HAVE_TERMIOS |
12063
e11fc0ef72db
The attached patch fixes a minor build problem on GNU/k*BSD: getch2.c should
diego
parents:
9380
diff
changeset
|
246 #if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GLIBC__) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
247 tcsetattr(0,TCSANOW,&tio_orig); |
5948 | 248 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
249 ioctl(0,TIOCSETA,&tio_orig); |
958
162a78d3cc08
FreeBSD support by Vladimir Kushnir vkushnir@Alfacom.net
arpi_esp
parents:
1
diff
changeset
|
250 #else |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
251 ioctl(0,TCSETS,&tio_orig); |
958
162a78d3cc08
FreeBSD support by Vladimir Kushnir vkushnir@Alfacom.net
arpi_esp
parents:
1
diff
changeset
|
252 #endif |
3009 | 253 #endif |
1632 | 254 getch2_status=0; |
1 | 255 } |
256 |