#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "termbox.h" #include "bytebuffer.inl" #include "output.inl" #include "input.inl" struct cellbuf { int width; int height; struct tb_cell *cells; }; #define CELL(buf, x, y) (buf)->cells[(y) * (buf)->width + (x)] #define IS_CURSOR_HIDDEN(cx, cy) (cx == -1 || cy == -1) #define LAST_COORD_INIT -1 static struct termios orig_tios; static struct cellbuf back_buffer; static struct cellbuf front_buffer; static struct bytebuffer output_buffer; static struct bytebuffer input_buffer; static int termw = -1; static int termh = -1; static int inout; static int winch_fds[2]; static int lastx = LAST_COORD_INIT; static int lasty = LAST_COORD_INIT; static int cursor_x = -1; static int cursor_y = -1; static uint16_t background = TB_BLACK; static uint16_t foreground = TB_WHITE; static void write_cursor(int x, int y); static void write_sgr(uint16_t fg, uint16_t bg); static void cellbuf_init(struct cellbuf *buf, int width, int height); static void cellbuf_resize(struct cellbuf *buf, int width, int height); static void cellbuf_clear(struct cellbuf *buf); static void cellbuf_free(struct cellbuf *buf); static void update_size(void); static void update_term_size(void); static void send_attr(uint16_t fg, uint16_t bg); static void send_char(int x, int y, uint32_t c); static void send_clear(void); static void sigwinch_handler(int xxx); static int wait_fill_event(struct tb_event *event, struct timeval *timeout); /* may happen in a different thread */ static volatile int buffer_size_change_request; /* -------------------------------------------------------- */ int tb_init(void) { inout = open("/dev/tty", O_RDWR); 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]); bytebuffer_puts(&output_buffer, funcs[T_ENTER_MOUSE]); 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; } void tb_shutdown(void) { if (termw == -1) return; bytebuffer_puts(&output_buffer, funcs[T_SHOW_CURSOR]); bytebuffer_puts(&output_buffer, funcs[T_SGR0]); bytebuffer_puts(&output_buffer, funcs[T_CLEAR_SCREEN]); bytebuffer_puts(&output_buffer, funcs[T_EXIT_CA]); bytebuffer_puts(&output_buffer, funcs[T_EXIT_KEYPAD]); bytebuffer_puts(&output_buffer, funcs[T_EXIT_MOUSE]); bytebuffer_flush(&output_buffer, inout); tcsetattr(inout, TCSAFLUSH, &orig_tios); shutdown_term(); close(inout); close(winch_fds[0]); close(winch_fds[1]); cellbuf_free(&back_buffer); cellbuf_free(&front_buffer); bytebuffer_free(&output_buffer); bytebuffer_free(&input_buffer); termw = termh = -1; } int tb_is_active(void) { return termw != -1; } void tb_present(void) { int x,y,w,i; struct tb_cell *back, *front; assert(termw != -1); /* invalidate cursor position */ lastx = LAST_COORD_INIT; lasty = LAST_COORD_INIT; if (buffer_size_change_request) { update_size(); buffer_size_change_request = 0; } for (y = 0; y < front_buffer.height; ++y) { for (x = 0; x < front_buffer.width; ) { back = &CELL(&back_buffer, x, y); front = &CELL(&front_buffer, x, y); w = wcwidth(back->ch); if (w < 1) w = 1; if (memcmp(back, front, sizeof(struct tb_cell)) == 0) { x += w; continue; } memcpy(front, back, sizeof(struct tb_cell)); send_attr(back->fg, back->bg); if
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
 * See LICENSE file for license details.
 */
#include "dwm.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

/* extern */

void *
emallocz(unsigned int size) {
	void *res = calloc(1, size);

	if(!res)
		eprint("fatal: could not malloc() %u bytes\n", size);
	return res;
}

void
eprint(const char *errstr, ...) {
	va_list ap;

	va_start(ap, errstr);
	vfprintf(stderr, errstr, ap);
	va_end(ap);
	exit(EXIT_FAILURE);
}

void
spawn(