summaryrefslogtreecommitdiffstats
path: root/tty-term.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2009-08-03 14:10:54 +0000
committerNicholas Marriott <nicm@openbsd.org>2009-08-03 14:10:54 +0000
commit1673735f0271c6f87e6ba0d85d8b4a1d0f2f3d35 (patch)
tree27a8faaf2b54de7cf47d822da839c6d62368a44a /tty-term.c
parente4bb08e1f5ebf47620758795efcbdd61849b73e8 (diff)
Add a terminal-overrides session option allowing individual terminfo(5) entries
to be overridden. The 88col/256col checks are now moved into the default setting and out of the code. Also remove a couple of old workarounds for xterm and rxvt which are no longer necessary (tmux can emulate them if missing).
Diffstat (limited to 'tty-term.c')
-rw-r--r--tty-term.c99
1 files changed, 79 insertions, 20 deletions
diff --git a/tty-term.c b/tty-term.c
index c8b47783..2813be61 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -19,12 +19,15 @@
#include <sys/types.h>
#include <curses.h>
+#include <fnmatch.h>
+#include <stdlib.h>
#include <string.h>
#include <term.h>
+#include <vis.h>
#include "tmux.h"
-void tty_term_quirks(struct tty_term *);
+void tty_term_override(struct tty_term *, const char *);
char *tty_term_strip(const char *);
struct tty_terms tty_terms = SLIST_HEAD_INITIALIZER(tty_terms);
@@ -140,27 +143,87 @@ tty_term_strip(const char *s)
}
void
-tty_term_quirks(struct tty_term *term)
+tty_term_override(struct tty_term *term, const char *overrides)
{
- if (strncmp(term->name, "rxvt", 4) == 0) {
- /* rxvt supports dch1 but some termcap files do not have it. */
- if (!tty_term_has(term, TTYC_DCH1)) {
- term->codes[TTYC_DCH1].type = TTYCODE_STRING;
- term->codes[TTYC_DCH1].value.string = xstrdup("\033[P");
+ struct tty_term_code_entry *ent;
+ struct tty_code *code;
+ char *termnext, *termstr, *entnext, *entstr;
+ char *s, *ptr, *val;
+ const char *errstr;
+ u_int i;
+ int n, removeflag;
+
+ s = xstrdup(overrides);
+
+ termnext = s;
+ while ((termstr = strsep(&termnext, ",")) != NULL) {
+ entnext = termstr;
+
+ entstr = strsep(&entnext, ":");
+ if (entstr == NULL || entnext == NULL)
+ continue;
+ if (fnmatch(entstr, term->name, 0) != 0)
+ continue;
+ while ((entstr = strsep(&entnext, ":")) != NULL) {
+ if (*entstr == '\0')
+ continue;
+
+ val = NULL;
+ removeflag = 0;
+ if ((ptr = strchr(entstr, '=')) != NULL) {
+ *ptr++ = '\0';
+ val = xstrdup(ptr);
+ if (strunvis(val, ptr) == NULL) {
+ xfree(val);
+ val = xstrdup(ptr);
+ }
+ } else if (entstr[strlen(entstr) - 1] == '@') {
+ entstr[strlen(entstr) - 1] = '\0';
+ removeflag = 1;
+ }
+
+ for (i = 0; i < NTTYCODE; i++) {
+ ent = &tty_term_codes[i];
+ if (strcmp(entstr, ent->name) != 0)
+ continue;
+ code = &term->codes[ent->code];
+
+ if (removeflag) {
+ code->type = TTYCODE_NONE;
+ continue;
+ }
+ switch (ent->type) {
+ case TTYCODE_NONE:
+ break;
+ case TTYCODE_STRING:
+ xfree(code->value.string);
+ code->value.string = xstrdup(val);
+ code->type = ent->type;
+ break;
+ case TTYCODE_NUMBER:
+ n = strtonum(val, 0, INT_MAX, &errstr);
+ if (errstr != NULL)
+ break;
+ code->value.number = n;
+ code->type = ent->type;
+ break;
+ case TTYCODE_FLAG:
+ code->value.flag = 1;
+ code->type = ent->type;
+ break;
+ }
+ }
+
+ if (val != NULL)
+ xfree(val);
}
}
- if (strncmp(term->name, "xterm", 5) == 0) {
- /* xterm supports ich1 but some termcaps omit it. */
- if (!tty_term_has(term, TTYC_ICH1)) {
- term->codes[TTYC_ICH1].type = TTYCODE_STRING;
- term->codes[TTYC_ICH1].value.string = xstrdup("\033[@");
- }
- }
+ xfree(s);
}
struct tty_term *
-tty_term_find(char *name, int fd, char **cause)
+tty_term_find(char *name, int fd, const char *overrides, char **cause)
{
struct tty_term *term;
struct tty_term_code_entry *ent;
@@ -235,7 +298,7 @@ tty_term_find(char *name, int fd, char **cause)
break;
}
}
- tty_term_quirks(term);
+ tty_term_override(term, overrides);
/* Delete curses data. */
del_curterm(cur_term);
@@ -297,12 +360,8 @@ tty_term_find(char *name, int fd, char **cause)
*/
if (tty_term_number(term, TTYC_COLORS) == 256)
term->flags |= TERM_256COLOURS;
- if (strstr(name, "256col") != NULL) /* XXX HACK */
- term->flags |= TERM_256COLOURS;
if (tty_term_number(term, TTYC_COLORS) == 88)
term->flags |= TERM_88COLOURS;
- if (strstr(name, "88col") != NULL) /* XXX HACK */
- term->flags |= TERM_88COLOURS;
/*
* Terminals without xenl (eat newline glitch) wrap at at $COLUMNS - 1