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