ftp.nice.ch/pub/next/unix/macintosh/uw.4.2.N.bs.tar.gz#/uw/server/uw_tty_mac.c

This is uw_tty_mac.c in view mode; [Download] [Up]

/*
 *	uw_tty - terminal support for UW
 *
 * Copyright 1985,1986 by John D. Bruner.  All rights reserved.  Permission to
 * copy this program is given provided that the copy is not sold and that
 * this copyright notice is included.
 */

#include <sys/types.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/stat.h>

#include "uw_param.h"
#include "uw_win.h"
#include "uw_opt.h"

#define	XON	021	/* ASCII XON (ASR-33 paper-tape reader on) */
#define	XOFF	023	/* ASCII XOFF (ASR-33 paper-tape reader off) */

static char *envinfo[][3] = {
	{
		"TERM=uw",
		"TERMCAP=uw:cr=^M:do=^J:nl=^J:al=\\EE:am:le=^H:bs:ce=\\ET:cm=\\E=%+ %+ :cl=^Z:cd=\\EY:co#80:dc=\\EW:dl=\\ER:ei=\\Er:ho=^^:im=\\Eq:li#24:mi:nd=^L:up=^K:MT:km:so=\\EG1:se=\\EG0:us=\\EG@:ue=\\EG0:mb=\\EGA:md=\\EG@:me=\EG0:mr=\\EG1:",
		(char *)0
	},
	{
		"TERM=vt52",
		(char *)0
	},
	{
		"TERM=ansi",
		(char *)0
	},
	{
		"TERM=tek4010",
		(char *)0
	}
};

/* private (emulation-specific) data */
struct tty {
	struct {
		unsigned short	h,v;
	}		t_size;
	unsigned	t_fontsz;
	unsigned	t_clipb;
	unsigned	t_bell;
	unsigned	t_curs;
	unsigned	t_chgsz;
};

#define	WOTTY_SIZE	8		/* terminal size in (row, col) */
#define	WOTTY_FONTSZ	9		/* font size index (0=7pt, 1=9pt) */
#define	WOTTY_CLIPB	10		/* 0=clipboard, 1=encode mouse clicks */
#define	WOTTY_BELL	11		/* bell: bit 0=visible, bit 1=audible */
#define	WOTTY_CURSOR	12		/* cursor type: 0=block, 1=underscore */
#define	WOTTY_CHGSZ	13		/* change actual size (not view size) */

static woptarg_t size_xdr[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
static woptarg_t fontsz_xdr[] = { WOA_UDATA(6), WOA_END };
static woptarg_t clipb_xdr[] = { WOA_UDATA(1), WOA_END };
static woptarg_t bell_xdr[] = { WOA_UDATA(2), WOA_END };
static woptarg_t curs_xdr[] = { WOA_UDATA(1), WOA_END };
static woptarg_t chgsz_xdr[] = { WOA_UDATA(1), WOA_END };

/* TIOCSWINSZ is in 4.3BSD, TIOCSSIZE is in Sun UNIX */
#if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
#define	RPTWINSZ	(1<<WOTTY_SIZE)
#else
#define	RPTWINSZ	0
#endif

#define	TTY_WOPT	{					\
	0, 0, 0, 0,						\
	RPTWINSZ|(1<<WOTTY_FONTSZ)|(1<<WOTTY_CLIPB)|		\
	 (1<<WOTTY_BELL)|(1<<WOTTY_CURSOR)|(1<<WOTTY_CHGSZ),	\
	{							\
		{ NULL, NULL, NULL },				\
		{ NULL, NULL, NULL },				\
		{ NULL, NULL, NULL },				\
		{ NULL, NULL, NULL },				\
		{ NULL, NULL, NULL },				\
		{ NULL, NULL, NULL },				\
		{ NULL, NULL, NULL },				\
		{ NULL, NULL, NULL },				\
		{ size_xdr, tty_getopt, tty_setopt },		\
		{ fontsz_xdr, tty_getopt, tty_setopt },		\
		{ clipb_xdr, tty_getopt, tty_setopt },		\
		{ bell_xdr, tty_getopt, tty_setopt },		\
		{ curs_xdr, tty_getopt, tty_setopt },		\
		{ chgsz_xdr, tty_getopt, tty_setopt }		\
	}							\
}
extern int tty_start();
extern void tty_stop(), tty_setopt(), tty_setext();
extern char *tty_getopt();

