setup.c 3.1 KB

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