summaryrefslogtreecommitdiffstats
path: root/tty-term.c
diff options
context:
space:
mode:
authornicm <nicm>2021-02-17 07:18:36 +0000
committernicm <nicm>2021-02-17 07:18:36 +0000
commitaf3ffa9c41936078d27b5ba1f96cec67850f98cb (patch)
tree46ea40336e88d204e72ac5056eb930aadacb3cba /tty-term.c
parentd768fc2553c2bdec6bb7b026ffffdaee0dd102f4 (diff)
Move the call to setupterm() into the client and have it pass the
results to the server over imsg, means the server does not need to enter ncurses or read terminfo db. Old clients will not work with a new server.
Diffstat (limited to 'tty-term.c')
-rw-r--r--tty-term.c162
1 files changed, 111 insertions, 51 deletions
diff --git a/tty-term.c b/tty-term.c
index b989328c..c8048f77 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -450,7 +450,8 @@ tty_term_apply_overrides(struct tty_term *term)
}
struct tty_term *
-tty_term_create(struct tty *tty, char *name, int *feat, int fd, char **cause)
+tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
+ int *feat, char **cause)
{
struct tty_term *term;
const struct tty_term_code_entry *ent;
@@ -458,10 +459,9 @@ tty_term_create(struct tty *tty, char *name, int *feat, int fd, char **cause)
struct options_entry *o;
struct options_array_item *a;
union options_value *ov;
- u_int i;
- int n, error;
- const char *s, *acs;
- size_t offset;
+ u_int i, j;
+ const char *s, *acs, *value;
+ size_t offset, namelen;
char *first;
log_debug("adding term %s", name);
@@ -472,57 +472,38 @@ tty_term_create(struct tty *tty, char *name, int *feat, int fd, char **cause)
term->codes = xcalloc(tty_term_ncodes(), sizeof *term->codes);
LIST_INSERT_HEAD(&tty_terms, term, entry);
- /* Set up curses terminal. */
- if (setupterm(name, fd, &error) != OK) {
- switch (error) {
- case 1:
- xasprintf(cause, "can't use hardcopy terminal: %s",
- name);
- break;
- case 0:
- xasprintf(cause, "missing or unsuitable terminal: %s",
- name);
- break;
- case -1:
- xasprintf(cause, "can't find terminfo database");
- break;
- default:
- xasprintf(cause, "unknown error");
- break;
- }
- goto error;
- }
-
/* Fill in codes. */
- for (i = 0; i < tty_term_ncodes(); i++) {
- ent = &tty_term_codes[i];
+ for (i = 0; i < ncaps; i++) {
+ namelen = strcspn(caps[i], "=");
+ if (namelen == 0)
+ continue;
+ value = caps[i] + namelen + 1;
- code = &term->codes[i];
- code->type = TTYCODE_NONE;
- switch (ent->type) {
- case TTYCODE_NONE:
- break;
- case TTYCODE_STRING:
- s = tigetstr((char *) ent->name);
- if (s == NULL || s == (char *) -1)
+ for (j = 0; j < tty_term_ncodes(); j++) {
+ ent = &tty_term_codes[j];
+ if (strncmp(ent->name, caps[i], namelen) != 0)
+ continue;
+ if (ent->name[namelen] != '\0')
+ continue;
+
+ code = &term->codes[j];
+ code->type = TTYCODE_NONE;
+ switch (ent->type) {
+ case TTYCODE_NONE:
break;
- code->type = TTYCODE_STRING;
- code->value.string = tty_term_strip(s);
- break;
- case TTYCODE_NUMBER:
- n = tigetnum((char *) ent->name);
- if (n == -1 || n == -2)
+ case TTYCODE_STRING:
+ code->type = TTYCODE_STRING;
+ code->value.string = tty_term_strip(value);
break;
- code->type = TTYCODE_NUMBER;
- code->value.number = n;
- break;
- case TTYCODE_FLAG:
- n = tigetflag((char *) ent->name);
- if (n == -1)
+ case TTYCODE_NUMBER:
+ code->type = TTYCODE_NUMBER;
+ code->value.number = atoi(value);
break;
- code->type = TTYCODE_FLAG;
- code->value.flag = n;
- break;
+ case TTYCODE_FLAG:
+ code->type = TTYCODE_FLAG;
+ code->value.flag = (*value == '1');
+ break;
+ }
}
}
@@ -644,6 +625,85 @@ tty_term_free(struct tty_term *term)
}
int
+tty_term_read_list(const char *name, int fd, char ***caps, u_int *ncaps,
+ char **cause)
+{
+ const struct tty_term_code_entry *ent;
+ int error, n;
+ u_int i;
+ const char *s;
+ char tmp[11];
+
+ if (setupterm(name, fd, &error) != OK) {
+ switch (error) {
+ case 1:
+ xasprintf(cause, "can't use hardcopy terminal: %s",
+ name);
+ break;
+ case 0:
+ xasprintf(cause, "missing or unsuitable terminal: %s",
+ name);
+ break;
+ case -1:
+ xasprintf(cause, "can't find terminfo database");
+ break;
+ default:
+ xasprintf(cause, "unknown error");
+ break;
+ }
+ return (-1);
+ }
+
+ *ncaps = 0;
+ *caps = NULL;
+
+ for (i = 0; i < tty_term_ncodes(); i++) {
+ ent = &tty_term_codes[i];
+ switch (ent->type) {
+ case TTYCODE_NONE:
+ break;
+ case TTYCODE_STRING:
+ s = tigetstr((char *)ent->name);
+ if (s == NULL || s == (char *)-1)
+ continue;
+ break;
+ case TTYCODE_NUMBER:
+ n = tigetnum((char *)ent->name);
+ if (n == -1 || n == -2)
+ continue;
+ xsnprintf(tmp, sizeof tmp, "%d", n);
+ s = tmp;
+ break;
+ case TTYCODE_FLAG:
+ n = tigetflag((char *) ent->name);
+ if (n == -1)
+ continue;
+ if (n)
+ s = "1";
+ else
+ s = "0";
+ break;
+ }
+ *caps = xreallocarray(*caps, (*ncaps) + 1, sizeof **caps);
+ xasprintf(&(*caps)[*ncaps], "%s=%s", ent->name, s);
+ (*ncaps)++;
+ }
+
+ del_curterm(cur_term);
+ return (0);
+}
+
+void
+tty_term_free_list(char **caps, u_int ncaps)
+{
+ u_int i;
+
+ for (i = 0; i < ncaps; i++)
+ free(caps[i]);
+ free(caps);
+}
+
+int
tty_term_has(struct tty_term *term, enum tty_code_code code)
{
return (term->codes[code].type != TTYCODE_NONE);