Mercurial > mplayer.hg
annotate osdep/getch2.c @ 25068:4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
available format list (but report call as failed, to
continue checking formats).
This gives small chance to build graph even if device
does not report about particular format as supported.
This makes mplayer be able to work with PVR-150 card
(card's driver does not report about yuy2 format, but
accepts connection and works with it).
author | voroshil |
---|---|
date | Sun, 18 Nov 2007 13:17:00 +0000 |
parents | c5c0cb0e90d2 |
children | e7c989f7a7c9 |
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 | |
24129 | 38 #include "mp_fifo.h" |
1 | 39 #include "keycodes.h" |
40 | |
3009 | 41 #ifdef HAVE_TERMIOS |
1 | 42 static struct termios tio_orig; |
3009 | 43 #endif |
1 | 44 static int getch2_len=0; |
45 static char getch2_buf[BUF_LEN]; | |
46 | |
47 int screen_width=80; | |
48 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
|
49 char * erase_to_end_of_line = NULL; |
1 | 50 |
51 typedef struct { | |
52 int len; | |
53 int code; | |
54 char chars[8]; | |
55 } keycode_st; | |
56 static keycode_st getch2_keys[MAX_KEYS]; | |
57 static int getch2_key_db=0; | |
58 | |
59 #ifdef USE_TERMCAP | |
60 | |
61 #if 0 | |
62 #include <termcap.h> | |
63 #else | |
64 extern int tgetent (char *BUFFER, char *TERMTYPE); | |
65 extern int tgetnum (char *NAME); | |
66 extern int tgetflag (char *NAME); | |
67 extern char *tgetstr (char *NAME, char **AREA); | |
68 #endif | |
69 | |
70 static char term_buffer[4096]; | |
71 static char term_buffer2[4096]; | |
72 static char *term_p=term_buffer2; | |
73 | |
74 static void termcap_add(char *id,int code){ | |
75 char *p=tgetstr(id,&term_p); | |
76 if(!p) return; | |
77 if(getch2_key_db>=MAX_KEYS) return; | |
78 getch2_keys[getch2_key_db].len=strlen(p); | |
79 strncpy(getch2_keys[getch2_key_db].chars,p,8); | |
80 getch2_keys[getch2_key_db].code=code; | |
81 ++getch2_key_db; | |
82 /* printf("%s=%s\n",id,p); */ | |
83 } | |
84 | |
85 static int success=0; | |
86 | |
87 int load_termcap(char *termtype){ | |
88 if(!termtype) termtype=getenv("TERM"); | |
8889
18427eee9205
The attached little patch fixes a core dump on termcap systems when
arpi
parents:
8016
diff
changeset
|
89 if(!termtype) termtype="unknown"; |
1 | 90 success=tgetent(term_buffer, termtype); |
91 if(success<0){ printf("Could not access the 'termcap' data base.\n"); return 0; } | |
92 if(success==0){ printf("Terminal type `%s' is not defined.\n", termtype);return 0;} | |
93 | |
94 screen_width=tgetnum("co"); | |
95 screen_height=tgetnum("li"); | |
96 if(screen_width<1 || screen_width>255) screen_width=80; | |
97 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
|
98 erase_to_end_of_line= tgetstr("cd",&term_p); |
1 | 99 |
100 termcap_add("kP",KEY_PGUP); | |
101 termcap_add("kN",KEY_PGDWN); | |
102 termcap_add("kh",KEY_HOME); | |
103 termcap_add("kH",KEY_END); | |
104 termcap_add("kI",KEY_INS); | |
105 termcap_add("kD",KEY_DEL); | |
106 termcap_add("kb",KEY_BS); | |
107 termcap_add("kl",KEY_LEFT); | |
108 termcap_add("kd",KEY_DOWN); | |
109 termcap_add("ku",KEY_UP); | |
110 termcap_add("kr",KEY_RIGHT); | |
111 termcap_add("k0",KEY_F+0); | |
112 termcap_add("k1",KEY_F+1); | |
113 termcap_add("k2",KEY_F+2); | |
114 termcap_add("k3",KEY_F+3); | |
115 termcap_add("k4",KEY_F+4); | |
116 termcap_add("k5",KEY_F+5); | |
117 termcap_add("k6",KEY_F+6); | |
118 termcap_add("k7",KEY_F+7); | |
119 termcap_add("k8",KEY_F+8); | |
120 termcap_add("k9",KEY_F+9); | |
121 termcap_add("k;",KEY_F+10); | |
122 return getch2_key_db; | |
123 } | |
124 | |
125 #endif | |
126 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17264
diff
changeset
|
127 void get_screen_size(void){ |
1 | 128 #ifdef USE_IOCTL |
129 struct winsize ws; | |
130 if (ioctl(0, TIOCGWINSZ, &ws) < 0 || !ws.ws_row || !ws.ws_col) return; | |
131 /* printf("Using IOCTL\n"); */ | |
132 screen_width=ws.ws_col; | |
133 screen_height=ws.ws_row; | |
134 #endif | |
135 } | |
136 | |
24129 | 137 void getch2(void) |
138 { | |
24130 | 139 int retval = read(0, &getch2_buf[getch2_len], BUF_LEN-getch2_len); |
24129 | 140 if (retval < 1) |
24130 | 141 return; |
142 getch2_len += retval; | |
1 | 143 |
24129 | 144 while (getch2_len > 0 && (getch2_len > 1 || getch2_buf[0] != 27)) { |
24130 | 145 int i, len, code; |
146 | |
147 /* First find in the TERMCAP database: */ | |
148 for (i = 0; i < getch2_key_db; i++) { | |
149 if ((len = getch2_keys[i].len) <= getch2_len) | |
150 if(memcmp(getch2_keys[i].chars, getch2_buf, len) == 0) { | |
151 code = getch2_keys[i].code; | |
152 goto found; | |
153 } | |
1 | 154 } |
24130 | 155 /* We always match some keypress here, with length 1 if nothing else. |
156 * Since some of the cases explicitly test remaining buffer length | |
157 * having a keycode only partially read in the buffer could incorrectly | |
158 * use the first byte as an independent character. | |
159 * However the buffer is big enough that this shouldn't happen too | |
160 * easily, and it's been this way for years without many complaints. | |
161 * I see no simple fix as there's no easy test which would tell | |
162 * whether a string must be part of a longer keycode. */ | |
163 len = 1; | |
164 code = getch2_buf[0]; | |
165 /* Check the well-known codes... */ | |
166 if (code != 27) { | |
167 if (code == 'A'-64) code = KEY_HOME; | |
168 else if (code == 'E'-64) code = KEY_END; | |
169 else if (code == 'D'-64) code = KEY_DEL; | |
170 else if (code == 'H'-64) code = KEY_BS; | |
171 else if (code == 'U'-64) code = KEY_PGUP; | |
172 else if (code == 'V'-64) code = KEY_PGDWN; | |
173 else if (code == 8 || code==127) code = KEY_BS; | |
174 else if (code == 10 || code==13) { | |
175 if (getch2_len > 1) { | |
176 int c = getch2_buf[1]; | |
177 if ((c == 10 || c == 13) && (c != code)) | |
178 len = 2; | |
179 } | |
180 code = KEY_ENTER; | |
181 } | |
1 | 182 } |
24130 | 183 else if (getch2_len > 1) { |
184 int c = getch2_buf[1]; | |
185 if (c == 27) { | |
186 code = KEY_ESC; | |
187 len = 2; | |
188 goto found; | |
189 } | |
190 if (c >= '0' && c <= '9') { | |
191 code = c-'0'+KEY_F; | |
192 len = 2; | |
193 goto found; | |
194 } | |
195 if (getch2_len >= 4 && c == '[' && getch2_buf[2] == '[') { | |
196 int c = getch2_buf[3]; | |
197 if (c >= 'A' && c < 'A'+12) { | |
198 code = KEY_F+1 + c-'A'; | |
199 len = 4; | |
200 goto found; | |
201 } | |
202 } | |
24515 | 203 if ((c == '[' || c == 'O') && getch2_len >= 3) { |
24130 | 204 int c = getch2_buf[2]; |
205 const short ctable[] = { | |
206 KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT, 0, | |
207 KEY_END, KEY_PGDWN, KEY_HOME, KEY_PGUP, 0, 0, KEY_INS, 0, 0, 0, | |
208 KEY_F+1, KEY_F+2, KEY_F+3, KEY_F+4}; | |
209 if (c >= 'A' && c <= 'S') | |
210 if (ctable[c - 'A']) { | |
211 code = ctable[c - 'A']; | |
212 len = 3; | |
213 goto found; | |
214 } | |
215 } | |
216 if (getch2_len >= 4 && c == '[' && getch2_buf[3] == '~') { | |
217 int c = getch2_buf[2]; | |
218 const int ctable[8] = {KEY_HOME, KEY_INS, KEY_DEL, KEY_END, KEY_PGUP, KEY_PGDWN, KEY_HOME, KEY_END}; | |
219 if (c >= '1' && c <= '8') { | |
220 code = ctable[c - '1']; | |
221 len = 4; | |
222 goto found; | |
223 } | |
224 } | |
225 if (getch2_len >= 5 && c == '[' && getch2_buf[4] == '~') { | |
226 int i = getch2_buf[2] - '0'; | |
227 int j = getch2_buf[3] - '0'; | |
228 if (i >= 0 && i <= 9 && j >= 0 && j <= 9) { | |
229 const short ftable[20] = { | |
230 11,12,13,14,15, 17,18,19,20,21, | |
231 23,24,25,26,28, 29,31,32,33,34 }; | |
232 int a = i*10 + j; | |
233 for (i = 0; i < 20; i++) | |
234 if (ftable[i] == a) { | |
235 code = KEY_F+1 + i; | |
236 len = 5; | |
237 goto found; | |
238 } | |
239 } | |
240 } | |
1 | 241 } |
24130 | 242 found: |
243 getch2_len -= len; | |
244 for (i = 0; i < getch2_len; i++) | |
245 getch2_buf[i] = getch2_buf[len+i]; | |
246 mplayer_put_key(code); | |
24129 | 247 } |
1 | 248 } |
249 | |
1632 | 250 static int getch2_status=0; |
251 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17264
diff
changeset
|
252 void getch2_enable(void){ |
3009 | 253 #ifdef HAVE_TERMIOS |
1 | 254 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
|
255 tcgetattr(0,&tio_orig); |
1 | 256 tio_new=tio_orig; |
257 tio_new.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */ | |
258 tio_new.c_cc[VMIN] = 1; | |
259 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
|
260 tcsetattr(0,TCSANOW,&tio_new); |
3009 | 261 #endif |
1632 | 262 getch2_status=1; |
1 | 263 } |
264 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17264
diff
changeset
|
265 void getch2_disable(void){ |
1632 | 266 if(!getch2_status) return; // already disabled / never enabled |
3009 | 267 #ifdef HAVE_TERMIOS |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
958
diff
changeset
|
268 tcsetattr(0,TCSANOW,&tio_orig); |
3009 | 269 #endif |
1632 | 270 getch2_status=0; |
1 | 271 } |
272 | |
22442
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
273 #ifdef USE_ICONV |
22886 | 274 char* get_term_charset(void) |
22442
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
275 { |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
276 char* charset = NULL; |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
277 #ifdef USE_LANGINFO |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
278 setlocale(LC_CTYPE, ""); |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
279 charset = nl_langinfo(CODESET); |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
280 setlocale(LC_CTYPE, "C"); |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
281 #endif |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
282 return charset; |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
283 } |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
284 #endif |
56a0b0f8a66e
Add code to detect and convert to console codepage on Windows.
reimar
parents:
21589
diff
changeset
|
285 |