2016-07-07 11:38:09 -03:00
# include <errno.h>
2012-04-30 13:55:08 +09:00
# include <signal.h>
# include <stdbool.h>
2019-07-04 11:21:24 -03:00
# include <stdlib.h>
2019-09-03 10:56:06 -03:00
# include <unistd.h>
2017-04-17 11:39:06 -03:00
# include <linux/kernel.h>
2014-12-22 13:44:11 +09:00
# ifdef HAVE_BACKTRACE_SUPPORT
# include <execinfo.h>
# endif
2012-04-30 13:55:08 +09:00
# include "../../util/debug.h"
2019-08-29 15:20:59 -03:00
# include "../../perf.h"
2012-04-30 13:55:08 +09:00
# include "../browser.h"
# include "../helpline.h"
# include "../ui.h"
# include "../util.h"
# include "../libslang.h"
# include "../keysyms.h"
2013-10-23 14:08:48 -03:00
# include "tui.h"
2012-04-30 13:55:08 +09:00
static volatile int ui__need_resize ;
2012-05-29 13:22:58 +09:00
extern struct perf_error_ops perf_tui_eops ;
2015-01-20 15:40:50 +09:00
extern bool tui_helpline__set ;
2012-05-29 13:22:58 +09:00
2012-09-03 11:53:09 +09:00
extern void hist_browser__init_hpp ( void ) ;
2012-04-30 13:55:08 +09:00
void ui__refresh_dimensions ( bool force )
{
if ( force | | ui__need_resize ) {
ui__need_resize = 0 ;
2022-08-26 09:42:33 -07:00
mutex_lock ( & ui__lock ) ;
2012-04-30 13:55:08 +09:00
SLtt_get_screen_size ( ) ;
SLsmg_reinit_smg ( ) ;
2022-08-26 09:42:33 -07:00
mutex_unlock ( & ui__lock ) ;
2012-04-30 13:55:08 +09:00
}
}
2012-09-11 01:15:03 +03:00
static void ui__sigwinch ( int sig __maybe_unused )
2012-04-30 13:55:08 +09:00
{
ui__need_resize = 1 ;
}
static void ui__setup_sigwinch ( void )
{
static bool done ;
if ( done )
return ;
done = true ;
pthread__unblock_sigwinch ( ) ;
signal ( SIGWINCH , ui__sigwinch ) ;
}
int ui__getch ( int delay_secs )
{
struct timeval timeout , * ptimeout = delay_secs ? & timeout : NULL ;
fd_set read_set ;
int err , key ;
ui__setup_sigwinch ( ) ;
FD_ZERO ( & read_set ) ;
FD_SET ( 0 , & read_set ) ;
if ( delay_secs ) {
timeout . tv_sec = delay_secs ;
timeout . tv_usec = 0 ;
}
err = select ( 1 , & read_set , NULL , NULL , ptimeout ) ;
if ( err = = 0 )
return K_TIMER ;
if ( err = = - 1 ) {
if ( errno = = EINTR )
return K_RESIZE ;
return K_ERROR ;
}
key = SLang_getkey ( ) ;
if ( key ! = K_ESC )
return key ;
FD_ZERO ( & read_set ) ;
FD_SET ( 0 , & read_set ) ;
timeout . tv_sec = 0 ;
timeout . tv_usec = 20 ;
err = select ( 1 , & read_set , NULL , NULL , & timeout ) ;
if ( err = = 0 )
return K_ESC ;
SLang_ungetkey ( key ) ;
return SLkp_getkey ( ) ;
}
2014-12-22 13:44:11 +09:00
# ifdef HAVE_BACKTRACE_SUPPORT
static void ui__signal_backtrace ( int sig )
{
void * stackdump [ 32 ] ;
size_t size ;
ui__exit ( false ) ;
psignal ( sig , " perf " ) ;
printf ( " -------- backtrace -------- \n " ) ;
size = backtrace ( stackdump , ARRAY_SIZE ( stackdump ) ) ;
backtrace_symbols_fd ( stackdump , size , STDOUT_FILENO ) ;
exit ( 0 ) ;
}
# else
# define ui__signal_backtrace ui__signal
# endif
2012-04-30 13:55:08 +09:00
static void ui__signal ( int sig )
{
ui__exit ( false ) ;
psignal ( sig , " perf " ) ;
exit ( 0 ) ;
}
2012-04-30 13:55:09 +09:00
int ui__init ( void )
2012-04-30 13:55:08 +09:00
{
int err ;
2013-03-28 11:34:10 -03:00
SLutf8_enable ( - 1 ) ;
SLtt_get_terminfo ( ) ;
SLtt_get_screen_size ( ) ;
err = SLsmg_init_smg ( ) ;
if ( err < 0 )
goto out ;
2015-05-29 21:53:44 +09:00
err = SLang_init_tty ( - 1 , 0 , 0 ) ;
2013-03-28 11:34:10 -03:00
if ( err < 0 )
goto out ;
2012-04-30 13:55:08 +09:00
err = SLkp_init ( ) ;
if ( err < 0 ) {
pr_err ( " TUI initialization failed. \n " ) ;
goto out ;
}
SLkp_define_keysym ( ( char * ) " ^(kB) " , SL_KEY_UNTAB ) ;
2014-12-22 13:44:11 +09:00
signal ( SIGSEGV , ui__signal_backtrace ) ;
signal ( SIGFPE , ui__signal_backtrace ) ;
2012-04-30 13:55:08 +09:00
signal ( SIGINT , ui__signal ) ;
signal ( SIGQUIT , ui__signal ) ;
signal ( SIGTERM , ui__signal ) ;
2012-05-29 13:22:58 +09:00
perf_error__register ( & perf_tui_eops ) ;
2012-09-03 11:53:09 +09:00
2015-10-22 16:44:17 -03:00
ui_helpline__init ( ) ;
ui_browser__init ( ) ;
tui_progress__init ( ) ;
2012-09-03 11:53:09 +09:00
hist_browser__init_hpp ( ) ;
2012-04-30 13:55:08 +09:00
out :
return err ;
}
void ui__exit ( bool wait_for_ok )
{
2015-01-20 15:40:50 +09:00
if ( wait_for_ok & & tui_helpline__set )
2012-04-30 13:55:08 +09:00
ui__question_window ( " Fatal Error " ,
ui_helpline__last_msg ,
" Press any key... " , 0 ) ;
SLtt_set_cursor_visibility ( 1 ) ;
2022-08-26 09:42:33 -07:00
if ( mutex_trylock ( & ui__lock ) ) {
2021-12-29 16:55:19 +08:00
SLsmg_refresh ( ) ;
SLsmg_reset_smg ( ) ;
2022-08-26 09:42:33 -07:00
mutex_unlock ( & ui__lock ) ;
2021-12-29 16:55:19 +08:00
}
2012-04-30 13:55:08 +09:00
SLang_reset_tty ( ) ;
2012-05-29 13:22:58 +09:00
perf_error__unregister ( & perf_tui_eops ) ;
2012-04-30 13:55:08 +09:00
}