diff options
author | Franklin Wei <git@fwei.tk> | 2018-02-07 20:04:46 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2018-03-12 20:52:01 -0400 |
commit | 6039eb05ba6d82ef56f2868c96654c552d117bf9 (patch) | |
tree | 9db7016bcbf66cfdf7b9bc998d84c6eaff9c8378 /apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c | |
parent | ef373c03b96b0be08babca581d9f10bccfd4931f (diff) | |
download | rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.tar.gz rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.zip |
sdl: remove non-rockbox drivers
We never use any of these other drivers, so having them around just takes
up space.
Change-Id: Iced812162df1fef3fd55522b7e700acb6c3bcd41
Diffstat (limited to 'apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c')
-rw-r--r-- | apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c | 1254 |
1 files changed, 0 insertions, 1254 deletions
diff --git a/apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c b/apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c deleted file mode 100644 index 5e369a4a89..0000000000 --- a/apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c +++ /dev/null | |||
@@ -1,1254 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Handle the event stream, converting console events into SDL events */ | ||
25 | |||
26 | #include <stdio.h> | ||
27 | #include <sys/types.h> | ||
28 | #include <sys/time.h> | ||
29 | #include <sys/ioctl.h> | ||
30 | #include <unistd.h> | ||
31 | #include <fcntl.h> | ||
32 | #include <errno.h> | ||
33 | #include <limits.h> | ||
34 | |||
35 | /* For parsing /proc */ | ||
36 | #include <dirent.h> | ||
37 | #include <ctype.h> | ||
38 | |||
39 | #include <linux/vt.h> | ||
40 | #include <linux/kd.h> | ||
41 | #include <linux/keyboard.h> | ||
42 | |||
43 | #include "SDL_timer.h" | ||
44 | #include "SDL_mutex.h" | ||
45 | #include "../SDL_sysvideo.h" | ||
46 | #include "../../events/SDL_sysevents.h" | ||
47 | #include "../../events/SDL_events_c.h" | ||
48 | #include "SDL_fbvideo.h" | ||
49 | #include "SDL_fbevents_c.h" | ||
50 | #include "SDL_fbkeys.h" | ||
51 | |||
52 | #include "SDL_fbelo.h" | ||
53 | |||
54 | #ifndef GPM_NODE_FIFO | ||
55 | #define GPM_NODE_FIFO "/dev/gpmdata" | ||
56 | #endif | ||
57 | |||
58 | /*#define DEBUG_KEYBOARD*/ | ||
59 | /*#define DEBUG_MOUSE*/ | ||
60 | |||
61 | /* The translation tables from a console scancode to a SDL keysym */ | ||
62 | #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) | ||
63 | static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; | ||
64 | static SDLKey keymap[128]; | ||
65 | static Uint16 keymap_temp[128]; /* only used at startup */ | ||
66 | static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); | ||
67 | |||
68 | /* Ugh, we have to duplicate the kernel's keysym mapping code... | ||
69 | Oh, it's not so bad. :-) | ||
70 | |||
71 | FIXME: Add keyboard LED handling code | ||
72 | */ | ||
73 | static void FB_vgainitkeymaps(int fd) | ||
74 | { | ||
75 | struct kbentry entry; | ||
76 | int map, i; | ||
77 | |||
78 | /* Don't do anything if we are passed a closed keyboard */ | ||
79 | if ( fd < 0 ) { | ||
80 | return; | ||
81 | } | ||
82 | |||
83 | /* Load all the keysym mappings */ | ||
84 | for ( map=0; map<NUM_VGAKEYMAPS; ++map ) { | ||
85 | SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16)); | ||
86 | for ( i=0; i<NR_KEYS; ++i ) { | ||
87 | entry.kb_table = map; | ||
88 | entry.kb_index = i; | ||
89 | if ( ioctl(fd, KDGKBENT, &entry) == 0 ) { | ||
90 | /* fill keytemp. This replaces SDL_fbkeys.h */ | ||
91 | if ( (map == 0) && (i<128) ) { | ||
92 | keymap_temp[i] = entry.kb_value; | ||
93 | } | ||
94 | /* The "Enter" key is a special case */ | ||
95 | if ( entry.kb_value == K_ENTER ) { | ||
96 | entry.kb_value = K(KT_ASCII,13); | ||
97 | } | ||
98 | /* Handle numpad specially as well */ | ||
99 | if ( KTYP(entry.kb_value) == KT_PAD ) { | ||
100 | switch ( entry.kb_value ) { | ||
101 | case K_P0: | ||
102 | case K_P1: | ||
103 | case K_P2: | ||
104 | case K_P3: | ||
105 | case K_P4: | ||
106 | case K_P5: | ||
107 | case K_P6: | ||
108 | case K_P7: | ||
109 | case K_P8: | ||
110 | case K_P9: | ||
111 | vga_keymap[map][i]=entry.kb_value; | ||
112 | vga_keymap[map][i]+= '0'; | ||
113 | break; | ||
114 | case K_PPLUS: | ||
115 | vga_keymap[map][i]=K(KT_ASCII,'+'); | ||
116 | break; | ||
117 | case K_PMINUS: | ||
118 | vga_keymap[map][i]=K(KT_ASCII,'-'); | ||
119 | break; | ||
120 | case K_PSTAR: | ||
121 | vga_keymap[map][i]=K(KT_ASCII,'*'); | ||
122 | break; | ||
123 | case K_PSLASH: | ||
124 | vga_keymap[map][i]=K(KT_ASCII,'/'); | ||
125 | break; | ||
126 | case K_PENTER: | ||
127 | vga_keymap[map][i]=K(KT_ASCII,'\r'); | ||
128 | break; | ||
129 | case K_PCOMMA: | ||
130 | vga_keymap[map][i]=K(KT_ASCII,','); | ||
131 | break; | ||
132 | case K_PDOT: | ||
133 | vga_keymap[map][i]=K(KT_ASCII,'.'); | ||
134 | break; | ||
135 | default: | ||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | /* Do the normal key translation */ | ||
140 | if ( (KTYP(entry.kb_value) == KT_LATIN) || | ||
141 | (KTYP(entry.kb_value) == KT_ASCII) || | ||
142 | (KTYP(entry.kb_value) == KT_LETTER) ) { | ||
143 | vga_keymap[map][i] = entry.kb_value; | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
150 | int FB_InGraphicsMode(_THIS) | ||
151 | { | ||
152 | return((keyboard_fd >= 0) && (saved_kbd_mode >= 0)); | ||
153 | } | ||
154 | |||
155 | int FB_EnterGraphicsMode(_THIS) | ||
156 | { | ||
157 | struct termios keyboard_termios; | ||
158 | |||
159 | /* Set medium-raw keyboard mode */ | ||
160 | if ( (keyboard_fd >= 0) && !FB_InGraphicsMode(this) ) { | ||
161 | |||
162 | /* Switch to the correct virtual terminal */ | ||
163 | if ( current_vt > 0 ) { | ||
164 | struct vt_stat vtstate; | ||
165 | |||
166 | if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) { | ||
167 | saved_vt = vtstate.v_active; | ||
168 | } | ||
169 | if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) { | ||
170 | ioctl(keyboard_fd, VT_WAITACTIVE, current_vt); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /* Set the terminal input mode */ | ||
175 | if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) { | ||
176 | SDL_SetError("Unable to get terminal attributes"); | ||
177 | if ( keyboard_fd > 0 ) { | ||
178 | close(keyboard_fd); | ||
179 | } | ||
180 | keyboard_fd = -1; | ||
181 | return(-1); | ||
182 | } | ||
183 | if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) { | ||
184 | SDL_SetError("Unable to get current keyboard mode"); | ||
185 | if ( keyboard_fd > 0 ) { | ||
186 | close(keyboard_fd); | ||
187 | } | ||
188 | keyboard_fd = -1; | ||
189 | return(-1); | ||
190 | } | ||
191 | keyboard_termios = saved_kbd_termios; | ||
192 | keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG); | ||
193 | keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); | ||
194 | keyboard_termios.c_cc[VMIN] = 0; | ||
195 | keyboard_termios.c_cc[VTIME] = 0; | ||
196 | if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) { | ||
197 | FB_CloseKeyboard(this); | ||
198 | SDL_SetError("Unable to set terminal attributes"); | ||
199 | return(-1); | ||
200 | } | ||
201 | /* This will fail if we aren't root or this isn't our tty */ | ||
202 | if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) { | ||
203 | FB_CloseKeyboard(this); | ||
204 | SDL_SetError("Unable to set keyboard in raw mode"); | ||
205 | return(-1); | ||
206 | } | ||
207 | if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { | ||
208 | FB_CloseKeyboard(this); | ||
209 | SDL_SetError("Unable to set keyboard in graphics mode"); | ||
210 | return(-1); | ||
211 | } | ||
212 | /* Prevent switching the virtual terminal */ | ||
213 | ioctl(keyboard_fd, VT_LOCKSWITCH, 1); | ||
214 | } | ||
215 | return(keyboard_fd); | ||
216 | } | ||
217 | |||
218 | void FB_LeaveGraphicsMode(_THIS) | ||
219 | { | ||
220 | if ( FB_InGraphicsMode(this) ) { | ||
221 | ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | ||
222 | ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); | ||
223 | tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); | ||
224 | saved_kbd_mode = -1; | ||
225 | |||
226 | /* Head back over to the original virtual terminal */ | ||
227 | ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1); | ||
228 | if ( saved_vt > 0 ) { | ||
229 | ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | |||
234 | void FB_CloseKeyboard(_THIS) | ||
235 | { | ||
236 | if ( keyboard_fd >= 0 ) { | ||
237 | FB_LeaveGraphicsMode(this); | ||
238 | if ( keyboard_fd > 0 ) { | ||
239 | close(keyboard_fd); | ||
240 | } | ||
241 | } | ||
242 | keyboard_fd = -1; | ||
243 | } | ||
244 | |||
245 | int FB_OpenKeyboard(_THIS) | ||
246 | { | ||
247 | /* Open only if not already opened */ | ||
248 | if ( keyboard_fd < 0 ) { | ||
249 | static const char * const tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; | ||
250 | static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; | ||
251 | int i, tty0_fd; | ||
252 | |||
253 | /* Try to query for a free virtual terminal */ | ||
254 | tty0_fd = -1; | ||
255 | for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) { | ||
256 | tty0_fd = open(tty0[i], O_WRONLY, 0); | ||
257 | } | ||
258 | if ( tty0_fd < 0 ) { | ||
259 | tty0_fd = dup(0); /* Maybe stdin is a VT? */ | ||
260 | } | ||
261 | ioctl(tty0_fd, VT_OPENQRY, ¤t_vt); | ||
262 | close(tty0_fd); | ||
263 | if ( (geteuid() == 0) && (current_vt > 0) ) { | ||
264 | for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) { | ||
265 | char vtpath[12]; | ||
266 | |||
267 | SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], current_vt); | ||
268 | keyboard_fd = open(vtpath, O_RDWR, 0); | ||
269 | #ifdef DEBUG_KEYBOARD | ||
270 | fprintf(stderr, "vtpath = %s, fd = %d\n", | ||
271 | vtpath, keyboard_fd); | ||
272 | #endif /* DEBUG_KEYBOARD */ | ||
273 | |||
274 | /* This needs to be our controlling tty | ||
275 | so that the kernel ioctl() calls work | ||
276 | */ | ||
277 | if ( keyboard_fd >= 0 ) { | ||
278 | tty0_fd = open("/dev/tty", O_RDWR, 0); | ||
279 | if ( tty0_fd >= 0 ) { | ||
280 | ioctl(tty0_fd, TIOCNOTTY, 0); | ||
281 | close(tty0_fd); | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | if ( keyboard_fd < 0 ) { | ||
287 | /* Last resort, maybe our tty is a usable VT */ | ||
288 | struct vt_stat vtstate; | ||
289 | |||
290 | keyboard_fd = open("/dev/tty", O_RDWR); | ||
291 | |||
292 | if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) { | ||
293 | current_vt = vtstate.v_active; | ||
294 | } else { | ||
295 | current_vt = 0; | ||
296 | } | ||
297 | } | ||
298 | #ifdef DEBUG_KEYBOARD | ||
299 | fprintf(stderr, "Current VT: %d\n", current_vt); | ||
300 | #endif | ||
301 | saved_kbd_mode = -1; | ||
302 | |||
303 | /* Make sure that our input is a console terminal */ | ||
304 | { int dummy; | ||
305 | if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) { | ||
306 | close(keyboard_fd); | ||
307 | keyboard_fd = -1; | ||
308 | SDL_SetError("Unable to open a console terminal"); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | /* Set up keymap */ | ||
313 | FB_vgainitkeymaps(keyboard_fd); | ||
314 | } | ||
315 | return(keyboard_fd); | ||
316 | } | ||
317 | |||
318 | static enum { | ||
319 | MOUSE_NONE = -1, | ||
320 | MOUSE_MSC, /* Note: GPM uses the MSC protocol */ | ||
321 | MOUSE_PS2, | ||
322 | MOUSE_IMPS2, | ||
323 | MOUSE_MS, | ||
324 | MOUSE_BM, | ||
325 | MOUSE_ELO, | ||
326 | MOUSE_TSLIB, | ||
327 | NUM_MOUSE_DRVS | ||
328 | } mouse_drv = MOUSE_NONE; | ||
329 | |||
330 | void FB_CloseMouse(_THIS) | ||
331 | { | ||
332 | #if SDL_INPUT_TSLIB | ||
333 | if (ts_dev != NULL) { | ||
334 | ts_close(ts_dev); | ||
335 | ts_dev = NULL; | ||
336 | mouse_fd = -1; | ||
337 | } | ||
338 | #endif /* SDL_INPUT_TSLIB */ | ||
339 | if ( mouse_fd > 0 ) { | ||
340 | close(mouse_fd); | ||
341 | } | ||
342 | mouse_fd = -1; | ||
343 | } | ||
344 | |||
345 | /* Returns processes listed in /proc with the desired name */ | ||
346 | static int find_pid(DIR *proc, const char *wanted_name) | ||
347 | { | ||
348 | struct dirent *entry; | ||
349 | int pid; | ||
350 | |||
351 | /* First scan proc for the gpm process */ | ||
352 | pid = 0; | ||
353 | while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) { | ||
354 | if ( isdigit(entry->d_name[0]) ) { | ||
355 | FILE *status; | ||
356 | char path[PATH_MAX]; | ||
357 | char name[PATH_MAX]; | ||
358 | |||
359 | SDL_snprintf(path, SDL_arraysize(path), "/proc/%s/status", entry->d_name); | ||
360 | status=fopen(path, "r"); | ||
361 | if ( status ) { | ||
362 | int matches = 0; | ||
363 | name[0] = '\0'; | ||
364 | matches = fscanf(status, "Name: %s", name); | ||
365 | if ( (matches == 1) && (SDL_strcmp(name, wanted_name) == 0) ) { | ||
366 | pid = SDL_atoi(entry->d_name); | ||
367 | } | ||
368 | fclose(status); | ||
369 | } | ||
370 | } | ||
371 | } | ||
372 | return pid; | ||
373 | } | ||
374 | |||
375 | /* Returns true if /dev/gpmdata is being written to by gpm */ | ||
376 | static int gpm_available(char *proto, size_t protolen) | ||
377 | { | ||
378 | int available; | ||
379 | DIR *proc; | ||
380 | int pid; | ||
381 | int cmdline, len, arglen; | ||
382 | char path[PATH_MAX]; | ||
383 | char args[PATH_MAX], *arg; | ||
384 | |||
385 | /* Don't bother looking if the fifo isn't there */ | ||
386 | #ifdef DEBUG_MOUSE | ||
387 | fprintf(stderr,"testing gpm\n"); | ||
388 | #endif | ||
389 | if ( access(GPM_NODE_FIFO, F_OK) < 0 ) { | ||
390 | return(0); | ||
391 | } | ||
392 | |||
393 | available = 0; | ||
394 | proc = opendir("/proc"); | ||
395 | if ( proc ) { | ||
396 | char raw_proto[10] = { '\0' }; | ||
397 | char repeat_proto[10] = { '\0' }; | ||
398 | while ( !available && (pid=find_pid(proc, "gpm")) > 0 ) { | ||
399 | SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid); | ||
400 | cmdline = open(path, O_RDONLY, 0); | ||
401 | if ( cmdline >= 0 ) { | ||
402 | len = read(cmdline, args, sizeof(args)); | ||
403 | arg = args; | ||
404 | while ( len > 0 ) { | ||
405 | arglen = SDL_strlen(arg)+1; | ||
406 | #ifdef DEBUG_MOUSE | ||
407 | fprintf(stderr,"gpm arg %s len %d\n",arg,arglen); | ||
408 | #endif | ||
409 | if ( SDL_strcmp(arg, "-t") == 0) { | ||
410 | /* protocol string, keep it for later */ | ||
411 | char *t, *s; | ||
412 | t = arg + arglen; | ||
413 | s = SDL_strchr(t, ' '); | ||
414 | if (s) *s = 0; | ||
415 | SDL_strlcpy(raw_proto, t, SDL_arraysize(raw_proto)); | ||
416 | if (s) *s = ' '; | ||
417 | } | ||
418 | if ( SDL_strncmp(arg, "-R", 2) == 0 ) { | ||
419 | char *t, *s; | ||
420 | available = 1; | ||
421 | t = arg + 2; | ||
422 | s = SDL_strchr(t, ' '); | ||
423 | if (s) *s = 0; | ||
424 | SDL_strlcpy(repeat_proto, t, SDL_arraysize(repeat_proto)); | ||
425 | if (s) *s = ' '; | ||
426 | } | ||
427 | len -= arglen; | ||
428 | arg += arglen; | ||
429 | } | ||
430 | close(cmdline); | ||
431 | } | ||
432 | } | ||
433 | closedir(proc); | ||
434 | |||
435 | if ( available ) { | ||
436 | if ( SDL_strcmp(repeat_proto, "raw") == 0 ) { | ||
437 | SDL_strlcpy(proto, raw_proto, protolen); | ||
438 | } else if ( *repeat_proto ) { | ||
439 | SDL_strlcpy(proto, repeat_proto, protolen); | ||
440 | } else { | ||
441 | SDL_strlcpy(proto, "msc", protolen); | ||
442 | } | ||
443 | } | ||
444 | } | ||
445 | return available; | ||
446 | } | ||
447 | |||
448 | |||
449 | /* rcg06112001 Set up IMPS/2 mode, if possible. This gives | ||
450 | * us access to the mousewheel, etc. Returns zero if | ||
451 | * writes to device failed, but you still need to query the | ||
452 | * device to see which mode it's actually in. | ||
453 | */ | ||
454 | static int set_imps2_mode(int fd) | ||
455 | { | ||
456 | /* If you wanted to control the mouse mode (and we do :) ) ... | ||
457 | Set IMPS/2 protocol: | ||
458 | {0xf3,200,0xf3,100,0xf3,80} | ||
459 | Reset mouse device: | ||
460 | {0xFF} | ||
461 | */ | ||
462 | Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; | ||
463 | /*Uint8 reset = 0xff;*/ | ||
464 | fd_set fdset; | ||
465 | struct timeval tv; | ||
466 | int retval = 0; | ||
467 | |||
468 | if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { | ||
469 | /* Don't reset it, that'll clear IMPS/2 mode on some mice | ||
470 | if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) { | ||
471 | retval = 1; | ||
472 | } | ||
473 | */ | ||
474 | } | ||
475 | |||
476 | /* Get rid of any chatter from the above */ | ||
477 | FD_ZERO(&fdset); | ||
478 | FD_SET(fd, &fdset); | ||
479 | tv.tv_sec = 0; | ||
480 | tv.tv_usec = 0; | ||
481 | while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | ||
482 | char temp[32]; | ||
483 | if (read(fd, temp, sizeof(temp)) <= 0) { | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | return retval; | ||
489 | } | ||
490 | |||
491 | |||
492 | /* Returns true if the mouse uses the IMPS/2 protocol */ | ||
493 | static int detect_imps2(int fd) | ||
494 | { | ||
495 | int imps2; | ||
496 | |||
497 | imps2 = 0; | ||
498 | |||
499 | if ( SDL_getenv("SDL_MOUSEDEV_IMPS2") ) { | ||
500 | imps2 = 1; | ||
501 | } | ||
502 | if ( ! imps2 ) { | ||
503 | Uint8 query_ps2 = 0xF2; | ||
504 | fd_set fdset; | ||
505 | struct timeval tv; | ||
506 | |||
507 | /* Get rid of any mouse motion noise */ | ||
508 | FD_ZERO(&fdset); | ||
509 | FD_SET(fd, &fdset); | ||
510 | tv.tv_sec = 0; | ||
511 | tv.tv_usec = 0; | ||
512 | while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | ||
513 | char temp[32]; | ||
514 | if (read(fd, temp, sizeof(temp)) <= 0) { | ||
515 | break; | ||
516 | } | ||
517 | } | ||
518 | |||
519 | /* Query for the type of mouse protocol */ | ||
520 | if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) { | ||
521 | Uint8 ch = 0; | ||
522 | |||
523 | /* Get the mouse protocol response */ | ||
524 | do { | ||
525 | FD_ZERO(&fdset); | ||
526 | FD_SET(fd, &fdset); | ||
527 | tv.tv_sec = 1; | ||
528 | tv.tv_usec = 0; | ||
529 | if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) { | ||
530 | break; | ||
531 | } | ||
532 | } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) && | ||
533 | ((ch == 0xFA) || (ch == 0xAA)) ); | ||
534 | |||
535 | /* Experimental values (Logitech wheelmouse) */ | ||
536 | #ifdef DEBUG_MOUSE | ||
537 | fprintf(stderr, "Last mouse mode: 0x%x\n", ch); | ||
538 | #endif | ||
539 | if ( (ch == 3) || (ch == 4) ) { | ||
540 | imps2 = 1; | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | return imps2; | ||
545 | } | ||
546 | |||
547 | int FB_OpenMouse(_THIS) | ||
548 | { | ||
549 | int i; | ||
550 | const char *mousedev; | ||
551 | const char *mousedrv; | ||
552 | |||
553 | mousedrv = SDL_getenv("SDL_MOUSEDRV"); | ||
554 | mousedev = SDL_getenv("SDL_MOUSEDEV"); | ||
555 | mouse_fd = -1; | ||
556 | |||
557 | #if SDL_INPUT_TSLIB | ||
558 | if ( mousedrv && (SDL_strcmp(mousedrv, "TSLIB") == 0) ) { | ||
559 | if (mousedev == NULL) mousedev = SDL_getenv("TSLIB_TSDEVICE"); | ||
560 | if (mousedev != NULL) { | ||
561 | ts_dev = ts_open(mousedev, 1); | ||
562 | if ((ts_dev != NULL) && (ts_config(ts_dev) >= 0)) { | ||
563 | #ifdef DEBUG_MOUSE | ||
564 | fprintf(stderr, "Using tslib touchscreen\n"); | ||
565 | #endif | ||
566 | mouse_drv = MOUSE_TSLIB; | ||
567 | mouse_fd = ts_fd(ts_dev); | ||
568 | return mouse_fd; | ||
569 | } | ||
570 | } | ||
571 | mouse_drv = MOUSE_NONE; | ||
572 | return mouse_fd; | ||
573 | } | ||
574 | #endif /* SDL_INPUT_TSLIB */ | ||
575 | |||
576 | /* ELO TOUCHSCREEN SUPPORT */ | ||
577 | |||
578 | if ( mousedrv && (SDL_strcmp(mousedrv, "ELO") == 0) ) { | ||
579 | mouse_fd = open(mousedev, O_RDWR); | ||
580 | if ( mouse_fd >= 0 ) { | ||
581 | if(eloInitController(mouse_fd)) { | ||
582 | #ifdef DEBUG_MOUSE | ||
583 | fprintf(stderr, "Using ELO touchscreen\n"); | ||
584 | #endif | ||
585 | mouse_drv = MOUSE_ELO; | ||
586 | } | ||
587 | |||
588 | } | ||
589 | else if ( mouse_fd < 0 ) { | ||
590 | mouse_drv = MOUSE_NONE; | ||
591 | } | ||
592 | |||
593 | return(mouse_fd); | ||
594 | } | ||
595 | |||
596 | /* STD MICE */ | ||
597 | |||
598 | if ( mousedev == NULL ) { | ||
599 | /* FIXME someday... allow multiple mice in this driver */ | ||
600 | static const char *ps2mice[] = { | ||
601 | "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL | ||
602 | }; | ||
603 | /* First try to use GPM in repeater mode */ | ||
604 | if ( mouse_fd < 0 ) { | ||
605 | char proto[10]; | ||
606 | if ( gpm_available(proto, SDL_arraysize(proto)) ) { | ||
607 | mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); | ||
608 | if ( mouse_fd >= 0 ) { | ||
609 | if ( SDL_strcmp(proto, "msc") == 0 ) { | ||
610 | mouse_drv = MOUSE_MSC; | ||
611 | } else if ( SDL_strcmp(proto, "ps2") == 0 ) { | ||
612 | mouse_drv = MOUSE_PS2; | ||
613 | } else if ( SDL_strcmp(proto, "imps2") == 0 ) { | ||
614 | mouse_drv = MOUSE_IMPS2; | ||
615 | } else if ( SDL_strcmp(proto, "ms") == 0 || | ||
616 | SDL_strcmp(proto, "bare") == 0 ) { | ||
617 | mouse_drv = MOUSE_MS; | ||
618 | } else if ( SDL_strcmp(proto, "bm") == 0 ) { | ||
619 | mouse_drv = MOUSE_BM; | ||
620 | } else { | ||
621 | /* Unknown protocol... */ | ||
622 | #ifdef DEBUG_MOUSE | ||
623 | fprintf(stderr, "GPM mouse using unknown protocol = %s\n", proto); | ||
624 | #endif | ||
625 | close(mouse_fd); | ||
626 | mouse_fd = -1; | ||
627 | } | ||
628 | } | ||
629 | #ifdef DEBUG_MOUSE | ||
630 | if ( mouse_fd >= 0 ) { | ||
631 | fprintf(stderr, "Using GPM mouse, protocol = %s\n", proto); | ||
632 | } | ||
633 | #endif /* DEBUG_MOUSE */ | ||
634 | } | ||
635 | } | ||
636 | /* Now try to use a modern PS/2 mouse */ | ||
637 | for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) { | ||
638 | mouse_fd = open(ps2mice[i], O_RDWR, 0); | ||
639 | if (mouse_fd < 0) { | ||
640 | mouse_fd = open(ps2mice[i], O_RDONLY, 0); | ||
641 | } | ||
642 | if (mouse_fd >= 0) { | ||
643 | /* rcg06112001 Attempt to set IMPS/2 mode */ | ||
644 | set_imps2_mode(mouse_fd); | ||
645 | if (detect_imps2(mouse_fd)) { | ||
646 | #ifdef DEBUG_MOUSE | ||
647 | fprintf(stderr, "Using IMPS2 mouse\n"); | ||
648 | #endif | ||
649 | mouse_drv = MOUSE_IMPS2; | ||
650 | } else { | ||
651 | #ifdef DEBUG_MOUSE | ||
652 | fprintf(stderr, "Using PS2 mouse\n"); | ||
653 | #endif | ||
654 | mouse_drv = MOUSE_PS2; | ||
655 | } | ||
656 | } | ||
657 | } | ||
658 | /* Next try to use a PPC ADB port mouse */ | ||
659 | if ( mouse_fd < 0 ) { | ||
660 | mouse_fd = open("/dev/adbmouse", O_RDONLY, 0); | ||
661 | if ( mouse_fd >= 0 ) { | ||
662 | #ifdef DEBUG_MOUSE | ||
663 | fprintf(stderr, "Using ADB mouse\n"); | ||
664 | #endif | ||
665 | mouse_drv = MOUSE_BM; | ||
666 | } | ||
667 | } | ||
668 | } | ||
669 | /* Default to a serial Microsoft mouse */ | ||
670 | if ( mouse_fd < 0 ) { | ||
671 | if ( mousedev == NULL ) { | ||
672 | mousedev = "/dev/mouse"; | ||
673 | } | ||
674 | mouse_fd = open(mousedev, O_RDONLY, 0); | ||
675 | if ( mouse_fd >= 0 ) { | ||
676 | struct termios mouse_termios; | ||
677 | |||
678 | /* Set the sampling speed to 1200 baud */ | ||
679 | tcgetattr(mouse_fd, &mouse_termios); | ||
680 | mouse_termios.c_iflag = IGNBRK | IGNPAR; | ||
681 | mouse_termios.c_oflag = 0; | ||
682 | mouse_termios.c_lflag = 0; | ||
683 | mouse_termios.c_line = 0; | ||
684 | mouse_termios.c_cc[VTIME] = 0; | ||
685 | mouse_termios.c_cc[VMIN] = 1; | ||
686 | mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL; | ||
687 | mouse_termios.c_cflag |= CS8; | ||
688 | mouse_termios.c_cflag |= B1200; | ||
689 | tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios); | ||
690 | if ( mousedrv && (SDL_strcmp(mousedrv, "PS2") == 0) ) { | ||
691 | #ifdef DEBUG_MOUSE | ||
692 | fprintf(stderr, "Using (user specified) PS2 mouse on %s\n", mousedev); | ||
693 | #endif | ||
694 | mouse_drv = MOUSE_PS2; | ||
695 | } else { | ||
696 | #ifdef DEBUG_MOUSE | ||
697 | fprintf(stderr, "Using (default) MS mouse on %s\n", mousedev); | ||
698 | #endif | ||
699 | mouse_drv = MOUSE_MS; | ||
700 | } | ||
701 | } | ||
702 | } | ||
703 | if ( mouse_fd < 0 ) { | ||
704 | mouse_drv = MOUSE_NONE; | ||
705 | } | ||
706 | return(mouse_fd); | ||
707 | } | ||
708 | |||
709 | static int posted = 0; | ||
710 | |||
711 | void FB_vgamousecallback(int button, int relative, int dx, int dy) | ||
712 | { | ||
713 | int button_1, button_3; | ||
714 | int button_state; | ||
715 | int state_changed; | ||
716 | int i; | ||
717 | Uint8 state; | ||
718 | |||
719 | if ( dx || dy ) { | ||
720 | posted += SDL_PrivateMouseMotion(0, relative, dx, dy); | ||
721 | } | ||
722 | |||
723 | /* Swap button 1 and 3 */ | ||
724 | button_1 = (button & 0x04) >> 2; | ||
725 | button_3 = (button & 0x01) << 2; | ||
726 | button &= ~0x05; | ||
727 | button |= (button_1|button_3); | ||
728 | |||
729 | /* See what changed */ | ||
730 | button_state = SDL_GetMouseState(NULL, NULL); | ||
731 | state_changed = button_state ^ button; | ||
732 | for ( i=0; i<8; ++i ) { | ||
733 | if ( state_changed & (1<<i) ) { | ||
734 | if ( button & (1<<i) ) { | ||
735 | state = SDL_PRESSED; | ||
736 | } else { | ||
737 | state = SDL_RELEASED; | ||
738 | } | ||
739 | posted += SDL_PrivateMouseButton(state, i+1, 0, 0); | ||
740 | } | ||
741 | } | ||
742 | } | ||
743 | |||
744 | /* Handle input from tslib */ | ||
745 | #if SDL_INPUT_TSLIB | ||
746 | static void handle_tslib(_THIS) | ||
747 | { | ||
748 | struct ts_sample sample; | ||
749 | int button; | ||
750 | |||
751 | while (ts_read(ts_dev, &sample, 1) > 0) { | ||
752 | button = (sample.pressure > 0) ? 1 : 0; | ||
753 | button <<= 2; /* must report it as button 3 */ | ||
754 | FB_vgamousecallback(button, 0, sample.x, sample.y); | ||
755 | } | ||
756 | return; | ||
757 | } | ||
758 | #endif /* SDL_INPUT_TSLIB */ | ||
759 | |||
760 | /* For now, use MSC, PS/2, and MS protocols | ||
761 | Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.) | ||
762 | */ | ||
763 | static void handle_mouse(_THIS) | ||
764 | { | ||
765 | static int start = 0; | ||
766 | static unsigned char mousebuf[BUFSIZ]; | ||
767 | static int relative = 1; | ||
768 | |||
769 | int i, nread; | ||
770 | int button = 0; | ||
771 | int dx = 0, dy = 0; | ||
772 | int packetsize = 0; | ||
773 | int realx, realy; | ||
774 | |||
775 | /* Figure out the mouse packet size */ | ||
776 | switch (mouse_drv) { | ||
777 | case MOUSE_NONE: | ||
778 | break; /* carry on to read from device and discard it. */ | ||
779 | case MOUSE_MSC: | ||
780 | packetsize = 5; | ||
781 | break; | ||
782 | case MOUSE_IMPS2: | ||
783 | packetsize = 4; | ||
784 | break; | ||
785 | case MOUSE_PS2: | ||
786 | case MOUSE_MS: | ||
787 | case MOUSE_BM: | ||
788 | packetsize = 3; | ||
789 | break; | ||
790 | case MOUSE_ELO: | ||
791 | /* try to read the next packet */ | ||
792 | if(eloReadPosition(this, mouse_fd, &dx, &dy, &button, &realx, &realy)) { | ||
793 | button = (button & 0x01) << 2; | ||
794 | FB_vgamousecallback(button, 0, dx, dy); | ||
795 | } | ||
796 | return; /* nothing left to do */ | ||
797 | case MOUSE_TSLIB: | ||
798 | #if SDL_INPUT_TSLIB | ||
799 | handle_tslib(this); | ||
800 | #endif | ||
801 | return; /* nothing left to do */ | ||
802 | default: | ||
803 | /* Uh oh.. */ | ||
804 | packetsize = 0; | ||
805 | break; | ||
806 | } | ||
807 | |||
808 | /* Special handling for the quite sensitive ELO controller */ | ||
809 | if (mouse_drv == MOUSE_ELO) { | ||
810 | |||
811 | } | ||
812 | |||
813 | /* Read as many packets as possible */ | ||
814 | nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start); | ||
815 | if ( nread < 0 ) { | ||
816 | return; | ||
817 | } | ||
818 | |||
819 | if (mouse_drv == MOUSE_NONE) { | ||
820 | return; /* we're done; just draining the input queue. */ | ||
821 | } | ||
822 | |||
823 | nread += start; | ||
824 | #ifdef DEBUG_MOUSE | ||
825 | fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start); | ||
826 | #endif | ||
827 | |||
828 | for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) { | ||
829 | switch (mouse_drv) { | ||
830 | case MOUSE_NONE: /* shouldn't actually hit this. */ | ||
831 | break; /* just throw everything away. */ | ||
832 | case MOUSE_MSC: | ||
833 | /* MSC protocol has 0x80 in high byte */ | ||
834 | if ( (mousebuf[i] & 0xF8) != 0x80 ) { | ||
835 | /* Go to next byte */ | ||
836 | i -= (packetsize-1); | ||
837 | continue; | ||
838 | } | ||
839 | /* Get current mouse state */ | ||
840 | button = (~mousebuf[i]) & 0x07; | ||
841 | dx = (signed char)(mousebuf[i+1]) + | ||
842 | (signed char)(mousebuf[i+3]); | ||
843 | dy = -((signed char)(mousebuf[i+2]) + | ||
844 | (signed char)(mousebuf[i+4])); | ||
845 | break; | ||
846 | case MOUSE_PS2: | ||
847 | /* PS/2 protocol has nothing in high byte */ | ||
848 | if ( (mousebuf[i] & 0xC0) != 0 ) { | ||
849 | /* Go to next byte */ | ||
850 | i -= (packetsize-1); | ||
851 | continue; | ||
852 | } | ||
853 | /* Get current mouse state */ | ||
854 | button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | ||
855 | (mousebuf[i] & 0x02) >> 1 | /*Right*/ | ||
856 | (mousebuf[i] & 0x01) << 2; /*Left*/ | ||
857 | dx = (mousebuf[i] & 0x10) ? | ||
858 | mousebuf[i+1] - 256 : mousebuf[i+1]; | ||
859 | dy = (mousebuf[i] & 0x20) ? | ||
860 | -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | ||
861 | break; | ||
862 | case MOUSE_IMPS2: | ||
863 | /* Get current mouse state */ | ||
864 | button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | ||
865 | (mousebuf[i] & 0x02) >> 1 | /*Right*/ | ||
866 | (mousebuf[i] & 0x01) << 2 | /*Left*/ | ||
867 | (mousebuf[i] & 0x40) >> 3 | /* 4 */ | ||
868 | (mousebuf[i] & 0x80) >> 3; /* 5 */ | ||
869 | dx = (mousebuf[i] & 0x10) ? | ||
870 | mousebuf[i+1] - 256 : mousebuf[i+1]; | ||
871 | dy = (mousebuf[i] & 0x20) ? | ||
872 | -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | ||
873 | switch (mousebuf[i+3]&0x0F) { | ||
874 | case 0x0E: /* DX = +1 */ | ||
875 | case 0x02: /* DX = -1 */ | ||
876 | break; | ||
877 | case 0x0F: /* DY = +1 (map button 4) */ | ||
878 | FB_vgamousecallback(button | (1<<3), | ||
879 | 1, 0, 0); | ||
880 | break; | ||
881 | case 0x01: /* DY = -1 (map button 5) */ | ||
882 | FB_vgamousecallback(button | (1<<4), | ||
883 | 1, 0, 0); | ||
884 | break; | ||
885 | } | ||
886 | break; | ||
887 | case MOUSE_MS: | ||
888 | /* Microsoft protocol has 0x40 in high byte */ | ||
889 | if ( (mousebuf[i] & 0x40) != 0x40 ) { | ||
890 | /* Go to next byte */ | ||
891 | i -= (packetsize-1); | ||
892 | continue; | ||
893 | } | ||
894 | /* Get current mouse state */ | ||
895 | button = ((mousebuf[i] & 0x20) >> 3) | | ||
896 | ((mousebuf[i] & 0x10) >> 4); | ||
897 | dx = (signed char)(((mousebuf[i] & 0x03) << 6) | | ||
898 | (mousebuf[i + 1] & 0x3F)); | ||
899 | dy = (signed char)(((mousebuf[i] & 0x0C) << 4) | | ||
900 | (mousebuf[i + 2] & 0x3F)); | ||
901 | break; | ||
902 | case MOUSE_BM: | ||
903 | /* BusMouse protocol has 0xF8 in high byte */ | ||
904 | if ( (mousebuf[i] & 0xF8) != 0x80 ) { | ||
905 | /* Go to next byte */ | ||
906 | i -= (packetsize-1); | ||
907 | continue; | ||
908 | } | ||
909 | /* Get current mouse state */ | ||
910 | button = (~mousebuf[i]) & 0x07; | ||
911 | dx = (signed char)mousebuf[i+1]; | ||
912 | dy = -(signed char)mousebuf[i+2]; | ||
913 | break; | ||
914 | default: | ||
915 | /* Uh oh.. */ | ||
916 | dx = 0; | ||
917 | dy = 0; | ||
918 | break; | ||
919 | } | ||
920 | FB_vgamousecallback(button, relative, dx, dy); | ||
921 | } | ||
922 | if ( i < nread ) { | ||
923 | SDL_memcpy(mousebuf, &mousebuf[i], (nread-i)); | ||
924 | start = (nread-i); | ||
925 | } else { | ||
926 | start = 0; | ||
927 | } | ||
928 | return; | ||
929 | } | ||
930 | |||
931 | /* Handle switching to another VC, returns when our VC is back */ | ||
932 | static void switch_vt_prep(_THIS) | ||
933 | { | ||
934 | SDL_Surface *screen = SDL_VideoSurface; | ||
935 | |||
936 | SDL_PrivateAppActive(0, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS)); | ||
937 | |||
938 | /* Save the contents of the screen, and go to text mode */ | ||
939 | wait_idle(this); | ||
940 | screen_arealen = ((screen->h + (2*this->offset_y)) * screen->pitch); | ||
941 | screen_contents = (Uint8 *)SDL_malloc(screen_arealen); | ||
942 | if ( screen_contents ) { | ||
943 | SDL_memcpy(screen_contents, screen->pixels, screen_arealen); | ||
944 | } | ||
945 | FB_SavePaletteTo(this, 256, screen_palette); | ||
946 | ioctl(console_fd, FBIOGET_VSCREENINFO, &screen_vinfo); | ||
947 | ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | ||
948 | ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1); | ||
949 | } | ||
950 | static void switch_vt_done(_THIS) | ||
951 | { | ||
952 | SDL_Surface *screen = SDL_VideoSurface; | ||
953 | |||
954 | /* Restore graphics mode and the contents of the screen */ | ||
955 | ioctl(keyboard_fd, VT_LOCKSWITCH, 1); | ||
956 | ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS); | ||
957 | ioctl(console_fd, FBIOPUT_VSCREENINFO, &screen_vinfo); | ||
958 | FB_RestorePaletteFrom(this, 256, screen_palette); | ||
959 | if ( screen_contents ) { | ||
960 | SDL_memcpy(screen->pixels, screen_contents, screen_arealen); | ||
961 | SDL_free(screen_contents); | ||
962 | screen_contents = NULL; | ||
963 | } | ||
964 | |||
965 | /* Get updates to the shadow surface while switched away */ | ||
966 | if ( SDL_ShadowSurface ) { | ||
967 | SDL_UpdateRect(SDL_ShadowSurface, 0, 0, 0, 0); | ||
968 | } | ||
969 | |||
970 | SDL_PrivateAppActive(1, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS)); | ||
971 | } | ||
972 | static void switch_vt(_THIS, unsigned short which) | ||
973 | { | ||
974 | struct vt_stat vtstate; | ||
975 | |||
976 | /* Figure out whether or not we're switching to a new console */ | ||
977 | if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || | ||
978 | (which == vtstate.v_active) ) { | ||
979 | return; | ||
980 | } | ||
981 | |||
982 | /* New console, switch to it */ | ||
983 | SDL_mutexP(hw_lock); | ||
984 | switch_vt_prep(this); | ||
985 | if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { | ||
986 | ioctl(keyboard_fd, VT_WAITACTIVE, which); | ||
987 | switched_away = 1; | ||
988 | } else { | ||
989 | switch_vt_done(this); | ||
990 | } | ||
991 | SDL_mutexV(hw_lock); | ||
992 | } | ||
993 | |||
994 | static void handle_keyboard(_THIS) | ||
995 | { | ||
996 | unsigned char keybuf[BUFSIZ]; | ||
997 | int i, nread; | ||
998 | int pressed; | ||
999 | int scancode; | ||
1000 | SDL_keysym keysym; | ||
1001 | |||
1002 | nread = read(keyboard_fd, keybuf, BUFSIZ); | ||
1003 | for ( i=0; i<nread; ++i ) { | ||
1004 | scancode = keybuf[i] & 0x7F; | ||
1005 | if ( keybuf[i] & 0x80 ) { | ||
1006 | pressed = SDL_RELEASED; | ||
1007 | } else { | ||
1008 | pressed = SDL_PRESSED; | ||
1009 | } | ||
1010 | TranslateKey(scancode, &keysym); | ||
1011 | /* Handle Ctrl-Alt-FN for vt switch */ | ||
1012 | switch (keysym.sym) { | ||
1013 | case SDLK_F1: | ||
1014 | case SDLK_F2: | ||
1015 | case SDLK_F3: | ||
1016 | case SDLK_F4: | ||
1017 | case SDLK_F5: | ||
1018 | case SDLK_F6: | ||
1019 | case SDLK_F7: | ||
1020 | case SDLK_F8: | ||
1021 | case SDLK_F9: | ||
1022 | case SDLK_F10: | ||
1023 | case SDLK_F11: | ||
1024 | case SDLK_F12: | ||
1025 | if ( (SDL_GetModState() & KMOD_CTRL) && | ||
1026 | (SDL_GetModState() & KMOD_ALT) ) { | ||
1027 | if ( pressed ) { | ||
1028 | switch_vt(this, (keysym.sym-SDLK_F1)+1); | ||
1029 | } | ||
1030 | break; | ||
1031 | } | ||
1032 | /* Fall through to normal processing */ | ||
1033 | default: | ||
1034 | posted += SDL_PrivateKeyboard(pressed, &keysym); | ||
1035 | break; | ||
1036 | } | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | void FB_PumpEvents(_THIS) | ||
1041 | { | ||
1042 | fd_set fdset; | ||
1043 | int max_fd; | ||
1044 | static struct timeval zero; | ||
1045 | |||
1046 | do { | ||
1047 | if ( switched_away ) { | ||
1048 | struct vt_stat vtstate; | ||
1049 | |||
1050 | SDL_mutexP(hw_lock); | ||
1051 | if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0) && | ||
1052 | vtstate.v_active == current_vt ) { | ||
1053 | switched_away = 0; | ||
1054 | switch_vt_done(this); | ||
1055 | } | ||
1056 | SDL_mutexV(hw_lock); | ||
1057 | } | ||
1058 | |||
1059 | posted = 0; | ||
1060 | |||
1061 | FD_ZERO(&fdset); | ||
1062 | max_fd = 0; | ||
1063 | if ( keyboard_fd >= 0 ) { | ||
1064 | FD_SET(keyboard_fd, &fdset); | ||
1065 | if ( max_fd < keyboard_fd ) { | ||
1066 | max_fd = keyboard_fd; | ||
1067 | } | ||
1068 | } | ||
1069 | if ( mouse_fd >= 0 ) { | ||
1070 | FD_SET(mouse_fd, &fdset); | ||
1071 | if ( max_fd < mouse_fd ) { | ||
1072 | max_fd = mouse_fd; | ||
1073 | } | ||
1074 | } | ||
1075 | if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) { | ||
1076 | if ( keyboard_fd >= 0 ) { | ||
1077 | if ( FD_ISSET(keyboard_fd, &fdset) ) { | ||
1078 | handle_keyboard(this); | ||
1079 | } | ||
1080 | } | ||
1081 | if ( mouse_fd >= 0 ) { | ||
1082 | if ( FD_ISSET(mouse_fd, &fdset) ) { | ||
1083 | handle_mouse(this); | ||
1084 | } | ||
1085 | } | ||
1086 | } | ||
1087 | } while ( posted ); | ||
1088 | } | ||
1089 | |||
1090 | void FB_InitOSKeymap(_THIS) | ||
1091 | { | ||
1092 | int i; | ||
1093 | |||
1094 | /* Initialize the Linux key translation table */ | ||
1095 | |||
1096 | /* First get the ascii keys and others not well handled */ | ||
1097 | for (i=0; i<SDL_arraysize(keymap); ++i) { | ||
1098 | switch(i) { | ||
1099 | /* These aren't handled by the x86 kernel keymapping (?) */ | ||
1100 | case SCANCODE_PRINTSCREEN: | ||
1101 | keymap[i] = SDLK_PRINT; | ||
1102 | break; | ||
1103 | case SCANCODE_BREAK: | ||
1104 | keymap[i] = SDLK_BREAK; | ||
1105 | break; | ||
1106 | case SCANCODE_BREAK_ALTERNATIVE: | ||
1107 | keymap[i] = SDLK_PAUSE; | ||
1108 | break; | ||
1109 | case SCANCODE_LEFTSHIFT: | ||
1110 | keymap[i] = SDLK_LSHIFT; | ||
1111 | break; | ||
1112 | case SCANCODE_RIGHTSHIFT: | ||
1113 | keymap[i] = SDLK_RSHIFT; | ||
1114 | break; | ||
1115 | case SCANCODE_LEFTCONTROL: | ||
1116 | keymap[i] = SDLK_LCTRL; | ||
1117 | break; | ||
1118 | case SCANCODE_RIGHTCONTROL: | ||
1119 | keymap[i] = SDLK_RCTRL; | ||
1120 | break; | ||
1121 | case SCANCODE_RIGHTWIN: | ||
1122 | keymap[i] = SDLK_RSUPER; | ||
1123 | break; | ||
1124 | case SCANCODE_LEFTWIN: | ||
1125 | keymap[i] = SDLK_LSUPER; | ||
1126 | break; | ||
1127 | case SCANCODE_LEFTALT: | ||
1128 | keymap[i] = SDLK_LALT; | ||
1129 | break; | ||
1130 | case SCANCODE_RIGHTALT: | ||
1131 | keymap[i] = SDLK_RALT; | ||
1132 | break; | ||
1133 | case 127: | ||
1134 | keymap[i] = SDLK_MENU; | ||
1135 | break; | ||
1136 | /* this should take care of all standard ascii keys */ | ||
1137 | default: | ||
1138 | keymap[i] = KVAL(vga_keymap[0][i]); | ||
1139 | break; | ||
1140 | } | ||
1141 | } | ||
1142 | for (i=0; i<SDL_arraysize(keymap); ++i) { | ||
1143 | switch(keymap_temp[i]) { | ||
1144 | case K_F1: keymap[i] = SDLK_F1; break; | ||
1145 | case K_F2: keymap[i] = SDLK_F2; break; | ||
1146 | case K_F3: keymap[i] = SDLK_F3; break; | ||
1147 | case K_F4: keymap[i] = SDLK_F4; break; | ||
1148 | case K_F5: keymap[i] = SDLK_F5; break; | ||
1149 | case K_F6: keymap[i] = SDLK_F6; break; | ||
1150 | case K_F7: keymap[i] = SDLK_F7; break; | ||
1151 | case K_F8: keymap[i] = SDLK_F8; break; | ||
1152 | case K_F9: keymap[i] = SDLK_F9; break; | ||
1153 | case K_F10: keymap[i] = SDLK_F10; break; | ||
1154 | case K_F11: keymap[i] = SDLK_F11; break; | ||
1155 | case K_F12: keymap[i] = SDLK_F12; break; | ||
1156 | |||
1157 | case K_DOWN: keymap[i] = SDLK_DOWN; break; | ||
1158 | case K_LEFT: keymap[i] = SDLK_LEFT; break; | ||
1159 | case K_RIGHT: keymap[i] = SDLK_RIGHT; break; | ||
1160 | case K_UP: keymap[i] = SDLK_UP; break; | ||
1161 | |||
1162 | case K_P0: keymap[i] = SDLK_KP0; break; | ||
1163 | case K_P1: keymap[i] = SDLK_KP1; break; | ||
1164 | case K_P2: keymap[i] = SDLK_KP2; break; | ||
1165 | case K_P3: keymap[i] = SDLK_KP3; break; | ||
1166 | case K_P4: keymap[i] = SDLK_KP4; break; | ||
1167 | case K_P5: keymap[i] = SDLK_KP5; break; | ||
1168 | case K_P6: keymap[i] = SDLK_KP6; break; | ||
1169 | case K_P7: keymap[i] = SDLK_KP7; break; | ||
1170 | case K_P8: keymap[i] = SDLK_KP8; break; | ||
1171 | case K_P9: keymap[i] = SDLK_KP9; break; | ||
1172 | case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break; | ||
1173 | case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break; | ||
1174 | case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break; | ||
1175 | case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break; | ||
1176 | case K_PENTER: keymap[i] = SDLK_KP_ENTER; break; | ||
1177 | case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break; | ||
1178 | |||
1179 | case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT ) | ||
1180 | keymap[i] = SDLK_LSHIFT; | ||
1181 | break; | ||
1182 | case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break; | ||
1183 | case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break; | ||
1184 | case K_CTRL: if ( keymap[i] != SDLK_RCTRL ) | ||
1185 | keymap[i] = SDLK_LCTRL; | ||
1186 | break; | ||
1187 | case K_CTRLL: keymap[i] = SDLK_LCTRL; break; | ||
1188 | case K_CTRLR: keymap[i] = SDLK_RCTRL; break; | ||
1189 | case K_ALT: keymap[i] = SDLK_LALT; break; | ||
1190 | case K_ALTGR: keymap[i] = SDLK_RALT; break; | ||
1191 | |||
1192 | case K_INSERT: keymap[i] = SDLK_INSERT; break; | ||
1193 | case K_REMOVE: keymap[i] = SDLK_DELETE; break; | ||
1194 | case K_PGUP: keymap[i] = SDLK_PAGEUP; break; | ||
1195 | case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break; | ||
1196 | case K_FIND: keymap[i] = SDLK_HOME; break; | ||
1197 | case K_SELECT: keymap[i] = SDLK_END; break; | ||
1198 | |||
1199 | case K_NUM: keymap[i] = SDLK_NUMLOCK; break; | ||
1200 | case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break; | ||
1201 | |||
1202 | case K_F13: keymap[i] = SDLK_PRINT; break; | ||
1203 | case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break; | ||
1204 | case K_PAUSE: keymap[i] = SDLK_PAUSE; break; | ||
1205 | |||
1206 | case 127: keymap[i] = SDLK_BACKSPACE; break; | ||
1207 | |||
1208 | default: break; | ||
1209 | } | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) | ||
1214 | { | ||
1215 | /* Set the keysym information */ | ||
1216 | keysym->scancode = scancode; | ||
1217 | keysym->sym = keymap[scancode]; | ||
1218 | keysym->mod = KMOD_NONE; | ||
1219 | |||
1220 | /* If UNICODE is on, get the UNICODE value for the key */ | ||
1221 | keysym->unicode = 0; | ||
1222 | if ( SDL_TranslateUNICODE ) { | ||
1223 | int map; | ||
1224 | SDLMod modstate; | ||
1225 | |||
1226 | modstate = SDL_GetModState(); | ||
1227 | map = 0; | ||
1228 | if ( modstate & KMOD_SHIFT ) { | ||
1229 | map |= (1<<KG_SHIFT); | ||
1230 | } | ||
1231 | if ( modstate & KMOD_CTRL ) { | ||
1232 | map |= (1<<KG_CTRL); | ||
1233 | } | ||
1234 | if ( modstate & KMOD_LALT ) { | ||
1235 | map |= (1<<KG_ALT); | ||
1236 | } | ||
1237 | if ( modstate & KMOD_RALT ) { | ||
1238 | map |= (1<<KG_ALTGR); | ||
1239 | } | ||
1240 | if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { | ||
1241 | if ( modstate & KMOD_CAPS ) { | ||
1242 | map ^= (1<<KG_SHIFT); | ||
1243 | } | ||
1244 | } | ||
1245 | if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) { | ||
1246 | if ( modstate & KMOD_NUM ) { | ||
1247 | keysym->unicode=KVAL(vga_keymap[map][scancode]); | ||
1248 | } | ||
1249 | } else { | ||
1250 | keysym->unicode = KVAL(vga_keymap[map][scancode]); | ||
1251 | } | ||
1252 | } | ||
1253 | return(keysym); | ||
1254 | } | ||