xref: /csrg-svn/sys/news3400/hbdev/ms.c (revision 53895)
1*53895Smckusick /*
2*53895Smckusick  * Copyright (c) 1992 The Regents of the University of California.
3*53895Smckusick  * All rights reserved.
4*53895Smckusick  *
5*53895Smckusick  * This code is derived from software contributed to Berkeley by
6*53895Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7*53895Smckusick  *
8*53895Smckusick  * %sccs.include.redist.c%
9*53895Smckusick  *
10*53895Smckusick  * from: $Hdr: ms.c,v 4.300 91/06/09 06:22:04 root Rel41 $ SONY
11*53895Smckusick  *
12*53895Smckusick  *	@(#)ms.c	7.1 (Berkeley) 06/04/92
13*53895Smckusick  */
14*53895Smckusick 
15*53895Smckusick #include "../include/fix_machine_type.h"
16*53895Smckusick 
17*53895Smckusick #include    "ms.h"
18*53895Smckusick #if NMS > 0
19*53895Smckusick /*
20*53895Smckusick  * mouse
21*53895Smckusick  */
22*53895Smckusick 
23*53895Smckusick #include "types.h"
24*53895Smckusick #include "../include/cpu.h"
25*53895Smckusick #include "../include/pte.h"
26*53895Smckusick #include "param.h"
27*53895Smckusick #include "proc.h"
28*53895Smckusick #include "user.h"
29*53895Smckusick #include "buf.h"
30*53895Smckusick #include "malloc.h"
31*53895Smckusick #include "systm.h"
32*53895Smckusick #include "uio.h"
33*53895Smckusick #include "kernel.h"
34*53895Smckusick #include "file.h"
35*53895Smckusick 
36*53895Smckusick #include "../iop/mouse.h"
37*53895Smckusick #include "../iop/msreg.h"
38*53895Smckusick 
39*53895Smckusick #include "../sio/scc.h"
40*53895Smckusick #include "../hbdev/hbvar.h"
41*53895Smckusick 
42*53895Smckusick #ifndef mips
43*53895Smckusick #define volatile
44*53895Smckusick #endif /* mips */
45*53895Smckusick 
46*53895Smckusick struct ms_stat	 ms_stat[NMS];
47*53895Smckusick 
48*53895Smckusick int	msprobe(), msattach();
49*53895Smckusick 
50*53895Smckusick struct hb_device   *msinfo[NMS];
51*53895Smckusick struct hb_driver   msdriver = {
52*53895Smckusick 	msprobe, 0, msattach, 0, 0, "ms", msinfo, "mc", 0, 0
53*53895Smckusick };
54*53895Smckusick 
55*53895Smckusick #ifndef news700
56*53895Smckusick extern int tty00_is_console;
57*53895Smckusick #endif
58*53895Smckusick 
59*53895Smckusick #ifdef news3400
60*53895Smckusick #define	splms		spl4
61*53895Smckusick #else /* news3400 */
62*53895Smckusick #ifdef news700
63*53895Smckusick #define	splms		spl4
64*53895Smckusick #else /* news700 */
65*53895Smckusick #define	splms		spl5
66*53895Smckusick #endif /* news700 */
67*53895Smckusick #endif /* news3400 */
68*53895Smckusick 
69*53895Smckusick /*ARGSUSED*/
70*53895Smckusick msprobe(ii)
71*53895Smckusick 	struct hb_device *ii;
72*53895Smckusick {
73*53895Smckusick 	return(sizeof(struct ms_stat));
74*53895Smckusick }
75*53895Smckusick 
76*53895Smckusick /*ARGSUSED*/
77*53895Smckusick msattach(ii)
78*53895Smckusick 	struct hb_device *ii;
79*53895Smckusick {
80*53895Smckusick 
81*53895Smckusick }
82*53895Smckusick 
83*53895Smckusick /* queue structure operators */
84*53895Smckusick 
85*53895Smckusick msq_init(unit)
86*53895Smckusick 	int unit;
87*53895Smckusick {
88*53895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
89*53895Smckusick 
90*53895Smckusick 	q->mq_head = q->mq_tail = 0;
91*53895Smckusick }
92*53895Smckusick 
93*53895Smckusick int
94*53895Smckusick msq_stat(unit)
95*53895Smckusick 	int unit;
96*53895Smckusick {
97*53895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
98*53895Smckusick 
99*53895Smckusick 	while (q->mq_head != q->mq_tail) {
100*53895Smckusick 		if (!q->mq_queue[q->mq_head].mse_inval)
101*53895Smckusick 			break;
102*53895Smckusick 		q->mq_head = ++q->mq_head % MS_MAXREPORT;
103*53895Smckusick 	}
104*53895Smckusick 	return (q->mq_head != q->mq_tail);
105*53895Smckusick }
106*53895Smckusick 
107*53895Smckusick struct ms_event *
108*53895Smckusick msq_read(unit)
109*53895Smckusick 	int unit;
110*53895Smckusick {
111*53895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
112*53895Smckusick 	register volatile struct ms_event *data;
113*53895Smckusick 
114*53895Smckusick 	while (q->mq_head != q->mq_tail && q->mq_queue[q->mq_head].mse_inval)
115*53895Smckusick 		q->mq_head = ++q->mq_head % MS_MAXREPORT;
116*53895Smckusick 	if (q->mq_head == q->mq_tail) {
117*53895Smckusick 		data = NULL;
118*53895Smckusick 	} else {
119*53895Smckusick 		data = q->mq_queue + q->mq_head++;
120*53895Smckusick 		q->mq_head %= MS_MAXREPORT;
121*53895Smckusick 	}
122*53895Smckusick 	return (data);
123*53895Smckusick }
124*53895Smckusick 
125*53895Smckusick struct ms_event *
126*53895Smckusick msq_write(unit)
127*53895Smckusick 	int unit;
128*53895Smckusick {
129*53895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
130*53895Smckusick 	register volatile struct ms_event *data = q->mq_queue + q->mq_tail;
131*53895Smckusick 	register int new;
132*53895Smckusick 
133*53895Smckusick 	/* if queue is full, newest data is gone away */
134*53895Smckusick 	new = (q->mq_tail + 1) % MS_MAXREPORT;
135*53895Smckusick 	if (new != q->mq_head)
136*53895Smckusick 		q->mq_tail = new;
137*53895Smckusick 	return (data);
138*53895Smckusick }
139*53895Smckusick 
140*53895Smckusick msq_flush(unit, trig)
141*53895Smckusick 	int unit;
142*53895Smckusick 	char trig;
143*53895Smckusick {
144*53895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
145*53895Smckusick 	register int i;
146*53895Smckusick 
147*53895Smckusick 	i = q->mq_head;
148*53895Smckusick 	while (i != q->mq_tail) {
149*53895Smckusick 		if (q->mq_queue[i].mse_trig == trig)
150*53895Smckusick 			q->mq_queue[i].mse_inval = -1;
151*53895Smckusick 		i = ++i % MS_MAXREPORT;
152*53895Smckusick 	}
153*53895Smckusick }
154*53895Smckusick 
155*53895Smckusick /*
156*53895Smckusick  * Mouse open function.
157*53895Smckusick  */
158*53895Smckusick msopen(dev, flag)
159*53895Smckusick 	dev_t dev;
160*53895Smckusick 	int flag;
161*53895Smckusick {
162*53895Smckusick 	register int unit = MSUNIT(dev);
163*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
164*53895Smckusick 	register struct hb_device *ii = msinfo[unit];
165*53895Smckusick 	static struct ms_coord initxy = { 0, 0 };
166*53895Smckusick 
167*53895Smckusick 	/* check device */
168*53895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
169*53895Smckusick 		return(ENXIO);
170*53895Smckusick 
171*53895Smckusick 	/* check duplicable open */
172*53895Smckusick 	if (ms->mss_stat & MS_ACTIVE)
173*53895Smckusick 		return(EBUSY);
174*53895Smckusick 
175*53895Smckusick 	ms->mss_queue = malloc(sizeof(struct ms_queue), M_DEVBUF, M_WAITOK);
176*53895Smckusick 	if (ms->mss_queue == NULL)
177*53895Smckusick 		return (ENOMEM);
178*53895Smckusick 	msq_init(unit);
179*53895Smckusick 	ms->mss_mode = flag;
180*53895Smckusick 	ms->mss_stat = MS_ACTIVE;
181*53895Smckusick 
182*53895Smckusick 	/* communicate to IOP .. clear event mask, set initial xy. */
183*53895Smckusick 	ms->mss_eventmask = 0;
184*53895Smckusick 	ms->mss_data.md_sw = 0;			/* XXX */
185*53895Smckusick 	ms->mss_data.md_x = 0;
186*53895Smckusick 	ms->mss_data.md_y = 0;
187*53895Smckusick 	ms->mss_param.mp_delta = 5;
188*53895Smckusick 	ms->mss_param.mp_mag = 3;
189*53895Smckusick 	ms->mss_range.mr_min.mc_x = 0x80000000;
190*53895Smckusick 	ms->mss_range.mr_min.mc_y = 0x80000000;
191*53895Smckusick 	ms->mss_range.mr_max.mc_x = 0x7fffffff;
192*53895Smckusick 	ms->mss_range.mr_max.mc_y = 0x7fffffff;
193*53895Smckusick 
194*53895Smckusick 	if (curproc->p_pgrp->pg_id == 0) {
195*53895Smckusick 		if (ms->mss_pgrp == 0)
196*53895Smckusick 			ms->mss_pgrp = curproc->p_pid;
197*53895Smckusick 		curproc->p_pgrp->pg_id = ms->mss_pgrp;
198*53895Smckusick 	}
199*53895Smckusick #ifdef news700
200*53895Smckusick 	scc_open(SCC_MOUSE);
201*53895Smckusick #else
202*53895Smckusick 	if (tty00_is_console)
203*53895Smckusick 		kbm_open(SCC_KEYBOARD);
204*53895Smckusick 	kbm_open(SCC_MOUSE);
205*53895Smckusick #endif
206*53895Smckusick 
207*53895Smckusick 	return (0);
208*53895Smckusick }
209*53895Smckusick 
210*53895Smckusick /*
211*53895Smckusick  * Mouse close function.
212*53895Smckusick  */
213*53895Smckusick 
214*53895Smckusick /*ARGSUSED*/
215*53895Smckusick msclose(dev, flag)
216*53895Smckusick 	dev_t dev;
217*53895Smckusick 	int flag;
218*53895Smckusick {
219*53895Smckusick 	int unit = MSUNIT(dev);
220*53895Smckusick 	register struct ms_stat	*ms = &ms_stat[unit];
221*53895Smckusick 	register struct hb_device *ii = msinfo[unit];
222*53895Smckusick 
223*53895Smckusick 	/* check unit no. */
224*53895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
225*53895Smckusick 		return ENXIO;
226*53895Smckusick 
227*53895Smckusick 	/* check status */
228*53895Smckusick 	if (!(ms->mss_stat & MS_ACTIVE))
229*53895Smckusick 		return ENXIO;
230*53895Smckusick 
231*53895Smckusick 	/* clear eventmask and status */
232*53895Smckusick 	ms->mss_stat = 0;
233*53895Smckusick 	ms->mss_eventmask = 0;
234*53895Smckusick 
235*53895Smckusick 	free(ms->mss_queue, M_DEVBUF);
236*53895Smckusick 	ms->mss_pgrp = 0;
237*53895Smckusick #ifndef news700
238*53895Smckusick 	if (tty00_is_console)
239*53895Smckusick 		kbm_close(SCC_KEYBOARD);
240*53895Smckusick 	kbm_close(SCC_MOUSE);
241*53895Smckusick #endif /* news700 */
242*53895Smckusick 
243*53895Smckusick 	return (0);
244*53895Smckusick }
245*53895Smckusick 
246*53895Smckusick /*
247*53895Smckusick  * Mouse read function.
248*53895Smckusick  */
249*53895Smckusick 
250*53895Smckusick msread(dev, uio, flag)
251*53895Smckusick 	dev_t dev;
252*53895Smckusick 	struct uio *uio;
253*53895Smckusick 	int flag;
254*53895Smckusick {
255*53895Smckusick 	register int unit = MSUNIT(dev);
256*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
257*53895Smckusick 	register struct hb_device *ii = msinfo[unit];
258*53895Smckusick 	register volatile struct ms_event *data;
259*53895Smckusick 	struct ms_data xy;
260*53895Smckusick 	int s, error;
261*53895Smckusick 
262*53895Smckusick 	/* check argument */
263*53895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
264*53895Smckusick 		return ENXIO;
265*53895Smckusick 
266*53895Smckusick 	/* event mode -> waiting */
267*53895Smckusick 	if (ms->mss_eventmask & MS_EMEVENT) {
268*53895Smckusick 		s = splms();
269*53895Smckusick 		if (msq_stat(unit) == 0 && (ms->mss_stat & MS_NBIO)) {
270*53895Smckusick 			splx(s);
271*53895Smckusick 			return (EWOULDBLOCK);
272*53895Smckusick 		}
273*53895Smckusick 		while (msq_stat(unit) == 0) {
274*53895Smckusick 			ms->mss_stat |= MS_EVWAIT;
275*53895Smckusick 			sleep((caddr_t)&ms->mss_queue, MSPRI);
276*53895Smckusick 			ms->mss_stat &= ~MS_EVWAIT;
277*53895Smckusick 		}
278*53895Smckusick 		splx(s);
279*53895Smckusick 		if(MSOLDIF(dev)) {
280*53895Smckusick 			while ((data = msq_read(unit)) != NULL &&
281*53895Smckusick 			    uio->uio_resid >= sizeof(struct ms_data)) {
282*53895Smckusick 				error = uiomove((caddr_t)&data->mse_data,
283*53895Smckusick 						sizeof(struct ms_data), uio);
284*53895Smckusick 				if (error)
285*53895Smckusick 					return error;
286*53895Smckusick 			}
287*53895Smckusick 		} else {
288*53895Smckusick 			while ((data = msq_read(unit)) != NULL &&
289*53895Smckusick 			    uio->uio_resid >= sizeof(struct ms_event)) {
290*53895Smckusick 				error = uiomove((caddr_t)data,
291*53895Smckusick 						sizeof(struct ms_event), uio);
292*53895Smckusick 				if (error)
293*53895Smckusick 					return error;
294*53895Smckusick 			}
295*53895Smckusick 		}
296*53895Smckusick 	} else {
297*53895Smckusick 		while (uio->uio_resid >= sizeof(struct ms_data)) {
298*53895Smckusick 			s = splms();
299*53895Smckusick 			xy = ms->mss_data;
300*53895Smckusick 			splx(s);
301*53895Smckusick 			error = uiomove((caddr_t)&xy,
302*53895Smckusick 					sizeof(struct ms_data), uio);
303*53895Smckusick 			if (error)
304*53895Smckusick 				return error;
305*53895Smckusick 		}
306*53895Smckusick 	}
307*53895Smckusick 	return 0;
308*53895Smckusick }
309*53895Smckusick 
310*53895Smckusick /*
311*53895Smckusick  * Mouse write function
312*53895Smckusick  */
313*53895Smckusick 
314*53895Smckusick mswrite(dev, uio, flag)
315*53895Smckusick 	dev_t dev;
316*53895Smckusick 	struct uio *uio;
317*53895Smckusick 	int flag;
318*53895Smckusick {
319*53895Smckusick 	register int unit = MSUNIT(dev);
320*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
321*53895Smckusick 	register struct hb_device *ii = msinfo[unit];
322*53895Smckusick 	struct ms_coord xy;
323*53895Smckusick 	register int s, error;
324*53895Smckusick 
325*53895Smckusick 	/* check argument */
326*53895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
327*53895Smckusick 		return ENXIO;
328*53895Smckusick 
329*53895Smckusick 	while (uio->uio_resid >= sizeof(struct ms_coord)) {
330*53895Smckusick 		error = uiomove((caddr_t)&xy, sizeof(xy), uio);
331*53895Smckusick 		if (error)
332*53895Smckusick 			return error;
333*53895Smckusick 		s = splms();
334*53895Smckusick 		ms->mss_data.md_x = xy.mc_x;
335*53895Smckusick 		ms->mss_data.md_y = xy.mc_y;
336*53895Smckusick 		splx(s);
337*53895Smckusick 		lock_bitmap();
338*53895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);
339*53895Smckusick 		unlock_bitmap();
340*53895Smckusick 	}
341*53895Smckusick 	return 0;
342*53895Smckusick }
343*53895Smckusick 
344*53895Smckusick 
345*53895Smckusick /*
346*53895Smckusick  * Mouse I/O control function
347*53895Smckusick  */
348*53895Smckusick 
349*53895Smckusick /*ARGSUSED*/
350*53895Smckusick msioctl(dev, cmd, data, flag)
351*53895Smckusick 	dev_t dev;
352*53895Smckusick 	int cmd;
353*53895Smckusick 	caddr_t data;
354*53895Smckusick 	int flag;
355*53895Smckusick {
356*53895Smckusick 	register int unit = MSUNIT(dev);
357*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
358*53895Smckusick 	register struct hb_device *ii = msinfo[unit];
359*53895Smckusick 	register int s;
360*53895Smckusick 
361*53895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
362*53895Smckusick 		return EIO;
363*53895Smckusick 
364*53895Smckusick 	s = splms();
365*53895Smckusick 
366*53895Smckusick 	switch (cmd) {
367*53895Smckusick 	case MSIOCGETEM:
368*53895Smckusick 		(*(int*)data) = ms->mss_eventmask;
369*53895Smckusick 		break;
370*53895Smckusick 	case MSIOCSETEM:
371*53895Smckusick 		ms->mss_eventmask = *(int *)data;
372*53895Smckusick 		break;
373*53895Smckusick 	case MSIOCSETXY:
374*53895Smckusick 		ms->mss_data.md_x = ((struct ms_coord*)data)->mc_x;
375*53895Smckusick 		ms->mss_data.md_y = ((struct ms_coord*)data)->mc_y;
376*53895Smckusick 		lock_bitmap();
377*53895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);
378*53895Smckusick 		unlock_bitmap();
379*53895Smckusick 		msq_flush(unit, MSE_MOTION);
380*53895Smckusick 		break;
381*53895Smckusick 	case MSIOCFLUSH:
382*53895Smckusick 		msq_init(unit);
383*53895Smckusick 		break;
384*53895Smckusick 	case MSIOCSETPARAM:
385*53895Smckusick 		ms->mss_param = *(struct ms_param*)data;
386*53895Smckusick 		break;
387*53895Smckusick 	case MSIOCSETRANGE:
388*53895Smckusick 		ms->mss_range = *(struct ms_range*)data;
389*53895Smckusick 		break;
390*53895Smckusick 	case FIONBIO:
391*53895Smckusick 		if (*(int *)data)
392*53895Smckusick 			ms->mss_stat |= MS_NBIO;
393*53895Smckusick 		else
394*53895Smckusick 			ms->mss_stat &= ~MS_NBIO;
395*53895Smckusick 		break;
396*53895Smckusick 	case FIOASYNC:
397*53895Smckusick 		if (*(int *)data)
398*53895Smckusick 			ms->mss_stat |= MS_ASYNC;
399*53895Smckusick 		else
400*53895Smckusick 			ms->mss_stat &= ~MS_ASYNC;
401*53895Smckusick 		break;
402*53895Smckusick 	case TIOCSPGRP:
403*53895Smckusick 		ms->mss_pgrp = *(int *)data;
404*53895Smckusick 		break;
405*53895Smckusick 	case TIOCGPGRP:
406*53895Smckusick 		*(int *)data = ms->mss_pgrp;
407*53895Smckusick 		break;
408*53895Smckusick 	default:
409*53895Smckusick 		splx(s);
410*53895Smckusick 		return ENOTTY;
411*53895Smckusick 	}
412*53895Smckusick 	splx(s);
413*53895Smckusick 	return 0;
414*53895Smckusick }
415*53895Smckusick 
416*53895Smckusick msselect(dev, flag)
417*53895Smckusick 	dev_t dev;
418*53895Smckusick 	int flag;
419*53895Smckusick {
420*53895Smckusick 	register int unit = MSUNIT(dev);
421*53895Smckusick 	register struct ms_stat *ms;
422*53895Smckusick 	int s;
423*53895Smckusick 
424*53895Smckusick 	if (unit < 0 || unit >= NMS)
425*53895Smckusick 		return(0);
426*53895Smckusick 
427*53895Smckusick 	s = splms();
428*53895Smckusick 	ms = &ms_stat[unit];
429*53895Smckusick 
430*53895Smckusick 	switch(flag) {
431*53895Smckusick 	case FREAD:
432*53895Smckusick 		if (!(ms->mss_eventmask & MS_EMEVENT))
433*53895Smckusick 			goto win;
434*53895Smckusick 		if(msq_stat(unit))
435*53895Smckusick 			goto win;
436*53895Smckusick 
437*53895Smckusick 		if (ms->mss_rsel && ms->mss_rsel->p_wchan == (caddr_t)&selwait)
438*53895Smckusick 			ms->mss_stat |= MS_RCOLL;
439*53895Smckusick 		else
440*53895Smckusick 			ms->mss_rsel = curproc;
441*53895Smckusick 		break;
442*53895Smckusick 
443*53895Smckusick 	case FWRITE:
444*53895Smckusick 		goto win;
445*53895Smckusick 	}
446*53895Smckusick 	splx(s);
447*53895Smckusick 	return(0);
448*53895Smckusick win:
449*53895Smckusick 	splx(s);
450*53895Smckusick 	return(1);
451*53895Smckusick }
452*53895Smckusick 
453*53895Smckusick msselwakeup(ms)
454*53895Smckusick 	register struct ms_stat *ms;
455*53895Smckusick {
456*53895Smckusick 	if (ms->mss_rsel) {
457*53895Smckusick 		selwakeup(ms->mss_rsel, ms->mss_stat&MS_RCOLL);
458*53895Smckusick 		ms->mss_stat &= ~MS_RCOLL;
459*53895Smckusick 		ms->mss_rsel = 0;
460*53895Smckusick 	}
461*53895Smckusick 	if (ms->mss_stat & MS_ASYNC)
462*53895Smckusick 		gsignal(ms->mss_pgrp, SIGIO);
463*53895Smckusick }
464*53895Smckusick 
465*53895Smckusick mssint()
466*53895Smckusick {
467*53895Smckusick 	printf("mssint\n");
468*53895Smckusick }
469*53895Smckusick 
470*53895Smckusick msputevent(unit, trig, dir, code)
471*53895Smckusick 	int unit, trig, dir, code;
472*53895Smckusick {
473*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
474*53895Smckusick 	register volatile struct ms_event *me;
475*53895Smckusick 	register int s;
476*53895Smckusick 
477*53895Smckusick 	me = msq_write(unit);
478*53895Smckusick 
479*53895Smckusick 	s = splclock();
480*53895Smckusick 	me->mse_time = time;
481*53895Smckusick 	me->mse_inval = 0;
482*53895Smckusick 	splx(s);
483*53895Smckusick 
484*53895Smckusick 	me->mse_trig = trig;
485*53895Smckusick 	me->mse_dir = dir;
486*53895Smckusick 	me->mse_code = code;
487*53895Smckusick 	me->mse_data = ms->mss_data;
488*53895Smckusick 
489*53895Smckusick 	if (ms->mss_stat & MS_EVWAIT)
490*53895Smckusick 		wakeup((caddr_t)&ms->mss_queue);
491*53895Smckusick 
492*53895Smckusick 	msselwakeup(ms);
493*53895Smckusick 
494*53895Smckusick 	return (0);
495*53895Smckusick }
496*53895Smckusick 
497*53895Smckusick /*
498*53895Smckusick  * for keyboard
499*53895Smckusick  */
500*53895Smckusick mskeytrigger(unit, up, keycode)
501*53895Smckusick 	int unit;
502*53895Smckusick 	int up;
503*53895Smckusick 	int keycode;
504*53895Smckusick {
505*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
506*53895Smckusick 
507*53895Smckusick 	if((ms->mss_eventmask & MS_EMEVENT) == 0)
508*53895Smckusick 		return 0;
509*53895Smckusick 	if((ms->mss_eventmask & MS_EMKEY) == 0)
510*53895Smckusick 		return 0;
511*53895Smckusick 
512*53895Smckusick 	(void) msputevent(unit, MSE_KEY, up ? MSE_UP : MSE_DOWN, keycode);
513*53895Smckusick 
514*53895Smckusick 	return 1;
515*53895Smckusick }
516*53895Smckusick 
517*53895Smckusick /*
518*53895Smckusick  * msconv - convert mouse hardware reports(3 bytes) into internal mouse data
519*53895Smckusick  *		it leaves the old mouse data in ms_data_old and
520*53895Smckusick  *		new mouse data in ms_data.
521*53895Smckusick  */
522*53895Smckusick msconv(unit, rep)
523*53895Smckusick 	int unit;
524*53895Smckusick 	register char rep[];
525*53895Smckusick {
526*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
527*53895Smckusick 	register int s_byte;
528*53895Smckusick 	register int sw = 0;
529*53895Smckusick 	register int dx, dy;
530*53895Smckusick 	int adx, ady;
531*53895Smckusick 
532*53895Smckusick 	ms->mss_data_old = ms->mss_data;
533*53895Smckusick 
534*53895Smckusick 	/* switch status */
535*53895Smckusick 	s_byte = rep[MS_S_BYTE];
536*53895Smckusick 	if (s_byte & MS_S_SW1)
537*53895Smckusick 		sw |= MS_BUTNL;
538*53895Smckusick 	if (s_byte & MS_S_SW2)
539*53895Smckusick 		sw |= MS_BUTNR;
540*53895Smckusick 	if (s_byte & MS_S_SW3)
541*53895Smckusick 		sw |= MS_BUTNM;
542*53895Smckusick 	ms->mss_data.md_sw = sw;
543*53895Smckusick 
544*53895Smckusick 	/* delta x */
545*53895Smckusick 	dx = rep[MS_X_BYTE] & MS_X_X06;
546*53895Smckusick 	if (s_byte & MS_S_X7)
547*53895Smckusick 		dx = (~0&~MS_X_X06)|dx;
548*53895Smckusick 
549*53895Smckusick 	dy = rep[MS_Y_BYTE] & MS_Y_Y06;
550*53895Smckusick 	if (s_byte & MS_S_Y7)
551*53895Smckusick 		dy = (~0&~MS_Y_Y06)|dy;
552*53895Smckusick 
553*53895Smckusick #define ABS(x)	((x)>=0 ? (x) : -(x))
554*53895Smckusick 	adx = ABS(dx);
555*53895Smckusick 	ady = ABS(dy);
556*53895Smckusick #undef ABS
557*53895Smckusick 
558*53895Smckusick 	if (adx > ms->mss_param.mp_delta) {
559*53895Smckusick 		adx = ms->mss_param.mp_delta +
560*53895Smckusick 		      (adx - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;
561*53895Smckusick 		if (dx < 0)
562*53895Smckusick 			dx = -adx;
563*53895Smckusick 		else
564*53895Smckusick 			dx = adx;
565*53895Smckusick 	}
566*53895Smckusick 	if (ady > ms->mss_param.mp_delta) {
567*53895Smckusick 		ady = ms->mss_param.mp_delta +
568*53895Smckusick 		      (ady - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;
569*53895Smckusick 		if (dy < 0)
570*53895Smckusick 			dy = -ady;
571*53895Smckusick 		else
572*53895Smckusick 			dy = ady;
573*53895Smckusick 	}
574*53895Smckusick 	ms->mss_data.md_x += dx;
575*53895Smckusick 	ms->mss_data.md_y += dy;
576*53895Smckusick 
577*53895Smckusick 	if (dx > 0)
578*53895Smckusick 		ms->mss_data.md_x = MIN(ms->mss_data.md_x,
579*53895Smckusick 					ms->mss_range.mr_max.mc_x);
580*53895Smckusick 	else
581*53895Smckusick 		ms->mss_data.md_x = MAX(ms->mss_data.md_x,
582*53895Smckusick 					ms->mss_range.mr_min.mc_x);
583*53895Smckusick 	if (dy > 0)
584*53895Smckusick 		ms->mss_data.md_y = MIN(ms->mss_data.md_y,
585*53895Smckusick 					ms->mss_range.mr_max.mc_y);
586*53895Smckusick 	else
587*53895Smckusick 		ms->mss_data.md_y = MAX(ms->mss_data.md_y,
588*53895Smckusick 					ms->mss_range.mr_min.mc_y);
589*53895Smckusick 
590*53895Smckusick 	if (dx != 0 || dy != 0)
591*53895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 0);
592*53895Smckusick }
593*53895Smckusick 
594*53895Smckusick mscheckevent(unit)
595*53895Smckusick 	int unit;
596*53895Smckusick {
597*53895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
598*53895Smckusick 	register int i;
599*53895Smckusick 	register int changebits;
600*53895Smckusick 	register int dir;
601*53895Smckusick 
602*53895Smckusick 	if ((ms->mss_eventmask & MS_EMEVENT) == 0)
603*53895Smckusick 		return;
604*53895Smckusick 
605*53895Smckusick 	if (ms->mss_data_old.md_sw != ms->mss_data.md_sw) {
606*53895Smckusick 
607*53895Smckusick 		changebits = (ms->mss_data_old.md_sw ^ ms->mss_data.md_sw);
608*53895Smckusick 		changebits &= ms->mss_eventmask;
609*53895Smckusick 
610*53895Smckusick 		for(i = 0; i < 3; i++) {
611*53895Smckusick 			if(changebits & (1 << i)) {
612*53895Smckusick 				if((1 << i) & ms->mss_data.md_sw)
613*53895Smckusick 					dir = MSE_DOWN;
614*53895Smckusick 				else
615*53895Smckusick 					dir = MSE_UP;
616*53895Smckusick 				msputevent(unit, MSE_BUTTON, dir, i);
617*53895Smckusick 			}
618*53895Smckusick 		}
619*53895Smckusick 	}
620*53895Smckusick 
621*53895Smckusick 	if ((ms->mss_eventmask & MS_EMMOTION) &&
622*53895Smckusick 	    (ms->mss_data_old.md_x != ms->mss_data.md_x ||
623*53895Smckusick 	     ms->mss_data_old.md_y != ms->mss_data.md_y)) {
624*53895Smckusick 		msputevent(unit, MSE_MOTION, 0, 0);
625*53895Smckusick 		return;
626*53895Smckusick 	}
627*53895Smckusick }
628*53895Smckusick 
629*53895Smckusick /*
630*53895Smckusick  * _ms_helper - open the mouse line and read mouse data and
631*53895Smckusick  *		convert them into mouse data (events)
632*53895Smckusick  */
633*53895Smckusick _ms_helper(unit)
634*53895Smckusick 	int unit;
635*53895Smckusick {
636*53895Smckusick 	register int c;
637*53895Smckusick 	static int counter = 0;
638*53895Smckusick 	static char buf[MS_DB_SIZE];
639*53895Smckusick 
640*53895Smckusick #ifdef notyet /* KU:XXX */
641*53895Smckusick 	intrcnt[INTR_MOUSE]++;
642*53895Smckusick #endif
643*53895Smckusick 
644*53895Smckusick #if NBM > 0
645*53895Smckusick 	rst_dimmer_cnt();
646*53895Smckusick #endif
647*53895Smckusick 
648*53895Smckusick 	while ((c = xgetc(SCC_MOUSE)) >= 0) {
649*53895Smckusick 		if (c & MS_S_MARK)
650*53895Smckusick 			counter = 0;
651*53895Smckusick 		buf[counter] = c;
652*53895Smckusick 		if (++counter == 3) {
653*53895Smckusick 			msconv(unit, buf);
654*53895Smckusick 			mscheckevent(unit);
655*53895Smckusick 			counter = 0;
656*53895Smckusick 		}
657*53895Smckusick 	}
658*53895Smckusick }
659*53895Smckusick #endif /* NMS > 0 */
660