Move the terminal start/stop code into their own functions, exported (undocumented for now)

This commit is contained in:
Paul LeoNerd Evans 2012-03-08 21:15:25 +00:00
parent f7e4986849
commit 43a83e6e96
3 changed files with 81 additions and 47 deletions

View File

@ -45,6 +45,7 @@ struct _TermKey {
int waittime; // msec int waittime; // msec
char is_closed; char is_closed;
char is_started;
int nkeynames; int nkeynames;
const char **keynames; const char **keynames;

124
termkey.c
View File

@ -195,6 +195,7 @@ static TermKey *termkey_alloc(void)
tk->waittime = 50; /* msec */ tk->waittime = 50; /* msec */
tk->is_closed = 0; tk->is_closed = 0;
tk->is_started = 0;
tk->nkeynames = 64; tk->nkeynames = 64;
tk->keynames = NULL; tk->keynames = NULL;
@ -270,51 +271,10 @@ static int termkey_init(TermKey *tk, const char *term)
goto abort_free_keynames; goto abort_free_keynames;
} }
if(tk->fd != -1 && !(tk->flags & TERMKEY_FLAG_NOTERMIOS)) {
struct termios termios;
if(tcgetattr(tk->fd, &termios) == 0) {
tk->restore_termios = termios;
tk->restore_termios_valid = 1;
termios.c_iflag &= ~(IXON|INLCR|ICRNL);
termios.c_lflag &= ~(ICANON|ECHO);
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
if(tk->flags & TERMKEY_FLAG_CTRLC)
/* want no signal keys at all, so just disable ISIG */
termios.c_lflag &= ~ISIG;
else {
/* Disable Ctrl-\==VQUIT and Ctrl-D==VSUSP but leave Ctrl-C as SIGINT */
termios.c_cc[VQUIT] = _POSIX_VDISABLE;
termios.c_cc[VSUSP] = _POSIX_VDISABLE;
/* Some OSes have Ctrl-Y==VDSUSP */
#ifdef VDSUSP
termios.c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif
}
#ifdef DEBUG
fprintf(stderr, "Setting termios(3) flags\n");
#endif
tcsetattr(tk->fd, TCSANOW, &termios);
}
}
struct TermKeyDriverNode *p;
for(p = tk->drivers; p; p = p->next)
if(p->driver->start_driver)
if(!(*p->driver->start_driver)(tk, p->info))
goto abort_free_drivers;
#ifdef DEBUG
fprintf(stderr, "Drivers started; termkey instance %p is ready\n", tk);
#endif
return 1; return 1;
abort_free_drivers: abort_free_drivers:
for(p = tk->drivers; p; ) { for(struct TermKeyDriverNode *p = tk->drivers; p; ) {
(*p->driver->free_driver)(p->info); (*p->driver->free_driver)(p->info);
struct TermKeyDriverNode *next = p->next; struct TermKeyDriverNode *next = p->next;
free(p); free(p);
@ -361,12 +321,17 @@ TermKey *termkey_new(int fd, int flags)
const char *term = getenv("TERM"); const char *term = getenv("TERM");
if(!termkey_init(tk, term)) { if(!termkey_init(tk, term))
free(tk); goto abort;
return NULL;
} if(!termkey_start(tk))
goto abort;
return tk; return tk;
abort:
free(tk);
return NULL;
} }
TermKey *termkey_new_abstract(const char *term, int flags) TermKey *termkey_new_abstract(const char *term, int flags)
@ -384,6 +349,8 @@ TermKey *termkey_new_abstract(const char *term, int flags)
return NULL; return NULL;
} }
termkey_start(tk);
return tk; return tk;
} }
@ -405,6 +372,67 @@ void termkey_free(TermKey *tk)
void termkey_destroy(TermKey *tk) void termkey_destroy(TermKey *tk)
{ {
if(tk->is_started)
termkey_stop(tk);
termkey_free(tk);
}
int termkey_start(TermKey *tk)
{
if(tk->is_started)
return 1;
if(tk->fd != -1 && !(tk->flags & TERMKEY_FLAG_NOTERMIOS)) {
struct termios termios;
if(tcgetattr(tk->fd, &termios) == 0) {
tk->restore_termios = termios;
tk->restore_termios_valid = 1;
termios.c_iflag &= ~(IXON|INLCR|ICRNL);
termios.c_lflag &= ~(ICANON|ECHO);
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
if(tk->flags & TERMKEY_FLAG_CTRLC)
/* want no signal keys at all, so just disable ISIG */
termios.c_lflag &= ~ISIG;
else {
/* Disable Ctrl-\==VQUIT and Ctrl-D==VSUSP but leave Ctrl-C as SIGINT */
termios.c_cc[VQUIT] = _POSIX_VDISABLE;
termios.c_cc[VSUSP] = _POSIX_VDISABLE;
/* Some OSes have Ctrl-Y==VDSUSP */
#ifdef VDSUSP
termios.c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif
}
#ifdef DEBUG
fprintf(stderr, "Setting termios(3) flags\n");
#endif
tcsetattr(tk->fd, TCSANOW, &termios);
}
}
struct TermKeyDriverNode *p;
for(p = tk->drivers; p; p = p->next)
if(p->driver->start_driver)
if(!(*p->driver->start_driver)(tk, p->info))
return 0;
#ifdef DEBUG
fprintf(stderr, "Drivers started; termkey instance %p is ready\n", tk);
#endif
tk->is_started = 1;
return 1;
}
int termkey_stop(TermKey *tk)
{
if(!tk->is_started)
return 1;
struct TermKeyDriverNode *p; struct TermKeyDriverNode *p;
for(p = tk->drivers; p; p = p->next) for(p = tk->drivers; p; p = p->next)
if(p->driver->stop_driver) if(p->driver->stop_driver)
@ -413,7 +441,9 @@ void termkey_destroy(TermKey *tk)
if(tk->restore_termios_valid) if(tk->restore_termios_valid)
tcsetattr(tk->fd, TCSANOW, &tk->restore_termios); tcsetattr(tk->fd, TCSANOW, &tk->restore_termios);
termkey_free(tk); tk->is_started = 0;
return 1;
} }
int termkey_get_fd(TermKey *tk) int termkey_get_fd(TermKey *tk)

View File

@ -161,6 +161,9 @@ TermKey *termkey_new_abstract(const char *term, int flags);
void termkey_free(TermKey *tk); void termkey_free(TermKey *tk);
void termkey_destroy(TermKey *tk); void termkey_destroy(TermKey *tk);
int termkey_start(TermKey *tk);
int termkey_stop(TermKey *tk);
int termkey_get_fd(TermKey *tk); int termkey_get_fd(TermKey *tk);
int termkey_get_flags(TermKey *tk); int termkey_get_flags(TermKey *tk);