=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/tty-term.c,v retrieving revision 1.86 retrieving revision 1.87 diff -u -r1.86 -r1.87 --- src/usr.bin/tmux/tty-term.c 2021/02/05 12:29:19 1.86 +++ src/usr.bin/tmux/tty-term.c 2021/02/17 07:18:36 1.87 @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-term.c,v 1.86 2021/02/05 12:29:19 nicm Exp $ */ +/* $OpenBSD: tty-term.c,v 1.87 2021/02/17 07:18:36 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -450,7 +450,8 @@ } 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 @@ 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 @@ 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; + } } } @@ -641,6 +622,85 @@ LIST_REMOVE(term, entry); free(term->name); free(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