aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--termkey-internal.h1
-rw-r--r--termkey.c124
-rw-r--r--termkey.h.in3
3 files changed, 81 insertions, 47 deletions
diff --git a/termkey-internal.h b/termkey-internal.h
index e277939..17ff677 100644
--- a/termkey-internal.h
+++ b/termkey-internal.h
@@ -45,6 +45,7 @@ struct _TermKey {
int waittime; // msec
char is_closed;
+ char is_started;
int nkeynames;
const char **keynames;
diff --git a/termkey.c b/termkey.c
index 8e443d1..9286149 100644
--- a/termkey.c
+++ b/termkey.c
@@ -195,6 +195,7 @@ static TermKey *termkey_alloc(void)
tk->waittime = 50; /* msec */
tk->is_closed = 0;
+ tk->is_started = 0;
tk->nkeynames = 64;
tk->keynames = NULL;
@@ -270,51 +271,10 @@ static int termkey_init(TermKey *tk, const char *term)
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;
abort_free_drivers:
- for(p = tk->drivers; p; ) {
+ for(struct TermKeyDriverNode *p = tk->drivers; p; ) {
(*p->driver->free_driver)(p->info);
struct TermKeyDriverNode *next = p->next;
free(p);
@@ -361,12 +321,17 @@ TermKey *termkey_new(int fd, int flags)
const char *term = getenv("TERM");
- if(!termkey_init(tk, term)) {
- free(tk);
- return NULL;
- }
+ if(!termkey_init(tk, term))
+ goto abort;
+
+ if(!termkey_start(tk))
+ goto abort;
return tk;
+
+abort:
+ free(tk);
+ return NULL;
}
TermKey *termkey_new_abstract(const char *term, int flags)
@@ -384,6 +349,8 @@ TermKey *termkey_new_abstract(const char *term, int flags)
return NULL;
}
+ termkey_start(tk);
+
return tk;
}
@@ -405,6 +372,67 @@ void termkey_free(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;
for(p = tk->drivers; p; p = p->next)
if(p->driver->stop_driver)
@@ -413,7 +441,9 @@ void termkey_destroy(TermKey *tk)
if(tk->restore_termios_valid)
tcsetattr(tk->fd, TCSANOW, &tk->restore_termios);
- termkey_free(tk);
+ tk->is_started = 0;
+
+ return 1;
}
int termkey_get_fd(TermKey *tk)
diff --git a/termkey.h.in b/termkey.h.in
index d7317b0..5b7a2ce 100644
--- a/termkey.h.in
+++ b/termkey.h.in
@@ -161,6 +161,9 @@ TermKey *termkey_new_abstract(const char *term, int flags);
void termkey_free(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_flags(TermKey *tk);