mirror of
https://github.com/Aigor44/ncursesw-morphos.git
synced 2025-01-12 14:54:25 +08:00
f06e14af5e
+ modify tset -w (and tput reset) to update the program's copy of the screensize if it was already set in the system, to improve tabstop setting which relies upon knowing the actual screensize. + add functionality of tset -w to tput, like the "-c" feature this is not optional in tput. + add "clear" as a possible link/alias to tput. + improve tput's check for being called as "init" or "reset" to allow for transformed names. + split-out the "clear" function from progs/clear.c, share with tput to get the same behavior, e.g., the E3 extension.
687 lines
17 KiB
C
687 lines
17 KiB
C
/****************************************************************************
|
|
* Copyright (c) 2016 Free Software Foundation, Inc. *
|
|
* *
|
|
* Permission is hereby granted, free of charge, to any person obtaining a *
|
|
* copy of this software and associated documentation files (the *
|
|
* "Software"), to deal in the Software without restriction, including *
|
|
* without limitation the rights to use, copy, modify, merge, publish, *
|
|
* distribute, distribute with modifications, sublicense, and/or sell *
|
|
* copies of the Software, and to permit persons to whom the Software is *
|
|
* furnished to do so, subject to the following conditions: *
|
|
* *
|
|
* The above copyright notice and this permission notice shall be included *
|
|
* in all copies or substantial portions of the Software. *
|
|
* *
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
|
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
|
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
|
* *
|
|
* Except as contained in this notice, the name(s) of the above copyright *
|
|
* holders shall not be used in advertising or otherwise to promote the *
|
|
* sale, use or other dealings in this Software without prior written *
|
|
* authorization. *
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Author: Thomas E. Dickey *
|
|
****************************************************************************/
|
|
|
|
#include <reset_cmd.h>
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
|
|
#if HAVE_SIZECHANGE
|
|
# if !defined(sun) || !TERMIOS
|
|
# if HAVE_SYS_IOCTL_H
|
|
# include <sys/ioctl.h>
|
|
# endif
|
|
# endif
|
|
#endif
|
|
|
|
#if NEED_PTEM_H
|
|
/* they neglected to define struct winsize in termios.h -- it's only
|
|
in termio.h */
|
|
#include <sys/stream.h>
|
|
#include <sys/ptem.h>
|
|
#endif
|
|
|
|
MODULE_ID("$Id: reset_cmd.c,v 1.9 2016/10/23 01:08:11 tom Exp $")
|
|
|
|
/*
|
|
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
|
|
* Solaris, IRIX) define TIOCGWINSZ and struct winsize.
|
|
*/
|
|
#ifdef TIOCGSIZE
|
|
# define IOCTL_GET_WINSIZE TIOCGSIZE
|
|
# define IOCTL_SET_WINSIZE TIOCSSIZE
|
|
# define STRUCT_WINSIZE struct ttysize
|
|
# define WINSIZE_ROWS(n) n.ts_lines
|
|
# define WINSIZE_COLS(n) n.ts_cols
|
|
#else
|
|
# ifdef TIOCGWINSZ
|
|
# define IOCTL_GET_WINSIZE TIOCGWINSZ
|
|
# define IOCTL_SET_WINSIZE TIOCSWINSZ
|
|
# define STRUCT_WINSIZE struct winsize
|
|
# define WINSIZE_ROWS(n) n.ws_row
|
|
# define WINSIZE_COLS(n) n.ws_col
|
|
# endif
|
|
#endif
|
|
|
|
static int my_fd;
|
|
static FILE *my_file;
|
|
static TTY original_settings;
|
|
|
|
static bool can_restore = FALSE;
|
|
static bool use_reset = FALSE; /* invoked as reset */
|
|
static bool use_init = FALSE; /* invoked as init */
|
|
|
|
static void
|
|
exit_error(void)
|
|
{
|
|
restore_tty_settings();
|
|
(void) fprintf(my_file, "\n");
|
|
fflush(my_file);
|
|
ExitProgram(EXIT_FAILURE);
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
static void
|
|
failed(const char *msg)
|
|
{
|
|
char temp[BUFSIZ];
|
|
|
|
_nc_STRCPY(temp, _nc_progname, sizeof(temp));
|
|
_nc_STRCAT(temp, ": ", sizeof(temp));
|
|
_nc_STRNCAT(temp, msg, sizeof(temp), sizeof(temp) - strlen(temp) - 2);
|
|
perror(temp);
|
|
exit_error();
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
static bool
|
|
get_tty_settings(int fd, TTY * tty_settings)
|
|
{
|
|
bool success = TRUE;
|
|
my_fd = fd;
|
|
if (fd < 0 || GET_TTY(my_fd, tty_settings) < 0) {
|
|
success = FALSE;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
static bool
|
|
cat_file(char *file)
|
|
{
|
|
FILE *fp;
|
|
size_t nr;
|
|
char buf[BUFSIZ];
|
|
bool sent = FALSE;
|
|
|
|
if (file != 0) {
|
|
if ((fp = fopen(file, "r")) == 0)
|
|
failed(file);
|
|
|
|
while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) {
|
|
if (fwrite(buf, sizeof(char), nr, my_file) != nr) {
|
|
failed(file);
|
|
}
|
|
sent = TRUE;
|
|
}
|
|
fclose(fp);
|
|
}
|
|
return sent;
|
|
}
|
|
|
|
static int
|
|
out_char(int c)
|
|
{
|
|
return putc(c, my_file);
|
|
}
|
|
|
|
/**************************************************************************
|
|
* Mode-setting logic
|
|
**************************************************************************/
|
|
|
|
/* some BSD systems have these built in, some systems are missing
|
|
* one or more definitions. The safest solution is to override unless the
|
|
* commonly-altered ones are defined.
|
|
*/
|
|
#if !(defined(CERASE) && defined(CINTR) && defined(CKILL) && defined(CQUIT))
|
|
#undef CEOF
|
|
#undef CERASE
|
|
#undef CINTR
|
|
#undef CKILL
|
|
#undef CLNEXT
|
|
#undef CRPRNT
|
|
#undef CQUIT
|
|
#undef CSTART
|
|
#undef CSTOP
|
|
#undef CSUSP
|
|
#endif
|
|
|
|
/* control-character defaults */
|
|
#ifndef CEOF
|
|
#define CEOF CTRL('D')
|
|
#endif
|
|
#ifndef CERASE
|
|
#define CERASE CTRL('H')
|
|
#endif
|
|
#ifndef CINTR
|
|
#define CINTR 127 /* ^? */
|
|
#endif
|
|
#ifndef CKILL
|
|
#define CKILL CTRL('U')
|
|
#endif
|
|
#ifndef CLNEXT
|
|
#define CLNEXT CTRL('v')
|
|
#endif
|
|
#ifndef CRPRNT
|
|
#define CRPRNT CTRL('r')
|
|
#endif
|
|
#ifndef CQUIT
|
|
#define CQUIT CTRL('\\')
|
|
#endif
|
|
#ifndef CSTART
|
|
#define CSTART CTRL('Q')
|
|
#endif
|
|
#ifndef CSTOP
|
|
#define CSTOP CTRL('S')
|
|
#endif
|
|
#ifndef CSUSP
|
|
#define CSUSP CTRL('Z')
|
|
#endif
|
|
|
|
#if defined(_POSIX_VDISABLE)
|
|
#define DISABLED(val) (((_POSIX_VDISABLE != -1) \
|
|
&& ((val) == _POSIX_VDISABLE)) \
|
|
|| ((val) <= 0))
|
|
#else
|
|
#define DISABLED(val) ((int)(val) <= 0)
|
|
#endif
|
|
|
|
#define CHK(val, dft) (unsigned char) (DISABLED(val) ? dft : val)
|
|
|
|
#define reset_char(item, value) \
|
|
tty_settings->c_cc[item] = CHK(tty_settings->c_cc[item], value)
|
|
|
|
/*
|
|
* Reset the terminal mode bits to a sensible state. Very useful after
|
|
* a child program dies in raw mode.
|
|
*/
|
|
void
|
|
reset_tty_settings(TTY * tty_settings)
|
|
{
|
|
#ifdef TERMIOS
|
|
tcgetattr(my_fd, tty_settings);
|
|
#else
|
|
stty(my_fd, tty_settings);
|
|
#endif
|
|
|
|
#ifdef TERMIOS
|
|
#if defined(VDISCARD) && defined(CDISCARD)
|
|
reset_char(VDISCARD, CDISCARD);
|
|
#endif
|
|
reset_char(VEOF, CEOF);
|
|
reset_char(VERASE, CERASE);
|
|
#if defined(VFLUSH) && defined(CFLUSH)
|
|
reset_char(VFLUSH, CFLUSH);
|
|
#endif
|
|
reset_char(VINTR, CINTR);
|
|
reset_char(VKILL, CKILL);
|
|
#if defined(VLNEXT) && defined(CLNEXT)
|
|
reset_char(VLNEXT, CLNEXT);
|
|
#endif
|
|
reset_char(VQUIT, CQUIT);
|
|
#if defined(VREPRINT) && defined(CRPRNT)
|
|
reset_char(VREPRINT, CRPRNT);
|
|
#endif
|
|
#if defined(VSTART) && defined(CSTART)
|
|
reset_char(VSTART, CSTART);
|
|
#endif
|
|
#if defined(VSTOP) && defined(CSTOP)
|
|
reset_char(VSTOP, CSTOP);
|
|
#endif
|
|
#if defined(VSUSP) && defined(CSUSP)
|
|
reset_char(VSUSP, CSUSP);
|
|
#endif
|
|
#if defined(VWERASE) && defined(CWERASE)
|
|
reset_char(VWERASE, CWERASE);
|
|
#endif
|
|
|
|
tty_settings->c_iflag &= ~((unsigned) (IGNBRK
|
|
| PARMRK
|
|
| INPCK
|
|
| ISTRIP
|
|
| INLCR
|
|
| IGNCR
|
|
#ifdef IUCLC
|
|
| IUCLC
|
|
#endif
|
|
#ifdef IXANY
|
|
| IXANY
|
|
#endif
|
|
| IXOFF));
|
|
|
|
tty_settings->c_iflag |= (BRKINT
|
|
| IGNPAR
|
|
| ICRNL
|
|
| IXON
|
|
#ifdef IMAXBEL
|
|
| IMAXBEL
|
|
#endif
|
|
);
|
|
|
|
tty_settings->c_oflag &= ~((unsigned) (0
|
|
#ifdef OLCUC
|
|
| OLCUC
|
|
#endif
|
|
#ifdef OCRNL
|
|
| OCRNL
|
|
#endif
|
|
#ifdef ONOCR
|
|
| ONOCR
|
|
#endif
|
|
#ifdef ONLRET
|
|
| ONLRET
|
|
#endif
|
|
#ifdef OFILL
|
|
| OFILL
|
|
#endif
|
|
#ifdef OFDEL
|
|
| OFDEL
|
|
#endif
|
|
#ifdef NLDLY
|
|
| NLDLY
|
|
#endif
|
|
#ifdef CRDLY
|
|
| CRDLY
|
|
#endif
|
|
#ifdef TABDLY
|
|
| TABDLY
|
|
#endif
|
|
#ifdef BSDLY
|
|
| BSDLY
|
|
#endif
|
|
#ifdef VTDLY
|
|
| VTDLY
|
|
#endif
|
|
#ifdef FFDLY
|
|
| FFDLY
|
|
#endif
|
|
));
|
|
|
|
tty_settings->c_oflag |= (OPOST
|
|
#ifdef ONLCR
|
|
| ONLCR
|
|
#endif
|
|
);
|
|
|
|
tty_settings->c_cflag &= ~((unsigned) (CSIZE
|
|
| CSTOPB
|
|
| PARENB
|
|
| PARODD
|
|
| CLOCAL));
|
|
tty_settings->c_cflag |= (CS8 | CREAD);
|
|
tty_settings->c_lflag &= ~((unsigned) (ECHONL
|
|
| NOFLSH
|
|
#ifdef TOSTOP
|
|
| TOSTOP
|
|
#endif
|
|
#ifdef ECHOPTR
|
|
| ECHOPRT
|
|
#endif
|
|
#ifdef XCASE
|
|
| XCASE
|
|
#endif
|
|
));
|
|
|
|
tty_settings->c_lflag |= (ISIG
|
|
| ICANON
|
|
| ECHO
|
|
| ECHOE
|
|
| ECHOK
|
|
#ifdef ECHOCTL
|
|
| ECHOCTL
|
|
#endif
|
|
#ifdef ECHOKE
|
|
| ECHOKE
|
|
#endif
|
|
);
|
|
#endif
|
|
|
|
SET_TTY(my_fd, tty_settings);
|
|
}
|
|
|
|
/*
|
|
* Returns a "good" value for the erase character. This is loosely based on
|
|
* the BSD4.4 logic.
|
|
*/
|
|
static int
|
|
default_erase(void)
|
|
{
|
|
int result;
|
|
|
|
if (over_strike
|
|
&& key_backspace != 0
|
|
&& strlen(key_backspace) == 1) {
|
|
result = key_backspace[0];
|
|
} else {
|
|
result = CERASE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* Update the values of the erase, interrupt, and kill characters in the TTY
|
|
* parameter.
|
|
*
|
|
* SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase
|
|
* characters if they're unset, or if we specify them as options. This differs
|
|
* from BSD 4.4 tset, which always sets erase.
|
|
*/
|
|
void
|
|
set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill)
|
|
{
|
|
if (DISABLED(tty_settings->c_cc[VERASE]) || my_erase >= 0) {
|
|
tty_settings->c_cc[VERASE] = UChar((my_erase >= 0)
|
|
? my_erase
|
|
: default_erase());
|
|
}
|
|
|
|
if (DISABLED(tty_settings->c_cc[VINTR]) || my_intr >= 0) {
|
|
tty_settings->c_cc[VINTR] = UChar((my_intr >= 0)
|
|
? my_intr
|
|
: CINTR);
|
|
}
|
|
|
|
if (DISABLED(tty_settings->c_cc[VKILL]) || my_kill >= 0) {
|
|
tty_settings->c_cc[VKILL] = UChar((my_kill >= 0)
|
|
? my_kill
|
|
: CKILL);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Set up various conversions in the TTY parameter, including parity, tabs,
|
|
* returns, echo, and case, according to the termcap entry.
|
|
*/
|
|
void
|
|
set_conversions(TTY * tty_settings)
|
|
{
|
|
#ifdef ONLCR
|
|
tty_settings->c_oflag |= ONLCR;
|
|
#endif
|
|
tty_settings->c_iflag |= ICRNL;
|
|
tty_settings->c_lflag |= ECHO;
|
|
#ifdef OXTABS
|
|
tty_settings->c_oflag |= OXTABS;
|
|
#endif /* OXTABS */
|
|
|
|
/* test used to be tgetflag("NL") */
|
|
if (newline != (char *) 0 && newline[0] == '\n' && !newline[1]) {
|
|
/* Newline, not linefeed. */
|
|
#ifdef ONLCR
|
|
tty_settings->c_oflag &= ~((unsigned) ONLCR);
|
|
#endif
|
|
tty_settings->c_iflag &= ~((unsigned) ICRNL);
|
|
}
|
|
#ifdef OXTABS
|
|
/* test used to be tgetflag("pt") */
|
|
if (has_hardware_tabs) /* Print tabs. */
|
|
tty_settings->c_oflag &= ~OXTABS;
|
|
#endif /* OXTABS */
|
|
tty_settings->c_lflag |= (ECHOE | ECHOK);
|
|
}
|
|
|
|
/*
|
|
* Set the hardware tabs on the terminal, using the 'ct' (clear all tabs),
|
|
* 'st' (set one tab) and 'ch' (horizontal cursor addressing) capabilities.
|
|
* This is done before 'if' and 'is', so they can recover in case of error.
|
|
*
|
|
* Return TRUE if we set any tab stops, FALSE if not.
|
|
*/
|
|
static bool
|
|
reset_tabstops(int wide)
|
|
{
|
|
if ((init_tabs != 8) && (set_tab && clear_all_tabs)) {
|
|
int c;
|
|
|
|
(void) putc('\r', my_file); /* Force to left margin. */
|
|
tputs(clear_all_tabs, 0, out_char);
|
|
|
|
for (c = 8; c < wide; c += 8) {
|
|
/* Get to the right column. In BSD tset, this used to try a bunch
|
|
* of half-clever things with cup and hpa, for an average saving of
|
|
* somewhat less than two character times per tab stop, less than
|
|
* .01 sec at 2400cps. We lost all this cruft because it seemed to
|
|
* be introducing some odd bugs.
|
|
* -----------12345678----------- */
|
|
(void) fputs(" ", my_file);
|
|
tputs(set_tab, 0, out_char);
|
|
}
|
|
putc('\r', my_file);
|
|
return (TRUE);
|
|
}
|
|
return (FALSE);
|
|
}
|
|
|
|
static bool
|
|
sent_string(const char *s)
|
|
{
|
|
bool sent = FALSE;
|
|
if (s != 0) {
|
|
tputs(s, 0, out_char);
|
|
sent = TRUE;
|
|
}
|
|
return sent;
|
|
}
|
|
|
|
#define PUTCHAR(c) fputc(c, my_file)
|
|
|
|
/* Output startup string. */
|
|
bool
|
|
send_init_strings(TTY * old_settings)
|
|
{
|
|
int i;
|
|
bool need_flush = FALSE;
|
|
|
|
(void) old_settings;
|
|
#ifdef TAB3
|
|
if (old_settings != 0 &&
|
|
old_settings->c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
|
|
old_settings->c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
|
|
SET_TTY(my_fd, old_settings);
|
|
}
|
|
#endif
|
|
if (use_reset || use_init) {
|
|
if (init_prog != 0) {
|
|
IGNORE_RC(system(init_prog));
|
|
}
|
|
|
|
need_flush |= sent_string((use_reset && (reset_1string != 0))
|
|
? reset_1string
|
|
: init_1string);
|
|
|
|
need_flush |= sent_string((use_reset && (reset_2string != 0))
|
|
? reset_2string
|
|
: init_2string);
|
|
|
|
if (set_lr_margin != 0) {
|
|
need_flush |= sent_string(TPARM_2(set_lr_margin, 0,
|
|
columns - 1));
|
|
} else if (set_left_margin_parm != 0
|
|
&& set_right_margin_parm != 0) {
|
|
need_flush |= sent_string(TPARM_1(set_left_margin_parm, 0));
|
|
need_flush |= sent_string(TPARM_1(set_right_margin_parm,
|
|
columns - 1));
|
|
} else if (clear_margins != 0
|
|
&& set_left_margin != 0
|
|
&& set_right_margin != 0) {
|
|
need_flush |= sent_string(clear_margins);
|
|
if (carriage_return != 0) {
|
|
need_flush |= sent_string(carriage_return);
|
|
} else {
|
|
PUTCHAR('\r');
|
|
}
|
|
need_flush |= sent_string(set_left_margin);
|
|
if (parm_right_cursor) {
|
|
need_flush |= sent_string(TPARM_1(parm_right_cursor,
|
|
columns - 1));
|
|
} else {
|
|
for (i = 0; i < columns - 1; i++) {
|
|
PUTCHAR(' ');
|
|
}
|
|
}
|
|
need_flush |= sent_string(set_right_margin);
|
|
if (carriage_return != 0) {
|
|
need_flush |= sent_string(carriage_return);
|
|
} else {
|
|
PUTCHAR('\r');
|
|
}
|
|
}
|
|
|
|
need_flush |= reset_tabstops(columns);
|
|
|
|
need_flush |= cat_file((use_reset && reset_file) ? reset_file : init_file);
|
|
|
|
need_flush |= sent_string((use_reset && (reset_3string != 0))
|
|
? reset_3string
|
|
: init_3string);
|
|
}
|
|
|
|
return need_flush;
|
|
}
|
|
|
|
/*
|
|
* Tell the user if a control key has been changed from the default value.
|
|
*/
|
|
static void
|
|
show_tty_change(TTY * old_settings,
|
|
TTY * new_settings,
|
|
const char *name,
|
|
int which,
|
|
unsigned def)
|
|
{
|
|
unsigned older, newer;
|
|
char *p;
|
|
|
|
newer = new_settings->c_cc[which];
|
|
older = old_settings->c_cc[which];
|
|
|
|
if (older == newer && older == def)
|
|
return;
|
|
|
|
(void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
|
|
|
|
if (DISABLED(newer)) {
|
|
(void) fprintf(stderr, "undef.\n");
|
|
/*
|
|
* Check 'delete' before 'backspace', since the key_backspace value
|
|
* is ambiguous.
|
|
*/
|
|
} else if (newer == 0177) {
|
|
(void) fprintf(stderr, "delete.\n");
|
|
} else if ((p = key_backspace) != 0
|
|
&& newer == (unsigned char) p[0]
|
|
&& p[1] == '\0') {
|
|
(void) fprintf(stderr, "backspace.\n");
|
|
} else if (newer < 040) {
|
|
newer ^= 0100;
|
|
(void) fprintf(stderr, "control-%c (^%c).\n", UChar(newer), UChar(newer));
|
|
} else
|
|
(void) fprintf(stderr, "%c.\n", UChar(newer));
|
|
}
|
|
|
|
/**************************************************************************
|
|
* Miscellaneous.
|
|
**************************************************************************/
|
|
|
|
void
|
|
reset_start(FILE *fp, bool is_reset, bool is_init)
|
|
{
|
|
my_file = fp;
|
|
use_reset = is_reset;
|
|
use_init = is_init;
|
|
}
|
|
|
|
void
|
|
reset_flush(void)
|
|
{
|
|
if (my_file != 0)
|
|
fflush(my_file);
|
|
}
|
|
|
|
void
|
|
print_tty_chars(TTY * old_settings, TTY * new_settings)
|
|
{
|
|
show_tty_change(old_settings, new_settings, "Erase", VERASE, CERASE);
|
|
show_tty_change(old_settings, new_settings, "Kill", VKILL, CKILL);
|
|
show_tty_change(old_settings, new_settings, "Interrupt", VINTR, CINTR);
|
|
}
|
|
|
|
/*
|
|
* Open a file descriptor on the current terminal, to obtain its settings.
|
|
* stderr is less likely to be redirected than stdout; try that first.
|
|
*/
|
|
int
|
|
save_tty_settings(TTY * tty_settings)
|
|
{
|
|
if (!get_tty_settings(STDERR_FILENO, tty_settings) &&
|
|
!get_tty_settings(STDOUT_FILENO, tty_settings) &&
|
|
!get_tty_settings(STDIN_FILENO, tty_settings) &&
|
|
!get_tty_settings(open("/dev/tty", O_RDWR), tty_settings)) {
|
|
failed("terminal attributes");
|
|
}
|
|
can_restore = TRUE;
|
|
original_settings = *tty_settings;
|
|
return my_fd;
|
|
}
|
|
|
|
void
|
|
restore_tty_settings(void)
|
|
{
|
|
if (can_restore)
|
|
SET_TTY(my_fd, &original_settings);
|
|
}
|
|
|
|
/* Set the modes if they've changed. */
|
|
void
|
|
update_tty_settings(TTY * old_settings, TTY * new_settings)
|
|
{
|
|
if (memcmp(new_settings, old_settings, sizeof(TTY))) {
|
|
SET_TTY(my_fd, new_settings);
|
|
}
|
|
}
|
|
|
|
#if HAVE_SIZECHANGE
|
|
/*
|
|
* Set window size if not set already, but update our copy of the values if the
|
|
* size was set.
|
|
*/
|
|
void
|
|
set_window_size(int fd, short *high, short *wide)
|
|
{
|
|
STRUCT_WINSIZE win;
|
|
(void) ioctl(fd, IOCTL_GET_WINSIZE, &win);
|
|
if (WINSIZE_ROWS(win) == 0 &&
|
|
WINSIZE_COLS(win) == 0) {
|
|
if (*high > 0 && *wide > 0) {
|
|
WINSIZE_ROWS(win) = (unsigned short) *high;
|
|
WINSIZE_COLS(win) = (unsigned short) *wide;
|
|
(void) ioctl(fd, IOCTL_SET_WINSIZE, &win);
|
|
}
|
|
} else if (WINSIZE_ROWS(win) > 0 &&
|
|
WINSIZE_COLS(win) > 0) {
|
|
*high = (short) WINSIZE_ROWS(win);
|
|
*wide = (short) WINSIZE_COLS(win);
|
|
}
|
|
}
|
|
#endif
|