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