diff -p -up DirectFB-1.2.3/inputdrivers/keyboard/keyboard.c.reopen_vt DirectFB-1.2.3/inputdrivers/keyboard/keyboard.c --- DirectFB-1.2.3/inputdrivers/keyboard/keyboard.c.reopen_vt 2008-08-08 16:11:32.000000000 +0200 +++ DirectFB-1.2.3/inputdrivers/keyboard/keyboard.c 2008-09-22 16:39:27.000000000 +0200 @@ -289,6 +289,51 @@ keyboard_set_lights( KeyboardData *data, ioctl( data->vt_fd, KDSKBLED, locks ); } +static DFBResult +keyboard_open_fd(int *fd, int reopen) { + if (dfb_system_type() == CORE_FBDEV && dfb_config->vt) { + FBDev *dfb_fbdev = dfb_system_data(); + if (reopen) { + close(*fd); + close(dfb_fbdev->vt->fd); + dfb_fbdev->vt->method_open(dfb_fbdev->vt); + } + + *fd = dup( dfb_fbdev->vt->fd ); + if (*fd < 0) { + D_PERROR( "DirectFB/Keyboard: Could not dup() file descriptor of TTY!\n" ); + return DFB_INIT; + } + + /* put keyboard into medium raw mode */ + if (ioctl( *fd, KDSKBMODE, K_MEDIUMRAW ) < 0) { + D_PERROR( "DirectFB/Keyboard: K_MEDIUMRAW failed!\n" ); + return DFB_INIT; + } + } + else { + *fd = open( "/dev/tty0", O_RDWR | O_NOCTTY ); + if (*fd < 0) { + D_PERROR( "DirectFB/Keyboard: Could not open() /dev/tty0!\n" ); + return DFB_INIT; + } + } + return DFB_OK; +} + +static void +keyboard_set_input (KeyboardData *data) +{ + struct termios ts; + ts = data->old_ts; + ts.c_cc[VTIME] = 0; + ts.c_cc[VMIN] = 1; + ts.c_lflag &= ~(ICANON|ECHO|ISIG); + ts.c_iflag = 0; + tcsetattr( data->vt_fd, TCSAFLUSH, &ts ); + tcsetpgrp( data->vt_fd, getpgrp() ); +} + static void* keyboardEventThread( DirectThread *thread, void *driver_data ) { @@ -302,6 +347,13 @@ keyboardEventThread( DirectThread *threa direct_thread_testcancel( thread ); + if (readlen == 0) { + /* Maybe our controlling terminal has been stolen by init */ + if (keyboard_open_fd(&data->vt_fd, 1) != DFB_OK) + break; + keyboard_set_input (data); + } + for (i = 0; i < readlen; i++) { DFBInputEvent evt; @@ -371,32 +423,11 @@ driver_open_device( CoreInputDevice *de void **driver_data ) { int fd; - struct termios ts; KeyboardData *data; - - if (dfb_system_type() == CORE_FBDEV && dfb_config->vt) { - FBDev *dfb_fbdev = dfb_system_data(); - - fd = dup( dfb_fbdev->vt->fd ); - if (fd < 0) { - D_PERROR( "DirectFB/Keyboard: Could not dup() file descriptor of TTY!\n" ); - return DFB_INIT; - } - - /* put keyboard into medium raw mode */ - if (ioctl( fd, KDSKBMODE, K_MEDIUMRAW ) < 0) { - D_PERROR( "DirectFB/Keyboard: K_MEDIUMRAW failed!\n" ); - return DFB_INIT; - } - } - else { - fd = open( "/dev/tty0", O_RDWR | O_NOCTTY ); - if (fd < 0) { - D_PERROR( "DirectFB/Keyboard: Could not open() /dev/tty0!\n" ); - return DFB_INIT; - } - } + DFBResult res = keyboard_open_fd(&fd, 0); + if (res != DFB_OK) + return res; /* allocate and fill private data */ data = D_CALLOC( 1, sizeof(KeyboardData) ); @@ -406,14 +437,7 @@ driver_open_device( CoreInputDevice *de tcgetattr( data->vt_fd, &data->old_ts ); - ts = data->old_ts; - ts.c_cc[VTIME] = 0; - ts.c_cc[VMIN] = 1; - ts.c_lflag &= ~(ICANON|ECHO|ISIG); - ts.c_iflag = 0; - tcsetattr( data->vt_fd, TCSAFLUSH, &ts ); - - tcsetpgrp( data->vt_fd, getpgrp() ); + keyboard_set_input (data); /* fill device info structure */ snprintf( info->desc.name, diff -p -up DirectFB-1.2.3/systems/fbdev/vt.c.reopen_vt DirectFB-1.2.3/systems/fbdev/vt.c --- DirectFB-1.2.3/systems/fbdev/vt.c.reopen_vt 2008-06-02 08:07:44.000000000 +0200 +++ DirectFB-1.2.3/systems/fbdev/vt.c 2008-09-22 17:40:26.000000000 +0200 @@ -96,6 +96,8 @@ static int vt_get_fb( int vt ); static void vt_set_fb( int vt, int fb ); static void *vt_thread( DirectThread *thread, void *arg ); +static DFBResult vt_open (VirtualTerminal *vt); + DFBResult dfb_vt_initialize() { @@ -219,6 +221,8 @@ dfb_vt_initialize() return ret; } + dfb_vt->method_open = &vt_open; + dfb_fbdev->vt = dfb_vt; return DFB_OK; @@ -439,27 +443,23 @@ vt_switch_handler( int signum ) } static DFBResult -vt_init_switching() -{ - const char cursoroff_str[] = "\033[?1;0;0c"; - const char blankoff_str[] = "\033[9;0]"; +vt_open (VirtualTerminal *vt) { + char buf[32]; D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ ); - /* FIXME: Opening the device should be moved out of this function. */ - - snprintf(buf, 32, "/dev/tty%d", dfb_vt->num); - dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY ); - if (dfb_vt->fd < 0) { + snprintf(buf, 32, "/dev/tty%d", vt->num); + vt->fd = open( buf, O_RDWR | O_NOCTTY ); + if (vt->fd < 0) { if (errno == ENOENT) { - snprintf(buf, 32, "/dev/vc/%d", dfb_vt->num); - dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY ); - if (dfb_vt->fd < 0) { + snprintf(buf, 32, "/dev/vc/%d", vt->num); + vt->fd = open( buf, O_RDWR | O_NOCTTY ); + if (vt->fd < 0) { if (errno == ENOENT) { D_PERROR( "DirectFB/core/vt: Couldn't open " "neither `/dev/tty%d' nor `/dev/vc/%d'!\n", - dfb_vt->num, dfb_vt->num ); + vt->num, vt->num ); } else { D_PERROR( "DirectFB/core/vt: " @@ -477,7 +477,24 @@ vt_init_switching() /* attach to the new TTY before doing anything like KDSETMODE with it, otherwise we'd get access denied error: */ - ioctl( dfb_vt->fd, TIOCSCTTY, 0 ); + if (ioctl( vt->fd, TIOCSCTTY, 0 ) == -1) { + return errno2result (errno); + } + + return DFB_OK; +} + + +static DFBResult +vt_init_switching() +{ + const char cursoroff_str[] = "\033[?1;0;0c"; + const char blankoff_str[] = "\033[9;0]"; + DFBResult res; + + D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ ); + + if ((res = vt_open (dfb_vt)) != DFB_OK) return res; write( dfb_vt->fd, cursoroff_str, sizeof(cursoroff_str) ); if (dfb_config->kd_graphics) { diff -p -up DirectFB-1.2.3/systems/fbdev/vt.h.reopen_vt DirectFB-1.2.3/systems/fbdev/vt.h --- DirectFB-1.2.3/systems/fbdev/vt.h.reopen_vt 2008-06-02 08:07:44.000000000 +0200 +++ DirectFB-1.2.3/systems/fbdev/vt.h 2008-09-22 10:23:41.000000000 +0200 @@ -34,7 +34,7 @@ #include <directfb.h> -typedef struct { +typedef struct VirtualTerminal { int fd0; /* file descriptor of /dev/tty0 */ int fd; /* file descriptor of /dev/ttyN where N is the number of the allocated VT, @@ -56,6 +56,8 @@ typedef struct { pthread_cond_t wait; int vt_sig; + + DFBResult (*method_open) (struct VirtualTerminal *); } VirtualTerminal; /*