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