/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "tmux.h"
void tty_fill_acs(struct tty *);
void tty_raw(struct tty *, const char *);
int tty_try_256(struct tty *, u_char, const char *);
int tty_try_88(struct tty *, u_char, const char *);
void tty_attributes(struct tty *, const struct grid_cell *);
void tty_attributes_fg(struct tty *, const struct grid_cell *);
void tty_attributes_bg(struct tty *, const struct grid_cell *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_cell(struct tty *,
const struct grid_cell *, const struct grid_utf8 *);
void
tty_init(struct tty *tty, char *path, char *term)
{
tty->path = xstrdup(path);
if (term == NULL || *term == '\0')
tty->termname = xstrdup("unknown");
else
tty->termname = xstrdup(term);
tty->flags = 0;
tty->term_flags = 0;
}
int
tty_open(struct tty *tty, char **cause)
{
int mode;
tty->fd = open(tty->path, O_RDWR|O_NONBLOCK);
if (tty->fd == -1) {
xasprintf(cause, "%s: %s", tty->path, strerror(errno));
return (-1);
}
if ((mode = fcntl(tty->fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(tty->fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
if (debug_level > 3)
tty->log_fd = open("tmux.out", O_WRONLY|O_CREAT|O_TRUNC, 0644);
else
tty->log_fd = -1;
if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL)
goto error;
tty->in = buffer_create(BUFSIZ);
tty->out = buffer_create(BUFSIZ);
tty->flags &= TTY_UTF8;
tty_start_tty(tty);
tty_keys_init(tty);
tty_fill_acs(tty);
return (0);
error:
close(tty->fd);
tty->fd = -1;
return (-1);
}
void
tty_start_tty(struct tty *tty)
{
struct termios tio;
int what;
#if 0
tty_detect_utf8(tty);
#endif
if (tcgetattr(tty->fd, &tty->tio) != 0)
fatal("tcgetattr failed");
memcpy(&tio, &tty->tio, sizeof tio);
tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
tio.c_iflag |= IGNBRK;
tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|
ECHOPRT|ECHOKE|ECHOCTL|ISIG);
tio.