/* ARGSUSED */ int intrflush(WINDOW *w, bool bf) { PTERMIOS(_prog)->c_lflag &= ~NOFLSH; if (!bf) PTERMIOS(_prog)->c_lflag |= NOFLSH; return (__m_tty_set_prog_mode()); }
/* ARGSUSED */ int meta(WINDOW *w, bool bf) { PTERMIOS(_prog)->c_cflag &= ~CSIZE; PTERMIOS(_prog)->c_cflag |= bf ? CS8 : CS7; if (__m_tty_set_prog_mode() == ERR) return (ERR); __m_screen->_flags &= ~S_USE_META; if (bf) { if (meta_on != NULL) (void) TPUTS(meta_on, 1, __m_outc); __m_screen->_flags |= S_USE_META; } else if (meta_off != NULL) { (void) TPUTS(meta_off, 1, __m_outc); } return (OK); }
char killchar(void) { char ch; /* * Refer to _shell instead of _prog, since _shell will * correctly reflect the user's prefered settings, whereas * _prog may not have been initialised if both input and * output have been redirected. */ ch = (char)PTERMIOS(_shell)->c_cc[VKILL]; return (ch); }
/* * Restore the termios settings. */ int __m_tty_set(struct termios *tp) { int fd; int rval; if (cur_term->_flags & __TERM_ISATTY_OUT) { fd = cur_term->_ofd; } else if (cur_term->_flags & __TERM_ISATTY_IN) { fd = cur_term->_ifd; } else { return (OK); } if (memcmp(tp, &cur_term->_actual, sizeof (struct termios)) == 0) return (OK); *PTERMIOS(_actual) = *tp; rval = tcsetattr(fd, TCSADRAIN, tp) == 0 ? OK : ERR; return (rval); }
int reset_shell_mode(void) { return (__m_tty_set(PTERMIOS(_shell))); }
int def_prog_mode(void) { return (__m_tty_get(PTERMIOS(_prog))); }
int def_shell_mode(void) { return (__m_tty_get(PTERMIOS(_shell))); }
int __m_tty_set_prog_mode(void) { return (__m_tty_set(PTERMIOS(_prog))); }
/* * Set up terminal. * * Reads in the terminfo database pointed to by $TERMINFO env. var. * for the given terminal, but does not set up the output virtualization * structues used by CURSES. If the terminal name pointer is NULL, * the $TERM env. var. is used for the terminal. All output is to * the given file descriptor which is initialized for output. * * On error, if errret != NULL then setupterm() returns OK * or ERR and stores a status value in the integer pointed to by * errret. A status of 1 is normal, 0 means the terminal could * not be found, and -1 means the terminfo database could not be * found. If errret == NULL then setupterm() prints an error * message upon and exit(). * * On success, cur_term set to a terminfo structure and OK returned. */ int __m_setupterm(char *termname, int ifd, int ofd, int *err_return) { int err_code = 1; TERMINAL *old_term; const char *err_msg; /* * It is possible to call setupterm() for multiple terminals, * in which case we have to be able to restore cur_term in * case of error. */ old_term = cur_term; cur_term = (TERMINAL *) calloc(1, sizeof (*cur_term)); if (cur_term == NULL) { err_code = -1; goto error; } if (isatty(cur_term->_ifd = ifd)) cur_term->_flags |= __TERM_ISATTY_IN; if (isatty(cur_term->_ofd = ofd)) cur_term->_flags |= __TERM_ISATTY_OUT; cur_term->_shell = (void *) calloc(1, sizeof (struct termios)); cur_term->_prog = (void *) calloc(1, sizeof (struct termios)); cur_term->_save = (void *) calloc(1, sizeof (struct termios)); cur_term->_actual = (void *) calloc(1, sizeof (struct termios)); cur_term->_term = NULL; cur_term->_names = NULL; cur_term->_str_table = NULL; (void) def_shell_mode(); (void) def_prog_mode(); (void) __m_tty_get(PTERMIOS(_actual)); /* Synch cached value */ #ifdef ONLCR if ((PTERMIOS(_prog)->c_oflag & (OPOST | ONLCR)) == (OPOST | ONLCR)) #else if (PTERMIOS(_prog)->c_oflag & OPOST) #endif cur_term->_flags |= __TERM_NL_IS_CRLF; (void) restartterm(termname, ofd, &err_code); error: switch (err_code) { case -1: err_msg = e_terminal; break; case 0: err_msg = e_unknown; break; case 1: break; case 2: err_msg = e_pathmax; err_code = -1; break; } if (err_return != NULL) { *err_return = err_code; if (err_code == 1) { err_code = OK; } else { err_code = ERR; free(cur_term); cur_term = old_term; } } else if (err_code != 1) { (void) fprintf(stderr, err_msg, termname); exit(1); } return (err_code); }
/* * Create a new terminal screen. Used if a program is going to be sending * output to more than one terminal. It returns a SCREEN* for the terminal. * The parameters are a terminal name, output FILE*, and input FILE*. If * the terminal name is null then $TERM is used. The program must also * call endwin() for each terminal being used before exiting from curses. * If newterm() is called more than once for the same terminal, the first * terminal referred to must be the last one for which endwin() is called. */ SCREEN * newterm(char *term, FILE *out_fp, FILE *in_fp) { WINDOW *w; t_wide_io *wio; SCREEN *sp, *osp; int i, n, y, errret; /* * Input stream should be unbuffered so that m_tfgetc() works * correctly on BSD and SUN systems. */ (void) setvbuf(in_fp, (char *) 0, _IONBF, BUFSIZ); #if 0 /* * Not sure whether we really want to concern ourselves with the output * buffer scheme. Might be best to leave it upto the application to * deal with buffer schemes and when to perform flushes. * * MKS Vi uses MKS Curses and so must support the ability to switch in * and out of Curses mode when switching from Vi to Ex and back. * Problem is that in Vi mode you would prefer full buffered output to * give updates a smoother appearance and Ex mode you require line * buffered in order to see prompts and messages. */ (void) setvbuf(out_fp, (char *) 0, _IOLBF, BUFSIZ); #endif errno = 0; if (__m_setupterm(term, fileno(in_fp), fileno(out_fp), &errret) == ERR) { switch (errret) { case -1: errno = ENOMEM; break; case 2: errno = ENAMETOOLONG; break; case 0: default: errno = ENOENT; break; } goto error1; } if (__m_doupdate_init()) goto error1; if ((sp = (SCREEN *) calloc(1, sizeof (*sp))) == NULL) goto error1; sp->_kfd = -1; sp->_if = in_fp; sp->_of = out_fp; sp->_term = cur_term; sp->_unget._size = __m_decode_init((t_decode **) &sp->_decode); /* * Maximum length of a multbyte key sequence, including * multibyte characters and terminal function keys. */ if (sp->_unget._size < (M_TYPEAHEAD_SIZE + MB_LEN_MAX)) sp->_unget._size = M_TYPEAHEAD_SIZE + MB_LEN_MAX; sp->_unget._stack = calloc((size_t) sp->_unget._size, sizeof (*sp->_unget._stack)); if (sp->_unget._stack == NULL) goto error2; if ((wio = (t_wide_io *) calloc(1, sizeof (*wio))) == NULL) goto error2; /* Setup wide input for XCurses. */ wio->get = (int (*)(void *)) wgetch; wio->unget = __xc_ungetc; wio->reset = __xc_clearerr; wio->iserror = __xc_ferror; wio->iseof = __xc_feof; sp->_in = wio; if (assume_one_line) { /* Assume only one line. */ lines = 1; /* Disable capabilities that assume more than one line. */ clear_screen = clr_eos = cursor_up = cursor_down = NULL; cursor_home = cursor_to_ll = cursor_address = NULL; row_address = parm_up_cursor = parm_down_cursor = NULL; /* Re-evaluate the cursor motion costs. */ __m_mvcur_cost(); /* Reset flag for subsequent calls to newterm(). */ assume_one_line = FALSE; } if ((sp->_curscr = newwin(lines, columns, 0, 0)) == NULL) goto error2; if ((sp->_newscr = newwin(lines, columns, 0, 0)) == NULL) goto error2; #if defined(_LP64) sp->_hash = (unsigned int *) calloc(lines, sizeof (*sp->_hash)); #else sp->_hash = (unsigned long *) calloc(lines, sizeof (*sp->_hash)); #endif if (sp->_hash == NULL) goto error2; if (0 <= __m_slk_format && __m_slk_init(sp, __m_slk_format) == ERR) { goto error2; } /* * doupdate() will perform the final screen preparations like * enter_ca_mode, reset_prog_mode() (to assert the termios * changes), etc. */ sp->_flags |= S_ENDWIN; #ifdef SIGTSTP (void) signal(SIGTSTP, tstp); #endif /* Assert that __m_screen is set to the new terminal. */ osp = set_term(sp); /* Disable echo in tty driver, Curses does software echo. */ PTERMIOS(_prog)->c_lflag &= ~ECHO; /* Enable mappnig of cr -> nl on input and nl -> crlf on output. */ PTERMIOS(_prog)->c_iflag |= ICRNL; PTERMIOS(_prog)->c_oflag |= OPOST; #ifdef ONLCR PTERMIOS(_prog)->c_oflag |= ONLCR; #endif cur_term->_flags |= __TERM_NL_IS_CRLF; #ifdef TAB0 /* Use real tabs. */ PTERMIOS(_prog)->c_oflag &= ~(TAB1|TAB2|TAB3); #endif /* * Default to 'cbreak' mode as per * test /tset/CAPIxcurses/fcbreak/fcbreak1{4} */ cur_term->_flags &= ~__TERM_HALF_DELAY; /* * Default to 'idcok' mode as per * test /tset/CAPIxcurses/fidcok/fidcok1{3} */ __m_screen->_flags |= S_INS_DEL_CHAR; PTERMIOS(_prog)->c_cc[VMIN] = 1; PTERMIOS(_prog)->c_cc[VTIME] = 0; PTERMIOS(_prog)->c_lflag &= ~ICANON; (void) __m_tty_set_prog_mode(); (void) __m_set_echo(1); (void) typeahead(fileno(in_fp)); (void) __m_slk_clear(1); n = rip.top - rip.bottom; if (stdscr == NULL) { stdscr = newwin(lines - n, 0, rip.top, 0); if (stdscr == NULL) goto error3; } /* * Create and initialise ripped off line windows. * It is the application's responsiblity to free the * windows when the application terminates. */ for (i = 0; i < n; ++i) { if (rip.line[i].created) continue; y = rip.line[i].dy; if (y < 0) y += lines; w = newwin(1, 0, y, 0); if (rip.line[i].init != (int (*)(WINDOW *, int)) 0) (void) (*rip.line[i].init)(w, columns); rip.line[i].created = 1; } LINES = stdscr->_maxy = sp->_curscr->_maxy - n; return (sp); error3: (void) set_term(osp); error2: delscreen(sp); error1: return (NULL); }
void noqiflush(void) { PTERMIOS(_prog)->c_lflag |= NOFLSH; (void) __m_tty_set_prog_mode(); }
int resetty(void) { return (__m_tty_set(PTERMIOS(_save))); }
int savetty(void) { return (__m_tty_get(PTERMIOS(_save))); }