diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2007-07-09 19:04:12 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2007-07-09 19:04:12 +0000 |
commit | a41ece5ff0d3ce7a0b7d987baa9759f8a012b48b (patch) | |
tree | 95adfffa5b036fe4c593254efd2b32aa03696b34 /local.c | |
parent | 2905e0ef10926ab6f538598228a71e40844a8be6 (diff) | |
download | rtmux-a41ece5ff0d3ce7a0b7d987baa9759f8a012b48b.tar.gz rtmux-a41ece5ff0d3ce7a0b7d987baa9759f8a012b48b.tar.bz2 rtmux-a41ece5ff0d3ce7a0b7d987baa9759f8a012b48b.zip |
Initial import to CVS. Basic functions are working, albeit with a couple of showstopper memory bugs and many missing features. Detaching, reattaching, creating new sessions, listing sessions work acceptably for using with shells. Simple curses programs (top, systat, tetris) and more complicated ones (mutt, emacs) that don't require scrolling regions (ESC[r) mostly work fine (including mutt, emacs). No status bar yet and no key remapping or other customisation.
Diffstat (limited to 'local.c')
-rw-r--r-- | local.c | 690 |
1 files changed, 690 insertions, 0 deletions
diff --git a/local.c b/local.c new file mode 100644 index 00000000..eeadb659 --- /dev/null +++ b/local.c @@ -0,0 +1,690 @@ +/* $Id: local.c,v 1.1.1.1 2007-07-09 19:03:30 nicm Exp $ */ + +/* + * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> + +#include <curses.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <term.h> +#include <unistd.h> + +#include "tmux.h" + +/* + * Functions to translate input and write output to the local client terminal. + * This file should probably be called tty or terminal.c. + */ + +int local_cmp(const void *, const void *); +int local_putc(int); +void local_putp(const char *); + +/* Local key types and key codes. */ +struct local_key { + const char *name; + char *string; + size_t size; + int code; +}; +struct local_key local_keys[] = { + { "ka1", NULL, 0, KEYC_A1 }, + { "ka3", NULL, 0, KEYC_A3 }, + { "kb2", NULL, 0, KEYC_B2 }, + { "kbs", NULL, 0, KEYC_BACKSPACE }, + { "kbeg", NULL, 0, KEYC_BEG }, + { "kcbt", NULL, 0, KEYC_BTAB }, + { "kc1", NULL, 0, KEYC_C1 }, + { "kc3", NULL, 0, KEYC_C3 }, + { "kcan", NULL, 0, KEYC_CANCEL }, + { "ktbc", NULL, 0, KEYC_CATAB }, + { "kclr", NULL, 0, KEYC_CLEAR }, + { "kclo", NULL, 0, KEYC_CLOSE }, + { "kcmd", NULL, 0, KEYC_COMMAND }, + { "kcpy", NULL, 0, KEYC_COPY }, + { "kcrt", NULL, 0, KEYC_CREATE }, + { "kctab", NULL, 0, KEYC_CTAB }, + { "kdch1", NULL, 0, KEYC_DC }, + { "kdl1", NULL, 0, KEYC_DL }, + { "kcud1", NULL, 0, KEYC_DOWN }, + { "krmir", NULL, 0, KEYC_EIC }, + { "kend", NULL, 0, KEYC_END }, + { "kent", NULL, 0, KEYC_ENTER }, + { "kel", NULL, 0, KEYC_EOL }, + { "ked", NULL, 0, KEYC_EOS }, + { "kext", NULL, 0, KEYC_EXIT }, + { "kf0", NULL, 0, KEYC_F0 }, + { "kf1", NULL, 0, KEYC_F1 }, + { "kf10", NULL, 0, KEYC_F10 }, + { "kf11", NULL, 0, KEYC_F11 }, + { "kf12", NULL, 0, KEYC_F12 }, + { "kf13", NULL, 0, KEYC_F13 }, + { "kf14", NULL, 0, KEYC_F14 }, + { "kf15", NULL, 0, KEYC_F15 }, + { "kf16", NULL, 0, KEYC_F16 }, + { "kf17", NULL, 0, KEYC_F17 }, + { "kf18", NULL, 0, KEYC_F18 }, + { "kf19", NULL, 0, KEYC_F19 }, + { "kf2", NULL, 0, KEYC_F2 }, + { "kf20", NULL, 0, KEYC_F20 }, + { "kf21", NULL, 0, KEYC_F21 }, + { "kf22", NULL, 0, KEYC_F22 }, + { "kf23", NULL, 0, KEYC_F23 }, + { "kf24", NULL, 0, KEYC_F24 }, + { "kf25", NULL, 0, KEYC_F25 }, + { "kf26", NULL, 0, KEYC_F26 }, + { "kf27", NULL, 0, KEYC_F27 }, + { "kf28", NULL, 0, KEYC_F28 }, + { "kf29", NULL, 0, KEYC_F29 }, + { "kf3", NULL, 0, KEYC_F3 }, + { "kf30", NULL, 0, KEYC_F30 }, + { "kf31", NULL, 0, KEYC_F31 }, + { "kf32", NULL, 0, KEYC_F32 }, + { "kf33", NULL, 0, KEYC_F33 }, + { "kf34", NULL, 0, KEYC_F34 }, + { "kf35", NULL, 0, KEYC_F35 }, + { "kf36", NULL, 0, KEYC_F36 }, + { "kf37", NULL, 0, KEYC_F37 }, + { "kf38", NULL, 0, KEYC_F38 }, + { "kf39", NULL, 0, KEYC_F39 }, + { "kf4", NULL, 0, KEYC_F4 }, + { "kf40", NULL, 0, KEYC_F40 }, + { "kf41", NULL, 0, KEYC_F41 }, + { "kf42", NULL, 0, KEYC_F42 }, + { "kf43", NULL, 0, KEYC_F43 }, + { "kf44", NULL, 0, KEYC_F44 }, + { "kf45", NULL, 0, KEYC_F45 }, + { "kf46", NULL, 0, KEYC_F46 }, + { "kf47", NULL, 0, KEYC_F47 }, + { "kf48", NULL, 0, KEYC_F48 }, + { "kf49", NULL, 0, KEYC_F49 }, + { "kf5", NULL, 0, KEYC_F5 }, + { "kf50", NULL, 0, KEYC_F50 }, + { "kf51", NULL, 0, KEYC_F51 }, + { "kf52", NULL, 0, KEYC_F52 }, + { "kf53", NULL, 0, KEYC_F53 }, + { "kf54", NULL, 0, KEYC_F54 }, + { "kf55", NULL, 0, KEYC_F55 }, + { "kf56", NULL, 0, KEYC_F56 }, + { "kf57", NULL, 0, KEYC_F57 }, + { "kf58", NULL, 0, KEYC_F58 }, + { "kf59", NULL, 0, KEYC_F59 }, + { "kf6", NULL, 0, KEYC_F6 }, + { "kf60", NULL, 0, KEYC_F60 }, + { "kf61", NULL, 0, KEYC_F61 }, + { "kf62", NULL, 0, KEYC_F62 }, + { "kf63", NULL, 0, KEYC_F63 }, + { "kf7", NULL, 0, KEYC_F7 }, + { "kf8", NULL, 0, KEYC_F8 }, + { "kf9", NULL, 0, KEYC_F9 }, + { "kfnd", NULL, 0, KEYC_FIND }, + { "khlp", NULL, 0, KEYC_HELP }, + { "khome", NULL, 0, KEYC_HOME }, + { "kich1", NULL, 0, KEYC_IC }, + { "kil1", NULL, 0, KEYC_IL }, + { "kcub1", NULL, 0, KEYC_LEFT }, + { "kll", NULL, 0, KEYC_LL }, + { "kmrk", NULL, 0, KEYC_MARK }, + { "kmsg", NULL, 0, KEYC_MESSAGE }, + { "kmov", NULL, 0, KEYC_MOVE }, + { "knxt", NULL, 0, KEYC_NEXT }, + { "knp", NULL, 0, KEYC_NPAGE }, + { "kopn", NULL, 0, KEYC_OPEN }, + { "kopt", NULL, 0, KEYC_OPTIONS }, + { "kpp", NULL, 0, KEYC_PPAGE }, + { "kprv", NULL, 0, KEYC_PREVIOUS }, + { "kprt", NULL, 0, KEYC_PRINT }, + { "krdo", NULL, 0, KEYC_REDO }, + { "kref", NULL, 0, KEYC_REFERENCE }, + { "krfr", NULL, 0, KEYC_REFRESH }, + { "krpl", NULL, 0, KEYC_REPLACE }, + { "krst", NULL, 0, KEYC_RESTART }, + { "kres", NULL, 0, KEYC_RESUME }, + { "kcuf1", NULL, 0, KEYC_RIGHT }, + { "ksav", NULL, 0, KEYC_SAVE }, + { "kBEG", NULL, 0, KEYC_SBEG }, + { "kCAN", NULL, 0, KEYC_SCANCEL }, + { "kCMD", NULL, 0, KEYC_SCOMMAND }, + { "kCPY", NULL, 0, KEYC_SCOPY }, + { "kCRT", NULL, 0, KEYC_SCREATE }, + { "kDC", NULL, 0, KEYC_SDC }, + { "kDL", NULL, 0, KEYC_SDL }, + { "kslt", NULL, 0, KEYC_SELECT }, + { "kEND", NULL, 0, KEYC_SEND }, + { "kEOL", NULL, 0, KEYC_SEOL }, + { "kEXT", NULL, 0, KEYC_SEXIT }, + { "kind", NULL, 0, KEYC_SF }, + { "kFND", NULL, 0, KEYC_SFIND }, + { "kHLP", NULL, 0, KEYC_SHELP }, + { "kHOM", NULL, 0, KEYC_SHOME }, + { "kIC", NULL, 0, KEYC_SIC }, + { "kLFT", NULL, 0, KEYC_SLEFT }, + { "kMSG", NULL, 0, KEYC_SMESSAGE }, + { "kMOV", NULL, 0, KEYC_SMOVE }, + { "kNXT", NULL, 0, KEYC_SNEXT }, + { "kOPT", NULL, 0, KEYC_SOPTIONS }, + { "kPRV", NULL, 0, KEYC_SPREVIOUS }, + { "kPRT", NULL, 0, KEYC_SPRINT }, + { "kri", NULL, 0, KEYC_SR }, + { "kRDO", NULL, 0, KEYC_SREDO }, + { "kRPL", NULL, 0, KEYC_SREPLACE }, + { "kRIT", NULL, 0, KEYC_SRIGHT }, + { "kRES", NULL, 0, KEYC_SRSUME }, + { "kSAV", NULL, 0, KEYC_SSAVE }, + { "kSPD", NULL, 0, KEYC_SSUSPEND }, + { "khts", NULL, 0, KEYC_STAB }, + { "kUND", NULL, 0, KEYC_SUNDO }, + { "kspd", NULL, 0, KEYC_SUSPEND }, + { "kund", NULL, 0, KEYC_UNDO }, + { "kcuu1", NULL, 0, KEYC_UP }, + { "pmous", NULL, 0, KEYC_MOUSE }, + { NULL, NULL, 0, KEYC_NONE } +}; + +/* tty file descriptor and local terminal buffers. */ +int local_fd; +struct buffer *local_in; +struct buffer *local_out; +struct termios local_tio; + +/* Initialise local terminal. */ +int +local_init(struct buffer **in, struct buffer **out) +{ + char *tty; + int mode; + struct termios tio; + struct local_key *lk; + + if ((tty = ttyname(STDOUT_FILENO)) == NULL) + log_fatal("ttyname"); + if ((local_fd = open(tty, O_RDWR)) == -1) + log_fatal("open(\"%s\")", tty); + if ((mode = fcntl(local_fd, F_GETFL)) == -1) + log_fatal("fcntl"); + if (fcntl(local_fd, F_SETFL, mode|O_NONBLOCK) == -1) + log_fatal("fcntl"); + + *in = local_in = buffer_create(BUFSIZ); + *out = local_out = buffer_create(BUFSIZ); + + setupterm(NULL, STDOUT_FILENO, NULL); + + if (tcgetattr(local_fd, &local_tio) != 0) + log_fatal("tcgetattr"); + memcpy(&tio, &local_tio, sizeof tio); + tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR); + tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET); + tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG); + if (tcsetattr(local_fd, TCSANOW, &tio) != 0) + log_fatal("tcsetattr"); + + if (enter_ca_mode) + local_putp(enter_ca_mode); + local_putp(keypad_xmit); + local_putp(clear_screen); + + for (lk = local_keys; lk->name != NULL; lk++) { + lk->string = tigetstr(lk->name); + if (lk->string == (char *) -1 || lk->string == (char *) 0) + lk->string = NULL; + else { + lk->size = strlen(lk->string); + log_debug("string for %s (%d): \"%s\", length %zu", + lk->name, lk->code, lk->string, lk->size); + } + } + qsort(local_keys, sizeof local_keys / + sizeof local_keys[0], sizeof local_keys[0], local_cmp); + + return (local_fd); +} + +/* Compare keys. */ +int +local_cmp(const void *ptr1, const void *ptr2) +{ + const struct local_key *lk1 = ptr1, *lk2 = ptr2; + + if (lk1->string == NULL && lk2->string == NULL) + return (0); + if (lk1->string == NULL) + return (1); + if (lk2->string == NULL) + return (-1); + return (lk2->size - lk1->size); +} + +/* Tidy up and reset local terminal. */ +void +local_done(void) +{ + xfree(local_in); + xfree(local_out); + + if (tcsetattr(local_fd, TCSANOW, &local_tio) != 0) + log_fatal("tcsetattr"); + close(local_fd); + + putp(keypad_local); /* not local_putp */ + if (exit_ca_mode) + putp(exit_ca_mode); + putp(clear_screen); + putp(cursor_normal); + putp(exit_attribute_mode); +} + +/* Put a character. Used as parameter to tputs. */ +int +local_putc(int c) +{ + FILE *f; + u_char ch = c; + + if (c < 0 || c > (int) UCHAR_MAX) + log_fatalx("local_putc: invalid character"); + + if (debug_level > 1) { + f = fopen("tmux-out.log", "a+"); + fprintf(f, "%c", ch); + fclose(f); + } + + buffer_write(local_out, &ch, 1); + return (c); +} + +/* Put terminfo string. */ +void +local_putp(const char *s) +{ + if (s == NULL) + log_fatalx("local_putp: null pointer"); + + tputs(s, 1, local_putc); +} + +/* Return waiting keys if any. */ +int +local_key(size_t *used) +{ + struct local_key *lk; + u_int i; + size_t size; + + size = BUFFER_USED(local_in); + if (size == 0) + return (KEYC_NONE); + + i = 0; + lk = local_keys; + while (lk->string != NULL) { + if (strncmp(BUFFER_OUT(local_in), lk->string, size) == 0) { + if (size < lk->size) + return (KEYC_NONE); + log_debug("got key: %s %d", lk->name, lk->code); + buffer_remove(local_in, lk->size); + if (used != NULL) + *used = lk->size; + return (lk->code); + } + + i++; + lk = local_keys + i; + } + + if (used != NULL) + *used = 1; + return (input_extract8(local_in)); +} + +/* Display output data. */ +void +local_output(struct buffer *b, size_t size) +{ + u_char ch; + uint16_t ua, ub; + + while (size != 0) { + if (size < 1) + break; + size--; + ch = input_extract8(b); + if (ch != '\e') { + switch (ch) { + case '\n': /* LF */ + if (cursor_down) { + local_putp(cursor_down); + break; + } + log_fatalx("local_output: cursor_down"); + case '\r': /* CR */ + if (carriage_return) { + local_putp(carriage_return); + break; + } + log_fatalx("local_output: carriage_return"); + case '\010': /* BS */ + if (cursor_left) { + local_putp(cursor_left); + break; + } + log_fatalx("local_output: cursor_left"); + break; + default: + local_putc(ch); + break; + } + continue; + } + + if (size < 1) + log_fatalx("local_output: underflow"); + size--; + ch = input_extract8(b); + + log_debug("received code %hhu", ch); + switch (ch) { + case CODE_CURSORUP: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_up_cursor) + log_fatalx("local_output: parm_up_cursor"); + local_putp(tparm(parm_up_cursor, ua)); + break; + case CODE_CURSORDOWN: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_down_cursor) + log_fatalx("local_output: parm_down_cursor"); + local_putp(tparm(parm_down_cursor, ua)); + break; + case CODE_CURSORRIGHT: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_right_cursor) + log_fatalx("local_output: parm_right_cursor"); + local_putp(tparm(parm_right_cursor, ua)); + break; + case CODE_CURSORLEFT: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_left_cursor) + log_fatalx("local_output: parm_left_cursor"); + local_putp(tparm(parm_left_cursor, ua)); + break; + case CODE_CURSORMOVE: + if (size < 4) + log_fatalx("local_output: underflow"); + size -= 4; + ua = input_extract16(b); + ub = input_extract16(b); + if (!cursor_address) + log_fatalx("local_output: cursor_address"); + local_putp(tparm(cursor_address, ua - 1, ub - 1)); + break; + case CODE_CLEARENDOFSCREEN: + if (!clr_eos) + log_fatalx("local_output: clr_eos"); + local_putp(clr_eos); + break; + case CODE_CLEARSCREEN: + if (!clear_screen) + log_fatalx("local_output: clear_screen"); + local_putp(clear_screen); + break; + case CODE_CLEARENDOFLINE: + if (!clr_eol) + log_fatalx("local_output: clr_eol"); + local_putp(clr_eol); + break; + case CODE_CLEARSTARTOFLINE: + if (!clr_bol) + log_fatalx("local_output: clr_bol"); + local_putp(clr_bol); + break; + case CODE_CLEARLINE: + if (!clr_eol) + log_fatalx("local_output: clr_eol"); + local_putp(clr_eol); /* XXX */ + break; + case CODE_INSERTLINE: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_insert_line) + log_fatalx("local_output: parm_insert_line"); + local_putp(tparm(parm_insert_line, ua)); + break; + case CODE_DELETELINE: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_delete_line) + log_fatalx("local_output: parm_delete"); + local_putp(tparm(parm_delete_line, ua)); + break; + case CODE_INSERTCHARACTER: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_ich) + log_fatalx("local_output: parm_ich"); + local_putp(tparm(parm_ich, ua)); + break; + case CODE_DELETECHARACTER: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + if (!parm_dch) + log_fatalx("local_output: parm_dch"); + local_putp(tparm(parm_dch, ua)); + break; + case CODE_CURSORON: + if (!cursor_normal) + log_fatalx("local_output: cursor_normal"); + local_putp(cursor_normal); + break; + case CODE_CURSOROFF: + if (!cursor_invisible) + log_fatalx("local_output: cursor_invisible"); + local_putp(cursor_invisible); + break; + case CODE_CURSORUPSCROLL: + if (!scroll_reverse) + log_fatalx("local_output: scroll_reverse"); + local_putp(scroll_reverse); + break; + case CODE_CURSORDOWNSCROLL: + if (!scroll_forward) + log_fatalx("local_output: scroll_forward"); + local_putp(scroll_forward); + break; + case CODE_SCROLLREGION: + if (size < 4) + log_fatalx("local_output: underflow"); + size -= 4; + ua = input_extract16(b); + ub = input_extract16(b); + if (!change_scroll_region) { + log_fatalx( + "local_output: change_scroll_region"); + } + local_putp(tparm(change_scroll_region, ua - 1, ub - 1)); + break; + case CODE_INSERTON: + if (!enter_insert_mode) + log_fatalx("local_output: enter_insert_mode"); + local_putp(enter_insert_mode); + break; + case CODE_INSERTOFF: + if (!exit_insert_mode) + log_fatalx("local_output: exit_insert_mode"); + local_putp(exit_insert_mode); + break; + case CODE_KCURSOROFF: + /*t = tigetstr("CE"); + if (t != (char *) 0 && t != (char *) -1) + local_putp(t);*/ + break; + case CODE_KCURSORON: + /*t = tigetstr("CS"); + if (t != (char *) 0 && t != (char *) -1) + local_putp(t);*/ + break; + case CODE_KKEYPADOFF:/* + if (!keypad_local) + log_fatalx("local_output: keypad_local"); + local_putp(keypad_local);*/ + break; + case CODE_KKEYPADON:/* + if (!keypad_xmit) + log_fatalx("local_output: keypad_xmit"); + local_putp(keypad_xmit);*/ + break; + case CODE_TITLE: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + + if (size < ua) + log_fatalx("local_output: underflow"); + size -= ua; + buffer_remove(b, ua); + break; + case CODE_ATTRIBUTES: + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ua = input_extract16(b); + + if (!exit_attribute_mode) + log_fatalx("local_output: exit_attribute_mode"); + if (ua == 0) { + if (exit_attribute_mode) + local_putp(exit_attribute_mode); + break; + } + + while (ua-- != 0) { + if (size < 2) + log_fatalx("local_output: underflow"); + size -= 2; + ub = input_extract16(b); + + switch (ub) { + case 0: + case 10: + if (exit_attribute_mode) + local_putp(exit_attribute_mode); + break; + case 1: + if (enter_bold_mode) + local_putp(enter_bold_mode); + break; + case 2: + if (enter_dim_mode) + local_putp(enter_dim_mode); + break; + case 3: + if (enter_standout_mode) + local_putp(enter_standout_mode); + break; + case 4: + if (enter_underline_mode) + local_putp(enter_underline_mode); + break; + case 5: + if (enter_blink_mode) + local_putp(enter_blink_mode); + break; + case 7: + if (enter_reverse_mode) + local_putp(enter_reverse_mode); + break; + case 8: + if (enter_secure_mode) + local_putp(enter_secure_mode); + break; + case 23: + if (exit_standout_mode) + local_putp(exit_standout_mode); + break; + case 24: + if (exit_underline_mode) + local_putp(exit_underline_mode); + break; + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + local_putp( + tparm(set_a_foreground, ub - 30)); + break; + case 39: + if (tigetflag("AX") == TRUE) + local_putp("\e[39m"); + else { + local_putp( + tparm(set_a_background, 0)); + } + break; + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + local_putp( + tparm(set_a_background, ub - 40)); + break; + case 49: + if (tigetflag("AX") == TRUE) + local_putp("\e[49m"); + else { + local_putp( + tparm(set_a_background, 0)); + } + break; + } + } + break; + } + } +} |