xref: /csrg-svn/sys/news3400/hbdev/ms.c (revision 55764)
153895Smckusick /*
253895Smckusick  * Copyright (c) 1992 The Regents of the University of California.
353895Smckusick  * All rights reserved.
453895Smckusick  *
553895Smckusick  * This code is derived from software contributed to Berkeley by
653895Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753895Smckusick  *
853895Smckusick  * %sccs.include.redist.c%
953895Smckusick  *
1053895Smckusick  * from: $Hdr: ms.c,v 4.300 91/06/09 06:22:04 root Rel41 $ SONY
1153895Smckusick  *
12*55764Sbostic  *	@(#)ms.c	7.2 (Berkeley) 07/28/92
1353895Smckusick  */
1453895Smckusick 
1553895Smckusick #include "../include/fix_machine_type.h"
1653895Smckusick 
1753895Smckusick #include    "ms.h"
1853895Smckusick #if NMS > 0
1953895Smckusick /*
2053895Smckusick  * mouse
2153895Smckusick  */
2253895Smckusick 
2353895Smckusick #include "types.h"
2453895Smckusick #include "../include/cpu.h"
2553895Smckusick #include "../include/pte.h"
2653895Smckusick #include "param.h"
2753895Smckusick #include "proc.h"
2853895Smckusick #include "user.h"
2953895Smckusick #include "buf.h"
3053895Smckusick #include "malloc.h"
3153895Smckusick #include "systm.h"
3253895Smckusick #include "uio.h"
3353895Smckusick #include "kernel.h"
3453895Smckusick #include "file.h"
3553895Smckusick 
3653895Smckusick #include "../iop/mouse.h"
3753895Smckusick #include "../iop/msreg.h"
3853895Smckusick 
3953895Smckusick #include "../sio/scc.h"
4053895Smckusick #include "../hbdev/hbvar.h"
4153895Smckusick 
4253895Smckusick #ifndef mips
4353895Smckusick #define volatile
4453895Smckusick #endif /* mips */
4553895Smckusick 
4653895Smckusick struct ms_stat	 ms_stat[NMS];
4753895Smckusick 
4853895Smckusick int	msprobe(), msattach();
4953895Smckusick 
5053895Smckusick struct hb_device   *msinfo[NMS];
5153895Smckusick struct hb_driver   msdriver = {
5253895Smckusick 	msprobe, 0, msattach, 0, 0, "ms", msinfo, "mc", 0, 0
5353895Smckusick };
5453895Smckusick 
5553895Smckusick #ifndef news700
5653895Smckusick extern int tty00_is_console;
5753895Smckusick #endif
5853895Smckusick 
5953895Smckusick #ifdef news3400
6053895Smckusick #define	splms		spl4
6153895Smckusick #else /* news3400 */
6253895Smckusick #ifdef news700
6353895Smckusick #define	splms		spl4
6453895Smckusick #else /* news700 */
6553895Smckusick #define	splms		spl5
6653895Smckusick #endif /* news700 */
6753895Smckusick #endif /* news3400 */
6853895Smckusick 
6953895Smckusick /*ARGSUSED*/
7053895Smckusick msprobe(ii)
7153895Smckusick 	struct hb_device *ii;
7253895Smckusick {
7353895Smckusick 	return(sizeof(struct ms_stat));
7453895Smckusick }
7553895Smckusick 
7653895Smckusick /*ARGSUSED*/
7753895Smckusick msattach(ii)
7853895Smckusick 	struct hb_device *ii;
7953895Smckusick {
8053895Smckusick 
8153895Smckusick }
8253895Smckusick 
8353895Smckusick /* queue structure operators */
8453895Smckusick 
8553895Smckusick msq_init(unit)
8653895Smckusick 	int unit;
8753895Smckusick {
8853895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
8953895Smckusick 
9053895Smckusick 	q->mq_head = q->mq_tail = 0;
9153895Smckusick }
9253895Smckusick 
9353895Smckusick int
9453895Smckusick msq_stat(unit)
9553895Smckusick 	int unit;
9653895Smckusick {
9753895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
9853895Smckusick 
9953895Smckusick 	while (q->mq_head != q->mq_tail) {
10053895Smckusick 		if (!q->mq_queue[q->mq_head].mse_inval)
10153895Smckusick 			break;
10253895Smckusick 		q->mq_head = ++q->mq_head % MS_MAXREPORT;
10353895Smckusick 	}
10453895Smckusick 	return (q->mq_head != q->mq_tail);
10553895Smckusick }
10653895Smckusick 
10753895Smckusick struct ms_event *
10853895Smckusick msq_read(unit)
10953895Smckusick 	int unit;
11053895Smckusick {
11153895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
11253895Smckusick 	register volatile struct ms_event *data;
11353895Smckusick 
11453895Smckusick 	while (q->mq_head != q->mq_tail && q->mq_queue[q->mq_head].mse_inval)
11553895Smckusick 		q->mq_head = ++q->mq_head % MS_MAXREPORT;
11653895Smckusick 	if (q->mq_head == q->mq_tail) {
11753895Smckusick 		data = NULL;
11853895Smckusick 	} else {
11953895Smckusick 		data = q->mq_queue + q->mq_head++;
12053895Smckusick 		q->mq_head %= MS_MAXREPORT;
12153895Smckusick 	}
12253895Smckusick 	return (data);
12353895Smckusick }
12453895Smckusick 
12553895Smckusick struct ms_event *
12653895Smckusick msq_write(unit)
12753895Smckusick 	int unit;
12853895Smckusick {
12953895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
13053895Smckusick 	register volatile struct ms_event *data = q->mq_queue + q->mq_tail;
13153895Smckusick 	register int new;
13253895Smckusick 
13353895Smckusick 	/* if queue is full, newest data is gone away */
13453895Smckusick 	new = (q->mq_tail + 1) % MS_MAXREPORT;
13553895Smckusick 	if (new != q->mq_head)
13653895Smckusick 		q->mq_tail = new;
13753895Smckusick 	return (data);
13853895Smckusick }
13953895Smckusick 
14053895Smckusick msq_flush(unit, trig)
14153895Smckusick 	int unit;
14253895Smckusick 	char trig;
14353895Smckusick {
14453895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
14553895Smckusick 	register int i;
14653895Smckusick 
14753895Smckusick 	i = q->mq_head;
14853895Smckusick 	while (i != q->mq_tail) {
14953895Smckusick 		if (q->mq_queue[i].mse_trig == trig)
15053895Smckusick 			q->mq_queue[i].mse_inval = -1;
15153895Smckusick 		i = ++i % MS_MAXREPORT;
15253895Smckusick 	}
15353895Smckusick }
15453895Smckusick 
15553895Smckusick /*
15653895Smckusick  * Mouse open function.
15753895Smckusick  */
15853895Smckusick msopen(dev, flag)
15953895Smckusick 	dev_t dev;
16053895Smckusick 	int flag;
16153895Smckusick {
16253895Smckusick 	register int unit = MSUNIT(dev);
16353895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
16453895Smckusick 	register struct hb_device *ii = msinfo[unit];
16553895Smckusick 	static struct ms_coord initxy = { 0, 0 };
16653895Smckusick 
16753895Smckusick 	/* check device */
16853895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
16953895Smckusick 		return(ENXIO);
17053895Smckusick 
17153895Smckusick 	/* check duplicable open */
17253895Smckusick 	if (ms->mss_stat & MS_ACTIVE)
17353895Smckusick 		return(EBUSY);
17453895Smckusick 
17553895Smckusick 	ms->mss_queue = malloc(sizeof(struct ms_queue), M_DEVBUF, M_WAITOK);
17653895Smckusick 	if (ms->mss_queue == NULL)
17753895Smckusick 		return (ENOMEM);
17853895Smckusick 	msq_init(unit);
17953895Smckusick 	ms->mss_mode = flag;
18053895Smckusick 	ms->mss_stat = MS_ACTIVE;
18153895Smckusick 
18253895Smckusick 	/* communicate to IOP .. clear event mask, set initial xy. */
18353895Smckusick 	ms->mss_eventmask = 0;
18453895Smckusick 	ms->mss_data.md_sw = 0;			/* XXX */
18553895Smckusick 	ms->mss_data.md_x = 0;
18653895Smckusick 	ms->mss_data.md_y = 0;
18753895Smckusick 	ms->mss_param.mp_delta = 5;
18853895Smckusick 	ms->mss_param.mp_mag = 3;
18953895Smckusick 	ms->mss_range.mr_min.mc_x = 0x80000000;
19053895Smckusick 	ms->mss_range.mr_min.mc_y = 0x80000000;
19153895Smckusick 	ms->mss_range.mr_max.mc_x = 0x7fffffff;
19253895Smckusick 	ms->mss_range.mr_max.mc_y = 0x7fffffff;
19353895Smckusick 
19453895Smckusick 	if (curproc->p_pgrp->pg_id == 0) {
19553895Smckusick 		if (ms->mss_pgrp == 0)
19653895Smckusick 			ms->mss_pgrp = curproc->p_pid;
19753895Smckusick 		curproc->p_pgrp->pg_id = ms->mss_pgrp;
19853895Smckusick 	}
19953895Smckusick #ifdef news700
20053895Smckusick 	scc_open(SCC_MOUSE);
20153895Smckusick #else
20253895Smckusick 	if (tty00_is_console)
20353895Smckusick 		kbm_open(SCC_KEYBOARD);
20453895Smckusick 	kbm_open(SCC_MOUSE);
20553895Smckusick #endif
20653895Smckusick 
20753895Smckusick 	return (0);
20853895Smckusick }
20953895Smckusick 
21053895Smckusick /*
21153895Smckusick  * Mouse close function.
21253895Smckusick  */
21353895Smckusick 
21453895Smckusick /*ARGSUSED*/
21553895Smckusick msclose(dev, flag)
21653895Smckusick 	dev_t dev;
21753895Smckusick 	int flag;
21853895Smckusick {
21953895Smckusick 	int unit = MSUNIT(dev);
22053895Smckusick 	register struct ms_stat	*ms = &ms_stat[unit];
22153895Smckusick 	register struct hb_device *ii = msinfo[unit];
22253895Smckusick 
22353895Smckusick 	/* check unit no. */
22453895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
22553895Smckusick 		return ENXIO;
22653895Smckusick 
22753895Smckusick 	/* check status */
22853895Smckusick 	if (!(ms->mss_stat & MS_ACTIVE))
22953895Smckusick 		return ENXIO;
23053895Smckusick 
23153895Smckusick 	/* clear eventmask and status */
23253895Smckusick 	ms->mss_stat = 0;
23353895Smckusick 	ms->mss_eventmask = 0;
23453895Smckusick 
23553895Smckusick 	free(ms->mss_queue, M_DEVBUF);
23653895Smckusick 	ms->mss_pgrp = 0;
23753895Smckusick #ifndef news700
23853895Smckusick 	if (tty00_is_console)
23953895Smckusick 		kbm_close(SCC_KEYBOARD);
24053895Smckusick 	kbm_close(SCC_MOUSE);
24153895Smckusick #endif /* news700 */
24253895Smckusick 
24353895Smckusick 	return (0);
24453895Smckusick }
24553895Smckusick 
24653895Smckusick /*
24753895Smckusick  * Mouse read function.
24853895Smckusick  */
24953895Smckusick 
25053895Smckusick msread(dev, uio, flag)
25153895Smckusick 	dev_t dev;
25253895Smckusick 	struct uio *uio;
25353895Smckusick 	int flag;
25453895Smckusick {
25553895Smckusick 	register int unit = MSUNIT(dev);
25653895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
25753895Smckusick 	register struct hb_device *ii = msinfo[unit];
25853895Smckusick 	register volatile struct ms_event *data;
25953895Smckusick 	struct ms_data xy;
26053895Smckusick 	int s, error;
26153895Smckusick 
26253895Smckusick 	/* check argument */
26353895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
26453895Smckusick 		return ENXIO;
26553895Smckusick 
26653895Smckusick 	/* event mode -> waiting */
26753895Smckusick 	if (ms->mss_eventmask & MS_EMEVENT) {
26853895Smckusick 		s = splms();
26953895Smckusick 		if (msq_stat(unit) == 0 && (ms->mss_stat & MS_NBIO)) {
27053895Smckusick 			splx(s);
27153895Smckusick 			return (EWOULDBLOCK);
27253895Smckusick 		}
27353895Smckusick 		while (msq_stat(unit) == 0) {
27453895Smckusick 			ms->mss_stat |= MS_EVWAIT;
27553895Smckusick 			sleep((caddr_t)&ms->mss_queue, MSPRI);
27653895Smckusick 			ms->mss_stat &= ~MS_EVWAIT;
27753895Smckusick 		}
27853895Smckusick 		splx(s);
27953895Smckusick 		if(MSOLDIF(dev)) {
28053895Smckusick 			while ((data = msq_read(unit)) != NULL &&
28153895Smckusick 			    uio->uio_resid >= sizeof(struct ms_data)) {
28253895Smckusick 				error = uiomove((caddr_t)&data->mse_data,
28353895Smckusick 						sizeof(struct ms_data), uio);
28453895Smckusick 				if (error)
28553895Smckusick 					return error;
28653895Smckusick 			}
28753895Smckusick 		} else {
28853895Smckusick 			while ((data = msq_read(unit)) != NULL &&
28953895Smckusick 			    uio->uio_resid >= sizeof(struct ms_event)) {
29053895Smckusick 				error = uiomove((caddr_t)data,
29153895Smckusick 						sizeof(struct ms_event), uio);
29253895Smckusick 				if (error)
29353895Smckusick 					return error;
29453895Smckusick 			}
29553895Smckusick 		}
29653895Smckusick 	} else {
29753895Smckusick 		while (uio->uio_resid >= sizeof(struct ms_data)) {
29853895Smckusick 			s = splms();
29953895Smckusick 			xy = ms->mss_data;
30053895Smckusick 			splx(s);
30153895Smckusick 			error = uiomove((caddr_t)&xy,
30253895Smckusick 					sizeof(struct ms_data), uio);
30353895Smckusick 			if (error)
30453895Smckusick 				return error;
30553895Smckusick 		}
30653895Smckusick 	}
30753895Smckusick 	return 0;
30853895Smckusick }
30953895Smckusick 
31053895Smckusick /*
31153895Smckusick  * Mouse write function
31253895Smckusick  */
31353895Smckusick 
31453895Smckusick mswrite(dev, uio, flag)
31553895Smckusick 	dev_t dev;
31653895Smckusick 	struct uio *uio;
31753895Smckusick 	int flag;
31853895Smckusick {
31953895Smckusick 	register int unit = MSUNIT(dev);
32053895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
32153895Smckusick 	register struct hb_device *ii = msinfo[unit];
32253895Smckusick 	struct ms_coord xy;
32353895Smckusick 	register int s, error;
32453895Smckusick 
32553895Smckusick 	/* check argument */
32653895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
32753895Smckusick 		return ENXIO;
32853895Smckusick 
32953895Smckusick 	while (uio->uio_resid >= sizeof(struct ms_coord)) {
33053895Smckusick 		error = uiomove((caddr_t)&xy, sizeof(xy), uio);
33153895Smckusick 		if (error)
33253895Smckusick 			return error;
33353895Smckusick 		s = splms();
33453895Smckusick 		ms->mss_data.md_x = xy.mc_x;
33553895Smckusick 		ms->mss_data.md_y = xy.mc_y;
33653895Smckusick 		splx(s);
33753895Smckusick 		lock_bitmap();
33853895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);
33953895Smckusick 		unlock_bitmap();
34053895Smckusick 	}
34153895Smckusick 	return 0;
34253895Smckusick }
34353895Smckusick 
34453895Smckusick 
34553895Smckusick /*
34653895Smckusick  * Mouse I/O control function
34753895Smckusick  */
34853895Smckusick 
34953895Smckusick /*ARGSUSED*/
35053895Smckusick msioctl(dev, cmd, data, flag)
35153895Smckusick 	dev_t dev;
35253895Smckusick 	int cmd;
35353895Smckusick 	caddr_t data;
35453895Smckusick 	int flag;
35553895Smckusick {
35653895Smckusick 	register int unit = MSUNIT(dev);
35753895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
35853895Smckusick 	register struct hb_device *ii = msinfo[unit];
35953895Smckusick 	register int s;
36053895Smckusick 
36153895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
36253895Smckusick 		return EIO;
36353895Smckusick 
36453895Smckusick 	s = splms();
36553895Smckusick 
36653895Smckusick 	switch (cmd) {
36753895Smckusick 	case MSIOCGETEM:
36853895Smckusick 		(*(int*)data) = ms->mss_eventmask;
36953895Smckusick 		break;
37053895Smckusick 	case MSIOCSETEM:
37153895Smckusick 		ms->mss_eventmask = *(int *)data;
37253895Smckusick 		break;
37353895Smckusick 	case MSIOCSETXY:
37453895Smckusick 		ms->mss_data.md_x = ((struct ms_coord*)data)->mc_x;
37553895Smckusick 		ms->mss_data.md_y = ((struct ms_coord*)data)->mc_y;
37653895Smckusick 		lock_bitmap();
37753895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);
37853895Smckusick 		unlock_bitmap();
37953895Smckusick 		msq_flush(unit, MSE_MOTION);
38053895Smckusick 		break;
38153895Smckusick 	case MSIOCFLUSH:
38253895Smckusick 		msq_init(unit);
38353895Smckusick 		break;
38453895Smckusick 	case MSIOCSETPARAM:
38553895Smckusick 		ms->mss_param = *(struct ms_param*)data;
38653895Smckusick 		break;
38753895Smckusick 	case MSIOCSETRANGE:
38853895Smckusick 		ms->mss_range = *(struct ms_range*)data;
38953895Smckusick 		break;
39053895Smckusick 	case FIONBIO:
39153895Smckusick 		if (*(int *)data)
39253895Smckusick 			ms->mss_stat |= MS_NBIO;
39353895Smckusick 		else
39453895Smckusick 			ms->mss_stat &= ~MS_NBIO;
39553895Smckusick 		break;
39653895Smckusick 	case FIOASYNC:
39753895Smckusick 		if (*(int *)data)
39853895Smckusick 			ms->mss_stat |= MS_ASYNC;
39953895Smckusick 		else
40053895Smckusick 			ms->mss_stat &= ~MS_ASYNC;
40153895Smckusick 		break;
40253895Smckusick 	case TIOCSPGRP:
40353895Smckusick 		ms->mss_pgrp = *(int *)data;
40453895Smckusick 		break;
40553895Smckusick 	case TIOCGPGRP:
40653895Smckusick 		*(int *)data = ms->mss_pgrp;
40753895Smckusick 		break;
40853895Smckusick 	default:
40953895Smckusick 		splx(s);
41053895Smckusick 		return ENOTTY;
41153895Smckusick 	}
41253895Smckusick 	splx(s);
41353895Smckusick 	return 0;
41453895Smckusick }
41553895Smckusick 
41653895Smckusick msselect(dev, flag)
41753895Smckusick 	dev_t dev;
41853895Smckusick 	int flag;
41953895Smckusick {
42053895Smckusick 	register int unit = MSUNIT(dev);
42153895Smckusick 	register struct ms_stat *ms;
42253895Smckusick 	int s;
42353895Smckusick 
42453895Smckusick 	if (unit < 0 || unit >= NMS)
42553895Smckusick 		return(0);
42653895Smckusick 
42753895Smckusick 	s = splms();
42853895Smckusick 	ms = &ms_stat[unit];
42953895Smckusick 
43053895Smckusick 	switch(flag) {
43153895Smckusick 	case FREAD:
43253895Smckusick 		if (!(ms->mss_eventmask & MS_EMEVENT))
43353895Smckusick 			goto win;
43453895Smckusick 		if(msq_stat(unit))
43553895Smckusick 			goto win;
43653895Smckusick 
43753895Smckusick 		if (ms->mss_rsel && ms->mss_rsel->p_wchan == (caddr_t)&selwait)
43853895Smckusick 			ms->mss_stat |= MS_RCOLL;
43953895Smckusick 		else
44053895Smckusick 			ms->mss_rsel = curproc;
44153895Smckusick 		break;
44253895Smckusick 
44353895Smckusick 	case FWRITE:
44453895Smckusick 		goto win;
44553895Smckusick 	}
44653895Smckusick 	splx(s);
44753895Smckusick 	return(0);
44853895Smckusick win:
44953895Smckusick 	splx(s);
45053895Smckusick 	return(1);
45153895Smckusick }
45253895Smckusick 
45353895Smckusick msselwakeup(ms)
45453895Smckusick 	register struct ms_stat *ms;
45553895Smckusick {
45653895Smckusick 	if (ms->mss_rsel) {
45753895Smckusick 		selwakeup(ms->mss_rsel, ms->mss_stat&MS_RCOLL);
45853895Smckusick 		ms->mss_stat &= ~MS_RCOLL;
45953895Smckusick 		ms->mss_rsel = 0;
46053895Smckusick 	}
46153895Smckusick 	if (ms->mss_stat & MS_ASYNC)
46253895Smckusick 		gsignal(ms->mss_pgrp, SIGIO);
46353895Smckusick }
46453895Smckusick 
46553895Smckusick mssint()
46653895Smckusick {
46753895Smckusick 	printf("mssint\n");
46853895Smckusick }
46953895Smckusick 
47053895Smckusick msputevent(unit, trig, dir, code)
47153895Smckusick 	int unit, trig, dir, code;
47253895Smckusick {
47353895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
47453895Smckusick 	register volatile struct ms_event *me;
47553895Smckusick 	register int s;
47653895Smckusick 
47753895Smckusick 	me = msq_write(unit);
47853895Smckusick 
47953895Smckusick 	s = splclock();
48053895Smckusick 	me->mse_time = time;
48153895Smckusick 	me->mse_inval = 0;
48253895Smckusick 	splx(s);
48353895Smckusick 
48453895Smckusick 	me->mse_trig = trig;
48553895Smckusick 	me->mse_dir = dir;
48653895Smckusick 	me->mse_code = code;
48753895Smckusick 	me->mse_data = ms->mss_data;
48853895Smckusick 
48953895Smckusick 	if (ms->mss_stat & MS_EVWAIT)
49053895Smckusick 		wakeup((caddr_t)&ms->mss_queue);
49153895Smckusick 
49253895Smckusick 	msselwakeup(ms);
49353895Smckusick 
49453895Smckusick 	return (0);
49553895Smckusick }
49653895Smckusick 
49753895Smckusick /*
49853895Smckusick  * for keyboard
49953895Smckusick  */
50053895Smckusick mskeytrigger(unit, up, keycode)
50153895Smckusick 	int unit;
50253895Smckusick 	int up;
50353895Smckusick 	int keycode;
50453895Smckusick {
50553895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
50653895Smckusick 
50753895Smckusick 	if((ms->mss_eventmask & MS_EMEVENT) == 0)
50853895Smckusick 		return 0;
50953895Smckusick 	if((ms->mss_eventmask & MS_EMKEY) == 0)
51053895Smckusick 		return 0;
51153895Smckusick 
51253895Smckusick 	(void) msputevent(unit, MSE_KEY, up ? MSE_UP : MSE_DOWN, keycode);
51353895Smckusick 
51453895Smckusick 	return 1;
51553895Smckusick }
51653895Smckusick 
51753895Smckusick /*
51853895Smckusick  * msconv - convert mouse hardware reports(3 bytes) into internal mouse data
51953895Smckusick  *		it leaves the old mouse data in ms_data_old and
52053895Smckusick  *		new mouse data in ms_data.
52153895Smckusick  */
52253895Smckusick msconv(unit, rep)
52353895Smckusick 	int unit;
52453895Smckusick 	register char rep[];
52553895Smckusick {
52653895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
52753895Smckusick 	register int s_byte;
52853895Smckusick 	register int sw = 0;
52953895Smckusick 	register int dx, dy;
53053895Smckusick 	int adx, ady;
53153895Smckusick 
53253895Smckusick 	ms->mss_data_old = ms->mss_data;
53353895Smckusick 
53453895Smckusick 	/* switch status */
53553895Smckusick 	s_byte = rep[MS_S_BYTE];
53653895Smckusick 	if (s_byte & MS_S_SW1)
53753895Smckusick 		sw |= MS_BUTNL;
53853895Smckusick 	if (s_byte & MS_S_SW2)
53953895Smckusick 		sw |= MS_BUTNR;
54053895Smckusick 	if (s_byte & MS_S_SW3)
54153895Smckusick 		sw |= MS_BUTNM;
54253895Smckusick 	ms->mss_data.md_sw = sw;
54353895Smckusick 
54453895Smckusick 	/* delta x */
54553895Smckusick 	dx = rep[MS_X_BYTE] & MS_X_X06;
54653895Smckusick 	if (s_byte & MS_S_X7)
54753895Smckusick 		dx = (~0&~MS_X_X06)|dx;
54853895Smckusick 
54953895Smckusick 	dy = rep[MS_Y_BYTE] & MS_Y_Y06;
55053895Smckusick 	if (s_byte & MS_S_Y7)
55153895Smckusick 		dy = (~0&~MS_Y_Y06)|dy;
55253895Smckusick 
55353895Smckusick #define ABS(x)	((x)>=0 ? (x) : -(x))
55453895Smckusick 	adx = ABS(dx);
55553895Smckusick 	ady = ABS(dy);
55653895Smckusick #undef ABS
55753895Smckusick 
55853895Smckusick 	if (adx > ms->mss_param.mp_delta) {
55953895Smckusick 		adx = ms->mss_param.mp_delta +
56053895Smckusick 		      (adx - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;
56153895Smckusick 		if (dx < 0)
56253895Smckusick 			dx = -adx;
56353895Smckusick 		else
56453895Smckusick 			dx = adx;
56553895Smckusick 	}
56653895Smckusick 	if (ady > ms->mss_param.mp_delta) {
56753895Smckusick 		ady = ms->mss_param.mp_delta +
56853895Smckusick 		      (ady - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;
56953895Smckusick 		if (dy < 0)
57053895Smckusick 			dy = -ady;
57153895Smckusick 		else
57253895Smckusick 			dy = ady;
57353895Smckusick 	}
57453895Smckusick 	ms->mss_data.md_x += dx;
57553895Smckusick 	ms->mss_data.md_y += dy;
57653895Smckusick 
57753895Smckusick 	if (dx > 0)
578*55764Sbostic 		ms->mss_data.md_x = min(ms->mss_data.md_x,
57953895Smckusick 					ms->mss_range.mr_max.mc_x);
58053895Smckusick 	else
581*55764Sbostic 		ms->mss_data.md_x = max(ms->mss_data.md_x,
58253895Smckusick 					ms->mss_range.mr_min.mc_x);
58353895Smckusick 	if (dy > 0)
584*55764Sbostic 		ms->mss_data.md_y = min(ms->mss_data.md_y,
58553895Smckusick 					ms->mss_range.mr_max.mc_y);
58653895Smckusick 	else
587*55764Sbostic 		ms->mss_data.md_y = max(ms->mss_data.md_y,
58853895Smckusick 					ms->mss_range.mr_min.mc_y);
58953895Smckusick 
59053895Smckusick 	if (dx != 0 || dy != 0)
59153895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 0);
59253895Smckusick }
59353895Smckusick 
59453895Smckusick mscheckevent(unit)
59553895Smckusick 	int unit;
59653895Smckusick {
59753895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
59853895Smckusick 	register int i;
59953895Smckusick 	register int changebits;
60053895Smckusick 	register int dir;
60153895Smckusick 
60253895Smckusick 	if ((ms->mss_eventmask & MS_EMEVENT) == 0)
60353895Smckusick 		return;
60453895Smckusick 
60553895Smckusick 	if (ms->mss_data_old.md_sw != ms->mss_data.md_sw) {
60653895Smckusick 
60753895Smckusick 		changebits = (ms->mss_data_old.md_sw ^ ms->mss_data.md_sw);
60853895Smckusick 		changebits &= ms->mss_eventmask;
60953895Smckusick 
61053895Smckusick 		for(i = 0; i < 3; i++) {
61153895Smckusick 			if(changebits & (1 << i)) {
61253895Smckusick 				if((1 << i) & ms->mss_data.md_sw)
61353895Smckusick 					dir = MSE_DOWN;
61453895Smckusick 				else
61553895Smckusick 					dir = MSE_UP;
61653895Smckusick 				msputevent(unit, MSE_BUTTON, dir, i);
61753895Smckusick 			}
61853895Smckusick 		}
61953895Smckusick 	}
62053895Smckusick 
62153895Smckusick 	if ((ms->mss_eventmask & MS_EMMOTION) &&
62253895Smckusick 	    (ms->mss_data_old.md_x != ms->mss_data.md_x ||
62353895Smckusick 	     ms->mss_data_old.md_y != ms->mss_data.md_y)) {
62453895Smckusick 		msputevent(unit, MSE_MOTION, 0, 0);
62553895Smckusick 		return;
62653895Smckusick 	}
62753895Smckusick }
62853895Smckusick 
62953895Smckusick /*
63053895Smckusick  * _ms_helper - open the mouse line and read mouse data and
63153895Smckusick  *		convert them into mouse data (events)
63253895Smckusick  */
63353895Smckusick _ms_helper(unit)
63453895Smckusick 	int unit;
63553895Smckusick {
63653895Smckusick 	register int c;
63753895Smckusick 	static int counter = 0;
63853895Smckusick 	static char buf[MS_DB_SIZE];
63953895Smckusick 
64053895Smckusick #ifdef notyet /* KU:XXX */
64153895Smckusick 	intrcnt[INTR_MOUSE]++;
64253895Smckusick #endif
64353895Smckusick 
64453895Smckusick #if NBM > 0
64553895Smckusick 	rst_dimmer_cnt();
64653895Smckusick #endif
64753895Smckusick 
64853895Smckusick 	while ((c = xgetc(SCC_MOUSE)) >= 0) {
64953895Smckusick 		if (c & MS_S_MARK)
65053895Smckusick 			counter = 0;
65153895Smckusick 		buf[counter] = c;
65253895Smckusick 		if (++counter == 3) {
65353895Smckusick 			msconv(unit, buf);
65453895Smckusick 			mscheckevent(unit);
65553895Smckusick 			counter = 0;
65653895Smckusick 		}
65753895Smckusick 	}
65853895Smckusick }
65953895Smckusick #endif /* NMS > 0 */
660