aboutsummaryrefslogtreecommitdiff
path: root/local.c
diff options
context:
space:
mode:
Diffstat (limited to 'local.c')
-rw-r--r--local.c690
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;
+ }
+ }
+}