brintos

brintos / linux-shallow public Read only

0
0
Text · 3.7 KiB · 16c6eff Raw
202 lines · c
1#include <errno.h>2#include <signal.h>3#include <stdbool.h>4#include <stdlib.h>5#include <termios.h>6#include <unistd.h>7#include <linux/kernel.h>8#ifdef HAVE_BACKTRACE_SUPPORT9#include <execinfo.h>10#endif11 12#include "../../util/color.h"13#include "../../util/debug.h"14#include "../browser.h"15#include "../helpline.h"16#include "../ui.h"17#include "../util.h"18#include "../libslang.h"19#include "../keysyms.h"20#include "tui.h"21 22static volatile int ui__need_resize;23 24extern struct perf_error_ops perf_tui_eops;25extern bool tui_helpline__set;26 27extern void hist_browser__init_hpp(void);28 29void ui__refresh_dimensions(bool force)30{31	if (force || ui__need_resize) {32		ui__need_resize = 0;33		mutex_lock(&ui__lock);34		SLtt_get_screen_size();35		SLsmg_reinit_smg();36		mutex_unlock(&ui__lock);37	}38}39 40static void ui__sigwinch(int sig __maybe_unused)41{42	ui__need_resize = 1;43}44 45static void ui__setup_sigwinch(void)46{47	static bool done;48 49	if (done)50		return;51 52	done = true;53	pthread__unblock_sigwinch();54	signal(SIGWINCH, ui__sigwinch);55}56 57int ui__getch(int delay_secs)58{59	struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;60	fd_set read_set;61	int err, key;62 63	ui__setup_sigwinch();64 65	FD_ZERO(&read_set);66	FD_SET(0, &read_set);67 68	if (delay_secs) {69		timeout.tv_sec = delay_secs;70		timeout.tv_usec = 0;71	}72 73        err = select(1, &read_set, NULL, NULL, ptimeout);74 75	if (err == 0)76		return K_TIMER;77 78	if (err == -1) {79		if (errno == EINTR)80			return K_RESIZE;81		return K_ERROR;82	}83 84	key = SLang_getkey();85	if (key != K_ESC)86		return key;87 88	FD_ZERO(&read_set);89	FD_SET(0, &read_set);90	timeout.tv_sec = 0;91	timeout.tv_usec = 20;92        err = select(1, &read_set, NULL, NULL, &timeout);93	if (err == 0)94		return K_ESC;95 96	SLang_ungetkey(key);97	return SLkp_getkey();98}99 100#ifdef HAVE_BACKTRACE_SUPPORT101static void ui__signal_backtrace(int sig)102{103	void *stackdump[32];104	size_t size;105 106	ui__exit(false);107	psignal(sig, "perf");108 109	printf("-------- backtrace --------\n");110	size = backtrace(stackdump, ARRAY_SIZE(stackdump));111	backtrace_symbols_fd(stackdump, size, STDOUT_FILENO);112 113	exit(0);114}115#else116# define ui__signal_backtrace  ui__signal117#endif118 119static void ui__signal(int sig)120{121	ui__exit(false);122	psignal(sig, "perf");123	exit(0);124}125 126static void ui__sigcont(int sig)127{128	static struct termios tty;129 130	if (sig == SIGTSTP) {131		while (tcgetattr(SLang_TT_Read_FD, &tty) == -1 && errno == EINTR)132			;133		while (write(SLang_TT_Read_FD, PERF_COLOR_RESET, sizeof(PERF_COLOR_RESET) - 1) == -1 && errno == EINTR)134			;135		raise(SIGSTOP);136	} else {137		while (tcsetattr(SLang_TT_Read_FD, TCSADRAIN, &tty) == -1 && errno == EINTR)138			;139		raise(SIGWINCH);140	}141}142 143int ui__init(void)144{145	int err;146 147	SLutf8_enable(-1);148	SLtt_get_terminfo();149	SLtt_get_screen_size();150 151	err = SLsmg_init_smg();152	if (err < 0)153		goto out;154	err = SLang_init_tty(-1, 0, 0);155	if (err < 0)156		goto out;157	SLtty_set_suspend_state(true);158 159	err = SLkp_init();160	if (err < 0) {161		pr_err("TUI initialization failed.\n");162		goto out;163	}164 165	SLkp_define_keysym("^(kB)", SL_KEY_UNTAB);166 167	signal(SIGSEGV, ui__signal_backtrace);168	signal(SIGFPE, ui__signal_backtrace);169	signal(SIGINT, ui__signal);170	signal(SIGQUIT, ui__signal);171	signal(SIGTERM, ui__signal);172	signal(SIGTSTP, ui__sigcont);173	signal(SIGCONT, ui__sigcont);174 175	perf_error__register(&perf_tui_eops);176 177	ui_helpline__init();178	ui_browser__init();179	tui_progress__init();180 181	hist_browser__init_hpp();182out:183	return err;184}185 186void ui__exit(bool wait_for_ok)187{188	if (wait_for_ok && tui_helpline__set)189		ui__question_window("Fatal Error",190				    ui_helpline__last_msg,191				    "Press any key...", 0);192 193	SLtt_set_cursor_visibility(1);194	if (mutex_trylock(&ui__lock)) {195		SLsmg_refresh();196		SLsmg_reset_smg();197		mutex_unlock(&ui__lock);198	}199	SLang_reset_tty();200	perf_error__unregister(&perf_tui_eops);201}202