#include #include #include #include "../cache.h" #include "../debug.h" #include "browser.h" #include "helpline.h" #include "ui.h" #include "util.h" #include "libslang.h" #include "keysyms.h" pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; static volatile int ui__need_resize; void ui__refresh_dimensions(bool force) { if (force || ui__need_resize) { ui__need_resize = 0; pthread_mutex_lock(&ui__lock); SLtt_get_screen_size(); SLsmg_reinit_smg(); pthread_mutex_unlock(&ui__lock); } } static void ui__sigwinch(int sig __used) { ui__need_resize = 1; } static void ui__setup_sigwinch(void) { static bool done; if (done) return; done = true; pthread__unblock_sigwinch(); signal(SIGWINCH, ui__sigwinch); } int ui__getch(int delay_secs) { struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL; fd_set read_set; int err, key; ui__setup_sigwinch(); FD_ZERO(&read_set); FD_SET(0, &read_set); if (delay_secs) { timeout.tv_sec = delay_secs; timeout.tv_usec = 0; } err = select(1, &read_set, NULL, NULL, ptimeout); if (err == 0) return K_TIMER; if (err == -1) { if (errno == EINTR) return K_RESIZE; return K_ERROR; } key = SLang_getkey(); if (key != K_ESC) return key; FD_ZERO(&read_set); FD_SET(0, &read_set); timeout.tv_sec = 0; timeout.tv_usec = 20; err = select(1, &read_set, NULL, NULL, &timeout); if (err == 0) return K_ESC; SLang_ungetkey(key); return SLkp_getkey(); } static void newt_suspend(void *d __used) { newtSuspend(); raise(SIGTSTP); newtResume(); } static int ui__init(void) { int err = SLkp_init(); if (err < 0) goto out; SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB); out: return err; } static void ui__exit(void) { SLtt_set_cursor_visibility(1); SLsmg_refresh(); SLsmg_reset_smg(); SLang_reset_tty(); } static void ui__signal(int sig) { ui__exit(); psignal(sig, "perf"); exit(0); } void setup_browser(bool fallback_to_pager) { if (!isatty(1) || !use_browser || dump_trace) { use_browser = 0; if (fallback_to_pager) setup_pager(); return; } use_browser = 1; newtInit(); ui__init(); newtSetSuspendCallback(newt_suspend, NULL); ui_helpline__init(); ui_browser__init(); signal(SIGSEGV, ui__signal); signal(SIGFPE, ui__signal); signal(SIGINT, ui__signal); signal(SIGQUIT, ui__signal); signal(SIGTERM, ui__signal); } void exit_browser(bool wait_for_ok) { if (use_browser > 0) { if (wait_for_ok) ui__question_window("Fatal Error", ui_helpline__last_msg, "Press any key...", 0); ui__exit(); } }