1 /* tty_tb.c 4.5 82/10/13 */ 2 3 #include "tb.h" 4 #if NTB > 0 5 6 #include "../h/param.h" 7 #include "../h/systm.h" 8 #include "../h/dir.h" 9 #include "../h/user.h" 10 #include "../h/tty.h" 11 #include "../h/proc.h" 12 #include "../h/inode.h" 13 #include "../h/file.h" 14 #include "../h/conf.h" 15 #include "../h/buf.h" 16 #include "../h/uio.h" 17 18 /* 19 * Line discipline for RS232 tablets. 20 * Supplies binary coordinate data. 21 * 22 * FIX WAY IN WHICH OVERLAYING IS DONE 23 * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE. 24 */ 25 26 #define MTABCHAR 5 27 #define MNTABCHAR 6 28 29 struct tbposition { 30 int xpos; 31 int ypos; 32 short status; 33 short scount; 34 }; 35 36 /* 37 * Open as tablet discipline. Called when discipline changed 38 * with ioctl, and changes the interpretation of the information 39 * in the tty structure. 40 */ 41 /*ARGSUSED*/ 42 tbopen(dev, tp) 43 dev_t dev; 44 register struct tty *tp; 45 { 46 register struct tbposition *tbp; 47 48 if (u.u_error) 49 return; /* paranoia */ 50 if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) { 51 u.u_error = EBUSY; 52 return; 53 } 54 wflushtty(tp); 55 tp->t_cp = (char *) &tp->t_un.T_CTLQ; /* overlay control queue */ 56 tp->t_inbuf = 0; 57 tbp = (struct tbposition *) &tp->t_rocount; 58 tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0; 59 } 60 61 /* 62 * Break down... called when discipline changed or from device 63 * close routine. 64 */ 65 tbclose(tp) 66 register struct tty *tp; 67 { 68 register s; 69 70 s = spl5(); 71 tp->t_cp = 0; 72 tp->t_inbuf = 0; 73 tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */ 74 tp->t_canq.c_cc = 0; 75 tp->t_un.T_CTLQ.c_cc = 0; /* clear overlaid queue status */ 76 tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL; 77 tp->t_line = 0; /* paranoid: avoid races */ 78 splx(s); 79 } 80 81 /* 82 * Read from a tablet line. 83 * Characters have been buffered in a buffer and 84 * decoded. The coordinates are now sluffed back to the user. 85 */ 86 tbread(tp, uio) 87 register struct tty *tp; 88 struct uio *uio; 89 { 90 register int i; 91 register s; 92 struct tbposition tbposition; 93 94 if ((tp->t_state&TS_CARR_ON)==0) 95 return (EIO); 96 return (iomove(&tp->t_rocount, sizeof tbposition, UIO_READ, uio)); 97 } 98 99 /* 100 * Low level character input routine. 101 * Stuff the character in the buffer, and decode the it 102 * if all the chars are there. 103 * 104 * This routine could be expanded in-line in the receiver 105 * interrupt routine of the dh-11 to make it run as fast as possible. 106 */ 107 int LASTTABC; 108 109 tbinput(c, tp) 110 register int c; 111 register struct tty *tp; 112 { 113 114 if (tp->t_line == TABLDISC) { 115 if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { 116 tp->t_cp = (char *) &tp->t_un.T_CTLQ; 117 tp->t_inbuf = 0; 118 } 119 *tp->t_cp++ = c&0177; 120 if (++tp->t_inbuf == MTABCHAR) 121 tbdecode((char *) &tp->t_un.T_CTLQ, 122 (struct tbposition *) &tp->t_rocount); 123 } else if (tp->t_line == NTABLDISC) { 124 if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 125 tp->t_cp = (char *) &tp->t_un.T_CTLQ; 126 tp->t_inbuf = 0; 127 } 128 *tp->t_cp++ = c&0177; 129 if (++tp->t_inbuf == MNTABCHAR) 130 tbndecode((char *) &tp->t_un.T_CTLQ, 131 (struct tbposition *) &tp->t_rocount); 132 } 133 } 134 135 /* 136 * Decode tablet coordinates from ascii to binary. 137 * (gtco 6 character format) 138 */ 139 tbndecode(cp, tbposition) 140 register char *cp; 141 register struct tbposition *tbposition; 142 { 143 144 tbposition->status = *cp>>2; /* this needs to be decoded */ 145 tbposition->xpos = ((*cp++)&03)<<14; 146 tbposition->xpos |= (*cp++)<<7; 147 tbposition->xpos |= (*cp++); 148 tbposition->ypos = ((*cp++)&03)<<14; 149 tbposition->ypos |= (*cp++)<<7; 150 tbposition->ypos |= (*cp++); 151 tbposition->scount++; 152 } 153 154 /* 155 * Decode tablet coordinates from ascii to binary. 156 * (hitachi 5 character format) 157 */ 158 tbdecode(cp, tbposition) 159 register char *cp; 160 register struct tbposition *tbposition; 161 { 162 register int status; 163 register char byte; 164 165 byte = *cp++; 166 status = (byte&0100) ? 0100000 : 0; 167 byte &= ~0100; 168 if (byte > 036) 169 status |= 1<<((byte-040)/2); 170 tbposition->xpos = (*cp++)<<7; 171 tbposition->xpos |= (*cp++); 172 if (tbposition->xpos < 256) /* tablet wraps around at 256 */ 173 status &= 077777; /* make it out of proximity */ 174 tbposition->ypos = (*cp++)<<7; 175 tbposition->ypos |= (*cp++); 176 tbposition->status = status; 177 tbposition->scount++; 178 } 179 180 /* 181 * This routine is called whenever a ioctl is about to be performed 182 * and gets a chance to reject the ioctl. We reject all teletype 183 * oriented ioctl's except those which set the discipline, and 184 * those which get parameters (gtty and get special characters). 185 */ 186 /*ARGSUSED*/ 187 tbioctl(tp, cmd, data, flag) 188 struct tty *tp; 189 caddr_t data; 190 { 191 192 if ((cmd>>8) != 't') 193 return (cmd); 194 switch (cmd) { 195 196 case TIOCSETD: 197 case TIOCGETD: 198 case TIOCGETP: 199 case TIOCGETC: 200 return (cmd); 201 } 202 u.u_error = ENOTTY; 203 return (0); 204 } 205 #endif 206