Back to home page

OSCL-LXR

 
 

    


0001 #include <errno.h>
0002 #include <signal.h>
0003 #include <stdbool.h>
0004 #include <stdlib.h>
0005 #include <unistd.h>
0006 #include <linux/kernel.h>
0007 #ifdef HAVE_BACKTRACE_SUPPORT
0008 #include <execinfo.h>
0009 #endif
0010 
0011 #include "../../util/debug.h"
0012 #include "../../perf.h"
0013 #include "../browser.h"
0014 #include "../helpline.h"
0015 #include "../ui.h"
0016 #include "../util.h"
0017 #include "../libslang.h"
0018 #include "../keysyms.h"
0019 #include "tui.h"
0020 
0021 static volatile int ui__need_resize;
0022 
0023 extern struct perf_error_ops perf_tui_eops;
0024 extern bool tui_helpline__set;
0025 
0026 extern void hist_browser__init_hpp(void);
0027 
0028 void ui__refresh_dimensions(bool force)
0029 {
0030     if (force || ui__need_resize) {
0031         ui__need_resize = 0;
0032         pthread_mutex_lock(&ui__lock);
0033         SLtt_get_screen_size();
0034         SLsmg_reinit_smg();
0035         pthread_mutex_unlock(&ui__lock);
0036     }
0037 }
0038 
0039 static void ui__sigwinch(int sig __maybe_unused)
0040 {
0041     ui__need_resize = 1;
0042 }
0043 
0044 static void ui__setup_sigwinch(void)
0045 {
0046     static bool done;
0047 
0048     if (done)
0049         return;
0050 
0051     done = true;
0052     pthread__unblock_sigwinch();
0053     signal(SIGWINCH, ui__sigwinch);
0054 }
0055 
0056 int ui__getch(int delay_secs)
0057 {
0058     struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
0059     fd_set read_set;
0060     int err, key;
0061 
0062     ui__setup_sigwinch();
0063 
0064     FD_ZERO(&read_set);
0065     FD_SET(0, &read_set);
0066 
0067     if (delay_secs) {
0068         timeout.tv_sec = delay_secs;
0069         timeout.tv_usec = 0;
0070     }
0071 
0072         err = select(1, &read_set, NULL, NULL, ptimeout);
0073 
0074     if (err == 0)
0075         return K_TIMER;
0076 
0077     if (err == -1) {
0078         if (errno == EINTR)
0079             return K_RESIZE;
0080         return K_ERROR;
0081     }
0082 
0083     key = SLang_getkey();
0084     if (key != K_ESC)
0085         return key;
0086 
0087     FD_ZERO(&read_set);
0088     FD_SET(0, &read_set);
0089     timeout.tv_sec = 0;
0090     timeout.tv_usec = 20;
0091         err = select(1, &read_set, NULL, NULL, &timeout);
0092     if (err == 0)
0093         return K_ESC;
0094 
0095     SLang_ungetkey(key);
0096     return SLkp_getkey();
0097 }
0098 
0099 #ifdef HAVE_BACKTRACE_SUPPORT
0100 static void ui__signal_backtrace(int sig)
0101 {
0102     void *stackdump[32];
0103     size_t size;
0104 
0105     ui__exit(false);
0106     psignal(sig, "perf");
0107 
0108     printf("-------- backtrace --------\n");
0109     size = backtrace(stackdump, ARRAY_SIZE(stackdump));
0110     backtrace_symbols_fd(stackdump, size, STDOUT_FILENO);
0111 
0112     exit(0);
0113 }
0114 #else
0115 # define ui__signal_backtrace  ui__signal
0116 #endif
0117 
0118 static void ui__signal(int sig)
0119 {
0120     ui__exit(false);
0121     psignal(sig, "perf");
0122     exit(0);
0123 }
0124 
0125 int ui__init(void)
0126 {
0127     int err;
0128 
0129     SLutf8_enable(-1);
0130     SLtt_get_terminfo();
0131     SLtt_get_screen_size();
0132 
0133     err = SLsmg_init_smg();
0134     if (err < 0)
0135         goto out;
0136     err = SLang_init_tty(-1, 0, 0);
0137     if (err < 0)
0138         goto out;
0139 
0140     err = SLkp_init();
0141     if (err < 0) {
0142         pr_err("TUI initialization failed.\n");
0143         goto out;
0144     }
0145 
0146     SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);
0147 
0148     signal(SIGSEGV, ui__signal_backtrace);
0149     signal(SIGFPE, ui__signal_backtrace);
0150     signal(SIGINT, ui__signal);
0151     signal(SIGQUIT, ui__signal);
0152     signal(SIGTERM, ui__signal);
0153 
0154     perf_error__register(&perf_tui_eops);
0155 
0156     ui_helpline__init();
0157     ui_browser__init();
0158     tui_progress__init();
0159 
0160     hist_browser__init_hpp();
0161 out:
0162     return err;
0163 }
0164 
0165 void ui__exit(bool wait_for_ok)
0166 {
0167     if (wait_for_ok && tui_helpline__set)
0168         ui__question_window("Fatal Error",
0169                     ui_helpline__last_msg,
0170                     "Press any key...", 0);
0171 
0172     SLtt_set_cursor_visibility(1);
0173     if (!pthread_mutex_trylock(&ui__lock)) {
0174         SLsmg_refresh();
0175         SLsmg_reset_smg();
0176         pthread_mutex_unlock(&ui__lock);
0177     }
0178     SLang_reset_tty();
0179     perf_error__unregister(&perf_tui_eops);
0180 }