|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 39661 (0x9aed)
Types: TextFile
Names: »main.c.orig«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/obsolete/xterm/main.c.orig«
#include <X/mit-copyright.h>
/* Copyright Massachusetts Institute of Technology 1984, 1985 */
/* main.c */
#ifndef lint
static char *rcsid_ptyx_c = "$Header: main.c,v 10.47 86/07/30 15:12:56 wesommer Exp $";
#endif lint
#ifdef vms
#include <ptyctl.h>
#include <descrip.h>
#include <ssdef.h>
Cleanup();
#else vms
#include <pwd.h>
#endif
#include <sgtty.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>
#include <sys/file.h>
#include <errno.h>
#include <signal.h>
#include <strings.h>
#include <X/Xlib.h>
#include "ptyx.h"
#include <grp.h>
#include <ttyent.h>
#include <utmp.h>
char *xterm_name; /* argv[0] */
Terminal term; /* master data structure for client */
int am_slave = 0; /* set to 1 if running as a slave process */
int debug = 0; /* true causes error messages to be displayed */
static char *ptydev = "/dev/ptyxx";
static char *ttydev = "/dev/ttyxx";
#include "../cursors/xterm.cursor"
#include "../cursors/xterm_mask.cursor"
#ifdef ICONWINDOW
#define icon_width screen->iconwidth
#define icon_height screen->iconheight
#else ICONWINDOW
#include "icon.ic"
#include "icon_mask.ic"
#endif ICONWINDOW
#ifndef vms
static int reapchild ();
#endif vms
static char **command_to_exec = (char **) NULL;
static char *win_name = (char *) 0;
static struct sgttyb d_sg = {
0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
};
static struct tchars d_tc = {
CINTR, CQUIT, CSTART,
CSTOP, CEOF, CBRK,
};
static struct ltchars d_ltc = {
CSUSP, CDSUSP, CRPRNT,
CFLUSH, CWERASE, CLNEXT
};
static int d_disipline = NTTYDISC;
static int d_lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
static int no_dev_tty = 0;
static int loginflag = 0;
static int dologinflag = 0;
#ifdef sun
#ifdef TIOCCONS
static int SunConsole = 0;
#endif TIOCCONS
#endif sun
main (argc, argv)
int argc;
char **argv;
{
int ind;
char *strind, *strind1, *strscan();
char *fn = "vtsingle";
char *fb = "vtbold";
short fnflag = 0; /* True iff -fn option used */
short fbflag = 0; /* True iff -fb option used */
#ifdef ICONWINDOW
char *fi = "nil2";
int allowiconinput = 0;
#endif ICONWINDOW
char *getty = NULL;
char *keymap = NULL;
int reverse = 0, multiscroll = 0;
int border = 1, tek = 0;
int borderwidth = 2;
int bitmapicon = 0;
#ifdef JUMPSCROLL
int jumpscroll = 0;
#endif JUMPSCROLL
int slave = 0; /* if non-zero, run as slave */
char passedPty[2]; /* name if pty if slave */
char *fore_color;
char *back_color;
char *brdr_color;
char *curs_color;
char *mous_color;
char display[256];
char *getenv();
char *option;
char *geometry, *def = "=80x24+1+1";
char *hcom;
Screen *screen = &term.screen;
screen->TekCursCR = 0;
screen->TekPrintCom[0] = 0;
#ifdef vms
xterm_name = basename( argv[0] );
#else vms
xterm_name = argv[0];
#endif vms
display[0] = '\0';
/*
* go get options out of default file
*/
if ((option = XGetDefault(argv[0], "BodyFont")) != NULL) {
fn = option;
fnflag = 1;
}
if ((option = XGetDefault(argv[0], "BoldFont")) != NULL) {
fb = option;
fbflag = 1;
}
if ((option = XGetDefault(argv[0], "InternalBorder")) != NULL) {
border = atoi (option);
}
if ((option = XGetDefault(argv[0], "BorderWidth")) != NULL) {
borderwidth = atoi (option);
}
#ifdef ICONWINDOW
if ((option = XGetDefault(argv[0], "AllowIconInput")) != NULL)
if (strcmp (option, "on") == 0)
allowiconinput = 1;
#endif ICONWINDOW
if ((option = XGetDefault(argv[0], "BitmapIcon")) != NULL)
if (strcmp (option, "on") == 0)
bitmapicon =
#ifdef ICONWINDOW
allowiconinput ? 2 :
#endif ICONWINDOW
1;
if ((option = XGetDefault(argv[0], "ReverseVideo")) != NULL)
if (strcmp (option, "on") == 0)
reverse = 1;
if ((option = XGetDefault(argv[0], "Tektronix")) != NULL)
if (strcmp (option, "on") == 0)
tek = 1;
if ((option = XGetDefault(argv[0], "TekCursCR")) != NULL)
if (strcmp (option, "on") == 0)
screen->TekCursCR = 1;
#ifdef JUMPSCROLL
if ((option = XGetDefault(argv[0], "JumpScroll")) != NULL)
if (strcmp (option, "on") == 0)
jumpscroll = 1;
#endif JUMPSCROLL
fore_color = XGetDefault(argv[0], "Foreground");
back_color = XGetDefault(argv[0], "Background");
brdr_color = XGetDefault(argv[0], "Border");
curs_color = XGetDefault(argv[0], "Cursor");
mous_color = XGetDefault(argv[0], "Mouse");
keymap = XGetDefault(argv[0], "Keymap");
if ((hcom = XGetDefault(argv[0], "HardCopyCom")) != NULL)
strcpy (hcom, screen->TekPrintCom);
/* parse command line */
for (ind = 1; ind < argc; ind++) {
if (argv [ind] [0] == '=') {
geometry = argv[ind];
continue;
}
strind = index (argv[ind], ':');
if(strind != NULL) {
strncpy(display,argv[ind],sizeof(display));
continue;
}
strind = (char *) index (argv [ind], '-');
if (strind == NULL) Syntax ();
if (strcmp (argv [ind], "-L") == 0) {
char tt[32];
int mode = O_RDWR|O_NDELAY;
loginflag = 1;
getty = argv[argc-1];
argc -= 1;
#ifndef vms
strcpy(tt,"/dev/");
strcat(tt, getty);
chown(tt, 0, 0);
chmod(tt, 0622);
if (open(tt, mode, 0) < 0) {
consolepr("open failed\n");
}
signal(SIGHUP, SIG_IGN);
vhangup();
setpgrp(0,0);
signal(SIGHUP, SIG_DFL);
open(tt, mode, 0);
close(0);
dup(1);
dup(0);
#endif vms
continue;
}
if (strncmp (argv [ind], "-S", 2) == 0) {
sscanf(argv[ind] + 2, "%c%c%d", passedPty, passedPty+1,
&slave);
if (slave <= 0) Syntax();
am_slave = 1;
continue;
}
if (strcmp (argv [ind], "-e") == 0) {
if (++ind >= argc) Syntax ();
command_to_exec = argv + ind;
break;
}
/* Switch to set up Tektronix-shaped (4096x3128 -> 512x390) window
* with characters sized to fit 39 lines of 85 characters each */
if (strcmp (argv [ind], "-t") == 0) {
tek = 1;
if (!fnflag) fn = "6x10";
if (!fbflag) fb = "6x10";
def = "85x39+1+1";
continue;
}
if (strcmp (argv [ind], "-fn") == 0) {
if (++ind >= argc) Syntax ();
fn = argv [ind];
fnflag = 1;
continue;
}
if (strcmp (argv [ind], "-fb") == 0) {
if (++ind >= argc) Syntax ();
fb = argv [ind];
fbflag = 1;
continue;
}
if (strcmp (argv[ind], "-fi") == 0) {
if (++ind >= argc) Syntax ();
fi = argv [ind];
continue;
}
if (strcmp (argv [ind], "-fg") == 0) {
if (++ind >= argc) Syntax ();
fore_color = argv [ind];
continue;
}
if (strcmp (argv [ind], "-bg") == 0) {
if (++ind >= argc) Syntax ();
back_color = argv [ind];
continue;
}
if (strcmp (argv [ind], "-bd") == 0) {
if (++ind >= argc) Syntax ();
brdr_color = argv [ind];
continue;
}
if (strcmp (argv [ind], "-cc") == 0) {
screen->TekCursCR = 1;
continue;
}
if (strcmp (argv [ind], "-hc") == 0) {
if (++ind >= argc) Syntax ();
hcom = argv [ind];
strcpy (hcom, screen->TekPrintCom);
continue;
}
if (strcmp (argv [ind], "-cr") == 0) {
if (++ind >= argc) Syntax ();
curs_color = argv [ind];
continue;
}
if (strcmp (argv [ind], "-ms") == 0) {
if (++ind >= argc) Syntax ();
mous_color = argv [ind];
continue;
}
if (strcmp (argv [ind], "-l") == 0) {
dologinflag = 1;
continue;
}
if (strcmp (argv [ind], "-d") == 0) {
debug = 1;
continue;
}
if (strcmp (argv [ind], "-b") == 0) {
if (++ind >= argc) Syntax ();
border = atoi (argv [ind]);
continue;
}
if (strcmp (argv [ind], "-bw") == 0 ||
strcmp (argv [ind], "-w") == 0) {
if (++ind >= argc) Syntax ();
borderwidth = atoi (argv [ind]);
continue;
}
if (strcmp (argv [ind], "-rv") == 0 ||
strcmp (argv [ind], "-r") == 0) {
reverse = 1; /* backwards from usual definition */
continue;
}
if (strcmp (argv [ind], "-s") == 0) {
multiscroll = 1;
continue;
}
if (strcmp (argv [ind], "-i") == 0) {
bitmapicon =
#ifdef ICONWINDOW
allowiconinput ? 2 :
#endif ICONWINDOW
1;
continue;
}
#ifdef JUMPSCROLL
if (strcmp (argv [ind], "-j") == 0) {
jumpscroll = 1;
continue;
}
#endif JUMPSCROLL
if (strcmp (argv [ind], "-n") == 0) {
if (++ind >= argc) Syntax ();
win_name = argv [ind];
continue;
}
if (strcmp (argv [ind], "-k") ==0) {
ind++;
keymap = argv[ind++];
continue;
}
#ifdef sun
#ifdef TIOCCONS
if (strcmp (argv [ind], "-C") == 0) {
SunConsole = 1;
continue;
}
#endif TIOCCONS
#endif sun
Syntax ();
}
if (fnflag && !fbflag) fb = fn;
if (!fnflag && fbflag) fn = fb;
#ifdef JUMPSCROLL
if(tek)
jumpscroll = 0;
#endif JUMPSCROLL
if ((char *)win_name == 0 && getty) {
(char *) win_name = (char *) malloc(33);
strcpy(win_name, "login(");
gethostname(win_name+6, 25);
strcat(win_name, ")");
}
if (keymap != NULL) XUseKeymap(keymap);
Serve (display, fn, fb,
#ifdef ICONWINDOW
fi,
#endif ICONWINDOW
geometry, def, getty, slave, passedPty,
border, borderwidth, tek, reverse, multiscroll, bitmapicon,
fore_color, back_color, brdr_color, curs_color, mous_color
#ifdef JUMPSCROLL
, jumpscroll
#endif JUMPSCROLL
);
}
Syntax ()
{
static char *ustring[] = {
"Usage: xterm [-rv] [-fn normal_font] [-fb bold_font]",
#ifdef ICONWINDOW
" [-fi icon_font]",
#endif ICONWINDOW
"\n\t[=[width]x[height][[+-]xoff[[+-]yoff]]] [-bw bdr_width]\n",
"\t[-fg color] [-bg color] [-bd color] [-cr color] [-ms color]\n",
"\t[[[host]:vs]] [-d] [-s] [-t] [-i] [-j] [-e command_to_exec]\n",
"\t[-n window_name] [-cc] [-hc command] [-k keymap_file]\n\n",
"Fonts must be of fixed width and of same size;\n",
"If only one font is specified, it will be used for normal and bold text\n",
#ifdef JUMPSCROLL
"The -j option enables jump scroll\n",
#endif
"The -s option enables asynchronous scrolling\n",
"The -t option enables Tektronics 4010 emulation\n",
"The -i option enables bitmap icons\n",
"The -d option turns debugging on (error messages printed)\n",
"The -n option sets the window name\n",
"The -b option specifies the inner padding\n",
"The -cc option causes a carriage return after Tek cursor return\n",
"The -hc option specifies the Tek hard copy command\n",
"Default is: xterm -fn vtsingle -fb vtbold =80x24 :0\n",
0};
char **us = ustring;
while (*us) fputs(*us++, stderr);
exit (1);
}
char *strscan (search, what)
/*
Returns pointer to first char ins search which is also in what, else NULL.
*/
char *search, *what;
{
int i, len = strlen (what);
char c;
while ((c = *(search++)) != NULL)
for (i = 0; i < len; i++)
if (c == what [i]) return (--search);
return (NULL);
}
Serve (disp, fn, fb,
#ifdef ICONWINDOW
fi,
#endif ICONWINDOW
geometry, def, getty, slave, passedPty,
border, borderwidth, tek, reverse, multiscroll, bitmapicon,
fore_color, back_color, brdr_color, curs_color, mous_color
#ifdef JUMPSCROLL
, jumpscroll
#endif JUMPSCROLL
)
char *disp; /* host of display to serve */
char *fn; /* fontname of normal characters */
char *fb; /* fontname of bold characters */
#ifdef ICONWINDOW
char *fi; /* fontname of icon characters */
#endif ICONWINDOW
char *getty; /* true iff child should be getty */
int slave; /* true if should run as slave (contains file # of pty) */
char *passedPty; /* name of pty to use if slave */
char *geometry; /* user supplied geometry spec */
char *def; /* default geometry spec */
int border; /* inner border in pixels */
int borderwidth; /* outer border in pixels */
int tek; /* true ==> Tektronics emulation */
int reverse; /* true ==> black background, white characters */
int multiscroll; /* true ==> asynchronous full-screen scrolling */
int bitmapicon; /* true ==> bitmap icons rather than text icon */
#ifdef JUMPSCROLL
int jumpscroll; /* true ==> fast multi-line scrolling */
#endif JUMPSCROLL
char *fore_color;/* text color */
char *back_color;/* background color */
char *brdr_color;/* border color */
char *curs_color;/* text cursor color */
char *mous_color;/* mouse cursor color */
{
int pty; /* fildes for pty of client */
XEvent reply;
XEvent *rep = & reply;
int aborted = 0;
int Select_mask, select_mask = 0;
int maxplus1;
short toggled = NULL;
Screen *screen = &term.screen;
int Xsocket;
int pty_mask, X_mask;
extern int errno;
int mode = 1;
#ifdef TIOCSWINSZ
struct winsize ws;
#endif
#ifndef vms
signal (SIGCHLD, reapchild);
#endif vms
signal (SIGHUP, SIG_IGN);
/* open a terminal for client */
get_terminal (disp, &term, fn, fb,
#ifdef ICONWINDOW
fi,
#endif ICONWINDOW
geometry, def, border,
borderwidth, (int)getty, slave, reverse, multiscroll, bitmapicon,
tek, fore_color, back_color, brdr_color, curs_color, mous_color
#ifdef JUMPSCROLL
, jumpscroll
#endif JUMPSCROLL
);
Xsocket = screen->display->fd;
spawn (disp, &pty, Xsocket, screen, getty, slave, passedPty);
if (slave) { /* Write window id so master end can read and use */
write(pty, &screen->window, sizeof(screen->window));
write(pty, "\n", 1);
}
screen->respond = term.buf.fildes = pty;
#ifdef TIOCSWINSZ
#ifdef vms
if(!getty) {
#endif vms
/* tell tty how big window is */
ws.ws_row = screen->max_row + 1;
ws.ws_col = screen->max_col + 1;
ws.ws_xpixel = screen->width;
ws.ws_ypixel = screen->height;
ioctl (screen->respond, TIOCSWINSZ, &ws);
#ifdef vms
}
#endif vms
#endif TIOCSWINSZ
/* Initialize Tektronix graphics mode parameters */
TekErase (&term);
screen->TekEmu = tek;
screen->cur_x = screen->cur_y = 0;
screen->cur_X = screen->cur_Y = 0;
screen->TekGMode = 0;
screen->TekAMode = 0;
screen->TekPMode = 0;
if (ioctl (pty, FIONBIO, &mode) == -1) Error ();
pty_mask = 1 << pty;
X_mask = 1 << Xsocket;
Select_mask = pty_mask | X_mask;
maxplus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
if (debug) printf ("debugging on\n");
while (1)
{
if (! aborted)
{
#ifdef JUMPSCROLL
if(screen->scroll_amt)
FlushScroll(screen);
#endif JUMPSCROLL
if (toggled)
{
CursorToggle (screen, toggled);
toggled = NULL;
}
select_mask = Select_mask;
XFlush();
while (select (maxplus1, &select_mask, NULL, NULL, 0) <= 0) {
if (errno != EINTR) Error();
}
}
else select_mask = NULL;
if (select_mask & pty_mask || aborted)
{
if (!toggled)
{
CursorToggle (screen, toggled);
toggled = 1;
}
do {
aborted = (*screen->mode)(&term);
} while (screen->display->qlen==0 && term.buf.cnt>0);
}
if (select_mask & X_mask || aborted)
{
#ifdef JUMPSCROLL
if(screen->scroll_amt)
FlushScroll(screen);
#endif JUMPSCROLL
XPending ();
do {
XNextEvent (&reply);
switch ((int)reply.type)
{
case KeyPressed:
Input (&term.keyboard, &term.screen,
(XKeyPressedEvent *)rep);
break;
case ExposeWindow:
#ifdef ICONWINDOW
if (screen->window != reply.window) {
screen->window = reply.window;
if (Icon(screen)) {
screen->f_height = screen->if_height;
screen->f_width = screen->if_width;
screen->height = screen->iconheight;
screen->width = screen->iconwidth;
}
else
{
screen->f_height = screen->ff_height;
screen->f_width = screen->ff_width;
screen->height = screen->fullheight;
screen->width = screen->fullwidth;
}
}
#else ICONWINDOW
if (bitmapicon) {
if (((XExposeWindowEvent *)rep)->window
== screen->iconwindow) {
RefreshIcon(screen);
break;
}
}
#endif ICONWINDOW
toggled = 1;
if (ScreenResize (screen,
((XExposeWindowEvent *)rep)->width,
((XExposeWindowEvent *)rep)->height,
&term.flags) != -1)
{
TabReset (term.tabs);
XClear (screen->window);
ScrnRefresh (screen, 0, 0,
screen->max_row + 1,
screen->max_col + 1);
if (screen->TekEmu) TekRefresh (&term);
}
break;
case ExposeRegion:
if (((XExposeWindowEvent *)rep)->detail ==
ExposeCopy &&
screen->incopy <= 0) {
screen->incopy = 1;
if (screen->scrolls > 0)
screen->scrolls--;
}
if (HandleExposure (screen, &reply))
toggled = 1;
break;
case ExposeCopy:
if (screen->incopy <= 0 && screen->scrolls > 0)
screen->scrolls--;
if (screen->scrolls)
screen->incopy = -1;
else
screen->incopy = 0;
break;
case ButtonPressed:
case ButtonReleased:
if (screen->incopy)
CopyWait (screen);
if (HandleButtons(&term,&reply,pty))
toggled = 1;
break;
/*
* Enter window is being handled just to give xterm
* a kick in the pants when the mouse gets in the
* window in case it was swapped out. Of course,
* one might thrash...
*/
case EnterWindow:
break;
default:
break;
}
} while (screen->display->qlen > 0);
}
}
}
#ifndef ICONWINDOW
RefreshIcon(screen)
register Screen *screen;
{
XBitmapBitsPut(screen->iconwindow, 0, 0, icon_width, icon_height,
icon_bits, screen->foreground, screen->background,
screen->iconmask, GXcopy, AllPlanes);
}
#endif ICONWINDOW
#ifndef vms
get_pty (pty, pty_name)
/*
opens a pty, storing fildes in pty
and it's identifying character in pty_name.
*/
int *pty;
char *pty_name;
{
int devindex, letter = 0;
int fd;
extern errno;
if (debug) {
fd = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2 (fd, fileno (stderr));
}
while (letter < 4) {
ttydev [8] = ptydev [8] = "pqrs" [letter++];
devindex = 0;
while (devindex < 16) {
ptydev [9] = *pty_name = "0123456789abcdef" [devindex++];
if ((*pty = open (ptydev, O_RDWR, 0)) < 0) {
if (debug) fprintf (stderr, "pty %d code %d\n",
devindex - 1, errno);
continue;
}
goto got_pty;
}
}
fprintf (stderr,"Not enough available pty's\n");
exit (11);
got_pty:
if (debug) {
close (fileno (stderr));
close (fd);
}
}
#endif vms
get_terminal (disp, term, fn, fb,
#ifdef ICONWINDOW
fi,
#endif ICONWINDOW
geometry, def,
border, borderwidth, do_warp, slave, reverse, multiscroll, bitmapicon,
tek, fore_color, back_color, brdr_color, curs_color, mous_color
#ifdef JUMPSCROLL
, jumpscroll
#endif JUMPSCROLL
)
/*
* sets up X and initializes the terminal structure except for term.buf.fildes.
*/
char *disp;
register Terminal *term;
char *fn, *fb;
#ifdef ICONWINDOW
char *fi;
#endif ICONWINDOW
char *geometry, *def;
int border, borderwidth, do_warp, reverse, multiscroll, bitmapicon;
int slave;
int tek;
#ifdef JUMPSCROLL
int jumpscroll;
#endif JUMPSCROLL
char *fore_color, *back_color, *brdr_color, *curs_color, *mous_color;
{
int width, height;
FontInfo *fInfo;
#ifdef ICONWINDOW
FontInfo *ifInfo;
#endif ICONWINDOW
register Keyboard *keyboard;
register Screen *screen;
Buffer *buf;
long scale_x, scale_y;
Color cdef;
int pixels[2];
int try = 10;
OpaqueFrame twindow;
keyboard = &term->keyboard;
screen = &term->screen;
buf = &term->buf;
term->flags = WRAPAROUND|SMOOTHSCROLL;
keyboard->flags = NULL;
keyboard->offset = 0;
#ifdef ICONWINDOW
term->actionflags = (bitmapicon == 2) ? ICONINPUT : 0;
#endif ICONWINDOW
buf->cnt = 0;
buf->ptr = &buf->buf[0];
TabReset (term->tabs);
while (try--)
if ((screen->display = XOpenDisplay(disp)) == NULL) {
if (loginflag == 0) {
fprintf(stderr,"No such display server %s\n", disp);
exit(1);
}
sleep (5);
continue;
}
else break;
if (try <= 0) {
fprintf (stderr,"Can't connect to display server %s\n",
disp);
exit (111);
}
screen->foreground = BlackPixel;
screen->background = WhitePixel;
screen->cursorcolor = BlackPixel;
screen->mousecolor = BlackPixel;
screen->xorplane = 1;
if (DisplayCells() > 2 && (fore_color || back_color || curs_color)) {
if (tek) {
if (curs_color && XParseColor(curs_color, &cdef)) {
if (XGetColorCells(0, 2, 1, &screen->xorplane,
pixels)) {
screen->background = pixels[0];
screen->foreground = pixels[1];
screen->cursorcolor = screen->background |
screen->xorplane;
cdef.pixel = screen->cursorcolor;
XStoreColor(&cdef);
}
}
else if (XGetColorCells(0, 1, 1, &screen->xorplane,
&screen->background)) {
screen->foreground = screen->background |
screen->xorplane;
screen->cursorcolor = screen->foreground;
}
if (screen->background != WhitePixel) {
if (back_color == NULL ||
!XParseColor(back_color, &cdef)) {
cdef.pixel = WhitePixel;
XQueryColor(&cdef);
}
cdef.pixel = screen->background;
XStoreColor(&cdef);
if(screen->cursorcolor != screen->foreground) {
cdef.pixel = screen->foreground |
screen->xorplane;
XStoreColor(&cdef);
}
if (fore_color == NULL ||
!XParseColor(fore_color, &cdef)) {
cdef.pixel = BlackPixel;
XQueryColor(&cdef);
}
cdef.pixel = screen->foreground;
XStoreColor(&cdef);
}
}
else {
if (fore_color && XParseColor(fore_color, &cdef) &&
XGetHardwareColor(&cdef)) {
screen->foreground =
screen->foreground = cdef.pixel;
reverse = 0;
}
if (back_color && XParseColor(back_color, &cdef) &&
XGetHardwareColor(&cdef)) {
screen->background = cdef.pixel;
reverse = 0;
}
if (curs_color && XParseColor(curs_color, &cdef) &&
XGetHardwareColor(&cdef))
screen->cursorcolor = cdef.pixel;
else
screen->cursorcolor = screen->foreground;
}
}
screen->border = border;
screen->borderwidth = borderwidth;
screen->fnt_norm = screen->fnt_bold = NULL;
if ((fInfo = XOpenFont(fn)) == NULL) {
fprintf(stderr, "%s: Could not open font %s!\n",
xterm_name, fn);
exit(1);
}
if (fn) screen->fnt_norm = fInfo->id;
if (fb) screen->fnt_bold = XOpenFont(fb)->id;
screen->f_width = fInfo->width;
screen->f_height = fInfo->height;
#ifdef ICONWINDOW
screen->fnt_icon = NULL;
if ((ifInfo = XOpenFont(fi)) == NULL) {
fprintf(stderr, "%s: Could not open font %s!\n",
xterm_name, fi);
exit(1);
}
screen->fnt_icon = ifInfo->id;
screen->if_width = ifInfo->width;
screen->if_height = ifInfo->height;
#endif ICONWINDOW
if (brdr_color && DisplayCells() > 2 &&
XParseColor(brdr_color, &cdef) && XGetHardwareColor(&cdef))
screen->bordertile = XMakeTile(cdef.pixel);
else
screen->bordertile = BlackPixmap;
screen->cursor = XStoreBitmap(xterm_width, xterm_height, xterm_bits);
screen->mask = XStoreBitmap(xterm_mask_width, xterm_mask_height,
xterm_mask_bits);
if (mous_color && DisplayCells() > 2 &&
XParseColor(mous_color, &cdef) && XGetHardwareColor(&cdef))
screen->mousecolor = cdef.pixel;
else
screen->mousecolor = screen->cursorcolor;
screen->curs = XStoreCursor(screen->cursor, screen->mask, 5, 8,
screen->mousecolor, screen->background, GXcopy);
screen->rcurs = XStoreCursor(screen->cursor, screen->mask, 5, 8,
screen->background, screen->mousecolor, GXcopy);
if (reverse) { /* reverse is black background with white chars */
term->flags |= REVERSE_VIDEO;
screen->cursorcolor = screen->background;
screen->background = screen->foreground;
screen->foreground = screen->cursorcolor;
if (screen->bordertile == BlackPixmap)
screen->bordertile = WhitePixmap;
}
screen->bgndtile = XMakeTile(screen->background);
twindow.bdrwidth = screen->borderwidth;
twindow.border = screen->bordertile;
twindow.background = screen->bgndtile;
screen->window = XCreateTerm ("Terminal Emulator", xterm_name,
geometry, def, &twindow, 12, 8,
screen->border * 2, screen->border * 2,
&width, &height,
fInfo, fInfo->width, fInfo->height);
screen->width = twindow.width - border * 2;
screen->height = twindow.height - border * 2;
#ifdef ICONWINDOW
screen->fullwindow = screen->window;
screen->fullwidth = screen->width;
screen->fullheight = screen->height;
screen->ff_height = screen->f_height;
screen->ff_width = screen->f_width;
#endif ICONWINDOW
/* Reset variables used by ANSI emulation. */
screen->ansi.a_type = 0; /* New sequence. */
screen->ansi.a_pintro = 0; /* New sequence. */
screen->ansi.a_final = 0; /* New sequence. */
screen->gsets[0] = 'B'; /* ASCII_G */
screen->gsets[1] = 'B';
screen->gsets[2] = '<'; /* DEC supplemental. */
screen->gsets[3] = '<';
screen->curgl = 0; /* G0 => GL. */
screen->curgr = 2; /* G2 => GR. */
screen->curss = 0; /* No single shift. */
screen->rx8bit = 0; /* 7 bit. */
screen->tx8bit = 0; /* 7 bit. */
screen->mode = ANSInormal;
/* Reset Tektronix alpha mode */
screen->TekGMode = 0;
screen->TekAMode = 0;
screen->cur_x = screen->cur_y = 0;
screen->cur_X = screen->cur_Y = 0;
/* Set Tektronix scale factor */
scale_x = (screen->width << 14) / 4096;
scale_y = (screen->height << 14) / 3128;
#ifdef notdef
/* Alternative method when divide is faster than multiple shifts */
scale_x = (screen->width * 10000) / 4096;
scale_y = (screen->height * 10000) / 3128;
#endif notdef
screen->TekScale = scale_x;
if (scale_y < scale_x) screen->TekScale = scale_y;
if (bitmapicon) {
#ifdef ICONWINDOW
screen->iconwidth = (screen->width / fInfo->width) * ifInfo->width;
screen->iconheight = (screen->height / fInfo->height) * ifInfo->height;
screen->iconwindow = XCreateWindow (RootWindow,
0, 0, icon_width, icon_height,
screen->border, screen->bordertile, screen->bgndtile);
XSelectInput (screen->iconwindow,
(bitmapicon == 2) ?
ExposeWindow | ExposeRegion | ExposeCopy | KeyPressed :
ExposeWindow | ExposeRegion | ExposeCopy);
XDefineCursor(screen->iconwindow,
(reverse ? screen->rcurs : screen->curs));
#else ICONWINDOW
screen->iconwindow = XCreateWindow (RootWindow,
0, 0, icon_width, icon_height, 0, 0, 0);
XTileRelative(screen->iconwindow);
screen->iconmask = XStoreBitmap(icon_mask_width,
icon_mask_height, icon_mask_bits);
XSelectInput (screen->iconwindow, ExposeWindow);
#endif ICONWINDOW
XSetIconWindow(screen->window, screen->iconwindow);
}
#ifdef ICONWINDOW
else
screen->iconwindow = NULL;
#endif ICONWINDOW
if (reverse)
XDefineCursor(screen->window, screen->rcurs);
else XDefineCursor(screen->window, screen->curs);
XStoreName (screen->window, (win_name != (char *) 0 ? win_name:
(do_warp ? "login" :
(slave ? "xtermslave" :
(command_to_exec ? command_to_exec[0] : "xterm")))));
XSetResizeHint (screen->window,
2 * border, 2 * border, fInfo->width, fInfo->height);
XMapWindow (screen->window);
XSelectInput (screen->window, KeyPressed | ExposeWindow | EnterWindow |
ButtonPressed | ButtonReleased | ExposeRegion | ExposeCopy);
if (do_warp)
XWarpMouse (screen->window,
screen->width >> 1, screen->height >>1);
screen->cur_col = screen->cur_row = 0;
screen->max_col = screen->width / fInfo->width - 1;
screen->top_marg = 0;
screen->bot_marg = screen->max_row = screen->height/ fInfo->height - 1;
screen->sc.row = screen->sc.col = screen->sc.flags = NULL;
/* allocate memory for screen buffer */
screen->buf = (ScrnBuf) Allocate (screen->max_row + 1,
screen->max_col +1);
screen->do_wrap = NULL;
screen->scrolls = screen->incopy = 0;
screen->multiscroll = multiscroll;
#ifdef JUMPSCROLL
if (screen->jumpscroll = jumpscroll)
term->flags &= ~SMOOTHSCROLL;
#endif JUMPSCROLL
/* display initial cursor */
CursorToggle (screen, 1);
}
spawn (display, pty, Xsocket, screen, getty, slave, passedPty)
/*
* Inits pty and tty and forks a login process. Returns fd for pty in pty.
* Does not close fd Xsocket.
* If getty, execs getty rather than csh and uses std fd's rather
* than opening a pty/tty pair.
* If slave, the pty named in passedPty is already open for use
*/
int *pty, Xsocket;
Screen *screen;
char *getty; /* if true execs /etc/getty - Xwindow */
int slave;
char *passedPty;
char *display;
{
int index1, tty;
char pty_name;
int discipline;
unsigned lmode;
struct tchars tc;
struct ltchars ltc;
struct sgttyb sg;
char termcap [1024];
char newtc [1024];
char prog [256];
char numbuf[10];
char *ptr;
char *index (), *strindex ();
int i = 0;
char **envnew; /* new environment */
struct passwd *getpwuid();
struct passwd *pw;
char logindev[32];
char *TermName = "xterm";
int ldisc = 0;
/* be real paranoid about getting some usable entry */
if (tgetent (termcap, TermName) == 1
|| (TermName = "vt102", tgetent(termcap, TermName)) == 1
|| (TermName = "ansi", tgetent(termcap, TermName)) == 1) {
/* update termcap string */
/* first do columns */
if ((ptr = strindex (termcap, "co#")) == NULL){
fprintf(stderr,"Can't find co# in termcap string %s\n",
TermName);
exit (1);
}
strncpy (newtc, termcap, ptr - termcap + 3);
newtc[ptr-termcap+3] = '\0';
sprintf (numbuf, "%d\0", screen->max_col + 1);
strcat (newtc, numbuf);
ptr = index (ptr, ':');
strcat (newtc, ptr);
strncpy (termcap, newtc, sizeof(termcap));
/* now do lines */
if ((ptr = strindex (termcap, "li#")) == NULL) {
fprintf(stderr,"Can't find li# in termcap string %s\n",
TermName);
exit (1);
}
strncpy (newtc, termcap, ptr - termcap + 3);
newtc[ptr-termcap+3] = '\0';
sprintf (numbuf, "%d\0", screen->max_row + 1);
strcat (newtc, numbuf);
ptr = index (ptr, ':');
strcat (newtc, ptr);
if (strcmp(TermName, "xterm") != 0)
fprintf(stderr,
"xterm: can't find xterm termcap entry, using %s instead!\n", TermName);
}
#ifndef vms
else fprintf(stderr,"xterm: can't find any usable termcap entry!\n");
if (getty) {
strcpy(logindev,"/dev/");
strcat(logindev,getty);
logindev [5] = 'p';
*pty = open (logindev, O_RDWR, 0);
}
else if (slave) {
*pty = slave;
ptydev[8] = ttydev[8] = passedPty[0];
ptydev[9] = ttydev[9] = passedPty[1];
}
else {
if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) {
if (errno != ENXIO) Error();
else {
no_dev_tty = 1;
sg = d_sg;
tc = d_tc;
discipline = d_disipline;
ltc = d_ltc;
lmode = d_lmode;
for (index1 = 0; index1 < 3; index1++)
close (index1);
}
}
else {
/* get a copy of the current terminal's state */
if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) Error ();
if (ioctl (tty, TIOCGETP, &sg) == -1) Error ();
if (ioctl (tty, TIOCGETC, (int *)&tc) == -1) Error ();
if (ioctl (tty, TIOCGETD, &discipline) == -1) Error ();
if (ioctl (tty, TIOCGLTC, (int *)<c) == -1) Error ();
if (ioctl (tty, TIOCLGET, &lmode) == -1) Error ();
close (tty);
/* close all std file descriptors */
for (index1 = 0; index1 < 3; index1++)
close (index1);
if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) Error ();
if (ioctl (tty, TIOCNOTTY, 0) == -1) Error ();
close (tty);
}
get_pty (pty, &pty_name);
if (*pty != Xsocket + 1) {
dup2 (*pty, Xsocket + 1);
close (*pty);
*pty = Xsocket + 1;
}
ttydev [9] = pty_name;
if ((tty = open (ttydev, O_RDWR, 0)) < 0) Error ();
/* change ownership of tty to real group and user id */
chown (ttydev, getuid (), tty_gid (getgid()));
/* change protection of tty */
chmod (ttydev, 0620);
if (tty != Xsocket + 2) {
dup2 (tty, Xsocket + 2);
close (tty);
tty = Xsocket + 2;
}
/* set the new terminal's state to be the old one's
with minor modifications for efficiency */
sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
sg.sg_flags |= ECHO | CRMOD;
/* make sure speed is set on pty so that editors work right*/
sg.sg_ispeed = B9600;
sg.sg_ospeed = B9600;
if (ioctl (tty, TIOCSETP, &sg) == -1) Error ();
if (ioctl (tty, TIOCSETC, (int *)&tc) == -1) Error ();
if (ioctl (tty, TIOCSETD, &discipline) == -1) Error ();
if (ioctl (tty, TIOCSLTC, (int *)<c) == -1) Error ();
if (ioctl (tty, TIOCLSET, &lmode) == -1) Error ();
#ifdef sun
#ifdef TIOCCONS
if (SunConsole) {
int on = 1;
if (ioctl (tty, TIOCCONS, &on) == -1) Error();
}
#endif TIOCCONS
#endif sun
close (open ("/dev/null", O_RDWR, 0));
for (index1 = 0; index1 < 3; index1++)
dup2 (tty, index1);
}
if (!slave && (screen->pid = fork ()) == -1) Error ();
if (!slave && screen->pid == 0) {
extern char **environ;
int pgrp = getpid();
close (Xsocket);
close (*pty);
if (getty == NULL) close (tty);
signal (SIGCHLD, SIG_DFL);
signal (SIGHUP, SIG_IGN);
/* copy the environment before Setenving */
while (environ [i] != NULL) i++;
envnew = (char **) malloc (sizeof (char *) * (i + 4));
for (; i >= 0; i--) envnew [i] = environ [i];
environ = envnew;
Setenv ("TERM=", TermName);
Setenv ("TERMCAP=", newtc);
/* put the display into the environment of the shell*/
if (display[0] != '\0')
Setenv ("DISPLAY=", screen->display->displayname);
pw = getpwuid (getuid ());
signal(SIGTERM, SIG_DFL);
ioctl(0, TIOCSPGRP, &pgrp);
setpgrp (0, 0);
close(open(ttyname(0), O_WRONLY, 0));
setpgrp (0, pgrp);
if (dologinflag) /* login */
utrelog(1, pw->pw_name, screen->display->displayname);
setgid(getgid ());
setuid(getuid ());
if (command_to_exec) {
execvp(command_to_exec[0], command_to_exec, 0);
}
signal(SIGHUP, SIG_IGN);
if (getty) {
ioctl (0, TIOCNOTTY, 0);
execl ("/etc/getty", "+", "Xwindow", getty, 0);
}
signal(SIGHUP, SIG_DFL);
if (*pw->pw_shell == '\0') pw->pw_shell = "/bin/sh";
/* make sure line discipline gets set */
ldisc = 0;
ioctl(0, TIOCSETD, &ldisc);
if (!strcmp(pw->pw_shell, "/bin/csh")) {
ldisc = NTTYDISC;
ioctl(0, TIOCSETD, &ldisc);
}
ptr = rindex(pw->pw_shell, '/');
if (ptr == NULL)
ptr = pw->pw_shell;
else
ptr++;
if (dologinflag) {
prog[0] = '-';
strcpy(&prog[1], ptr);
} else
strcpy(prog, ptr);
execlp (pw->pw_shell, prog, 0);
fprintf (stderr,"Error: Could not exec %s!\n", pw->pw_shell);
sleep(5);
Cleanup(121);
}
close (tty);
signal(SIGHUP,SIG_IGN);
signal(SIGTTOU,SIG_IGN); /* so that TIOCSWINSZ doesn't block */
if ((tty = open (no_dev_tty ? "/dev/null" : "/dev/tty",
O_RDWR, 0)) < 0) Error();
for (index1 = 0; index1 < 3; index1++)
dup2 (tty, index1);
if (tty > 2) close (tty);
/* set ids to user's */
/*
setgid (getgid ());
setuid (getuid ());
setregid (getegid (), getgid ());
setreuid (geteuid (), getuid ());
*/
#else vms
{
struct astroutine ast;
if (open_pty (pty, Xsocket+1) < 0) Error ();
ast.routine = Cleanup; /* do this when pty hangs up */
ast.param = 0;
ptyctl (*pty, TIOCHPCL, &ast);
if (!getty) { /* spawn a subprocess */
char ptyname[64], command_string[256];
short ptychan;
struct tmode ptymode;
struct dsc$descriptor_s ptydsc, command;
int flags = 0x01;
/* in_getname() works just like getname() */
if (in_getname( *pty, ptyname ) == NULL) {
perror( "Error: pty getname() failed\n" );
Cleanup( vaxc$errno );
}
ptydsc.dsc$b_dtype = DSC$K_DTYPE_T;
ptydsc.dsc$b_class = DSC$K_CLASS_S;
ptydsc.dsc$w_length = strlen (ptyname);
ptydsc.dsc$a_pointer = ptyname;
/* assign a channel to keep from hanging up pty */
if ((vaxc$errno = sys$assign( &ptydsc, &ptychan, 0, 0 )) != SS$NORMAL) {
perror( "Error: Assign pty failed\n" );
Cleanup( vaxc$errno );
}
ptyctl( *pty, TIOCGETP, &ptymode );
ptymode.type = TT$_VT102;
ptymode.basic_char |= TT$M_LOWER | TT$M_MECHTAB | TT$M_SCOPE;
ptymode.ext_char |= TT2$M_ANSICRT | TT2$M_EDIT | TT2$M_DECCRT;
ptymode.width = screen->max_col + 1;
ptymode.length = screen->max_row + 1;
ptyctl( *pty, TIOCSETP, &ptymode );
if (command_to_exec) {
int i;
strcpy( command_string, command_to_exec[0] );
for (i=1; command_to_exec[i] != NULL; i++) {
strcat( command_string, " " );
strcat( command_string, command_to_exec[i] );
}
command.dsc$b_dtype = DSC$K_DTYPE_T;
command.dsc$b_class = DSC$K_CLASS_S;
command.dsc$a_pointer = command_string;
command.dsc$w_length = strlen (command_string);
}
Setenv ("TERM", TermName);
Setenv ("TERMCAP", newtc);
/* put the display into the environment of the shell*/
if (display[0] != '\0')
Setenv ("DISPLAY", screen->display->displayname);
if ((vaxc$errno = lib$spawn( (command_to_exec ? &command : 0)
, (command_to_exec ? 0 : &ptydsc), &ptydsc, &flags
, 0, 0, 0, 0, Cleanup, 0, 0, 0 )) != SS$_NORMAL) {
perror( "Error: Spawn failed\n" );
Cleanup( vaxc$errno );
}
sys$dassgn( ptychan );
}
}
#endif vms
}
#ifndef vms
static reapchild ()
{
extern Terminal term;
register long pgrp;
union wait status;
int pid;
if (debug) printf ("Exiting\n");
pid = wait3 (&status, WNOHANG, NULL);
if (!pid) return;
if (pid != term.screen.pid) return;
if (dologinflag)
utrelog(0, "", "");
Cleanup(0);
}
consolepr(string)
char *string;
{
extern int errno;
extern char *sys_errlist[];
int oerrno;
int f;
oerrno = errno;
f = open("/dev/console",O_WRONLY, 0);
write(f, "xterm: ", 7);
write(f, string, strlen(string));
write(f, ": ", 2);
write(f, sys_errlist[oerrno],strlen(sys_errlist[oerrno]));
write(f, "\n", 1);
close(f);
if ((f = open("/dev/tty", 2, 0)) >= 0) {
ioctl(f, TIOCNOTTY, 0);
close(f);
}
}
#define TTYGRPNAME "tty"
tty_gid(default_gid)
int default_gid;
{
struct group *getgrnam(), *gr;
int gid = default_gid;
gr = getgrnam(TTYGRPNAME);
if (gr != (struct group *) 0)
gid = gr->gr_gid;
endgrent();
return (gid);
}
utrelog(io, user, display)
int io;
char *user;
char *display;
{
struct utmp ut;
struct ttyent *ty;
register int s;
long slot;
int ufd;
char *colon;
if (io == 1) {
strncpy(ut.ut_line, &ttydev[5], sizeof ut.ut_line);
colon = index(display, ':');
if (colon)
*colon = '\0';
strncpy(ut.ut_host, display, sizeof ut.ut_host);
if (colon)
*colon = ':';
strncpy(ut.ut_name, user, sizeof ut.ut_name);
(void) time(&ut.ut_time);
}
else {
strcpy(ut.ut_line, "");
strcpy(ut.ut_name, "");
strcpy(ut.ut_host, "");
ut.ut_time = 0;
chown(ttydev, 0, 0);
chmod(ttydev, 0666);
}
setttyent();
slot = 0;
s = 0;
while ((ty = getttyent()) != NULL) {
s++;
if (strcmp(ty->ty_name, &ttydev[5]) == 0) {
slot = s;
break;
}
}
endttyent();
if (slot > 0 && (ufd = open("/etc/utmp", O_WRONLY, 0)) >= 0) {
if (lseek(ufd, slot * sizeof ut, 0) < 0L ||
write(ufd, (char *)&ut, sizeof ut) != sizeof ut) {
close(ufd);
return(-1);
}
close(ufd);
}
return(0);
}
#endif vms