1*7732Sroot /* tty_tb.c 4.3 82/08/13 */ 27297Ssam 37297Ssam #include "tb.h" 47297Ssam #if NTB > 0 57297Ssam 67297Ssam #include "../h/param.h" 77297Ssam #include "../h/systm.h" 87297Ssam #include "../h/dir.h" 97297Ssam #include "../h/user.h" 107297Ssam #include "../h/tty.h" 117297Ssam #include "../h/proc.h" 127297Ssam #include "../h/inode.h" 137297Ssam #include "../h/file.h" 147297Ssam #include "../h/conf.h" 157297Ssam #include "../h/buf.h" 16*7732Sroot #include "../h/uio.h" 177297Ssam 187297Ssam /* 197297Ssam * Line discipline for RS232 tablets. 207297Ssam * 217297Ssam * This supplies binary coordinate data to a user level program 227297Ssam * with a minimum of fuss. 237297Ssam * 247297Ssam * This discipline requires that tty device drivers call 257297Ssam * the line specific l_ioctl routine from their ioctl routines, 267297Ssam * assigning the result to cmd so that we can refuse most tty specific 277297Ssam * ioctls which are unsafe because we have ambushed the 287297Ssam * teletype input queues and other data, overlaying them with 297297Ssam * the following information: the tty queue header, t_un.T_CTLQ, 307297Ssam * is overlaid with a MTABCHAR character buffer -- the raw input 317297Ssam * chars. The local characters (t_rocount on) are overlaid with 327297Ssam * the current coordinate position. 337297Ssam */ 347297Ssam 357297Ssam #define MTABCHAR 5 367297Ssam #define MNTABCHAR 6 377297Ssam struct tbposition { 387297Ssam int xpos; 397297Ssam int ypos; 407297Ssam short int status; 417297Ssam short int scount; 427297Ssam }; 437297Ssam 447297Ssam /* 457297Ssam * Open as tablet discipline. Called when discipline changed 467297Ssam * with ioctl, and changes the interpretation of the information 477297Ssam * in the tty structure. 487297Ssam */ 497297Ssam /*ARGSUSED*/ 507297Ssam tbopen(dev, tp) 517632Ssam dev_t dev; 527632Ssam register struct tty *tp; 537297Ssam { 547297Ssam register struct tbposition *tbp; 557297Ssam 567297Ssam if (u.u_error) 577297Ssam return; /* paranoia */ 587297Ssam if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) { 597297Ssam u.u_error = EBUSY; 607297Ssam return; 617297Ssam } 627297Ssam wflushtty(tp); 637297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; /* overlay control queue */ 647297Ssam tp->t_inbuf = 0; 657297Ssam tbp = (struct tbposition *) &tp->t_rocount; 667297Ssam tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0; 677297Ssam } 687297Ssam 697297Ssam /* 707297Ssam * Break down... called when discipline changed or from device 717297Ssam * close routine. 727297Ssam */ 737297Ssam tbclose(tp) 747297Ssam register struct tty *tp; 757297Ssam { 767297Ssam register s; 777297Ssam 787297Ssam s = spl5(); 797297Ssam tp->t_cp = 0; 807297Ssam tp->t_inbuf = 0; 817297Ssam tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */ 827297Ssam tp->t_canq.c_cc = 0; 837297Ssam tp->t_un.T_CTLQ.c_cc = 0; /* clear overlaid queue status */ 847297Ssam tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL; 857297Ssam tp->t_line = 0; /* paranoid: avoid races */ 867297Ssam splx(s); 877297Ssam } 887297Ssam 897297Ssam /* 907297Ssam * Read from a tablet line. 917297Ssam * Characters have been buffered in a buffer and 927297Ssam * decoded. The coordinates are now sluffed back to the user. 937297Ssam */ 94*7732Sroot tbread(tp, uio) 95*7732Sroot register struct tty *tp; 96*7732Sroot struct uio *uio; 977297Ssam { 987297Ssam register int i; 997297Ssam register s; 1007297Ssam struct tbposition tbposition; 1017297Ssam 1027297Ssam if ((tp->t_state&TS_CARR_ON)==0) 1037297Ssam return (-1); 104*7732Sroot u.u_error = copyuout(uio, &tp->t_rocount, sizeof tbposition); 105*7732Sroot if (u.u_error) 1067297Ssam return (-1); 1077297Ssam return (0); 1087297Ssam } 1097297Ssam 1107297Ssam /* 1117297Ssam * Low level character input routine. 1127297Ssam * Stuff the character in the buffer, and decode the it 1137297Ssam * if all the chars are there. 1147297Ssam * 1157297Ssam * This routine could be expanded in-line in the receiver 1167297Ssam * interrupt routine of the dh-11 to make it run as fast as possible. 1177297Ssam */ 1187297Ssam int LASTTABC; 1197297Ssam tbinput(c, tp) 1207297Ssam register c; 1217297Ssam register struct tty *tp; 1227297Ssam { 1237297Ssam 1247297Ssam if(tp->t_line == TABLDISC) { 1257297Ssam if((c&0200) || (tp->t_inbuf == MTABCHAR)) { 1267297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; 1277297Ssam tp->t_inbuf = 0; 1287297Ssam } 1297297Ssam *tp->t_cp++ = c&0177; 1307297Ssam if(++tp->t_inbuf == MTABCHAR) 1317297Ssam tbdecode((char *) &tp->t_un.T_CTLQ, 1327297Ssam (struct tbposition *) &tp->t_rocount); 1337297Ssam } else if(tp->t_line == NTABLDISC) { 1347297Ssam if((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 1357297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; 1367297Ssam tp->t_inbuf = 0; 1377297Ssam } 1387297Ssam *tp->t_cp++ = c&0177; 1397297Ssam if(++tp->t_inbuf == MNTABCHAR) 1407297Ssam tbndecode((char *) &tp->t_un.T_CTLQ, 1417297Ssam (struct tbposition *) &tp->t_rocount); 1427297Ssam } 1437297Ssam } 1447297Ssam 1457297Ssam /* 1467297Ssam * Decode tablet coordinates from ascii to binary. 1477297Ssam * (gtco 6 character format) 1487297Ssam */ 1497297Ssam tbndecode(cp, tbposition) 1507297Ssam register char *cp; 1517297Ssam register struct tbposition *tbposition; 1527297Ssam { 1537297Ssam 1547297Ssam tbposition->status = *cp>>2; /* this needs to be decoded */ 1557297Ssam tbposition->xpos = ((*cp++)&03)<<14; 1567297Ssam tbposition->xpos |= (*cp++)<<7; 1577297Ssam tbposition->xpos |= (*cp++); 1587297Ssam tbposition->ypos = ((*cp++)&03)<<14; 1597297Ssam tbposition->ypos |= (*cp++)<<7; 1607297Ssam tbposition->ypos |= (*cp++); 1617297Ssam tbposition->scount++; 1627297Ssam } 1637297Ssam 1647297Ssam /* 1657297Ssam * Decode tablet coordinates from ascii to binary. 1667297Ssam * (hitachi 5 character format) 1677297Ssam */ 1687297Ssam tbdecode(cp, tbposition) 1697297Ssam register char *cp; 1707297Ssam register struct tbposition *tbposition; 1717297Ssam { 1727297Ssam register int status; 1737297Ssam register char byte; 1747297Ssam 1757297Ssam byte = *cp++; 1767297Ssam status = (byte&0100) ? 0100000 : 0; 1777297Ssam byte &= ~0100; 1787297Ssam if(byte > 036) 1797297Ssam status |= 1<<((byte-040)/2); 1807297Ssam tbposition->xpos = (*cp++)<<7; 1817297Ssam tbposition->xpos |= (*cp++); 1827297Ssam if(tbposition->xpos < 256) /* tablet wraps around at 256 */ 1837297Ssam status &= 077777; /* make it out of proximity */ 1847297Ssam tbposition->ypos = (*cp++)<<7; 1857297Ssam tbposition->ypos |= (*cp++); 1867297Ssam tbposition->status = status; 1877297Ssam tbposition->scount++; 1887297Ssam } 1897297Ssam 1907297Ssam /* 1917297Ssam * This routine is called whenever a ioctl is about to be performed 1927297Ssam * and gets a chance to reject the ioctl. We reject all teletype 1937297Ssam * oriented ioctl's except those which set the discipline, and 1947297Ssam * those which get parameters (gtty and get special characters). 1957297Ssam */ 1967297Ssam /*ARGSUSED*/ 1977632Ssam tbioctl(tp, cmd, data, flag) 1987632Ssam struct tty *tp; 1997632Ssam caddr_t data; 2007297Ssam { 2017297Ssam 2027297Ssam if ((cmd>>8) != 't') 2037297Ssam return (cmd); 2047297Ssam switch (cmd) { 2057297Ssam 2067297Ssam case TIOCSETD: 2077297Ssam case TIOCGETD: 2087297Ssam case TIOCGETP: 2097297Ssam case TIOCGETC: 2107297Ssam return (cmd); 2117297Ssam } 2127297Ssam u.u_error = ENOTTY; 2137297Ssam return (0); 2147297Ssam } 2157297Ssam #endif 216