Save term data in a linked list and reuse it.

This commit is contained in:
Nicholas Marriott 2007-12-06 18:28:55 +00:00
parent 08d7be638e
commit 2bc8108b3e
3 changed files with 149 additions and 99 deletions

7
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.45 2007-12-06 09:46:23 nicm Exp $ */
/* $Id: tmux.c,v 1.46 2007-12-06 18:28:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -32,8 +32,13 @@
#include "tmux.h"
#ifdef DEBUG
#ifdef __OpenBSD__
const char *malloc_options = "AFGJPX";
#endif
#ifdef __FreeBSD__
const char *_malloc_options = "AJX";
#endif
#endif
volatile sig_atomic_t sigwinch;
volatile sig_atomic_t sigterm;

14
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.111 2007-12-06 10:36:01 nicm Exp $ */
/* $Id: tmux.h,v 1.112 2007-12-06 18:28:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -556,11 +556,19 @@ struct tty_key {
RB_ENTRY(tty_key) entry;
};
struct tty_term {
char *name;
TERMINAL *term;
u_int references;
TAILQ_ENTRY(tty_term) entry;
};
struct tty {
char *path;
char *term;
TERMINAL *termp;
char *termname;
struct tty_term *term;
int fd;
struct buffer *in;

227
tty.c
View File

@ -1,4 +1,4 @@
/* $Id: tty.c,v 1.11 2007-12-06 11:11:15 nicm Exp $ */
/* $Id: tty.c,v 1.12 2007-12-06 18:28:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -30,6 +30,9 @@
#include "tmux.h"
struct tty_term *tty_find_term(char *, int,char **);
void tty_free_term(struct tty_term *);
void tty_fill_acs(struct tty *);
u_char tty_get_acs(struct tty *, u_char);
@ -40,18 +43,20 @@ void tty_putc(struct tty *, char);
void tty_attributes(struct tty *, u_char, u_char);
char tty_translate(char);
TAILQ_HEAD(, tty_term) tty_terms = TAILQ_HEAD_INITIALIZER(tty_terms);
void
tty_init(struct tty *tty, char *path, char *term)
{
tty->path = xstrdup(path);
tty->term = xstrdup(term);
tty->termname = xstrdup(term);
}
int
tty_open(struct tty *tty, char **cause)
{
struct termios tio;
int error, what;
int what;
tty->fd = open(tty->path, O_RDWR|O_NONBLOCK);
if (tty->fd == -1) {
@ -59,10 +64,117 @@ tty_open(struct tty *tty, char **cause)
return (-1);
}
tty->termp = NULL;
if (tty->term == NULL)
tty->term = xstrdup("unknown");
if (setupterm(tty->term, tty->fd, &error) != OK) {
if (tty->termname == NULL)
tty->termname = xstrdup("unknown");
if ((tty->term = tty_find_term(tty->termname, tty->fd, cause)) == NULL)
goto error;
tty->in = buffer_create(BUFSIZ);
tty->out = buffer_create(BUFSIZ);
tty->attr = SCREEN_DEFATTR;
tty->colr = SCREEN_DEFCOLR;
tty_keys_init(tty);
tty_fill_acs(tty);
if (tcgetattr(tty->fd, &tty->tio) != 0)
fatal("tcgetattr failed");
memset(&tio, 0, sizeof tio);
tio.c_iflag = TTYDEF_IFLAG & ~(IXON|IXOFF|ICRNL|INLCR);
tio.c_oflag = TTYDEF_OFLAG & ~(OPOST|ONLCR|OCRNL|ONLRET);
tio.c_lflag =
TTYDEF_LFLAG & ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG);
tio.c_cflag = TTYDEF_CFLAG;
memcpy(&tio.c_cc, ttydefchars, sizeof tio.c_cc);
cfsetspeed(&tio, TTYDEF_SPEED);
if (tcsetattr(tty->fd, TCSANOW, &tio) != 0)
fatal("tcsetattr failed");
what = 0;
if (ioctl(tty->fd, TIOCFLUSH, &what) != 0)
fatal("ioctl(TIOCFLUSH)");
if (enter_ca_mode != NULL)
tty_puts(tty, enter_ca_mode);
if (keypad_xmit != NULL)
tty_puts(tty, keypad_xmit);
if (ena_acs != NULL)
tty_puts(tty, ena_acs);
tty_puts(tty, clear_screen);
return (0);
error:
close(tty->fd);
tty->fd = -1;
return (-1);
}
void
tty_close(struct tty *tty)
{
struct winsize ws;
if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
if (tcsetattr(tty->fd, TCSANOW, &tty->tio) != 0)
fatal("tcsetattr failed");
if (change_scroll_region != NULL)
tty_raw(tty, tparm(change_scroll_region, 0, ws.ws_row - 1));
if (keypad_local != NULL)
tty_raw(tty, keypad_local);
if (exit_ca_mode != NULL)
tty_raw(tty, exit_ca_mode);
tty_raw(tty, clear_screen);
if (cursor_normal != NULL)
tty_raw(tty, cursor_normal);
if (exit_attribute_mode != NULL)
tty_raw(tty, exit_attribute_mode);
tty_free_term(tty->term);
tty_keys_free(tty);
close(tty->fd);
tty->fd = -1;
buffer_destroy(tty->in);
buffer_destroy(tty->out);
}
void
tty_free(struct tty *tty)
{
if (tty->fd != -1)
tty_close(tty);
if (tty->path != NULL)
xfree(tty->path);
if (tty->termname != NULL)
xfree(tty->termname);
}
struct tty_term *
tty_find_term(char *name, int fd, char **cause)
{
struct tty_term *term;
int error;
TAILQ_FOREACH(term, &tty_terms, entry) {
if (strcmp(term->name, name) == 0)
return (term);
}
term = xmalloc(sizeof *term);
term->name = xstrdup(name);
term->term = NULL;
term->references = 1;
TAILQ_INSERT_HEAD(&tty_terms, term, entry);
if (setupterm(name, fd, &error) != OK) {
switch (error) {
case 0:
xasprintf(cause, "can't use hardcopy terminal");
@ -79,9 +191,8 @@ tty_open(struct tty *tty, char **cause)
}
goto error;
}
tty->termp = cur_term;
term->term = cur_term;
/* Check for required capabilities. */
if (clear_screen == NULL) {
xasprintf(cause, "clear_screen missing");
goto error;
@ -144,100 +255,26 @@ tty_open(struct tty *tty, char **cause)
goto error;
}
tty->in = buffer_create(BUFSIZ);
tty->out = buffer_create(BUFSIZ);
tty->attr = SCREEN_DEFATTR;
tty->colr = SCREEN_DEFCOLR;
tty_keys_init(tty);
tty_fill_acs(tty);
if (tcgetattr(tty->fd, &tty->tio) != 0)
fatal("tcgetattr failed");
memset(&tio, 0, sizeof tio);
tio.c_iflag = TTYDEF_IFLAG & ~(IXON|IXOFF|ICRNL|INLCR);
tio.c_oflag = TTYDEF_OFLAG & ~(OPOST|ONLCR|OCRNL|ONLRET);
tio.c_lflag =
TTYDEF_LFLAG & ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG);
tio.c_cflag = TTYDEF_CFLAG;
memcpy(&tio.c_cc, ttydefchars, sizeof tio.c_cc);
cfsetspeed(&tio, TTYDEF_SPEED);
if (tcsetattr(tty->fd, TCSANOW, &tio) != 0)
fatal("tcsetattr failed");
what = 0;
if (ioctl(tty->fd, TIOCFLUSH, &what) != 0)
fatal("ioctl(TIOCFLUSH)");
if (enter_ca_mode != NULL)
tty_puts(tty, enter_ca_mode);
if (keypad_xmit != NULL)
tty_puts(tty, keypad_xmit);
if (ena_acs != NULL)
tty_puts(tty, ena_acs);
tty_puts(tty, clear_screen);
return (0);
return (term);
error:
close(tty->fd);
tty->fd = -1;
if (tty->termp != NULL)
del_curterm(tty->termp);
return (-1);
tty_free_term(term);
return (NULL);
}
void
tty_close(struct tty *tty)
tty_free_term(struct tty_term *term)
{
struct winsize ws;
if (--term->references != 0)
return;
if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
if (tcsetattr(tty->fd, TCSANOW, &tty->tio) != 0)
fatal("tcsetattr failed");
TAILQ_REMOVE(&tty_terms, term, entry);
if (change_scroll_region != NULL)
tty_raw(tty, tparm(change_scroll_region, 0, ws.ws_row - 1));
if (keypad_local != NULL)
tty_raw(tty, keypad_local);
if (exit_ca_mode != NULL)
tty_raw(tty, exit_ca_mode);
tty_raw(tty, clear_screen);
if (cursor_normal != NULL)
tty_raw(tty, cursor_normal);
if (exit_attribute_mode != NULL)
tty_raw(tty, exit_attribute_mode);
if (term->term != NULL)
del_curterm(term->term);
if (tty->termp != NULL)
del_curterm(tty->termp);
tty_keys_free(tty);
close(tty->fd);
tty->fd = -1;
buffer_destroy(tty->in);
buffer_destroy(tty->out);
}
void
tty_free(struct tty *tty)
{
if (tty->fd != -1)
tty_close(tty);
if (tty->path != NULL) {
xfree(tty->path);
tty->path = NULL;
}
if (tty->term != NULL) {
xfree(tty->term);
tty->term = NULL;
}
xfree(term->name);
xfree(term);
}
void
@ -286,7 +323,7 @@ tty_vwrite(struct tty *tty, unused struct screen *s, int cmd, va_list ap)
char ch;
u_int i, ua, ub;
set_curterm(tty->termp);
set_curterm(tty->term->term);
switch (cmd) {
case TTY_CHARACTER: