]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty_tb.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
27 * Copyright (c) 1982, 1986, 1991, 1993
28 * The Regents of the University of California. All rights reserved.
30 * @(#)tty_tb.c 8.1 (Berkeley) 6/10/93
37 * Line discipline for RS232 tablets;
38 * supplies binary coordinate data.
40 #include <sys/param.h>
41 #include <sys/tablet.h>
48 * Tablet configuration table.
51 short tbc_recsize
; /* input record size in bytes */
52 short tbc_uiosize
; /* size of data record returned user */
53 int tbc_sync
; /* mask for finding sync byte/bit */
54 int (*tbc_decode
)();/* decoding routine */
55 char *tbc_run
; /* enter run mode sequence */
56 char *tbc_point
; /* enter point mode sequence */
57 char *tbc_stop
; /* stop sequence */
58 char *tbc_start
; /* start/restart sequence */
60 #define TBF_POL 0x1 /* polhemus hack */
61 #define TBF_INPROX 0x2 /* tablet has proximity info */
64 static int tbdecode(), gtcodecode(), poldecode();
65 static int tblresdecode(), tbhresdecode();
67 struct tbconf tbconf
[TBTYPE
] = {
69 { 5, sizeof (struct tbpos
), 0200, tbdecode
, "6", "4" },
70 { 5, sizeof (struct tbpos
), 0200, tbdecode
, "\1CN", "\1RT", "\2", "\4" },
71 { 8, sizeof (struct gtcopos
), 0200, gtcodecode
},
72 {17, sizeof (struct polpos
), 0200, poldecode
, 0, 0, "\21", "\5\22\2\23",
74 { 5, sizeof (struct tbpos
), 0100, tblresdecode
, "\1CN", "\1PT", "\2", "\4",
76 { 6, sizeof (struct tbpos
), 0200, tbhresdecode
, "\1CN", "\1PT", "\2", "\4",
78 { 5, sizeof (struct tbpos
), 0100, tblresdecode
, "\1CL\33", "\1PT\33", 0, 0},
79 { 6, sizeof (struct tbpos
), 0200, tbhresdecode
, "\1CL\33", "\1PT\33", 0, 0},
86 int tbflags
; /* mode & type bits */
87 #define TBMAXREC 17 /* max input record size */
88 char cbuf
[TBMAXREC
]; /* input buffer */
91 struct gtcopos gtcopos
;
93 } rets
; /* processed state */
98 * Open as tablet discipline; called on discipline change.
103 register struct tty
*tp
;
105 register struct tb
*tbp
;
107 if (tp
->t_line
== TABLDISC
)
110 for (tbp
= tb
; tbp
< &tb
[NTBS
]; tbp
++)
111 if (tbp
->tbflags
== 0)
113 if (tbp
>= &tb
[NTBS
])
115 tbp
->tbflags
= TBTIGER
|TBPOINT
; /* default */
116 tp
->t_cp
= tbp
->cbuf
;
118 bzero((caddr_t
)&tbp
->rets
, sizeof (tbp
->rets
));
119 tp
->T_LINEP
= (caddr_t
)tbp
;
120 tp
->t_flags
|= LITOUT
;
125 * Line discipline change or last device close.
128 register struct tty
*tp
;
131 int modebits
= TBPOINT
|TBSTOP
;
134 tbioctl(tp
, BIOSMODE
, &modebits
, 0);
136 tbioctl(tp
, BIOSMODE
, &modebits
, 0, current_proc());
139 ((struct tb
*)tp
->T_LINEP
)->tbflags
= 0;
142 tp
->t_rawq
.c_cc
= 0; /* clear queues -- paranoid */
144 tp
->t_line
= 0; /* paranoid: avoid races */
149 * Read from a tablet line.
150 * Characters have been buffered in a buffer and decoded.
153 register struct tty
*tp
;
156 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
157 register struct tbconf
*tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
160 if ((tp
->t_state
&TS_CARR_ON
) == 0)
162 ret
= uiomove(&tbp
->rets
, tc
->tbc_uiosize
, uio
);
163 if (tc
->tbc_flags
&TBF_POL
)
164 tbp
->rets
.polpos
.p_key
= ' ';
169 * Low level character input routine.
170 * Stuff the character in the buffer, and decode
171 * if all the chars are there.
173 * This routine could be expanded in-line in the receiver
174 * interrupt routine to make it run as fast as possible.
178 register struct tty
*tp
;
180 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
181 register struct tbconf
*tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
183 if (tc
->tbc_recsize
== 0 || tc
->tbc_decode
== 0) /* paranoid? */
186 * Locate sync bit/byte or reset input buffer.
188 if (c
&tc
->tbc_sync
|| tp
->t_inbuf
== tc
->tbc_recsize
) {
189 tp
->t_cp
= tbp
->cbuf
;
192 *tp
->t_cp
++ = c
&0177;
194 * Call decode routine only if a full record has been collected.
196 if (++tp
->t_inbuf
== tc
->tbc_recsize
)
197 (*tc
->tbc_decode
)(tc
, tbp
->cbuf
, &tbp
->rets
);
201 * Decode GTCO 8 byte format (high res, tilt, and pressure).
204 gtcodecode(tc
, cp
, tbpos
)
207 register struct gtcopos
*tbpos
;
210 tbpos
->pressure
= *cp
>> 2;
211 tbpos
->status
= (tbpos
->pressure
> 16) | TBINPROX
; /* half way down */
212 tbpos
->xpos
= (*cp
++ & 03) << 14;
213 tbpos
->xpos
|= *cp
++ << 7;
214 tbpos
->xpos
|= *cp
++;
215 tbpos
->ypos
= (*cp
++ & 03) << 14;
216 tbpos
->ypos
|= *cp
++ << 7;
217 tbpos
->ypos
|= *cp
++;
218 tbpos
->xtilt
= *cp
++;
219 tbpos
->ytilt
= *cp
++;
224 * Decode old Hitachi 5 byte format (low res).
227 tbdecode(tc
, cp
, tbpos
)
230 register struct tbpos
*tbpos
;
235 tbpos
->status
= (byte
&0100) ? TBINPROX
: 0;
238 tbpos
->status
|= 1 << ((byte
-040)/2);
239 tbpos
->xpos
= *cp
++ << 7;
240 tbpos
->xpos
|= *cp
++;
241 if (tbpos
->xpos
< 256) /* tablet wraps around at 256 */
242 tbpos
->status
&= ~TBINPROX
; /* make it out of proximity */
243 tbpos
->ypos
= *cp
++ << 7;
244 tbpos
->ypos
|= *cp
++;
249 * Decode new Hitach 5-byte format (low res).
252 tblresdecode(tc
, cp
, tbpos
)
255 register struct tbpos
*tbpos
;
258 *cp
&= ~0100; /* mask sync bit */
259 tbpos
->status
= (*cp
++ >> 2) | TBINPROX
;
260 if (tc
->tbc_flags
&TBF_INPROX
&& tbpos
->status
&020)
261 tbpos
->status
&= ~(020|TBINPROX
);
263 tbpos
->xpos
|= *cp
++ << 6;
265 tbpos
->ypos
|= *cp
++ << 6;
270 * Decode new Hitach 6-byte format (high res).
273 tbhresdecode(tc
, cp
, tbpos
)
276 register struct tbpos
*tbpos
;
281 tbpos
->xpos
= (byte
& 03) << 14;
282 tbpos
->xpos
|= *cp
++ << 7;
283 tbpos
->xpos
|= *cp
++;
284 tbpos
->ypos
= *cp
++ << 14;
285 tbpos
->ypos
|= *cp
++ << 7;
286 tbpos
->ypos
|= *cp
++;
287 tbpos
->status
= (byte
>> 2) | TBINPROX
;
288 if (tc
->tbc_flags
&TBF_INPROX
&& tbpos
->status
&020)
289 tbpos
->status
&= ~(020|TBINPROX
);
297 poldecode(tc
, cp
, polpos
)
300 register struct polpos
*polpos
;
303 polpos
->p_x
= cp
[4] | cp
[3]<<7 | (cp
[9] & 0x03) << 14;
304 polpos
->p_y
= cp
[6] | cp
[5]<<7 | (cp
[9] & 0x0c) << 12;
305 polpos
->p_z
= cp
[8] | cp
[7]<<7 | (cp
[9] & 0x30) << 10;
306 polpos
->p_azi
= cp
[11] | cp
[10]<<7 | (cp
[16] & 0x03) << 14;
307 polpos
->p_pit
= cp
[13] | cp
[12]<<7 | (cp
[16] & 0x0c) << 12;
308 polpos
->p_rol
= cp
[15] | cp
[14]<<7 | (cp
[16] & 0x30) << 10;
309 polpos
->p_stat
= cp
[1] | cp
[0]<<7;
311 polpos
->p_key
= cp
[2];
316 tbioctl(tp
, cmd
, data
, flag
)
320 tbtioctl(tp
, cmd
, data
, flag
, p
)
328 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
333 *(int *)data
= tbp
->tbflags
& TBMODE
;
337 if (tbconf
[*(int *)data
& TBTYPE
].tbc_recsize
== 0 ||
338 tbconf
[*(int *)data
& TBTYPE
].tbc_decode
== 0)
340 tbp
->tbflags
&= ~TBTYPE
;
341 tbp
->tbflags
|= *(int *)data
& TBTYPE
;
342 /* fall thru... to set mode bits */
345 register struct tbconf
*tc
;
347 tbp
->tbflags
&= ~TBMODE
;
348 tbp
->tbflags
|= *(int *)data
& TBMODE
;
349 tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
350 if (tbp
->tbflags
&TBSTOP
) {
352 ttyout(tc
->tbc_stop
, tp
);
353 } else if (tc
->tbc_start
)
354 ttyout(tc
->tbc_start
, tp
);
355 if (tbp
->tbflags
&TBPOINT
) {
357 ttyout(tc
->tbc_point
, tp
);
358 } else if (tc
->tbc_run
)
359 ttyout(tc
->tbc_run
, tp
);
365 *(int *)data
= tbp
->tbflags
& TBTYPE
;
372 return (-1); /* pass thru... */