home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.muug.mb.ca
/
2014.06.ftp.muug.mb.ca.tar
/
ftp.muug.mb.ca
/
pub
/
src
/
linux
/
old-src
/
xterm
/
resize.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-22
|
12KB
|
537 lines
/*
* $XConsortium: resize.c,v 1.27 91/07/23 11:11:19 rws Exp $
*/
/*
* Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of Digital Equipment
* Corporation not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
*
*
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 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.
*/
/* resize.c */
#include <X11/Xos.h>
#include <stdio.h>
#include <ctype.h>
#if defined(att) || (defined(SYSV) && defined(SYSV386))
#define ATT
#endif
#ifdef SVR4
#define SYSV
#define ATT
#endif
#ifdef ATT
#define USE_USG_PTYS
#endif
#ifdef APOLLO_SR9
#define CANT_OPEN_DEV_TTY
#endif
#ifdef macII
#define USE_SYSV_TERMIO
#undef SYSV /* pretend to be bsd */
#endif /* macII */
#ifdef SYSV
#define USE_SYSV_TERMIO
#define USE_SYSV_UTMP
#else /* else not SYSV */
#define USE_TERMCAP
#endif /* SYSV */
#include <sys/ioctl.h>
#ifdef USE_SYSV_TERMIO
#include <sys/termio.h>
#else /* else not USE_SYSV_TERMIO */
#include <sgtty.h>
#endif /* USE_SYSV_TERMIO */
#ifdef USE_USG_PTYS
#include <sys/stream.h>
#include <sys/ptem.h>
#endif
#include <signal.h>
#include <pwd.h>
#ifdef SIGNALRETURNSINT
#define SIGNAL_T int
#else
#define SIGNAL_T void
#endif
#ifndef X_NOT_STDC_ENV
#include <stdlib.h>
#else
char *getenv();
#endif
#ifdef USE_SYSV_TERMIO
#ifdef X_NOT_POSIX
#ifndef SYSV386
extern struct passwd *getpwuid(); /* does ANYBODY need this? */
#endif /* SYSV386 */
#endif /* X_NOT_POSIX */
#define bzero(s, n) memset(s, 0, n)
#endif /* USE_SYSV_TERMIO */
#define EMULATIONS 2
#define SUN 1
#define TIMEOUT 10
#define VT100 0
#define SHELL_UNKNOWN 0
#define SHELL_C 1
#define SHELL_BOURNE 2
struct {
char *name;
int type;
} shell_list[] = {
"csh", SHELL_C, /* vanilla cshell */
"tcsh", SHELL_C,
"jcsh", SHELL_C,
"sh", SHELL_BOURNE, /* vanilla Bourne shell */
"ksh", SHELL_BOURNE, /* Korn shell (from AT&T toolchest) */
"ksh-i", SHELL_BOURNE, /* other name for latest Korn shell */
"bash", SHELL_BOURNE, /* GNU Bourne again shell */
"jsh", SHELL_BOURNE,
NULL, SHELL_BOURNE /* default (same as xterm's) */
};
char *emuname[EMULATIONS] = {
"VT100",
"Sun",
};
char *myname;
int shell_type = SHELL_UNKNOWN;
char *getsize[EMULATIONS] = {
"\0337\033[r\033[999;999H\033[6n",
"\033[18t",
};
#ifndef sun
#ifdef TIOCSWINSZ
char *getwsize[EMULATIONS] = { /* size in pixels */
0,
"\033[14t",
};
#endif /* TIOCSWINSZ */
#endif /* sun */
char *restore[EMULATIONS] = {
"\0338",
0,
};
char *setname = "";
char *setsize[EMULATIONS] = {
0,
"\033[8;%s;%st",
};
#ifdef USE_SYSV_TERMIO
struct termio tioorig;
#else /* not USE_SYSV_TERMIO */
struct sgttyb sgorig;
#endif /* USE_SYSV_TERMIO */
char *size[EMULATIONS] = {
"\033[%d;%dR",
"\033[8;%d;%dt",
};
char sunname[] = "sunsize";
int tty;
FILE *ttyfp;
#ifndef sun
#ifdef TIOCSWINSZ
char *wsize[EMULATIONS] = {
0,
"\033[4;%hd;%hdt",
};
#endif /* TIOCSWINSZ */
#endif /* sun */
char *strindex ();
SIGNAL_T onintr();
/*
resets termcap string to reflect current screen size
*/
main (argc, argv)
int argc;
char **argv;
{
register char *ptr, *env;
register int emu = VT100;
char *shell;
struct passwd *pw;
int i;
int rows, cols;
#ifdef USE_SYSV_TERMIO
struct termio tio;
#else /* not USE_SYSV_TERMIO */
struct sgttyb sg;
#endif /* USE_SYSV_TERMIO */
#ifdef USE_TERMCAP
char termcap [1024];
char newtc [1024];
#endif /* USE_TERMCAP */
char buf[BUFSIZ];
#ifdef sun
#ifdef TIOCSSIZE
struct ttysize ts;
#endif /* TIOCSSIZE */
#else /* sun */
#ifdef TIOCSWINSZ
struct winsize ws;
#endif /* TIOCSWINSZ */
#endif /* sun */
char *name_of_tty;
#ifdef CANT_OPEN_DEV_TTY
extern char *ttyname();
#endif
ptr = rindex(myname = argv[0], '/');
if(ptr)
myname = ptr + 1;
if(strcmp(myname, sunname) == 0)
emu = SUN;
for(argv++, argc-- ; argc > 0 && **argv == '-' ; argv++, argc--) {
switch((*argv)[1]) {
case 's': /* Sun emulation */
if(emu == SUN)
Usage(); /* Never returns */
emu = SUN;
break;
case 'u': /* Bourne (Unix) shell */
shell_type = SHELL_BOURNE;
break;
case 'c': /* C shell */
shell_type = SHELL_C;
break;
default:
Usage(); /* Never returns */
}
}
if (SHELL_UNKNOWN == shell_type) {
/* Find out what kind of shell this user is running.
* This is the same algorithm that xterm uses.
*/
if (((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
(((pw = getpwuid(getuid())) == NULL) ||
*(ptr = pw->pw_shell) == 0))
/* this is the same default that xterm uses */
ptr = "/bin/sh";
shell = rindex(ptr, '/');
if(shell)
shell++;
else
shell = ptr;
/* now that we know, what kind is it? */
for (i = 0; shell_list[i].name; i++)
if (!strcmp(shell_list[i].name, shell))
break;
shell_type = shell_list[i].type;
}
if(argc == 2) {
if(!setsize[emu]) {
fprintf(stderr,
"%s: Can't set window size under %s emulation\n",
myname, emuname[emu]);
exit(1);
}
if(!checkdigits(argv[0]) || !checkdigits(argv[1]))
Usage(); /* Never returns */
} else if(argc != 0)
Usage(); /* Never returns */
#ifdef CANT_OPEN_DEV_TTY
if ((name_of_tty = ttyname(fileno(stderr))) == NULL)
#endif
name_of_tty = "/dev/tty";
if ((ttyfp = fopen (name_of_tty, "r+")) == NULL) {
fprintf (stderr, "%s: can't open terminal %s\n",
myname, name_of_tty);
exit (1);
}
tty = fileno(ttyfp);
#ifdef USE_TERMCAP
if(!(env = getenv("TERM")) || !*env) {
env = "xterm";
if(SHELL_BOURNE == shell_type)
setname = "TERM=xterm;\nexport TERM;\n";
else
setname = "setenv TERM xterm;\n";
}
if(tgetent (termcap, env) <= 0) {
fprintf(stderr, "%s: Can't get entry \"%s\"\n",
myname, env);
exit(1);
}
#else /* else not USE_TERMCAP */
if(!(env = getenv("TERM")) || !*env) {
env = "xterm";
if(SHELL_BOURNE == shell_type)
setname = "TERM=xterm;\nexport TERM;\n";
else setname = "setenv TERM xterm;\n";
}
#endif /* USE_TERMCAP */
#ifdef USE_SYSV_TERMIO
ioctl (tty, TCGETA, &tioorig);
tio = tioorig;
tio.c_iflag &= ~(ICRNL | IUCLC);
tio.c_lflag &= ~(ICANON | ECHO);
tio.c_cflag |= CS8;
tio.c_cc[VMIN] = 6;
tio.c_cc[VTIME] = 1;
#else /* else not USE_SYSV_TERMIO */
ioctl (tty, TIOCGETP, &sgorig);
sg = sgorig;
sg.sg_flags |= RAW;
sg.sg_flags &= ~ECHO;
#endif /* USE_SYSV_TERMIO */
signal(SIGINT, onintr);
signal(SIGQUIT, onintr);
signal(SIGTERM, onintr);
#ifdef USE_SYSV_TERMIO
ioctl (tty, TCSETAW, &tio);
#else /* not USE_SYSV_TERMIO */
ioctl (tty, TIOCSETP, &sg);
#endif /* USE_SYSV_TERMIO */
if (argc == 2) {
sprintf (buf, setsize[emu], argv[0], argv[1]);
write(tty, buf, strlen(buf));
}
write(tty, getsize[emu], strlen(getsize[emu]));
readstring(ttyfp, buf, size[emu]);
if(sscanf (buf, size[emu], &rows, &cols) != 2) {
fprintf(stderr, "%s: Can't get rows and columns\r\n", myname);
onintr(0);
}
if(restore[emu])
write(tty, restore[emu], strlen(restore[emu]));
#ifdef sun
#ifdef TIOCGSIZE
/* finally, set the tty's window size */
if (ioctl (tty, TIOCGSIZE, &ts) != -1) {
ts.ts_lines = rows;
ts.ts_cols = cols;
ioctl (tty, TIOCSSIZE, &ts);
}
#endif /* TIOCGSIZE */
#else /* sun */
#ifdef TIOCGWINSZ
/* finally, set the tty's window size */
if(getwsize[emu]) {
/* get the window size in pixels */
write (tty, getwsize[emu], strlen (getwsize[emu]));
readstring(ttyfp, buf, wsize[emu]);
if(sscanf (buf, wsize[emu], &ws.ws_xpixel, &ws.ws_ypixel) != 2) {
fprintf(stderr, "%s: Can't get window size\r\n", myname);
onintr(0);
}
ws.ws_row = rows;
ws.ws_col = cols;
ioctl (tty, TIOCSWINSZ, &ws);
} else if (ioctl (tty, TIOCGWINSZ, &ws) != -1) {
/* we don't have any way of directly finding out
the current height & width of the window in pixels. We try
our best by computing the font height and width from the "old"
struct winsize values, and multiplying by these ratios...*/
if (ws.ws_col != 0)
ws.ws_xpixel = cols * (ws.ws_xpixel / ws.ws_col);
if (ws.ws_row != 0)
ws.ws_ypixel = rows * (ws.ws_ypixel / ws.ws_row);
ws.ws_row = rows;
ws.ws_col = cols;
ioctl (tty, TIOCSWINSZ, &ws);
}
#endif /* TIOCGWINSZ */
#endif /* sun */
#ifdef USE_SYSV_TERMIO
ioctl (tty, TCSETAW, &tioorig);
#else /* not USE_SYSV_TERMIO */
ioctl (tty, TIOCSETP, &sgorig);
#endif /* USE_SYSV_TERMIO */
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#ifdef USE_TERMCAP
/* update termcap string */
/* first do columns */
if ((ptr = strindex (termcap, "co#")) == NULL) {
fprintf(stderr, "%s: No `co#'\n", myname);
exit (1);
}
i = ptr - termcap + 3;
strncpy (newtc, termcap, i);
sprintf (newtc + i, "%d", cols);
ptr = index (ptr, ':');
strcat (newtc, ptr);
/* now do lines */
if ((ptr = strindex (newtc, "li#")) == NULL) {
fprintf(stderr, "%s: No `li#'\n", myname);
exit (1);
}
i = ptr - newtc + 3;
strncpy (termcap, newtc, i);
sprintf (termcap + i, "%d", rows);
ptr = index (ptr, ':');
strcat (termcap, ptr);
#endif /* USE_TERMCAP */
if(SHELL_BOURNE == shell_type) {
#ifdef USE_TERMCAP
printf ("%sTERMCAP='%s'\n",
setname, termcap);
#else /* else not USE_TERMCAP */
#ifndef SVR4
printf ("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n",
setname, cols, rows);
#endif /* !SVR4 */
#endif /* USE_SYSV_TERMCAP */
} else { /* not Bourne shell */
#ifdef USE_TERMCAP
printf ("set noglob;\n%ssetenv TERMCAP '%s';\nunset noglob;\n",
setname, termcap);
#else /* else not USE_TERMCAP */
#ifndef SVR4
printf ("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n",
setname, cols, rows);
#endif /* !SVR4 */
#endif /* USE_TERMCAP */
}
exit(0);
}
char *strindex (s1, s2)
/*
returns a pointer to the first occurrence of s2 in s1, or NULL if there are
none.
*/
register char *s1, *s2;
{
register char *s3;
int s2len = strlen (s2);
while ((s3 = index (s1, *s2)) != NULL)
{
if (strncmp (s3, s2, s2len) == 0) return (s3);
s1 = ++s3;
}
return (NULL);
}
checkdigits(str)
register char *str;
{
while(*str) {
if(!isdigit(*str))
return(0);
str++;
}
return(1);
}
readstring(fp, buf, str)
register FILE *fp;
register char *buf;
char *str;
{
register int last, c;
SIGNAL_T timeout();
#ifndef USG
struct itimerval it;
#endif
signal(SIGALRM, timeout);
#ifdef USG
alarm (TIMEOUT);
#else
bzero((char *)&it, sizeof(struct itimerval));
it.it_value.tv_sec = TIMEOUT;
setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL);
#endif
if ((c = getc(fp)) == 0233) { /* meta-escape, CSI */
*buf++ = c = '\033';
*buf++ = '[';
} else
*buf++ = c;
if(c != *str) {
fprintf(stderr, "%s: unknown character, exiting.\r\n", myname);
onintr(0);
}
last = str[strlen(str) - 1];
while((*buf++ = getc(fp)) != last)
;
#ifdef USG
alarm (0);
#else
bzero((char *)&it, sizeof(struct itimerval));
setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL);
#endif
*buf = 0;
}
Usage()
{
fprintf(stderr, strcmp(myname, sunname) == 0 ?
"Usage: %s [rows cols]\n" :
"Usage: %s [-u] [-c] [-s [rows cols]]\n", myname);
exit(1);
}
SIGNAL_T
timeout(sig)
int sig;
{
fprintf(stderr, "%s: Time out occurred\r\n", myname);
onintr(sig);
}
/* ARGSUSED */
SIGNAL_T
onintr(sig)
int sig;
{
#ifdef USE_SYSV_TERMIO
ioctl (tty, TCSETAW, &tioorig);
#else /* not USE_SYSV_TERMIO */
ioctl (tty, TIOCSETP, &sgorig);
#endif /* USE_SYSV_TERMIO */
exit(1);
}