Mercurial > sdl-ios-xcode
annotate src/video/fbcon/SDL_fbevents.c @ 821:30168104389f
Date: Sat, 14 Feb 2004 14:52:40 +0200
From: "Mike Gorchak"
Subject: Batch of the QNX6 fixes for the SDL
1. Updated readme.QNX
2. Fixed crashes during intensive window updating under fast machines (got over 200 rectangles for update).
3. Fixed double-buffered fullscreen modes, now it works as needed.
4. Fixed Photon detection algorithm.
5. Fixed HWSURFACE update function.
6. Added SDL_PHOTON_FULLSCREEN_REFRESH environment variable support for control refresh rates under Photon.
7. Added 640x400 fullscreen mode emulation via 640x480 (if videodriver not supports original 640x400 mode of course) shifted by 40 vertical pixels from begin, to center it. It's needed for some old DOS games which ran in doubled 320x200 mode.
8. Added available video ram amount support.
8. Added hardware surface allocation/deallocation support if current videomode and videodriver supports it.
9. Added hardware filling support.
10. Added hardware blits support (simple and colorkeyed).
And I've added to testvidinfo test color-keyed blits benchmark (maybe need to add alpha blits benchmark too ?). Currently Photon not supporting any alpha hardware blittings (all drivers lack of alpha blitting code support, only software alpha blitting exist in photon, which is hundreds times slowest than the SDL's one). So I've not added the alpha support. I suppose new QNX 6.3 will have the hardware alpha support, so when it will be done, I'll add alpha support.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 14 Feb 2004 20:22:21 +0000 |
parents | b8d311d90021 |
children | 3d4f1930ed02 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 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 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
132
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Handle the event stream, converting console events into SDL events */ | |
29 | |
30 #include <sys/types.h> | |
31 #include <sys/time.h> | |
32 #include <sys/ioctl.h> | |
33 #include <stdlib.h> | |
34 #include <stdio.h> | |
35 #include <unistd.h> | |
36 #include <fcntl.h> | |
37 #include <string.h> | |
38 #include <errno.h> | |
39 #include <limits.h> | |
40 | |
41 /* For parsing /proc */ | |
42 #include <dirent.h> | |
43 #include <ctype.h> | |
44 | |
45 #include <linux/vt.h> | |
46 #include <linux/kd.h> | |
47 #include <linux/keyboard.h> | |
48 | |
49 #include "SDL.h" | |
50 #include "SDL_mutex.h" | |
51 #include "SDL_sysevents.h" | |
52 #include "SDL_sysvideo.h" | |
53 #include "SDL_events_c.h" | |
54 #include "SDL_fbvideo.h" | |
55 #include "SDL_fbevents_c.h" | |
56 #include "SDL_fbkeys.h" | |
57 | |
58 #include "SDL_fbelo.h" | |
59 | |
60 #ifndef GPM_NODE_FIFO | |
61 #define GPM_NODE_FIFO "/dev/gpmdata" | |
62 #endif | |
63 | |
64 | |
65 /* The translation tables from a console scancode to a SDL keysym */ | |
66 #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) | |
67 static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; | |
68 static SDLKey keymap[128]; | |
69 static Uint16 keymap_temp[128]; /* only used at startup */ | |
70 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); | |
71 | |
72 /* Ugh, we have to duplicate the kernel's keysym mapping code... | |
73 Oh, it's not so bad. :-) | |
74 | |
75 FIXME: Add keyboard LED handling code | |
76 */ | |
77 static void FB_vgainitkeymaps(int fd) | |
78 { | |
79 struct kbentry entry; | |
80 int map, i; | |
81 | |
82 /* Don't do anything if we are passed a closed keyboard */ | |
83 if ( fd < 0 ) { | |
84 return; | |
85 } | |
86 | |
87 /* Load all the keysym mappings */ | |
88 for ( map=0; map<NUM_VGAKEYMAPS; ++map ) { | |
89 memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16)); | |
90 for ( i=0; i<NR_KEYS; ++i ) { | |
91 entry.kb_table = map; | |
92 entry.kb_index = i; | |
93 if ( ioctl(fd, KDGKBENT, &entry) == 0 ) { | |
94 /* fill keytemp. This replaces SDL_fbkeys.h */ | |
95 if ( (map == 0) && (i<128) ) { | |
96 keymap_temp[i] = entry.kb_value; | |
97 } | |
98 /* The "Enter" key is a special case */ | |
99 if ( entry.kb_value == K_ENTER ) { | |
100 entry.kb_value = K(KT_ASCII,13); | |
101 } | |
102 /* Handle numpad specially as well */ | |
103 if ( KTYP(entry.kb_value) == KT_PAD ) { | |
104 switch ( entry.kb_value ) { | |
105 case K_P0: | |
106 case K_P1: | |
107 case K_P2: | |
108 case K_P3: | |
109 case K_P4: | |
110 case K_P5: | |
111 case K_P6: | |
112 case K_P7: | |
113 case K_P8: | |
114 case K_P9: | |
115 vga_keymap[map][i]=entry.kb_value; | |
116 vga_keymap[map][i]+= '0'; | |
117 break; | |
118 case K_PPLUS: | |
119 vga_keymap[map][i]=K(KT_ASCII,'+'); | |
120 break; | |
121 case K_PMINUS: | |
122 vga_keymap[map][i]=K(KT_ASCII,'-'); | |
123 break; | |
124 case K_PSTAR: | |
125 vga_keymap[map][i]=K(KT_ASCII,'*'); | |
126 break; | |
127 case K_PSLASH: | |
128 vga_keymap[map][i]=K(KT_ASCII,'/'); | |
129 break; | |
130 case K_PENTER: | |
131 vga_keymap[map][i]=K(KT_ASCII,'\r'); | |
132 break; | |
133 case K_PCOMMA: | |
134 vga_keymap[map][i]=K(KT_ASCII,','); | |
135 break; | |
136 case K_PDOT: | |
137 vga_keymap[map][i]=K(KT_ASCII,'.'); | |
138 break; | |
139 default: | |
140 break; | |
141 } | |
142 } | |
143 /* Do the normal key translation */ | |
144 if ( (KTYP(entry.kb_value) == KT_LATIN) || | |
145 (KTYP(entry.kb_value) == KT_ASCII) || | |
146 (KTYP(entry.kb_value) == KT_LETTER) ) { | |
147 vga_keymap[map][i] = entry.kb_value; | |
148 } | |
149 } | |
150 } | |
151 } | |
152 } | |
153 | |
154 int FB_InGraphicsMode(_THIS) | |
155 { | |
156 return((keyboard_fd >= 0) && (saved_kbd_mode >= 0)); | |
157 } | |
158 | |
159 int FB_EnterGraphicsMode(_THIS) | |
160 { | |
161 struct termios keyboard_termios; | |
162 | |
163 /* Set medium-raw keyboard mode */ | |
164 if ( (keyboard_fd >= 0) && !FB_InGraphicsMode(this) ) { | |
165 | |
166 /* Switch to the correct virtual terminal */ | |
167 if ( current_vt > 0 ) { | |
168 struct vt_stat vtstate; | |
169 | |
170 if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) { | |
171 saved_vt = vtstate.v_active; | |
172 } | |
173 if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) { | |
174 ioctl(keyboard_fd, VT_WAITACTIVE, current_vt); | |
175 } | |
176 } | |
177 | |
178 /* Set the terminal input mode */ | |
179 if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) { | |
180 SDL_SetError("Unable to get terminal attributes"); | |
181 if ( keyboard_fd > 0 ) { | |
182 close(keyboard_fd); | |
183 } | |
184 keyboard_fd = -1; | |
185 return(-1); | |
186 } | |
187 if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) { | |
188 SDL_SetError("Unable to get current keyboard mode"); | |
189 if ( keyboard_fd > 0 ) { | |
190 close(keyboard_fd); | |
191 } | |
192 keyboard_fd = -1; | |
193 return(-1); | |
194 } | |
195 keyboard_termios = saved_kbd_termios; | |
196 keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG); | |
197 keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); | |
198 keyboard_termios.c_cc[VMIN] = 0; | |
199 keyboard_termios.c_cc[VTIME] = 0; | |
200 if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) { | |
201 FB_CloseKeyboard(this); | |
202 SDL_SetError("Unable to set terminal attributes"); | |
203 return(-1); | |
204 } | |
205 /* This will fail if we aren't root or this isn't our tty */ | |
206 if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) { | |
207 FB_CloseKeyboard(this); | |
208 SDL_SetError("Unable to set keyboard in raw mode"); | |
209 return(-1); | |
210 } | |
211 if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { | |
212 FB_CloseKeyboard(this); | |
213 SDL_SetError("Unable to set keyboard in graphics mode"); | |
214 return(-1); | |
215 } | |
216 } | |
217 return(keyboard_fd); | |
218 } | |
219 | |
220 void FB_LeaveGraphicsMode(_THIS) | |
221 { | |
222 if ( FB_InGraphicsMode(this) ) { | |
223 ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | |
224 ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); | |
225 tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); | |
226 saved_kbd_mode = -1; | |
227 | |
228 /* Head back over to the original virtual terminal */ | |
229 if ( saved_vt > 0 ) { | |
230 ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); | |
231 } | |
232 } | |
233 } | |
234 | |
235 void FB_CloseKeyboard(_THIS) | |
236 { | |
237 if ( keyboard_fd >= 0 ) { | |
238 FB_LeaveGraphicsMode(this); | |
239 if ( keyboard_fd > 0 ) { | |
240 close(keyboard_fd); | |
241 } | |
242 } | |
243 keyboard_fd = -1; | |
244 } | |
245 | |
246 int FB_OpenKeyboard(_THIS) | |
247 { | |
248 /* Open only if not already opened */ | |
249 if ( keyboard_fd < 0 ) { | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
69
diff
changeset
|
250 static const char * const tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; |
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
69
diff
changeset
|
251 static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; |
0 | 252 int i, tty0_fd; |
253 | |
254 /* Try to query for a free virtual terminal */ | |
255 tty0_fd = -1; | |
256 for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) { | |
257 tty0_fd = open(tty0[i], O_WRONLY, 0); | |
258 } | |
259 if ( tty0_fd < 0 ) { | |
260 tty0_fd = dup(0); /* Maybe stdin is a VT? */ | |
261 } | |
262 ioctl(tty0_fd, VT_OPENQRY, ¤t_vt); | |
263 close(tty0_fd); | |
264 if ( (geteuid() == 0) && (current_vt > 0) ) { | |
265 for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) { | |
266 char vtpath[12]; | |
267 | |
268 sprintf(vtpath, vcs[i], current_vt); | |
269 keyboard_fd = open(vtpath, O_RDWR, 0); | |
270 #ifdef DEBUG_KEYBOARD | |
271 fprintf(stderr, "vtpath = %s, fd = %d\n", | |
272 vtpath, keyboard_fd); | |
273 #endif /* DEBUG_KEYBOARD */ | |
274 | |
275 /* This needs to be our controlling tty | |
276 so that the kernel ioctl() calls work | |
277 */ | |
278 if ( keyboard_fd >= 0 ) { | |
279 tty0_fd = open("/dev/tty", O_RDWR, 0); | |
280 if ( tty0_fd >= 0 ) { | |
281 ioctl(tty0_fd, TIOCNOTTY, 0); | |
282 close(tty0_fd); | |
283 } | |
284 } | |
285 } | |
286 } | |
287 if ( keyboard_fd < 0 ) { | |
288 /* Last resort, maybe our tty is a usable VT */ | |
289 current_vt = 0; | |
290 keyboard_fd = open("/dev/tty", O_RDWR); | |
291 } | |
292 #ifdef DEBUG_KEYBOARD | |
293 fprintf(stderr, "Current VT: %d\n", current_vt); | |
294 #endif | |
295 saved_kbd_mode = -1; | |
296 | |
297 /* Make sure that our input is a console terminal */ | |
298 { int dummy; | |
299 if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) { | |
300 close(keyboard_fd); | |
301 keyboard_fd = -1; | |
302 SDL_SetError("Unable to open a console terminal"); | |
303 } | |
304 } | |
305 | |
306 /* Set up keymap */ | |
307 FB_vgainitkeymaps(keyboard_fd); | |
308 } | |
309 return(keyboard_fd); | |
310 } | |
311 | |
312 static enum { | |
313 MOUSE_NONE = -1, | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
314 MOUSE_MSC, /* Note: GPM uses the MSC protocol */ |
0 | 315 MOUSE_PS2, |
316 MOUSE_IMPS2, | |
317 MOUSE_MS, | |
318 MOUSE_BM, | |
319 MOUSE_ELO, | |
320 NUM_MOUSE_DRVS | |
321 } mouse_drv = MOUSE_NONE; | |
322 | |
323 void FB_CloseMouse(_THIS) | |
324 { | |
325 if ( mouse_fd > 0 ) { | |
326 close(mouse_fd); | |
327 } | |
328 mouse_fd = -1; | |
329 } | |
330 | |
331 /* Returns processes listed in /proc with the desired name */ | |
332 static int find_pid(DIR *proc, const char *wanted_name) | |
333 { | |
334 struct dirent *entry; | |
335 int pid; | |
336 | |
337 /* First scan proc for the gpm process */ | |
338 pid = 0; | |
339 while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) { | |
340 if ( isdigit(entry->d_name[0]) ) { | |
341 FILE *status; | |
342 char path[PATH_MAX]; | |
343 char name[PATH_MAX]; | |
344 | |
345 sprintf(path, "/proc/%s/status", entry->d_name); | |
346 status=fopen(path, "r"); | |
347 if ( status ) { | |
348 name[0] = '\0'; | |
349 fscanf(status, "Name: %s", name); | |
350 if ( strcmp(name, wanted_name) == 0 ) { | |
351 pid = atoi(entry->d_name); | |
352 } | |
353 fclose(status); | |
354 } | |
355 } | |
356 } | |
357 return pid; | |
358 } | |
359 | |
360 /* Returns true if /dev/gpmdata is being written to by gpm */ | |
361 static int gpm_available(void) | |
362 { | |
363 int available; | |
364 DIR *proc; | |
365 int pid; | |
366 int cmdline, len, arglen; | |
367 char path[PATH_MAX]; | |
368 char args[PATH_MAX], *arg; | |
369 | |
370 /* Don't bother looking if the fifo isn't there */ | |
371 if ( access(GPM_NODE_FIFO, F_OK) < 0 ) { | |
372 return(0); | |
373 } | |
374 | |
375 available = 0; | |
376 proc = opendir("/proc"); | |
377 if ( proc ) { | |
378 while ( (pid=find_pid(proc, "gpm")) > 0 ) { | |
379 sprintf(path, "/proc/%d/cmdline", pid); | |
380 cmdline = open(path, O_RDONLY, 0); | |
381 if ( cmdline >= 0 ) { | |
382 len = read(cmdline, args, sizeof(args)); | |
383 arg = args; | |
384 while ( len > 0 ) { | |
385 if ( strcmp(arg, "-R") == 0 ) { | |
386 available = 1; | |
387 } | |
388 arglen = strlen(arg)+1; | |
389 len -= arglen; | |
390 arg += arglen; | |
391 } | |
392 close(cmdline); | |
393 } | |
394 } | |
395 closedir(proc); | |
396 } | |
397 return available; | |
398 } | |
399 | |
59 | 400 |
401 /* rcg06112001 Set up IMPS/2 mode, if possible. This gives | |
402 * us access to the mousewheel, etc. Returns zero if | |
403 * writes to device failed, but you still need to query the | |
404 * device to see which mode it's actually in. | |
405 */ | |
406 static int set_imps2_mode(int fd) | |
407 { | |
408 /* If you wanted to control the mouse mode (and we do :) ) ... | |
409 Set IMPS/2 protocol: | |
410 {0xf3,200,0xf3,100,0xf3,80} | |
411 Reset mouse device: | |
412 {0xFF} | |
413 */ | |
414 Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; | |
415 Uint8 reset = 0xff; | |
416 fd_set fdset; | |
417 struct timeval tv; | |
418 int retval = 0; | |
419 | |
420 if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { | |
421 if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) { | |
422 retval = 1; | |
423 } | |
424 } | |
425 | |
426 /* Get rid of any chatter from the above */ | |
427 FD_ZERO(&fdset); | |
428 FD_SET(fd, &fdset); | |
429 tv.tv_sec = 0; | |
430 tv.tv_usec = 0; | |
431 while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | |
432 char temp[32]; | |
433 read(fd, temp, sizeof(temp)); | |
434 } | |
435 | |
436 return retval; | |
437 } | |
438 | |
439 | |
0 | 440 /* Returns true if the mouse uses the IMPS/2 protocol */ |
441 static int detect_imps2(int fd) | |
442 { | |
443 int imps2; | |
444 | |
445 imps2 = 0; | |
59 | 446 |
0 | 447 if ( getenv("SDL_MOUSEDEV_IMPS2") ) { |
448 imps2 = 1; | |
449 } | |
450 if ( ! imps2 ) { | |
59 | 451 Uint8 query_ps2 = 0xF2; |
0 | 452 fd_set fdset; |
453 struct timeval tv; | |
454 | |
455 /* Get rid of any mouse motion noise */ | |
456 FD_ZERO(&fdset); | |
457 FD_SET(fd, &fdset); | |
458 tv.tv_sec = 0; | |
459 tv.tv_usec = 0; | |
460 while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | |
461 char temp[32]; | |
462 read(fd, temp, sizeof(temp)); | |
463 } | |
464 | |
59 | 465 /* Query for the type of mouse protocol */ |
466 if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) { | |
467 Uint8 ch = 0; | |
0 | 468 |
469 /* Get the mouse protocol response */ | |
470 do { | |
471 FD_ZERO(&fdset); | |
472 FD_SET(fd, &fdset); | |
473 tv.tv_sec = 1; | |
474 tv.tv_usec = 0; | |
475 if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) { | |
476 break; | |
477 } | |
59 | 478 } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) && |
0 | 479 ((ch == 0xFA) || (ch == 0xAA)) ); |
480 | |
481 /* Experimental values (Logitech wheelmouse) */ | |
482 #ifdef DEBUG_MOUSE | |
483 fprintf(stderr, "Last mouse mode: 0x%x\n", ch); | |
484 #endif | |
104
a746656b7599
Detect more types of IMPS/2 mouse
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
485 if ( (ch == 3) || (ch == 4) ) { |
0 | 486 imps2 = 1; |
487 } | |
488 } | |
489 } | |
490 return imps2; | |
491 } | |
492 | |
493 int FB_OpenMouse(_THIS) | |
494 { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
495 int i; |
0 | 496 const char *mousedev; |
497 const char *mousedrv; | |
498 | |
499 mousedrv = getenv("SDL_MOUSEDRV"); | |
500 mousedev = getenv("SDL_MOUSEDEV"); | |
501 mouse_fd = -1; | |
502 | |
503 /* ELO TOUCHSCREEN SUPPORT */ | |
504 | |
505 if( (mousedrv != NULL) && (strcmp(mousedrv, "ELO") == 0) ) { | |
506 mouse_fd = open(mousedev, O_RDWR); | |
507 if ( mouse_fd >= 0 ) { | |
508 if(eloInitController(mouse_fd)) { | |
509 #ifdef DEBUG_MOUSE | |
510 fprintf(stderr, "Using ELO touchscreen\n"); | |
511 #endif | |
512 mouse_drv = MOUSE_ELO; | |
513 } | |
514 | |
515 } | |
516 else if ( mouse_fd < 0 ) { | |
517 mouse_drv = MOUSE_NONE; | |
518 } | |
519 | |
520 return(mouse_fd); | |
521 } | |
522 | |
523 /* STD MICE */ | |
524 | |
525 if ( mousedev == NULL ) { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
526 /* FIXME someday... allow multiple mice in this driver */ |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
69
diff
changeset
|
527 static const char * const ps2mice[] = { |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
528 "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
529 }; |
0 | 530 /* First try to use GPM in repeater mode */ |
531 if ( mouse_fd < 0 ) { | |
532 if ( gpm_available() ) { | |
533 mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); | |
534 if ( mouse_fd >= 0 ) { | |
535 #ifdef DEBUG_MOUSE | |
536 fprintf(stderr, "Using GPM mouse\n"); | |
537 #endif | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
538 mouse_drv = MOUSE_MSC; |
0 | 539 } |
540 } | |
541 } | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
542 /* Now try to use a modern PS/2 mouse */ |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
543 for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) { |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
544 mouse_fd = open(ps2mice[i], O_RDWR, 0); |
59 | 545 if (mouse_fd < 0) { |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
546 mouse_fd = open(ps2mice[i], O_RDONLY, 0); |
59 | 547 } |
548 if (mouse_fd >= 0) { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
549 /* rcg06112001 Attempt to set IMPS/2 mode */ |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
550 if ( i == 0 ) { |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
551 set_imps2_mode(mouse_fd); |
59 | 552 } |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
553 if (detect_imps2(mouse_fd)) { |
0 | 554 #ifdef DEBUG_MOUSE |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
555 fprintf(stderr, "Using IMPS2 mouse\n"); |
0 | 556 #endif |
557 mouse_drv = MOUSE_IMPS2; | |
558 } else { | |
559 #ifdef DEBUG_MOUSE | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
560 fprintf(stderr, "Using PS2 mouse\n"); |
0 | 561 #endif |
562 mouse_drv = MOUSE_PS2; | |
563 } | |
564 } | |
565 } | |
566 /* Next try to use a PPC ADB port mouse */ | |
567 if ( mouse_fd < 0 ) { | |
568 mouse_fd = open("/dev/adbmouse", O_RDONLY, 0); | |
569 if ( mouse_fd >= 0 ) { | |
570 #ifdef DEBUG_MOUSE | |
571 fprintf(stderr, "Using ADB mouse\n"); | |
572 #endif | |
573 mouse_drv = MOUSE_BM; | |
574 } | |
575 } | |
576 } | |
577 /* Default to a serial Microsoft mouse */ | |
578 if ( mouse_fd < 0 ) { | |
579 if ( mousedev == NULL ) { | |
580 mousedev = "/dev/mouse"; | |
581 } | |
582 mouse_fd = open(mousedev, O_RDONLY, 0); | |
583 if ( mouse_fd >= 0 ) { | |
584 struct termios mouse_termios; | |
585 | |
586 /* Set the sampling speed to 1200 baud */ | |
587 tcgetattr(mouse_fd, &mouse_termios); | |
588 mouse_termios.c_iflag = IGNBRK | IGNPAR; | |
589 mouse_termios.c_oflag = 0; | |
590 mouse_termios.c_lflag = 0; | |
591 mouse_termios.c_line = 0; | |
592 mouse_termios.c_cc[VTIME] = 0; | |
593 mouse_termios.c_cc[VMIN] = 1; | |
594 mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL; | |
595 mouse_termios.c_cflag |= CS8; | |
596 mouse_termios.c_cflag |= B1200; | |
597 tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios); | |
598 #ifdef DEBUG_MOUSE | |
599 fprintf(stderr, "Using Microsoft mouse on %s\n", mousedev); | |
600 #endif | |
601 mouse_drv = MOUSE_MS; | |
602 } | |
603 } | |
604 if ( mouse_fd < 0 ) { | |
605 mouse_drv = MOUSE_NONE; | |
606 } | |
607 return(mouse_fd); | |
608 } | |
609 | |
610 static int posted = 0; | |
611 | |
612 void FB_vgamousecallback(int button, int relative, int dx, int dy) | |
613 { | |
614 int button_1, button_3; | |
615 int button_state; | |
616 int state_changed; | |
617 int i; | |
618 Uint8 state; | |
619 | |
620 if ( dx || dy ) { | |
621 posted += SDL_PrivateMouseMotion(0, relative, dx, dy); | |
622 } | |
623 | |
624 /* Swap button 1 and 3 */ | |
625 button_1 = (button & 0x04) >> 2; | |
626 button_3 = (button & 0x01) << 2; | |
627 button &= ~0x05; | |
628 button |= (button_1|button_3); | |
629 | |
630 /* See what changed */ | |
631 button_state = SDL_GetMouseState(NULL, NULL); | |
632 state_changed = button_state ^ button; | |
633 for ( i=0; i<8; ++i ) { | |
634 if ( state_changed & (1<<i) ) { | |
635 if ( button & (1<<i) ) { | |
636 state = SDL_PRESSED; | |
637 } else { | |
638 state = SDL_RELEASED; | |
639 } | |
640 posted += SDL_PrivateMouseButton(state, i+1, 0, 0); | |
641 } | |
642 } | |
643 } | |
644 | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
645 /* For now, use MSC, PS/2, and MS protocols |
0 | 646 Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.) |
647 */ | |
648 static void handle_mouse(_THIS) | |
649 { | |
650 static int start = 0; | |
651 static unsigned char mousebuf[BUFSIZ]; | |
652 static int relative = 1; | |
653 | |
654 int i, nread; | |
655 int button = 0; | |
656 int dx = 0, dy = 0; | |
657 int packetsize = 0; | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
658 int realx, realy; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
659 |
0 | 660 /* Figure out the mouse packet size */ |
661 switch (mouse_drv) { | |
662 case MOUSE_NONE: | |
663 /* Ack! */ | |
664 read(mouse_fd, mousebuf, BUFSIZ); | |
665 return; | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
666 case MOUSE_MSC: |
0 | 667 packetsize = 5; |
668 break; | |
669 case MOUSE_IMPS2: | |
670 packetsize = 4; | |
671 break; | |
672 case MOUSE_PS2: | |
673 case MOUSE_MS: | |
674 case MOUSE_BM: | |
675 packetsize = 3; | |
676 break; | |
677 case MOUSE_ELO: | |
678 packetsize = ELO_PACKET_SIZE; | |
679 relative = 0; | |
680 break; | |
681 case NUM_MOUSE_DRVS: | |
682 /* Uh oh.. */ | |
683 packetsize = 0; | |
684 break; | |
685 } | |
686 | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
687 /* Special handling for the quite sensitive ELO controller */ |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
688 if (mouse_drv == MOUSE_ELO) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
689 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
690 /* try to read the next packet */ |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
691 if(eloReadPosition(this, mouse_fd, &dx, &dy, &button, &realx, &realy)) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
692 button = (button & 0x01) << 2; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
693 FB_vgamousecallback(button, relative, dx, dy); |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
694 } |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
695 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
696 return; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
697 } |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
698 |
0 | 699 /* Read as many packets as possible */ |
700 nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start); | |
701 if ( nread < 0 ) { | |
702 return; | |
703 } | |
704 nread += start; | |
705 #ifdef DEBUG_MOUSE | |
706 fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start); | |
707 #endif | |
708 for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) { | |
709 switch (mouse_drv) { | |
710 case MOUSE_NONE: | |
711 break; | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
712 case MOUSE_MSC: |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
713 /* MSC protocol has 0x80 in high byte */ |
0 | 714 if ( (mousebuf[i] & 0xF8) != 0x80 ) { |
715 /* Go to next byte */ | |
716 i -= (packetsize-1); | |
717 continue; | |
718 } | |
719 /* Get current mouse state */ | |
720 button = (~mousebuf[i]) & 0x07; | |
721 dx = (signed char)(mousebuf[i+1]) + | |
722 (signed char)(mousebuf[i+3]); | |
723 dy = -((signed char)(mousebuf[i+2]) + | |
724 (signed char)(mousebuf[i+4])); | |
725 break; | |
726 case MOUSE_PS2: | |
727 /* PS/2 protocol has nothing in high byte */ | |
728 if ( (mousebuf[i] & 0xC0) != 0 ) { | |
729 /* Go to next byte */ | |
730 i -= (packetsize-1); | |
731 continue; | |
732 } | |
733 /* Get current mouse state */ | |
734 button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | |
735 (mousebuf[i] & 0x02) >> 1 | /*Right*/ | |
736 (mousebuf[i] & 0x01) << 2; /*Left*/ | |
737 dx = (mousebuf[i] & 0x10) ? | |
738 mousebuf[i+1] - 256 : mousebuf[i+1]; | |
739 dy = (mousebuf[i] & 0x20) ? | |
740 -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | |
741 break; | |
742 case MOUSE_IMPS2: | |
743 /* Get current mouse state */ | |
744 button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | |
745 (mousebuf[i] & 0x02) >> 1 | /*Right*/ | |
746 (mousebuf[i] & 0x01) << 2 | /*Left*/ | |
747 (mousebuf[i] & 0x40) >> 3 | /* 4 */ | |
748 (mousebuf[i] & 0x80) >> 3; /* 5 */ | |
749 dx = (mousebuf[i] & 0x10) ? | |
750 mousebuf[i+1] - 256 : mousebuf[i+1]; | |
751 dy = (mousebuf[i] & 0x20) ? | |
752 -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | |
753 switch (mousebuf[i+3]&0x0F) { | |
754 case 0x0E: /* DX = +1 */ | |
755 case 0x02: /* DX = -1 */ | |
756 break; | |
757 case 0x0F: /* DY = +1 (map button 4) */ | |
132
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
758 FB_vgamousecallback(button | (1<<3), |
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
759 1, 0, 0); |
0 | 760 break; |
761 case 0x01: /* DY = -1 (map button 5) */ | |
132
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
762 FB_vgamousecallback(button | (1<<4), |
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
763 1, 0, 0); |
0 | 764 break; |
765 } | |
766 break; | |
767 case MOUSE_MS: | |
768 /* Microsoft protocol has 0x40 in high byte */ | |
769 if ( (mousebuf[i] & 0x40) != 0x40 ) { | |
770 /* Go to next byte */ | |
771 i -= (packetsize-1); | |
772 continue; | |
773 } | |
774 /* Get current mouse state */ | |
775 button = ((mousebuf[i] & 0x20) >> 3) | | |
776 ((mousebuf[i] & 0x10) >> 4); | |
777 dx = (signed char)(((mousebuf[i] & 0x03) << 6) | | |
778 (mousebuf[i + 1] & 0x3F)); | |
779 dy = (signed char)(((mousebuf[i] & 0x0C) << 4) | | |
780 (mousebuf[i + 2] & 0x3F)); | |
781 break; | |
782 case MOUSE_BM: | |
783 /* BusMouse protocol has 0xF8 in high byte */ | |
784 if ( (mousebuf[i] & 0xF8) != 0x80 ) { | |
785 /* Go to next byte */ | |
786 i -= (packetsize-1); | |
787 continue; | |
788 } | |
789 /* Get current mouse state */ | |
790 button = (~mousebuf[i]) & 0x07; | |
791 dx = (signed char)mousebuf[i+1]; | |
792 dy = -(signed char)mousebuf[i+2]; | |
793 break; | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
794 /* |
0 | 795 case MOUSE_ELO: |
796 if ( mousebuf[i] != ELO_START_BYTE ) { | |
797 i -= (packetsize-1); | |
798 continue; | |
799 } | |
800 | |
801 if(!eloParsePacket(&(mousebuf[i]), &dx, &dy, &button)) { | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
802 i -= (packetsize-1); |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
803 continue; |
0 | 804 } |
805 | |
806 button = (button & 0x01) << 2; | |
807 | |
808 eloConvertXY(this, &dx, &dy); | |
809 break; | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
810 */ |
0 | 811 |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
812 case MOUSE_ELO: |
0 | 813 case NUM_MOUSE_DRVS: |
814 /* Uh oh.. */ | |
815 dx = 0; | |
816 dy = 0; | |
817 break; | |
818 } | |
819 FB_vgamousecallback(button, relative, dx, dy); | |
820 } | |
821 if ( i < nread ) { | |
822 memcpy(mousebuf, &mousebuf[i], (nread-i)); | |
823 start = (nread-i); | |
824 } else { | |
825 start = 0; | |
826 } | |
827 return; | |
828 } | |
829 | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
830 /* Handle switching to another VC, returns when our VC is back. |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
831 This isn't necessarily the best solution. For SDL 1.3 we need |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
832 a way of notifying the application when we lose access to the |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
833 video hardware and when we regain it. |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
834 */ |
0 | 835 static void switch_vt(_THIS, unsigned short which) |
836 { | |
837 struct vt_stat vtstate; | |
838 unsigned short current; | |
839 SDL_Surface *screen; | |
840 __u16 saved_pal[3*256]; | |
841 Uint32 screen_arealen; | |
842 Uint8 *screen_contents; | |
843 | |
844 /* Figure out whether or not we're switching to a new console */ | |
845 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || | |
846 (which == vtstate.v_active) ) { | |
847 return; | |
848 } | |
849 current = vtstate.v_active; | |
850 | |
851 /* Save the contents of the screen, and go to text mode */ | |
852 SDL_mutexP(hw_lock); | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
853 wait_idle(this); |
0 | 854 screen = SDL_VideoSurface; |
855 screen_arealen = (screen->h*screen->pitch); | |
856 screen_contents = (Uint8 *)malloc(screen_arealen); | |
857 if ( screen_contents ) { | |
858 memcpy(screen_contents, screen->pixels, screen_arealen); | |
859 } | |
860 FB_SavePaletteTo(this, 256, saved_pal); | |
861 ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | |
862 | |
863 /* New console, switch to it */ | |
864 if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { | |
865 /* Wait for our console to be activated again */ | |
866 ioctl(keyboard_fd, VT_WAITACTIVE, which); | |
867 while ( ioctl(keyboard_fd, VT_WAITACTIVE, current) < 0 ) { | |
868 if ( (errno != EINTR) && (errno != EAGAIN) ) { | |
869 /* Unknown VT error - cancel this */ | |
870 break; | |
871 } | |
872 SDL_Delay(500); | |
873 } | |
874 } | |
875 | |
876 /* Restore graphics mode and the contents of the screen */ | |
877 ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS); | |
878 FB_RestorePaletteFrom(this, 256, saved_pal); | |
879 if ( screen_contents ) { | |
880 memcpy(screen->pixels, screen_contents, screen_arealen); | |
881 free(screen_contents); | |
882 } | |
883 SDL_mutexV(hw_lock); | |
884 } | |
885 | |
886 static void handle_keyboard(_THIS) | |
887 { | |
888 unsigned char keybuf[BUFSIZ]; | |
889 int i, nread; | |
890 int pressed; | |
891 int scancode; | |
892 SDL_keysym keysym; | |
893 | |
894 nread = read(keyboard_fd, keybuf, BUFSIZ); | |
895 for ( i=0; i<nread; ++i ) { | |
896 scancode = keybuf[i] & 0x7F; | |
897 if ( keybuf[i] & 0x80 ) { | |
898 pressed = SDL_RELEASED; | |
899 } else { | |
900 pressed = SDL_PRESSED; | |
901 } | |
902 TranslateKey(scancode, &keysym); | |
903 /* Handle Alt-FN for vt switch */ | |
904 switch (keysym.sym) { | |
905 case SDLK_F1: | |
906 case SDLK_F2: | |
907 case SDLK_F3: | |
908 case SDLK_F4: | |
909 case SDLK_F5: | |
910 case SDLK_F6: | |
911 case SDLK_F7: | |
912 case SDLK_F8: | |
913 case SDLK_F9: | |
914 case SDLK_F10: | |
915 case SDLK_F11: | |
916 case SDLK_F12: | |
917 if ( SDL_GetModState() & KMOD_ALT ) { | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
918 if ( pressed ) { |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
919 switch_vt(this, (keysym.sym-SDLK_F1)+1); |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
920 } |
0 | 921 break; |
922 } | |
923 /* Fall through to normal processing */ | |
924 default: | |
925 posted += SDL_PrivateKeyboard(pressed, &keysym); | |
926 break; | |
927 } | |
928 } | |
929 } | |
930 | |
931 void FB_PumpEvents(_THIS) | |
932 { | |
933 fd_set fdset; | |
934 int max_fd; | |
935 static struct timeval zero; | |
936 | |
937 do { | |
938 posted = 0; | |
939 | |
940 FD_ZERO(&fdset); | |
941 max_fd = 0; | |
942 if ( keyboard_fd >= 0 ) { | |
943 FD_SET(keyboard_fd, &fdset); | |
944 if ( max_fd < keyboard_fd ) { | |
945 max_fd = keyboard_fd; | |
946 } | |
947 } | |
948 if ( mouse_fd >= 0 ) { | |
949 FD_SET(mouse_fd, &fdset); | |
950 if ( max_fd < mouse_fd ) { | |
951 max_fd = mouse_fd; | |
952 } | |
953 } | |
954 if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) { | |
955 if ( keyboard_fd >= 0 ) { | |
956 if ( FD_ISSET(keyboard_fd, &fdset) ) { | |
957 handle_keyboard(this); | |
958 } | |
959 } | |
960 if ( mouse_fd >= 0 ) { | |
961 if ( FD_ISSET(mouse_fd, &fdset) ) { | |
962 handle_mouse(this); | |
963 } | |
964 } | |
965 } | |
966 } while ( posted ); | |
967 } | |
968 | |
969 void FB_InitOSKeymap(_THIS) | |
970 { | |
971 int i; | |
972 | |
973 /* Initialize the Linux key translation table */ | |
974 | |
975 /* First get the ascii keys and others not well handled */ | |
976 for (i=0; i<SDL_TABLESIZE(keymap); ++i) { | |
977 switch(i) { | |
978 /* These aren't handled by the x86 kernel keymapping (?) */ | |
979 case SCANCODE_PRINTSCREEN: | |
980 keymap[i] = SDLK_PRINT; | |
981 break; | |
982 case SCANCODE_BREAK: | |
983 keymap[i] = SDLK_BREAK; | |
984 break; | |
985 case SCANCODE_BREAK_ALTERNATIVE: | |
986 keymap[i] = SDLK_PAUSE; | |
987 break; | |
988 case SCANCODE_LEFTSHIFT: | |
989 keymap[i] = SDLK_LSHIFT; | |
990 break; | |
991 case SCANCODE_RIGHTSHIFT: | |
992 keymap[i] = SDLK_RSHIFT; | |
993 break; | |
994 case SCANCODE_LEFTCONTROL: | |
995 keymap[i] = SDLK_LCTRL; | |
996 break; | |
997 case SCANCODE_RIGHTCONTROL: | |
998 keymap[i] = SDLK_RCTRL; | |
999 break; | |
1000 case SCANCODE_RIGHTWIN: | |
1001 keymap[i] = SDLK_RSUPER; | |
1002 break; | |
1003 case SCANCODE_LEFTWIN: | |
1004 keymap[i] = SDLK_LSUPER; | |
1005 break; | |
1006 case 127: | |
1007 keymap[i] = SDLK_MENU; | |
1008 break; | |
1009 /* this should take care of all standard ascii keys */ | |
1010 default: | |
1011 keymap[i] = KVAL(vga_keymap[0][i]); | |
1012 break; | |
1013 } | |
1014 } | |
1015 for (i=0; i<SDL_TABLESIZE(keymap); ++i) { | |
1016 switch(keymap_temp[i]) { | |
1017 case K_F1: keymap[i] = SDLK_F1; break; | |
1018 case K_F2: keymap[i] = SDLK_F2; break; | |
1019 case K_F3: keymap[i] = SDLK_F3; break; | |
1020 case K_F4: keymap[i] = SDLK_F4; break; | |
1021 case K_F5: keymap[i] = SDLK_F5; break; | |
1022 case K_F6: keymap[i] = SDLK_F6; break; | |
1023 case K_F7: keymap[i] = SDLK_F7; break; | |
1024 case K_F8: keymap[i] = SDLK_F8; break; | |
1025 case K_F9: keymap[i] = SDLK_F9; break; | |
1026 case K_F10: keymap[i] = SDLK_F10; break; | |
1027 case K_F11: keymap[i] = SDLK_F11; break; | |
1028 case K_F12: keymap[i] = SDLK_F12; break; | |
1029 | |
1030 case K_DOWN: keymap[i] = SDLK_DOWN; break; | |
1031 case K_LEFT: keymap[i] = SDLK_LEFT; break; | |
1032 case K_RIGHT: keymap[i] = SDLK_RIGHT; break; | |
1033 case K_UP: keymap[i] = SDLK_UP; break; | |
1034 | |
1035 case K_P0: keymap[i] = SDLK_KP0; break; | |
1036 case K_P1: keymap[i] = SDLK_KP1; break; | |
1037 case K_P2: keymap[i] = SDLK_KP2; break; | |
1038 case K_P3: keymap[i] = SDLK_KP3; break; | |
1039 case K_P4: keymap[i] = SDLK_KP4; break; | |
1040 case K_P5: keymap[i] = SDLK_KP5; break; | |
1041 case K_P6: keymap[i] = SDLK_KP6; break; | |
1042 case K_P7: keymap[i] = SDLK_KP7; break; | |
1043 case K_P8: keymap[i] = SDLK_KP8; break; | |
1044 case K_P9: keymap[i] = SDLK_KP9; break; | |
1045 case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break; | |
1046 case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break; | |
1047 case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break; | |
1048 case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break; | |
1049 case K_PENTER: keymap[i] = SDLK_KP_ENTER; break; | |
1050 case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break; | |
1051 | |
1052 case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT ) | |
1053 keymap[i] = SDLK_LSHIFT; | |
1054 break; | |
1055 case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break; | |
1056 case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break; | |
1057 case K_CTRL: if ( keymap[i] != SDLK_RCTRL ) | |
1058 keymap[i] = SDLK_LCTRL; | |
1059 break; | |
1060 case K_CTRLL: keymap[i] = SDLK_LCTRL; break; | |
1061 case K_CTRLR: keymap[i] = SDLK_RCTRL; break; | |
1062 case K_ALT: keymap[i] = SDLK_LALT; break; | |
1063 case K_ALTGR: keymap[i] = SDLK_RALT; break; | |
1064 | |
1065 case K_INSERT: keymap[i] = SDLK_INSERT; break; | |
1066 case K_REMOVE: keymap[i] = SDLK_DELETE; break; | |
1067 case K_PGUP: keymap[i] = SDLK_PAGEUP; break; | |
1068 case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break; | |
1069 case K_FIND: keymap[i] = SDLK_HOME; break; | |
1070 case K_SELECT: keymap[i] = SDLK_END; break; | |
1071 | |
1072 case K_NUM: keymap[i] = SDLK_NUMLOCK; break; | |
1073 case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break; | |
1074 | |
1075 case K_F13: keymap[i] = SDLK_PRINT; break; | |
1076 case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break; | |
1077 case K_PAUSE: keymap[i] = SDLK_PAUSE; break; | |
1078 | |
1079 case 127: keymap[i] = SDLK_BACKSPACE; break; | |
1080 | |
1081 default: break; | |
1082 } | |
1083 } | |
1084 } | |
1085 | |
1086 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) | |
1087 { | |
1088 /* Set the keysym information */ | |
1089 keysym->scancode = scancode; | |
1090 keysym->sym = keymap[scancode]; | |
1091 keysym->mod = KMOD_NONE; | |
1092 | |
1093 /* If UNICODE is on, get the UNICODE value for the key */ | |
1094 keysym->unicode = 0; | |
1095 if ( SDL_TranslateUNICODE ) { | |
1096 int map; | |
1097 SDLMod modstate; | |
1098 | |
1099 modstate = SDL_GetModState(); | |
1100 map = 0; | |
1101 if ( modstate & KMOD_SHIFT ) { | |
1102 map |= (1<<KG_SHIFT); | |
1103 } | |
1104 if ( modstate & KMOD_CTRL ) { | |
1105 map |= (1<<KG_CTRL); | |
1106 } | |
1107 if ( modstate & KMOD_ALT ) { | |
1108 map |= (1<<KG_ALT); | |
1109 } | |
1110 if ( modstate & KMOD_MODE ) { | |
1111 map |= (1<<KG_ALTGR); | |
1112 } | |
1113 if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { | |
1114 if ( modstate & KMOD_CAPS ) { | |
1115 map ^= (1<<KG_SHIFT); | |
1116 } | |
1117 } | |
1118 if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) { | |
1119 if ( modstate & KMOD_NUM ) { | |
1120 keysym->unicode=KVAL(vga_keymap[map][scancode]); | |
1121 } | |
1122 } else { | |
1123 keysym->unicode = KVAL(vga_keymap[map][scancode]); | |
1124 } | |
1125 } | |
1126 return(keysym); | |
1127 } |