Mercurial > sdl-ios-xcode
comparison src/video/fbcon/SDL_fbevents.c @ 1780:7a36f01acf71
Fixed bug #49
Added support for non-blocking VT switching on the framebuffer console.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 08 May 2006 05:33:02 +0000 |
parents | e28233f37f8c |
children | d8030f368b84 |
comparison
equal
deleted
inserted
replaced
1779:67fc81efcfc3 | 1780:7a36f01acf71 |
---|---|
207 if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { | 207 if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { |
208 FB_CloseKeyboard(this); | 208 FB_CloseKeyboard(this); |
209 SDL_SetError("Unable to set keyboard in graphics mode"); | 209 SDL_SetError("Unable to set keyboard in graphics mode"); |
210 return(-1); | 210 return(-1); |
211 } | 211 } |
212 /* Prevent switching the virtual terminal */ | |
213 ioctl(keyboard_fd, VT_LOCKSWITCH, 1); | |
212 } | 214 } |
213 return(keyboard_fd); | 215 return(keyboard_fd); |
214 } | 216 } |
215 | 217 |
216 void FB_LeaveGraphicsMode(_THIS) | 218 void FB_LeaveGraphicsMode(_THIS) |
220 ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); | 222 ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); |
221 tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); | 223 tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); |
222 saved_kbd_mode = -1; | 224 saved_kbd_mode = -1; |
223 | 225 |
224 /* Head back over to the original virtual terminal */ | 226 /* Head back over to the original virtual terminal */ |
227 ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1); | |
225 if ( saved_vt > 0 ) { | 228 if ( saved_vt > 0 ) { |
226 ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); | 229 ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); |
227 } | 230 } |
228 } | 231 } |
229 } | 232 } |
454 {0xf3,200,0xf3,100,0xf3,80} | 457 {0xf3,200,0xf3,100,0xf3,80} |
455 Reset mouse device: | 458 Reset mouse device: |
456 {0xFF} | 459 {0xFF} |
457 */ | 460 */ |
458 Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; | 461 Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; |
459 Uint8 reset = 0xff; | 462 /*Uint8 reset = 0xff;*/ |
460 fd_set fdset; | 463 fd_set fdset; |
461 struct timeval tv; | 464 struct timeval tv; |
462 int retval = 0; | 465 int retval = 0; |
463 | 466 |
464 if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { | 467 if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { |
914 start = 0; | 917 start = 0; |
915 } | 918 } |
916 return; | 919 return; |
917 } | 920 } |
918 | 921 |
919 /* Handle switching to another VC, returns when our VC is back. | 922 /* Handle switching to another VC, returns when our VC is back */ |
920 This isn't necessarily the best solution. For SDL 1.3 we need | 923 static void switch_vt_prep(_THIS) |
921 a way of notifying the application when we lose access to the | 924 { |
922 video hardware and when we regain it. | 925 SDL_Surface *screen = SDL_VideoSurface; |
923 */ | 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 SDL_PrivateAppActive(1, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS)); | |
957 } | |
924 static void switch_vt(_THIS, unsigned short which) | 958 static void switch_vt(_THIS, unsigned short which) |
925 { | 959 { |
926 struct fb_var_screeninfo vinfo; | |
927 struct vt_stat vtstate; | 960 struct vt_stat vtstate; |
928 unsigned short v_active; | |
929 __u16 saved_pal[3*256]; | |
930 SDL_Surface *screen; | |
931 Uint32 screen_arealen; | |
932 Uint8 *screen_contents = NULL; | |
933 | 961 |
934 /* Figure out whether or not we're switching to a new console */ | 962 /* Figure out whether or not we're switching to a new console */ |
935 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || | 963 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || |
936 (which == vtstate.v_active) ) { | 964 (which == vtstate.v_active) ) { |
937 return; | 965 return; |
938 } | 966 } |
939 v_active = vtstate.v_active; | 967 |
940 | 968 /* New console, switch to it */ |
941 /* Save the contents of the screen, and go to text mode */ | |
942 SDL_mutexP(hw_lock); | 969 SDL_mutexP(hw_lock); |
943 wait_idle(this); | 970 switch_vt_prep(this); |
944 screen = SDL_VideoSurface; | |
945 if ( !SDL_ShadowSurface ) { | |
946 screen_arealen = (screen->h*screen->pitch); | |
947 screen_contents = (Uint8 *)SDL_malloc(screen_arealen); | |
948 if ( screen_contents ) { | |
949 SDL_memcpy(screen_contents, (Uint8 *)screen->pixels + screen->offset, screen_arealen); | |
950 } | |
951 } | |
952 FB_SavePaletteTo(this, 256, saved_pal); | |
953 ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo); | |
954 ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | |
955 | |
956 /* New console, switch to it */ | |
957 if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { | 971 if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { |
958 /* Wait for our console to be activated again */ | |
959 ioctl(keyboard_fd, VT_WAITACTIVE, which); | 972 ioctl(keyboard_fd, VT_WAITACTIVE, which); |
960 while ( ioctl(keyboard_fd, VT_WAITACTIVE, v_active) < 0 ) { | 973 switched_away = 1; |
961 if ( (errno != EINTR) && (errno != EAGAIN) ) { | |
962 /* Unknown VT error - cancel this */ | |
963 break; | |
964 } | |
965 SDL_Delay(500); | |
966 } | |
967 } | |
968 | |
969 /* Restore graphics mode and the contents of the screen */ | |
970 ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS); | |
971 ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo); | |
972 FB_RestorePaletteFrom(this, 256, saved_pal); | |
973 if ( screen_contents ) { | |
974 SDL_memcpy((Uint8 *)screen->pixels + screen->offset, screen_contents, screen_arealen); | |
975 SDL_free(screen_contents); | |
976 } else { | 974 } else { |
977 SDL_UpdateRect(screen, 0, 0, 0, 0); | 975 switch_vt_done(this); |
978 } | 976 } |
979 SDL_mutexV(hw_lock); | 977 SDL_mutexV(hw_lock); |
980 } | 978 } |
981 | 979 |
982 static void handle_keyboard(_THIS) | 980 static void handle_keyboard(_THIS) |
1030 fd_set fdset; | 1028 fd_set fdset; |
1031 int max_fd; | 1029 int max_fd; |
1032 static struct timeval zero; | 1030 static struct timeval zero; |
1033 | 1031 |
1034 do { | 1032 do { |
1033 if ( switched_away ) { | |
1034 struct vt_stat vtstate; | |
1035 | |
1036 SDL_mutexP(hw_lock); | |
1037 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0) && | |
1038 vtstate.v_active == current_vt ) { | |
1039 switched_away = 0; | |
1040 switch_vt_done(this); | |
1041 } | |
1042 SDL_mutexV(hw_lock); | |
1043 } | |
1044 | |
1035 posted = 0; | 1045 posted = 0; |
1036 | 1046 |
1037 FD_ZERO(&fdset); | 1047 FD_ZERO(&fdset); |
1038 max_fd = 0; | 1048 max_fd = 0; |
1039 if ( keyboard_fd >= 0 ) { | 1049 if ( keyboard_fd >= 0 ) { |