struct emulation adm31_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
struct emulation vt52_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
struct emulation ansi_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
struct emulation tek_emul = { { 0, 0, 0, 0, 0 }, tty_start, tty_stop };

tty_mode(f)
int f;
{
	static struct sgttyb ostty, nstty;
	static struct tchars otchars, ntchars;
	static struct ltchars oltchars, nltchars;
	static int olmode, nlmode;
	static int operm;
	static saved;
	static int inout = FREAD|FWRITE;
	struct stat st;

	/*
	 * This routine either saves the current terminal modes and then
	 * sets up the terminal line or resets the terminal modes (depending
	 * upon the value of "f").  The terminal line is used in "cbreak"
	 * mode with all special characters except XON/XOFF disabled.  The
	 * hated (by me) LDECCTQ mode is required for the Macintosh to
	 * handle flow control properly.
	 */
	if (f == 1) {
		if (fstat(0, &st) == 0)
			operm = st.st_mode & 06777;
		else
			operm = -1;
		if (ioctl(0, (int)TIOCGETP, (char *)&ostty) < 0) {
			perror("ioctl((int)TIOCGETP)");
			done(1);
		}
		if (ioctl(0, (int)TIOCGETC, (char *)&otchars) < 0) {
			perror("ioctl((int)TIOCGETC)");
			done(1);
		}
		if (ioctl(0, (int)TIOCGLTC, (char *)&oltchars) < 0) {
			perror("ioctl((int)TIOCGLTC)");
			done(1);
		}
		if (ioctl(0, (int)TIOCLGET, (char *)&olmode) < 0) {
			perror("ioctl((int)TIOCLGET)");
			done(1);
		}
		nstty = ostty;
		nstty.sg_erase = nstty.sg_kill = -1;
		nstty.sg_flags |= CBREAK;
		nstty.sg_flags &= ~(RAW|CRMOD|ECHO|LCASE|XTABS|ALLDELAY);
		ntchars.t_intrc = ntchars.t_quitc = -1;
		ntchars.t_eofc = ntchars.t_brkc = -1;
		ntchars.t_startc = XON;
		ntchars.t_stopc = XOFF;
		nltchars.t_suspc = nltchars.t_dsuspc = -1;
		nltchars.t_rprntc = nltchars.t_flushc = -1;
		nltchars.t_werasc = nltchars.t_lnextc = -1;
		nlmode = olmode | LDECCTQ;
		if (operm != -1 && fchmod(0, S_IREAD|S_IWRITE) < 0)
			operm = -1;
		if (ioctl(0, (int)TIOCSETN, (char *)&nstty) < 0) {
			perror("ioctl((int)TIOCSETN)");
			done(1);
		}
		if (ioctl(0, (int)TIOCSETC, (char *)&ntchars) < 0) {
			perror("ioctl((int)TIOCSETC");
			done(1);
		}
		if (ioctl(0, (int)TIOCSLTC, (char *)&nltchars) < 0) {
			perror("ioctl((int)TIOCSLTC");
			done(1);
		}
		if (ioctl(0, (int)TIOCLSET, (char *)&nlmode) < 0) {
			perror("ioctl((int)TIOCLSET)");
			done(1);
		}
		saved = 1;
	} else if (saved) {
		(void)ioctl(0, (int)TIOCFLUSH, (char *)&inout);
		(void)ioctl(0, (int)TIOCSETP, (char *)&ostty);
		(void)ioctl(0, (int)TIOCSETC, (char *)&otchars);
		(void)ioctl(0, (int)TIOCSLTC, (char *)&oltchars);
		(void)ioctl(0, (int)TIOCLSET, (char *)&olmode);
		if (operm != -1)
			(void)fchmod(0, operm);
	}
}

