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