4.1cBSD/a/sys/sys/tty_tb.c

Compare this file to the similar file:
Show the results in this format:

/*	tty_tb.c	4.7	82/12/05	*/

#include "tb.h"
#if NTB > 0

#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/ioctl.h"
#include "../h/tty.h"
#include "../h/proc.h"
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/conf.h"
#include "../h/buf.h"
#include "../h/uio.h"

/*
 * Line discipline for RS232 tablets.
 * Supplies binary coordinate data.
 *
 * FIX WAY IN WHICH OVERLAYING IS DONE
 * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE.
 */

#define MTABCHAR 5
#define MNTABCHAR 6

struct tbposition {
	int	xpos;
	int	ypos;
	short	status;
	short	scount;
};

/*
 * Open as tablet discipline.  Called when discipline changed
 * with ioctl, and changes the interpretation of the information
 * in the tty structure.
 */
/*ARGSUSED*/
tbopen(dev, tp)
	dev_t dev;
	register struct tty *tp;
{
	register struct tbposition *tbp;

	if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) {
		return (EBUSY);
	wflushtty(tp);
	tp->t_cp = (char *) &tp->t_un.T_CTLQ;	/* overlay control queue */
	tp->t_inbuf = 0;
	tbp = (struct tbposition *) &tp->t_rocount;
	tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0;
	return (0);
}

/*
 * Break down... called when discipline changed or from device
 * close routine.
 */
tbclose(tp)
	register struct tty *tp;
{
	register int s = spl5();

	tp->t_cp = 0;
	tp->t_inbuf = 0;
	tp->t_rawq.c_cc = 0;		/* clear queues -- paranoid */
	tp->t_canq.c_cc = 0;
	tp->t_un.T_CTLQ.c_cc = 0;	/* clear overlaid queue status */
	tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL;
	tp->t_line = 0;		/* paranoid: avoid races */
	splx(s);
}

/*
 * Read from a tablet line.
 * Characters have been buffered in a buffer and
 * decoded. The coordinates are now sluffed back to the user.
 */
tbread(tp, uio)
	register struct tty *tp;
	struct uio *uio;
{
	register int i;
	register s;
	struct tbposition tbposition;

	if ((tp->t_state&TS_CARR_ON)==0)
		return (EIO);
	return (iomove(&tp->t_rocount, sizeof tbposition, UIO_READ, uio));
}

/*
 * Low level character input routine.
 * Stuff the character in the buffer, and decode the it
 * if all the chars are there.
 *
 * This routine could be expanded in-line in the receiver
 * interrupt routine of the dh-11 to make it run as fast as possible.
 */
int	LASTTABC;

tbinput(c, tp)
	register int c;
	register struct tty *tp;
{

	if (tp->t_line == TABLDISC) {
		if ((c&0200) || (tp->t_inbuf == MTABCHAR)) {
			tp->t_cp = (char *) &tp->t_un.T_CTLQ;
			tp->t_inbuf = 0;
		}
		*tp->t_cp++ = c&0177;
		if (++tp->t_inbuf == MTABCHAR)
			tbdecode((char *) &tp->t_un.T_CTLQ,
				(struct tbposition *) &tp->t_rocount);
	} else if (tp->t_line == NTABLDISC) {
		if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) {
			tp->t_cp = (char *) &tp->t_un.T_CTLQ;
			tp->t_inbuf = 0;
		}
		*tp->t_cp++ = c&0177;
		if (++tp->t_inbuf == MNTABCHAR)
			tbndecode((char *) &tp->t_un.T_CTLQ,
					(struct tbposition *) &tp->t_rocount);
	}
}

/*
 * Decode tablet coordinates from ascii to binary.
 *	(gtco 6 character format)
 */
tbndecode(cp, tbposition)
	register char *cp;
	register struct tbposition *tbposition;
{

	tbposition->status = *cp>>2;	/* this needs to be decoded */
	tbposition->xpos = ((*cp++)&03)<<14;
	tbposition->xpos |= (*cp++)<<7;
	tbposition->xpos |= (*cp++);
	tbposition->ypos = ((*cp++)&03)<<14;
	tbposition->ypos |= (*cp++)<<7;
	tbposition->ypos |= (*cp++);
	tbposition->scount++;
}

/*
 * Decode tablet coordinates from ascii to binary.
 *	(hitachi 5 character format)
 */
tbdecode(cp, tbposition)
	register char *cp;
	register struct tbposition *tbposition;
{
	register int status;
	register char byte;

	byte = *cp++;
	status = (byte&0100) ? 0100000 : 0;
	byte &= ~0100;
	if (byte > 036)
		status |= 1<<((byte-040)/2);
	tbposition->xpos = (*cp++)<<7;
	tbposition->xpos |= (*cp++);
	if (tbposition->xpos < 256)	/* tablet wraps around at 256 */
		status &= 077777;	/* make it out of proximity */
	tbposition->ypos = (*cp++)<<7;
	tbposition->ypos |= (*cp++);
	tbposition->status  = status;
	tbposition->scount++;
}

/*
 * This routine is called whenever a ioctl is about to be performed
 * and gets a chance to reject the ioctl.  We reject all teletype
 * oriented ioctl's except those which set the discipline, and
 * those which get parameters (gtty and get special characters).
 */
/*ARGSUSED*/
tbioctl(tp, cmd, data, flag)
	struct tty *tp;
	caddr_t data;
{

	if ((cmd>>8) != 't')
		return (cmd);
	switch (cmd) {

	case TIOCSETD:
	case TIOCGETD:
	case TIOCGETP:
	case TIOCGETC:
		return (cmd);
	}
	u.u_error = ENOTTY;
	return (0);
}
#endif