/* 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