static
tty_start(w)
register struct window *w;
{
	register struct tty *t;
	extern char *malloc();

	/*
	 * Start up a terminal emulation.  Establish reasonable defaults
	 * for the terminal-specific window options.
	 */
	if (w->w_type != WT_TEK4010) {
		if ((w->w_private = malloc(sizeof(struct tty))) != NULL) {
			t = (struct tty *)w->w_private;
			t->t_size.h = 80;
			t->t_size.v = 24;
			t->t_fontsz = 0;
			t->t_clipb = 0;
			t->t_bell = 3;
			t->t_curs = 0;
			t->t_chgsz = 0;
			return(1);
		} else
			return(0);
	} else {
		w->w_private = (char *)0;
		return(1);
	}
}

static
void
tty_stop(w)
register struct window *w;
{
	/*
	 * Shut down (stop) a terminal emulation.
	 */
	free(w->w_private);
	w->w_private = (char *)0;
}

static
void
tty_setext(wod)
register struct woptdefn *wod;
{
	/*
	 * This routine makes adjustments to the window option definitions
	 * for external windows.  Basically, we turn off reporting for
	 * WOTTY_SIZE.  (If the external process wants to handle this, it
	 * can turn it back on.)
	 */
	WOPT_CLR(wod->wod_do, WOTTY_SIZE);
	WOPT_CLR(wod->wod_askrpt, WOTTY_SIZE);
}

tty_envinit(wtype)
register wtype_t wtype;
{
	/*
	 * Set up environment variables corresponding to the window type
	 * "wtype".
	 */
	env_set(envinfo[wtype]);
}

static
char *
tty_getopt(win, num)
caddr_t win;
woption_t num;
{
	register struct tty *t;
	static union optvalue ov;
	struct window *w;

	if ((w=(struct window *)win) != NULL && w->w_alloc &&
	    (t=(struct tty *)w->w_private) != NULL) {
		switch (num) {
		case WOTTY_SIZE:
			ov.ov_point.h = t->t_size.h;
			ov.ov_point.v = t->t_size.v;
			break;
		case WOTTY_FONTSZ:
			ov.ov_udata6 = t->t_fontsz;
			break;
		case WOTTY_CLIPB:
			ov.ov_udata1 = t->t_clipb;
			break;
		case WOTTY_BELL:
			ov.ov_udata2 = t->t_bell;
			break;
		case WOTTY_CURSOR:
			ov.ov_udata1 = t->t_curs;
			break;
		case WOTTY_CHGSZ:
			ov.ov_udata1 = t->t_chgsz;
			break;
		}
	}
	return((char *)&ov);
}

static
void
tty_setopt(win, num, value)
caddr_t win;
woption_t num;
char *value;
{
	register struct tty *t;
	register union optvalue *ovp;
	register struct window *w;

	if ((w=(struct window *)win) != NULL && w->w_alloc &&
	    (t=(struct tty *)w->w_private) != NULL &&
	    (ovp = (union optvalue *)value) != NULL) {
		switch (num) {
		case WOTTY_SIZE:
			t->t_size.h = ovp->ov_point.h;
			t->t_size.v = ovp->ov_point.v;
#ifdef TIOCSWINSZ
			if (w->w_class == WC_INTERNAL) {
				/* set window size on pty (4.3BSD) */
				struct winsize ws;
				ws.ws_row = t->t_size.v;
				ws.ws_col = t->t_size.h;
				ws.ws_xpixel = w->w_size.h;
				ws.ws_ypixel = w->w_size.v;
				(void)ioctl(w->w_datafd, (int)TIOCSWINSZ,
				    (char *)&ws);
			}
#else
#ifdef TIOCSSIZE
			if (w->w_class == WC_INTERNAL) {
				/* set window size on pty (Sun) */
				struct ttysize ts;
				ts.ts_lines = t->t_size.v;
				ts.ts_cols = t->t_size.h;
				(void)ioctl(w->w_datafd, (int)TIOCSSIZE,
				    (char *)&ts);
			}
#endif
#endif
			break;
		case WOTTY_FONTSZ:
			t->t_fontsz = ovp->ov_udata6;
			break;
		case WOTTY_CLIPB:
			t->t_clipb = ovp->ov_udata1;
			break;
		case WOTTY_BELL:
			t->t_bell = ovp->ov_udata2;
			break;
		case WOTTY_CURSOR:
			t->t_curs = ovp->ov_udata1;
			break;
		case WOTTY_CHGSZ:
			t->t_chgsz = ovp->ov_udata1;
			break;
		}
	}
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.