setup.c 3.0 KB

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