DFBResult dfb_vt_shutdown( bool emergency ) { if (!dfb_vt) return DFB_OK; #if 0 if (dfb_config->vt_switching) { if (ioctl( dfb_vt->fd, VT_SETMODE, &Sdfb_vt->vt_mode ) < 0) PERRORMSG( "DirectFB/core/vt: Unable to restore VT mode!!!\n" ); //sigaction( SIG_SWITCH_FROM, &Sdfb_vt->sig_usr1, NULL ); //sigaction( SIG_SWITCH_TO, &Sdfb_vt->sig_usr2, NULL ); } #endif if (dfb_config->vt_switch) { DEBUGMSG( "switching back...\n" ); if (ioctl( dfb_vt->fd0, VT_ACTIVATE, Sdfb_vt->prev ) < 0) PERRORMSG( "DirectFB/core/vt: VT_ACTIVATE" ); if (ioctl( dfb_vt->fd0, VT_WAITACTIVE, Sdfb_vt->prev ) < 0) PERRORMSG( "DirectFB/core/vt: VT_WAITACTIVE" ); DEBUGMSG( "switched back...\n" ); usleep( 40000 ); /* restore con2fbmap */ vt_set_fb( Sdfb_vt->num, Sdfb_vt->old_fb ); if (close( dfb_vt->fd ) < 0) PERRORMSG( "DirectFB/core/vt: Unable to " "close file descriptor of allocated VT!\n" ); if (ioctl( dfb_vt->fd0, VT_DISALLOCATE, Sdfb_vt->num ) < 0) PERRORMSG( "DirectFB/core/vt: Unable to disallocate VT!\n" ); } else { /* restore con2fbmap */ vt_set_fb( Sdfb_vt->num, Sdfb_vt->old_fb ); } if (close( dfb_vt->fd0 ) < 0) PERRORMSG( "DirectFB/core/vt: Unable to " "close file descriptor of tty0!\n" ); DFBFREE( dfb_vt ); dfb_vt = NULL; return DFB_OK; }
DFBResult dfb_vt_initialize() { DFBResult ret; struct vt_stat vs; D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ ); dfb_vt = D_CALLOC( 1, sizeof(VirtualTerminal) ); setsid(); dfb_vt->fd0 = open( "/dev/tty0", O_RDONLY | O_NOCTTY ); if (dfb_vt->fd0 < 0) { if (errno == ENOENT) { dfb_vt->fd0 = open( "/dev/vc/0", O_RDONLY | O_NOCTTY ); if (dfb_vt->fd0 < 0) { if (errno == ENOENT) { D_PERROR( "DirectFB/core/vt: Couldn't open " "neither `/dev/tty0' nor `/dev/vc/0'!\n" ); } else { D_PERROR( "DirectFB/core/vt: " "Error opening `/dev/vc/0'!\n" ); } D_FREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } } else { D_PERROR( "DirectFB/core/vt: Error opening `/dev/tty0'!\n"); D_FREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } } if (ioctl( dfb_vt->fd0, VT_GETSTATE, &vs ) < 0) { D_PERROR( "DirectFB/core/vt: VT_GETSTATE failed!\n" ); close( dfb_vt->fd0 ); D_FREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } dfb_vt->prev = vs.v_active; if (!dfb_config->vt_switch) { if (dfb_config->vt_num != -1) dfb_vt->num = dfb_config->vt_num; else dfb_vt->num = dfb_vt->prev; /* move vt to framebuffer */ dfb_vt->old_fb = vt_get_fb( dfb_vt->num ); vt_set_fb( dfb_vt->num, -1 ); } else { if (dfb_config->vt_num == -1) { int n; n = ioctl( dfb_vt->fd0, VT_OPENQRY, &dfb_vt->num ); if (n < 0 || dfb_vt->num == -1) { D_PERROR( "DirectFB/core/vt: Cannot allocate VT!\n" ); close( dfb_vt->fd0 ); D_FREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } } else { dfb_vt->num = dfb_config->vt_num; } /* move vt to framebuffer */ dfb_vt->old_fb = vt_get_fb( dfb_vt->num ); vt_set_fb( dfb_vt->num, -1 ); /* switch to vt */ while (ioctl( dfb_vt->fd0, VT_ACTIVATE, dfb_vt->num ) < 0) { if (errno == EINTR) continue; D_PERROR( "DirectFB/core/vt: VT_ACTIVATE failed!\n" ); close( dfb_vt->fd0 ); D_FREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } while (ioctl( dfb_vt->fd0, VT_WAITACTIVE, dfb_vt->num ) < 0) { if (errno == EINTR) continue; D_PERROR( "DirectFB/core/vt: VT_WAITACTIVE failed!\n" ); close( dfb_vt->fd0 ); D_FREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } usleep( 40000 ); } ret = vt_init_switching(); if (ret) { if (dfb_config->vt_switch) { D_DEBUG_AT( VT, " -> switching back...\n" ); ioctl( dfb_vt->fd0, VT_ACTIVATE, dfb_vt->prev ); ioctl( dfb_vt->fd0, VT_WAITACTIVE, dfb_vt->prev ); D_DEBUG_AT( VT, " -> ...switched back\n" ); ioctl( dfb_vt->fd0, VT_DISALLOCATE, dfb_vt->num ); } close( dfb_vt->fd0 ); D_FREE( dfb_vt ); dfb_vt = NULL; return ret; } dfb_fbdev->vt = dfb_vt; return DFB_OK; }
DFBResult dfb_vt_shutdown( bool emergency ) { const char cursoron_str[] = "\033[?0;0;0c"; const char blankon_str[] = "\033[9;10]"; D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ ); if (!dfb_vt) return DFB_OK; if (dfb_config->vt_switching) { if (ioctl( dfb_vt->fd, VT_SETMODE, &dfb_vt->vt_mode ) < 0) D_PERROR( "DirectFB/fbdev/vt: Unable to restore VT mode!!!\n" ); sigaction( SIG_SWITCH_FROM, &dfb_vt->sig_usr1, NULL ); sigaction( SIG_SWITCH_TO, &dfb_vt->sig_usr2, NULL ); direct_thread_cancel( dfb_vt->thread ); direct_thread_join( dfb_vt->thread ); direct_thread_destroy( dfb_vt->thread ); pthread_mutex_destroy( &dfb_vt->lock ); pthread_cond_destroy( &dfb_vt->wait ); } if (dfb_config->kd_graphics) { if (ioctl( dfb_vt->fd, KDSETMODE, KD_TEXT ) < 0) D_PERROR( "DirectFB/Keyboard: KD_TEXT failed!\n" ); } else { write( dfb_vt->fd, blankon_str, sizeof(blankon_str) ); } write( dfb_vt->fd, cursoron_str, sizeof(cursoron_str) ); if (dfb_config->vt_switch) { D_DEBUG_AT( VT, " -> switching back...\n" ); if (ioctl( dfb_vt->fd0, VT_ACTIVATE, dfb_vt->prev ) < 0) D_PERROR( "DirectFB/core/vt: VT_ACTIVATE" ); if (ioctl( dfb_vt->fd0, VT_WAITACTIVE, dfb_vt->prev ) < 0) D_PERROR( "DirectFB/core/vt: VT_WAITACTIVE" ); D_DEBUG_AT( VT, " -> switched back...\n" ); usleep( 40000 ); /* restore con2fbmap */ vt_set_fb( dfb_vt->num, dfb_vt->old_fb ); if (close( dfb_vt->fd ) < 0) D_PERROR( "DirectFB/core/vt: Unable to " "close file descriptor of allocated VT!\n" ); if (ioctl( dfb_vt->fd0, VT_DISALLOCATE, dfb_vt->num ) < 0) D_PERROR( "DirectFB/core/vt: Unable to disallocate VT!\n" ); } else { /* restore con2fbmap */ vt_set_fb( dfb_vt->num, dfb_vt->old_fb ); if (close( dfb_vt->fd ) < 0) D_PERROR( "DirectFB/core/vt: Unable to " "close file descriptor of current VT!\n" ); } if (close( dfb_vt->fd0 ) < 0) D_PERROR( "DirectFB/core/vt: Unable to " "close file descriptor of tty0!\n" ); D_FREE( dfb_vt ); dfb_vt = dfb_fbdev->vt = NULL; return DFB_OK; }
DFBResult dfb_vt_initialize() { DFBResult ret; struct vt_stat vs; dfb_vt = (VirtualTerminal*)DFBCALLOC( 1, sizeof(VirtualTerminal) ); Sdfb_vt = (VirtualTerminalShared*)shmalloc( sizeof(VirtualTerminal) ); setsid(); dfb_vt->fd0 = open( "/dev/tty0", O_WRONLY ); if (dfb_vt->fd0 < 0) { if (errno == ENOENT) { dfb_vt->fd0 = open( "/dev/vc/0", O_RDWR ); if (dfb_vt->fd0 < 0) { if (errno == ENOENT) { PERRORMSG( "DirectFB/core/vt: Couldn't open " "neither `/dev/tty0' nor `/dev/vc/0'!\n" ); } else { PERRORMSG( "DirectFB/core/vt: " "Error opening `/dev/vc/0'!\n" ); } DFBFREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } } else { PERRORMSG( "DirectFB/core/vt: Error opening `/dev/tty0'!\n"); DFBFREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } } if (ioctl( dfb_vt->fd0, VT_GETSTATE, &vs ) < 0) { PERRORMSG( "DirectFB/core/vt: VT_GETSTATE failed!\n" ); close( dfb_vt->fd0 ); DFBFREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } Sdfb_vt->prev = vs.v_active; if (!dfb_config->vt_switch) { dfb_vt->fd = dfb_vt->fd0; Sdfb_vt->num = Sdfb_vt->prev; /* move vt to framebuffer */ Sdfb_vt->old_fb = vt_get_fb( Sdfb_vt->num ); vt_set_fb( Sdfb_vt->num, -1 ); } else { int n; n = ioctl( dfb_vt->fd0, VT_OPENQRY, &Sdfb_vt->num ); if (n < 0 || Sdfb_vt->num == -1) { PERRORMSG( "DirectFB/core/vt: Cannot allocate VT!\n" ); close( dfb_vt->fd0 ); DFBFREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } /* move vt to framebuffer */ Sdfb_vt->old_fb = vt_get_fb( Sdfb_vt->num ); vt_set_fb( Sdfb_vt->num, -1 ); /* switch to vt */ while (ioctl( dfb_vt->fd0, VT_ACTIVATE, Sdfb_vt->num ) < 0) { if (errno == EINTR) continue; PERRORMSG( "DirectFB/core/vt: VT_ACTIVATE failed!\n" ); close( dfb_vt->fd0 ); DFBFREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } while (ioctl( dfb_vt->fd0, VT_WAITACTIVE, Sdfb_vt->num ) < 0) { if (errno == EINTR) continue; PERRORMSG( "DirectFB/core/vt: VT_WAITACTIVE failed!\n" ); close( dfb_vt->fd0 ); DFBFREE( dfb_vt ); dfb_vt = NULL; return DFB_INIT; } usleep( 40000 ); } ret = vt_init_switching(); if (ret) { if (dfb_config->vt_switch) { DEBUGMSG( "switching back...\n" ); ioctl( dfb_vt->fd0, VT_ACTIVATE, Sdfb_vt->prev ); ioctl( dfb_vt->fd0, VT_WAITACTIVE, Sdfb_vt->prev ); DEBUGMSG( "...switched back\n" ); ioctl( dfb_vt->fd0, VT_DISALLOCATE, Sdfb_vt->num ); } close( dfb_vt->fd0 ); DFBFREE( dfb_vt ); dfb_vt = NULL; return ret; } return DFB_OK; }