linux/tools/perf/ui/tui/setup.c
<<
>>
Prefs
   1#include <signal.h>
   2#include <stdbool.h>
   3#ifdef HAVE_BACKTRACE_SUPPORT
   4#include <execinfo.h>
   5#endif
   6
   7#include "../../util/cache.h"
   8#include "../../util/debug.h"
   9#include "../browser.h"
  10#include "../helpline.h"
  11#include "../ui.h"
  12#include "../util.h"
  13#include "../libslang.h"
  14#include "../keysyms.h"
  15#include "tui.h"
  16
  17static volatile int ui__need_resize;
  18
  19extern struct perf_error_ops perf_tui_eops;
  20extern bool tui_helpline__set;
  21
  22extern void hist_browser__init_hpp(void);
  23
  24void ui__refresh_dimensions(bool force)
  25{
  26        if (force || ui__need_resize) {
  27                ui__need_resize = 0;
  28                pthread_mutex_lock(&ui__lock);
  29                SLtt_get_screen_size();
  30                SLsmg_reinit_smg();
  31                pthread_mutex_unlock(&ui__lock);
  32        }
  33}
  34
  35static void ui__sigwinch(int sig __maybe_unused)
  36{
  37        ui__need_resize = 1;
  38}
  39
  40static void ui__setup_sigwinch(void)
  41{
  42        static bool done;
  43
  44        if (done)
  45                return;
  46
  47        done = true;
  48        pthread__unblock_sigwinch();
  49        signal(SIGWINCH, ui__sigwinch);
  50}
  51
  52int ui__getch(int delay_secs)
  53{
  54        struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
  55        fd_set read_set;
  56        int err, key;
  57
  58        ui__setup_sigwinch();
  59
  60        FD_ZERO(&read_set);
  61        FD_SET(0, &read_set);
  62
  63        if (delay_secs) {
  64                timeout.tv_sec = delay_secs;
  65                timeout.tv_usec = 0;
  66        }
  67
  68        err = select(1, &read_set, NULL, NULL, ptimeout);
  69
  70        if (err == 0)
  71                return K_TIMER;
  72
  73        if (err == -1) {
  74                if (errno == EINTR)
  75                        return K_RESIZE;
  76                return K_ERROR;
  77        }
  78
  79        key = SLang_getkey();
  80        if (key != K_ESC)
  81                return key;
  82
  83        FD_ZERO(&read_set);
  84        FD_SET(0, &read_set);
  85        timeout.tv_sec = 0;
  86        timeout.tv_usec = 20;
  87        err = select(1, &read_set, NULL, NULL, &timeout);
  88        if (err == 0)
  89                return K_ESC;
  90
  91        SLang_ungetkey(key);
  92        return SLkp_getkey();
  93}
  94
  95#ifdef HAVE_BACKTRACE_SUPPORT
  96static void ui__signal_backtrace(int sig)
  97{
  98        void *stackdump[32];
  99        size_t size;
 100
 101        ui__exit(false);
 102        psignal(sig, "perf");
 103
 104        printf("-------- backtrace --------\n");
 105        size = backtrace(stackdump, ARRAY_SIZE(stackdump));
 106        backtrace_symbols_fd(stackdump, size, STDOUT_FILENO);
 107
 108        exit(0);
 109}
 110#else
 111# define ui__signal_backtrace  ui__signal
 112#endif
 113
 114static void ui__signal(int sig)
 115{
 116        ui__exit(false);
 117        psignal(sig, "perf");
 118        exit(0);
 119}
 120
 121int ui__init(void)
 122{
 123        int err;
 124
 125        SLutf8_enable(-1);
 126        SLtt_get_terminfo();
 127        SLtt_get_screen_size();
 128
 129        err = SLsmg_init_smg();
 130        if (err < 0)
 131                goto out;
 132        err = SLang_init_tty(-1, 0, 0);
 133        if (err < 0)
 134                goto out;
 135
 136        err = SLkp_init();
 137        if (err < 0) {
 138                pr_err("TUI initialization failed.\n");
 139                goto out;
 140        }
 141
 142        SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);
 143
 144        signal(SIGSEGV, ui__signal_backtrace);
 145        signal(SIGFPE, ui__signal_backtrace);
 146        signal(SIGINT, ui__signal);
 147        signal(SIGQUIT, ui__signal);
 148        signal(SIGTERM, ui__signal);
 149
 150        perf_error__register(&perf_tui_eops);
 151
 152        ui_helpline__init();
 153        ui_browser__init();
 154        tui_progress__init();
 155
 156        hist_browser__init_hpp();
 157out:
 158        return err;
 159}
 160
 161void ui__exit(bool wait_for_ok)
 162{
 163        if (wait_for_ok && tui_helpline__set)
 164                ui__question_window("Fatal Error",
 165                                    ui_helpline__last_msg,
 166                                    "Press any key...", 0);
 167
 168        SLtt_set_cursor_visibility(1);
 169        SLsmg_refresh();
 170        SLsmg_reset_smg();
 171        SLang_reset_tty();
 172
 173        perf_error__unregister(&perf_tui_eops);
 174}
 175