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