int tb_init_fd(int inout_) { inout = inout_; if (inout == -1) { return TB_EFAILED_TO_OPEN_TTY; } if (init_term() < 0) { close(inout); return TB_EUNSUPPORTED_TERMINAL; } if (pipe(winch_fds) < 0) { close(inout); return TB_EPIPE_TRAP_ERROR; } struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigwinch_handler; sa.sa_flags = 0; sigaction(SIGWINCH, &sa, 0); tcgetattr(inout, &orig_tios); struct termios tios; memcpy(&tios, &orig_tios, sizeof(tios)); tios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); tios.c_oflag &= ~OPOST; tios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tios.c_cflag &= ~(CSIZE | PARENB); tios.c_cflag |= CS8; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = 0; tcsetattr(inout, TCSAFLUSH, &tios); bytebuffer_init(&input_buffer, 128); bytebuffer_init(&output_buffer, 32 * 1024); bytebuffer_puts(&output_buffer, funcs[T_ENTER_CA]); bytebuffer_puts(&output_buffer, funcs[T_ENTER_KEYPAD]); bytebuffer_puts(&output_buffer, funcs[T_HIDE_CURSOR]); send_clear(); update_term_size(); cellbuf_init(&back_buffer, termw, termh); cellbuf_init(&front_buffer, termw, termh); cellbuf_clear(&back_buffer); cellbuf_clear(&front_buffer); return 0; }
int tb_init(void) { out = open("/dev/tty", O_WRONLY); in = fopen("/dev/tty", "r"); if (out == -1 || !in) return TB_EFAILED_TO_OPEN_TTY; out_fileno = out; in_fileno = fileno(in); if (init_term() < 0) return TB_EUNSUPPORTED_TERMINAL; if (pipe(winch_fds) < 0) return TB_EPIPE_TRAP_ERROR; struct sigaction sa; sa.sa_handler = sigwinch_handler; sa.sa_flags = 0; sigaction(SIGWINCH, &sa, 0); tcgetattr(out_fileno, &orig_tios); struct termios tios; memcpy(&tios, &orig_tios, sizeof(tios)); tios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); tios.c_oflag &= ~OPOST; tios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tios.c_cflag &= ~(CSIZE | PARENB); tios.c_cflag |= CS8; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = 0; tcsetattr(out_fileno, TCSAFLUSH, &tios); memstream_init(&write_buffer, out_fileno, write_buffer_data, sizeof(write_buffer_data)); memstream_puts(&write_buffer, funcs[T_ENTER_CA]); memstream_puts(&write_buffer, funcs[T_ENTER_KEYPAD]); memstream_puts(&write_buffer, funcs[T_HIDE_CURSOR]); send_clear(); update_term_size(); cellbuf_init(&back_buffer, termw, termh); cellbuf_init(&front_buffer, termw, termh); cellbuf_clear(&back_buffer); cellbuf_clear(&front_buffer); init_ringbuffer(&inbuf, 4096); return 0; }
static void update_size(void) { update_term_size(); cellbuf_resize(&back_buffer, termw, termh); cellbuf_resize(&front_buffer, termw, termh); cellbuf_clear(&front_buffer); send_clear(); }
void tb_clear(void) { if (buffer_size_change_request) { update_size(); buffer_size_change_request = 0; } cellbuf_clear(&back_buffer); }
static void cellbuf_resize(struct cellbuf *buf, unsigned int width, unsigned int height) { if (buf->width == width && buf->height == height) return; unsigned int oldw = buf->width; unsigned int oldh = buf->height; struct tb_cell *oldcells = buf->cells; cellbuf_init(buf, width, height); cellbuf_clear(buf); unsigned int minw = (width < oldw) ? width : oldw; unsigned int minh = (height < oldh) ? height : oldh; unsigned int i; for (i = 0; i < minh; ++i) { struct tb_cell *csrc = oldcells + (i * oldw); struct tb_cell *cdst = buf->cells + (i * width); memcpy(cdst, csrc, sizeof(struct tb_cell) * minw); } free(oldcells); }