mirror of
https://github.com/tmate-io/tmate.git
synced 2024-12-24 15:48:58 +01:00
Save term data in a linked list and reuse it.
This commit is contained in:
parent
08d7be638e
commit
2bc8108b3e
7
tmux.c
7
tmux.c
@ -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>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -32,8 +32,13 @@
|
|||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
#ifdef __OpenBSD__
|
||||||
const char *malloc_options = "AFGJPX";
|
const char *malloc_options = "AFGJPX";
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
const char *_malloc_options = "AJX";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
volatile sig_atomic_t sigwinch;
|
volatile sig_atomic_t sigwinch;
|
||||||
volatile sig_atomic_t sigterm;
|
volatile sig_atomic_t sigterm;
|
||||||
|
14
tmux.h
14
tmux.h
@ -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>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -556,11 +556,19 @@ struct tty_key {
|
|||||||
RB_ENTRY(tty_key) entry;
|
RB_ENTRY(tty_key) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tty_term {
|
||||||
|
char *name;
|
||||||
|
TERMINAL *term;
|
||||||
|
u_int references;
|
||||||
|
|
||||||
|
TAILQ_ENTRY(tty_term) entry;
|
||||||
|
};
|
||||||
|
|
||||||
struct tty {
|
struct tty {
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
char *term;
|
char *termname;
|
||||||
TERMINAL *termp;
|
struct tty_term *term;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct buffer *in;
|
struct buffer *in;
|
||||||
|
227
tty.c
227
tty.c
@ -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>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
#include "tmux.h"
|
#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 *);
|
void tty_fill_acs(struct tty *);
|
||||||
u_char tty_get_acs(struct tty *, u_char);
|
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);
|
void tty_attributes(struct tty *, u_char, u_char);
|
||||||
char tty_translate(char);
|
char tty_translate(char);
|
||||||
|
|
||||||
|
TAILQ_HEAD(, tty_term) tty_terms = TAILQ_HEAD_INITIALIZER(tty_terms);
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_init(struct tty *tty, char *path, char *term)
|
tty_init(struct tty *tty, char *path, char *term)
|
||||||
{
|
{
|
||||||
tty->path = xstrdup(path);
|
tty->path = xstrdup(path);
|
||||||
tty->term = xstrdup(term);
|
tty->termname = xstrdup(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
tty_open(struct tty *tty, char **cause)
|
tty_open(struct tty *tty, char **cause)
|
||||||
{
|
{
|
||||||
struct termios tio;
|
struct termios tio;
|
||||||
int error, what;
|
int what;
|
||||||
|
|
||||||
tty->fd = open(tty->path, O_RDWR|O_NONBLOCK);
|
tty->fd = open(tty->path, O_RDWR|O_NONBLOCK);
|
||||||
if (tty->fd == -1) {
|
if (tty->fd == -1) {
|
||||||
@ -59,10 +64,117 @@ tty_open(struct tty *tty, char **cause)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tty->termp = NULL;
|
if (tty->termname == NULL)
|
||||||
if (tty->term == NULL)
|
tty->termname = xstrdup("unknown");
|
||||||
tty->term = xstrdup("unknown");
|
if ((tty->term = tty_find_term(tty->termname, tty->fd, cause)) == NULL)
|
||||||
if (setupterm(tty->term, tty->fd, &error) != OK) {
|
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) {
|
switch (error) {
|
||||||
case 0:
|
case 0:
|
||||||
xasprintf(cause, "can't use hardcopy terminal");
|
xasprintf(cause, "can't use hardcopy terminal");
|
||||||
@ -79,9 +191,8 @@ tty_open(struct tty *tty, char **cause)
|
|||||||
}
|
}
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
tty->termp = cur_term;
|
term->term = cur_term;
|
||||||
|
|
||||||
/* Check for required capabilities. */
|
|
||||||
if (clear_screen == NULL) {
|
if (clear_screen == NULL) {
|
||||||
xasprintf(cause, "clear_screen missing");
|
xasprintf(cause, "clear_screen missing");
|
||||||
goto error;
|
goto error;
|
||||||
@ -144,100 +255,26 @@ tty_open(struct tty *tty, char **cause)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tty->in = buffer_create(BUFSIZ);
|
return (term);
|
||||||
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:
|
error:
|
||||||
close(tty->fd);
|
tty_free_term(term);
|
||||||
tty->fd = -1;
|
return (NULL);
|
||||||
|
|
||||||
if (tty->termp != NULL)
|
|
||||||
del_curterm(tty->termp);
|
|
||||||
|
|
||||||
return (-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
TAILQ_REMOVE(&tty_terms, term, entry);
|
||||||
fatal("ioctl(TIOCGWINSZ)");
|
|
||||||
if (tcsetattr(tty->fd, TCSANOW, &tty->tio) != 0)
|
|
||||||
fatal("tcsetattr failed");
|
|
||||||
|
|
||||||
if (change_scroll_region != NULL)
|
if (term->term != NULL)
|
||||||
tty_raw(tty, tparm(change_scroll_region, 0, ws.ws_row - 1));
|
del_curterm(term->term);
|
||||||
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 (tty->termp != NULL)
|
xfree(term->name);
|
||||||
del_curterm(tty->termp);
|
xfree(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);
|
|
||||||
tty->path = NULL;
|
|
||||||
}
|
|
||||||
if (tty->term != NULL) {
|
|
||||||
xfree(tty->term);
|
|
||||||
tty->term = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -286,7 +323,7 @@ tty_vwrite(struct tty *tty, unused struct screen *s, int cmd, va_list ap)
|
|||||||
char ch;
|
char ch;
|
||||||
u_int i, ua, ub;
|
u_int i, ua, ub;
|
||||||
|
|
||||||
set_curterm(tty->termp);
|
set_curterm(tty->term->term);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TTY_CHARACTER:
|
case TTY_CHARACTER:
|
||||||
|
Loading…
Reference in New Issue
Block a user