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 13 static volatile int ui__need_resize; 14 15 extern struct perf_error_ops perf_tui_eops; 16 17 extern void hist_browser__init_hpp(void); 18 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 30 static void ui__sigwinch(int sig __maybe_unused) 31 { 32 ui__need_resize = 1; 33 } 34 35 static 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 47 int 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 90 static void ui__signal(int sig) 91 { 92 ui__exit(false); 93 psignal(sig, "perf"); 94 exit(0); 95 } 96 97 int 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(); 133 out: 134 return err; 135 } 136 137 void 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