Mercurial > mplayer.hg
annotate osdep/getch2.c @ 22616:09dc129234a0
Matroska seeking fixes
If a relative seek forward went past the last index position the
Matroska demuxer did not seek to any index position. It did however set
the mkv_d->skip_to_timecode variable which meant that the next
fill_buffer() call would read from the current position until the target
position (probably the end of the file). Fix this by changing the code
to seek to the last index position if that is between the current and
target positions.
Also change backwards relative seek to accept an exactly matching index
position (<= vs <) and reorganize the seeking conditionals to allow
making the above change without turning the code into a complete mess.
author | uau |
---|---|
date | Fri, 16 Mar 2007 14:55:41 +0000 |
parents | 56a0b0f8a66e |
children | 71b3e04d0555 |
rev | line source |
---|---|
1 | 1 /* GyS-TermIO v2.0 (for GySmail v3) (C) 1999 A'rpi/ESP-team */ |
2 | |
16985 | 3 #include "config.h" |
1 | 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 |
22442
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
31 #if defined(USE_LANGINFO) && defined(USE_ICONV) |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
32 #include <locale.h> |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
33 #include <langinfo.h> |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
34 #endif |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
35 |
1 | 36 #include <unistd.h> |
37 | |
38 #include "keycodes.h" | |
39 | |
3009 | 40 #ifdef HAVE_TERMIOS |
1 | 41 static struct termios tio_orig; |
3009 | 42 #endif |
1 | 43 static int getch2_len=0; |
44 static char getch2_buf[BUF_LEN]; | |
45 | |
46 int screen_width=80; | |
47 int screen_height=24; | |
17258
3d02f6e2a432
change erase to end of line, fall back to old behavior if no termcap found
ods15
parents:
17240
diff
changeset
|
48 char * erase_to_end_of_line = NULL; |
1 | 49 |
50 typedef struct { | |
51 int len; | |
52 int code; | |
53 char chars[8]; | |
54 } keycode_st; | |
55 static keycode_st getch2_keys[MAX_KEYS]; | |
56 static int getch2_key_db=0; | |
57 | |
58 #ifdef USE_TERMCAP | |
59 | |
60 #if 0 | |
61 #include <termcap.h> | |
62 #else | |
63 extern int tgetent (char *BUFFER, char *TERMTYPE); | |
64 extern int tgetnum (char *NAME); | |
65 extern int tgetflag (char *NAME); | |
66 extern char *tgetstr (char *NAME, char **AREA); | |
67 #endif | |
68 | |
69 static char term_buffer[4096]; | |
70 static char term_buffer2[4096]; | |
71 static char *term_p=term_buffer2; | |
72 | |
73 static void termcap_add(char *id,int code){ | |
74 char *p=tgetstr(id,&term_p); | |
75 if(!p) return; | |
76 if(getch2_key_db>=MAX_KEYS) return; | |
77 getch2_keys[getch2_key_db].len=strlen(p); | |
78 strncpy(getch2_keys[getch2_key_db].chars,p,8); | |
79 getch2_keys[getch2_key_db].code=code; | |
80 ++getch2_key_db; | |
81 /* printf("%s=%s\n",id,p); */ | |
82 } | |
83 | |
84 static int success=0; | |
85 | |
86 int load_termcap(char *termtype){ | |
87 if(!termtype) termtype=getenv("TERM"); | |
8889
18427eee9205
The attached little patch fixes a core dump on termcap systems when
arpi
parents:
8016
diff
changeset
|
88 if(!termtype) termtype="unknown"; |
1 | 89 success=tgetent(term_buffer, termtype); |
90 if(success<0){ printf("Could not access the 'termcap' data base.\n"); return 0; } | |
91 if(success==0){ printf("Terminal type `%s' is not defined.\n", termtype);return 0;} | |
92 | |
93 screen_width=tgetnum("co"); | |
94 screen_height=tgetnum("li"); | |
95 if(screen_width<1 || screen_width>255) screen_width=80; | |
96 if(screen_height<1 || screen_height>255) screen_height=24; | |
17258
3d02f6e2a432
change erase to end of line, fall back to old behavior if no termcap found
ods15
parents:
17240
diff
changeset
|
97 erase_to_end_of_line= tgetstr("cd",&term_p); |
1 | 98 |
99 termcap_add("kP",KEY_PGUP); | |
100 termcap_add("kN",KEY_PGDWN); | |
101 termcap_add("kh",KEY_HOME); | |
102 termcap_add("kH",KEY_END); | |
103 termcap_add("kI",KEY_INS); | |
104 termcap_add("kD",KEY_DEL); | |
105 termcap_add("kb",KEY_BS); | |
106 termcap_add("kl",KEY_LEFT); | |
107 termcap_add("kd",KEY_DOWN); | |
108 termcap_add("ku",KEY_UP); | |
109 termcap_add("kr",KEY_RIGHT); | |
110 termcap_add("k0",KEY_F+0); | |
111 termcap_add("k1",KEY_F+1); | |
112 termcap_add("k2",KEY_F+2); | |
113 termcap_add("k3",KEY_F+3); | |
114 termcap_add("k4",KEY_F+4); | |
115 termcap_add("k5",KEY_F+5); | |
116 termcap_add("k6",KEY_F+6); | |
117 termcap_add("k7",KEY_F+7); | |
118 termcap_add("k8",KEY_F+8); | |
119 termcap_add("k9",KEY_F+9); | |
120 termcap_add("k;",KEY_F+10); | |
121 return getch2_key_db; | |
122 } | |
123 | |
124 #endif | |
125 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17264
diff
changeset
|
126 void get_screen_size(void){ |
1 | 127 #ifdef USE_IOCTL |
128 struct winsize ws; | |
129 if (ioctl(0, TIOCGWINSZ, &ws) < 0 || !ws.ws_row || !ws.ws_col) return; | |
130 /* printf("Using IOCTL\n"); */ | |
131 screen_width=ws.ws_col; | |
132 screen_height=ws.ws_row; | |
133 #endif | |
134 } | |
135 | |
136 int getch2(int time){ | |
137 int len=0; | |
138 int code=0; | |
139 int i=0; | |
140 | |
141 while(!getch2_len || (getch2_len==1 && getch2_buf[0]==27)){ | |
142 fd_set rfds; | |
143 struct timeval tv; | |
144 int retval; | |
145 /* Watch stdin (fd 0) to see when it has input. */ | |
146 FD_ZERO(&rfds); FD_SET(0,&rfds); | |
147 /* Wait up to 'time' microseconds. */ | |
148 tv.tv_sec=time/1000; tv.tv_usec = (time%1000)*1000; | |
149 retval=select(1, &rfds, NULL, NULL, &tv); | |
3014
16576e05b93a
Profiling fix by Artur Skawina <skawina@geocities.com>
atmos4
parents:
3009
diff
changeset
|
150 if(retval<=0) return -1; |
1 | 151 /* Data is available now. */ |
152 retval=read(0,&getch2_buf[getch2_len],BUF_LEN-getch2_len); | |
153 if(retval<1) return -1; | |
154 getch2_len+=retval; | |
155 } | |
156 | |
157 /* First find in the TERMCAP database: */ | |
158 for(i=0;i<getch2_key_db;i++){ | |
159 if((len=getch2_keys[i].len)<=getch2_len) | |
160 if(memcmp(getch2_keys[i].chars,getch2_buf,len)==0){ | |
161 code=getch2_keys[i].code; goto found; | |
162 } | |
163 } | |
164 len=1;code=getch2_buf[0]; | |
165 /* Check the well-known codes... */ | |
166 if(code!=27){ | |
167 if(code=='A'-64){ code=KEY_HOME; goto found;} | |
168 if(code=='E'-64){ code=KEY_END; goto found;} | |
169 if(code=='D'-64){ code=KEY_DEL; goto found;} | |
170 if(code=='H'-64){ code=KEY_BS; goto found;} | |
171 if(code=='U'-64){ code=KEY_PGUP; goto found;} | |
172 if(code=='V'-64){ code=KEY_PGDWN; goto found;} | |
173 if(code==8 || code==127){ code=KEY_BS; goto found;} | |
174 if(code==10 || code==13){ | |
175 if(getch2_len>1){ | |
176 int c=getch2_buf[1]; | |
177 if(c==10 || c==13) if(c!=code) len=2; | |
178 } | |
179 code=KEY_ENTER; | |
180 goto found; | |
181 } | |
182 } else if(getch2_len>1){ | |
183 int c=getch2_buf[1]; | |
184 if(c==27){ code=KEY_ESC; len=2; goto found;} | |
185 if(c>='0' && c<='9'){ code=c-'0'+KEY_F; len=2; goto found;} | |
186 if(getch2_len>=4 && c=='[' && getch2_buf[2]=='['){ | |
187 int c=getch2_buf[3]; | |
188 if(c>='A' && c<'A'+12){ code=KEY_F+1+c-'A';len=4;goto found;} | |
189 } | |
190 if(c=='[' || c=='O') if(getch2_len>=3){ | |
191 int c=getch2_buf[2]; | |
192 static short int ctable[]={ KEY_UP,KEY_DOWN,KEY_RIGHT,KEY_LEFT,0, | |
193 KEY_END,KEY_PGDWN,KEY_HOME,KEY_PGUP,0,0,KEY_INS,0,0,0, | |
194 KEY_F+1,KEY_F+2,KEY_F+3,KEY_F+4}; | |
195 if(c>='A' && c<='S') | |
196 if(ctable[c-'A']){ code=ctable[c-'A']; len=3; goto found;} | |
197 } | |
198 if(getch2_len>=4 && c=='[' && getch2_buf[3]=='~'){ | |
199 int c=getch2_buf[2]; | |
200 int ctable[8]={KEY_HOME,KEY_INS,KEY_DEL,KEY_END,KEY_PGUP,KEY_PGDWN,KEY_HOME,KEY_END}; | |
201 if(c>='1' && c<='8'){ code=ctable[c-'1']; len=4; goto found;} | |
202 } | |
203 if(getch2_len>=5 && c=='[' && getch2_buf[4]=='~'){ | |
204 int i=getch2_buf[2]-'0'; | |
205 int j=getch2_buf[3]-'0'; | |
206 if(i>=0 && i<=9 && j>=0 && j<=9){ | |
207 static short int ftable[20]={ | |
208 11,12,13,14,15, 17,18,19,20,21, | |
209 23,24,25,26,28, 29,31,32,33,34 }; | |
210 int a=i*10+j; | |
211 for(i=0;i<20;i++) if(ftable[i]==a){ code=KEY_F+1+i;len=5;goto found;} | |
212 } | |
213 } | |
214 } | |
215 found: | |
216 if((getch2_len-=len)>0){ | |
217 int i; | |
218 for(i=0;i<getch2_len;i++) getch2_buf[i]=getch2_buf[len+i]; | |
219 } | |
220 return code; | |
221 } | |
222 | |
1632 | 223 static int getch2_status=0; |
224 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17264
diff
changeset
|
225 void getch2_enable(void){ |
3009 | 226 #ifdef HAVE_TERMIOS |
1 | 227 struct termios tio_new; |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
228 tcgetattr(0,&tio_orig); |
1 | 229 tio_new=tio_orig; |
230 tio_new.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */ | |
231 tio_new.c_cc[VMIN] = 1; | |
232 tio_new.c_cc[VTIME] = 0; | |
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); |
3009 | 234 #endif |
1632 | 235 getch2_status=1; |
1 | 236 } |
237 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17264
diff
changeset
|
238 void getch2_disable(void){ |
1632 | 239 if(!getch2_status) return; // already disabled / never enabled |
3009 | 240 #ifdef HAVE_TERMIOS |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
241 tcsetattr(0,TCSANOW,&tio_orig); |
3009 | 242 #endif |
1632 | 243 getch2_status=0; |
1 | 244 } |
245 | |
22442
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
246 #ifdef USE_ICONV |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
247 char* get_term_charset() |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
248 { |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
249 char* charset = NULL; |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
250 #ifdef USE_LANGINFO |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
251 setlocale(LC_CTYPE, ""); |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
252 charset = nl_langinfo(CODESET); |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
253 setlocale(LC_CTYPE, "C"); |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
254 #endif |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
255 return charset; |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
256 } |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
257 #endif |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
258 |