comparison src/video/fbcon/SDL_fbevents.c @ 1659:14717b52abc0 SDL-1.3

Merge trunk-1.3-3
author Sam Lantinga <slouken@libsdl.org>
date Wed, 17 May 2006 08:18:28 +0000
parents 980d2a0dc2a3
children 782fd950bd46
comparison
equal deleted inserted replaced
1658:e49147870aac 1659:14717b52abc0
53 53
54 #ifndef GPM_NODE_FIFO 54 #ifndef GPM_NODE_FIFO
55 #define GPM_NODE_FIFO "/dev/gpmdata" 55 #define GPM_NODE_FIFO "/dev/gpmdata"
56 #endif 56 #endif
57 57
58 /*#define DEBUG_KEYBOARD*/
59 /*#define DEBUG_MOUSE*/
58 60
59 /* The translation tables from a console scancode to a SDL keysym */ 61 /* The translation tables from a console scancode to a SDL keysym */
60 #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) 62 #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT)
61 static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; 63 static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS];
62 static SDLKey keymap[128]; 64 static SDLKey keymap[128];
205 if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { 207 if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) {
206 FB_CloseKeyboard(this); 208 FB_CloseKeyboard(this);
207 SDL_SetError("Unable to set keyboard in graphics mode"); 209 SDL_SetError("Unable to set keyboard in graphics mode");
208 return(-1); 210 return(-1);
209 } 211 }
212 /* Prevent switching the virtual terminal */
213 ioctl(keyboard_fd, VT_LOCKSWITCH, 1);
210 } 214 }
211 return(keyboard_fd); 215 return(keyboard_fd);
212 } 216 }
213 217
214 void FB_LeaveGraphicsMode(_THIS) 218 void FB_LeaveGraphicsMode(_THIS)
218 ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); 222 ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode);
219 tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); 223 tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios);
220 saved_kbd_mode = -1; 224 saved_kbd_mode = -1;
221 225
222 /* Head back over to the original virtual terminal */ 226 /* Head back over to the original virtual terminal */
227 ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1);
223 if ( saved_vt > 0 ) { 228 if ( saved_vt > 0 ) {
224 ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); 229 ioctl(keyboard_fd, VT_ACTIVATE, saved_vt);
225 } 230 }
226 } 231 }
227 } 232 }
278 } 283 }
279 } 284 }
280 } 285 }
281 if ( keyboard_fd < 0 ) { 286 if ( keyboard_fd < 0 ) {
282 /* Last resort, maybe our tty is a usable VT */ 287 /* Last resort, maybe our tty is a usable VT */
283 current_vt = 0; 288 struct vt_stat vtstate;
289
284 keyboard_fd = open("/dev/tty", O_RDWR); 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 }
285 } 297 }
286 #ifdef DEBUG_KEYBOARD 298 #ifdef DEBUG_KEYBOARD
287 fprintf(stderr, "Current VT: %d\n", current_vt); 299 fprintf(stderr, "Current VT: %d\n", current_vt);
288 #endif 300 #endif
289 saved_kbd_mode = -1; 301 saved_kbd_mode = -1;
358 } 370 }
359 return pid; 371 return pid;
360 } 372 }
361 373
362 /* Returns true if /dev/gpmdata is being written to by gpm */ 374 /* Returns true if /dev/gpmdata is being written to by gpm */
363 static int gpm_available(void) 375 static int gpm_available(char *proto, size_t protolen)
364 { 376 {
365 int available; 377 int available;
366 DIR *proc; 378 DIR *proc;
367 int pid; 379 int pid;
368 int cmdline, len, arglen; 380 int cmdline, len, arglen;
369 char path[PATH_MAX]; 381 char path[PATH_MAX];
370 char args[PATH_MAX], *arg; 382 char args[PATH_MAX], *arg;
371 383
372 /* Don't bother looking if the fifo isn't there */ 384 /* Don't bother looking if the fifo isn't there */
385 #ifdef DEBUG_MOUSE
386 fprintf(stderr,"testing gpm\n");
387 #endif
373 if ( access(GPM_NODE_FIFO, F_OK) < 0 ) { 388 if ( access(GPM_NODE_FIFO, F_OK) < 0 ) {
374 return(0); 389 return(0);
375 } 390 }
376 391
377 available = 0; 392 available = 0;
378 proc = opendir("/proc"); 393 proc = opendir("/proc");
379 if ( proc ) { 394 if ( proc ) {
380 while ( (pid=find_pid(proc, "gpm")) > 0 ) { 395 char raw_proto[10] = { '\0' };
396 char repeat_proto[10] = { '\0' };
397 while ( !available && (pid=find_pid(proc, "gpm")) > 0 ) {
381 SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid); 398 SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid);
382 cmdline = open(path, O_RDONLY, 0); 399 cmdline = open(path, O_RDONLY, 0);
383 if ( cmdline >= 0 ) { 400 if ( cmdline >= 0 ) {
384 len = read(cmdline, args, sizeof(args)); 401 len = read(cmdline, args, sizeof(args));
385 arg = args; 402 arg = args;
386 while ( len > 0 ) { 403 while ( len > 0 ) {
387 if ( SDL_strcmp(arg, "-R") == 0 ) { 404 arglen = SDL_strlen(arg)+1;
405 #ifdef DEBUG_MOUSE
406 fprintf(stderr,"gpm arg %s len %d\n",arg,arglen);
407 #endif
408 if ( SDL_strcmp(arg, "-t") == 0) {
409 /* protocol string, keep it for later */
410 char *t, *s;
411 t = arg + arglen;
412 s = SDL_strchr(t, ' ');
413 if (s) *s = 0;
414 SDL_strlcpy(raw_proto, t, SDL_arraysize(raw_proto));
415 if (s) *s = ' ';
416 }
417 if ( SDL_strncmp(arg, "-R", 2) == 0 ) {
418 char *t, *s;
388 available = 1; 419 available = 1;
420 t = arg + 2;
421 s = SDL_strchr(t, ' ');
422 if (s) *s = 0;
423 SDL_strlcpy(repeat_proto, t, SDL_arraysize(repeat_proto));
424 if (s) *s = ' ';
389 } 425 }
390 arglen = SDL_strlen(arg)+1;
391 len -= arglen; 426 len -= arglen;
392 arg += arglen; 427 arg += arglen;
393 } 428 }
394 close(cmdline); 429 close(cmdline);
395 } 430 }
396 } 431 }
397 closedir(proc); 432 closedir(proc);
433
434 if ( available ) {
435 if ( SDL_strcmp(repeat_proto, "raw") == 0 ) {
436 SDL_strlcpy(proto, raw_proto, protolen);
437 } else if ( *repeat_proto ) {
438 SDL_strlcpy(proto, repeat_proto, protolen);
439 } else {
440 SDL_strlcpy(proto, "msc", protolen);
441 }
442 }
398 } 443 }
399 return available; 444 return available;
400 } 445 }
401 446
402 447
412 {0xf3,200,0xf3,100,0xf3,80} 457 {0xf3,200,0xf3,100,0xf3,80}
413 Reset mouse device: 458 Reset mouse device:
414 {0xFF} 459 {0xFF}
415 */ 460 */
416 Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; 461 Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80};
417 Uint8 reset = 0xff; 462 /*Uint8 reset = 0xff;*/
418 fd_set fdset; 463 fd_set fdset;
419 struct timeval tv; 464 struct timeval tv;
420 int retval = 0; 465 int retval = 0;
421 466
422 if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { 467 if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) {
550 static const char *ps2mice[] = { 595 static const char *ps2mice[] = {
551 "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL 596 "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL
552 }; 597 };
553 /* First try to use GPM in repeater mode */ 598 /* First try to use GPM in repeater mode */
554 if ( mouse_fd < 0 ) { 599 if ( mouse_fd < 0 ) {
555 if ( gpm_available() ) { 600 char proto[10];
601 if ( gpm_available(proto, SDL_arraysize(proto)) ) {
556 mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); 602 mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0);
557 if ( mouse_fd >= 0 ) { 603 if ( mouse_fd >= 0 ) {
604 if ( SDL_strcmp(proto, "msc") == 0 ) {
605 mouse_drv = MOUSE_MSC;
606 } else if ( SDL_strcmp(proto, "ps2") == 0 ) {
607 mouse_drv = MOUSE_PS2;
608 } else if ( SDL_strcmp(proto, "imps2") == 0 ) {
609 mouse_drv = MOUSE_IMPS2;
610 } else if ( SDL_strcmp(proto, "ms") == 0 ||
611 SDL_strcmp(proto, "bare") == 0 ) {
612 mouse_drv = MOUSE_MS;
613 } else if ( SDL_strcmp(proto, "bm") == 0 ) {
614 mouse_drv = MOUSE_BM;
615 } else {
616 /* Unknown protocol... */
558 #ifdef DEBUG_MOUSE 617 #ifdef DEBUG_MOUSE
559 fprintf(stderr, "Using GPM mouse\n"); 618 fprintf(stderr, "GPM mouse using unknown protocol = %s\n", proto);
560 #endif 619 #endif
561 mouse_drv = MOUSE_MSC; 620 close(mouse_fd);
562 } 621 mouse_fd = -1;
622 }
623 }
624 #ifdef DEBUG_MOUSE
625 if ( mouse_fd >= 0 ) {
626 fprintf(stderr, "Using GPM mouse, protocol = %s\n", proto);
627 }
628 #endif /* DEBUG_MOUSE */
563 } 629 }
564 } 630 }
565 /* Now try to use a modern PS/2 mouse */ 631 /* Now try to use a modern PS/2 mouse */
566 for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) { 632 for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) {
567 mouse_fd = open(ps2mice[i], O_RDWR, 0); 633 mouse_fd = open(ps2mice[i], O_RDWR, 0);
851 start = 0; 917 start = 0;
852 } 918 }
853 return; 919 return;
854 } 920 }
855 921
856 /* Handle switching to another VC, returns when our VC is back. 922 /* Handle switching to another VC, returns when our VC is back */
857 This isn't necessarily the best solution. For SDL 1.3 we need 923 static void switch_vt_prep(_THIS)
858 a way of notifying the application when we lose access to the 924 {
859 video hardware and when we regain it. 925 SDL_Surface *screen = SDL_VideoSurface;
860 */ 926
927 SDL_PrivateAppActive(0, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS));
928
929 /* Save the contents of the screen, and go to text mode */
930 wait_idle(this);
931 screen_arealen = ((screen->h + (2*this->offset_y)) * screen->pitch);
932 screen_contents = (Uint8 *)SDL_malloc(screen_arealen);
933 if ( screen_contents ) {
934 SDL_memcpy(screen_contents, screen->pixels, screen_arealen);
935 }
936 FB_SavePaletteTo(this, 256, screen_palette);
937 ioctl(console_fd, FBIOGET_VSCREENINFO, &screen_vinfo);
938 ioctl(keyboard_fd, KDSETMODE, KD_TEXT);
939 ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1);
940 }
941 static void switch_vt_done(_THIS)
942 {
943 SDL_Surface *screen = SDL_VideoSurface;
944
945 /* Restore graphics mode and the contents of the screen */
946 ioctl(keyboard_fd, VT_LOCKSWITCH, 1);
947 ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS);
948 ioctl(console_fd, FBIOPUT_VSCREENINFO, &screen_vinfo);
949 FB_RestorePaletteFrom(this, 256, screen_palette);
950 if ( screen_contents ) {
951 SDL_memcpy(screen->pixels, screen_contents, screen_arealen);
952 SDL_free(screen_contents);
953 screen_contents = NULL;
954 }
955
956 /* Get updates to the shadow surface while switched away */
957 if ( SDL_ShadowSurface ) {
958 SDL_UpdateRect(SDL_ShadowSurface, 0, 0, 0, 0);
959 }
960
961 SDL_PrivateAppActive(1, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS));
962 }
861 static void switch_vt(_THIS, unsigned short which) 963 static void switch_vt(_THIS, unsigned short which)
862 { 964 {
863 struct fb_var_screeninfo vinfo;
864 struct vt_stat vtstate; 965 struct vt_stat vtstate;
865 unsigned short v_active;
866 __u16 saved_pal[3*256];
867 SDL_Surface *screen;
868 Uint32 screen_arealen;
869 Uint8 *screen_contents = NULL;
870 966
871 /* Figure out whether or not we're switching to a new console */ 967 /* Figure out whether or not we're switching to a new console */
872 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || 968 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) ||
873 (which == vtstate.v_active) ) { 969 (which == vtstate.v_active) ) {
874 return; 970 return;
875 } 971 }
876 v_active = vtstate.v_active; 972
877 973 /* New console, switch to it */
878 /* Save the contents of the screen, and go to text mode */
879 SDL_mutexP(hw_lock); 974 SDL_mutexP(hw_lock);
880 wait_idle(this); 975 switch_vt_prep(this);
881 screen = SDL_VideoSurface;
882 if ( !SDL_ShadowSurface ) {
883 screen_arealen = (screen->h*screen->pitch);
884 screen_contents = (Uint8 *)SDL_malloc(screen_arealen);
885 if ( screen_contents ) {
886 SDL_memcpy(screen_contents, (Uint8 *)screen->pixels + screen->offset, screen_arealen);
887 }
888 }
889 FB_SavePaletteTo(this, 256, saved_pal);
890 ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo);
891 ioctl(keyboard_fd, KDSETMODE, KD_TEXT);
892
893 /* New console, switch to it */
894 if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { 976 if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) {
895 /* Wait for our console to be activated again */
896 ioctl(keyboard_fd, VT_WAITACTIVE, which); 977 ioctl(keyboard_fd, VT_WAITACTIVE, which);
897 while ( ioctl(keyboard_fd, VT_WAITACTIVE, v_active) < 0 ) { 978 switched_away = 1;
898 if ( (errno != EINTR) && (errno != EAGAIN) ) {
899 /* Unknown VT error - cancel this */
900 break;
901 }
902 SDL_Delay(500);
903 }
904 }
905
906 /* Restore graphics mode and the contents of the screen */
907 ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS);
908 ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo);
909 FB_RestorePaletteFrom(this, 256, saved_pal);
910 if ( screen_contents ) {
911 SDL_memcpy((Uint8 *)screen->pixels + screen->offset, screen_contents, screen_arealen);
912 SDL_free(screen_contents);
913 } else { 979 } else {
914 SDL_UpdateRect(screen, 0, 0, 0, 0); 980 switch_vt_done(this);
915 } 981 }
916 SDL_mutexV(hw_lock); 982 SDL_mutexV(hw_lock);
917 } 983 }
918 984
919 static void handle_keyboard(_THIS) 985 static void handle_keyboard(_THIS)
967 fd_set fdset; 1033 fd_set fdset;
968 int max_fd; 1034 int max_fd;
969 static struct timeval zero; 1035 static struct timeval zero;
970 1036
971 do { 1037 do {
1038 if ( switched_away ) {
1039 struct vt_stat vtstate;
1040
1041 SDL_mutexP(hw_lock);
1042 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0) &&
1043 vtstate.v_active == current_vt ) {
1044 switched_away = 0;
1045 switch_vt_done(this);
1046 }
1047 SDL_mutexV(hw_lock);
1048 }
1049
972 posted = 0; 1050 posted = 0;
973 1051
974 FD_ZERO(&fdset); 1052 FD_ZERO(&fdset);
975 max_fd = 0; 1053 max_fd = 0;
976 if ( keyboard_fd >= 0 ) { 1054 if ( keyboard_fd >= 0 ) {
1035 keymap[i] = SDLK_RSUPER; 1113 keymap[i] = SDLK_RSUPER;
1036 break; 1114 break;
1037 case SCANCODE_LEFTWIN: 1115 case SCANCODE_LEFTWIN:
1038 keymap[i] = SDLK_LSUPER; 1116 keymap[i] = SDLK_LSUPER;
1039 break; 1117 break;
1118 case SCANCODE_LEFTALT:
1119 keymap[i] = SDLK_LALT;
1120 break;
1121 case SCANCODE_RIGHTALT:
1122 keymap[i] = SDLK_RALT;
1123 break;
1040 case 127: 1124 case 127:
1041 keymap[i] = SDLK_MENU; 1125 keymap[i] = SDLK_MENU;
1042 break; 1126 break;
1043 /* this should take care of all standard ascii keys */ 1127 /* this should take care of all standard ascii keys */
1044 default: 1128 default:
1136 map |= (1<<KG_SHIFT); 1220 map |= (1<<KG_SHIFT);
1137 } 1221 }
1138 if ( modstate & KMOD_CTRL ) { 1222 if ( modstate & KMOD_CTRL ) {
1139 map |= (1<<KG_CTRL); 1223 map |= (1<<KG_CTRL);
1140 } 1224 }
1141 if ( modstate & KMOD_ALT ) { 1225 if ( modstate & KMOD_LALT ) {
1142 map |= (1<<KG_ALT); 1226 map |= (1<<KG_ALT);
1143 } 1227 }
1144 if ( modstate & KMOD_MODE ) { 1228 if ( modstate & KMOD_RALT ) {
1145 map |= (1<<KG_ALTGR); 1229 map |= (1<<KG_ALTGR);
1146 } 1230 }
1147 if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { 1231 if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) {
1148 if ( modstate & KMOD_CAPS ) { 1232 if ( modstate & KMOD_CAPS ) {
1149 map ^= (1<<KG_SHIFT); 1233 map ^= (1<<KG_SHIFT);